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

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

improvements to smoketest script, additional test case
added a function to get a key's parent in both regfi and pyregfi
bug fixes

File size: 7.4 KB
RevLine 
[204]1#!/usr/bin/env python
2
3import sys
4import os
5import traceback
6import ctypes
7import ctypes.util
[205]8from ctypes import *
[204]9
[205]10# XXX: can we always be sure enums are this size?
11REGFI_ENCODING = c_uint32
[213]12REGFI_ENCODING_UTF8 = 1
13
[205]14REGFI_DATA_TYPE = c_uint32
[215]15REGFI_REGF_SIZE = 0x1000 
[204]16
[209]17# Registry value data types
18REG_NONE                       =  0
19REG_SZ                         =  1
20REG_EXPAND_SZ                  =  2
21REG_BINARY                     =  3
22REG_DWORD                      =  4
23REG_DWORD_LE                   =  4 # DWORD, little endian
24REG_DWORD_BE                   =  5 # DWORD, big endian
25REG_LINK                       =  6
26REG_MULTI_SZ                   =  7
27REG_RESOURCE_LIST              =  8
28REG_FULL_RESOURCE_DESCRIPTOR   =  9
29REG_RESOURCE_REQUIREMENTS_LIST = 10
30REG_QWORD                      = 11 # 64-bit little endian
[205]31
[209]32
[205]33# Prototype everything first so we don't have to worry about reference order
34class REGFI_NTTIME(Structure):
35    pass
36
37class REGFI_VK(Structure):
38    pass
39
40class REGFI_SK(Structure):
41    pass
42
43class REGFI_SUBKEY_LIST(Structure):
44    pass
45
46class REGFI_VALUE_LIST(Structure):
47    pass
48
49class REGFI_CLASSNAME(Structure):
50    pass
51
52class REGFI_DATA(Structure):
53    pass
54
55class REGFI_NK(Structure):
56    pass
57
58class REGFI_ITERATOR(Structure):
59    pass
60
61class REGFI_FILE(Structure):
62    pass
63
64class REGFI_RAW_FILE(Structure):
[204]65    fh = None
66   
67    def cb_seek(self, raw_file, offset, whence):
68        try:
69            self.fh.seek(offset, whence)
70        except Exception:
71            traceback.print_exc()
72            # XXX: os.EX_IOERR may not be available on Windoze
[205]73            set_errno(os.EX_IOERR)
[204]74            return -1
75
76        return self.fh.tell()
77
78
79    def cb_read(self, raw_file, buf, count):
80        try:
81            # XXX: anyway to do a readinto() here?
82            tmp = self.fh.read(count)
[205]83            memmove(buf,tmp,len(tmp))
[204]84
85        except Exception:
86            traceback.print_exc()
87            # XXX: os.EX_IOERR may not be available on Windoze
[205]88            set_errno(os.EX_IOERR)
[204]89            return -1
90        return len(tmp)
91
92
93# XXX: how can we know for sure the size of off_t and size_t?
[205]94seek_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), c_uint64, c_int, use_errno=True)
95read_cb_type = CFUNCTYPE(c_int64, POINTER(REGFI_RAW_FILE), POINTER(c_char), c_uint64, use_errno=True)
[204]96
97
[205]98REGFI_NTTIME._fields_ = [('low', c_uint32),
99                         ('high', c_uint32)]
100
101REGFI_VK._fields_ = [('offset', c_uint32),
102                     ('cell_size', c_uint32),
[206]103                     ('name', c_char_p),
104                     ('name_raw', POINTER(c_char)),
[205]105                     ('name_length', c_uint16),
106                     ('hbin_off', c_uint32),
107                     ('data_size', c_uint32),
108                     ('data_off', c_uint32),
109                     ('type', REGFI_DATA_TYPE),
110                     ('magic', c_char * 2),
111                     ('flags', c_uint16),
112                     ('unknown1', c_uint16),
113                     ('data_in_offset', c_bool),
114                     ]
115
116
117REGFI_SK._fields_ = [('offset', c_uint32),
118                     ('cell_size', c_uint32),
119                     ('sec_desc', c_void_p), #XXX
120                     ('hbin_off', c_uint32),
121                     ('prev_sk_off', c_uint32),
122                     ('next_sk_off', c_uint32),
123                     ('ref_count', c_uint32),
124                     ('desc_size', c_uint32),
125                     ('unknown_tag', c_uint16),
126                     ('magic', c_char * 2),
127                     ]
128
129
130REGFI_NK._fields_ = [('offset', c_uint32),
131                     ('cell_size', c_uint32),
132                     ('values', POINTER(REGFI_VALUE_LIST)),
133                     ('subkeys', POINTER(REGFI_SUBKEY_LIST)),
134                     ('flags', c_uint16),
135                     ('magic', c_char * 2),
136                     ('mtime', REGFI_NTTIME),
137                     ('name_length', c_uint16),
138                     ('classname_length', c_uint16),
[206]139                     ('name', c_char_p),
140                     ('name_raw', POINTER(c_char)),
[205]141                     ('parent_off', c_uint32),
142                     ('classname_off', c_uint32),
143                     ('max_bytes_subkeyname', c_uint32),
144                     ('max_bytes_subkeyclassname', c_uint32),
145                     ('max_bytes_valuename', c_uint32),
146                     ('max_bytes_value', c_uint32),
147                     ('unknown1', c_uint32),
148                     ('unknown2', c_uint32),
149                     ('unknown3', c_uint32),
150                     ('unk_index', c_uint32),
151                     ('num_subkeys', c_uint32),
152                     ('subkeys_off', c_uint32),
153                     ('num_values', c_uint32),
154                     ('values_off', c_uint32),
155                     ('sk_off', c_uint32),
156                     ]
157
158
159REGFI_SUBKEY_LIST._fields_ = [('offset', c_uint32),
160                              ('cell_size', c_uint32),
161                              ('num_children', c_uint32),
162                              ('num_keys', c_uint32),
163                              ('elements', c_void_p),
164                              ('magic', c_char * 2),
165                              ('recursive_type', c_bool),
166                              ]
167
168
169REGFI_VALUE_LIST._fields_ = [('offset', c_uint32),
170                             ('cell_size', c_uint32),
171                             ('num_children', c_uint32),
172                             ('num_values', c_uint32),
173                             ('elements', c_void_p),
174                             ]
175
176REGFI_CLASSNAME._fields_ = [('offset', c_uint32),
177                            ('interpreted', c_char_p),
178                            ('raw', POINTER(c_char)),
179                            ('size', c_uint16),
180                            ]
181
182
183class REGFI_DATA__interpreted(Union):
184    _fields_ = [('none',POINTER(c_char)),
185                ('string', c_char_p),
186                ('expand_string', c_char_p),
187                ('binary',POINTER(c_char)),
188                ('dword', c_uint32),
189                ('dword_be', c_uint32),
190                ('link', c_char_p),
191                ('multiple_string', POINTER(c_char_p)),
192                ('qword', c_uint64),
193                ('resource_list',POINTER(c_char)),
194                ('full_resource_descriptor',POINTER(c_char)),
195                ('resource_requirements_list',POINTER(c_char)),
[209]196                ]
[205]197REGFI_DATA._fields_ = [('offset', c_uint32),
198                       ('type', REGFI_DATA_TYPE),
199                       ('size', c_uint32),
200                       ('raw', POINTER(c_char)),
201                       ('interpreted_size', c_uint32),
202                       ('interpreted', REGFI_DATA__interpreted),
203                       ]
204
[209]205
[205]206REGFI_FILE._fields_ = [('magic', c_char * 4),
207                       ('sequence1', c_uint32),
208                       ('sequence2', c_uint32),
209                       ('mtime', REGFI_NTTIME),
210                       ('major_version', c_uint32),
211                       ('minor_version', c_uint32),
212                       ('type', c_uint32),
213                       ('format', c_uint32),
214                       ('root_cell', c_uint32),
215                       ('last_block', c_uint32),
216                       ('cluster', c_uint32),
217                       ]
218
219
[204]220REGFI_RAW_FILE._fields_ = [('seek', seek_cb_type),
221                           ('read', read_cb_type),
222                           ('cur_off', c_uint64),
223                           ('size', c_uint64),
224                           ('state', c_void_p),
225                           ]
Note: See TracBrowser for help on using the repository browser.