source: trunk/python/pyregfi/structures.py@ 243

Last change on this file since 243 was 233, checked in by tim, 14 years ago

improved version information interface by adding a special purpose function

File size: 11.6 KB
RevLine 
[204]1#!/usr/bin/env python
2
[221]3## @package pyregfi.structures
4# Low-level data structures and C API mappings.
5#
6# Most users need not venture here. For more information, see the source.
7
[204]8import sys
9import os
10import traceback
11import ctypes
12import ctypes.util
[205]13from ctypes import *
[204]14
[226]15is_win32 = hasattr(ctypes, 'windll')
[221]16
[205]17# XXX: can we always be sure enums are this size?
18REGFI_ENCODING = c_uint32
[227]19REGFI_ENCODING_UTF8 = REGFI_ENCODING(1)
[213]20
[205]21REGFI_DATA_TYPE = c_uint32
[204]22
[205]23
24# Prototype everything first so we don't have to worry about reference order
25class REGFI_NTTIME(Structure):
26 pass
27
28class REGFI_VK(Structure):
29 pass
30
31class REGFI_SK(Structure):
32 pass
33
34class REGFI_SUBKEY_LIST(Structure):
35 pass
36
37class REGFI_VALUE_LIST(Structure):
38 pass
39
40class REGFI_CLASSNAME(Structure):
41 pass
42
43class REGFI_DATA(Structure):
44 pass
45
46class REGFI_NK(Structure):
47 pass
48
49class REGFI_ITERATOR(Structure):
50 pass
51
52class REGFI_FILE(Structure):
53 pass
54
55class REGFI_RAW_FILE(Structure):
[204]56 fh = None
57
58 def cb_seek(self, raw_file, offset, whence):
59 try:
60 self.fh.seek(offset, whence)
61 except Exception:
62 traceback.print_exc()
[226]63 set_errno(74) # os.EX_IOERR
[204]64 return -1
65
66 return self.fh.tell()
67
68
69 def cb_read(self, raw_file, buf, count):
70 try:
71 # XXX: anyway to do a readinto() here?
72 tmp = self.fh.read(count)
[205]73 memmove(buf,tmp,len(tmp))
[204]74
75 except Exception:
76 traceback.print_exc()
[226]77 set_errno(74) # os.EX_IOERR
[204]78 return -1
79 return len(tmp)
80
81
[225]82# Load libregfi according to platform
83regfi = None
[226]84if is_win32:
85 # XXX: Using C calling conventions on cross-compiled DLLs seems to work fine
86 # on Windows, but I'm not sure if stdcall symbols are supported
87 # correctly for native Windows binaries...
[225]88 #regfi = ctypes.windll.libregfi
[226]89 #CB_FACTORY = ctypes.WINFUNCTYPE
90 regfi = ctypes.CDLL('libregfi.dll', use_errno=True)
91 CB_FACTORY = ctypes.CFUNCTYPE
[225]92else:
93 regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
94 CB_FACTORY = ctypes.CFUNCTYPE
[204]95
[226]96seek_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
97read_cb_type = CB_FACTORY(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_size_t, use_errno=True)
[204]98
[225]99
[205]100REGFI_NTTIME._fields_ = [('low', c_uint32),
101 ('high', c_uint32)]
102
103REGFI_VK._fields_ = [('offset', c_uint32),
104 ('cell_size', c_uint32),
[206]105 ('name', c_char_p),
106 ('name_raw', POINTER(c_char)),
[205]107 ('name_length', c_uint16),
108 ('hbin_off', c_uint32),
109 ('data_size', c_uint32),
110 ('data_off', c_uint32),
111 ('type', REGFI_DATA_TYPE),
112 ('magic', c_char * 2),
113 ('flags', c_uint16),
114 ('unknown1', c_uint16),
115 ('data_in_offset', c_bool),
116 ]
117
118
119REGFI_SK._fields_ = [('offset', c_uint32),
120 ('cell_size', c_uint32),
121 ('sec_desc', c_void_p), #XXX
122 ('hbin_off', c_uint32),
123 ('prev_sk_off', c_uint32),
124 ('next_sk_off', c_uint32),
125 ('ref_count', c_uint32),
126 ('desc_size', c_uint32),
127 ('unknown_tag', c_uint16),
128 ('magic', c_char * 2),
129 ]
130
131
132REGFI_NK._fields_ = [('offset', c_uint32),
133 ('cell_size', c_uint32),
134 ('values', POINTER(REGFI_VALUE_LIST)),
135 ('subkeys', POINTER(REGFI_SUBKEY_LIST)),
136 ('flags', c_uint16),
137 ('magic', c_char * 2),
138 ('mtime', REGFI_NTTIME),
139 ('name_length', c_uint16),
140 ('classname_length', c_uint16),
[206]141 ('name', c_char_p),
142 ('name_raw', POINTER(c_char)),
[205]143 ('parent_off', c_uint32),
144 ('classname_off', c_uint32),
145 ('max_bytes_subkeyname', c_uint32),
146 ('max_bytes_subkeyclassname', c_uint32),
147 ('max_bytes_valuename', c_uint32),
148 ('max_bytes_value', c_uint32),
149 ('unknown1', c_uint32),
150 ('unknown2', c_uint32),
151 ('unknown3', c_uint32),
152 ('unk_index', c_uint32),
153 ('num_subkeys', c_uint32),
154 ('subkeys_off', c_uint32),
155 ('num_values', c_uint32),
156 ('values_off', c_uint32),
157 ('sk_off', c_uint32),
158 ]
159
160
161REGFI_SUBKEY_LIST._fields_ = [('offset', c_uint32),
162 ('cell_size', c_uint32),
163 ('num_children', c_uint32),
164 ('num_keys', c_uint32),
165 ('elements', c_void_p),
166 ('magic', c_char * 2),
167 ('recursive_type', c_bool),
168 ]
169
170
171REGFI_VALUE_LIST._fields_ = [('offset', c_uint32),
172 ('cell_size', c_uint32),
173 ('num_values', c_uint32),
174 ('elements', c_void_p),
175 ]
176
177REGFI_CLASSNAME._fields_ = [('offset', c_uint32),
178 ('interpreted', c_char_p),
179 ('raw', POINTER(c_char)),
180 ('size', c_uint16),
181 ]
182
183
184class REGFI_DATA__interpreted(Union):
185 _fields_ = [('none',POINTER(c_char)),
186 ('string', c_char_p),
187 ('expand_string', c_char_p),
188 ('binary',POINTER(c_char)),
189 ('dword', c_uint32),
190 ('dword_be', c_uint32),
191 ('link', c_char_p),
192 ('multiple_string', POINTER(c_char_p)),
193 ('qword', c_uint64),
194 ('resource_list',POINTER(c_char)),
195 ('full_resource_descriptor',POINTER(c_char)),
196 ('resource_requirements_list',POINTER(c_char)),
[209]197 ]
[205]198REGFI_DATA._fields_ = [('offset', c_uint32),
199 ('type', REGFI_DATA_TYPE),
200 ('size', c_uint32),
201 ('raw', POINTER(c_char)),
202 ('interpreted_size', c_uint32),
203 ('interpreted', REGFI_DATA__interpreted),
204 ]
205
[209]206
[205]207REGFI_FILE._fields_ = [('magic', c_char * 4),
208 ('sequence1', c_uint32),
209 ('sequence2', c_uint32),
210 ('mtime', REGFI_NTTIME),
211 ('major_version', c_uint32),
212 ('minor_version', c_uint32),
213 ('type', c_uint32),
214 ('format', c_uint32),
215 ('root_cell', c_uint32),
216 ('last_block', c_uint32),
217 ('cluster', c_uint32),
218 ]
219
220
[204]221REGFI_RAW_FILE._fields_ = [('seek', seek_cb_type),
222 ('read', read_cb_type),
223 ('cur_off', c_uint64),
224 ('size', c_uint64),
225 ('state', c_void_p),
226 ]
[220]227
228
[225]229# Define function prototypes
[233]230regfi.regfi_version.argtypes = []
231regfi.regfi_version.restype = c_char_p
232
[220]233regfi.regfi_alloc.argtypes = [c_int, REGFI_ENCODING]
234regfi.regfi_alloc.restype = POINTER(REGFI_FILE)
235
236regfi.regfi_alloc_cb.argtypes = [POINTER(REGFI_RAW_FILE), REGFI_ENCODING]
237regfi.regfi_alloc_cb.restype = POINTER(REGFI_FILE)
238
239regfi.regfi_free.argtypes = [POINTER(REGFI_FILE)]
240regfi.regfi_free.restype = None
241
242regfi.regfi_log_get_str.argtypes = []
243regfi.regfi_log_get_str.restype = c_char_p
244
245regfi.regfi_log_set_mask.argtypes = [c_uint16]
246regfi.regfi_log_set_mask.restype = c_bool
247
248regfi.regfi_get_rootkey.argtypes = [POINTER(REGFI_FILE)]
249regfi.regfi_get_rootkey.restype = POINTER(REGFI_NK)
250
[228]251regfi.regfi_free_record.argtypes = [POINTER(REGFI_FILE), c_void_p]
[220]252regfi.regfi_free_record.restype = None
253
[228]254regfi.regfi_reference_record.argtypes = [POINTER(REGFI_FILE), c_void_p]
[224]255regfi.regfi_reference_record.restype = c_bool
256
[220]257regfi.regfi_fetch_num_subkeys.argtypes = [POINTER(REGFI_NK)]
258regfi.regfi_fetch_num_subkeys.restype = c_uint32
259
260regfi.regfi_fetch_num_values.argtypes = [POINTER(REGFI_NK)]
261regfi.regfi_fetch_num_values.restype = c_uint32
262
263regfi.regfi_fetch_classname.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
264regfi.regfi_fetch_classname.restype = POINTER(REGFI_CLASSNAME)
265
266regfi.regfi_fetch_sk.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
267regfi.regfi_fetch_sk.restype = POINTER(REGFI_SK)
268
269regfi.regfi_fetch_data.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_VK)]
270regfi.regfi_fetch_data.restype = POINTER(REGFI_DATA)
271
272regfi.regfi_find_subkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
273 c_char_p, POINTER(c_uint32)]
274regfi.regfi_find_subkey.restype = c_bool
275
276regfi.regfi_find_value.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
277 c_char_p, POINTER(c_uint32)]
278regfi.regfi_find_value.restype = c_bool
279
280regfi.regfi_get_subkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
281 c_uint32]
282regfi.regfi_get_subkey.restype = POINTER(REGFI_NK)
283
284regfi.regfi_get_value.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
285 c_uint32]
286regfi.regfi_get_value.restype = POINTER(REGFI_VK)
287
288regfi.regfi_get_parentkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
289regfi.regfi_get_parentkey.restype = POINTER(REGFI_NK)
290
291regfi.regfi_nt2unix_time.argtypes = [POINTER(REGFI_NTTIME)]
292regfi.regfi_nt2unix_time.restype = c_double
293
[228]294regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE)]
[220]295regfi.regfi_iterator_new.restype = POINTER(REGFI_ITERATOR)
296
297regfi.regfi_iterator_free.argtypes = [POINTER(REGFI_ITERATOR)]
298regfi.regfi_iterator_free.restype = None
299
300regfi.regfi_iterator_down.argtypes = [POINTER(REGFI_ITERATOR)]
301regfi.regfi_iterator_down.restype = c_bool
302
303regfi.regfi_iterator_up.argtypes = [POINTER(REGFI_ITERATOR)]
304regfi.regfi_iterator_up.restype = c_bool
305
306regfi.regfi_iterator_to_root.argtypes = [POINTER(REGFI_ITERATOR)]
307regfi.regfi_iterator_to_root.restype = c_bool
308
[228]309regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR), POINTER(c_char_p)]
[220]310regfi.regfi_iterator_walk_path.restype = c_bool
311
312regfi.regfi_iterator_cur_key.argtypes = [POINTER(REGFI_ITERATOR)]
313regfi.regfi_iterator_cur_key.restype = POINTER(REGFI_NK)
314
315regfi.regfi_iterator_first_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
316regfi.regfi_iterator_first_subkey.restype = c_bool
317
318regfi.regfi_iterator_cur_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
319regfi.regfi_iterator_cur_subkey.restype = POINTER(REGFI_NK)
320
321regfi.regfi_iterator_next_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
322regfi.regfi_iterator_next_subkey.restype = c_bool
323
324regfi.regfi_iterator_find_subkey.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
325regfi.regfi_iterator_find_subkey.restype = c_bool
326
327regfi.regfi_iterator_first_value.argtypes = [POINTER(REGFI_ITERATOR)]
328regfi.regfi_iterator_first_value.restype = c_bool
329
330regfi.regfi_iterator_cur_value.argtypes = [POINTER(REGFI_ITERATOR)]
331regfi.regfi_iterator_cur_value.restype = POINTER(REGFI_VK)
332
333regfi.regfi_iterator_next_value.argtypes = [POINTER(REGFI_ITERATOR)]
334regfi.regfi_iterator_next_value.restype = c_bool
335
336regfi.regfi_iterator_find_value.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
337regfi.regfi_iterator_find_value.restype = c_bool
338
339
340regfi.regfi_init.argtypes = []
341regfi.regfi_init.restype = None
342regfi.regfi_init()
Note: See TracBrowser for help on using the repository browser.