Update of /cvsroot/pythoncard/PythonCard/tools/standaloneBuilder In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5037 Modified Files: changelog.txt customDialogs.py outputWindow.py outputWindow.rsrc.py prefsDialog.rsrc.py readme.txt standaloneBuilder.gtk.rsrc.py standaloneBuilder.py standaloneBuilder.rsrc.py Added Files: newProjectWizard.gtk.rsrc.py newProjectWizardPage1.gtk.rsrc.py newProjectWizardPage2.gtk.rsrc.py newProjectWizardPage3.gtk.rsrc.py newProjectWizardPage4.gtk.rsrc.py outputWindow.gtk.rsrc.py prefsDialog.gtk.rsrc.py propertiesDialog.gtk.rsrc.py versionInfo.py Log Message: Multiple bug fixes and enhancements ready for release of 0.8.2 Index: standaloneBuilder.rsrc.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/standaloneBuilder/standaloneBuilder.rsrc.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** standaloneBuilder.rsrc.py 9 Sep 2005 12:32:08 -0000 1.6 --- standaloneBuilder.rsrc.py 12 May 2006 16:26:20 -0000 1.7 *************** *** 22,29 **** --- 22,31 ---- 'name':'menuFileOpen', 'label':'&Open\tCtrl+O', + 'command':'openBtn', }, {'type':'MenuItem', 'name':'menuFileSave', 'label':'&Save\tCtrl+S', + 'command':'saveBtn', }, [...966 lines suppressed...] }, --- 575,578 ---- *************** *** 627,632 **** 'name':'StaticText7', 'position':(15, 95), - 'labelSpecified':0, - 'nameSpecified':0, 'text':'Base directory', }, --- 581,584 ---- *************** *** 635,640 **** 'name':'StaticText6', 'position':(15, 65), - 'labelSpecified':0, - 'nameSpecified':0, 'text':'Name', }, --- 587,590 ---- --- NEW FILE: newProjectWizardPage2.gtk.rsrc.py --- {'type':'CustomDialog', 'name':'Template', 'title':'New Project Wizard', 'position':(171, 401), 'size':(600, 310), 'components': [ {'type':'StaticText', 'name':'page2text1', 'position':(175, 0), 'actionBindings':{}, 'font':{'faceName': 'Tahoma', 'family': 'sansSerif', 'size': 20}, 'text':'New project wizard', 'userdata':'page2', }, {'type':'StaticText', 'name':'page2text2', 'position':(175, 60), 'actionBindings':{}, 'text':'Project description', 'userdata':'page2', }, {'type':'TextField', 'name':'projectDesc', 'position':(175, 80), 'size':(415, -1), 'actionBindings':{}, 'userdata':'page2', }, {'type':'Image', 'name':'Image1', 'position':(-5, -5), 'size':(174, 324), 'actionBindings':{}, 'file':'pixmaps/newproject.png', }, ] # end components } # end CustomDialog --- NEW FILE: propertiesDialog.gtk.rsrc.py --- {'type':'CustomDialog', 'name':'propertiesDialog', 'title':'Project properties', 'position':(468, 29), 'size':(450, 385), 'components': [ {'type':'TextField', 'name':'buildPath', 'position':(130, 5), 'size':(265, -1), 'actionBindings':{}, }, {'type':'Button', 'name':'buildPathBtn', 'position':(400, 5), 'size':(25, 22), 'actionBindings':{}, 'label':'...', }, {'type':'TextField', 'name':'distPath', 'position':(130, 40), 'size':(265, -1), 'actionBindings':{}, }, {'type':'Button', 'name':'distPathBtn', 'position':(400, 40), 'size':(25, 22), 'actionBindings':{}, 'label':'...', }, {'type':'TextField', 'name':'pixmapsPath', 'position':(130, 75), 'size':(265, -1), 'actionBindings':{}, }, {'type':'Button', 'name':'pixmapsPathBtn', 'position':(400, 75), 'size':(25, 22), 'actionBindings':{}, 'label':'...', }, {'type':'TextField', 'name':'tarballPath', 'position':(130, 110), 'size':(265, -1), 'actionBindings':{}, }, {'type':'Button', 'name':'tarballsPathBtn', 'position':(400, 110), 'size':(25, 22), 'actionBindings':{}, 'label':'...', }, {'type':'TextField', 'name':'appPublisher', 'position':(130, 145), 'size':(265, -1), 'actionBindings':{}, }, {'type':'TextField', 'name':'appURL', 'position':(130, 180), 'size':(265, -1), 'actionBindings':{}, }, {'type':'TextField', 'name':'appLicence', 'position':(130, 215), 'size':(265, -1), 'actionBindings':{}, }, {'type':'Button', 'name':'appLicenceBtn', 'position':(400, 215), 'size':(25, 22), 'actionBindings':{}, 'label':'...', }, {'type':'Choice', 'name':'buildType', 'position':(125, 250), 'size':(140, -1), 'actionBindings':{}, 'items':[u'Single file', u'Single directory'], 'stringSelection':'Single directory', }, {'type':'CheckBox', 'name':'asciiChk', 'position':(120, 285), 'actionBindings':{}, 'label':'No encoding', }, {'type':'CheckBox', 'name':'consoleChk', 'position':(250, 285), 'actionBindings':{}, 'label':'Console', }, {'type':'CheckBox', 'name':'compressChk', 'position':(345, 285), 'actionBindings':{}, 'label':'Compress', }, {'type':'CheckBox', 'name':'striplibsChk', 'position':(120, 305), 'actionBindings':{}, 'label':'Strip libs (Linux)', }, {'type':'CheckBox', 'name':'optimizeChk', 'position':(250, 305), 'actionBindings':{}, 'label':'Optimize', }, {'type':'CheckBox', 'name':'debugChk', 'position':(345, 305), 'actionBindings':{}, 'label':'Debug', }, {'type':'Button', 'id':5100, 'name':'btnOK', 'position':(270, 340), 'actionBindings':{}, 'label':'OK', }, {'type':'Button', 'id':5101, 'name':'btnCancel', 'position':(355, 340), 'actionBindings':{}, 'label':'Cancel', }, {'type':'StaticText', 'name':'StaticText9', 'position':(25, 220), 'actionBindings':{}, 'text':'App licence file', }, {'type':'StaticText', 'name':'StaticText8', 'position':(20, 185), 'actionBindings':{}, 'text':'Application URL', }, {'type':'StaticText', 'name':'StaticText7', 'position':(30, 150), 'actionBindings':{}, 'text':'App publisher', }, {'type':'StaticText', 'name':'StaticText6', 'position':(30, 285), 'actionBindings':{}, 'text':'Build options', }, {'type':'StaticText', 'name':'StaticText5', 'position':(15, 255), 'actionBindings':{}, 'text':'Deployment type', }, {'type':'StaticText', 'name':'StaticText4', 'position':(15, 115), 'actionBindings':{}, 'text':'Tarballs directory', }, {'type':'StaticText', 'name':'StaticText3', 'position':(15, 80), 'actionBindings':{}, 'text':'Pixmaps directory', }, {'type':'StaticText', 'name':'StaticText2', 'position':(5, 45), 'actionBindings':{}, 'text':'Distribution directory', }, {'type':'StaticText', 'name':'StaticText1', 'position':(30, 10), 'actionBindings':{}, 'text':'Build directory', }, ] # end components } # end CustomDialog Index: outputWindow.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/standaloneBuilder/outputWindow.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** outputWindow.py 9 Apr 2005 09:30:36 -0000 1.2 --- outputWindow.py 12 May 2006 16:26:20 -0000 1.3 *************** *** 1,52 **** ! #!/usr/bin/python ! # ! # projectmanager message output window ! # ! # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! # ! # Copyright (C)2003 Phil Edwards, ph...@li... ! # vim: ts=4 sw=4 ai et ! ! import string ! import time ! ! from PythonCard import model, dialog ! import wx ! ! class outputWindow(model.Background): ! ! def on_initialize(self, event): ! self.parent = self.GetParent() ! ! def clearLines(self): ! self.components.returnedText.text = '' ! self.Refresh() ! wx.Yield() ! ! def addLine(self, text): ! self.components.returnedText.text += str(text) ! #self.Refresh() ! #self.Update() ! #wx.Yield() ! ! def on_closeBtn_mouseClick(self, event): ! self.Hide() ! ! def on_close(self, event): ! self.Hide() ! ! if __name__ == '__main__': ! app = model.PythonCardApp(outputWindow) ! app.MainLoop() --- 1,67 ---- ! #!/usr/bin/python ! # ! # projectmanager message output window ! # ! # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! # ! # Copyright (C)2003 Phil Edwards, ph...@li... ! # vim: ts=4 sw=4 ai et ! ! import string ! import time ! import sys ! ! from PythonCard import model, dialog ! import wx ! ! class outputWindow(model.Background): ! ! def on_initialize(self, event): ! self.parent = self.GetParent() ! ! def clearLines(self): ! self.components.returnedText.text = '' ! self.components.importError.text = '' ! self.Refresh() ! wx.Yield() ! ! def addLine(self, text): ! if self.components.returnedText.enabled: ! self.components.returnedText.text += str(text) ! else: ! self.components.importError.text += str(text) ! #self.Refresh() ! #self.Update() ! #wx.Yield() ! ! def on_closeBtn_mouseClick(self, event): ! self.Hide() ! ! def on_close(self, event): ! self.Hide() ! ! def on_clipBoardBtn_mouseClick(self, event): ! if sys.platform.startswith('win'): ! stuff = wx.TextDataObject() ! stuff.SetText(self.components.clipBoardBtn.userdata) ! if wx.TheClipboard.Open(): ! wx.TheClipboard.SetData(stuff) ! wx.TheClipboard.Close() ! ! ! ! if __name__ == '__main__': ! app = model.PythonCardApp(outputWindow) ! app.MainLoop() --- NEW FILE: outputWindow.gtk.rsrc.py --- {'application':{'type':'Application', 'name':'Template', 'backgrounds': [ {'type':'Background', 'name':'outputWindow', 'title':'Rebuild project', 'size':(400, 300), 'visible':0, 'components': [ {'type':'TextArea', 'name':'importError', 'position':(10, 10), 'size':(375, 205), 'actionBindings':{}, 'editable':False, 'enabled':False, 'visible':False, }, {'type':'Button', 'name':'clipBoardBtn', 'position':(95, 225), 'actionBindings':{}, 'label':'Clipboard', 'toolTip':'Click here to copy the PythonCard component imports line to the Windows clipboard', }, {'type':'Button', 'name':'closeBtn', 'position':(10, 225), 'actionBindings':{}, 'label':'Close', }, {'type':'StaticText', 'name':'txt5', 'position':(10, 90), 'actionBindings':{}, 'text':'Returned messages:', }, {'type':'TextArea', 'name':'returnedText', 'position':(10, 105), 'size':(375, 110), 'actionBindings':{}, }, {'type':'StaticText', 'name':'txt4c', 'position':(145, 70), 'actionBindings':{}, 'text':'please wait...', 'visible':False, }, {'type':'StaticText', 'name':'txt4b', 'position':(145, 70), 'actionBindings':{}, 'font':{'style': 'bold', 'faceName': 'Verdana', 'family': 'sansSerif', 'size': 8}, 'text':'Done', 'visible':False, }, {'type':'StaticText', 'name':'txt4a', 'position':(10, 70), 'actionBindings':{}, 'text':'Rebuilding distributable:', 'visible':False, }, {'type':'StaticText', 'name':'txt3c', 'position':(145, 50), 'actionBindings':{}, 'text':'please wait...', 'visible':False, }, {'type':'StaticText', 'name':'txt3b', 'position':(145, 50), 'actionBindings':{}, 'font':{'style': 'bold', 'faceName': 'Verdana', 'family': 'sansSerif', 'size': 8}, 'text':'Done', 'visible':False, }, {'type':'StaticText', 'name':'txt3a', 'position':(10, 50), 'actionBindings':{}, 'text':'Rebuilding application:', 'visible':False, }, {'type':'StaticText', 'name':'txt2b', 'position':(145, 30), 'actionBindings':{}, 'font':{'style': 'bold', 'faceName': 'Verdana', 'family': 'sansSerif', 'size': 8}, 'text':'Done', 'visible':False, }, {'type':'StaticText', 'name':'txt2a', 'position':(10, 30), 'actionBindings':{}, 'text':'Rebuilding versioninfo file:', 'visible':False, }, {'type':'StaticText', 'name':'txt1b', 'position':(145, 10), 'actionBindings':{}, 'font':{'style': 'bold', 'faceName': 'Verdana', 'family': 'sansSerif', 'size': 8}, 'text':'Done', 'visible':False, }, {'type':'StaticText', 'name':'txt1a', 'position':(10, 10), 'actionBindings':{}, 'text':'Rebuilding spec file:', 'visible':False, }, ] # end components } # end background ] # end backgrounds } } --- NEW FILE: versionInfo.py --- # copyright 2001 McMillan Enterprises, Inc. # license: use as you please. No warranty. # Gordon McMillan gm...@hy... # 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 files 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 = -17890115 # 0xfeef04bd 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('13l', 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, ... [truncated message content] |