|
1 # Copyright (C) 2005, Giovanni Bajo |
|
2 # Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc. |
|
3 # |
|
4 # This program is free software; you can redistribute it and/or |
|
5 # modify it under the terms of the GNU General Public License |
|
6 # as published by the Free Software Foundation; either version 2 |
|
7 # of the License, or (at your option) any later version. |
|
8 # |
|
9 # This program is distributed in the hope that it will be useful, |
|
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 # GNU General Public License for more details. |
|
13 # |
|
14 # You should have received a copy of the GNU General Public License |
|
15 # along with this program; if not, write to the Free Software |
|
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
17 import win32api |
|
18 import struct |
|
19 import pywintypes |
|
20 import string |
|
21 import pprint |
|
22 |
|
23 TEST=0 |
|
24 |
|
25 LOAD_LIBRARY_AS_DATAFILE = 2 |
|
26 RT_VERSION = 16 |
|
27 |
|
28 def getRaw0(o): |
|
29 return o.raw |
|
30 def getRaw1(o): |
|
31 return str(buffer(o)) |
|
32 import sys |
|
33 if hasattr(sys, "version_info"): |
|
34 pyvers = sys.version_info[0]*10 + sys.version_info[1] |
|
35 else: |
|
36 toks = string.split(sys.version, '.', 2) |
|
37 pyvers = int(toks[0])*10 + int(toks[1]) |
|
38 if pyvers < 20: |
|
39 getRaw = getRaw0 |
|
40 else: |
|
41 getRaw = getRaw1 |
|
42 |
|
43 |
|
44 ##VS_VERSION_INFO { |
|
45 ## WORD wLength; // Specifies the length of the VS_VERSION_INFO structure |
|
46 ## WORD wValueLength; // Specifies the length of the Value member |
|
47 ## WORD wType; // 1 means text, 0 means binary |
|
48 ## WCHAR szKey[]; // Contains the Unicode string "VS_VERSION_INFO". |
|
49 ## WORD Padding1[]; |
|
50 ## VS_FIXEDFILEINFO Value; |
|
51 ## WORD Padding2[]; |
|
52 ## WORD Children[]; // Specifies a list of zero or more StringFileInfo or VarFileInfo structures (or both) that are children of the current version structure. |
|
53 ##}; |
|
54 def decode(pathnm): |
|
55 h = win32api.LoadLibraryEx(pathnm, 0, LOAD_LIBRARY_AS_DATAFILE) |
|
56 nm = win32api.EnumResourceNames(h, RT_VERSION)[0] |
|
57 data = win32api.LoadResource(h, RT_VERSION, nm) |
|
58 vs = VSVersionInfo() |
|
59 j = vs.fromRaw(data) |
|
60 if TEST: |
|
61 print vs |
|
62 if data[:j] != vs.toRaw(): |
|
63 print "AAAAAGGHHHH" |
|
64 txt = repr(vs) |
|
65 glbls = {} |
|
66 glbls['VSVersionInfo'] = VSVersionInfo |
|
67 glbls['FixedFileInfo'] = FixedFileInfo |
|
68 glbls['StringFileInfo'] = StringFileInfo |
|
69 glbls['StringTable'] = StringTable |
|
70 glbls['StringStruct'] = StringStruct |
|
71 glbls['VarFileInfo'] = VarFileInfo |
|
72 glbls['VarStruct'] = VarStruct |
|
73 vs2 = eval(txt+'\n', glbls) |
|
74 if vs.toRaw() != vs2.toRaw(): |
|
75 print |
|
76 print 'reconstruction not the same!' |
|
77 print vs2 |
|
78 win32api.FreeLibrary(h) |
|
79 return vs |
|
80 |
|
81 class VSVersionInfo: |
|
82 def __init__(self, ffi=None, kids=None): |
|
83 self.ffi = ffi |
|
84 self.kids = kids |
|
85 if kids is None: |
|
86 self.kids = [] |
|
87 def fromRaw(self, data): |
|
88 i, (sublen, vallen, wType, nm) = parseCommon(data) |
|
89 #vallen is length of the ffi, typ is 0, nm is 'VS_VERSION_INFO' |
|
90 i = ((i + 3) / 4) * 4 |
|
91 # now a VS_FIXEDFILEINFO |
|
92 self.ffi = FixedFileInfo() |
|
93 j = self.ffi.fromRaw(data, i) |
|
94 #print ffi |
|
95 if TEST: |
|
96 if data[i:j] != self.ffi.toRaw(): |
|
97 print "raw:", `data[i:j]` |
|
98 print "ffi:", `self.ffi.toRaw()` |
|
99 i = j |
|
100 while i < sublen: |
|
101 j = i |
|
102 i, (csublen, cvallen, ctyp, nm) = parseCommon(data, i) |
|
103 if string.strip(str(nm)) == "StringFileInfo": |
|
104 sfi = StringFileInfo() |
|
105 k = sfi.fromRaw(csublen, cvallen, nm, data, i, j+csublen) |
|
106 if TEST: |
|
107 if data[j:k] != sfi.toRaw(): |
|
108 rd = data[j:k] |
|
109 sd = sfi.toRaw() |
|
110 for x in range(0, len(rd), 16): |
|
111 rds = rd[x:x+16] |
|
112 sds = sd[x:x+16] |
|
113 if rds != sds: |
|
114 print "rd[%s:%s+16]: %s" % (x, x, `rds`) |
|
115 print "sd[%s:%s+16]: %s" % (x, x, `sds`) |
|
116 print |
|
117 print "raw: len %d, wLength %d" % (len(rd), struct.unpack('h', rd[:2])[0]) |
|
118 print "sfi: len %d, wLength %d" % (len(sd), struct.unpack('h', sd[:2])[0]) |
|
119 self.kids.append(sfi) |
|
120 i = k |
|
121 else: |
|
122 vfi = VarFileInfo() |
|
123 k = vfi.fromRaw(csublen, cvallen, nm, data, i, j+csublen) |
|
124 self.kids.append(vfi) |
|
125 if TEST: |
|
126 if data[j:k] != vfi.toRaw(): |
|
127 print "raw:", `data[j:k]` |
|
128 print "vfi:", `vfi.toRaw()` |
|
129 i = k |
|
130 i = j + csublen |
|
131 i = ((i + 3) / 4) * 4 |
|
132 return i |
|
133 def toRaw(self): |
|
134 nm = pywintypes.Unicode('VS_VERSION_INFO') |
|
135 rawffi = self.ffi.toRaw() |
|
136 vallen = len(rawffi) |
|
137 typ = 0 |
|
138 sublen = 6 + 2*len(nm) + 2 |
|
139 pad = '' |
|
140 if sublen % 4: |
|
141 pad = '\000\000' |
|
142 sublen = sublen + len(pad) + vallen |
|
143 pad2 = '' |
|
144 if sublen % 4: |
|
145 pad2 = '\000\000' |
|
146 tmp = [] |
|
147 for kid in self.kids: |
|
148 tmp.append(kid.toRaw()) |
|
149 tmp = string.join(tmp, '') |
|
150 sublen = sublen + len(pad2) + len(tmp) |
|
151 return struct.pack('hhh', sublen, vallen, typ) + getRaw(nm) + '\000\000' + pad + rawffi + pad2 + tmp |
|
152 def __repr__(self, indent=''): |
|
153 tmp = [] |
|
154 newindent = indent + ' ' |
|
155 for kid in self.kids: |
|
156 tmp.append(kid.__repr__(newindent+' ')) |
|
157 tmp = string.join(tmp, ', \n') |
|
158 return "VSVersionInfo(\n%sffi=%s,\n%skids=[\n%s\n%s]\n)" % (newindent, self.ffi.__repr__(newindent), newindent, tmp, newindent) |
|
159 |
|
160 def parseCommon(data, start=0): |
|
161 i = start + 6 |
|
162 (wLength, wValueLength, wType) = struct.unpack('3h', data[start:i]) |
|
163 #print "wLength, wValueLength, wType, i:", wLength, wValueLength, wType, i |
|
164 i, szKey = parseUString(data, i, i+wLength) |
|
165 #i = ((i + 3) / 4) * 4 |
|
166 #print `data[start+6:start+wLength]` |
|
167 return i, (wLength, wValueLength, wType, szKey) |
|
168 |
|
169 def parseUString(data, start, limit): |
|
170 i = start |
|
171 while i < limit: |
|
172 if data[i:i+2] == '\000\000': |
|
173 break |
|
174 i = i + 2 |
|
175 szKey = pywintypes.UnicodeFromRaw(data[start:i]) |
|
176 i = i + 2 |
|
177 #print "szKey:", '"'+str(szKey)+'"', "(consumed", i-start, "bytes - to", i, ")" |
|
178 return i, szKey |
|
179 |
|
180 ##VS_FIXEDFILEINFO { // vsffi |
|
181 ## DWORD dwSignature; //Contains the value 0xFEEFO4BD |
|
182 ## 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. |
|
183 ## DWORD dwFileVersionMS; // Specifies the most significant 32 bits of the file's binary version number |
|
184 ## DWORD dwFileVersionLS; // |
|
185 ## DWORD dwProductVersionMS; // Specifies the most significant 32 bits of the binary version number of the product with which this file was distributed |
|
186 ## DWORD dwProductVersionLS; // |
|
187 ## 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. |
|
188 ## DWORD dwFileFlags; // VS_FF_DEBUG, VS_FF_PATCHED etc. |
|
189 ## DWORD dwFileOS; // VOS_NT, VOS_WINDOWS32 etc. |
|
190 ## DWORD dwFileType; // VFT_APP etc. |
|
191 ## DWORD dwFileSubtype; // 0 unless VFT_DRV or VFT_FONT or VFT_VXD |
|
192 ## DWORD dwFileDateMS; |
|
193 ## DWORD dwFileDateLS; |
|
194 ##}; |
|
195 |
|
196 class FixedFileInfo: |
|
197 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)): |
|
198 self.sig = 0xfeef04bdL |
|
199 self.strucVersion = 0x10000 |
|
200 self.fileVersionMS = (filevers[0] << 16) | (filevers[1] & 0xffff) |
|
201 self.fileVersionLS = (filevers[2] << 16) | (filevers[3] & 0xffff) |
|
202 self.productVersionMS = (prodvers[0] << 16) | (prodvers[1] & 0xffff) |
|
203 self.productVersionLS = (prodvers[2] << 16) | (prodvers[3] & 0xffff) |
|
204 self.fileFlagsMask = mask |
|
205 self.fileFlags = flags |
|
206 self.fileOS = OS |
|
207 self.fileType = fileType |
|
208 self.fileSubtype = subtype |
|
209 self.fileDateMS = date[0] |
|
210 self.fileDateLS = date[1] |
|
211 def fromRaw(self, data, i): |
|
212 (self.sig, |
|
213 self.strucVersion, |
|
214 self.fileVersionMS, |
|
215 self.fileVersionLS, |
|
216 self.productVersionMS, |
|
217 self.productVersionLS, |
|
218 self.fileFlagsMask, |
|
219 self.fileFlags, |
|
220 self.fileOS, |
|
221 self.fileType, |
|
222 self.fileSubtype, |
|
223 self.fileDateMS, |
|
224 self.fileDateLS) = struct.unpack('13l', data[i:i+52]) |
|
225 return i+52 |
|
226 def toRaw(self): |
|
227 return struct.pack('L12l', self.sig, |
|
228 self.strucVersion, |
|
229 self.fileVersionMS, |
|
230 self.fileVersionLS, |
|
231 self.productVersionMS, |
|
232 self.productVersionLS, |
|
233 self.fileFlagsMask, |
|
234 self.fileFlags, |
|
235 self.fileOS, |
|
236 self.fileType, |
|
237 self.fileSubtype, |
|
238 self.fileDateMS, |
|
239 self.fileDateLS) |
|
240 def __repr__(self, indent=''): |
|
241 fv = (self.fileVersionMS >> 16, self.fileVersionMS & 0xffff, self.fileVersionLS >> 16, self.fileVersionLS & 0xFFFF) |
|
242 pv = (self.productVersionMS >> 16, self.productVersionMS & 0xffff, self.productVersionLS >> 16, self.productVersionLS & 0xFFFF) |
|
243 fd = (self.fileDateMS, self.fileDateLS) |
|
244 tmp = ["FixedFileInfo(", |
|
245 "filevers=%s," % (fv,), |
|
246 "prodvers=%s," % (pv,), |
|
247 "mask=%s," % hex(self.fileFlagsMask), |
|
248 "flags=%s," % hex(self.fileFlags), |
|
249 "OS=%s," % hex(self.fileOS), |
|
250 "fileType=%s," % hex(self.fileType), |
|
251 "subtype=%s," % hex(self.fileSubtype), |
|
252 "date=%s" % (fd,), |
|
253 ")" |
|
254 ] |
|
255 return string.join(tmp, '\n'+indent+' ') |
|
256 |
|
257 ##StringFileInfo { |
|
258 ## WORD wLength; // Specifies the length of the version resource |
|
259 ## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure |
|
260 ## WORD wType; // 1 means text, 0 means binary |
|
261 ## WCHAR szKey[]; // Contains the Unicode string "StringFileInfo". |
|
262 ## WORD Padding[]; |
|
263 ## StringTable Children[]; // Specifies a list of zero or more String structures |
|
264 ##}; |
|
265 |
|
266 class StringFileInfo: |
|
267 def __init__(self, kids=None): |
|
268 self.name = "StringFileInfo" |
|
269 if kids is None: |
|
270 self.kids = [] |
|
271 else: |
|
272 self.kids = kids |
|
273 def fromRaw(self, sublen, vallen, name, data, i, limit): |
|
274 self.name = name |
|
275 while i < limit: |
|
276 st = StringTable() |
|
277 j = st.fromRaw(data, i, limit) |
|
278 if TEST: |
|
279 if data[i:j] != st.toRaw(): |
|
280 rd = data[i:j] |
|
281 sd = st.toRaw() |
|
282 for x in range(0, len(rd), 16): |
|
283 rds = rd[x:x+16] |
|
284 sds = sd[x:x+16] |
|
285 if rds != sds: |
|
286 print "rd[%s:%s+16]: %s" % (x, x, `rds`) |
|
287 print "sd[%s:%s+16]: %s" % (x, x, `sds`) |
|
288 print |
|
289 print "raw: len %d, wLength %d" % (len(rd), struct.unpack('h', rd[:2])[0]) |
|
290 print " st: len %d, wLength %d" % (len(sd), struct.unpack('h', sd[:2])[0]) |
|
291 self.kids.append(st) |
|
292 i = j |
|
293 return i |
|
294 def toRaw(self): |
|
295 if type(self.name) is STRINGTYPE: |
|
296 self.name = pywintypes.Unicode(self.name) |
|
297 vallen = 0 |
|
298 typ = 1 |
|
299 sublen = 6 + 2*len(self.name) + 2 |
|
300 pad = '' |
|
301 if sublen % 4: |
|
302 pad = '\000\000' |
|
303 tmp = [] |
|
304 for kid in self.kids: |
|
305 tmp.append(kid.toRaw()) |
|
306 tmp = string.join(tmp, '') |
|
307 sublen = sublen + len(pad) + len(tmp) |
|
308 if tmp[-2:] == '\000\000': |
|
309 sublen = sublen - 2 |
|
310 return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + pad + tmp |
|
311 def __repr__(self, indent=''): |
|
312 tmp = [] |
|
313 newindent = indent + ' ' |
|
314 for kid in self.kids: |
|
315 tmp.append(kid.__repr__(newindent)) |
|
316 tmp = string.join(tmp, ', \n') |
|
317 return "%sStringFileInfo(\n%s[\n%s\n%s])" % (indent, newindent, tmp, newindent) |
|
318 |
|
319 ##StringTable { |
|
320 ## WORD wLength; |
|
321 ## WORD wValueLength; |
|
322 ## WORD wType; |
|
323 ## WCHAR szKey[]; |
|
324 ## String Children[]; // Specifies a list of zero or more String structures. |
|
325 ##}; |
|
326 |
|
327 class StringTable: |
|
328 def __init__(self, name=None, kids=None): |
|
329 self.name = name |
|
330 self.kids = kids |
|
331 if name is None: |
|
332 self.name = '' |
|
333 if kids is None: |
|
334 self.kids = [] |
|
335 def fromRaw(self, data, i, limit): |
|
336 #print "Parsing StringTable" |
|
337 i, (cpsublen, cpwValueLength, cpwType, self.name) = parseCodePage(data, i, limit) # should be code page junk |
|
338 #i = ((i + 3) / 4) * 4 |
|
339 while i < limit: |
|
340 ss = StringStruct() |
|
341 j = ss.fromRaw(data, i, limit) |
|
342 if TEST: |
|
343 if data[i:j] != ss.toRaw(): |
|
344 print "raw:", `data[i:j]` |
|
345 print " ss:", `ss.toRaw()` |
|
346 i = j |
|
347 self.kids.append(ss) |
|
348 i = ((i + 3) / 4) * 4 |
|
349 return i |
|
350 def toRaw(self): |
|
351 if type(self.name) is STRINGTYPE: |
|
352 self.name = pywintypes.Unicode(self.name) |
|
353 vallen = 0 |
|
354 typ = 1 |
|
355 sublen = 6 + 2*len(self.name) + 2 |
|
356 tmp = [] |
|
357 for kid in self.kids: |
|
358 raw = kid.toRaw() |
|
359 if len(raw) % 4: |
|
360 raw = raw + '\000\000' |
|
361 tmp.append(raw) |
|
362 tmp = string.join(tmp, '') |
|
363 sublen = sublen + len(tmp) |
|
364 if tmp[-2:] == '\000\000': |
|
365 sublen = sublen - 2 |
|
366 return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + tmp |
|
367 def __repr__(self, indent=''): |
|
368 tmp = [] |
|
369 newindent = indent + ' ' |
|
370 for kid in self.kids: |
|
371 tmp.append(repr(kid)) |
|
372 tmp = string.join(tmp, ',\n%s' % newindent) |
|
373 return "%sStringTable(\n%s'%s', \n%s[%s])" % (indent, newindent, str(self.name), newindent, tmp) |
|
374 |
|
375 ##String { |
|
376 ## WORD wLength; |
|
377 ## WORD wValueLength; |
|
378 ## WORD wType; |
|
379 ## WCHAR szKey[]; |
|
380 ## WORD Padding[]; |
|
381 ## String Value[]; |
|
382 ##}; |
|
383 |
|
384 class StringStruct: |
|
385 def __init__(self, name=None, val=None): |
|
386 self.name = name |
|
387 self.val = val |
|
388 if name is None: |
|
389 self.name = '' |
|
390 if val is None: |
|
391 self.val = '' |
|
392 def fromRaw(self, data, i, limit): |
|
393 i, (sublen, vallen, typ, self.name) = parseCommon(data, i) |
|
394 limit = i + sublen |
|
395 i = ((i + 3) / 4) * 4 |
|
396 i, self.val = parseUString(data, i, limit) |
|
397 return i |
|
398 def toRaw(self): |
|
399 if type(self.name) is STRINGTYPE: |
|
400 self.name = pywintypes.Unicode(self.name) |
|
401 if type(self.val) is STRINGTYPE: |
|
402 self.val = pywintypes.Unicode(self.val) |
|
403 vallen = len(self.val) + 1 |
|
404 typ = 1 |
|
405 sublen = 6 + 2*len(self.name) + 2 |
|
406 pad = '' |
|
407 if sublen % 4: |
|
408 pad = '\000\000' |
|
409 sublen = sublen + len(pad) + 2*vallen |
|
410 return struct.pack('hhh', sublen, vallen, typ) + getRaw(self.name) + '\000\000' + pad + getRaw(self.val) + '\000\000' |
|
411 def __repr__(self, indent=''): |
|
412 if pyvers < 20: |
|
413 return "StringStruct('%s', '%s')" % (str(self.name), str(self.val)) |
|
414 else: |
|
415 return "StringStruct('%s', '%s')" % (self.name, self.val) |
|
416 |
|
417 def parseCodePage(data, i, limit): |
|
418 #print "Parsing CodePage" |
|
419 i, (sublen, wValueLength, wType, nm) = parseCommon(data, i) |
|
420 #i = ((i + 3) / 4) * 4 |
|
421 return i, (sublen, wValueLength, wType, nm) |
|
422 |
|
423 ##VarFileInfo { |
|
424 ## WORD wLength; // Specifies the length of the version resource |
|
425 ## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure |
|
426 ## WORD wType; // 1 means text, 0 means binary |
|
427 ## WCHAR szKey[]; // Contains the Unicode string "VarFileInfo". |
|
428 ## WORD Padding[]; |
|
429 ## Var Children[]; // Specifies a list of zero or more Var structures |
|
430 ##}; |
|
431 |
|
432 class VarFileInfo: |
|
433 def __init__(self, kids=None): |
|
434 if kids is None: |
|
435 self.kids = [] |
|
436 else: |
|
437 self.kids = kids |
|
438 def fromRaw(self, sublen, vallen, name, data, i, limit): |
|
439 self.sublen = sublen |
|
440 self.vallen = vallen |
|
441 self.name = name |
|
442 i = ((i + 3) / 4) * 4 |
|
443 while i < limit: |
|
444 vs = VarStruct() |
|
445 j = vs.fromRaw(data, i, limit) |
|
446 self.kids.append(vs) |
|
447 if TEST: |
|
448 if data[i:j] != vs.toRaw(): |
|
449 print "raw:", `data[i:j]` |
|
450 print "cmp:", `vs.toRaw()` |
|
451 i = j |
|
452 return i |
|
453 def toRaw(self): |
|
454 self.vallen = 0 |
|
455 self.wType = 1 |
|
456 self.name = pywintypes.Unicode('VarFileInfo') |
|
457 sublen = 6 + 2*len(self.name) + 2 |
|
458 pad = '' |
|
459 if sublen % 4: |
|
460 pad = '\000\000' |
|
461 tmp = [] |
|
462 for kid in self.kids: |
|
463 tmp.append(kid.toRaw()) |
|
464 tmp = string.join(tmp, '') |
|
465 self.sublen = sublen + len(pad) + len(tmp) |
|
466 return struct.pack('hhh', self.sublen, self.vallen, self.wType) + getRaw(self.name) + '\000\000' + pad + tmp |
|
467 def __repr__(self, indent=''): |
|
468 tmp = map(repr, self.kids) |
|
469 return "%sVarFileInfo([%s])" % (indent, string.join(tmp, ', ')) |
|
470 |
|
471 ##Var { |
|
472 ## WORD wLength; // Specifies the length of the version resource |
|
473 ## WORD wValueLength; // Specifies the length of the Value member in the current VS_VERSION_INFO structure |
|
474 ## WORD wType; // 1 means text, 0 means binary |
|
475 ## WCHAR szKey[]; // Contains the Unicode string "Translation" or a user-defined key string value |
|
476 ## WORD Padding[]; // |
|
477 ## WORD Value[]; // Specifies a list of one or more values that are language and code-page identifiers |
|
478 ##}; |
|
479 |
|
480 STRINGTYPE = type('') |
|
481 |
|
482 class VarStruct: |
|
483 def __init__(self, name=None, kids=None): |
|
484 self.name = name |
|
485 self.kids = kids |
|
486 if name is None: |
|
487 self.name = '' |
|
488 if kids is None: |
|
489 self.kids = [] |
|
490 def fromRaw(self, data, i, limit): |
|
491 i, (self.sublen, self.wValueLength, self.wType, self.name) = parseCommon(data, i) |
|
492 i = ((i + 3) / 4) * 4 |
|
493 for j in range(self.wValueLength/2): |
|
494 kid = struct.unpack('h', data[i:i+2])[0] |
|
495 self.kids.append(kid) |
|
496 i = i + 2 |
|
497 return i |
|
498 def toRaw(self): |
|
499 self.wValueLength = len(self.kids) * 2 |
|
500 self.wType = 0 |
|
501 if type(self.name) is STRINGTYPE: |
|
502 self.name = pywintypes.Unicode(self.name) |
|
503 sublen = 6 + 2*len(self.name) + 2 |
|
504 pad = '' |
|
505 if sublen % 4: |
|
506 pad = '\000\000' |
|
507 self.sublen = sublen + len(pad) + self.wValueLength |
|
508 tmp = [] |
|
509 for kid in self.kids: |
|
510 tmp.append(struct.pack('h', kid)) |
|
511 tmp = string.join(tmp, '') |
|
512 return struct.pack('hhh', self.sublen, self.wValueLength, self.wType) + getRaw(self.name) + '\000\000' + pad + tmp |
|
513 def __repr__(self, indent=''): |
|
514 return "VarStruct('%s', %s)" % (str(self.name), repr(self.kids)) |
|
515 |
|
516 def SetVersion(exenm, versionfile): |
|
517 txt = open(versionfile, 'r').read() |
|
518 vs = eval(txt+'\n', globals()) |
|
519 hdst = win32api.BeginUpdateResource(exenm, 0) |
|
520 win32api.UpdateResource(hdst, RT_VERSION, 1, vs.toRaw()) |
|
521 win32api.EndUpdateResource (hdst, 0) |
|
522 |
|
523 if __name__ == '__main__': |
|
524 import sys |
|
525 TEST = 1 |
|
526 if len(sys.argv) < 2: |
|
527 decode('c:/Program Files/Netscape/Communicator/Program/netscape.exe') |
|
528 else: |
|
529 print "Examining", sys.argv[1] |
|
530 decode(sys.argv[1]) |
|
531 |