diff -r 509e4801c378 -r 22878952f6e2 srcanamdw/codescanner/pyinstaller/versionInfo.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srcanamdw/codescanner/pyinstaller/versionInfo.py Thu Feb 18 12:29:02 2010 +0530 @@ -0,0 +1,531 @@ +# Copyright (C) 2005, Giovanni Bajo +# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +import win32api +import struct +import pywintypes +import string +import pprint + +TEST=0 + +LOAD_LIBRARY_AS_DATAFILE = 2 +RT_VERSION = 16 + +def getRaw0(o): + return o.raw +def getRaw1(o): + return str(buffer(o)) +import sys +if hasattr(sys, "version_info"): + pyvers = sys.version_info[0]*10 + sys.version_info[1] +else: + toks = string.split(sys.version, '.', 2) + pyvers = int(toks[0])*10 + int(toks[1]) +if pyvers < 20: + getRaw = getRaw0 +else: + getRaw = getRaw1 + + +##VS_VERSION_INFO { +## WORD wLength; // Specifies the length of the VS_VERSION_INFO structure +## WORD wValueLength; // Specifies the length of the Value member +## WORD wType; // 1 means text, 0 means binary +## WCHAR szKey[]; // Contains the Unicode string "VS_VERSION_INFO". +## WORD Padding1[]; +## VS_FIXEDFILEINFO Value; +## WORD Padding2[]; +## WORD Children[]; // Specifies a list of zero or more StringFileInfo or VarFileInfo structures (or both) that are children of the current version structure. +##}; +def decode(pathnm): + h = win32api.LoadLibraryEx(pathnm, 0, LOAD_LIBRARY_AS_DATAFILE) + nm = win32api.EnumResourceNames(h, RT_VERSION)[0] + data = win32api.LoadResource(h, RT_VERSION, nm) + vs = VSVersionInfo() + j = vs.fromRaw(data) + if TEST: + print vs + if data[:j] != vs.toRaw(): + print "AAAAAGGHHHH" + txt = repr(vs) + glbls = {} + glbls['VSVersionInfo'] = VSVersionInfo + glbls['FixedFileInfo'] = FixedFileInfo + glbls['StringFileInfo'] = StringFileInfo + glbls['StringTable'] = StringTable + glbls['StringStruct'] = StringStruct + glbls['VarFileInfo'] = VarFileInfo + glbls['VarStruct'] = VarStruct + vs2 = eval(txt+'\n', glbls) + if vs.toRaw() != vs2.toRaw(): + print + print 'reconstruction not the same!' + print vs2 + win32api.FreeLibrary(h) + return vs + +class VSVersionInfo: + def __init__(self, ffi=None, kids=None): + self.ffi = ffi + self.kids = kids + if kids is None: + self.kids = [] + def fromRaw(self, data): + i, (sublen, vallen, wType, nm) = parseCommon(data) + #vallen is length of the ffi, typ is 0, nm is 'VS_VERSION_INFO' + i = ((i + 3) / 4) * 4 + # now a VS_FIXEDFILEINFO + self.ffi = FixedFileInfo() + j = self.ffi.fromRaw(data, i) + #print ffi + if TEST: + if data[i:j] != self.ffi.toRaw(): + print "raw:", `data[i:j]` + print "ffi:", `self.ffi.toRaw()` + i = j + while i < sublen: + j = i + i, (csublen, cvallen, ctyp, nm) = parseCommon(data, i) + if string.strip(str(nm)) == "StringFileInfo": + sfi = StringFileInfo() + k = sfi.fromRaw(csublen, cvallen, nm, data, i, j+csublen) + if TEST: + if data[j:k] != sfi.toRaw(): + rd = data[j:k] + sd = sfi.toRaw() + for x in range(0, len(rd), 16): + rds = rd[x:x+16] + sds = sd[x:x+16] + if rds != sds: + print "rd[%s:%s+16]: %s" % (x, x, `rds`) + print "sd[%s:%s+16]: %s" % (x, x, `sds`) + print + print "raw: len %d, wLength %d" % (len(rd), struct.unpack('h', rd[:2])[0]) + print "sfi: len %d, wLength %d" % (len(sd), struct.unpack('h', sd[:2])[0]) + self.kids.append(sfi) + i = k + else: + vfi = VarFileInfo() + k = vfi.fromRaw(csublen, cvallen, nm, data, i, j+csublen) + self.kids.append(vfi) + if TEST: + if data[j:k] != vfi.toRaw(): + print "raw:", `data[j:k]` + print "vfi:", `vfi.toRaw()` + i = k + i = j + csublen + i = ((i + 3) / 4) * 4 + return i + def toRaw(self): + nm = pywintypes.Unicode('VS_VERSION_INFO') + rawffi = self.ffi.toRaw() + vallen = len(rawffi) + typ = 0 + sublen = 6 + 2*len(nm) + 2 + pad = '' + if sublen % 4: + pad = '\000\000' + sublen = sublen + len(pad) + vallen + pad2 = '' + if sublen % 4: + pad2 = '\000\000' + tmp = [] + for kid in self.kids: + tmp.append(kid.toRaw()) + tmp = string.join(tmp, '') + sublen = sublen + len(pad2) + len(tmp) + return struct.pack('hhh', sublen, vallen, typ) + getRaw(nm) + '\000\000' + pad + rawffi + pad2 + tmp + def __repr__(self, indent=''): + tmp = [] + newindent = indent + ' ' + for kid in self.kids: + tmp.append(kid.__repr__(newindent+' ')) + tmp = string.join(tmp, ', \n') + return "VSVersionInfo(\n%sffi=%s,\n%skids=[\n%s\n%s]\n)" % (newindent, self.ffi.__repr__(newindent), newindent, tmp, newindent) + +def parseCommon(data, start=0): + i = start + 6 + (wLength, wValueLength, wType) = struct.unpack('3h', data[start:i]) + #print "wLength, wValueLength, wType, i:", wLength, wValueLength, wType, i + i, szKey = parseUString(data, i, i+wLength) + #i = ((i + 3) / 4) * 4 + #print `data[start+6:start+wLength]` + return i, (wLength, wValueLength, wType, szKey) + +def parseUString(data, start, limit): + i = start + while i < limit: + if data[i:i+2] == '\000\000': + break + i = i + 2 + szKey = pywintypes.UnicodeFromRaw(data[start:i]) + i = i + 2 + #print "szKey:", '"'+str(szKey)+'"', "(consumed", i-start, "bytes - to", i, ")" + return i, szKey + +##VS_FIXEDFILEINFO { // vsffi +## DWORD dwSignature; //Contains the value 0xFEEFO4BD +## DWORD dwStrucVersion; //Specifies the binary version number of this structure. The high-order word of this member contains the major version number, and the low-order word contains the minor version number. +## DWORD dwFileVersionMS; // Specifies the most significant 32 bits of the file's binary version number +## DWORD dwFileVersionLS; // +## DWORD dwProductVersionMS; // Specifies the most significant 32 bits of the binary version number of the product with which this file was distributed +## DWORD dwProductVersionLS; // +## DWORD dwFileFlagsMask; // Contains a bitmask that specifies the valid bits in dwFileFlags. A bit is valid only if it was defined when the file was created. +## DWORD dwFileFlags; // VS_FF_DEBUG, VS_FF_PATCHED etc. +## DWORD dwFileOS; // VOS_NT, VOS_WINDOWS32 etc. +## DWORD dwFileType; // VFT_APP etc. +## DWORD dwFileSubtype; // 0 unless VFT_DRV or VFT_FONT or VFT_VXD +## DWORD dwFileDateMS; +## DWORD dwFileDateLS; +##}; + +class FixedFileInfo: + def __init__(self, filevers=(0, 0, 0, 0), prodvers=(0, 0, 0, 0), mask=0x3f, flags=0x0, OS=0x40004, fileType=0x1, subtype=0x0, date=(0, 0)): + self.sig = 0xfeef04bdL + self.strucVersion = 0x10000 + self.fileVersionMS = (filevers[0] << 16) | (filevers[1] & 0xffff) + self.fileVersionLS = (filevers[2] << 16) | (filevers[3] & 0xffff) + self.productVersionMS = (prodvers[0] << 16) | (prodvers[1] & 0xffff) + self.productVersionLS = (prodvers[2] << 16) | (prodvers[3] & 0xffff) + self.fileFlagsMask = mask + self.fileFlags = flags + self.fileOS = OS + self.fileType = fileType + self.fileSubtype = subtype + self.fileDateMS = date[0] + self.fileDateLS = date[1] + def fromRaw(self, data, i): + (self.sig, + self.strucVersion, + self.fileVersionMS, + self.fileVersionLS, + self.productVersionMS, + self.productVersionLS, + self.fileFlagsMask, + self.fileFlags, + self.fileOS, + self.fileType, + self.fileSubtype, + self.fileDateMS, + self.fileDateLS) = struct.unpack('13l', data[i:i+52]) + return i+52 + def toRaw(self): + return struct.pack('L12l', self.sig, + self.strucVersion, + self.fileVersionMS, + self.fileVersionLS, + self.productVersionMS, + self.productVersionLS, + self.fileFlagsMask, + self.fileFlags, + self.fileOS, + self.fileType, + self.fileSubtype, + self.fileDateMS, + self.fileDateLS) + def __repr__(self, indent=''): + fv = (self.fileVersionMS >> 16, self.fileVersionMS & 0xffff, self.fileVersionLS >> 16, self.fileVersionLS & 0xFFFF) + pv = (self.productVersionMS >> 16, self.productVersionMS & 0xffff, self.productVersionLS >> 16, self.productVersionLS & 0xFFFF) + fd = (self.fileDateMS, self.fileDateLS) + tmp = ["FixedFileInfo(", + "filevers=%s," % (fv,), + "prodvers=%s," % (pv,), + "mask=%s," % hex(self.fileFlagsMask), + "flags=%s," % hex(self.fileFlags), + "OS=%s," % hex(self.fileOS), + "fileType=%s," % hex(self.fileType), + "subtype=%s," % hex(self.fileSubtype), + "date=%s" % (fd,), + ")" + ] + return string.join(tmp, '\n'+indent+' ') + +##StringFileInfo { +## WORD wLength; // Specifies the length of the version resource +## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure +## WORD wType; // 1 means text, 0 means binary +## WCHAR szKey[]; // Contains the Unicode string "StringFileInfo". +## WORD Padding[]; +## StringTable Children[]; // Specifies a list of zero or more String structures +##}; + +class StringFileInfo: + def __init__(self, kids=None): + self.name = "StringFileInfo" + if kids is None: + self.kids = [] + else: + self.kids = kids + def fromRaw(self, sublen, vallen, name, data, i, limit): + self.name = name + while i < limit: + st = StringTable() + j = st.fromRaw(data, i, limit) + if TEST: + if data[i:j] != st.toRaw(): + rd = data[i:j] + sd = st.toRaw() + for x in range(0, len(rd), 16): + rds = rd[x:x+16] + sds = sd[x:x+16] + if rds != sds: + print "rd[%s:%s+16]: %s" % (x, x, `rds`) + print "sd[%s:%s+16]: %s" % (x, x, `sds`) + print + print "raw: len %d, wLength %d" % (len(rd), struct.unpack('h', rd[:2])[0]) + print " st: len %d, wLength %d" % (len(sd), struct.unpack('h', sd[:2])[0]) + self.kids.append(st) + i = j + return i + def toRaw(self): + if type(self.name) is STRINGTYPE: + self.name = pywintypes.Unicode(self.name) + vallen = 0 + typ = 1 + sublen = 6 + 2*len(self.name) + 2 + pad = '' + if sublen % 4: + pad = '\000\000' + tmp = [] + for kid in self.kids: + tmp.append(kid.toRaw()) + tmp = string.join(tmp, '') + sublen = sublen + len(pad) + len(tmp) + if tmp[-2:] == '\000\000': + sublen = sublen - 2 + return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + pad + tmp + def __repr__(self, indent=''): + tmp = [] + newindent = indent + ' ' + for kid in self.kids: + tmp.append(kid.__repr__(newindent)) + tmp = string.join(tmp, ', \n') + return "%sStringFileInfo(\n%s[\n%s\n%s])" % (indent, newindent, tmp, newindent) + +##StringTable { +## WORD wLength; +## WORD wValueLength; +## WORD wType; +## WCHAR szKey[]; +## String Children[]; // Specifies a list of zero or more String structures. +##}; + +class StringTable: + def __init__(self, name=None, kids=None): + self.name = name + self.kids = kids + if name is None: + self.name = '' + if kids is None: + self.kids = [] + def fromRaw(self, data, i, limit): + #print "Parsing StringTable" + i, (cpsublen, cpwValueLength, cpwType, self.name) = parseCodePage(data, i, limit) # should be code page junk + #i = ((i + 3) / 4) * 4 + while i < limit: + ss = StringStruct() + j = ss.fromRaw(data, i, limit) + if TEST: + if data[i:j] != ss.toRaw(): + print "raw:", `data[i:j]` + print " ss:", `ss.toRaw()` + i = j + self.kids.append(ss) + i = ((i + 3) / 4) * 4 + return i + def toRaw(self): + if type(self.name) is STRINGTYPE: + self.name = pywintypes.Unicode(self.name) + vallen = 0 + typ = 1 + sublen = 6 + 2*len(self.name) + 2 + tmp = [] + for kid in self.kids: + raw = kid.toRaw() + if len(raw) % 4: + raw = raw + '\000\000' + tmp.append(raw) + tmp = string.join(tmp, '') + sublen = sublen + len(tmp) + if tmp[-2:] == '\000\000': + sublen = sublen - 2 + return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + tmp + def __repr__(self, indent=''): + tmp = [] + newindent = indent + ' ' + for kid in self.kids: + tmp.append(repr(kid)) + tmp = string.join(tmp, ',\n%s' % newindent) + return "%sStringTable(\n%s'%s', \n%s[%s])" % (indent, newindent, str(self.name), newindent, tmp) + +##String { +## WORD wLength; +## WORD wValueLength; +## WORD wType; +## WCHAR szKey[]; +## WORD Padding[]; +## String Value[]; +##}; + +class StringStruct: + def __init__(self, name=None, val=None): + self.name = name + self.val = val + if name is None: + self.name = '' + if val is None: + self.val = '' + def fromRaw(self, data, i, limit): + i, (sublen, vallen, typ, self.name) = parseCommon(data, i) + limit = i + sublen + i = ((i + 3) / 4) * 4 + i, self.val = parseUString(data, i, limit) + return i + def toRaw(self): + if type(self.name) is STRINGTYPE: + self.name = pywintypes.Unicode(self.name) + if type(self.val) is STRINGTYPE: + self.val = pywintypes.Unicode(self.val) + vallen = len(self.val) + 1 + typ = 1 + sublen = 6 + 2*len(self.name) + 2 + pad = '' + if sublen % 4: + pad = '\000\000' + sublen = sublen + len(pad) + 2*vallen + return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + pad + getRaw(self.val) + '\000\000' + def __repr__(self, indent=''): + if pyvers < 20: + return "StringStruct('%s', '%s')" % (str(self.name), str(self.val)) + else: + return "StringStruct('%s', '%s')" % (self.name, self.val) + +def parseCodePage(data, i, limit): + #print "Parsing CodePage" + i, (sublen, wValueLength, wType, nm) = parseCommon(data, i) + #i = ((i + 3) / 4) * 4 + return i, (sublen, wValueLength, wType, nm) + +##VarFileInfo { +## WORD wLength; // Specifies the length of the version resource +## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure +## WORD wType; // 1 means text, 0 means binary +## WCHAR szKey[]; // Contains the Unicode string "VarFileInfo". +## WORD Padding[]; +## Var Children[]; // Specifies a list of zero or more Var structures +##}; + +class VarFileInfo: + def __init__(self, kids=None): + if kids is None: + self.kids = [] + else: + self.kids = kids + def fromRaw(self, sublen, vallen, name, data, i, limit): + self.sublen = sublen + self.vallen = vallen + self.name = name + i = ((i + 3) / 4) * 4 + while i < limit: + vs = VarStruct() + j = vs.fromRaw(data, i, limit) + self.kids.append(vs) + if TEST: + if data[i:j] != vs.toRaw(): + print "raw:", `data[i:j]` + print "cmp:", `vs.toRaw()` + i = j + return i + def toRaw(self): + self.vallen = 0 + self.wType = 1 + self.name = pywintypes.Unicode('VarFileInfo') + sublen = 6 + 2*len(self.name) + 2 + pad = '' + if sublen % 4: + pad = '\000\000' + tmp = [] + for kid in self.kids: + tmp.append(kid.toRaw()) + tmp = string.join(tmp, '') + self.sublen = sublen + len(pad) + len(tmp) + return struct.pack('hhh', self.sublen, self.vallen, self.wType) + getRaw(self.name) + '\000\000' + pad + tmp + def __repr__(self, indent=''): + tmp = map(repr, self.kids) + return "%sVarFileInfo([%s])" % (indent, string.join(tmp, ', ')) + +##Var { +## WORD wLength; // Specifies the length of the version resource +## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure +## WORD wType; // 1 means text, 0 means binary +## WCHAR szKey[]; // Contains the Unicode string "Translation" or a user-defined key string value +## WORD Padding[]; // +## WORD Value[]; // Specifies a list of one or more values that are language and code-page identifiers +##}; + +STRINGTYPE = type('') + +class VarStruct: + def __init__(self, name=None, kids=None): + self.name = name + self.kids = kids + if name is None: + self.name = '' + if kids is None: + self.kids = [] + def fromRaw(self, data, i, limit): + i, (self.sublen, self.wValueLength, self.wType, self.name) = parseCommon(data, i) + i = ((i + 3) / 4) * 4 + for j in range(self.wValueLength/2): + kid = struct.unpack('h', data[i:i+2])[0] + self.kids.append(kid) + i = i + 2 + return i + def toRaw(self): + self.wValueLength = len(self.kids) * 2 + self.wType = 0 + if type(self.name) is STRINGTYPE: + self.name = pywintypes.Unicode(self.name) + sublen = 6 + 2*len(self.name) + 2 + pad = '' + if sublen % 4: + pad = '\000\000' + self.sublen = sublen + len(pad) + self.wValueLength + tmp = [] + for kid in self.kids: + tmp.append(struct.pack('h', kid)) + tmp = string.join(tmp, '') + return struct.pack('hhh', self.sublen, self.wValueLength, self.wType) + getRaw(self.name) + '\000\000' + pad + tmp + def __repr__(self, indent=''): + return "VarStruct('%s', %s)" % (str(self.name), repr(self.kids)) + +def SetVersion(exenm, versionfile): + txt = open(versionfile, 'r').read() + vs = eval(txt+'\n', globals()) + hdst = win32api.BeginUpdateResource(exenm, 0) + win32api.UpdateResource(hdst, RT_VERSION, 1, vs.toRaw()) + win32api.EndUpdateResource (hdst, 0) + +if __name__ == '__main__': + import sys + TEST = 1 + if len(sys.argv) < 2: + decode('c:/Program Files/Netscape/Communicator/Program/netscape.exe') + else: + print "Examining", sys.argv[1] + decode(sys.argv[1]) +