1 /*
2 * Python object wrapper of libolecf_item_t
3 *
4 * Copyright (C) 2008-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 <memory.h>
24 #include <narrow_string.h>
25 #include <types.h>
26
27 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
28 #include <stdlib.h>
29 #endif
30
31 #include "pyolecf_datetime.h"
32 #include "pyolecf_error.h"
33 #include "pyolecf_integer.h"
34 #include "pyolecf_item.h"
35 #include "pyolecf_items.h"
36 #include "pyolecf_libcerror.h"
37 #include "pyolecf_libolecf.h"
38 #include "pyolecf_property_set_stream.h"
39 #include "pyolecf_python.h"
40 #include "pyolecf_stream.h"
41 #include "pyolecf_unused.h"
42
43 PyMethodDef pyolecf_item_object_methods[] = {
44
45 { "get_name",
46 (PyCFunction) pyolecf_item_get_name,
47 METH_NOARGS,
48 "get_name() -> Unicode string or None\n"
49 "\n"
50 "Retrieves the name." },
51
52 { "get_size",
53 (PyCFunction) pyolecf_item_get_size,
54 METH_NOARGS,
55 "get_size() -> Integer or None\n"
56 "\n"
57 "Retrieves the size." },
58
59 { "get_creation_time",
60 (PyCFunction) pyolecf_item_get_creation_time,
61 METH_NOARGS,
62 "get_creation_time() -> Datetime or None\n"
63 "\n"
64 "Retrieves the creation time." },
65
66 { "get_creation_time_as_integer",
67 (PyCFunction) pyolecf_item_get_creation_time_as_integer,
68 METH_NOARGS,
69 "get_creation_time_as_integer() -> Integer or None\n"
70 "\n"
71 "Retrieves the creation time as a 64-bit integer containing a FILETIME value." },
72
73 { "get_modification_time",
74 (PyCFunction) pyolecf_item_get_modification_time,
75 METH_NOARGS,
76 "get_modification_time() -> Datetime or None\n"
77 "\n"
78 "Retrieves the modification time." },
79
80 { "get_modification_time_as_integer",
81 (PyCFunction) pyolecf_item_get_modification_time_as_integer,
82 METH_NOARGS,
83 "get_modification_time_as_integer() -> Integer or None\n"
84 "\n"
85 "Retrieves the modification time as a 64-bit integer containing a FILETIME value." },
86
87 { "get_number_of_sub_items",
88 (PyCFunction) pyolecf_item_get_number_of_sub_items,
89 METH_NOARGS,
90 "get_number_of_sub_items() -> Integer or None\n"
91 "\n"
92 "Retrieves the number of sub items." },
93
94 { "get_sub_item",
95 (PyCFunction) pyolecf_item_get_sub_item,
96 METH_VARARGS | METH_KEYWORDS,
97 "get_sub_item(sub_item_index) -> Object or None\n"
98 "\n"
99 "Retrieves the sub item specified by the index." },
100
101 { "get_sub_item_by_name",
102 (PyCFunction) pyolecf_item_get_sub_item_by_name,
103 METH_VARARGS | METH_KEYWORDS,
104 "get_sub_item_by_name(name) -> Object or None\n"
105 "\n"
106 "Retrieves the sub item specified by the name." },
107
108 { "get_sub_item_by_path",
109 (PyCFunction) pyolecf_item_get_sub_item_by_path,
110 METH_VARARGS | METH_KEYWORDS,
111 "get_sub_item_by_path(path) -> Object or None\n"
112 "\n"
113 "Retrieves the sub item specified by the path." },
114
115 /* Sentinel */
116 { NULL, NULL, 0, NULL }
117 };
118
119 PyGetSetDef pyolecf_item_object_get_set_definitions[] = {
120
121 { "name",
122 (getter) pyolecf_item_get_name,
123 (setter) 0,
124 "The name.",
125 NULL },
126
127 { "size",
128 (getter) pyolecf_item_get_size,
129 (setter) 0,
130 "The size.",
131 NULL },
132
133 { "creation_time",
134 (getter) pyolecf_item_get_creation_time,
135 (setter) 0,
136 "The creation time.",
137 NULL },
138
139 { "modification_time",
140 (getter) pyolecf_item_get_modification_time,
141 (setter) 0,
142 "The modification time.",
143 NULL },
144
145 { "number_of_sub_items",
146 (getter) pyolecf_item_get_number_of_sub_items,
147 (setter) 0,
148 "The number of sub items.",
149 NULL },
150
151 { "sub_items",
152 (getter) pyolecf_item_get_sub_items,
153 (setter) 0,
154 "The sub items.",
155 NULL },
156
157 /* Sentinel */
158 { NULL, NULL, NULL, NULL, NULL }
159 };
160
161 PyTypeObject pyolecf_item_type_object = {
162 PyVarObject_HEAD_INIT( NULL, 0 )
163
164 /* tp_name */
165 "pyolecf.item",
166 /* tp_basicsize */
167 sizeof( pyolecf_item_t ),
168 /* tp_itemsize */
169 0,
170 /* tp_dealloc */
171 (destructor) pyolecf_item_free,
172 /* tp_print */
173 0,
174 /* tp_getattr */
175 0,
176 /* tp_setattr */
177 0,
178 /* tp_compare */
179 0,
180 /* tp_repr */
181 0,
182 /* tp_as_number */
183 0,
184 /* tp_as_sequence */
185 0,
186 /* tp_as_mapping */
187 0,
188 /* tp_hash */
189 0,
190 /* tp_call */
191 0,
192 /* tp_str */
193 0,
194 /* tp_getattro */
195 0,
196 /* tp_setattro */
197 0,
198 /* tp_as_buffer */
199 0,
200 /* tp_flags */
201 Py_TPFLAGS_DEFAULT,
202 /* tp_doc */
203 "pyolecf item object (wraps libolecf_item_t)",
204 /* tp_traverse */
205 0,
206 /* tp_clear */
207 0,
208 /* tp_richcompare */
209 0,
210 /* tp_weaklistoffset */
211 0,
212 /* tp_iter */
213 0,
214 /* tp_iternext */
215 0,
216 /* tp_methods */
217 pyolecf_item_object_methods,
218 /* tp_members */
219 0,
220 /* tp_getset */
221 pyolecf_item_object_get_set_definitions,
222 /* tp_base */
223 0,
224 /* tp_dict */
225 0,
226 /* tp_descr_get */
227 0,
228 /* tp_descr_set */
229 0,
230 /* tp_dictoffset */
231 0,
232 /* tp_init */
233 (initproc) pyolecf_item_init,
234 /* tp_alloc */
235 0,
236 /* tp_new */
237 0,
238 /* tp_free */
239 0,
240 /* tp_is_gc */
241 0,
242 /* tp_bases */
243 NULL,
244 /* tp_mro */
245 NULL,
246 /* tp_cache */
247 NULL,
248 /* tp_subclasses */
249 NULL,
250 /* tp_weaklist */
251 NULL,
252 /* tp_del */
253 0
254 };
255
256 /* Creates a new item object
257 * Returns a Python object if successful or NULL on error
258 */
pyolecf_item_new(PyTypeObject * type_object,libolecf_item_t * item,PyObject * parent_object)259 PyObject *pyolecf_item_new(
260 PyTypeObject *type_object,
261 libolecf_item_t *item,
262 PyObject *parent_object )
263 {
264 pyolecf_item_t *pyolecf_item = NULL;
265 static char *function = "pyolecf_item_new";
266
267 if( item == NULL )
268 {
269 PyErr_Format(
270 PyExc_ValueError,
271 "%s: invalid item.",
272 function );
273
274 return( NULL );
275 }
276 /* PyObject_New does not invoke tp_init
277 */
278 pyolecf_item = PyObject_New(
279 struct pyolecf_item,
280 type_object );
281
282 if( pyolecf_item == NULL )
283 {
284 PyErr_Format(
285 PyExc_MemoryError,
286 "%s: unable to initialize item.",
287 function );
288
289 goto on_error;
290 }
291 pyolecf_item->item = item;
292 pyolecf_item->parent_object = parent_object;
293
294 if( pyolecf_item->parent_object != NULL )
295 {
296 Py_IncRef(
297 pyolecf_item->parent_object );
298 }
299 return( (PyObject *) pyolecf_item );
300
301 on_error:
302 if( pyolecf_item != NULL )
303 {
304 Py_DecRef(
305 (PyObject *) pyolecf_item );
306 }
307 return( NULL );
308 }
309
310 /* Initializes an item object
311 * Returns 0 if successful or -1 on error
312 */
pyolecf_item_init(pyolecf_item_t * pyolecf_item)313 int pyolecf_item_init(
314 pyolecf_item_t *pyolecf_item )
315 {
316 static char *function = "pyolecf_item_init";
317
318 if( pyolecf_item == NULL )
319 {
320 PyErr_Format(
321 PyExc_ValueError,
322 "%s: invalid item.",
323 function );
324
325 return( -1 );
326 }
327 /* Make sure libolecf item is set to NULL
328 */
329 pyolecf_item->item = NULL;
330
331 PyErr_Format(
332 PyExc_NotImplementedError,
333 "%s: initialize of item not supported.",
334 function );
335
336 return( -1 );
337 }
338
339 /* Frees an item object
340 */
pyolecf_item_free(pyolecf_item_t * pyolecf_item)341 void pyolecf_item_free(
342 pyolecf_item_t *pyolecf_item )
343 {
344 struct _typeobject *ob_type = NULL;
345 libcerror_error_t *error = NULL;
346 static char *function = "pyolecf_item_free";
347 int result = 0;
348
349 if( pyolecf_item == NULL )
350 {
351 PyErr_Format(
352 PyExc_ValueError,
353 "%s: invalid item.",
354 function );
355
356 return;
357 }
358 ob_type = Py_TYPE(
359 pyolecf_item );
360
361 if( ob_type == NULL )
362 {
363 PyErr_Format(
364 PyExc_ValueError,
365 "%s: missing ob_type.",
366 function );
367
368 return;
369 }
370 if( ob_type->tp_free == NULL )
371 {
372 PyErr_Format(
373 PyExc_ValueError,
374 "%s: invalid ob_type - missing tp_free.",
375 function );
376
377 return;
378 }
379 if( pyolecf_item->item != NULL )
380 {
381 Py_BEGIN_ALLOW_THREADS
382
383 result = libolecf_item_free(
384 &( pyolecf_item->item ),
385 &error );
386
387 Py_END_ALLOW_THREADS
388
389 if( result != 1 )
390 {
391 pyolecf_error_raise(
392 error,
393 PyExc_MemoryError,
394 "%s: unable to free libolecf item.",
395 function );
396
397 libcerror_error_free(
398 &error );
399 }
400 }
401 if( pyolecf_item->parent_object != NULL )
402 {
403 Py_DecRef(
404 pyolecf_item->parent_object );
405 }
406 ob_type->tp_free(
407 (PyObject*) pyolecf_item );
408 }
409
410 /* Retrieves the name
411 * Returns a Python object if successful or NULL on error
412 */
pyolecf_item_get_name(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)413 PyObject *pyolecf_item_get_name(
414 pyolecf_item_t *pyolecf_item,
415 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
416 {
417 PyObject *string_object = NULL;
418 libcerror_error_t *error = NULL;
419 const char *errors = NULL;
420 static char *function = "pyolecf_item_get_name";
421 char *utf8_string = NULL;
422 size_t utf8_string_size = 0;
423 int result = 0;
424
425 PYOLECF_UNREFERENCED_PARAMETER( arguments )
426
427 if( pyolecf_item == NULL )
428 {
429 PyErr_Format(
430 PyExc_ValueError,
431 "%s: invalid item.",
432 function );
433
434 return( NULL );
435 }
436 Py_BEGIN_ALLOW_THREADS
437
438 result = libolecf_item_get_utf8_name_size(
439 pyolecf_item->item,
440 &utf8_string_size,
441 &error );
442
443 Py_END_ALLOW_THREADS
444
445 if( result == -1 )
446 {
447 pyolecf_error_raise(
448 error,
449 PyExc_IOError,
450 "%s: unable to determine size of name as UTF-8 string.",
451 function );
452
453 libcerror_error_free(
454 &error );
455
456 goto on_error;
457 }
458 else if( ( result == 0 )
459 || ( utf8_string_size == 0 ) )
460 {
461 Py_IncRef(
462 Py_None );
463
464 return( Py_None );
465 }
466 utf8_string = (char *) PyMem_Malloc(
467 sizeof( char ) * utf8_string_size );
468
469 if( utf8_string == NULL )
470 {
471 PyErr_Format(
472 PyExc_MemoryError,
473 "%s: unable to create UTF-8 string.",
474 function );
475
476 goto on_error;
477 }
478 Py_BEGIN_ALLOW_THREADS
479
480 result = libolecf_item_get_utf8_name(
481 pyolecf_item->item,
482 (uint8_t *) utf8_string,
483 utf8_string_size,
484 &error );
485
486 Py_END_ALLOW_THREADS
487
488 if( result != 1 )
489 {
490 pyolecf_error_raise(
491 error,
492 PyExc_IOError,
493 "%s: unable to retrieve name as UTF-8 string.",
494 function );
495
496 libcerror_error_free(
497 &error );
498
499 goto on_error;
500 }
501 /* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
502 * the end of string character is part of the string
503 */
504 string_object = PyUnicode_DecodeUTF8(
505 utf8_string,
506 (Py_ssize_t) utf8_string_size - 1,
507 errors );
508
509 if( string_object == NULL )
510 {
511 PyErr_Format(
512 PyExc_IOError,
513 "%s: unable to convert UTF-8 string into Unicode object.",
514 function );
515
516 goto on_error;
517 }
518 PyMem_Free(
519 utf8_string );
520
521 return( string_object );
522
523 on_error:
524 if( utf8_string != NULL )
525 {
526 PyMem_Free(
527 utf8_string );
528 }
529 return( NULL );
530 }
531
532 /* Retrieves the size
533 * Returns a Python object if successful or NULL on error
534 */
pyolecf_item_get_size(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)535 PyObject *pyolecf_item_get_size(
536 pyolecf_item_t *pyolecf_item,
537 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
538 {
539 PyObject *integer_object = NULL;
540 libcerror_error_t *error = NULL;
541 static char *function = "pyolecf_item_get_size";
542 uint32_t value_32bit = 0;
543 int result = 0;
544
545 PYOLECF_UNREFERENCED_PARAMETER( arguments )
546
547 if( pyolecf_item == NULL )
548 {
549 PyErr_Format(
550 PyExc_ValueError,
551 "%s: invalid item.",
552 function );
553
554 return( NULL );
555 }
556 Py_BEGIN_ALLOW_THREADS
557
558 result = libolecf_item_get_size(
559 pyolecf_item->item,
560 &value_32bit,
561 &error );
562
563 Py_END_ALLOW_THREADS
564
565 if( result == -1 )
566 {
567 pyolecf_error_raise(
568 error,
569 PyExc_IOError,
570 "%s: unable to retrieve size.",
571 function );
572
573 libcerror_error_free(
574 &error );
575
576 return( NULL );
577 }
578 else if( result == 0 )
579 {
580 Py_IncRef(
581 Py_None );
582
583 return( Py_None );
584 }
585 integer_object = PyLong_FromUnsignedLong(
586 (unsigned long) value_32bit );
587
588 return( integer_object );
589 }
590
591 /* Retrieves the creation time
592 * Returns a Python object if successful or NULL on error
593 */
pyolecf_item_get_creation_time(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)594 PyObject *pyolecf_item_get_creation_time(
595 pyolecf_item_t *pyolecf_item,
596 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
597 {
598 PyObject *datetime_object = NULL;
599 libcerror_error_t *error = NULL;
600 static char *function = "pyolecf_item_get_creation_time";
601 uint64_t filetime = 0;
602 int result = 0;
603
604 PYOLECF_UNREFERENCED_PARAMETER( arguments )
605
606 if( pyolecf_item == NULL )
607 {
608 PyErr_Format(
609 PyExc_ValueError,
610 "%s: invalid item.",
611 function );
612
613 return( NULL );
614 }
615 Py_BEGIN_ALLOW_THREADS
616
617 result = libolecf_item_get_creation_time(
618 pyolecf_item->item,
619 &filetime,
620 &error );
621
622 Py_END_ALLOW_THREADS
623
624 if( result == -1 )
625 {
626 pyolecf_error_raise(
627 error,
628 PyExc_IOError,
629 "%s: unable to retrieve creation time.",
630 function );
631
632 libcerror_error_free(
633 &error );
634
635 return( NULL );
636 }
637 else if( result == 0 )
638 {
639 Py_IncRef(
640 Py_None );
641
642 return( Py_None );
643 }
644 datetime_object = pyolecf_datetime_new_from_filetime(
645 filetime );
646
647 return( datetime_object );
648 }
649
650 /* Retrieves the creation time as an integer
651 * Returns a Python object if successful or NULL on error
652 */
pyolecf_item_get_creation_time_as_integer(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)653 PyObject *pyolecf_item_get_creation_time_as_integer(
654 pyolecf_item_t *pyolecf_item,
655 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
656 {
657 PyObject *integer_object = NULL;
658 libcerror_error_t *error = NULL;
659 static char *function = "pyolecf_item_get_creation_time_as_integer";
660 uint64_t filetime = 0;
661 int result = 0;
662
663 PYOLECF_UNREFERENCED_PARAMETER( arguments )
664
665 if( pyolecf_item == NULL )
666 {
667 PyErr_Format(
668 PyExc_ValueError,
669 "%s: invalid item.",
670 function );
671
672 return( NULL );
673 }
674 Py_BEGIN_ALLOW_THREADS
675
676 result = libolecf_item_get_creation_time(
677 pyolecf_item->item,
678 &filetime,
679 &error );
680
681 Py_END_ALLOW_THREADS
682
683 if( result == -1 )
684 {
685 pyolecf_error_raise(
686 error,
687 PyExc_IOError,
688 "%s: unable to retrieve creation time.",
689 function );
690
691 libcerror_error_free(
692 &error );
693
694 return( NULL );
695 }
696 else if( result == 0 )
697 {
698 Py_IncRef(
699 Py_None );
700
701 return( Py_None );
702 }
703 integer_object = pyolecf_integer_unsigned_new_from_64bit(
704 (uint64_t) filetime );
705
706 return( integer_object );
707 }
708
709 /* Retrieves the modification time
710 * Returns a Python object if successful or NULL on error
711 */
pyolecf_item_get_modification_time(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)712 PyObject *pyolecf_item_get_modification_time(
713 pyolecf_item_t *pyolecf_item,
714 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
715 {
716 PyObject *datetime_object = NULL;
717 libcerror_error_t *error = NULL;
718 static char *function = "pyolecf_item_get_modification_time";
719 uint64_t filetime = 0;
720 int result = 0;
721
722 PYOLECF_UNREFERENCED_PARAMETER( arguments )
723
724 if( pyolecf_item == NULL )
725 {
726 PyErr_Format(
727 PyExc_ValueError,
728 "%s: invalid item.",
729 function );
730
731 return( NULL );
732 }
733 Py_BEGIN_ALLOW_THREADS
734
735 result = libolecf_item_get_modification_time(
736 pyolecf_item->item,
737 &filetime,
738 &error );
739
740 Py_END_ALLOW_THREADS
741
742 if( result == -1 )
743 {
744 pyolecf_error_raise(
745 error,
746 PyExc_IOError,
747 "%s: unable to retrieve modification time.",
748 function );
749
750 libcerror_error_free(
751 &error );
752
753 return( NULL );
754 }
755 else if( result == 0 )
756 {
757 Py_IncRef(
758 Py_None );
759
760 return( Py_None );
761 }
762 datetime_object = pyolecf_datetime_new_from_filetime(
763 filetime );
764
765 return( datetime_object );
766 }
767
768 /* Retrieves the modification time as an integer
769 * Returns a Python object if successful or NULL on error
770 */
pyolecf_item_get_modification_time_as_integer(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)771 PyObject *pyolecf_item_get_modification_time_as_integer(
772 pyolecf_item_t *pyolecf_item,
773 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
774 {
775 PyObject *integer_object = NULL;
776 libcerror_error_t *error = NULL;
777 static char *function = "pyolecf_item_get_modification_time_as_integer";
778 uint64_t filetime = 0;
779 int result = 0;
780
781 PYOLECF_UNREFERENCED_PARAMETER( arguments )
782
783 if( pyolecf_item == NULL )
784 {
785 PyErr_Format(
786 PyExc_ValueError,
787 "%s: invalid item.",
788 function );
789
790 return( NULL );
791 }
792 Py_BEGIN_ALLOW_THREADS
793
794 result = libolecf_item_get_modification_time(
795 pyolecf_item->item,
796 &filetime,
797 &error );
798
799 Py_END_ALLOW_THREADS
800
801 if( result == -1 )
802 {
803 pyolecf_error_raise(
804 error,
805 PyExc_IOError,
806 "%s: unable to retrieve modification time.",
807 function );
808
809 libcerror_error_free(
810 &error );
811
812 return( NULL );
813 }
814 else if( result == 0 )
815 {
816 Py_IncRef(
817 Py_None );
818
819 return( Py_None );
820 }
821 integer_object = pyolecf_integer_unsigned_new_from_64bit(
822 (uint64_t) filetime );
823
824 return( integer_object );
825 }
826
827 /* Retrieves the number of sub items
828 * Returns a Python object if successful or NULL on error
829 */
pyolecf_item_get_number_of_sub_items(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)830 PyObject *pyolecf_item_get_number_of_sub_items(
831 pyolecf_item_t *pyolecf_item,
832 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
833 {
834 PyObject *integer_object = NULL;
835 libcerror_error_t *error = NULL;
836 static char *function = "pyolecf_item_get_number_of_sub_items";
837 int number_of_sub_items = 0;
838 int result = 0;
839
840 PYOLECF_UNREFERENCED_PARAMETER( arguments )
841
842 if( pyolecf_item == NULL )
843 {
844 PyErr_Format(
845 PyExc_ValueError,
846 "%s: invalid item.",
847 function );
848
849 return( NULL );
850 }
851 Py_BEGIN_ALLOW_THREADS
852
853 result = libolecf_item_get_number_of_sub_items(
854 pyolecf_item->item,
855 &number_of_sub_items,
856 &error );
857
858 Py_END_ALLOW_THREADS
859
860 if( result != 1 )
861 {
862 pyolecf_error_raise(
863 error,
864 PyExc_IOError,
865 "%s: unable to retrieve number of sub items.",
866 function );
867
868 libcerror_error_free(
869 &error );
870
871 return( NULL );
872 }
873 #if PY_MAJOR_VERSION >= 3
874 integer_object = PyLong_FromLong(
875 (long) number_of_sub_items );
876 #else
877 integer_object = PyInt_FromLong(
878 (long) number_of_sub_items );
879 #endif
880 return( integer_object );
881 }
882
883 /* Retrieves the item type object
884 * Returns a Python type object if successful or NULL on error
885 */
pyolecf_item_get_item_type_object(libolecf_item_t * item)886 PyTypeObject *pyolecf_item_get_item_type_object(
887 libolecf_item_t *item )
888 {
889 uint8_t utf8_string[ 32 ];
890
891 libcerror_error_t *error = NULL;
892 static char *function = "pyolecf_item_get_item_type_object";
893 size_t utf8_string_size = 0;
894 uint8_t item_type = 0;
895 int result = 0;
896
897 if( item == NULL )
898 {
899 PyErr_Format(
900 PyExc_TypeError,
901 "%s: invalid item.",
902 function );
903
904 return( NULL );
905 }
906 Py_BEGIN_ALLOW_THREADS
907
908 result = libolecf_item_get_type(
909 item,
910 &item_type,
911 &error );
912
913 Py_END_ALLOW_THREADS
914
915 if( result == -1 )
916 {
917 pyolecf_error_raise(
918 error,
919 PyExc_IOError,
920 "%s: unable to retrieve item type.",
921 function );
922
923 libcerror_error_free(
924 &error );
925
926 return( NULL );
927 }
928 if( item_type == LIBOLECF_ITEM_TYPE_STREAM )
929 {
930 Py_BEGIN_ALLOW_THREADS
931
932 result = libolecf_item_get_utf8_name_size(
933 item,
934 &utf8_string_size,
935 &error );
936
937 Py_END_ALLOW_THREADS
938
939 if( result == -1 )
940 {
941 pyolecf_error_raise(
942 error,
943 PyExc_IOError,
944 "%s: unable to retrieve name size.",
945 function );
946
947 libcerror_error_free(
948 &error );
949
950 return( NULL );
951 }
952 if( ( utf8_string_size == 20 )
953 || ( utf8_string_size == 28 ) )
954 {
955 Py_BEGIN_ALLOW_THREADS
956
957 result = libolecf_item_get_utf8_name(
958 item,
959 utf8_string,
960 utf8_string_size,
961 &error );
962
963 Py_END_ALLOW_THREADS
964
965 if( result != 1 )
966 {
967 pyolecf_error_raise(
968 error,
969 PyExc_IOError,
970 "%s: unable to retrieve name.",
971 function );
972
973 libcerror_error_free(
974 &error );
975
976 return( NULL );
977 }
978 if( utf8_string_size == 20 )
979 {
980 if( narrow_string_compare(
981 "\005SummaryInformation",
982 utf8_string,
983 19 ) == 0 )
984 {
985 return( &pyolecf_property_set_stream_type_object );
986 }
987 }
988 else if( utf8_string_size == 28 )
989 {
990 if( narrow_string_compare(
991 "\005DocumentSummaryInformation",
992 utf8_string,
993 27 ) == 0 )
994 {
995 return( &pyolecf_property_set_stream_type_object );
996 }
997 }
998 }
999 return( &pyolecf_stream_type_object );
1000 }
1001 return( &pyolecf_item_type_object );
1002 }
1003
1004 /* Retrieves a specific sub item by index
1005 * Returns a Python object if successful or NULL on error
1006 */
pyolecf_item_get_sub_item_by_index(PyObject * pyolecf_item,int sub_item_index)1007 PyObject *pyolecf_item_get_sub_item_by_index(
1008 PyObject *pyolecf_item,
1009 int sub_item_index )
1010 {
1011 PyObject *item_object = NULL;
1012 PyTypeObject *type_object = NULL;
1013 libcerror_error_t *error = NULL;
1014 libolecf_item_t *sub_item = NULL;
1015 static char *function = "pyolecf_item_get_sub_item_by_index";
1016 int result = 0;
1017
1018 if( pyolecf_item == NULL )
1019 {
1020 PyErr_Format(
1021 PyExc_ValueError,
1022 "%s: invalid item.",
1023 function );
1024
1025 return( NULL );
1026 }
1027 Py_BEGIN_ALLOW_THREADS
1028
1029 result = libolecf_item_get_sub_item(
1030 ( (pyolecf_item_t *) pyolecf_item )->item,
1031 sub_item_index,
1032 &sub_item,
1033 &error );
1034
1035 Py_END_ALLOW_THREADS
1036
1037 if( result != 1 )
1038 {
1039 pyolecf_error_raise(
1040 error,
1041 PyExc_IOError,
1042 "%s: unable to retrieve sub item: %d.",
1043 function,
1044 sub_item_index );
1045
1046 libcerror_error_free(
1047 &error );
1048
1049 goto on_error;
1050 }
1051 type_object = pyolecf_item_get_item_type_object(
1052 sub_item );
1053
1054 if( type_object == NULL )
1055 {
1056 PyErr_Format(
1057 PyExc_IOError,
1058 "%s: unable to retrieve item type object.",
1059 function );
1060
1061 goto on_error;
1062 }
1063 item_object = pyolecf_item_new(
1064 type_object,
1065 sub_item,
1066 ( (pyolecf_item_t *) pyolecf_item )->parent_object );
1067
1068 if( item_object == NULL )
1069 {
1070 PyErr_Format(
1071 PyExc_MemoryError,
1072 "%s: unable to create sub item object.",
1073 function );
1074
1075 goto on_error;
1076 }
1077 return( item_object );
1078
1079 on_error:
1080 if( sub_item != NULL )
1081 {
1082 libolecf_item_free(
1083 &sub_item,
1084 NULL );
1085 }
1086 return( NULL );
1087 }
1088
1089 /* Retrieves a specific sub item
1090 * Returns a Python object if successful or NULL on error
1091 */
pyolecf_item_get_sub_item(pyolecf_item_t * pyolecf_item,PyObject * arguments,PyObject * keywords)1092 PyObject *pyolecf_item_get_sub_item(
1093 pyolecf_item_t *pyolecf_item,
1094 PyObject *arguments,
1095 PyObject *keywords )
1096 {
1097 PyObject *item_object = NULL;
1098 static char *keyword_list[] = { "sub_item_index", NULL };
1099 int sub_item_index = 0;
1100
1101 if( PyArg_ParseTupleAndKeywords(
1102 arguments,
1103 keywords,
1104 "i",
1105 keyword_list,
1106 &sub_item_index ) == 0 )
1107 {
1108 return( NULL );
1109 }
1110 item_object = pyolecf_item_get_sub_item_by_index(
1111 (PyObject *) pyolecf_item,
1112 sub_item_index );
1113
1114 return( item_object );
1115 }
1116
1117 /* Retrieves a sequence and iterator object for the sub items
1118 * Returns a Python object if successful or NULL on error
1119 */
pyolecf_item_get_sub_items(pyolecf_item_t * pyolecf_item,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)1120 PyObject *pyolecf_item_get_sub_items(
1121 pyolecf_item_t *pyolecf_item,
1122 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
1123 {
1124 PyObject *sequence_object = NULL;
1125 libcerror_error_t *error = NULL;
1126 static char *function = "pyolecf_item_get_sub_items";
1127 int number_of_sub_items = 0;
1128 int result = 0;
1129
1130 PYOLECF_UNREFERENCED_PARAMETER( arguments )
1131
1132 if( pyolecf_item == NULL )
1133 {
1134 PyErr_Format(
1135 PyExc_ValueError,
1136 "%s: invalid item.",
1137 function );
1138
1139 return( NULL );
1140 }
1141 Py_BEGIN_ALLOW_THREADS
1142
1143 result = libolecf_item_get_number_of_sub_items(
1144 pyolecf_item->item,
1145 &number_of_sub_items,
1146 &error );
1147
1148 Py_END_ALLOW_THREADS
1149
1150 if( result != 1 )
1151 {
1152 pyolecf_error_raise(
1153 error,
1154 PyExc_IOError,
1155 "%s: unable to retrieve number of sub items.",
1156 function );
1157
1158 libcerror_error_free(
1159 &error );
1160
1161 return( NULL );
1162 }
1163 sequence_object = pyolecf_items_new(
1164 (PyObject *) pyolecf_item,
1165 &pyolecf_item_get_sub_item_by_index,
1166 number_of_sub_items );
1167
1168 if( sequence_object == NULL )
1169 {
1170 pyolecf_error_raise(
1171 error,
1172 PyExc_MemoryError,
1173 "%s: unable to create sequence object.",
1174 function );
1175
1176 return( NULL );
1177 }
1178 return( sequence_object );
1179 }
1180
1181 /* Retrieves the sub item specified by the name
1182 * Returns a Python object if successful or NULL on error
1183 */
pyolecf_item_get_sub_item_by_name(pyolecf_item_t * pyolecf_item,PyObject * arguments,PyObject * keywords)1184 PyObject *pyolecf_item_get_sub_item_by_name(
1185 pyolecf_item_t *pyolecf_item,
1186 PyObject *arguments,
1187 PyObject *keywords )
1188 {
1189 PyObject *item_object = NULL;
1190 PyTypeObject *type_object = NULL;
1191 libcerror_error_t *error = NULL;
1192 libolecf_item_t *sub_item = NULL;
1193 static char *function = "pyolecf_item_get_sub_item_by_name";
1194 static char *keyword_list[] = { "name", NULL };
1195 char *utf8_name = NULL;
1196 size_t utf8_name_length = 0;
1197 int result = 0;
1198
1199 if( pyolecf_item == NULL )
1200 {
1201 PyErr_Format(
1202 PyExc_ValueError,
1203 "%s: invalid item.",
1204 function );
1205
1206 return( NULL );
1207 }
1208 if( PyArg_ParseTupleAndKeywords(
1209 arguments,
1210 keywords,
1211 "s",
1212 keyword_list,
1213 &utf8_name ) == 0 )
1214 {
1215 goto on_error;
1216 }
1217 utf8_name_length = narrow_string_length(
1218 utf8_name );
1219
1220 Py_BEGIN_ALLOW_THREADS
1221
1222 result = libolecf_item_get_sub_item_by_utf8_name(
1223 pyolecf_item->item,
1224 (uint8_t *) utf8_name,
1225 utf8_name_length,
1226 &sub_item,
1227 &error );
1228
1229 Py_END_ALLOW_THREADS
1230
1231 if( result == -1 )
1232 {
1233 pyolecf_error_raise(
1234 error,
1235 PyExc_IOError,
1236 "%s: unable to retrieve sub item.",
1237 function );
1238
1239 libcerror_error_free(
1240 &error );
1241
1242 goto on_error;
1243 }
1244 else if( result == 0 )
1245 {
1246 Py_IncRef(
1247 Py_None );
1248
1249 return( Py_None );
1250 }
1251 type_object = pyolecf_item_get_item_type_object(
1252 sub_item );
1253
1254 if( type_object == NULL )
1255 {
1256 PyErr_Format(
1257 PyExc_IOError,
1258 "%s: unable to retrieve item type object.",
1259 function );
1260
1261 goto on_error;
1262 }
1263 item_object = pyolecf_item_new(
1264 type_object,
1265 sub_item,
1266 pyolecf_item->parent_object );
1267
1268 if( item_object == NULL )
1269 {
1270 PyErr_Format(
1271 PyExc_MemoryError,
1272 "%s: unable to create sub item object.",
1273 function );
1274
1275 goto on_error;
1276 }
1277 return( item_object );
1278
1279 on_error:
1280 if( sub_item != NULL )
1281 {
1282 libolecf_item_free(
1283 &sub_item,
1284 NULL );
1285 }
1286 return( NULL );
1287 }
1288
1289 /* Retrieves the sub item specified by the path
1290 * Returns a Python object if successful or NULL on error
1291 */
pyolecf_item_get_sub_item_by_path(pyolecf_item_t * pyolecf_item,PyObject * arguments,PyObject * keywords)1292 PyObject *pyolecf_item_get_sub_item_by_path(
1293 pyolecf_item_t *pyolecf_item,
1294 PyObject *arguments,
1295 PyObject *keywords )
1296 {
1297 PyObject *item_object = NULL;
1298 PyTypeObject *type_object = NULL;
1299 libcerror_error_t *error = NULL;
1300 libolecf_item_t *sub_item = NULL;
1301 static char *function = "pyolecf_item_get_sub_item_by_path";
1302 static char *keyword_list[] = { "path", NULL };
1303 char *utf8_path = NULL;
1304 size_t utf8_path_length = 0;
1305 int result = 0;
1306
1307 if( pyolecf_item == NULL )
1308 {
1309 PyErr_Format(
1310 PyExc_ValueError,
1311 "%s: invalid item.",
1312 function );
1313
1314 return( NULL );
1315 }
1316 if( PyArg_ParseTupleAndKeywords(
1317 arguments,
1318 keywords,
1319 "s",
1320 keyword_list,
1321 &utf8_path ) == 0 )
1322 {
1323 goto on_error;
1324 }
1325 utf8_path_length = narrow_string_length(
1326 utf8_path );
1327
1328 Py_BEGIN_ALLOW_THREADS
1329
1330 result = libolecf_item_get_sub_item_by_utf8_path(
1331 pyolecf_item->item,
1332 (uint8_t *) utf8_path,
1333 utf8_path_length,
1334 &sub_item,
1335 &error );
1336
1337 Py_END_ALLOW_THREADS
1338
1339 if( result == -1 )
1340 {
1341 pyolecf_error_raise(
1342 error,
1343 PyExc_IOError,
1344 "%s: unable to retrieve sub item.",
1345 function );
1346
1347 libcerror_error_free(
1348 &error );
1349
1350 goto on_error;
1351 }
1352 else if( result == 0 )
1353 {
1354 Py_IncRef(
1355 Py_None );
1356
1357 return( Py_None );
1358 }
1359 type_object = pyolecf_item_get_item_type_object(
1360 sub_item );
1361
1362 if( type_object == NULL )
1363 {
1364 PyErr_Format(
1365 PyExc_IOError,
1366 "%s: unable to retrieve item type object.",
1367 function );
1368
1369 goto on_error;
1370 }
1371 item_object = pyolecf_item_new(
1372 type_object,
1373 sub_item,
1374 pyolecf_item->parent_object );
1375
1376 if( item_object == NULL )
1377 {
1378 PyErr_Format(
1379 PyExc_MemoryError,
1380 "%s: unable to create sub item object.",
1381 function );
1382
1383 goto on_error;
1384 }
1385 return( item_object );
1386
1387 on_error:
1388 if( sub_item != NULL )
1389 {
1390 libolecf_item_free(
1391 &sub_item,
1392 NULL );
1393 }
1394 return( NULL );
1395 }
1396
1397