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

Last change on this file since 252 was 252, checked in by tim, 13 years ago

updated pyregfi to work with regfi changes
renamed some functions for more clarity
fixed some issues related to talloc_reference

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