source: trunk/python2/regfi/regfi.c @ 200

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

redesigned python key iterator and test script
updated documentation

File size: 6.2 KB
Line 
1/*
2** regfi.c
3**
4** Made by (mic)
5** Login   <mic@laptop>
6**
7** Started on  Fri Apr 30 02:06:28 2010 mic
8** Last update Sun May 12 01:17:25 2002 Speed Blue
9*/
10
11#include "pyregfi.h"
12
13static int RegistryFile_dest(void *self) {
14  RegistryFile this = (RegistryFile)self;
15
16  regfi_free(this->reg);
17  close(this->fd);
18
19  return 0;
20}
21
22static RegistryFile RegistryFile_Con(RegistryFile self, char *filename) {
23  self->fd = open(filename, O_RDONLY);
24  if(self->fd < 0) {
25    RaiseError(EIOError, "Unable to open %s", filename);
26    goto error;
27  }
28
29  self->reg = regfi_alloc(self->fd);
30
31  if(!self->reg) {
32    RaiseError(ERuntimeError, "REGFI Error: %s", regfi_log_get_str());
33    /*char* e = regfi_log_get_str();*/
34    /*fprintf(stderr, "%p\n", e);*/
35    goto error;
36  }
37
38  talloc_set_destructor((void *)self, RegistryFile_dest);
39  return self;
40
41 error:
42  talloc_free(self);
43  return NULL;
44}
45
46static KeyIterator RegistryFile_get_key(RegistryFile self, char **path, REGFI_ENCODING encoding) {
47  return CONSTRUCT(KeyIterator, KeyIterator, Con, NULL, self, path, encoding);
48}
49
50
51VIRTUAL(RegistryFile, Object) {
52  VMETHOD(Con) = RegistryFile_Con;
53  VMETHOD(get_key) = RegistryFile_get_key;
54} END_VIRTUAL
55
56static int KeyIterator_dest(void *self) {
57  KeyIterator this = (KeyIterator)self;
58
59  regfi_iterator_free(this->iter);
60  return 0;
61}
62
63static KeyIterator KeyIterator_Con(KeyIterator self, 
64                                   RegistryFile file, 
65                                   char **path,
66                                   REGFI_ENCODING encoding) 
67{
68  self->iter = regfi_iterator_new(file->reg, encoding);
69
70  if(!self->iter) {
71    RaiseError(ERuntimeError, "Error: %s", regfi_log_get_str());
72    goto error;
73  }
74
75  talloc_set_destructor((void*)self, KeyIterator_dest);
76
77  /* Traverse to the path */
78  if(path[0]) {
79    if(!regfi_iterator_walk_path(self->iter, (const char **)path)) {
80      RaiseError(ERuntimeError, "Unable to walk down key path");
81      goto error;
82    }
83  }
84
85  self->root_traversed = false;
86
87  return self;
88 error:
89  return NULL;
90}
91
92static void KeyIterator__iter__(KeyIterator self) 
93{
94  return;
95}
96
97
98static const REGFI_NK_REC *KeyIterator_next(KeyIterator self) 
99{
100  if(!self->root_traversed)
101    self->root_traversed = true;
102  else if(!regfi_iterator_down(self->iter))
103  {
104    do
105    {
106      if(!regfi_iterator_up(self->iter))
107        return NULL;
108    } while(!regfi_iterator_next_subkey(self->iter));
109
110    /* XXX: This is an error condition. 
111     *      Probably should throw an exception or something. */
112    if(!regfi_iterator_down(self->iter))
113      return NULL;
114  }
115
116  regfi_iterator_first_subkey(self->iter);
117  return regfi_iterator_cur_key(self->iter);
118}
119
120
121static int KeyIterator_down(KeyIterator self) {
122  int result = regfi_iterator_down(self->iter);
123  regfi_iterator_first_subkey(self->iter);
124  regfi_iterator_first_value(self->iter);
125  return result;
126}
127
128static int KeyIterator_up(KeyIterator self) {
129  return regfi_iterator_up(self->iter);
130}
131
132static ValueIterator KeyIterator_list_values(KeyIterator self) {
133  return CONSTRUCT(ValueIterator, ValueIterator, Con, NULL, self);
134}
135
136VIRTUAL(KeyIterator, Object) {
137  VMETHOD(Con) = KeyIterator_Con;
138  VMETHOD(iternext) = KeyIterator_next;
139  VMETHOD(down) = KeyIterator_down;
140  VMETHOD(up) = KeyIterator_up;
141  VMETHOD(__iter__) = KeyIterator__iter__;
142  VMETHOD(list_values) = KeyIterator_list_values;
143} END_VIRTUAL
144
145static int ValueIterator_dest(void *self) {
146  ValueIterator this = (ValueIterator)self;
147
148  talloc_unlink(this, this->iter);
149
150  return 0;
151}
152
153static ValueIterator ValueIterator_Con(ValueIterator self, KeyIterator key) {
154  // Take a copy of the iterator
155  self->iter = key->iter;
156  talloc_reference(self, self->iter);
157
158  talloc_set_destructor((void *)self, ValueIterator_dest);
159
160  return self;
161}
162
163static void ValueIterator__iter__(ValueIterator self) {
164  return;
165}
166
167static REGFI_VK_REC* ValueIterator_iternext(ValueIterator self) {
168  RawData result;
169  const REGFI_DATA* data;
170  const REGFI_VK_REC* rec;
171
172  if(!self->first_called)
173  {
174    regfi_iterator_first_value(self->iter);
175    self->first_called = true;
176  }
177  else
178    regfi_iterator_next_value(self->iter);
179
180  rec = regfi_iterator_cur_value(self->iter);
181
182  return rec;
183
184  if(!rec) return NULL;
185
186  /* XXX: shouldn't parse data here every time we walk over a value. 
187   *      Instead, make data fetching a method and parse it then.
188   */
189  /*
190  data = (REGFI_DATA *)regfi_iterator_fetch_data(self->iter, rec);
191  if(!data) {
192    RaiseError(ERuntimeError, "Unable to fetch data: %s", regfi_log_get_str());
193    goto error;
194  }
195
196  switch(rec->type) {
197  case REG_EXPAND_SZ:
198  case REG_SZ:
199    result = (RawData)CONSTRUCT(DataString, RawData, Con, NULL, data, rec);
200    break;
201
202  case REG_DWORD:
203    result = (RawData)CONSTRUCT(DWORDData, RawData, Con, NULL, data, rec);
204    break;
205
206  case REG_BINARY:
207  default:
208    result = (RawData)CONSTRUCT(RawData, RawData, Con, NULL, data, rec);
209    break;
210  }
211  */
212
213  return result;
214 error:
215  talloc_free(self);
216  return NULL;
217}
218
219VIRTUAL(ValueIterator, Object) {
220  VMETHOD(Con) = ValueIterator_Con;
221  VMETHOD(__iter__) = ValueIterator__iter__;
222  VMETHOD(iternext) = ValueIterator_iternext;
223} END_VIRTUAL
224
225static int RawData_dest(void *self) {
226  RawData this = (RawData)self;
227
228  if(this->data) {
229    regfi_free_record(this->data);
230  };
231
232  if(this->rec) {
233    regfi_free_record(this->rec);
234  };
235
236  return 0;
237}
238
239static RawData RawData_Con(RawData self, REGFI_DATA *data, REGFI_VK_REC *record) {
240  self->rec = record;
241  self->data = data;
242
243  talloc_set_destructor((void *)self, RawData_dest);
244
245  return self;
246}
247
248static int RawData_get_value(RawData self, char *buff, int len) {
249  int available_to_read = min(len, self->data->interpreted_size);
250
251  memcpy(buff, self->data->raw, available_to_read);
252
253  return available_to_read;
254}
255
256VIRTUAL(RawData, Object) {
257  VMETHOD(Con) = RawData_Con;
258  VMETHOD(get_value) = RawData_get_value;
259} END_VIRTUAL
260
261static char* DataString_get_value(DataString self) {
262  RawData this = (RawData)self;
263
264  return (char*)this->data->interpreted.string;
265}
266
267VIRTUAL(DataString, RawData) {
268  VMETHOD(get_value) = DataString_get_value;
269} END_VIRTUAL
270
271static uint64_t DWORDData_get_value(DWORDData self) {
272  RawData this = (RawData)self;
273
274  return this->data->interpreted.dword;
275}
276
277VIRTUAL(DWORDData, RawData) {
278  VMETHOD(get_value) = DWORDData_get_value;
279} END_VIRTUAL
280
281void pyregfi_init() {
282  regfi_init();
283  INIT_CLASS(RegistryFile);
284}
Note: See TracBrowser for help on using the repository browser.