scripts/python/sis2rom/sis2rom.py
changeset 28 ab800b3e45ab
equal deleted inserted replaced
27:8a82bd4d7b19 28:ab800b3e45ab
       
     1 """
       
     2 Copyright (c) 2006, Jari Sukanen
       
     3 All rights reserved.
       
     4 
       
     5 Redistribution and use in source and binary forms, with or 
       
     6 without modification, are permitted provided that the following 
       
     7 conditions are met:
       
     8 	* Redistributions of source code must retain the above copyright 
       
     9 	  notice, this list of conditions and the following disclaimer.
       
    10     * Redistributions in binary form must reproduce the above copyright 
       
    11 	  notice, this list of conditions and the following disclaimer in 
       
    12 	  the documentation and/or other materials provided with the 
       
    13 	  distribution.
       
    14     * Names of the contributors may not be used to endorse or promote 
       
    15 	  products derived from this software without specific prior written 
       
    16 	  permission.
       
    17 
       
    18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
       
    19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
       
    20 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
       
    21 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
       
    22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
       
    23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
       
    24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
       
    25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
       
    26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
       
    27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
       
    28 THE POSSIBILITY OF SUCH DAMAGE.
       
    29 """
       
    30 from sis import sisinfo, sisfields
       
    31 import optparse
       
    32 import sys, os
       
    33 
       
    34 APP_PATH = "epoc32" + os.sep + "apps"
       
    35 IBY_PATH = "epoc32" + os.sep + "rom" + os.sep + "include"
       
    36 CRLF = '\r\n'
       
    37 
       
    38 try:
       
    39 	os.uname()
       
    40 	ZIP_CMD = 'zip -r '
       
    41 except: # no uname on windows
       
    42 	ZIP_CMD = '7z a '
       
    43 
       
    44 PyASN1Availabe = True
       
    45 
       
    46 try :
       
    47     from pyasn1.codec.der import decoder
       
    48     from pyasn1.type import univ, base
       
    49 except :
       
    50     PyASN1Availabe = False
       
    51 
       
    52 def _findItem(item, itemParent, index, objectIdentifier) :
       
    53 	if isinstance(item, base.AbstractSimpleAsn1Item) :
       
    54 		if item == objectIdentifier :
       
    55 			return itemParent[index+1]
       
    56 	else :
       
    57 		for i in range(len(item)) :
       
    58 			found = _findItem(item[i], item, i, objectIdentifier)
       
    59 			if found : 
       
    60 				return found
       
    61 
       
    62 def findItem(decodedCert, objectIdentifier) :
       
    63 	return _findItem(decodedCert, None, 0, objectIdentifier)
       
    64 
       
    65 
       
    66 class CertificateOrganization :
       
    67 	def __init__(self) :
       
    68 		pass
       
    69 	
       
    70 	def parse(self, decodedCert) :
       
    71 		self.commonName = findItem(decodedCert, (2,5,4,3))
       
    72 		self.countryCode = findItem(decodedCert, (2,5,4,6))
       
    73 		self.locality = findItem(decodedCert, (2,5,4,7))
       
    74 		self.state = findItem(decodedCert, (2,5,4,8))
       
    75 		self.street = findItem(decodedCert, (2,5,4,9))
       
    76 		self.organization = findItem(decodedCert, (2,5,4,10))
       
    77 
       
    78 	def readableStr(self) :
       
    79 		buf = ""
       
    80 		if self.commonName :
       
    81 			buf += self.commonName.prettyPrint() + "\n"
       
    82 		if self.countryCode :
       
    83 			buf += self.countryCode.prettyPrint() + "\n"
       
    84 		if self.locality :
       
    85 			buf += self.locality.prettyPrint() + "\n"
       
    86 		if self.state :
       
    87 			buf += self.state.prettyPrint() + "\n"
       
    88 		if self.street :
       
    89 			buf += self.street.prettyPrint() + "\n"
       
    90 		if self.organization :
       
    91 			buf += self.organization.prettyPrint()
       
    92 		return buf
       
    93 		
       
    94 class CertificateInfo :
       
    95 	def __init__(self) :
       
    96 		pass
       
    97 		
       
    98 	def parse(self, decodedCert) :
       
    99 		self.issuer = CertificateOrganization()
       
   100 		self.issuer.parse(decodedCert[0][3])
       
   101 		
       
   102 		self.signer = CertificateOrganization()
       
   103 		self.signer.parse(decodedCert[0][5])
       
   104 		
       
   105 	def readableStr(self) :
       
   106 		buf = "Signer:\n      " + "\n      ".join(self.signer.readableStr().split('\n')) + "\n"
       
   107 		buf += "Issuer:\n      " + "\n      ".join(self.issuer.readableStr().split('\n')) + "\n"
       
   108 		return buf
       
   109 			
       
   110 
       
   111 class Handler :
       
   112     def __init__(self) :
       
   113 		self.files = []
       
   114 		self.fileDatas = []
       
   115 		self.signatureCertificateChains = []
       
   116 		
       
   117     def handleField(self, field, depth) :
       
   118 		if field.type == sisfields.FileDescriptionField :
       
   119 			self.files.append(field)
       
   120 		elif field.type == sisfields.FileDataField :
       
   121 			self.fileDatas.append(field)
       
   122 		elif field.type == sisfields.SignatureCertificateChainField  :
       
   123 			self.signatureCertificateChains.append(field)
       
   124 
       
   125     def print_iby_for_file(self, iby, extracted_file, install_path):
       
   126     	#binarypath="file=ABI_DIR\\BUILD_DIR\\"
       
   127     	#datapath="data=DATAZ_\\RESOURCE_FILES_DIR\\"
       
   128     	binarypath="file=\\"
       
   129     	datapath="data=\\"
       
   130     	#privatepath="data=\\epoc32\\data\\z\\"
       
   131     	
       
   132     	install_path=install_path.replace('c:', 'z:')
       
   133     	#basename = filepath[filepath.rfind('\\')+1:]
       
   134     	
       
   135     	if extracted_file.endswith('exe') or extracted_file.endswith('dll'):
       
   136     		iby.write( binarypath + extracted_file + '\t\t' + install_path + CRLF)
       
   137     	else:
       
   138     		iby.write( datapath + extracted_file + '\t\t' + install_path + CRLF)
       
   139 
       
   140     	
       
   141     def execute(self,outputname, iby) :
       
   142         for f in self.files :
       
   143 			buf = f.findField(sisfields.StringField)[0].readableStr()
       
   144 #			caps = f.findField(sisfields.CapabilitiesField)[0]
       
   145 #			if caps :
       
   146 #				buf += " [" + " ".join(f.findField(sisfields.CapabilitiesField)[0].readableCaps) + "]"
       
   147 			
       
   148 			install_path=buf
       
   149 			parts = f.findField(sisfields.StringField)[0].readableStr().split("\\")
       
   150 			#for part in parts:
       
   151 			#	print part
       
   152 			if len(parts[len(parts) - 1]) > 0 :
       
   153 				path = os.getcwd() + os.sep + APP_PATH
       
   154 				
       
   155 				path += os.sep + os.sep.join(parts[1:-1])
       
   156 				rel_file = APP_PATH + os.sep + outputname + os.sep + os.sep.join(parts[1:])
       
   157 				rel_file = rel_file.replace('/','\\')
       
   158 				if not os.path.exists(path) :
       
   159 					os.makedirs(path)
       
   160 				extracted_file = path + os.sep + parts[len(parts) - 1]
       
   161 				newFile = file(extracted_file, "wb")
       
   162 				newFile.write(self.fileDatas[f.fileIndex].findField(sisfields.CompressedField)[0].data)
       
   163 				newFile.close()
       
   164 				self.print_iby_for_file(iby,rel_file, install_path)
       
   165 			
       
   166 class ContentPrinter :
       
   167 	def __init__(self) :
       
   168 		pass
       
   169 		
       
   170 	def handleField(self, field, depth) :
       
   171 		buf = ""
       
   172 		for i in range(depth) :
       
   173 			buf += "  "
       
   174 		buf += sisfields.FieldNames[field.type] + " "
       
   175 		if len(field.readableStr()) > 0 :
       
   176 			buf += field.readableStr()
       
   177 		print buf
       
   178 
       
   179 import pdb
       
   180     
       
   181 if __name__ == "__main__" :
       
   182 	if len(sys.argv) == 1:
       
   183 		print "usage: %s <sisfile>" % sys.argv[0]
       
   184 		exit()
       
   185 		
       
   186 	sisname = sys.argv[1]
       
   187 	sisInfo = sisinfo.SISInfo()
       
   188 	sisInfo.parse(sisname)
       
   189 	
       
   190 	handler = Handler()
       
   191 	sisInfo.traverse(handler)
       
   192 	
       
   193 	tmp = sisname.lower()
       
   194 	
       
   195 	if tmp.find(os.sep):
       
   196 		tmp = sisname[sisname.rfind(os.sep)+1:]
       
   197 	
       
   198 	if tmp.find('sisx'):
       
   199 		tmp = tmp[0:len(tmp)-4]
       
   200 	elif tmp.find('sis'):
       
   201 		tmp = tmp[0:len(tmp)-3]
       
   202 	
       
   203 	iby_path = os.getcwd() + os.sep + IBY_PATH + os.sep
       
   204 	iby_file = tmp + ".iby"
       
   205 	
       
   206 	if not os.path.exists(iby_path) :
       
   207 		os.makedirs(iby_path)
       
   208 					
       
   209 	iby = open(iby_path + iby_file,'w')
       
   210 	print "Creating IBY file..."
       
   211 	iby.write( "#ifndef __%s_IBY__" % tmp.upper() + CRLF)
       
   212 	iby.write( "#define __%s_IBY__" % tmp.upper() + CRLF)
       
   213 	print "Extracting SIS..."
       
   214 	handler.execute(tmp, iby)
       
   215 	iby.write( "#endif" + CRLF)
       
   216 	iby.close()
       
   217 	print "Zipping..."
       
   218 	os.system(ZIP_CMD + tmp + '.zip epoc32')
       
   219 	print "All done. Remember to #include <%s> in your main IBY file" % iby_file