diff -r 8a82bd4d7b19 -r ab800b3e45ab scripts/python/sis2rom/sis/sisfields.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/python/sis2rom/sis/sisfields.py Wed Jan 27 10:52:27 2010 +0000 @@ -0,0 +1,728 @@ +""" +Copyright (c) 2006, Jari Sukanen +All rights reserved. + +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following +conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Names of the contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. +""" + +import sisreader +import zlib +import sys + +class SISFileHeader : + def __init__(self) : + self.uid1 = 0 + self.uid2 = 0 + self.uid3 = 0 + self.uidChecksum = 0 + +class SISField : + def __init__(self) : + self.type = 0 + self.length = None + self.subFields = [] + + def readFieldLength(self, fileReader) : + length = fileReader.readBytesAsUint(4) + if length & 0x80000000 > 0 : + length = length << 32 + length |= fileReader.readBytesAsUint(4) + return length + + def findField(self, fieldType, startIndex = 0) : + result = None + index = startIndex + + for field in self.subFields[startIndex:] : + if field.type == fieldType : + result = field + break + ++index + return (result, index) + + def readableStr(self) : + return "" + + def traverse(self, handler, depth = 0) : + handler.handleField(self, depth) + for field in self.subFields : + field.traverse(handler, depth + 1) + +class SISUnsupportedField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fileReader.readPlainBytes(self.length) + +class SISStringField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.data = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + buf = fileReader.readPlainBytes(self.length) + self.data = u"" + while len(buf) > 0 : + temp = buf[:2] + buf = buf[2:] + self.data += unichr(ord(temp[0]) | ord(temp[1]) << 8) + + def readableStr(self) : + return self.data + +class SISArrayField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + type = fileReader.readBytesAsInt(4) + l = self.length - 4 + while l > 0 : + field = SISFieldTypes[type]() + field.type = type + field.initFromFile(fileReader) + self.subFields.append(field) + + l -= field.length + 4 # field length + the length field + padding = fileReader.skipPadding() + l -= padding + +class SISCompressedField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.algorithm = None + self.uncompressedDataSize = None + self.data = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.algorithm = fileReader.readBytesAsUint(4) + self.uncompressedDataSize = fileReader.readBytesAsUint(8) + data = fileReader.readPlainBytes(self.length - 4 - 8) + if self.algorithm == 0 : + self.data = data + elif self.algorithm == 1 : + self.data = zlib.decompress(data) + +class SISVersionField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.version = (-1, -1, -1) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + major = fileReader.readBytesAsInt(4) + minor = fileReader.readBytesAsInt(4) + build = fileReader.readBytesAsInt(4) + self.version = (major, minor, build) + + def readableStr(self) : + return str(self.version) + +class SISVersionRangeField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.fromVersion = None + self.toVersion = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.fromVersion = fieldParser.parseField(fileReader) + if self.length - fieldParser.lastReadBytes > 0 : + self.toVersion = fieldParser.parseField(fileReader) + +class SISDateField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.year = None + self.month = None + self.day = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.year = fileReader.readBytesAsUint(2) + self.month = fileReader.readBytesAsUint(1) + self.day = fileReader.readBytesAsUint(1) + + def readableStr(self) : + return str(self.year) + "." + str(self.month) + "." + str(self.day) + +class SISTimeField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.hours = None + self.minutes = None + self.seconds = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.hours = fileReader.readBytesAsUint(1) + self.minutes = fileReader.readBytesAsUint(1) + self.seconds = fileReader.readBytesAsUint(1) + + def readableStr(self) : + return str(self.hours) + ":" + str(self.minutes) + ":" + str(self.seconds) + +class SISDateTimeField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.date = None + self.time = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.date = fieldParser.parseField(fileReader) + self.time = fieldParser.parseField(fileReader) + +class SISUidField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.uid = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.uid = fileReader.readBytesAsUint(4) + + def readableStr(self) : + return hex(self.uid) + +class SISLanguageField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.language = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.language = fileReader.readBytesAsUint(4) + + def readableStr(self) : + return str(self.language) + +class SISContentsField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + field = fieldParser.parseField(fileReader) + while field : + if field.type == 3 : # compressed + bufferReader = sisreader.SISBufferReader(field.data) + field = fieldParser.parseField(bufferReader) + self.subFields.append(field) + field = fieldParser.parseField(fileReader) + +class SISControllerField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + bufferReader = sisreader.SISBufferReader(fileReader.readPlainBytes(self.length)) + field = fieldParser.parseField(bufferReader) + while field : + self.subFields.append(field) + field = fieldParser.parseField(bufferReader) + +class SISInfoField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.installType = None + self.installFlags = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # UID + self.subFields.append(fieldParser.parseField(fileReader)) # Vendor name unique + self.subFields.append(fieldParser.parseField(fileReader)) # names + self.subFields.append(fieldParser.parseField(fileReader)) # vendor names + self.subFields.append(fieldParser.parseField(fileReader)) # version + self.subFields.append(fieldParser.parseField(fileReader)) # creation time + self.installType = fileReader.readBytesAsUint(1) + self.installFlags = fileReader.readBytesAsUint(1) + +class SISSupportedLanguagesField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # languages + +class SISSupportedOptionsField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # options + +class SISPrerequisitiesField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # target devices + self.subFields.append(fieldParser.parseField(fileReader)) # dependencies + +import pdb + +class SISDependencyField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # UID + field = fieldParser.parseField(fileReader) + # Version range field is optional + if field.type == VersionRangeField : + self.subFields.append(field) # version range + self.subFields.append(fieldParser.parseField(fileReader)) # dependency names + else : + self.subFields.append(field) # dependency names + +class SISPropertiesField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # properties + +class SISPropertyField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.key = None + self.value = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.key = fileReader.readBytesAsInt(4) + self.value = fileReader.readBytesAsInt(4) + +# There is a type for this field, but there is no definition of the field contents +class SISSignaturesField(SISUnsupportedField) : + pass + +class SISCertificateChainField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # certificate data + +class SISLogoField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # logo file + +class SISFileDescriptionField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.operation = None + self.operationOptions = None + self.compressedLength = None + self.uncompressedLength = None + self.fileIndex = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + + self.subFields.append(fieldParser.parseField(fileReader)) + self.subFields.append(fieldParser.parseField(fileReader)) + field = fieldParser.parseField(fileReader) + self.subFields.append(field) + if field.type == 41 : # read field was capabilities ==> there is one more field left + self.subFields.append(fieldParser.parseField(fileReader)) + + self.operation = fileReader.readBytesAsUint(4) + self.operationOptions = fileReader.readBytesAsUint(4) + self.compressedLength = fileReader.readBytesAsUint(8) + self.uncompressedLength = fileReader.readBytesAsUint(8) + self.fileIndex = fileReader.readBytesAsUint(4) + + def readableStr(self) : + return "index: " + str(self.fileIndex) + +class SISHashField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.algorithm = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.algorithm = fileReader.readBytesAsUint(4) + self.subFields.append(fieldParser.parseField(fileReader)) # logo file + +class SISIfField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # expression + self.subFields.append(fieldParser.parseField(fileReader)) # install block + self.subFields.append(fieldParser.parseField(fileReader)) # else ifs + +class SISElseIfField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # expression + self.subFields.append(fieldParser.parseField(fileReader)) # install block + +class SISInstallBlockField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.files = None + self.embeddedSISFiles = None + self.ifBlocks = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) + self.subFields.append(fieldParser.parseField(fileReader)) + self.subFields.append(fieldParser.parseField(fileReader)) + +class SISExpressionField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.operator = None + self.integerValue = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.operator = fileReader.readBytesAsUint(4) + self.integerValue = fileReader.readBytesAsInt(4) + + if self.operator == 10 or self.operator == 13 : + self.subFields.append(fieldParser.parseField(fileReader)) + if self.operator == 1 or self.operator == 2 or self.operator == 3 or self.operator == 4 or self.operator == 5 or self.operator == 6 or self.operator == 7 or self.operator == 8 or self.operator == 11 or self.operator == 12 : + self.subFields.append(fieldParser.parseField(fileReader)) + if not (self.operator == 13 or self.operator == 14 or self.operator == 15 or self.operator == 16 or self.operator == 10) : + self.subFields.append(fieldParser.parseField(fileReader)) + +class SISDataField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # data units + +class SISDataUnitField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # file data + +class SISFileDataField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # raw file data + +class SISSupportedOptionField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # names + +class SISControllerChecksumField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.checksum = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.checksum = fileReader.readBytesAsUint(2) + +class SISDataChecksumField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.checksum = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.checksum = fileReader.readBytesAsUint(2) + +class SISSignatureField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # signature algorithm + self.subFields.append(fieldParser.parseField(fileReader)) # signature data + +class SISBlobField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.data = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.data = fileReader.readPlainBytes(self.length) + +class SISSignatureAlgorithmField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # algorithm identifier + +class SISSignatureCertificateChainField(SISField) : + def __init__(self) : + SISField.__init__(self) + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + fieldParser = sisreader.SISFieldParser() + self.subFields.append(fieldParser.parseField(fileReader)) # signatures + self.subFields.append(fieldParser.parseField(fileReader)) # certificate chain + +class SISDataIndexField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.dataIndex = None + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.dataIndex = fileReader.readBytesAsUint(4) + +class SISCapabilitiesField(SISField) : + def __init__(self) : + SISField.__init__(self) + self.capabilities = 0 + self.readableCaps = [] + + def initFromFile(self, fileReader) : + self.length = self.readFieldLength(fileReader) + self.capabilities = fileReader.readBytesAsUint(self.length) + + for i in range(20) : + if (self.capabilities >> i) & 0x01 : + self.readableCaps.append(CapabilityNames[i]) + + def readableStr(self) : + return " ".join(self.readableCaps) + +SISFieldTypes = { + 1 : SISStringField, + 2 : SISArrayField, + 3 : SISCompressedField, + 4 : SISVersionField, + 5 : SISVersionRangeField, + 6 : SISDateField, + 7 : SISTimeField, + 8 : SISDateTimeField, + 9 : SISUidField, + 10 : SISUnsupportedField, + 11 : SISLanguageField, + 12 : SISContentsField, + 13 : SISControllerField, + 14 : SISInfoField, + 15 : SISSupportedLanguagesField, + 16 : SISSupportedOptionsField, + 17 : SISPrerequisitiesField, + 18 : SISDependencyField, + 19 : SISPropertiesField, + 20 : SISPropertyField, + 21 : SISSignaturesField, + 22 : SISCertificateChainField, + 23 : SISLogoField, + 24 : SISFileDescriptionField, + 25 : SISHashField, + 26 : SISIfField, + 27 : SISElseIfField, + 28 : SISInstallBlockField, + 29 : SISExpressionField, + 30 : SISDataField, + 31 : SISDataUnitField, + 32 : SISFileDataField, + 33 : SISSupportedOptionField, + 34 : SISControllerChecksumField, + 35 : SISDataChecksumField, + 36 : SISSignatureField, + 37 : SISBlobField, + 38 : SISSignatureAlgorithmField, + 39 : SISSignatureCertificateChainField, + 40 : SISDataIndexField, + 41 : SISCapabilitiesField + } + +[StringField, + ArrayField, + CompressedField, + VersionField, + VersionRangeField, + DateField, + TimeField, + DateTimeField, + UidField, + UnusedField, + LanguageField, + ContentsField, + ControllerField, + InfoField, + SupportedLanguagesField, + SupportedOptionsField, + PrerequisitiesField, + DependencyField, + PropertiesField, + PropertyField, + SignaturesField, + CertificateChainField, + LogoField, + FileDescriptionField, + HashField, + IfField, + ElseIfField, + InstallBlockField, + ExpressionField, + DataField, + DataUnitField, + FileDataField, + SupportedOptionField, + ControllerChecksumField, + DataChecksumField, + SignatureField, + BlobField, + SignatureAlgorithmField, + SignatureCertificateChainField, + DataIndexField, + CapabilitiesField] = range(1, 42) + +FieldNames = { + 0 : "ROOT", + StringField : "StringField", + ArrayField : "ArrayField", + CompressedField : "CompressedField", + VersionField : "VersionField", + VersionRangeField : "VersionRangeField", + DateField : "DateField", + TimeField : "TimeField", + DateTimeField : "DateTimeField", + UidField : "UidField", + UnusedField : "UnusedField", + LanguageField : "LanguageField", + ContentsField : "ContentsField", + ControllerField : "ControllerField", + InfoField : "InfoField", + SupportedLanguagesField : "SupportedLanguagesField", + SupportedOptionsField : "SupportedOptionsField", + PrerequisitiesField : "PrerequisitiesField", + DependencyField : "DependencyField", + PropertiesField : "PropertiesField", + PropertyField : "PropertyField", + SignaturesField : "SignaturesField", + CertificateChainField : "CertificateChainField", + LogoField : "LogoField", + FileDescriptionField : "FileDescriptionField", + HashField : "HashField", + IfField : "IfField", + ElseIfField : "ElseIfField", + InstallBlockField : "InstallBlockField", + ExpressionField : "ExpressionField", + DataField : "DataField", + DataUnitField : "DataUnitField", + FileDataField : "FileDataField", + SupportedOptionField : "SupportedOptionField", + ControllerChecksumField : "ControllerChecksumField", + DataChecksumField : "DataChecksumField", + SignatureField : "SignatureField", + BlobField : "BlobField", + SignatureAlgorithmField : "SignatureAlgorithmField", + SignatureCertificateChainField : "SignatureCertificateChainField", + DataIndexField : "DataIndexField", + CapabilitiesField : "CapabilitiesField" +} + +CapabilityNames = { + 0 : "TCB", + 1 : "CommDD", + 2 : "PowerMgmt", + 3 : "MultimediaDD", + 4 : "ReadDeviceData", + 5 : "WriteDeviceData", + 6 : "DRM", + 7 : "TrustedUI", + 8 : "ProtServ", + 9 : "DiskAdmin", + 10 : "NetworkControl", + 11 : "AllFiles", + 12 : "SwEvent", + 13 : "NetworkServices", + 14 : "LocalServices", + 15 : "ReadUserData", + 16 : "WriteUserData", + 17 : "Location", + 18 : "SurroundingsDD", + 19 : "UserEnvironment" + } \ No newline at end of file