1 /*
2 * Python object wrapper of libfsntfs_file_entry_t
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 <narrow_string.h>
24 #include <types.h>
25
26 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
27 #include <stdlib.h>
28 #endif
29
30 #include "pyfsntfs_attribute.h"
31 #include "pyfsntfs_attributes.h"
32 #include "pyfsntfs_data_stream.h"
33 #include "pyfsntfs_data_streams.h"
34 #include "pyfsntfs_datetime.h"
35 #include "pyfsntfs_error.h"
36 #include "pyfsntfs_file_entries.h"
37 #include "pyfsntfs_file_entry.h"
38 #include "pyfsntfs_file_name_attribute.h"
39 #include "pyfsntfs_integer.h"
40 #include "pyfsntfs_libcerror.h"
41 #include "pyfsntfs_libfsntfs.h"
42 #include "pyfsntfs_object_identifier_attribute.h"
43 #include "pyfsntfs_python.h"
44 #include "pyfsntfs_reparse_point_attribute.h"
45 #include "pyfsntfs_security_descriptor_attribute.h"
46 #include "pyfsntfs_standard_information_attribute.h"
47 #include "pyfsntfs_unused.h"
48 #include "pyfsntfs_volume_information_attribute.h"
49 #include "pyfsntfs_volume_name_attribute.h"
50
51 PyMethodDef pyfsntfs_file_entry_object_methods[] = {
52
53 /* Functions to access the file entry data */
54
55 { "read_buffer",
56 (PyCFunction) pyfsntfs_file_entry_read_buffer,
57 METH_VARARGS | METH_KEYWORDS,
58 "read_buffer(size) -> String\n"
59 "\n"
60 "Reads a buffer of file entry data." },
61
62 { "read_buffer_at_offset",
63 (PyCFunction) pyfsntfs_file_entry_read_buffer_at_offset,
64 METH_VARARGS | METH_KEYWORDS,
65 "read_buffer_at_offset(size, offset) -> String\n"
66 "\n"
67 "Reads a buffer of file entry data at a specific offset." },
68
69 { "seek_offset",
70 (PyCFunction) pyfsntfs_file_entry_seek_offset,
71 METH_VARARGS | METH_KEYWORDS,
72 "seek_offset(offset, whence) -> None\n"
73 "\n"
74 "Seeks an offset within the file entry data." },
75
76 { "get_offset",
77 (PyCFunction) pyfsntfs_file_entry_get_offset,
78 METH_NOARGS,
79 "get_offset() -> Integer\n"
80 "\n"
81 "Returns the current offset within the file entry data." },
82
83 /* Some Pythonesque aliases */
84
85 { "read",
86 (PyCFunction) pyfsntfs_file_entry_read_buffer,
87 METH_VARARGS | METH_KEYWORDS,
88 "read(size) -> String\n"
89 "\n"
90 "Reads a buffer of file entry data." },
91
92 { "seek",
93 (PyCFunction) pyfsntfs_file_entry_seek_offset,
94 METH_VARARGS | METH_KEYWORDS,
95 "seek(offset, whence) -> None\n"
96 "\n"
97 "Seeks an offset within the file entry data." },
98
99 { "tell",
100 (PyCFunction) pyfsntfs_file_entry_get_offset,
101 METH_NOARGS,
102 "tell() -> Integer\n"
103 "\n"
104 "Returns the current offset within the file entry data." },
105
106 /* Functions to access the metadata */
107
108 { "get_size",
109 (PyCFunction) pyfsntfs_file_entry_get_size,
110 METH_NOARGS,
111 "get_size() -> Integer\n"
112 "\n"
113 "Returns the size data." },
114
115 /* Functions to access the extents */
116
117 { "get_number_of_extents",
118 (PyCFunction) pyfsntfs_file_entry_get_number_of_extents,
119 METH_NOARGS,
120 "get_number_of_extents() -> Integer\n"
121 "\n"
122 "Retrieves the number of extents." },
123
124 { "get_extent",
125 (PyCFunction) pyfsntfs_file_entry_get_extent,
126 METH_VARARGS | METH_KEYWORDS,
127 "get_extent(extent_index) -> Tuple( Integer, Integer, Integer )\n"
128 "\n"
129 "Retrieves a specific extent.\t"
130 "The extent is a tuple of offset, size and flags." },
131
132 /* Functions to access the file entry data */
133
134 { "is_empty",
135 (PyCFunction) pyfsntfs_file_entry_is_empty,
136 METH_NOARGS,
137 "is_empty() -> Boolean\n"
138 "\n"
139 "Determines if the file entry is empty." },
140
141 { "is_allocated",
142 (PyCFunction) pyfsntfs_file_entry_is_allocated,
143 METH_NOARGS,
144 "is_allocated() -> Boolean\n"
145 "\n"
146 "Determines if the file entry is allocated." },
147
148 { "has_directory_entries_index",
149 (PyCFunction) pyfsntfs_file_entry_has_directory_entries_index,
150 METH_NOARGS,
151 "has_directory_entries_index() -> Boolean\n"
152 "\n"
153 "Determines if the file entry has a directory entries index." },
154
155 { "has_default_data_stream",
156 (PyCFunction) pyfsntfs_file_entry_has_default_data_stream,
157 METH_NOARGS,
158 "has_default_data_stream() -> Boolean\n"
159 "\n"
160 "Determines if the file entry has a default data stream." },
161
162 { "get_file_reference",
163 (PyCFunction) pyfsntfs_file_entry_get_file_reference,
164 METH_NOARGS,
165 "get_file_reference() -> Integer\n"
166 "\n"
167 "Returns the file reference, a combination of MFT entry index and sequence number." },
168
169 { "get_base_record_file_reference",
170 (PyCFunction) pyfsntfs_file_entry_get_base_record_file_reference,
171 METH_NOARGS,
172 "get_base_record_file_reference() -> Integer\n"
173 "\n"
174 "Returns the base record file reference, a combination of MFT entry index and sequence number." },
175
176 { "get_parent_file_reference",
177 (PyCFunction) pyfsntfs_file_entry_get_parent_file_reference,
178 METH_NOARGS,
179 "get_parent_file_reference() -> Integer or None\n"
180 "\n"
181 "Returns the parent file reference, a combination of MFT entry index and sequence number." },
182
183 { "get_parent_file_reference_by_attribute_index",
184 (PyCFunction) pyfsntfs_file_entry_get_parent_file_reference_by_attribute_index,
185 METH_VARARGS | METH_KEYWORDS,
186 "get_parent_file_reference_by_attribute_index(attribute_index) -> Integer\n"
187 "\n"
188 "Returns the parent file reference, a combination of MFT entry index and sequence number." },
189
190 { "get_journal_sequence_number",
191 (PyCFunction) pyfsntfs_file_entry_get_journal_sequence_number,
192 METH_NOARGS,
193 "get_journal_sequence_number() -> Integer\n"
194 "\n"
195 "Returns the journal sequence number." },
196
197 { "get_creation_time",
198 (PyCFunction) pyfsntfs_file_entry_get_creation_time,
199 METH_NOARGS,
200 "get_creation_time() -> Datetime or None\n"
201 "\n"
202 "Returns the creation date and time." },
203
204 { "get_creation_time_as_integer",
205 (PyCFunction) pyfsntfs_file_entry_get_creation_time_as_integer,
206 METH_NOARGS,
207 "get_creation_time_as_integer() -> Integer or None\n"
208 "\n"
209 "Returns the creation date and time as a 64-bit integer containing a FILETIME value." },
210
211 { "get_modification_time",
212 (PyCFunction) pyfsntfs_file_entry_get_modification_time,
213 METH_NOARGS,
214 "get_modification_time() -> Datetime or None\n"
215 "\n"
216 "Returns the modification date and time." },
217
218 { "get_modification_time_as_integer",
219 (PyCFunction) pyfsntfs_file_entry_get_modification_time_as_integer,
220 METH_NOARGS,
221 "get_modification_time_as_integer() -> Integer or None\n"
222 "\n"
223 "Returns the modification date and time as a 64-bit integer containing a FILETIME value." },
224
225 { "get_access_time",
226 (PyCFunction) pyfsntfs_file_entry_get_access_time,
227 METH_NOARGS,
228 "get_access_time() -> Datetime or None\n"
229 "\n"
230 "Returns the access date and time." },
231
232 { "get_access_time_as_integer",
233 (PyCFunction) pyfsntfs_file_entry_get_access_time_as_integer,
234 METH_NOARGS,
235 "get_access_time_as_integer() -> Integer or None\n"
236 "\n"
237 "Returns the access date and time as a 64-bit integer containing a FILETIME value." },
238
239 { "get_entry_modification_time",
240 (PyCFunction) pyfsntfs_file_entry_get_entry_modification_time,
241 METH_NOARGS,
242 "get_entry_modification_time() -> Datetime or None\n"
243 "\n"
244 "Returns the entry modification date and time." },
245
246 { "get_entry_modification_time_as_integer",
247 (PyCFunction) pyfsntfs_file_entry_get_entry_modification_time_as_integer,
248 METH_NOARGS,
249 "get_entry_modification_time_as_integer() -> Integer or None\n"
250 "\n"
251 "Returns the entry modification date and time as a 64-bit integer containing a FILETIME value." },
252
253 { "get_name",
254 (PyCFunction) pyfsntfs_file_entry_get_name,
255 METH_NOARGS,
256 "get_name() -> Unicode string or None\n"
257 "\n"
258 "Returns the name." },
259
260 { "get_name_attribute_index",
261 (PyCFunction) pyfsntfs_file_entry_get_name_attribute_index,
262 METH_NOARGS,
263 "get_name_attribute_index() -> Integer or None\n"
264 "\n"
265 "Returns the attribute index corresponding to the name." },
266
267 { "get_name_by_attribute_index",
268 (PyCFunction) pyfsntfs_file_entry_get_name_by_attribute_index,
269 METH_VARARGS | METH_KEYWORDS,
270 "get_name_by_attribute_index(attribute_index) -> Unicode string or None\n"
271 "\n"
272 "Returns the name." },
273
274 { "get_file_attribute_flags",
275 (PyCFunction) pyfsntfs_file_entry_get_file_attribute_flags,
276 METH_NOARGS,
277 "get_file_attribute_flags() -> Integer or None\n"
278 "\n"
279 "Returns the file attribute flags." },
280
281 { "get_path_hint",
282 (PyCFunction) pyfsntfs_file_entry_get_path_hint,
283 METH_VARARGS | METH_KEYWORDS,
284 "get_path_hint(attribute_index) -> Unicode string or None\n"
285 "\n"
286 "Returns the name." },
287
288 { "get_symbolic_link_target",
289 (PyCFunction) pyfsntfs_file_entry_get_symbolic_link_target,
290 METH_NOARGS,
291 "get_symbolic_link_target() -> Unicode string or None\n"
292 "\n"
293 "Returns the symbolic link target." },
294
295 { "get_security_descriptor_data",
296 (PyCFunction) pyfsntfs_file_entry_get_security_descriptor_data,
297 METH_NOARGS,
298 "get_security_descriptor_data() -> String or None\n"
299 "\n"
300 "Returns the security descriptor data." },
301
302 /* Functions to access the attributes */
303
304 { "get_number_of_attributes",
305 (PyCFunction) pyfsntfs_file_entry_get_number_of_attributes,
306 METH_NOARGS,
307 "get_number_of_attributes() -> Integer\n"
308 "\n"
309 "Retrieves the number of attributes." },
310
311 { "get_attribute",
312 (PyCFunction) pyfsntfs_file_entry_get_attribute,
313 METH_VARARGS | METH_KEYWORDS,
314 "get_attribute(attribute_index) -> Object\n"
315 "\n"
316 "Retrieves a specific attribute." },
317
318 /* Functions to access the alternate data streams */
319
320 { "get_number_of_alternate_data_streams",
321 (PyCFunction) pyfsntfs_file_entry_get_number_of_alternate_data_streams,
322 METH_NOARGS,
323 "get_number_of_alternate_data_streams() -> Integer\n"
324 "\n"
325 "Retrieves the number of alternate data streams." },
326
327 { "get_alternate_data_stream",
328 (PyCFunction) pyfsntfs_file_entry_get_alternate_data_stream,
329 METH_VARARGS | METH_KEYWORDS,
330 "get_alternate_data_stream(alternate_data_stream_index) -> Object\n"
331 "\n"
332 "Retrieves a specific alternate data stream." },
333
334 { "has_alternate_data_stream_by_name",
335 (PyCFunction) pyfsntfs_file_entry_has_alternate_data_stream_by_name,
336 METH_VARARGS | METH_KEYWORDS,
337 "has_alternate_data_stream_by_name(name) -> Boolean\n"
338 "\n"
339 "Determines if there is an alternate data stream specified by the name." },
340
341 { "get_alternate_data_stream_by_name",
342 (PyCFunction) pyfsntfs_file_entry_get_alternate_data_stream_by_name,
343 METH_VARARGS | METH_KEYWORDS,
344 "get_alternate_data_stream_by_name(name) -> Object or None\n"
345 "\n"
346 "Retrieves an alternate data stream specified by the name." },
347
348 /* Functions to access the sub file entries */
349
350 { "get_number_of_sub_file_entries",
351 (PyCFunction) pyfsntfs_file_entry_get_number_of_sub_file_entries,
352 METH_NOARGS,
353 "get_number_of_sub_file_entries() -> Integer\n"
354 "\n"
355 "Retrieves the number of sub file entries." },
356
357 { "get_sub_file_entry",
358 (PyCFunction) pyfsntfs_file_entry_get_sub_file_entry,
359 METH_VARARGS | METH_KEYWORDS,
360 "get_sub_file_entry(sub_file_entry_index) -> Object\n"
361 "\n"
362 "Retrieves a specific sub file entry." },
363
364 /* Sentinel */
365 { NULL, NULL, 0, NULL }
366 };
367
368 PyGetSetDef pyfsntfs_file_entry_object_get_set_definitions[] = {
369
370 { "size",
371 (getter) pyfsntfs_file_entry_get_size,
372 (setter) 0,
373 "The size of the data.",
374 NULL },
375
376 { "number_of_extents",
377 (getter) pyfsntfs_file_entry_get_number_of_extents,
378 (setter) 0,
379 "The number of extents.",
380 NULL },
381
382 { "file_reference",
383 (getter) pyfsntfs_file_entry_get_file_reference,
384 (setter) 0,
385 "The file reference, a combination of MFT entry index and sequence number.",
386 NULL },
387
388 { "base_record_file_reference",
389 (getter) pyfsntfs_file_entry_get_base_record_file_reference,
390 (setter) 0,
391 "The base record file reference, a combination of MFT entry index and sequence number.",
392 NULL },
393
394 { "parent_file_reference",
395 (getter) pyfsntfs_file_entry_get_parent_file_reference,
396 (setter) 0,
397 "The parent file reference, a combination of MFT entry index and sequence number.",
398 NULL },
399
400 { "journal_sequence_number",
401 (getter) pyfsntfs_file_entry_get_journal_sequence_number,
402 (setter) 0,
403 "The journal sequence number.",
404 NULL },
405
406 { "creation_time",
407 (getter) pyfsntfs_file_entry_get_creation_time,
408 (setter) 0,
409 "The creation date and time.",
410 NULL },
411
412 { "modification_time",
413 (getter) pyfsntfs_file_entry_get_modification_time,
414 (setter) 0,
415 "The modification date and time.",
416 NULL },
417
418 { "access_time",
419 (getter) pyfsntfs_file_entry_get_access_time,
420 (setter) 0,
421 "The access date and time.",
422 NULL },
423
424 { "entry_modification_time",
425 (getter) pyfsntfs_file_entry_get_entry_modification_time,
426 (setter) 0,
427 "The entry modification date and time.",
428 NULL },
429
430 { "name",
431 (getter) pyfsntfs_file_entry_get_name,
432 (setter) 0,
433 "The name.",
434 NULL },
435
436 { "name_attribute_index",
437 (getter) pyfsntfs_file_entry_get_name_attribute_index,
438 (setter) 0,
439 "The name.",
440 NULL },
441
442 { "file_attribute_flags",
443 (getter) pyfsntfs_file_entry_get_file_attribute_flags,
444 (setter) 0,
445 "The file attribute flags.",
446 NULL },
447
448 { "symbolic_link_target",
449 (getter) pyfsntfs_file_entry_get_symbolic_link_target,
450 (setter) 0,
451 "The symbolic link target.",
452 NULL },
453
454 { "security_descriptor_data",
455 (getter) pyfsntfs_file_entry_get_security_descriptor_data,
456 (setter) 0,
457 "The security descriptor data.",
458 NULL },
459
460 { "number_of_attributes",
461 (getter) pyfsntfs_file_entry_get_number_of_attributes,
462 (setter) 0,
463 "The number of attributes.",
464 NULL },
465
466 { "attributes",
467 (getter) pyfsntfs_file_entry_get_attributes,
468 (setter) 0,
469 "The attributes",
470 NULL },
471
472 { "number_of_alternate_data_streams",
473 (getter) pyfsntfs_file_entry_get_number_of_alternate_data_streams,
474 (setter) 0,
475 "The number of alternate data streams.",
476 NULL },
477
478 { "alternate_data_streams",
479 (getter) pyfsntfs_file_entry_get_alternate_data_streams,
480 (setter) 0,
481 "The alternate data streams",
482 NULL },
483
484 { "number_of_sub_file_entries",
485 (getter) pyfsntfs_file_entry_get_number_of_sub_file_entries,
486 (setter) 0,
487 "The number of sub file entries.",
488 NULL },
489
490 { "sub_file_entries",
491 (getter) pyfsntfs_file_entry_get_sub_file_entries,
492 (setter) 0,
493 "The sub file entries",
494 NULL },
495
496 /* Sentinel */
497 { NULL, NULL, NULL, NULL, NULL }
498 };
499
500 PyTypeObject pyfsntfs_file_entry_type_object = {
501 PyVarObject_HEAD_INIT( NULL, 0 )
502
503 /* tp_name */
504 "pyfsntfs.file_entry",
505 /* tp_basicsize */
506 sizeof( pyfsntfs_file_entry_t ),
507 /* tp_itemsize */
508 0,
509 /* tp_dealloc */
510 (destructor) pyfsntfs_file_entry_free,
511 /* tp_print */
512 0,
513 /* tp_getattr */
514 0,
515 /* tp_setattr */
516 0,
517 /* tp_compare */
518 0,
519 /* tp_repr */
520 0,
521 /* tp_as_number */
522 0,
523 /* tp_as_sequence */
524 0,
525 /* tp_as_mapping */
526 0,
527 /* tp_hash */
528 0,
529 /* tp_call */
530 0,
531 /* tp_str */
532 0,
533 /* tp_getattro */
534 0,
535 /* tp_setattro */
536 0,
537 /* tp_as_buffer */
538 0,
539 /* tp_flags */
540 Py_TPFLAGS_DEFAULT,
541 /* tp_doc */
542 "pyfsntfs file entry object (wraps libfsntfs_file_entry_t)",
543 /* tp_traverse */
544 0,
545 /* tp_clear */
546 0,
547 /* tp_richcompare */
548 0,
549 /* tp_weaklistoffset */
550 0,
551 /* tp_iter */
552 0,
553 /* tp_iternext */
554 0,
555 /* tp_methods */
556 pyfsntfs_file_entry_object_methods,
557 /* tp_members */
558 0,
559 /* tp_getset */
560 pyfsntfs_file_entry_object_get_set_definitions,
561 /* tp_base */
562 0,
563 /* tp_dict */
564 0,
565 /* tp_descr_get */
566 0,
567 /* tp_descr_set */
568 0,
569 /* tp_dictoffset */
570 0,
571 /* tp_init */
572 (initproc) pyfsntfs_file_entry_init,
573 /* tp_alloc */
574 0,
575 /* tp_new */
576 0,
577 /* tp_free */
578 0,
579 /* tp_is_gc */
580 0,
581 /* tp_bases */
582 NULL,
583 /* tp_mro */
584 NULL,
585 /* tp_cache */
586 NULL,
587 /* tp_subclasses */
588 NULL,
589 /* tp_weaklist */
590 NULL,
591 /* tp_del */
592 0
593 };
594
595 /* Creates a new file entry object
596 * Returns a Python object if successful or NULL on error
597 */
pyfsntfs_file_entry_new(libfsntfs_file_entry_t * file_entry,PyObject * parent_object)598 PyObject *pyfsntfs_file_entry_new(
599 libfsntfs_file_entry_t *file_entry,
600 PyObject *parent_object )
601 {
602 pyfsntfs_file_entry_t *pyfsntfs_file_entry = NULL;
603 static char *function = "pyfsntfs_file_entry_new";
604
605 if( file_entry == NULL )
606 {
607 PyErr_Format(
608 PyExc_ValueError,
609 "%s: invalid file entry.",
610 function );
611
612 return( NULL );
613 }
614 /* PyObject_New does not invoke tp_init
615 */
616 pyfsntfs_file_entry = PyObject_New(
617 struct pyfsntfs_file_entry,
618 &pyfsntfs_file_entry_type_object );
619
620 if( pyfsntfs_file_entry == NULL )
621 {
622 PyErr_Format(
623 PyExc_MemoryError,
624 "%s: unable to initialize file entry.",
625 function );
626
627 goto on_error;
628 }
629 pyfsntfs_file_entry->file_entry = file_entry;
630 pyfsntfs_file_entry->parent_object = parent_object;
631
632 if( pyfsntfs_file_entry->parent_object != NULL )
633 {
634 Py_IncRef(
635 pyfsntfs_file_entry->parent_object );
636 }
637 return( (PyObject *) pyfsntfs_file_entry );
638
639 on_error:
640 if( pyfsntfs_file_entry != NULL )
641 {
642 Py_DecRef(
643 (PyObject *) pyfsntfs_file_entry );
644 }
645 return( NULL );
646 }
647
648 /* Initializes a file entry object
649 * Returns 0 if successful or -1 on error
650 */
pyfsntfs_file_entry_init(pyfsntfs_file_entry_t * pyfsntfs_file_entry)651 int pyfsntfs_file_entry_init(
652 pyfsntfs_file_entry_t *pyfsntfs_file_entry )
653 {
654 static char *function = "pyfsntfs_file_entry_init";
655
656 if( pyfsntfs_file_entry == NULL )
657 {
658 PyErr_Format(
659 PyExc_ValueError,
660 "%s: invalid file entry.",
661 function );
662
663 return( -1 );
664 }
665 /* Make sure libfsntfs file entry is set to NULL
666 */
667 pyfsntfs_file_entry->file_entry = NULL;
668
669 PyErr_Format(
670 PyExc_NotImplementedError,
671 "%s: initialize of file entry not supported.",
672 function );
673
674 return( -1 );
675 }
676
677 /* Frees a file entry object
678 */
pyfsntfs_file_entry_free(pyfsntfs_file_entry_t * pyfsntfs_file_entry)679 void pyfsntfs_file_entry_free(
680 pyfsntfs_file_entry_t *pyfsntfs_file_entry )
681 {
682 struct _typeobject *ob_type = NULL;
683 libcerror_error_t *error = NULL;
684 static char *function = "pyfsntfs_file_entry_free";
685 int result = 0;
686
687 if( pyfsntfs_file_entry == NULL )
688 {
689 PyErr_Format(
690 PyExc_ValueError,
691 "%s: invalid file entry.",
692 function );
693
694 return;
695 }
696 ob_type = Py_TYPE(
697 pyfsntfs_file_entry );
698
699 if( ob_type == NULL )
700 {
701 PyErr_Format(
702 PyExc_ValueError,
703 "%s: missing ob_type.",
704 function );
705
706 return;
707 }
708 if( ob_type->tp_free == NULL )
709 {
710 PyErr_Format(
711 PyExc_ValueError,
712 "%s: invalid ob_type - missing tp_free.",
713 function );
714
715 return;
716 }
717 if( pyfsntfs_file_entry->file_entry != NULL )
718 {
719 Py_BEGIN_ALLOW_THREADS
720
721 result = libfsntfs_file_entry_free(
722 &( pyfsntfs_file_entry->file_entry ),
723 &error );
724
725 Py_END_ALLOW_THREADS
726
727 if( result != 1 )
728 {
729 pyfsntfs_error_raise(
730 error,
731 PyExc_MemoryError,
732 "%s: unable to free libfsntfs file entry.",
733 function );
734
735 libcerror_error_free(
736 &error );
737 }
738 }
739 if( pyfsntfs_file_entry->parent_object != NULL )
740 {
741 Py_DecRef(
742 pyfsntfs_file_entry->parent_object );
743 }
744 ob_type->tp_free(
745 (PyObject*) pyfsntfs_file_entry );
746 }
747
748 /* Reads a buffer of data from the file entry
749 * Returns a Python object holding the data if successful or NULL on error
750 */
pyfsntfs_file_entry_read_buffer(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)751 PyObject *pyfsntfs_file_entry_read_buffer(
752 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
753 PyObject *arguments,
754 PyObject *keywords )
755 {
756 libcerror_error_t *error = NULL;
757 PyObject *integer_object = NULL;
758 PyObject *string_object = NULL;
759 static char *function = "pyfsntfs_file_entry_read_buffer";
760 static char *keyword_list[] = { "size", NULL };
761 char *buffer = NULL;
762 size64_t read_size = 0;
763 ssize_t read_count = 0;
764 int result = 0;
765
766 if( pyfsntfs_file_entry == NULL )
767 {
768 PyErr_Format(
769 PyExc_ValueError,
770 "%s: invalid pyfsntfs file entry.",
771 function );
772
773 return( NULL );
774 }
775 if( pyfsntfs_file_entry->file_entry == NULL )
776 {
777 PyErr_Format(
778 PyExc_ValueError,
779 "%s: invalid pyfsntfs file entry - missing libfsntfs file entry.",
780 function );
781
782 return( NULL );
783 }
784 if( PyArg_ParseTupleAndKeywords(
785 arguments,
786 keywords,
787 "|O",
788 keyword_list,
789 &integer_object ) == 0 )
790 {
791 return( NULL );
792 }
793 PyErr_Clear();
794
795 Py_BEGIN_ALLOW_THREADS
796
797 result = libfsntfs_file_entry_has_default_data_stream(
798 pyfsntfs_file_entry->file_entry,
799 &error );
800
801 Py_END_ALLOW_THREADS
802
803 if( result == -1 )
804 {
805 pyfsntfs_error_raise(
806 error,
807 PyExc_IOError,
808 "%s: unable to determine if file entry has default data stream.",
809 function );
810
811 libcerror_error_free(
812 &error );
813
814 return( NULL );
815 }
816 else if( result == 0 )
817 {
818 PyErr_Format(
819 PyExc_IOError,
820 "%s: missing default data stream.",
821 function );
822
823 return( NULL );
824 }
825 if( integer_object == NULL )
826 {
827 result = 0;
828 }
829 else
830 {
831 result = PyObject_IsInstance(
832 integer_object,
833 (PyObject *) &PyLong_Type );
834
835 if( result == -1 )
836 {
837 pyfsntfs_error_fetch_and_raise(
838 PyExc_RuntimeError,
839 "%s: unable to determine if integer object is of type long.",
840 function );
841
842 return( NULL );
843 }
844 #if PY_MAJOR_VERSION < 3
845 else if( result == 0 )
846 {
847 PyErr_Clear();
848
849 result = PyObject_IsInstance(
850 integer_object,
851 (PyObject *) &PyInt_Type );
852
853 if( result == -1 )
854 {
855 pyfsntfs_error_fetch_and_raise(
856 PyExc_RuntimeError,
857 "%s: unable to determine if integer object is of type int.",
858 function );
859
860 return( NULL );
861 }
862 }
863 #endif
864 }
865 if( result != 0 )
866 {
867 if( pyfsntfs_integer_unsigned_copy_to_64bit(
868 integer_object,
869 (uint64_t *) &read_size,
870 &error ) != 1 )
871 {
872 pyfsntfs_error_raise(
873 error,
874 PyExc_IOError,
875 "%s: unable to convert integer object into read size.",
876 function );
877
878 libcerror_error_free(
879 &error );
880
881 return( NULL );
882 }
883 }
884 else if( ( integer_object == NULL )
885 || ( integer_object == Py_None ) )
886 {
887 Py_BEGIN_ALLOW_THREADS
888
889 result = libfsntfs_file_entry_get_size(
890 pyfsntfs_file_entry->file_entry,
891 &read_size,
892 &error );
893
894 Py_END_ALLOW_THREADS
895
896 if( result != 1 )
897 {
898 pyfsntfs_error_raise(
899 error,
900 PyExc_IOError,
901 "%s: unable to retrieve size.",
902 function );
903
904 libcerror_error_free(
905 &error );
906
907 return( NULL );
908 }
909 }
910 else
911 {
912 PyErr_Format(
913 PyExc_TypeError,
914 "%s: unsupported integer object type.",
915 function );
916
917 return( NULL );
918 }
919 if( read_size == 0 )
920 {
921 #if PY_MAJOR_VERSION >= 3
922 string_object = PyBytes_FromString(
923 "" );
924 #else
925 string_object = PyString_FromString(
926 "" );
927 #endif
928 return( string_object );
929 }
930 /* Make sure the data fits into a memory buffer
931 */
932 if( ( read_size > (size64_t) INT_MAX )
933 || ( read_size > (size64_t) SSIZE_MAX ) )
934 {
935 PyErr_Format(
936 PyExc_ValueError,
937 "%s: invalid argument read size value exceeds maximum.",
938 function );
939
940 return( NULL );
941 }
942 #if PY_MAJOR_VERSION >= 3
943 string_object = PyBytes_FromStringAndSize(
944 NULL,
945 read_size );
946
947 buffer = PyBytes_AsString(
948 string_object );
949 #else
950 /* Note that a size of 0 is not supported
951 */
952 string_object = PyString_FromStringAndSize(
953 NULL,
954 read_size );
955
956 buffer = PyString_AsString(
957 string_object );
958 #endif
959 Py_BEGIN_ALLOW_THREADS
960
961 read_count = libfsntfs_file_entry_read_buffer(
962 pyfsntfs_file_entry->file_entry,
963 (uint8_t *) buffer,
964 (size_t) read_size,
965 &error );
966
967 Py_END_ALLOW_THREADS
968
969 if( read_count <= -1 )
970 {
971 pyfsntfs_error_raise(
972 error,
973 PyExc_IOError,
974 "%s: unable to read data.",
975 function );
976
977 libcerror_error_free(
978 &error );
979
980 Py_DecRef(
981 (PyObject *) string_object );
982
983 return( NULL );
984 }
985 /* Need to resize the string here in case read_size was not fully read.
986 */
987 #if PY_MAJOR_VERSION >= 3
988 if( _PyBytes_Resize(
989 &string_object,
990 (Py_ssize_t) read_count ) != 0 )
991 #else
992 if( _PyString_Resize(
993 &string_object,
994 (Py_ssize_t) read_count ) != 0 )
995 #endif
996 {
997 Py_DecRef(
998 (PyObject *) string_object );
999
1000 return( NULL );
1001 }
1002 return( string_object );
1003 }
1004
1005 /* Reads a buffer of data at a specific foffset from the file entry
1006 * Returns a Python object holding the data if successful or NULL on error
1007 */
pyfsntfs_file_entry_read_buffer_at_offset(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)1008 PyObject *pyfsntfs_file_entry_read_buffer_at_offset(
1009 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1010 PyObject *arguments,
1011 PyObject *keywords )
1012 {
1013 libcerror_error_t *error = NULL;
1014 PyObject *integer_object = NULL;
1015 PyObject *string_object = NULL;
1016 static char *function = "pyfsntfs_file_entry_read_buffer_at_offset";
1017 static char *keyword_list[] = { "size", "offset", NULL };
1018 char *buffer = NULL;
1019 off64_t read_offset = 0;
1020 size64_t read_size = 0;
1021 ssize_t read_count = 0;
1022 int result = 0;
1023
1024 if( pyfsntfs_file_entry == NULL )
1025 {
1026 PyErr_Format(
1027 PyExc_ValueError,
1028 "%s: invalid pyfsntfs file entry.",
1029 function );
1030
1031 return( NULL );
1032 }
1033 if( pyfsntfs_file_entry->file_entry == NULL )
1034 {
1035 PyErr_Format(
1036 PyExc_ValueError,
1037 "%s: invalid pyfsntfs file entry - missing libfsntfs file entry.",
1038 function );
1039
1040 return( NULL );
1041 }
1042 if( PyArg_ParseTupleAndKeywords(
1043 arguments,
1044 keywords,
1045 "OL",
1046 keyword_list,
1047 &integer_object,
1048 &read_offset ) == 0 )
1049 {
1050 return( NULL );
1051 }
1052 Py_BEGIN_ALLOW_THREADS
1053
1054 result = libfsntfs_file_entry_has_default_data_stream(
1055 pyfsntfs_file_entry->file_entry,
1056 &error );
1057
1058 Py_END_ALLOW_THREADS
1059
1060 if( result == -1 )
1061 {
1062 pyfsntfs_error_raise(
1063 error,
1064 PyExc_IOError,
1065 "%s: unable to determine if file entry has default data stream.",
1066 function );
1067
1068 libcerror_error_free(
1069 &error );
1070
1071 return( NULL );
1072 }
1073 else if( result == 0 )
1074 {
1075 PyErr_Format(
1076 PyExc_IOError,
1077 "%s: missing default data stream.",
1078 function );
1079
1080 return( NULL );
1081 }
1082 result = PyObject_IsInstance(
1083 integer_object,
1084 (PyObject *) &PyLong_Type );
1085
1086 if( result == -1 )
1087 {
1088 pyfsntfs_error_fetch_and_raise(
1089 PyExc_RuntimeError,
1090 "%s: unable to determine if integer object is of type long.",
1091 function );
1092
1093 return( NULL );
1094 }
1095 #if PY_MAJOR_VERSION < 3
1096 else if( result == 0 )
1097 {
1098 PyErr_Clear();
1099
1100 result = PyObject_IsInstance(
1101 integer_object,
1102 (PyObject *) &PyInt_Type );
1103
1104 if( result == -1 )
1105 {
1106 pyfsntfs_error_fetch_and_raise(
1107 PyExc_RuntimeError,
1108 "%s: unable to determine if integer object is of type int.",
1109 function );
1110
1111 return( NULL );
1112 }
1113 }
1114 #endif
1115 if( result != 0 )
1116 {
1117 if( pyfsntfs_integer_unsigned_copy_to_64bit(
1118 integer_object,
1119 (uint64_t *) &read_size,
1120 &error ) != 1 )
1121 {
1122 pyfsntfs_error_raise(
1123 error,
1124 PyExc_IOError,
1125 "%s: unable to convert integer object into read size.",
1126 function );
1127
1128 libcerror_error_free(
1129 &error );
1130
1131 return( NULL );
1132 }
1133 }
1134 else if( integer_object == Py_None )
1135 {
1136 Py_BEGIN_ALLOW_THREADS
1137
1138 result = libfsntfs_file_entry_get_size(
1139 pyfsntfs_file_entry->file_entry,
1140 &read_size,
1141 &error );
1142
1143 Py_END_ALLOW_THREADS
1144
1145 if( result != 1 )
1146 {
1147 pyfsntfs_error_raise(
1148 error,
1149 PyExc_IOError,
1150 "%s: unable to retrieve size.",
1151 function );
1152
1153 libcerror_error_free(
1154 &error );
1155
1156 return( NULL );
1157 }
1158 }
1159 else
1160 {
1161 PyErr_Format(
1162 PyExc_TypeError,
1163 "%s: unsupported integer object type.",
1164 function );
1165
1166 return( NULL );
1167 }
1168 if( read_size == 0 )
1169 {
1170 #if PY_MAJOR_VERSION >= 3
1171 string_object = PyBytes_FromString(
1172 "" );
1173 #else
1174 string_object = PyString_FromString(
1175 "" );
1176 #endif
1177 return( string_object );
1178 }
1179 /* Make sure the data fits into a memory buffer
1180 */
1181 if( ( read_size > (size64_t) INT_MAX )
1182 || ( read_size > (size64_t) SSIZE_MAX ) )
1183 {
1184 PyErr_Format(
1185 PyExc_ValueError,
1186 "%s: invalid argument read size value exceeds maximum.",
1187 function );
1188
1189 return( NULL );
1190 }
1191 #if PY_MAJOR_VERSION >= 3
1192 string_object = PyBytes_FromStringAndSize(
1193 NULL,
1194 read_size );
1195
1196 buffer = PyBytes_AsString(
1197 string_object );
1198 #else
1199 /* Note that a size of 0 is not supported
1200 */
1201 string_object = PyString_FromStringAndSize(
1202 NULL,
1203 read_size );
1204
1205 buffer = PyString_AsString(
1206 string_object );
1207 #endif
1208 Py_BEGIN_ALLOW_THREADS
1209
1210 read_count = libfsntfs_file_entry_read_buffer_at_offset(
1211 pyfsntfs_file_entry->file_entry,
1212 (uint8_t *) buffer,
1213 (size_t) read_size,
1214 (off64_t) read_offset,
1215 &error );
1216
1217 Py_END_ALLOW_THREADS
1218
1219 if( read_count <= -1 )
1220 {
1221 pyfsntfs_error_raise(
1222 error,
1223 PyExc_IOError,
1224 "%s: unable to read data.",
1225 function );
1226
1227 libcerror_error_free(
1228 &error );
1229
1230 Py_DecRef(
1231 (PyObject *) string_object );
1232
1233 return( NULL );
1234 }
1235 /* Need to resize the string here in case read_size was not fully read.
1236 */
1237 #if PY_MAJOR_VERSION >= 3
1238 if( _PyBytes_Resize(
1239 &string_object,
1240 (Py_ssize_t) read_count ) != 0 )
1241 #else
1242 if( _PyString_Resize(
1243 &string_object,
1244 (Py_ssize_t) read_count ) != 0 )
1245 #endif
1246 {
1247 Py_DecRef(
1248 (PyObject *) string_object );
1249
1250 return( NULL );
1251 }
1252 return( string_object );
1253 }
1254
1255 /* Seeks a certain offset in the file entry data
1256 * Returns a Python object holding the offset if successful or NULL on error
1257 */
pyfsntfs_file_entry_seek_offset(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)1258 PyObject *pyfsntfs_file_entry_seek_offset(
1259 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1260 PyObject *arguments,
1261 PyObject *keywords )
1262 {
1263 libcerror_error_t *error = NULL;
1264 static char *function = "pyfsntfs_file_entry_seek_offset";
1265 static char *keyword_list[] = { "offset", "whence", NULL };
1266 off64_t offset = 0;
1267 int result = 0;
1268 int whence = 0;
1269
1270 if( pyfsntfs_file_entry == NULL )
1271 {
1272 PyErr_Format(
1273 PyExc_ValueError,
1274 "%s: invalid pyfsntfs file entry.",
1275 function );
1276
1277 return( NULL );
1278 }
1279 if( pyfsntfs_file_entry->file_entry == NULL )
1280 {
1281 PyErr_Format(
1282 PyExc_ValueError,
1283 "%s: invalid pyfsntfs file entry - missing libfsntfs file entry.",
1284 function );
1285
1286 return( NULL );
1287 }
1288 if( PyArg_ParseTupleAndKeywords(
1289 arguments,
1290 keywords,
1291 "L|i",
1292 keyword_list,
1293 &offset,
1294 &whence ) == 0 )
1295 {
1296 return( NULL );
1297 }
1298 Py_BEGIN_ALLOW_THREADS
1299
1300 result = libfsntfs_file_entry_has_default_data_stream(
1301 pyfsntfs_file_entry->file_entry,
1302 &error );
1303
1304 Py_END_ALLOW_THREADS
1305
1306 if( result == -1 )
1307 {
1308 pyfsntfs_error_raise(
1309 error,
1310 PyExc_IOError,
1311 "%s: unable to determine if file entry has default data stream.",
1312 function );
1313
1314 libcerror_error_free(
1315 &error );
1316
1317 return( NULL );
1318 }
1319 else if( result == 0 )
1320 {
1321 PyErr_Format(
1322 PyExc_IOError,
1323 "%s: missing default data stream.",
1324 function );
1325
1326 return( NULL );
1327 }
1328 Py_BEGIN_ALLOW_THREADS
1329
1330 offset = libfsntfs_file_entry_seek_offset(
1331 pyfsntfs_file_entry->file_entry,
1332 offset,
1333 whence,
1334 &error );
1335
1336 Py_END_ALLOW_THREADS
1337
1338 if( offset == -1 )
1339 {
1340 pyfsntfs_error_raise(
1341 error,
1342 PyExc_IOError,
1343 "%s: unable to seek offset.",
1344 function );
1345
1346 libcerror_error_free(
1347 &error );
1348
1349 return( NULL );
1350 }
1351 Py_IncRef(
1352 Py_None );
1353
1354 return( Py_None );
1355 }
1356
1357 /* Retrieves the offset
1358 * Returns a Python object if successful or NULL on error
1359 */
pyfsntfs_file_entry_get_offset(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1360 PyObject *pyfsntfs_file_entry_get_offset(
1361 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1362 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1363 {
1364 libcerror_error_t *error = NULL;
1365 PyObject *integer_object = NULL;
1366 static char *function = "pyfsntfs_file_entry_get_offset";
1367 off64_t offset = 0;
1368 int result = 0;
1369
1370 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1371
1372 if( pyfsntfs_file_entry == NULL )
1373 {
1374 PyErr_Format(
1375 PyExc_ValueError,
1376 "%s: invalid file entry.",
1377 function );
1378
1379 return( NULL );
1380 }
1381 Py_BEGIN_ALLOW_THREADS
1382
1383 result = libfsntfs_file_entry_has_default_data_stream(
1384 pyfsntfs_file_entry->file_entry,
1385 &error );
1386
1387 Py_END_ALLOW_THREADS
1388
1389 if( result == -1 )
1390 {
1391 pyfsntfs_error_raise(
1392 error,
1393 PyExc_IOError,
1394 "%s: unable to determine if file entry has default data stream.",
1395 function );
1396
1397 libcerror_error_free(
1398 &error );
1399
1400 return( NULL );
1401 }
1402 else if( result == 0 )
1403 {
1404 PyErr_Format(
1405 PyExc_IOError,
1406 "%s: missing default data stream.",
1407 function );
1408
1409 return( NULL );
1410 }
1411 Py_BEGIN_ALLOW_THREADS
1412
1413 result = libfsntfs_file_entry_get_offset(
1414 pyfsntfs_file_entry->file_entry,
1415 &offset,
1416 &error );
1417
1418 Py_END_ALLOW_THREADS
1419
1420 if( result != 1 )
1421 {
1422 pyfsntfs_error_raise(
1423 error,
1424 PyExc_IOError,
1425 "%s: unable to retrieve offset.",
1426 function );
1427
1428 libcerror_error_free(
1429 &error );
1430
1431 return( NULL );
1432 }
1433 integer_object = pyfsntfs_integer_signed_new_from_64bit(
1434 (int64_t) offset );
1435
1436 return( integer_object );
1437 }
1438
1439 /* Retrieves the size
1440 * Returns a Python object if successful or NULL on error
1441 */
pyfsntfs_file_entry_get_size(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1442 PyObject *pyfsntfs_file_entry_get_size(
1443 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1444 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1445 {
1446 libcerror_error_t *error = NULL;
1447 PyObject *integer_object = NULL;
1448 static char *function = "pyfsntfs_file_entry_get_size";
1449 size64_t size = 0;
1450 int result = 0;
1451
1452 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1453
1454 if( pyfsntfs_file_entry == NULL )
1455 {
1456 PyErr_Format(
1457 PyExc_ValueError,
1458 "%s: invalid file entry.",
1459 function );
1460
1461 return( NULL );
1462 }
1463 Py_BEGIN_ALLOW_THREADS
1464
1465 result = libfsntfs_file_entry_get_size(
1466 pyfsntfs_file_entry->file_entry,
1467 &size,
1468 &error );
1469
1470 Py_END_ALLOW_THREADS
1471
1472 if( result != 1 )
1473 {
1474 pyfsntfs_error_raise(
1475 error,
1476 PyExc_IOError,
1477 "%s: unable to retrieve size.",
1478 function );
1479
1480 libcerror_error_free(
1481 &error );
1482
1483 return( NULL );
1484 }
1485 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
1486 (uint64_t) size );
1487
1488 return( integer_object );
1489 }
1490
1491 /* Retrieves the number of extents
1492 * Returns a Python object if successful or NULL on error
1493 */
pyfsntfs_file_entry_get_number_of_extents(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1494 PyObject *pyfsntfs_file_entry_get_number_of_extents(
1495 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1496 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1497 {
1498 libcerror_error_t *error = NULL;
1499 PyObject *integer_object = NULL;
1500 static char *function = "pyfsntfs_file_entry_get_number_of_extents";
1501 int number_of_extents = 0;
1502 int result = 0;
1503
1504 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1505
1506 if( pyfsntfs_file_entry == NULL )
1507 {
1508 PyErr_Format(
1509 PyExc_ValueError,
1510 "%s: invalid file entry.",
1511 function );
1512
1513 return( NULL );
1514 }
1515 Py_BEGIN_ALLOW_THREADS
1516
1517 result = libfsntfs_file_entry_get_number_of_extents(
1518 pyfsntfs_file_entry->file_entry,
1519 &number_of_extents,
1520 &error );
1521
1522 Py_END_ALLOW_THREADS
1523
1524 if( result != 1 )
1525 {
1526 pyfsntfs_error_raise(
1527 error,
1528 PyExc_IOError,
1529 "%s: unable to retrieve number of extents.",
1530 function );
1531
1532 libcerror_error_free(
1533 &error );
1534
1535 return( NULL );
1536 }
1537 #if PY_MAJOR_VERSION >= 3
1538 integer_object = PyLong_FromLong(
1539 (long) number_of_extents );
1540 #else
1541 integer_object = PyInt_FromLong(
1542 (long) number_of_extents );
1543 #endif
1544 return( integer_object );
1545 }
1546
1547 /* Retrieves a specific extent by index
1548 * Returns a Python object if successful or NULL on error
1549 */
pyfsntfs_file_entry_get_extent_by_index(pyfsntfs_file_entry_t * pyfsntfs_file_entry,int extent_index)1550 PyObject *pyfsntfs_file_entry_get_extent_by_index(
1551 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1552 int extent_index )
1553 {
1554 libcerror_error_t *error = NULL;
1555 PyObject *integer_object = NULL;
1556 PyObject *tuple_object = NULL;
1557 static char *function = "pyfsntfs_file_entry_get_extent_by_index";
1558 off64_t extent_offset = 0;
1559 size64_t extent_size = 0;
1560 uint32_t extent_flags = 0;
1561 int result = 0;
1562
1563 if( pyfsntfs_file_entry == NULL )
1564 {
1565 PyErr_Format(
1566 PyExc_ValueError,
1567 "%s: invalid file entry.",
1568 function );
1569
1570 return( NULL );
1571 }
1572 Py_BEGIN_ALLOW_THREADS
1573
1574 result = libfsntfs_file_entry_get_extent_by_index(
1575 pyfsntfs_file_entry->file_entry,
1576 extent_index,
1577 &extent_offset,
1578 &extent_size,
1579 &extent_flags,
1580 &error );
1581
1582 Py_END_ALLOW_THREADS
1583
1584 if( result != 1 )
1585 {
1586 pyfsntfs_error_raise(
1587 error,
1588 PyExc_IOError,
1589 "%s: unable to retrieve extent: %d.",
1590 function,
1591 extent_index );
1592
1593 libcerror_error_free(
1594 &error );
1595
1596 goto on_error;
1597 }
1598 tuple_object = PyTuple_New(
1599 3 );
1600
1601 integer_object = pyfsntfs_integer_signed_new_from_64bit(
1602 (int64_t) extent_offset );
1603
1604 /* Tuple set item does not increment the reference count of the integer object
1605 */
1606 if( PyTuple_SetItem(
1607 tuple_object,
1608 0,
1609 integer_object ) != 0 )
1610 {
1611 goto on_error;
1612 }
1613 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
1614 (uint64_t) extent_size );
1615
1616 /* Tuple set item does not increment the reference count of the integer object
1617 */
1618 if( PyTuple_SetItem(
1619 tuple_object,
1620 1,
1621 integer_object ) != 0 )
1622 {
1623 goto on_error;
1624 }
1625 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
1626 (uint64_t) extent_flags );
1627
1628 /* Tuple set item does not increment the reference count of the integer object
1629 */
1630 if( PyTuple_SetItem(
1631 tuple_object,
1632 2,
1633 integer_object ) != 0 )
1634 {
1635 goto on_error;
1636 }
1637 return( tuple_object );
1638
1639 on_error:
1640 if( integer_object != NULL )
1641 {
1642 Py_DecRef(
1643 (PyObject *) integer_object );
1644 }
1645 if( tuple_object != NULL )
1646 {
1647 Py_DecRef(
1648 (PyObject *) tuple_object );
1649 }
1650 return( NULL );
1651 }
1652
1653 /* Retrieves a specific extent
1654 * Returns a Python object if successful or NULL on error
1655 */
pyfsntfs_file_entry_get_extent(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)1656 PyObject *pyfsntfs_file_entry_get_extent(
1657 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1658 PyObject *arguments,
1659 PyObject *keywords )
1660 {
1661 PyObject *sequence_object = NULL;
1662 static char *keyword_list[] = { "extent_index", NULL };
1663 int extent_index = 0;
1664
1665 if( PyArg_ParseTupleAndKeywords(
1666 arguments,
1667 keywords,
1668 "i",
1669 keyword_list,
1670 &extent_index ) == 0 )
1671 {
1672 return( NULL );
1673 }
1674 sequence_object = pyfsntfs_file_entry_get_extent_by_index(
1675 pyfsntfs_file_entry,
1676 extent_index );
1677
1678 return( sequence_object );
1679 }
1680
1681 /* Determines if the file entry is empty
1682 * Returns a Python object if successful or NULL on error
1683 */
pyfsntfs_file_entry_is_empty(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1684 PyObject *pyfsntfs_file_entry_is_empty(
1685 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1686 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1687 {
1688 libcerror_error_t *error = NULL;
1689 static char *function = "pyfsntfs_file_entry_is_empty";
1690 int result = 0;
1691
1692 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1693
1694 if( pyfsntfs_file_entry == NULL )
1695 {
1696 PyErr_Format(
1697 PyExc_ValueError,
1698 "%s: invalid file entry.",
1699 function );
1700
1701 return( NULL );
1702 }
1703 Py_BEGIN_ALLOW_THREADS
1704
1705 result = libfsntfs_file_entry_is_empty(
1706 pyfsntfs_file_entry->file_entry,
1707 &error );
1708
1709 Py_END_ALLOW_THREADS
1710
1711 if( result == -1 )
1712 {
1713 pyfsntfs_error_raise(
1714 error,
1715 PyExc_IOError,
1716 "%s: unable to determine if file entry is empty.",
1717 function );
1718
1719 libcerror_error_free(
1720 &error );
1721
1722 return( NULL );
1723 }
1724 if( result != 0 )
1725 {
1726 Py_IncRef(
1727 (PyObject *) Py_True );
1728
1729 return( Py_True );
1730 }
1731 Py_IncRef(
1732 (PyObject *) Py_False );
1733
1734 return( Py_False );
1735 }
1736
1737 /* Determines if the file entry is allocated (in use)
1738 * Returns a Python object if successful or NULL on error
1739 */
pyfsntfs_file_entry_is_allocated(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1740 PyObject *pyfsntfs_file_entry_is_allocated(
1741 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1742 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1743 {
1744 libcerror_error_t *error = NULL;
1745 static char *function = "pyfsntfs_file_entry_is_allocated";
1746 int result = 0;
1747
1748 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1749
1750 if( pyfsntfs_file_entry == NULL )
1751 {
1752 PyErr_Format(
1753 PyExc_ValueError,
1754 "%s: invalid file entry.",
1755 function );
1756
1757 return( NULL );
1758 }
1759 Py_BEGIN_ALLOW_THREADS
1760
1761 result = libfsntfs_file_entry_is_allocated(
1762 pyfsntfs_file_entry->file_entry,
1763 &error );
1764
1765 Py_END_ALLOW_THREADS
1766
1767 if( result == -1 )
1768 {
1769 pyfsntfs_error_raise(
1770 error,
1771 PyExc_IOError,
1772 "%s: unable to determine if file entry is allocated.",
1773 function );
1774
1775 libcerror_error_free(
1776 &error );
1777
1778 return( NULL );
1779 }
1780 if( result != 0 )
1781 {
1782 Py_IncRef(
1783 (PyObject *) Py_True );
1784
1785 return( Py_True );
1786 }
1787 Py_IncRef(
1788 (PyObject *) Py_False );
1789
1790 return( Py_False );
1791 }
1792
1793 /* Determines if the file entry has the directory entries index
1794 * Returns a Python object if successful or NULL on error
1795 */
pyfsntfs_file_entry_has_directory_entries_index(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1796 PyObject *pyfsntfs_file_entry_has_directory_entries_index(
1797 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1798 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1799 {
1800 libcerror_error_t *error = NULL;
1801 static char *function = "pyfsntfs_file_entry_has_directory_entries_index";
1802 int result = 0;
1803
1804 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1805
1806 if( pyfsntfs_file_entry == NULL )
1807 {
1808 PyErr_Format(
1809 PyExc_ValueError,
1810 "%s: invalid file entry.",
1811 function );
1812
1813 return( NULL );
1814 }
1815 Py_BEGIN_ALLOW_THREADS
1816
1817 result = libfsntfs_file_entry_has_directory_entries_index(
1818 pyfsntfs_file_entry->file_entry,
1819 &error );
1820
1821 Py_END_ALLOW_THREADS
1822
1823 if( result == -1 )
1824 {
1825 pyfsntfs_error_raise(
1826 error,
1827 PyExc_IOError,
1828 "%s: unable to determine if file entry has directory entries index.",
1829 function );
1830
1831 libcerror_error_free(
1832 &error );
1833
1834 return( NULL );
1835 }
1836 if( result != 0 )
1837 {
1838 Py_IncRef(
1839 (PyObject *) Py_True );
1840
1841 return( Py_True );
1842 }
1843 Py_IncRef(
1844 (PyObject *) Py_False );
1845
1846 return( Py_False );
1847 }
1848
1849 /* Determines if the file entry has the default data stream
1850 * Returns a Python object if successful or NULL on error
1851 */
pyfsntfs_file_entry_has_default_data_stream(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1852 PyObject *pyfsntfs_file_entry_has_default_data_stream(
1853 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1854 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1855 {
1856 libcerror_error_t *error = NULL;
1857 static char *function = "pyfsntfs_file_entry_has_default_data_stream";
1858 int result = 0;
1859
1860 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1861
1862 if( pyfsntfs_file_entry == NULL )
1863 {
1864 PyErr_Format(
1865 PyExc_ValueError,
1866 "%s: invalid file entry.",
1867 function );
1868
1869 return( NULL );
1870 }
1871 Py_BEGIN_ALLOW_THREADS
1872
1873 result = libfsntfs_file_entry_has_default_data_stream(
1874 pyfsntfs_file_entry->file_entry,
1875 &error );
1876
1877 Py_END_ALLOW_THREADS
1878
1879 if( result == -1 )
1880 {
1881 pyfsntfs_error_raise(
1882 error,
1883 PyExc_IOError,
1884 "%s: unable to determine if file entry has default data stream.",
1885 function );
1886
1887 libcerror_error_free(
1888 &error );
1889
1890 return( NULL );
1891 }
1892 else if( result != 0 )
1893 {
1894 Py_IncRef(
1895 (PyObject *) Py_True );
1896
1897 return( Py_True );
1898 }
1899 Py_IncRef(
1900 (PyObject *) Py_False );
1901
1902 return( Py_False );
1903 }
1904
1905 /* Retrieves the file reference
1906 * Returns a Python object if successful or NULL on error
1907 */
pyfsntfs_file_entry_get_file_reference(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1908 PyObject *pyfsntfs_file_entry_get_file_reference(
1909 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1910 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1911 {
1912 libcerror_error_t *error = NULL;
1913 PyObject *integer_object = NULL;
1914 static char *function = "pyfsntfs_file_entry_get_file_reference";
1915 uint64_t file_reference = 0;
1916 int result = 0;
1917
1918 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1919
1920 if( pyfsntfs_file_entry == NULL )
1921 {
1922 PyErr_Format(
1923 PyExc_ValueError,
1924 "%s: invalid file entry.",
1925 function );
1926
1927 return( NULL );
1928 }
1929 Py_BEGIN_ALLOW_THREADS
1930
1931 result = libfsntfs_file_entry_get_file_reference(
1932 pyfsntfs_file_entry->file_entry,
1933 &file_reference,
1934 &error );
1935
1936 Py_END_ALLOW_THREADS
1937
1938 if( result != 1 )
1939 {
1940 pyfsntfs_error_raise(
1941 error,
1942 PyExc_IOError,
1943 "%s: unable to retrieve file reference.",
1944 function );
1945
1946 libcerror_error_free(
1947 &error );
1948
1949 return( NULL );
1950 }
1951 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
1952 file_reference );
1953
1954 return( integer_object );
1955 }
1956
1957 /* Retrieves the base record file reference
1958 * Returns a Python object if successful or NULL on error
1959 */
pyfsntfs_file_entry_get_base_record_file_reference(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)1960 PyObject *pyfsntfs_file_entry_get_base_record_file_reference(
1961 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
1962 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
1963 {
1964 libcerror_error_t *error = NULL;
1965 PyObject *integer_object = NULL;
1966 static char *function = "pyfsntfs_file_entry_get_base_record_file_reference";
1967 uint64_t file_reference = 0;
1968 int result = 0;
1969
1970 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
1971
1972 if( pyfsntfs_file_entry == NULL )
1973 {
1974 PyErr_Format(
1975 PyExc_ValueError,
1976 "%s: invalid file entry.",
1977 function );
1978
1979 return( NULL );
1980 }
1981 Py_BEGIN_ALLOW_THREADS
1982
1983 result = libfsntfs_file_entry_get_base_record_file_reference(
1984 pyfsntfs_file_entry->file_entry,
1985 &file_reference,
1986 &error );
1987
1988 Py_END_ALLOW_THREADS
1989
1990 if( result != 1 )
1991 {
1992 pyfsntfs_error_raise(
1993 error,
1994 PyExc_IOError,
1995 "%s: unable to retrieve base record file reference.",
1996 function );
1997
1998 libcerror_error_free(
1999 &error );
2000
2001 return( NULL );
2002 }
2003 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2004 file_reference );
2005
2006 return( integer_object );
2007 }
2008
2009 /* Retrieves the parent file reference
2010 * Returns a Python object if successful or NULL on error
2011 */
pyfsntfs_file_entry_get_parent_file_reference(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2012 PyObject *pyfsntfs_file_entry_get_parent_file_reference(
2013 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2014 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2015 {
2016 libcerror_error_t *error = NULL;
2017 PyObject *integer_object = NULL;
2018 static char *function = "pyfsntfs_file_entry_get_parent_file_reference";
2019 uint64_t file_reference = 0;
2020 int result = 0;
2021
2022 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2023
2024 if( pyfsntfs_file_entry == NULL )
2025 {
2026 PyErr_Format(
2027 PyExc_ValueError,
2028 "%s: invalid file entry.",
2029 function );
2030
2031 return( NULL );
2032 }
2033 Py_BEGIN_ALLOW_THREADS
2034
2035 result = libfsntfs_file_entry_get_parent_file_reference(
2036 pyfsntfs_file_entry->file_entry,
2037 &file_reference,
2038 &error );
2039
2040 Py_END_ALLOW_THREADS
2041
2042 if( result == -1 )
2043 {
2044 pyfsntfs_error_raise(
2045 error,
2046 PyExc_IOError,
2047 "%s: unable to retrieve parent file reference.",
2048 function );
2049
2050 libcerror_error_free(
2051 &error );
2052
2053 return( NULL );
2054 }
2055 else if( result == 0 )
2056 {
2057 Py_IncRef(
2058 Py_None );
2059
2060 return( Py_None );
2061 }
2062 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2063 file_reference );
2064
2065 return( integer_object );
2066 }
2067
2068 /* Retrieves the parent file reference for a specific $FILE_NAME attribute
2069 * Returns a Python object if successful or NULL on error
2070 */
pyfsntfs_file_entry_get_parent_file_reference_by_attribute_index(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)2071 PyObject *pyfsntfs_file_entry_get_parent_file_reference_by_attribute_index(
2072 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2073 PyObject *arguments,
2074 PyObject *keywords )
2075 {
2076 libcerror_error_t *error = NULL;
2077 PyObject *integer_object = NULL;
2078 static char *function = "pyfsntfs_file_entry_get_parent_file_reference_by_attribute_index";
2079 static char *keyword_list[] = { "attribute_index", NULL };
2080 uint64_t file_reference = 0;
2081 int attribute_index = 0;
2082 int result = 0;
2083
2084 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2085
2086 if( pyfsntfs_file_entry == NULL )
2087 {
2088 PyErr_Format(
2089 PyExc_ValueError,
2090 "%s: invalid file entry.",
2091 function );
2092
2093 return( NULL );
2094 }
2095 if( PyArg_ParseTupleAndKeywords(
2096 arguments,
2097 keywords,
2098 "i",
2099 keyword_list,
2100 &attribute_index ) == 0 )
2101 {
2102 return( NULL );
2103 }
2104 Py_BEGIN_ALLOW_THREADS
2105
2106 result = libfsntfs_file_entry_get_parent_file_reference_by_attribute_index(
2107 pyfsntfs_file_entry->file_entry,
2108 attribute_index,
2109 &file_reference,
2110 &error );
2111
2112 Py_END_ALLOW_THREADS
2113
2114 if( result != 1 )
2115 {
2116 pyfsntfs_error_raise(
2117 error,
2118 PyExc_IOError,
2119 "%s: unable to retrieve parent file reference from attribute: %d.",
2120 function,
2121 attribute_index );
2122
2123 libcerror_error_free(
2124 &error );
2125
2126 return( NULL );
2127 }
2128 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2129 file_reference );
2130
2131 return( integer_object );
2132 }
2133
2134 /* Retrieves the journal sequence number
2135 * Returns a Python object if successful or NULL on error
2136 */
pyfsntfs_file_entry_get_journal_sequence_number(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2137 PyObject *pyfsntfs_file_entry_get_journal_sequence_number(
2138 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2139 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2140 {
2141 libcerror_error_t *error = NULL;
2142 PyObject *integer_object = NULL;
2143 static char *function = "pyfsntfs_file_entry_get_journal_sequence_number";
2144 uint64_t journal_sequence_number = 0;
2145 int result = 0;
2146
2147 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2148
2149 if( pyfsntfs_file_entry == NULL )
2150 {
2151 PyErr_Format(
2152 PyExc_ValueError,
2153 "%s: invalid file entry.",
2154 function );
2155
2156 return( NULL );
2157 }
2158 Py_BEGIN_ALLOW_THREADS
2159
2160 result = libfsntfs_file_entry_get_journal_sequence_number(
2161 pyfsntfs_file_entry->file_entry,
2162 &journal_sequence_number,
2163 &error );
2164
2165 Py_END_ALLOW_THREADS
2166
2167 if( result != 1 )
2168 {
2169 pyfsntfs_error_raise(
2170 error,
2171 PyExc_IOError,
2172 "%s: unable to retrieve journal sequence number.",
2173 function );
2174
2175 libcerror_error_free(
2176 &error );
2177
2178 return( NULL );
2179 }
2180 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2181 journal_sequence_number );
2182
2183 return( integer_object );
2184 }
2185
2186 /* Retrieves the creation date and time
2187 * Returns a Python object if successful or NULL on error
2188 */
pyfsntfs_file_entry_get_creation_time(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2189 PyObject *pyfsntfs_file_entry_get_creation_time(
2190 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2191 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2192 {
2193 libcerror_error_t *error = NULL;
2194 PyObject *date_time_object = NULL;
2195 static char *function = "pyfsntfs_file_entry_get_creation_time";
2196 uint64_t filetime = 0;
2197 int result = 0;
2198
2199 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2200
2201 if( pyfsntfs_file_entry == NULL )
2202 {
2203 PyErr_Format(
2204 PyExc_ValueError,
2205 "%s: invalid file entry.",
2206 function );
2207
2208 return( NULL );
2209 }
2210 Py_BEGIN_ALLOW_THREADS
2211
2212 result = libfsntfs_file_entry_get_creation_time(
2213 pyfsntfs_file_entry->file_entry,
2214 &filetime,
2215 &error );
2216
2217 Py_END_ALLOW_THREADS
2218
2219 if( result == -1 )
2220 {
2221 pyfsntfs_error_raise(
2222 error,
2223 PyExc_IOError,
2224 "%s: unable to retrieve creation time.",
2225 function );
2226
2227 libcerror_error_free(
2228 &error );
2229
2230 return( NULL );
2231 }
2232 else if( result == 0 )
2233 {
2234 Py_IncRef(
2235 Py_None );
2236
2237 return( Py_None );
2238 }
2239 date_time_object = pyfsntfs_datetime_new_from_filetime(
2240 filetime );
2241
2242 return( date_time_object );
2243 }
2244
2245 /* Retrieves the creation date and time as an integer
2246 * Returns a Python object if successful or NULL on error
2247 */
pyfsntfs_file_entry_get_creation_time_as_integer(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2248 PyObject *pyfsntfs_file_entry_get_creation_time_as_integer(
2249 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2250 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2251 {
2252 libcerror_error_t *error = NULL;
2253 PyObject *integer_object = NULL;
2254 static char *function = "pyfsntfs_file_entry_get_creation_time_as_integer";
2255 uint64_t filetime = 0;
2256 int result = 0;
2257
2258 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2259
2260 if( pyfsntfs_file_entry == NULL )
2261 {
2262 PyErr_Format(
2263 PyExc_ValueError,
2264 "%s: invalid file entry.",
2265 function );
2266
2267 return( NULL );
2268 }
2269 Py_BEGIN_ALLOW_THREADS
2270
2271 result = libfsntfs_file_entry_get_creation_time(
2272 pyfsntfs_file_entry->file_entry,
2273 &filetime,
2274 &error );
2275
2276 Py_END_ALLOW_THREADS
2277
2278 if( result == -1 )
2279 {
2280 pyfsntfs_error_raise(
2281 error,
2282 PyExc_IOError,
2283 "%s: unable to retrieve creation time.",
2284 function );
2285
2286 libcerror_error_free(
2287 &error );
2288
2289 return( NULL );
2290 }
2291 else if( result == 0 )
2292 {
2293 Py_IncRef(
2294 Py_None );
2295
2296 return( Py_None );
2297 }
2298 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2299 filetime );
2300
2301 return( integer_object );
2302 }
2303
2304 /* Retrieves the modification date and time
2305 * Returns a Python object if successful or NULL on error
2306 */
pyfsntfs_file_entry_get_modification_time(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2307 PyObject *pyfsntfs_file_entry_get_modification_time(
2308 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2309 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2310 {
2311 libcerror_error_t *error = NULL;
2312 PyObject *date_time_object = NULL;
2313 static char *function = "pyfsntfs_file_entry_get_modification_time";
2314 uint64_t filetime = 0;
2315 int result = 0;
2316
2317 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2318
2319 if( pyfsntfs_file_entry == NULL )
2320 {
2321 PyErr_Format(
2322 PyExc_ValueError,
2323 "%s: invalid file entry.",
2324 function );
2325
2326 return( NULL );
2327 }
2328 Py_BEGIN_ALLOW_THREADS
2329
2330 result = libfsntfs_file_entry_get_modification_time(
2331 pyfsntfs_file_entry->file_entry,
2332 &filetime,
2333 &error );
2334
2335 Py_END_ALLOW_THREADS
2336
2337 if( result == -1 )
2338 {
2339 pyfsntfs_error_raise(
2340 error,
2341 PyExc_IOError,
2342 "%s: unable to retrieve modification time.",
2343 function );
2344
2345 libcerror_error_free(
2346 &error );
2347
2348 return( NULL );
2349 }
2350 else if( result == 0 )
2351 {
2352 Py_IncRef(
2353 Py_None );
2354
2355 return( Py_None );
2356 }
2357 date_time_object = pyfsntfs_datetime_new_from_filetime(
2358 filetime );
2359
2360 return( date_time_object );
2361 }
2362
2363 /* Retrieves the modification date and time as an integer
2364 * Returns a Python object if successful or NULL on error
2365 */
pyfsntfs_file_entry_get_modification_time_as_integer(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2366 PyObject *pyfsntfs_file_entry_get_modification_time_as_integer(
2367 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2368 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2369 {
2370 libcerror_error_t *error = NULL;
2371 PyObject *integer_object = NULL;
2372 static char *function = "pyfsntfs_file_entry_get_modification_time_as_integer";
2373 uint64_t filetime = 0;
2374 int result = 0;
2375
2376 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2377
2378 if( pyfsntfs_file_entry == NULL )
2379 {
2380 PyErr_Format(
2381 PyExc_ValueError,
2382 "%s: invalid file entry.",
2383 function );
2384
2385 return( NULL );
2386 }
2387 Py_BEGIN_ALLOW_THREADS
2388
2389 result = libfsntfs_file_entry_get_modification_time(
2390 pyfsntfs_file_entry->file_entry,
2391 &filetime,
2392 &error );
2393
2394 Py_END_ALLOW_THREADS
2395
2396 if( result == -1 )
2397 {
2398 pyfsntfs_error_raise(
2399 error,
2400 PyExc_IOError,
2401 "%s: unable to retrieve modification time.",
2402 function );
2403
2404 libcerror_error_free(
2405 &error );
2406
2407 return( NULL );
2408 }
2409 else if( result == 0 )
2410 {
2411 Py_IncRef(
2412 Py_None );
2413
2414 return( Py_None );
2415 }
2416 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2417 filetime );
2418
2419 return( integer_object );
2420 }
2421
2422 /* Retrieves the access date and time
2423 * Returns a Python object if successful or NULL on error
2424 */
pyfsntfs_file_entry_get_access_time(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2425 PyObject *pyfsntfs_file_entry_get_access_time(
2426 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2427 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2428 {
2429 libcerror_error_t *error = NULL;
2430 PyObject *date_time_object = NULL;
2431 static char *function = "pyfsntfs_file_entry_get_access_time";
2432 uint64_t filetime = 0;
2433 int result = 0;
2434
2435 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2436
2437 if( pyfsntfs_file_entry == NULL )
2438 {
2439 PyErr_Format(
2440 PyExc_ValueError,
2441 "%s: invalid file entry.",
2442 function );
2443
2444 return( NULL );
2445 }
2446 Py_BEGIN_ALLOW_THREADS
2447
2448 result = libfsntfs_file_entry_get_access_time(
2449 pyfsntfs_file_entry->file_entry,
2450 &filetime,
2451 &error );
2452
2453 Py_END_ALLOW_THREADS
2454
2455 if( result == -1 )
2456 {
2457 pyfsntfs_error_raise(
2458 error,
2459 PyExc_IOError,
2460 "%s: unable to retrieve access time.",
2461 function );
2462
2463 libcerror_error_free(
2464 &error );
2465
2466 return( NULL );
2467 }
2468 else if( result == 0 )
2469 {
2470 Py_IncRef(
2471 Py_None );
2472
2473 return( Py_None );
2474 }
2475 date_time_object = pyfsntfs_datetime_new_from_filetime(
2476 filetime );
2477
2478 return( date_time_object );
2479 }
2480
2481 /* Retrieves the access date and time as an integer
2482 * Returns a Python object if successful or NULL on error
2483 */
pyfsntfs_file_entry_get_access_time_as_integer(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2484 PyObject *pyfsntfs_file_entry_get_access_time_as_integer(
2485 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2486 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2487 {
2488 libcerror_error_t *error = NULL;
2489 PyObject *integer_object = NULL;
2490 static char *function = "pyfsntfs_file_entry_get_access_time_as_integer";
2491 uint64_t filetime = 0;
2492 int result = 0;
2493
2494 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2495
2496 if( pyfsntfs_file_entry == NULL )
2497 {
2498 PyErr_Format(
2499 PyExc_ValueError,
2500 "%s: invalid file entry.",
2501 function );
2502
2503 return( NULL );
2504 }
2505 Py_BEGIN_ALLOW_THREADS
2506
2507 result = libfsntfs_file_entry_get_access_time(
2508 pyfsntfs_file_entry->file_entry,
2509 &filetime,
2510 &error );
2511
2512 Py_END_ALLOW_THREADS
2513
2514 if( result == -1 )
2515 {
2516 pyfsntfs_error_raise(
2517 error,
2518 PyExc_IOError,
2519 "%s: unable to retrieve access time.",
2520 function );
2521
2522 libcerror_error_free(
2523 &error );
2524
2525 return( NULL );
2526 }
2527 else if( result == 0 )
2528 {
2529 Py_IncRef(
2530 Py_None );
2531
2532 return( Py_None );
2533 }
2534 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
2535 filetime );
2536
2537 return( integer_object );
2538 }
2539
2540 /* Retrieves the entry modification date and time
2541 * Returns a Python object if successful or NULL on error
2542 */
pyfsntfs_file_entry_get_entry_modification_time(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2543 PyObject *pyfsntfs_file_entry_get_entry_modification_time(
2544 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2545 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2546 {
2547 libcerror_error_t *error = NULL;
2548 PyObject *date_time_object = NULL;
2549 static char *function = "pyfsntfs_file_entry_get_entry_modification_time";
2550 uint64_t filetime = 0;
2551 int result = 0;
2552
2553 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2554
2555 if( pyfsntfs_file_entry == NULL )
2556 {
2557 PyErr_Format(
2558 PyExc_ValueError,
2559 "%s: invalid file entry.",
2560 function );
2561
2562 return( NULL );
2563 }
2564 Py_BEGIN_ALLOW_THREADS
2565
2566 result = libfsntfs_file_entry_get_entry_modification_time(
2567 pyfsntfs_file_entry->file_entry,
2568 &filetime,
2569 &error );
2570
2571 Py_END_ALLOW_THREADS
2572
2573 if( result == -1 )
2574 {
2575 pyfsntfs_error_raise(
2576 error,
2577 PyExc_IOError,
2578 "%s: unable to retrieve entry modification time.",
2579 function );
2580
2581 libcerror_error_free(
2582 &error );
2583
2584 return( NULL );
2585 }
2586 else if( result == 0 )
2587 {
2588 Py_IncRef(
2589 Py_None );
2590
2591 return( Py_None );
2592 }
2593 date_time_object = pyfsntfs_datetime_new_from_filetime(
2594 filetime );
2595
2596 return( date_time_object );
2597 }
2598
2599 /* Retrieves the entry modification date and time as an integer
2600 * Returns a Python object if successful or NULL on error
2601 */
pyfsntfs_file_entry_get_entry_modification_time_as_integer(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2602 PyObject *pyfsntfs_file_entry_get_entry_modification_time_as_integer(
2603 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2604 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2605 {
2606 libcerror_error_t *error = NULL;
2607 PyObject *integer_object = NULL;
2608 static char *function = "pyfsntfs_file_entry_get_entry_modification_time_as_integer";
2609 uint64_t filetime = 0;
2610 int result = 0;
2611
2612 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2613
2614 if( pyfsntfs_file_entry == NULL )
2615 {
2616 PyErr_Format(
2617 PyExc_ValueError,
2618 "%s: invalid file entry.",
2619 function );
2620
2621 return( NULL );
2622 }
2623 Py_BEGIN_ALLOW_THREADS
2624
2625 result = libfsntfs_file_entry_get_entry_modification_time(
2626 pyfsntfs_file_entry->file_entry,
2627 &filetime,
2628 &error );
2629
2630 Py_END_ALLOW_THREADS
2631
2632 if( result == -1 )
2633 {
2634 pyfsntfs_error_raise(
2635 error,
2636 PyExc_IOError,
2637 "%s: unable to retrieve entry modification time.",
2638 function );
2639
2640 libcerror_error_free(
2641 &error );
2642
2643 return( NULL );
2644 }
2645 else if( result == 0 )
2646 {
2647 Py_IncRef(
2648 Py_None );
2649
2650 return( Py_None );
2651 }
2652 integer_object = pyfsntfs_integer_signed_new_from_64bit(
2653 filetime );
2654
2655 return( integer_object );
2656 }
2657
2658 /* Retrieves the name
2659 * Returns a Python object if successful or NULL on error
2660 */
pyfsntfs_file_entry_get_name(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2661 PyObject *pyfsntfs_file_entry_get_name(
2662 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2663 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2664 {
2665 libcerror_error_t *error = NULL;
2666 PyObject *string_object = NULL;
2667 const char *errors = NULL;
2668 uint8_t *name = NULL;
2669 static char *function = "pyfsntfs_file_entry_get_name";
2670 size_t name_size = 0;
2671 int result = 0;
2672
2673 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2674
2675 if( pyfsntfs_file_entry == NULL )
2676 {
2677 PyErr_Format(
2678 PyExc_ValueError,
2679 "%s: invalid file entry.",
2680 function );
2681
2682 return( NULL );
2683 }
2684 Py_BEGIN_ALLOW_THREADS
2685
2686 result = libfsntfs_file_entry_get_utf8_name_size(
2687 pyfsntfs_file_entry->file_entry,
2688 &name_size,
2689 &error );
2690
2691 Py_END_ALLOW_THREADS
2692
2693 if( result == -1 )
2694 {
2695 pyfsntfs_error_raise(
2696 error,
2697 PyExc_IOError,
2698 "%s: unable to retrieve name size.",
2699 function );
2700
2701 libcerror_error_free(
2702 &error );
2703
2704 goto on_error;
2705 }
2706 else if( ( result == 0 )
2707 || ( name_size == 0 ) )
2708 {
2709 Py_IncRef(
2710 Py_None );
2711
2712 return( Py_None );
2713 }
2714 name = (uint8_t *) PyMem_Malloc(
2715 sizeof( uint8_t ) * name_size );
2716
2717 if( name == NULL )
2718 {
2719 PyErr_Format(
2720 PyExc_IOError,
2721 "%s: unable to create name.",
2722 function );
2723
2724 goto on_error;
2725 }
2726 Py_BEGIN_ALLOW_THREADS
2727
2728 result = libfsntfs_file_entry_get_utf8_name(
2729 pyfsntfs_file_entry->file_entry,
2730 name,
2731 name_size,
2732 &error );
2733
2734 Py_END_ALLOW_THREADS
2735
2736 if( result != 1 )
2737 {
2738 pyfsntfs_error_raise(
2739 error,
2740 PyExc_IOError,
2741 "%s: unable to retrieve name.",
2742 function );
2743
2744 libcerror_error_free(
2745 &error );
2746
2747 goto on_error;
2748 }
2749 /* Pass the string length to PyUnicode_DecodeUTF8
2750 * otherwise it makes the end of string character is part
2751 * of the string
2752 */
2753 string_object = PyUnicode_DecodeUTF8(
2754 (char *) name,
2755 (Py_ssize_t) name_size - 1,
2756 errors );
2757
2758 PyMem_Free(
2759 name );
2760
2761 return( string_object );
2762
2763 on_error:
2764 if( name != NULL )
2765 {
2766 PyMem_Free(
2767 name );
2768 }
2769 return( NULL );
2770 }
2771
2772 /* Retrieves the name attribute index
2773 * Returns a Python object if successful or NULL on error
2774 */
pyfsntfs_file_entry_get_name_attribute_index(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2775 PyObject *pyfsntfs_file_entry_get_name_attribute_index(
2776 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2777 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2778 {
2779 libcerror_error_t *error = NULL;
2780 PyObject *integer_object = NULL;
2781 static char *function = "pyfsntfs_file_entry_get_name_attribute_index";
2782 int attribute_index = 0;
2783 int result = 0;
2784
2785 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2786
2787 if( pyfsntfs_file_entry == NULL )
2788 {
2789 PyErr_Format(
2790 PyExc_ValueError,
2791 "%s: invalid file entry.",
2792 function );
2793
2794 return( NULL );
2795 }
2796 Py_BEGIN_ALLOW_THREADS
2797
2798 result = libfsntfs_file_entry_get_name_attribute_index(
2799 pyfsntfs_file_entry->file_entry,
2800 &attribute_index,
2801 &error );
2802
2803 Py_END_ALLOW_THREADS
2804
2805 if( result == -1 )
2806 {
2807 pyfsntfs_error_raise(
2808 error,
2809 PyExc_IOError,
2810 "%s: unable to retrieve name attribute index.",
2811 function );
2812
2813 libcerror_error_free(
2814 &error );
2815
2816 return( NULL );
2817 }
2818 else if( result == 0 )
2819 {
2820 Py_IncRef(
2821 Py_None );
2822
2823 return( Py_None );
2824 }
2825 #if PY_MAJOR_VERSION >= 3
2826 integer_object = PyLong_FromLong(
2827 (long) attribute_index );
2828 #else
2829 integer_object = PyInt_FromLong(
2830 (long) attribute_index );
2831 #endif
2832 return( integer_object );
2833 }
2834
2835 /* Retrieves the name for a specific $FILE_NAME attribute
2836 * Returns a Python object if successful or NULL on error
2837 */
pyfsntfs_file_entry_get_name_by_attribute_index(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)2838 PyObject *pyfsntfs_file_entry_get_name_by_attribute_index(
2839 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2840 PyObject *arguments,
2841 PyObject *keywords )
2842 {
2843 libcerror_error_t *error = NULL;
2844 PyObject *string_object = NULL;
2845 const char *errors = NULL;
2846 uint8_t *name = NULL;
2847 static char *function = "pyfsntfs_file_entry_get_name_by_attribute_index";
2848 static char *keyword_list[] = { "attribute_index", NULL };
2849 size_t name_size = 0;
2850 int attribute_index = 0;
2851 int result = 0;
2852
2853 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2854
2855 if( pyfsntfs_file_entry == NULL )
2856 {
2857 PyErr_Format(
2858 PyExc_ValueError,
2859 "%s: invalid file entry.",
2860 function );
2861
2862 return( NULL );
2863 }
2864 if( PyArg_ParseTupleAndKeywords(
2865 arguments,
2866 keywords,
2867 "i",
2868 keyword_list,
2869 &attribute_index ) == 0 )
2870 {
2871 return( NULL );
2872 }
2873 Py_BEGIN_ALLOW_THREADS
2874
2875 result = libfsntfs_file_entry_get_utf8_name_size_by_attribute_index(
2876 pyfsntfs_file_entry->file_entry,
2877 attribute_index,
2878 &name_size,
2879 &error );
2880
2881 Py_END_ALLOW_THREADS
2882
2883 if( result != 1 )
2884 {
2885 pyfsntfs_error_raise(
2886 error,
2887 PyExc_IOError,
2888 "%s: unable to retrieve name size.",
2889 function );
2890
2891 libcerror_error_free(
2892 &error );
2893
2894 goto on_error;
2895 }
2896 else if( name_size == 0 )
2897 {
2898 Py_IncRef(
2899 Py_None );
2900
2901 return( Py_None );
2902 }
2903 name = (uint8_t *) PyMem_Malloc(
2904 sizeof( uint8_t ) * name_size );
2905
2906 if( name == NULL )
2907 {
2908 PyErr_Format(
2909 PyExc_IOError,
2910 "%s: unable to create name.",
2911 function );
2912
2913 goto on_error;
2914 }
2915 Py_BEGIN_ALLOW_THREADS
2916
2917 result = libfsntfs_file_entry_get_utf8_name_by_attribute_index(
2918 pyfsntfs_file_entry->file_entry,
2919 attribute_index,
2920 name,
2921 name_size,
2922 &error );
2923
2924 Py_END_ALLOW_THREADS
2925
2926 if( result != 1 )
2927 {
2928 pyfsntfs_error_raise(
2929 error,
2930 PyExc_IOError,
2931 "%s: unable to retrieve name.",
2932 function );
2933
2934 libcerror_error_free(
2935 &error );
2936
2937 goto on_error;
2938 }
2939 /* Pass the string length to PyUnicode_DecodeUTF8
2940 * otherwise it makes the end of string character is part
2941 * of the string
2942 */
2943 string_object = PyUnicode_DecodeUTF8(
2944 (char *) name,
2945 (Py_ssize_t) name_size - 1,
2946 errors );
2947
2948 PyMem_Free(
2949 name );
2950
2951 return( string_object );
2952
2953 on_error:
2954 if( name != NULL )
2955 {
2956 PyMem_Free(
2957 name );
2958 }
2959 return( NULL );
2960 }
2961
2962 /* Retrieves the file attribute flags
2963 * Returns a Python object if successful or NULL on error
2964 */
pyfsntfs_file_entry_get_file_attribute_flags(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)2965 PyObject *pyfsntfs_file_entry_get_file_attribute_flags(
2966 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
2967 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
2968 {
2969 libcerror_error_t *error = NULL;
2970 PyObject *integer_object = NULL;
2971 static char *function = "pyfsntfs_file_entry_get_file_entry_flags";
2972 uint32_t file_attribute_flags = 0;
2973 int result = 0;
2974
2975 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
2976
2977 if( pyfsntfs_file_entry == NULL )
2978 {
2979 PyErr_Format(
2980 PyExc_ValueError,
2981 "%s: invalid file entry.",
2982 function );
2983
2984 return( NULL );
2985 }
2986 Py_BEGIN_ALLOW_THREADS
2987
2988 result = libfsntfs_file_entry_get_file_attribute_flags(
2989 pyfsntfs_file_entry->file_entry,
2990 &file_attribute_flags,
2991 &error );
2992
2993 Py_END_ALLOW_THREADS
2994
2995 if( result == -1 )
2996 {
2997 pyfsntfs_error_raise(
2998 error,
2999 PyExc_IOError,
3000 "%s: unable to retrieve file attribute flags.",
3001 function );
3002
3003 libcerror_error_free(
3004 &error );
3005
3006 return( NULL );
3007 }
3008 else if( result == 0 )
3009 {
3010 Py_IncRef(
3011 Py_None );
3012
3013 return( Py_None );
3014 }
3015 integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
3016 (uint64_t) file_attribute_flags );
3017
3018 return( integer_object );
3019 }
3020
3021 /* Retrieves the path hint for a specific $FILE_NAME attribute
3022 * Returns a Python object if successful or NULL on error
3023 */
pyfsntfs_file_entry_get_path_hint(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)3024 PyObject *pyfsntfs_file_entry_get_path_hint(
3025 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3026 PyObject *arguments,
3027 PyObject *keywords )
3028 {
3029 libcerror_error_t *error = NULL;
3030 PyObject *string_object = NULL;
3031 const char *errors = NULL;
3032 uint8_t *path = NULL;
3033 static char *function = "pyfsntfs_file_entry_get_path_hint";
3034 static char *keyword_list[] = { "attribute_index", NULL };
3035 size_t path_size = 0;
3036 int attribute_index = 0;
3037 int result = 0;
3038
3039 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3040
3041 if( pyfsntfs_file_entry == NULL )
3042 {
3043 PyErr_Format(
3044 PyExc_ValueError,
3045 "%s: invalid file entry.",
3046 function );
3047
3048 return( NULL );
3049 }
3050 if( PyArg_ParseTupleAndKeywords(
3051 arguments,
3052 keywords,
3053 "i",
3054 keyword_list,
3055 &attribute_index ) == 0 )
3056 {
3057 return( NULL );
3058 }
3059 Py_BEGIN_ALLOW_THREADS
3060
3061 result = libfsntfs_file_entry_get_utf8_path_hint_size(
3062 pyfsntfs_file_entry->file_entry,
3063 attribute_index,
3064 &path_size,
3065 &error );
3066
3067 Py_END_ALLOW_THREADS
3068
3069 if( result != 1 )
3070 {
3071 pyfsntfs_error_raise(
3072 error,
3073 PyExc_IOError,
3074 "%s: unable to retrieve path size.",
3075 function );
3076
3077 libcerror_error_free(
3078 &error );
3079
3080 goto on_error;
3081 }
3082 else if( path_size == 0 )
3083 {
3084 Py_IncRef(
3085 Py_None );
3086
3087 return( Py_None );
3088 }
3089 path = (uint8_t *) PyMem_Malloc(
3090 sizeof( uint8_t ) * path_size );
3091
3092 if( path == NULL )
3093 {
3094 PyErr_Format(
3095 PyExc_IOError,
3096 "%s: unable to create path.",
3097 function );
3098
3099 goto on_error;
3100 }
3101 Py_BEGIN_ALLOW_THREADS
3102
3103 result = libfsntfs_file_entry_get_utf8_path_hint(
3104 pyfsntfs_file_entry->file_entry,
3105 attribute_index,
3106 path,
3107 path_size,
3108 &error );
3109
3110 Py_END_ALLOW_THREADS
3111
3112 if( result != 1 )
3113 {
3114 pyfsntfs_error_raise(
3115 error,
3116 PyExc_IOError,
3117 "%s: unable to retrieve path.",
3118 function );
3119
3120 libcerror_error_free(
3121 &error );
3122
3123 goto on_error;
3124 }
3125 /* Pass the string length to PyUnicode_DecodeUTF8
3126 * otherwise it makes the end of string character is part
3127 * of the string
3128 */
3129 string_object = PyUnicode_DecodeUTF8(
3130 (char *) path,
3131 (Py_ssize_t) path_size - 1,
3132 errors );
3133
3134 PyMem_Free(
3135 path );
3136
3137 return( string_object );
3138
3139 on_error:
3140 if( path != NULL )
3141 {
3142 PyMem_Free(
3143 path );
3144 }
3145 return( NULL );
3146 }
3147
3148 /* Retrieves the symbolic link target
3149 * Returns a Python object if successful or NULL on error
3150 */
pyfsntfs_file_entry_get_symbolic_link_target(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3151 PyObject *pyfsntfs_file_entry_get_symbolic_link_target(
3152 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3153 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3154 {
3155 libcerror_error_t *error = NULL;
3156 PyObject *string_object = NULL;
3157 const char *errors = NULL;
3158 uint8_t *name = NULL;
3159 static char *function = "pyfsntfs_file_entry_get_symbolic_link_target";
3160 size_t name_size = 0;
3161 int result = 0;
3162
3163 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3164
3165 if( pyfsntfs_file_entry == NULL )
3166 {
3167 PyErr_Format(
3168 PyExc_ValueError,
3169 "%s: invalid file entry.",
3170 function );
3171
3172 return( NULL );
3173 }
3174 Py_BEGIN_ALLOW_THREADS
3175
3176 result = libfsntfs_file_entry_get_utf8_symbolic_link_target_size(
3177 pyfsntfs_file_entry->file_entry,
3178 &name_size,
3179 &error );
3180
3181 Py_END_ALLOW_THREADS
3182
3183 if( result == -1 )
3184 {
3185 pyfsntfs_error_raise(
3186 error,
3187 PyExc_IOError,
3188 "%s: unable to retrieve symbolic link target size.",
3189 function );
3190
3191 libcerror_error_free(
3192 &error );
3193
3194 goto on_error;
3195 }
3196 else if( ( result == 0 )
3197 || ( name_size == 0 ) )
3198 {
3199 Py_IncRef(
3200 Py_None );
3201
3202 return( Py_None );
3203 }
3204 name = (uint8_t *) PyMem_Malloc(
3205 sizeof( uint8_t ) * name_size );
3206
3207 if( name == NULL )
3208 {
3209 PyErr_Format(
3210 PyExc_IOError,
3211 "%s: unable to create name.",
3212 function );
3213
3214 goto on_error;
3215 }
3216 Py_BEGIN_ALLOW_THREADS
3217
3218 result = libfsntfs_file_entry_get_utf8_symbolic_link_target(
3219 pyfsntfs_file_entry->file_entry,
3220 name,
3221 name_size,
3222 &error );
3223
3224 Py_END_ALLOW_THREADS
3225
3226 if( result != 1 )
3227 {
3228 pyfsntfs_error_raise(
3229 error,
3230 PyExc_IOError,
3231 "%s: unable to retrieve symbolic link target.",
3232 function );
3233
3234 libcerror_error_free(
3235 &error );
3236
3237 goto on_error;
3238 }
3239 /* Pass the string length to PyUnicode_DecodeUTF8
3240 * otherwise it makes the end of string character is part
3241 * of the string
3242 */
3243 string_object = PyUnicode_DecodeUTF8(
3244 (char *) name,
3245 (Py_ssize_t) name_size - 1,
3246 errors );
3247
3248 PyMem_Free(
3249 name );
3250
3251 return( string_object );
3252
3253 on_error:
3254 if( name != NULL )
3255 {
3256 PyMem_Free(
3257 name );
3258 }
3259 return( NULL );
3260 }
3261
3262 /* Retrieves the security descriptor data
3263 * Returns a Python object if successful or NULL on error
3264 */
pyfsntfs_file_entry_get_security_descriptor_data(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3265 PyObject *pyfsntfs_file_entry_get_security_descriptor_data(
3266 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3267 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3268 {
3269 libcerror_error_t *error = NULL;
3270 PyObject *string_object = NULL;
3271 static char *function = "pyfsntfs_file_entry_get_security_descriptor_data";
3272 char *security_desciptor_data = NULL;
3273 size_t security_desciptor_data_size = 0;
3274 int result = 0;
3275
3276 if( pyfsntfs_file_entry == NULL )
3277 {
3278 PyErr_Format(
3279 PyExc_ValueError,
3280 "%s: invalid file entry.",
3281 function );
3282
3283 return( NULL );
3284 }
3285 Py_BEGIN_ALLOW_THREADS
3286
3287 result = libfsntfs_file_entry_get_security_descriptor_size(
3288 pyfsntfs_file_entry->file_entry,
3289 &security_desciptor_data_size,
3290 &error );
3291
3292 Py_END_ALLOW_THREADS
3293
3294 if( result == -1 )
3295 {
3296 pyfsntfs_error_raise(
3297 error,
3298 PyExc_IOError,
3299 "%s: unable to determine security descriptor data size.",
3300 function );
3301
3302 libcerror_error_free(
3303 &error );
3304
3305 return( NULL );
3306 }
3307 else if( result == 0 )
3308 {
3309 Py_IncRef(
3310 Py_None );
3311
3312 return( Py_None );
3313 }
3314 #if PY_MAJOR_VERSION >= 3
3315 string_object = PyBytes_FromStringAndSize(
3316 NULL,
3317 security_desciptor_data_size );
3318
3319 security_desciptor_data = PyBytes_AsString(
3320 string_object );
3321 #else
3322 /* Note that a size of 0 is not supported
3323 */
3324 string_object = PyString_FromStringAndSize(
3325 NULL,
3326 security_desciptor_data_size );
3327
3328 security_desciptor_data = PyString_AsString(
3329 string_object );
3330 #endif
3331 Py_BEGIN_ALLOW_THREADS
3332
3333 result = libfsntfs_file_entry_get_security_descriptor(
3334 pyfsntfs_file_entry->file_entry,
3335 (uint8_t *) security_desciptor_data,
3336 security_desciptor_data_size,
3337 &error );
3338
3339 Py_END_ALLOW_THREADS
3340
3341 if( result != 1 )
3342 {
3343 pyfsntfs_error_raise(
3344 error,
3345 PyExc_IOError,
3346 "%s: unable to retrieve security descriptor data.",
3347 function );
3348
3349 libcerror_error_free(
3350 &error );
3351
3352 Py_DecRef(
3353 (PyObject *) string_object );
3354
3355 return( NULL );
3356 }
3357 return( string_object );
3358 }
3359
3360 /* Retrieves the number of attributes
3361 * Returns a Python object if successful or NULL on error
3362 */
pyfsntfs_file_entry_get_number_of_attributes(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3363 PyObject *pyfsntfs_file_entry_get_number_of_attributes(
3364 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3365 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3366 {
3367 libcerror_error_t *error = NULL;
3368 PyObject *integer_object = NULL;
3369 static char *function = "pyfsntfs_file_entry_get_number_of_attributes";
3370 int number_of_attributes = 0;
3371 int result = 0;
3372
3373 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3374
3375 if( pyfsntfs_file_entry == NULL )
3376 {
3377 PyErr_Format(
3378 PyExc_ValueError,
3379 "%s: invalid file entry.",
3380 function );
3381
3382 return( NULL );
3383 }
3384 Py_BEGIN_ALLOW_THREADS
3385
3386 result = libfsntfs_file_entry_get_number_of_attributes(
3387 pyfsntfs_file_entry->file_entry,
3388 &number_of_attributes,
3389 &error );
3390
3391 Py_END_ALLOW_THREADS
3392
3393 if( result != 1 )
3394 {
3395 pyfsntfs_error_raise(
3396 error,
3397 PyExc_IOError,
3398 "%s: unable to retrieve number of attributes.",
3399 function );
3400
3401 libcerror_error_free(
3402 &error );
3403
3404 return( NULL );
3405 }
3406 #if PY_MAJOR_VERSION >= 3
3407 integer_object = PyLong_FromLong(
3408 (long) number_of_attributes );
3409 #else
3410 integer_object = PyInt_FromLong(
3411 (long) number_of_attributes );
3412 #endif
3413 return( integer_object );
3414 }
3415
3416 /* Retrieves a specific attribute by index
3417 * Returns a Python object if successful or NULL on error
3418 */
pyfsntfs_file_entry_get_attribute_by_index(PyObject * pyfsntfs_file_entry,int attribute_index)3419 PyObject *pyfsntfs_file_entry_get_attribute_by_index(
3420 PyObject *pyfsntfs_file_entry,
3421 int attribute_index )
3422 {
3423 libcerror_error_t *error = NULL;
3424 libfsntfs_attribute_t *attribute = NULL;
3425 PyObject *attribute_object = NULL;
3426 PyTypeObject *type_object = NULL;
3427 static char *function = "pyfsntfs_file_entry_get_attribute_by_index";
3428 uint32_t attribute_type = 0;
3429 int result = 0;
3430
3431 if( pyfsntfs_file_entry == NULL )
3432 {
3433 PyErr_Format(
3434 PyExc_ValueError,
3435 "%s: invalid file entry.",
3436 function );
3437
3438 return( NULL );
3439 }
3440 Py_BEGIN_ALLOW_THREADS
3441
3442 result = libfsntfs_file_entry_get_attribute_by_index(
3443 ( (pyfsntfs_file_entry_t *) pyfsntfs_file_entry )->file_entry,
3444 attribute_index,
3445 &attribute,
3446 &error );
3447
3448 Py_END_ALLOW_THREADS
3449
3450 if( result != 1 )
3451 {
3452 pyfsntfs_error_raise(
3453 error,
3454 PyExc_IOError,
3455 "%s: unable to retrieve attribute: %d.",
3456 function,
3457 attribute_index );
3458
3459 libcerror_error_free(
3460 &error );
3461
3462 goto on_error;
3463 }
3464 Py_BEGIN_ALLOW_THREADS
3465
3466 result = libfsntfs_attribute_get_type(
3467 attribute,
3468 &attribute_type,
3469 &error );
3470
3471 Py_END_ALLOW_THREADS
3472
3473 if( result != 1 )
3474 {
3475 pyfsntfs_error_raise(
3476 error,
3477 PyExc_IOError,
3478 "%s: unable to retrieve type.",
3479 function );
3480
3481 libcerror_error_free(
3482 &error );
3483
3484 return( NULL );
3485 }
3486 switch( attribute_type )
3487 {
3488 case LIBFSNTFS_ATTRIBUTE_TYPE_FILE_NAME:
3489 type_object = &pyfsntfs_file_name_attribute_type_object;
3490 break;
3491
3492 case LIBFSNTFS_ATTRIBUTE_TYPE_OBJECT_IDENTIFIER:
3493 type_object = &pyfsntfs_object_identifier_attribute_type_object;
3494 break;
3495
3496 case LIBFSNTFS_ATTRIBUTE_TYPE_REPARSE_POINT:
3497 type_object = &pyfsntfs_reparse_point_attribute_type_object;
3498 break;
3499
3500 case LIBFSNTFS_ATTRIBUTE_TYPE_SECURITY_DESCRIPTOR:
3501 type_object = &pyfsntfs_security_descriptor_attribute_type_object;
3502 break;
3503
3504 case LIBFSNTFS_ATTRIBUTE_TYPE_STANDARD_INFORMATION:
3505 type_object = &pyfsntfs_standard_information_attribute_type_object;
3506 break;
3507
3508 case LIBFSNTFS_ATTRIBUTE_TYPE_VOLUME_INFORMATION:
3509 type_object = &pyfsntfs_volume_information_attribute_type_object;
3510 break;
3511
3512 case LIBFSNTFS_ATTRIBUTE_TYPE_VOLUME_NAME:
3513 type_object = &pyfsntfs_volume_name_attribute_type_object;
3514 break;
3515
3516 default:
3517 type_object = &pyfsntfs_attribute_type_object;
3518 break;
3519 }
3520 attribute_object = pyfsntfs_attribute_new(
3521 type_object,
3522 attribute,
3523 pyfsntfs_file_entry );
3524
3525 if( attribute_object == NULL )
3526 {
3527 PyErr_Format(
3528 PyExc_MemoryError,
3529 "%s: unable to create attribute object.",
3530 function );
3531
3532 goto on_error;
3533 }
3534 return( attribute_object );
3535
3536 on_error:
3537 if( attribute != NULL )
3538 {
3539 libfsntfs_attribute_free(
3540 &attribute,
3541 NULL );
3542 }
3543 return( NULL );
3544 }
3545
3546 /* Retrieves a specific attribute
3547 * Returns a Python object if successful or NULL on error
3548 */
pyfsntfs_file_entry_get_attribute(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)3549 PyObject *pyfsntfs_file_entry_get_attribute(
3550 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3551 PyObject *arguments,
3552 PyObject *keywords )
3553 {
3554 PyObject *attribute_object = NULL;
3555 static char *keyword_list[] = { "attribute_index", NULL };
3556 int attribute_index = 0;
3557
3558 if( PyArg_ParseTupleAndKeywords(
3559 arguments,
3560 keywords,
3561 "i",
3562 keyword_list,
3563 &attribute_index ) == 0 )
3564 {
3565 return( NULL );
3566 }
3567 attribute_object = pyfsntfs_file_entry_get_attribute_by_index(
3568 (PyObject *) pyfsntfs_file_entry,
3569 attribute_index );
3570
3571 return( attribute_object );
3572 }
3573
3574 /* Retrieves an attributes sequence and iterator object for the attributes
3575 * Returns a Python object if successful or NULL on error
3576 */
pyfsntfs_file_entry_get_attributes(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3577 PyObject *pyfsntfs_file_entry_get_attributes(
3578 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3579 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3580 {
3581 libcerror_error_t *error = NULL;
3582 PyObject *attributes_object = NULL;
3583 static char *function = "pyfsntfs_file_entry_get_attributes";
3584 int number_of_attributes = 0;
3585 int result = 0;
3586
3587 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3588
3589 if( pyfsntfs_file_entry == NULL )
3590 {
3591 PyErr_Format(
3592 PyExc_ValueError,
3593 "%s: invalid file entry.",
3594 function );
3595
3596 return( NULL );
3597 }
3598 Py_BEGIN_ALLOW_THREADS
3599
3600 result = libfsntfs_file_entry_get_number_of_attributes(
3601 pyfsntfs_file_entry->file_entry,
3602 &number_of_attributes,
3603 &error );
3604
3605 Py_END_ALLOW_THREADS
3606
3607 if( result != 1 )
3608 {
3609 pyfsntfs_error_raise(
3610 error,
3611 PyExc_IOError,
3612 "%s: unable to retrieve number of attributes.",
3613 function );
3614
3615 libcerror_error_free(
3616 &error );
3617
3618 return( NULL );
3619 }
3620 attributes_object = pyfsntfs_attributes_new(
3621 (PyObject *) pyfsntfs_file_entry,
3622 &pyfsntfs_file_entry_get_attribute_by_index,
3623 number_of_attributes );
3624
3625 if( attributes_object == NULL )
3626 {
3627 PyErr_Format(
3628 PyExc_MemoryError,
3629 "%s: unable to create attributes object.",
3630 function );
3631
3632 return( NULL );
3633 }
3634 return( attributes_object );
3635 }
3636
3637 /* Retrieves the number of alternate data streams
3638 * Returns a Python object if successful or NULL on error
3639 */
pyfsntfs_file_entry_get_number_of_alternate_data_streams(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3640 PyObject *pyfsntfs_file_entry_get_number_of_alternate_data_streams(
3641 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3642 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3643 {
3644 libcerror_error_t *error = NULL;
3645 PyObject *integer_object = NULL;
3646 static char *function = "pyfsntfs_file_entry_get_number_of_alternate_data_streams";
3647 int number_of_alternate_data_streams = 0;
3648 int result = 0;
3649
3650 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3651
3652 if( pyfsntfs_file_entry == NULL )
3653 {
3654 PyErr_Format(
3655 PyExc_ValueError,
3656 "%s: invalid file entry.",
3657 function );
3658
3659 return( NULL );
3660 }
3661 Py_BEGIN_ALLOW_THREADS
3662
3663 result = libfsntfs_file_entry_get_number_of_alternate_data_streams(
3664 pyfsntfs_file_entry->file_entry,
3665 &number_of_alternate_data_streams,
3666 &error );
3667
3668 Py_END_ALLOW_THREADS
3669
3670 if( result != 1 )
3671 {
3672 pyfsntfs_error_raise(
3673 error,
3674 PyExc_IOError,
3675 "%s: unable to retrieve number of alternate data streams.",
3676 function );
3677
3678 libcerror_error_free(
3679 &error );
3680
3681 return( NULL );
3682 }
3683 #if PY_MAJOR_VERSION >= 3
3684 integer_object = PyLong_FromLong(
3685 (long) number_of_alternate_data_streams );
3686 #else
3687 integer_object = PyInt_FromLong(
3688 (long) number_of_alternate_data_streams );
3689 #endif
3690 return( integer_object );
3691 }
3692
3693 /* Retrieves a specific alternate data stream by index
3694 * Returns a Python object if successful or NULL on error
3695 */
pyfsntfs_file_entry_get_alternate_data_stream_by_index(PyObject * pyfsntfs_file_entry,int alternate_data_stream_index)3696 PyObject *pyfsntfs_file_entry_get_alternate_data_stream_by_index(
3697 PyObject *pyfsntfs_file_entry,
3698 int alternate_data_stream_index )
3699 {
3700 libcerror_error_t *error = NULL;
3701 libfsntfs_data_stream_t *data_stream = NULL;
3702 PyObject *data_stream_object = NULL;
3703 static char *function = "pyfsntfs_file_entry_get_alternate_data_stream_by_index";
3704 int result = 0;
3705
3706 if( pyfsntfs_file_entry == NULL )
3707 {
3708 PyErr_Format(
3709 PyExc_ValueError,
3710 "%s: invalid file entry.",
3711 function );
3712
3713 return( NULL );
3714 }
3715 Py_BEGIN_ALLOW_THREADS
3716
3717 result = libfsntfs_file_entry_get_alternate_data_stream_by_index(
3718 ( (pyfsntfs_file_entry_t *) pyfsntfs_file_entry )->file_entry,
3719 alternate_data_stream_index,
3720 &data_stream,
3721 &error );
3722
3723 Py_END_ALLOW_THREADS
3724
3725 if( result != 1 )
3726 {
3727 pyfsntfs_error_raise(
3728 error,
3729 PyExc_IOError,
3730 "%s: unable to retrieve alternate data stream: %d.",
3731 function,
3732 alternate_data_stream_index );
3733
3734 libcerror_error_free(
3735 &error );
3736
3737 goto on_error;
3738 }
3739 data_stream_object = pyfsntfs_data_stream_new(
3740 data_stream,
3741 pyfsntfs_file_entry );
3742
3743 if( data_stream_object == NULL )
3744 {
3745 PyErr_Format(
3746 PyExc_MemoryError,
3747 "%s: unable to create alternate data stream object.",
3748 function );
3749
3750 goto on_error;
3751 }
3752 return( data_stream_object );
3753
3754 on_error:
3755 if( data_stream != NULL )
3756 {
3757 libfsntfs_data_stream_free(
3758 &data_stream,
3759 NULL );
3760 }
3761 return( NULL );
3762 }
3763
3764 /* Retrieves a specific alternate data stream
3765 * Returns a Python object if successful or NULL on error
3766 */
pyfsntfs_file_entry_get_alternate_data_stream(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)3767 PyObject *pyfsntfs_file_entry_get_alternate_data_stream(
3768 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3769 PyObject *arguments,
3770 PyObject *keywords )
3771 {
3772 PyObject *data_stream_object = NULL;
3773 static char *keyword_list[] = { "alternate_data_stream_index", NULL };
3774 int alternate_data_stream_index = 0;
3775
3776 if( PyArg_ParseTupleAndKeywords(
3777 arguments,
3778 keywords,
3779 "i",
3780 keyword_list,
3781 &alternate_data_stream_index ) == 0 )
3782 {
3783 return( NULL );
3784 }
3785 data_stream_object = pyfsntfs_file_entry_get_alternate_data_stream_by_index(
3786 (PyObject *) pyfsntfs_file_entry,
3787 alternate_data_stream_index );
3788
3789 return( data_stream_object );
3790 }
3791
3792 /* Retrieves a data streams sequence and iterator object for the alternate data streams
3793 * Returns a Python object if successful or NULL on error
3794 */
pyfsntfs_file_entry_get_alternate_data_streams(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)3795 PyObject *pyfsntfs_file_entry_get_alternate_data_streams(
3796 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3797 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
3798 {
3799 libcerror_error_t *error = NULL;
3800 PyObject *data_streams_object = NULL;
3801 static char *function = "pyfsntfs_file_entry_get_alternate_data_streams";
3802 int number_of_alternate_data_streams = 0;
3803 int result = 0;
3804
3805 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
3806
3807 if( pyfsntfs_file_entry == NULL )
3808 {
3809 PyErr_Format(
3810 PyExc_ValueError,
3811 "%s: invalid file entry.",
3812 function );
3813
3814 return( NULL );
3815 }
3816 Py_BEGIN_ALLOW_THREADS
3817
3818 result = libfsntfs_file_entry_get_number_of_alternate_data_streams(
3819 pyfsntfs_file_entry->file_entry,
3820 &number_of_alternate_data_streams,
3821 &error );
3822
3823 Py_END_ALLOW_THREADS
3824
3825 if( result != 1 )
3826 {
3827 pyfsntfs_error_raise(
3828 error,
3829 PyExc_IOError,
3830 "%s: unable to retrieve number of alternate data streams.",
3831 function );
3832
3833 libcerror_error_free(
3834 &error );
3835
3836 return( NULL );
3837 }
3838 data_streams_object = pyfsntfs_data_streams_new(
3839 (PyObject *) pyfsntfs_file_entry,
3840 &pyfsntfs_file_entry_get_alternate_data_stream_by_index,
3841 number_of_alternate_data_streams );
3842
3843 if( data_streams_object == NULL )
3844 {
3845 PyErr_Format(
3846 PyExc_MemoryError,
3847 "%s: unable to create data streams object.",
3848 function );
3849
3850 return( NULL );
3851 }
3852 return( data_streams_object );
3853 }
3854
3855 /* Determines if there is an alternate data stream specified by the name
3856 * Returns a Python object if successful or NULL on error
3857 */
pyfsntfs_file_entry_has_alternate_data_stream_by_name(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)3858 PyObject *pyfsntfs_file_entry_has_alternate_data_stream_by_name(
3859 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3860 PyObject *arguments,
3861 PyObject *keywords )
3862 {
3863 libcerror_error_t *error = NULL;
3864 char *data_stream_name = NULL;
3865 static char *keyword_list[] = { "data_stream_name", NULL };
3866 static char *function = "pyfsntfs_file_entry_has_alternate_data_stream_by_name";
3867 size_t data_stream_name_length = 0;
3868 int result = 0;
3869
3870 if( pyfsntfs_file_entry == NULL )
3871 {
3872 PyErr_Format(
3873 PyExc_ValueError,
3874 "%s: invalid file entry.",
3875 function );
3876
3877 return( NULL );
3878 }
3879 if( PyArg_ParseTupleAndKeywords(
3880 arguments,
3881 keywords,
3882 "s",
3883 keyword_list,
3884 &data_stream_name ) == 0 )
3885 {
3886 return( NULL );
3887 }
3888 data_stream_name_length = narrow_string_length(
3889 data_stream_name );
3890
3891 Py_BEGIN_ALLOW_THREADS
3892
3893 result = libfsntfs_file_entry_has_alternate_data_stream_by_utf8_name(
3894 pyfsntfs_file_entry->file_entry,
3895 (uint8_t *) data_stream_name,
3896 data_stream_name_length,
3897 &error );
3898
3899 Py_END_ALLOW_THREADS
3900
3901 if( result == -1 )
3902 {
3903 pyfsntfs_error_raise(
3904 error,
3905 PyExc_IOError,
3906 "%s: unable to determine if alternate data stream exists.",
3907 function );
3908
3909 libcerror_error_free(
3910 &error );
3911
3912 return( NULL );
3913 }
3914 /* Check if the alternate data stream is present
3915 */
3916 if( result != 0 )
3917 {
3918 Py_IncRef(
3919 (PyObject *) Py_True );
3920
3921 return( Py_True );
3922 }
3923 Py_IncRef(
3924 (PyObject *) Py_False );
3925
3926 return( Py_False );
3927 }
3928
3929 /* Retrieves the alternate data stream specified by the name
3930 * Returns a Python object if successful or NULL on error
3931 */
pyfsntfs_file_entry_get_alternate_data_stream_by_name(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)3932 PyObject *pyfsntfs_file_entry_get_alternate_data_stream_by_name(
3933 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
3934 PyObject *arguments,
3935 PyObject *keywords )
3936 {
3937 libcerror_error_t *error = NULL;
3938 libfsntfs_data_stream_t *data_stream = NULL;
3939 PyObject *data_stream_object = NULL;
3940 char *data_stream_name = NULL;
3941 static char *keyword_list[] = { "data_stream_name", NULL };
3942 static char *function = "pyfsntfs_file_entry_get_alternate_data_stream_by_name";
3943 size_t data_stream_name_length = 0;
3944 int result = 0;
3945
3946 if( pyfsntfs_file_entry == NULL )
3947 {
3948 PyErr_Format(
3949 PyExc_ValueError,
3950 "%s: invalid file entry.",
3951 function );
3952
3953 return( NULL );
3954 }
3955 if( PyArg_ParseTupleAndKeywords(
3956 arguments,
3957 keywords,
3958 "s",
3959 keyword_list,
3960 &data_stream_name ) == 0 )
3961 {
3962 goto on_error;
3963 }
3964 data_stream_name_length = narrow_string_length(
3965 data_stream_name );
3966
3967 Py_BEGIN_ALLOW_THREADS
3968
3969 result = libfsntfs_file_entry_get_alternate_data_stream_by_utf8_name(
3970 pyfsntfs_file_entry->file_entry,
3971 (uint8_t *) data_stream_name,
3972 data_stream_name_length,
3973 &data_stream,
3974 &error );
3975
3976 Py_END_ALLOW_THREADS
3977
3978 if( result == -1 )
3979 {
3980 pyfsntfs_error_raise(
3981 error,
3982 PyExc_IOError,
3983 "%s: unable to retrieve alternate data stream.",
3984 function );
3985
3986 libcerror_error_free(
3987 &error );
3988
3989 goto on_error;
3990 }
3991 /* Check if the alternate data stream is present
3992 */
3993 else if( result == 0 )
3994 {
3995 Py_IncRef(
3996 Py_None );
3997
3998 return( Py_None );
3999 }
4000 data_stream_object = pyfsntfs_data_stream_new(
4001 data_stream,
4002 (PyObject *) pyfsntfs_file_entry );
4003
4004 if( data_stream_object == NULL )
4005 {
4006 PyErr_Format(
4007 PyExc_MemoryError,
4008 "%s: unable to create data stream object.",
4009 function );
4010
4011 goto on_error;
4012 }
4013 return( data_stream_object );
4014
4015 on_error:
4016 if( data_stream != NULL )
4017 {
4018 libfsntfs_data_stream_free(
4019 &data_stream,
4020 NULL );
4021 }
4022 return( NULL );
4023 }
4024
4025 /* Retrieves the number of sub file entries
4026 * Returns a Python object if successful or NULL on error
4027 */
pyfsntfs_file_entry_get_number_of_sub_file_entries(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)4028 PyObject *pyfsntfs_file_entry_get_number_of_sub_file_entries(
4029 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
4030 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
4031 {
4032 libcerror_error_t *error = NULL;
4033 PyObject *integer_object = NULL;
4034 static char *function = "pyfsntfs_file_entry_get_number_of_sub_file_entries";
4035 int number_of_sub_file_entries = 0;
4036 int result = 0;
4037
4038 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
4039
4040 if( pyfsntfs_file_entry == NULL )
4041 {
4042 PyErr_Format(
4043 PyExc_ValueError,
4044 "%s: invalid file entry.",
4045 function );
4046
4047 return( NULL );
4048 }
4049 Py_BEGIN_ALLOW_THREADS
4050
4051 result = libfsntfs_file_entry_get_number_of_sub_file_entries(
4052 pyfsntfs_file_entry->file_entry,
4053 &number_of_sub_file_entries,
4054 &error );
4055
4056 Py_END_ALLOW_THREADS
4057
4058 if( result != 1 )
4059 {
4060 pyfsntfs_error_raise(
4061 error,
4062 PyExc_IOError,
4063 "%s: unable to retrieve number of sub file entries.",
4064 function );
4065
4066 libcerror_error_free(
4067 &error );
4068
4069 return( NULL );
4070 }
4071 #if PY_MAJOR_VERSION >= 3
4072 integer_object = PyLong_FromLong(
4073 (long) number_of_sub_file_entries );
4074 #else
4075 integer_object = PyInt_FromLong(
4076 (long) number_of_sub_file_entries );
4077 #endif
4078 return( integer_object );
4079 }
4080
4081 /* Retrieves a specific sub file entry by index
4082 * Returns a Python object if successful or NULL on error
4083 */
pyfsntfs_file_entry_get_sub_file_entry_by_index(PyObject * pyfsntfs_file_entry,int sub_file_entry_index)4084 PyObject *pyfsntfs_file_entry_get_sub_file_entry_by_index(
4085 PyObject *pyfsntfs_file_entry,
4086 int sub_file_entry_index )
4087 {
4088 libcerror_error_t *error = NULL;
4089 libfsntfs_file_entry_t *sub_file_entry = NULL;
4090 PyObject *file_entry_object = NULL;
4091 static char *function = "pyfsntfs_file_entry_get_sub_file_entry_by_index";
4092 int result = 0;
4093
4094 if( pyfsntfs_file_entry == NULL )
4095 {
4096 PyErr_Format(
4097 PyExc_ValueError,
4098 "%s: invalid file entry.",
4099 function );
4100
4101 return( NULL );
4102 }
4103 Py_BEGIN_ALLOW_THREADS
4104
4105 result = libfsntfs_file_entry_get_sub_file_entry_by_index(
4106 ( (pyfsntfs_file_entry_t *) pyfsntfs_file_entry )->file_entry,
4107 sub_file_entry_index,
4108 &sub_file_entry,
4109 &error );
4110
4111 Py_END_ALLOW_THREADS
4112
4113 if( result != 1 )
4114 {
4115 pyfsntfs_error_raise(
4116 error,
4117 PyExc_IOError,
4118 "%s: unable to retrieve sub file entry: %d.",
4119 function,
4120 sub_file_entry_index );
4121
4122 libcerror_error_free(
4123 &error );
4124
4125 goto on_error;
4126 }
4127 file_entry_object = pyfsntfs_file_entry_new(
4128 sub_file_entry,
4129 ( (pyfsntfs_file_entry_t *) pyfsntfs_file_entry )->parent_object );
4130
4131 if( file_entry_object == NULL )
4132 {
4133 PyErr_Format(
4134 PyExc_MemoryError,
4135 "%s: unable to create file entry object.",
4136 function );
4137
4138 goto on_error;
4139 }
4140 return( file_entry_object );
4141
4142 on_error:
4143 if( sub_file_entry != NULL )
4144 {
4145 libfsntfs_file_entry_free(
4146 &sub_file_entry,
4147 NULL );
4148 }
4149 return( NULL );
4150 }
4151
4152 /* Retrieves a specific sub file entry
4153 * Returns a Python object if successful or NULL on error
4154 */
pyfsntfs_file_entry_get_sub_file_entry(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments,PyObject * keywords)4155 PyObject *pyfsntfs_file_entry_get_sub_file_entry(
4156 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
4157 PyObject *arguments,
4158 PyObject *keywords )
4159 {
4160 PyObject *file_entry_object = NULL;
4161 static char *keyword_list[] = { "sub_file_entry_index", NULL };
4162 int sub_file_entry_index = 0;
4163
4164 if( PyArg_ParseTupleAndKeywords(
4165 arguments,
4166 keywords,
4167 "i",
4168 keyword_list,
4169 &sub_file_entry_index ) == 0 )
4170 {
4171 return( NULL );
4172 }
4173 file_entry_object = pyfsntfs_file_entry_get_sub_file_entry_by_index(
4174 (PyObject *) pyfsntfs_file_entry,
4175 sub_file_entry_index );
4176
4177 return( file_entry_object );
4178 }
4179
4180 /* Retrieves a file entries sequence and iterator object for the sub file entries
4181 * Returns a Python object if successful or NULL on error
4182 */
pyfsntfs_file_entry_get_sub_file_entries(pyfsntfs_file_entry_t * pyfsntfs_file_entry,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)4183 PyObject *pyfsntfs_file_entry_get_sub_file_entries(
4184 pyfsntfs_file_entry_t *pyfsntfs_file_entry,
4185 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
4186 {
4187 libcerror_error_t *error = NULL;
4188 PyObject *file_entries_object = NULL;
4189 static char *function = "pyfsntfs_file_entry_get_sub_file_entries";
4190 int number_of_sub_file_entries = 0;
4191 int result = 0;
4192
4193 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
4194
4195 if( pyfsntfs_file_entry == NULL )
4196 {
4197 PyErr_Format(
4198 PyExc_ValueError,
4199 "%s: invalid file entry.",
4200 function );
4201
4202 return( NULL );
4203 }
4204 Py_BEGIN_ALLOW_THREADS
4205
4206 result = libfsntfs_file_entry_get_number_of_sub_file_entries(
4207 pyfsntfs_file_entry->file_entry,
4208 &number_of_sub_file_entries,
4209 &error );
4210
4211 Py_END_ALLOW_THREADS
4212
4213 if( result != 1 )
4214 {
4215 pyfsntfs_error_raise(
4216 error,
4217 PyExc_IOError,
4218 "%s: unable to retrieve number of sub file entries.",
4219 function );
4220
4221 libcerror_error_free(
4222 &error );
4223
4224 return( NULL );
4225 }
4226 file_entries_object = pyfsntfs_file_entries_new(
4227 (PyObject *) pyfsntfs_file_entry,
4228 &pyfsntfs_file_entry_get_sub_file_entry_by_index,
4229 number_of_sub_file_entries );
4230
4231 if( file_entries_object == NULL )
4232 {
4233 PyErr_Format(
4234 PyExc_MemoryError,
4235 "%s: unable to create file entries object.",
4236 function );
4237
4238 return( NULL );
4239 }
4240 return( file_entries_object );
4241 }
4242
4243