source: trunk/python/pyregfi/__init__.py @ 206

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

simplified part of regfi API to move string encoding to the REGFI_FILE object

additional pyregfi implementation

File size: 6.9 KB
Line 
1#!/usr/bin/env python
2
3import sys
4from pyregfi.structures import *
5
6import ctypes
7import ctypes.util
8from ctypes import c_char,c_char_p,c_int,c_uint16,c_bool,POINTER
9
10regfi = ctypes.CDLL(ctypes.util.find_library('regfi'), use_errno=True)
11
12
13regfi.regfi_alloc.argtypes = [c_int]
14regfi.regfi_alloc.restype = POINTER(REGFI_FILE)
15
16regfi.regfi_alloc_cb.argtypes = [POINTER(REGFI_RAW_FILE)]
17regfi.regfi_alloc_cb.restype = POINTER(REGFI_FILE)
18
19regfi.regfi_free.argtypes = [POINTER(REGFI_FILE)]
20regfi.regfi_free.restype = None
21
22regfi.regfi_log_get_str.argtypes = []
23regfi.regfi_log_get_str.restype = c_char_p
24
25regfi.regfi_log_set_mask.argtypes = [c_uint16]
26regfi.regfi_log_set_mask.restype = c_bool
27
28regfi.regfi_free_record.argtypes = [c_void_p]
29regfi.regfi_free_record.restype = None
30
31regfi.regfi_fetch_classname.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
32regfi.regfi_fetch_classname.restype = POINTER(REGFI_CLASSNAME)
33
34regfi.regfi_fetch_sk.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
35regfi.regfi_fetch_sk.restype = POINTER(REGFI_SK)
36
37regfi.regfi_fetch_data.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_VK)]
38regfi.regfi_fetch_data.restype = POINTER(REGFI_DATA)
39
40regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE), REGFI_ENCODING]
41regfi.regfi_iterator_new.restype = POINTER(REGFI_ITERATOR)
42
43regfi.regfi_iterator_free.argtypes = [POINTER(REGFI_ITERATOR)]
44regfi.regfi_iterator_free.restype = None
45
46regfi.regfi_iterator_down.argtypes = [POINTER(REGFI_ITERATOR)]
47regfi.regfi_iterator_down.restype = c_bool
48
49regfi.regfi_iterator_up.argtypes = [POINTER(REGFI_ITERATOR)]
50regfi.regfi_iterator_up.restype = c_bool
51
52regfi.regfi_iterator_to_root.argtypes = [POINTER(REGFI_ITERATOR)]
53regfi.regfi_iterator_to_root.restype = c_bool
54
55regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR)]
56regfi.regfi_iterator_walk_path.restype = c_bool
57
58regfi.regfi_iterator_cur_key.argtypes = [POINTER(REGFI_ITERATOR)]
59regfi.regfi_iterator_cur_key.restype = POINTER(REGFI_NK)
60
61regfi.regfi_iterator_first_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
62regfi.regfi_iterator_first_subkey.restype = c_bool
63
64regfi.regfi_iterator_cur_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
65regfi.regfi_iterator_cur_subkey.restype = POINTER(REGFI_NK)
66
67regfi.regfi_iterator_next_subkey.argtypes = [POINTER(REGFI_ITERATOR)]
68regfi.regfi_iterator_next_subkey.restype = c_bool
69
70regfi.regfi_iterator_find_subkey.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
71regfi.regfi_iterator_find_subkey.restype = c_bool
72
73regfi.regfi_iterator_first_value.argtypes = [POINTER(REGFI_ITERATOR)]
74regfi.regfi_iterator_first_value.restype = c_bool
75
76regfi.regfi_iterator_cur_value.argtypes = [POINTER(REGFI_ITERATOR)]
77regfi.regfi_iterator_cur_value.restype = POINTER(REGFI_VK)
78
79regfi.regfi_iterator_next_value.argtypes = [POINTER(REGFI_ITERATOR)]
80regfi.regfi_iterator_next_value.restype = c_bool
81
82regfi.regfi_iterator_find_value.argtypes = [POINTER(REGFI_ITERATOR), c_char_p]
83regfi.regfi_iterator_find_value.restype = c_bool
84
85
86regfi.regfi_init.argtypes = []
87regfi.regfi_init.restype = None
88regfi.regfi_init()
89
90
91def GetLogMessages():
92    msgs = regfi.regfi_log_get_str()
93    if msgs == None:
94        return ''
95    return msgs
96
97
98class _StructureWrapper():
99    "Handles memory management and proxies attribute access to base structures"
100    base = None
101
102    def __init__(self, base):
103        # XXX: check for NULL here, throw an exception if so.
104        self.base = base
105
106    def __del__(self):
107        regfi.regfi_free_record(self.base)
108
109    def __getattr__(self, name):
110        return getattr(self.base.contents, name)
111
112    def __eq__(self, other):
113        return (type(self) == type(other)) and (self.offset == other.offset)
114
115    def __ne__(self, other):
116        return (not self.__eq__(other))
117
118
119class Key(_StructureWrapper):
120    pass
121
122class Value(_StructureWrapper):
123    pass
124
125class Data(_StructureWrapper):
126    pass
127
128class Security(_StructureWrapper):
129    pass
130
131class Hive():   
132    file = None
133    raw_file = None
134   
135    def __init__(self, fh):
136        # The fileno method may not exist, or it may thrown an exception
137        # when called if the file isn't backed with a descriptor.
138        try:
139            if hasattr(fh, 'fileno'):
140                self.file = regfi.regfi_alloc(fh.fileno())
141                return
142        except:
143            pass
144       
145        self.raw_file = structures.REGFI_RAW_FILE()
146        self.raw_file.fh = fh
147        self.raw_file.seek = seek_cb_type(self.raw_file.cb_seek)
148        self.raw_file.read = read_cb_type(self.raw_file.cb_read)
149        self.file = regfi.regfi_alloc_cb(self.raw_file)
150
151    def __getattr__(self, name):
152        return getattr(self.file.contents, name)
153   
154    def __del__(self):   
155        regfi.regfi_free(self.file)
156        if self.raw_file != None:
157            regfi.regfi_free(self.file)
158           
159
160    def __iter__(self):
161        return HiveIterator(self)
162
163    def subtree(self, path):
164        hi = HiveIterator(self)
165        hi.descend(path)
166        return hi
167
168
169class HiveIterator():
170    hive = None
171    iter = None
172    iteration_root = None
173
174    def __init__(self, hive):
175        # REGFI_ENCODING_UTF8==1
176        self.iter = regfi.regfi_iterator_new(hive.file, 1)
177        if self.iter == None:
178            raise Exception("Could not create iterator.  Current log:\n"
179                            + GetLogMessages())
180        self.hive = hive
181       
182    def __getattr__(self, name):
183        return getattr(self.file.contents, name)
184
185    def __del__(self):   
186        regfi.regfi_iterator_free(self.iter)       
187
188    def __iter__(self):
189        self.iteration_root = None
190        return self
191
192    def __next__(self):
193        if self.iteration_root == None:
194            self.iteration_root = self.current_key()           
195        elif not regfi.regfi_iterator_down(self.iter):
196            up_ret = regfi.regfi_iterator_up(self.iter)
197            while (up_ret and
198                   not regfi.regfi_iterator_next_subkey(self.iter)):
199                if self.iteration_root == self.current_key():
200                    self.iteration_root = None
201                    raise StopIteration('')
202                up_ret = regfi.regfi_iterator_up(self.iter)
203
204            if not up_ret:
205                raise StopIteration('')
206           
207            if not regfi.regfi_iterator_down(self.iter):
208                raise Exception('Error traversing iterator downward.'+
209                                ' Current log:\n'+ GetLogMessages())
210
211        regfi.regfi_iterator_first_subkey(self.iter)
212        return self.current_key()
213
214    def down(self):
215        pass
216
217    def up(self):
218        pass
219
220    def descend(self, path):
221        #set up generator
222        cpath = (bytes(p,'ascii') for p in path) 
223
224        # evaluate generator and create char* array
225        apath = (c_char_p*len(path))(*cpath)
226
227        if not regfi.regfi_iterator_walk_path(self.iter,apath):
228            raise Exception('Could not locate path.\n'+GetLogMessages())
229
230    def current_key(self):
231        return Key(regfi.regfi_iterator_cur_key(self.iter))
Note: See TracBrowser for help on using the repository browser.