示例#1
0
    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)
示例#2
0
    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()