1 /*
2 * Python object definition of the MFT metadata file entries sequence and iterator
3 *
4 * Copyright (C) 2010-2021, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <types.h>
24
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28
29 #include "pyfsntfs_file_entry.h"
30 #include "pyfsntfs_libcerror.h"
31 #include "pyfsntfs_libfsntfs.h"
32 #include "pyfsntfs_mft_metadata_file_entries.h"
33 #include "pyfsntfs_python.h"
34
35 PySequenceMethods pyfsntfs_mft_metadata_file_entries_sequence_methods = {
36 /* sq_length */
37 (lenfunc) pyfsntfs_mft_metadata_file_entries_len,
38 /* sq_concat */
39 0,
40 /* sq_repeat */
41 0,
42 /* sq_item */
43 (ssizeargfunc) pyfsntfs_mft_metadata_file_entries_getitem,
44 /* sq_slice */
45 0,
46 /* sq_ass_item */
47 0,
48 /* sq_ass_slice */
49 0,
50 /* sq_contains */
51 0,
52 /* sq_inplace_concat */
53 0,
54 /* sq_inplace_repeat */
55 0
56 };
57
58 PyTypeObject pyfsntfs_mft_metadata_file_entries_type_object = {
59 PyVarObject_HEAD_INIT( NULL, 0 )
60
61 /* tp_name */
62 "pyfsntfs._mft_metadata_file_entries",
63 /* tp_basicsize */
64 sizeof( pyfsntfs_mft_metadata_file_entries_t ),
65 /* tp_itemsize */
66 0,
67 /* tp_dealloc */
68 (destructor) pyfsntfs_mft_metadata_file_entries_free,
69 /* tp_print */
70 0,
71 /* tp_getattr */
72 0,
73 /* tp_setattr */
74 0,
75 /* tp_compare */
76 0,
77 /* tp_repr */
78 0,
79 /* tp_as_number */
80 0,
81 /* tp_as_sequence */
82 &pyfsntfs_mft_metadata_file_entries_sequence_methods,
83 /* tp_as_mapping */
84 0,
85 /* tp_hash */
86 0,
87 /* tp_call */
88 0,
89 /* tp_str */
90 0,
91 /* tp_getattro */
92 0,
93 /* tp_setattro */
94 0,
95 /* tp_as_buffer */
96 0,
97 /* tp_flags */
98 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
99 /* tp_doc */
100 "internal pyfsntfs MFT metadata file entries sequence and iterator object",
101 /* tp_traverse */
102 0,
103 /* tp_clear */
104 0,
105 /* tp_richcompare */
106 0,
107 /* tp_weaklistoffset */
108 0,
109 /* tp_iter */
110 (getiterfunc) pyfsntfs_mft_metadata_file_entries_iter,
111 /* tp_iternext */
112 (iternextfunc) pyfsntfs_mft_metadata_file_entries_iternext,
113 /* tp_methods */
114 0,
115 /* tp_members */
116 0,
117 /* tp_getset */
118 0,
119 /* tp_base */
120 0,
121 /* tp_dict */
122 0,
123 /* tp_descr_get */
124 0,
125 /* tp_descr_set */
126 0,
127 /* tp_dictoffset */
128 0,
129 /* tp_init */
130 (initproc) pyfsntfs_mft_metadata_file_entries_init,
131 /* tp_alloc */
132 0,
133 /* tp_new */
134 0,
135 /* tp_free */
136 0,
137 /* tp_is_gc */
138 0,
139 /* tp_bases */
140 NULL,
141 /* tp_mro */
142 NULL,
143 /* tp_cache */
144 NULL,
145 /* tp_subclasses */
146 NULL,
147 /* tp_weaklist */
148 NULL,
149 /* tp_del */
150 0
151 };
152
153 /* Creates a new MFT metadata file entries object
154 * Returns a Python object if successful or NULL on error
155 */
pyfsntfs_mft_metadata_file_entries_new(pyfsntfs_mft_metadata_file_t * mft_metadata_file_object,PyObject * (* get_file_entry_by_index)(pyfsntfs_mft_metadata_file_t * mft_metadata_file_object,uint64_t file_entry_index),uint64_t number_of_file_entries)156 PyObject *pyfsntfs_mft_metadata_file_entries_new(
157 pyfsntfs_mft_metadata_file_t *mft_metadata_file_object,
158 PyObject* (*get_file_entry_by_index)(
159 pyfsntfs_mft_metadata_file_t *mft_metadata_file_object,
160 uint64_t file_entry_index ),
161 uint64_t number_of_file_entries )
162 {
163 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries = NULL;
164 static char *function = "pyfsntfs_mft_metadata_file_entries_new";
165
166 if( mft_metadata_file_object == NULL )
167 {
168 PyErr_Format(
169 PyExc_ValueError,
170 "%s: invalid MFT metadata file object.",
171 function );
172
173 return( NULL );
174 }
175 if( get_file_entry_by_index == NULL )
176 {
177 PyErr_Format(
178 PyExc_ValueError,
179 "%s: invalid get file entry by index function.",
180 function );
181
182 return( NULL );
183 }
184 /* Make sure the MFT metadata file entries values are initialized
185 */
186 pyfsntfs_mft_metadata_file_entries = PyObject_New(
187 struct pyfsntfs_mft_metadata_file_entries,
188 &pyfsntfs_mft_metadata_file_entries_type_object );
189
190 if( pyfsntfs_mft_metadata_file_entries == NULL )
191 {
192 PyErr_Format(
193 PyExc_MemoryError,
194 "%s: unable to initialize MFT metadata file entries.",
195 function );
196
197 goto on_error;
198 }
199 if( pyfsntfs_mft_metadata_file_entries_init(
200 pyfsntfs_mft_metadata_file_entries ) != 0 )
201 {
202 PyErr_Format(
203 PyExc_MemoryError,
204 "%s: unable to initialize MFT metadata file entries.",
205 function );
206
207 goto on_error;
208 }
209 pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object = mft_metadata_file_object;
210 pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index = get_file_entry_by_index;
211 pyfsntfs_mft_metadata_file_entries->number_of_file_entries = number_of_file_entries;
212
213 Py_IncRef(
214 (PyObject *) pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object );
215
216 return( (PyObject *) pyfsntfs_mft_metadata_file_entries );
217
218 on_error:
219 if( pyfsntfs_mft_metadata_file_entries != NULL )
220 {
221 Py_DecRef(
222 (PyObject *) pyfsntfs_mft_metadata_file_entries );
223 }
224 return( NULL );
225 }
226
227 /* Initializes a MFT metadata file entries object
228 * Returns 0 if successful or -1 on error
229 */
pyfsntfs_mft_metadata_file_entries_init(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries)230 int pyfsntfs_mft_metadata_file_entries_init(
231 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries )
232 {
233 static char *function = "pyfsntfs_mft_metadata_file_entries_init";
234
235 if( pyfsntfs_mft_metadata_file_entries == NULL )
236 {
237 PyErr_Format(
238 PyExc_ValueError,
239 "%s: invalid MFT metadata file entries.",
240 function );
241
242 return( -1 );
243 }
244 /* Make sure the MFT metadata file entries values are initialized
245 */
246 pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object = NULL;
247 pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index = NULL;
248 pyfsntfs_mft_metadata_file_entries->file_entry_index = 0;
249 pyfsntfs_mft_metadata_file_entries->number_of_file_entries = 0;
250
251 return( 0 );
252 }
253
254 /* Frees a MFT metadata file entries object
255 */
pyfsntfs_mft_metadata_file_entries_free(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries)256 void pyfsntfs_mft_metadata_file_entries_free(
257 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries )
258 {
259 struct _typeobject *ob_type = NULL;
260 static char *function = "pyfsntfs_mft_metadata_file_entries_free";
261
262 if( pyfsntfs_mft_metadata_file_entries == NULL )
263 {
264 PyErr_Format(
265 PyExc_ValueError,
266 "%s: invalid MFT metadata file entries.",
267 function );
268
269 return;
270 }
271 ob_type = Py_TYPE(
272 pyfsntfs_mft_metadata_file_entries );
273
274 if( ob_type == NULL )
275 {
276 PyErr_Format(
277 PyExc_ValueError,
278 "%s: missing ob_type.",
279 function );
280
281 return;
282 }
283 if( ob_type->tp_free == NULL )
284 {
285 PyErr_Format(
286 PyExc_ValueError,
287 "%s: invalid ob_type - missing tp_free.",
288 function );
289
290 return;
291 }
292 if( pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object != NULL )
293 {
294 Py_DecRef(
295 (PyObject *) pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object );
296 }
297 ob_type->tp_free(
298 (PyObject*) pyfsntfs_mft_metadata_file_entries );
299 }
300
301 /* The MFT metadata file entries len() function
302 */
pyfsntfs_mft_metadata_file_entries_len(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries)303 Py_ssize_t pyfsntfs_mft_metadata_file_entries_len(
304 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries )
305 {
306 static char *function = "pyfsntfs_mft_metadata_file_entries_len";
307
308 if( pyfsntfs_mft_metadata_file_entries == NULL )
309 {
310 PyErr_Format(
311 PyExc_ValueError,
312 "%s: invalid MFT metadata file entries.",
313 function );
314
315 return( -1 );
316 }
317 return( (Py_ssize_t) pyfsntfs_mft_metadata_file_entries->number_of_file_entries );
318 }
319
320 /* The MFT metadata file entries getitem() function
321 */
pyfsntfs_mft_metadata_file_entries_getitem(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries,Py_ssize_t item_index)322 PyObject *pyfsntfs_mft_metadata_file_entries_getitem(
323 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries,
324 Py_ssize_t item_index )
325 {
326 PyObject *file_entry_object = NULL;
327 static char *function = "pyfsntfs_mft_metadata_file_entries_getitem";
328
329 if( pyfsntfs_mft_metadata_file_entries == NULL )
330 {
331 PyErr_Format(
332 PyExc_ValueError,
333 "%s: invalid MFT metadata file entries.",
334 function );
335
336 return( NULL );
337 }
338 if( pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index == NULL )
339 {
340 PyErr_Format(
341 PyExc_ValueError,
342 "%s: invalid MFT metadata file entries - missing get file entry by index function.",
343 function );
344
345 return( NULL );
346 }
347 if( pyfsntfs_mft_metadata_file_entries->number_of_file_entries < 0 )
348 {
349 PyErr_Format(
350 PyExc_ValueError,
351 "%s: invalid MFT metadata file entries - invalid number of file entries.",
352 function );
353
354 return( NULL );
355 }
356 if( ( item_index < 0 )
357 || ( item_index >= (Py_ssize_t) pyfsntfs_mft_metadata_file_entries->number_of_file_entries ) )
358 {
359 PyErr_Format(
360 PyExc_ValueError,
361 "%s: invalid invalid item index value out of bounds.",
362 function );
363
364 return( NULL );
365 }
366 file_entry_object = pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index(
367 pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object,
368 (uint64_t) item_index );
369
370 return( file_entry_object );
371 }
372
373 /* The MFT metadata file entries iter() function
374 */
pyfsntfs_mft_metadata_file_entries_iter(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries)375 PyObject *pyfsntfs_mft_metadata_file_entries_iter(
376 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries )
377 {
378 static char *function = "pyfsntfs_mft_metadata_file_entries_iter";
379
380 if( pyfsntfs_mft_metadata_file_entries == NULL )
381 {
382 PyErr_Format(
383 PyExc_ValueError,
384 "%s: invalid MFT metadata file entries.",
385 function );
386
387 return( NULL );
388 }
389 Py_IncRef(
390 (PyObject *) pyfsntfs_mft_metadata_file_entries );
391
392 return( (PyObject *) pyfsntfs_mft_metadata_file_entries );
393 }
394
395 /* The MFT metadata file entries iternext() function
396 */
pyfsntfs_mft_metadata_file_entries_iternext(pyfsntfs_mft_metadata_file_entries_t * pyfsntfs_mft_metadata_file_entries)397 PyObject *pyfsntfs_mft_metadata_file_entries_iternext(
398 pyfsntfs_mft_metadata_file_entries_t *pyfsntfs_mft_metadata_file_entries )
399 {
400 PyObject *file_entry_object = NULL;
401 static char *function = "pyfsntfs_mft_metadata_file_entries_iternext";
402
403 if( pyfsntfs_mft_metadata_file_entries == NULL )
404 {
405 PyErr_Format(
406 PyExc_ValueError,
407 "%s: invalid MFT metadata file entries.",
408 function );
409
410 return( NULL );
411 }
412 if( pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index == NULL )
413 {
414 PyErr_Format(
415 PyExc_ValueError,
416 "%s: invalid MFT metadata file entries - missing get file entry by index function.",
417 function );
418
419 return( NULL );
420 }
421 if( pyfsntfs_mft_metadata_file_entries->file_entry_index < 0 )
422 {
423 PyErr_Format(
424 PyExc_ValueError,
425 "%s: invalid MFT metadata file entries - invalid file entry index.",
426 function );
427
428 return( NULL );
429 }
430 if( pyfsntfs_mft_metadata_file_entries->number_of_file_entries < 0 )
431 {
432 PyErr_Format(
433 PyExc_ValueError,
434 "%s: invalid MFT metadata file entries - invalid number of file entries.",
435 function );
436
437 return( NULL );
438 }
439 if( pyfsntfs_mft_metadata_file_entries->file_entry_index >= pyfsntfs_mft_metadata_file_entries->number_of_file_entries )
440 {
441 PyErr_SetNone(
442 PyExc_StopIteration );
443
444 return( NULL );
445 }
446 file_entry_object = pyfsntfs_mft_metadata_file_entries->get_file_entry_by_index(
447 pyfsntfs_mft_metadata_file_entries->mft_metadata_file_object,
448 pyfsntfs_mft_metadata_file_entries->file_entry_index );
449
450 if( file_entry_object != NULL )
451 {
452 pyfsntfs_mft_metadata_file_entries->file_entry_index++;
453 }
454 return( file_entry_object );
455 }
456
457