def tostring(self): # UIDs (UID1 always 0x101f4a6b) fields = [symbianutil.uidstostring(0x101f4a6bL, self.uid2, self.uid3)] # Flags fields.append(struct.pack("<B", self.flags)) # Longest resource (to be updated) fields.append("\0\0") # Unicode compression bitmap (no compression) fields.append("\0" * ((len(self.resources) + 7) / 8)) # Resource contents offsets = [] foffset = len("".join(fields)) maxrlen = 0 for res in self.resources: # Find longest resource. rlen = len(res) if rlen > maxrlen: maxrlen = rlen offsets.append(foffset) fields.append(res) foffset += rlen offsets.append(foffset) # Update longest resource. fields[2] = struct.pack("<H", maxrlen) # Resource index for off in offsets: fields.append(struct.pack("<H", off)) # TODO: Ineffiecient. Improve. return "".join(fields)
def tostring(self): """Convert this SIS instance to a (possibly very large) string.""" # Generate a SISInfo SISField. infofield = sisfield.SISInfo( UID=self.uid, VendorUniqueName=self.vendorname, Names=self.names, VendorNames=self.vendornames, Version=self.version, CreationTime=self.creationtime, InstallType=sisfield.EInstInstallation, InstallFlags=0, ) # Generate an empty SISSupportedOptions SISField. # Option lists are not supported by SimpleSISWriter. sa = sisfield.SISArray(SISFields=[], SISFieldType="SISSupportedOption") optfield = sisfield.SISSupportedOptions(Options=sa) # Convert language numbers to SISArray of SISLanguages # and generate a SISSupportedLanguages SISField. langfieldlist = [] for lang in self.languages: langfieldlist.append(sisfield.SISLanguage(Language=lang)) sa = sisfield.SISArray(SISFields=langfieldlist, SISFieldType="SISLanguage") langfield = sisfield.SISSupportedLanguages(Languages=sa) # Generate SISPrerequisites SISField. sa1 = sisfield.SISArray(SISFields=self.targetdevices, SISFieldType="SISDependency") sa2 = sisfield.SISArray(SISFields=self.dependencies, SISFieldType="SISDependency") prereqfield = sisfield.SISPrerequisites(TargetDevices=sa1, Dependencies=sa2) # Generate SISProperties SISField. sa = sisfield.SISArray(SISFields=self.properties, SISFieldType="SISProperty") propfield = sisfield.SISProperties(Properties=sa) # Generate SISInstallBlock SISField. iffield = makelangconditional(self.languages, self.langdepfiles) if iffield: # Some language dependent files iffieldlist = [iffield] else: # No language dependent files iffieldlist = [] ibfield = makeinstallblock(self.files, [], iffieldlist) # Generate a data index field. No embedded SIS files, index is 0. didxfield = sisfield.SISDataIndex(DataIndex=0) # Generate a SISController SISField without any signatures. ctrlfield = sisfield.SISController( Info=infofield, Options=optfield, Languages=langfield, Prerequisites=prereqfield, Properties=propfield, Logo=self.logo, InstallBlock=ibfield, ) # Calculate metadata signature for each certificate. certfieldlist = [] for cert in self.certificates: # Calculate a signature of the SISController so far. string = ctrlfield.tostring() string = sisfield.stripheaderandpadding(string) signature, algoid = signstring(cert[0], cert[2], string) # Create a SISCertificateChain SISField from certificate data. sf1 = sisfield.SISBlob(Data=cryptutil.certtobinary(cert[1])) sf2 = sisfield.SISCertificateChain(CertificateData=sf1) # Create a SISSignature SISField from calculated signature. sf3 = sisfield.SISString(String=algoid) sf4 = sisfield.SISSignatureAlgorithm(AlgorithmIdentifier=sf3) sf5 = sisfield.SISBlob(Data=signature) sf6 = sisfield.SISSignature(SignatureAlgorithm=sf4, SignatureData=sf5) # Create a new SISSignatureCertificateChain SISField. sa = sisfield.SISArray(SISFields=[sf6]) certfieldlist.append(sisfield.SISSignatureCertificateChain(Signatures=sa, CertificateChain=sf2)) # Add certificate to SISController SISField. ctrlfield.setsignatures(certfieldlist) # Finally add a data index field to SISController SISField. # and wrap it in SISCompressed SISField. ctrlfield.DataIndex = didxfield ctrlcompfield = sisfield.SISCompressed(Data=ctrlfield, CompressionAlgorithm=sisfield.ECompressDeflate) # Generate SISData SISField. sa = sisfield.SISArray(SISFields=self.filedata, SISFieldType="SISFileData") dufield = sisfield.SISDataUnit(FileData=sa) sa = sisfield.SISArray(SISFields=[dufield]) datafield = sisfield.SISData(DataUnits=sa) # Calculate SISController checksum. # TODO: Requires an extra tostring() conversion. ctrlcs = symbianutil.crc16ccitt(ctrlcompfield.tostring()) ctrlcsfield = sisfield.SISControllerChecksum(Checksum=ctrlcs) # Calculate SISData checksum. # TODO: Requires an extra tostring() conversion. datacs = symbianutil.crc16ccitt(datafield.tostring()) datacsfield = sisfield.SISDataChecksum(Checksum=datacs) # Generate SISContents SISField. contentsfield = sisfield.SISContents( ControllerChecksum=ctrlcsfield, DataChecksum=datacsfield, Controller=ctrlcompfield, Data=datafield ) # Generate a SIS UID string. uidstring = symbianutil.uidstostring(0x10201A7AL, 0x00000000L, self.uid.UID1) # Return the completed SIS file as a string. return uidstring + contentsfield.tostring()