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
Line 
1#!/usr/bin/env python
2
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
8import sys
9import os
10import traceback
11import ctypes
12import ctypes.util
13from ctypes import *
14
15is_win32 = hasattr(ctypes, 'windll')
16
17# XXX: can we always be sure enums are this size?
18REGFI_ENCODING = c_uint32
19REGFI_ENCODING_UTF8 = REGFI_ENCODING(1)
20
21REGFI_DATA_TYPE = c_uint32
22REGFI_NTTIME = c_uint64
23
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):
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()
60            set_errno(74) # os.EX_IOERR
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)
70            memmove(buf,tmp,len(tmp))
71
72        except Exception:
73            traceback.print_exc()
74            set_errno(74) # os.EX_IOERR
75            return -1
76        return len(tmp)
77
78
79# Load libregfi according to platform
80regfi = None
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...
85    #regfi = ctypes.windll.libregfi
86    #CB_FACTORY = ctypes.WINFUNCTYPE
87    regfi = ctypes.CDLL('libregfi.dll', use_errno=True)
88    CB_FACTORY = ctypes.CFUNCTYPE
89else:
90    regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
91    CB_FACTORY = ctypes.CFUNCTYPE
92
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)
95
96
97REGFI_VK._fields_ = [('offset', c_uint32),
98                     ('cell_size', c_uint32),
99                     ('name', c_char_p),
100                     ('name_raw', POINTER(c_char)),
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),
135                     ('name', c_char_p),
136                     ('name_raw', POINTER(c_char)),
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)),
191                ]
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
200
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
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                           ]
221
222
223# Define function prototypes
224regfi.regfi_version.argtypes = []
225regfi.regfi_version.restype = c_char_p
226
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
245regfi.regfi_free_record.argtypes = [POINTER(REGFI_FILE), c_void_p]
246regfi.regfi_free_record.restype = None
247
248regfi.regfi_reference_record.argtypes = [POINTER(REGFI_FILE), c_void_p]
249regfi.regfi_reference_record.restype = c_void_p
250
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
288regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE)]
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
303regfi.regfi_iterator_descend.argtypes = [POINTER(REGFI_ITERATOR), POINTER(c_char_p)]
304regfi.regfi_iterator_descend.restype = c_bool
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
333regfi.regfi_iterator_ancestry.argtypes = [POINTER(REGFI_ITERATOR)]
334regfi.regfi_iterator_ancestry.restype = POINTER(POINTER(REGFI_NK))
335
336regfi.regfi_init.argtypes = []
337regfi.regfi_init.restype = None
338regfi.regfi_init()
Note: See TracBrowser for help on using the repository browser.