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
RevLine 
[196]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;
[198]20}
[196]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;
[198]27  }
[196]28
29  self->reg = regfi_alloc(self->fd);
30
31  if(!self->reg) {
[200]32    RaiseError(ERuntimeError, "REGFI Error: %s", regfi_log_get_str());
[198]33    /*char* e = regfi_log_get_str();*/
34    /*fprintf(stderr, "%p\n", e);*/
[196]35    goto error;
[198]36  }
[196]37
38  talloc_set_destructor((void *)self, RegistryFile_dest);
39  return self;
40
41 error:
42  talloc_free(self);
43  return NULL;
[198]44}
[196]45
46static KeyIterator RegistryFile_get_key(RegistryFile self, char **path, REGFI_ENCODING encoding) {
47  return CONSTRUCT(KeyIterator, KeyIterator, Con, NULL, self, path, encoding);
[198]48}
[196]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;
[198]61}
[196]62
[200]63static KeyIterator KeyIterator_Con(KeyIterator self, 
64                                   RegistryFile file, 
65                                   char **path,
66                                   REGFI_ENCODING encoding) 
67{
[196]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;
[198]73  }
[196]74
75  talloc_set_destructor((void*)self, KeyIterator_dest);
76
[199]77  /* Traverse to the path */
[196]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;
[198]82    }
83  }
[196]84
[200]85  self->root_traversed = false;
[196]86
87  return self;
88 error:
89  return NULL;
[198]90}
[196]91
[200]92static void KeyIterator__iter__(KeyIterator self) 
93{
94  return;
[198]95}
[196]96
[199]97
[200]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));
[196]109
[200]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  }
[196]115
[200]116  regfi_iterator_first_subkey(self->iter);
117  return regfi_iterator_cur_key(self->iter);
[199]118}
[196]119
120
[199]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);
[196]125  return result;
[198]126}
[196]127
[199]128static int KeyIterator_up(KeyIterator self) {
129  return regfi_iterator_up(self->iter);
130}
131
[196]132static ValueIterator KeyIterator_list_values(KeyIterator self) {
133  return CONSTRUCT(ValueIterator, ValueIterator, Con, NULL, self);
[198]134}
[196]135
136VIRTUAL(KeyIterator, Object) {
137  VMETHOD(Con) = KeyIterator_Con;
138  VMETHOD(iternext) = KeyIterator_next;
[199]139  VMETHOD(down) = KeyIterator_down;
140  VMETHOD(up) = KeyIterator_up;
[196]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
[199]148  talloc_unlink(this, this->iter);
[196]149
150  return 0;
[198]151}
[196]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;
[198]161}
[196]162
[200]163static void ValueIterator__iter__(ValueIterator self) {
164  return;
[198]165}
[196]166
[200]167static REGFI_VK_REC* ValueIterator_iternext(ValueIterator self) {
[196]168  RawData result;
[199]169  const REGFI_DATA* data;
170  const REGFI_VK_REC* rec;
[196]171
[199]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
[200]182  return rec;
183
[196]184  if(!rec) return NULL;
185
[199]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   */
[200]189  /*
[196]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;
[198]194  }
[196]195
[199]196  switch(rec->type) {
[196]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;
[198]210  }
[200]211  */
[196]212
213  return result;
214 error:
215  talloc_free(self);
216  return NULL;
[198]217}
[196]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;
[198]237}
[196]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;
[198]246}
[196]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;
[198]254}
[196]255
256VIRTUAL(RawData, Object) {
257  VMETHOD(Con) = RawData_Con;
258  VMETHOD(get_value) = RawData_get_value;
259} END_VIRTUAL
260
[198]261static char* DataString_get_value(DataString self) {
[196]262  RawData this = (RawData)self;
263
[198]264  return (char*)this->data->interpreted.string;
265}
[196]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;
[198]275}
[196]276
277VIRTUAL(DWORDData, RawData) {
278  VMETHOD(get_value) = DWORDData_get_value;
279} END_VIRTUAL
280
281void pyregfi_init() {
[199]282  regfi_init();
[196]283  INIT_CLASS(RegistryFile);
[198]284}
Note: See TracBrowser for help on using the repository browser.