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

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

added a lot of documentation for pyregfi and a few more attributes

File size: 11.1 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
15
16# XXX: can we always be sure enums are this size?
17REGFI_ENCODING = c_uint32
18REGFI_ENCODING_UTF8 = 1
19
20REGFI_DATA_TYPE = c_uint32
21REGFI_REGF_SIZE = 0x1000
22
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):
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()
63            # XXX: os.EX_IOERR may not be available on Windoze
64            set_errno(os.EX_IOERR)
65            return -1
66
67        return self.fh.tell()
68
69
70    def cb_read(self, raw_file, buf, count):
71        try:
72            # XXX: anyway to do a readinto() here?
73            tmp = self.fh.read(count)
74            memmove(buf,tmp,len(tmp))
75
76        except Exception:
77            traceback.print_exc()
78            # XXX: os.EX_IOERR may not be available on Windoze
79            set_errno(os.EX_IOERR)
80            return -1
81        return len(tmp)
82
83
84# XXX: how can we know for sure the size of off_t and size_t?
85seek_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
86read_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_uint64, use_errno=True)
87
88
89REGFI_NTTIME._fields_ = [('low', c_uint32),
90                         ('high', c_uint32)]
91
92REGFI_VK._fields_ = [('offset', c_uint32),
93                     ('cell_size', c_uint32),
94                     ('name', c_char_p),
95                     ('name_raw', POINTER(c_char)),
96                     ('name_length', c_uint16),
97                     ('hbin_off', c_uint32),
98                     ('data_size', c_uint32),
99                     ('data_off', c_uint32),
100                     ('type', REGFI_DATA_TYPE),
101                     ('magic', c_char * 2),
102                     ('flags', c_uint16),
103                     ('unknown1', c_uint16),
104                     ('data_in_offset', c_bool),
105                     ]
106
107
108REGFI_SK._fields_ = [('offset', c_uint32),
109                     ('cell_size', c_uint32),
110                     ('sec_desc', c_void_p), #XXX
111                     ('hbin_off', c_uint32),
112                     ('prev_sk_off', c_uint32),
113                     ('next_sk_off', c_uint32),
114                     ('ref_count', c_uint32),
115                     ('desc_size', c_uint32),
116                     ('unknown_tag', c_uint16),
117                     ('magic', c_char * 2),
118                     ]
119
120
121REGFI_NK._fields_ = [('offset', c_uint32),
122                     ('cell_size', c_uint32),
123                     ('values', POINTER(REGFI_VALUE_LIST)),
124                     ('subkeys', POINTER(REGFI_SUBKEY_LIST)),
125                     ('flags', c_uint16),
126                     ('magic', c_char * 2),
127                     ('mtime', REGFI_NTTIME),
128                     ('name_length', c_uint16),
129                     ('classname_length', c_uint16),
130                     ('name', c_char_p),
131                     ('name_raw', POINTER(c_char)),
132                     ('parent_off', c_uint32),
133                     ('classname_off', c_uint32),
134                     ('max_bytes_subkeyname', c_uint32),
135                     ('max_bytes_subkeyclassname', c_uint32),
136                     ('max_bytes_valuename', c_uint32),
137                     ('max_bytes_value', c_uint32),
138                     ('unknown1', c_uint32),
139                     ('unknown2', c_uint32),
140                     ('unknown3', c_uint32),
141                     ('unk_index', c_uint32),
142                     ('num_subkeys', c_uint32),
143                     ('subkeys_off', c_uint32),
144                     ('num_values', c_uint32),
145                     ('values_off', c_uint32),
146                     ('sk_off', c_uint32),
147                     ]
148
149
150REGFI_SUBKEY_LIST._fields_ = [('offset', c_uint32),
151                              ('cell_size', c_uint32),
152                              ('num_children', c_uint32),
153                              ('num_keys', c_uint32),
154                              ('elements', c_void_p),
155                              ('magic', c_char * 2),
156                              ('recursive_type', c_bool),
157                              ]
158
159
160REGFI_VALUE_LIST._fields_ = [('offset', c_uint32),
161                             ('cell_size', c_uint32),
162                             ('num_children', c_uint32),
163                             ('num_values', c_uint32),
164                             ('elements', c_void_p),
165                             ]
166
167REGFI_CLASSNAME._fields_ = [('offset', c_uint32),
168                            ('interpreted', c_char_p),
169                            ('raw', POINTER(c_char)),
170                            ('size', c_uint16),
171                            ]
172
173
174class REGFI_DATA__interpreted(Union):
175    _fields_ = [('none',POINTER(c_char)),
176                ('string', c_char_p),
177                ('expand_string', c_char_p),
178                ('binary',POINTER(c_char)),
179                ('dword', c_uint32),
180                ('dword_be', c_uint32),
181                ('link', c_char_p),
182                ('multiple_string', POINTER(c_char_p)),
183                ('qword', c_uint64),
184                ('resource_list',POINTER(c_char)),
185                ('full_resource_descriptor',POINTER(c_char)),
186                ('resource_requirements_list',POINTER(c_char)),
187                ]
188REGFI_DATA._fields_ = [('offset', c_uint32),
189                       ('type', REGFI_DATA_TYPE),
190                       ('size', c_uint32),
191                       ('raw', POINTER(c_char)),
192                       ('interpreted_size', c_uint32),
193                       ('interpreted', REGFI_DATA__interpreted),
194                       ]
195
196
197REGFI_FILE._fields_ = [('magic', c_char * 4),
198                       ('sequence1', c_uint32),
199                       ('sequence2', c_uint32),
200                       ('mtime', REGFI_NTTIME),
201                       ('major_version', c_uint32),
202                       ('minor_version', c_uint32),
203                       ('type', c_uint32),
204                       ('format', c_uint32),
205                       ('root_cell', c_uint32),
206                       ('last_block', c_uint32),
207                       ('cluster', c_uint32),
208                       ]
209
210
211REGFI_RAW_FILE._fields_ = [('seek', seek_cb_type),
212                           ('read', read_cb_type),
213                           ('cur_off', c_uint64),
214                           ('size', c_uint64),
215                           ('state', c_void_p),
216                           ]
217
218
219# Load libregfi and define function prototypes
220regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
221
222regfi.regfi_alloc.argtypes = [c_int, REGFI_ENCODING]
223regfi.regfi_alloc.restype = POINTER(REGFI_FILE)
224
225regfi.regfi_alloc_cb.argtypes = [POINTER(REGFI_RAW_FILE), REGFI_ENCODING]
226regfi.regfi_alloc_cb.restype = POINTER(REGFI_FILE)
227
228regfi.regfi_free.argtypes = [POINTER(REGFI_FILE)]
229regfi.regfi_free.restype = None
230
231regfi.regfi_log_get_str.argtypes = []
232regfi.regfi_log_get_str.restype = c_char_p
233
234regfi.regfi_log_set_mask.argtypes = [c_uint16]
235regfi.regfi_log_set_mask.restype = c_bool
236
237regfi.regfi_get_rootkey.argtypes = [POINTER(REGFI_FILE)]
238regfi.regfi_get_rootkey.restype = POINTER(REGFI_NK)
239
240regfi.regfi_free_record.argtypes = [c_void_p]
241regfi.regfi_free_record.restype = None
242
243regfi.regfi_fetch_num_subkeys.argtypes = [POINTER(REGFI_NK)]
244regfi.regfi_fetch_num_subkeys.restype = c_uint32
245
246regfi.regfi_fetch_num_values.argtypes = [POINTER(REGFI_NK)]
247regfi.regfi_fetch_num_values.restype = c_uint32
248
249regfi.regfi_fetch_classname.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
250regfi.regfi_fetch_classname.restype = POINTER(REGFI_CLASSNAME)
251
252regfi.regfi_fetch_sk.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
253regfi.regfi_fetch_sk.restype = POINTER(REGFI_SK)
254
255regfi.regfi_fetch_data.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_VK)]
256regfi.regfi_fetch_data.restype = POINTER(REGFI_DATA)
257
258regfi.regfi_find_subkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
259                                    c_char_p, POINTER(c_uint32)]
260regfi.regfi_find_subkey.restype = c_bool
261
262regfi.regfi_find_value.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
263                                    c_char_p, POINTER(c_uint32)]
264regfi.regfi_find_value.restype = c_bool
265
266regfi.regfi_get_subkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
267                                   c_uint32]
268regfi.regfi_get_subkey.restype = POINTER(REGFI_NK)
269
270regfi.regfi_get_value.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK),
271                                   c_uint32]
272regfi.regfi_get_value.restype = POINTER(REGFI_VK)
273
274regfi.regfi_get_parentkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
275regfi.regfi_get_parentkey.restype = POINTER(REGFI_NK)
276
277regfi.regfi_nt2unix_time.argtypes = [POINTER(REGFI_NTTIME)]
278regfi.regfi_nt2unix_time.restype = c_double
279
280regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE), REGFI_ENCODING]
281regfi.regfi_iterator_new.restype = POINTER(REGFI_ITERATOR)
282
283regfi.regfi_iterator_free.argtypes = [POINTER(REGFI_ITERATOR)]
284regfi.regfi_iterator_free.restype = None
285
286regfi.regfi_iterator_down.argtypes = [POINTER(REGFI_ITERATOR)]
287regfi.regfi_iterator_down.restype = c_bool
288
289regfi.regfi_iterator_up.argtypes = [POINTER(REGFI_ITERATOR)]
290regfi.regfi_iterator_up.restype = c_bool
291
292regfi.regfi_iterator_to_root.argtypes = [POINTER(REGFI_ITERATOR)]
293regfi.regfi_iterator_to_root.restype = c_bool
294
295regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR)]
296regfi.regfi_iterator_walk_path.restype = c_bool
297
298regfi.regfi_iterator_cur_key.argtypes = [POINTER(REGFI_ITERATOR)]
299regfi.regfi_iterator_cur_key.restype = POINTER(REGFI_NK)
300
301regfi.regfi_iterator_first_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
302regfi.regfi_iterator_first_subkey.restype = c_bool
303
304regfi.regfi_iterator_cur_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
305regfi.regfi_iterator_cur_subkey.restype = POINTER(REGFI_NK)
306
307regfi.regfi_iterator_next_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
308regfi.regfi_iterator_next_subkey.restype = c_bool
309
310regfi.regfi_iterator_find_subkey.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
311regfi.regfi_iterator_find_subkey.restype = c_bool
312
313regfi.regfi_iterator_first_value.argtypes = [POINTER(REGFI_ITERATOR)]
314regfi.regfi_iterator_first_value.restype = c_bool
315
316regfi.regfi_iterator_cur_value.argtypes = [POINTER(REGFI_ITERATOR)]
317regfi.regfi_iterator_cur_value.restype = POINTER(REGFI_VK)
318
319regfi.regfi_iterator_next_value.argtypes = [POINTER(REGFI_ITERATOR)]
320regfi.regfi_iterator_next_value.restype = c_bool
321
322regfi.regfi_iterator_find_value.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
323regfi.regfi_iterator_find_value.restype = c_bool
324
325
326regfi.regfi_init.argtypes = []
327regfi.regfi_init.restype = None
328regfi.regfi_init()
Note: See TracBrowser for help on using the repository browser.