1 /*
2 * Python object wrapper of libfwsi_item_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 )
27 #include <stdlib.h>
28 #endif
29
30 #include "pyfwsi_error.h"
31 #include "pyfwsi_extension_block.h"
32 #include "pyfwsi_extension_blocks.h"
33 #include "pyfwsi_file_entry_extension.h"
34 #include "pyfwsi_item.h"
35 #include "pyfwsi_item_list.h"
36 #include "pyfwsi_libcerror.h"
37 #include "pyfwsi_libclocale.h"
38 #include "pyfwsi_libfwsi.h"
39 #include "pyfwsi_python.h"
40 #include "pyfwsi_unused.h"
41
42 PyMethodDef pyfwsi_item_object_methods[] = {
43
44 { "copy_from_byte_stream",
45 (PyCFunction) pyfwsi_item_copy_from_byte_stream,
46 METH_VARARGS | METH_KEYWORDS,
47 "copy_from_byte_stream(byte_stream, ascii_codepage=cp1252)\n"
48 "\n"
49 "Copies the the item from the byte stream." },
50
51 /* Functions to access the item data */
52
53 { "get_class_type",
54 (PyCFunction) pyfwsi_item_get_class_type,
55 METH_NOARGS,
56 "get_class_type() -> Integer\n"
57 "\n"
58 "Returns the class type." },
59
60 { "get_data_size",
61 (PyCFunction) pyfwsi_item_get_data_size,
62 METH_NOARGS,
63 "get_data_size() -> Integer\n"
64 "\n"
65 "Returns the size of the item data." },
66
67 #ifdef TODO
68 { "get_data",
69 (PyCFunction) pyfwsi_item_get_data,
70 METH_NOARGS,
71 "get_data() -> String or None\n"
72 "\n"
73 "Returns the item data." },
74 #endif
75
76 /* Functions to access the extension blocks */
77
78 { "get_number_of_extension_blocks",
79 (PyCFunction) pyfwsi_item_get_number_of_extension_blocks,
80 METH_NOARGS,
81 "get_number_of_extension_blocks() -> Integer\n"
82 "\n"
83 "Retrieves the number of extension blocks." },
84
85 { "get_extension_block",
86 (PyCFunction) pyfwsi_item_get_extension_block,
87 METH_VARARGS | METH_KEYWORDS,
88 "get_extension_block(extension_block_index) -> Object\n"
89 "\n"
90 "Retrieves a specific extension block." },
91
92 /* Sentinel */
93 { NULL, NULL, 0, NULL }
94 };
95
96 PyGetSetDef pyfwsi_item_object_get_set_definitions[] = {
97
98 { "class_type",
99 (getter) pyfwsi_item_get_class_type,
100 (setter) 0,
101 "The class type.",
102 NULL },
103
104 { "data_size",
105 (getter) pyfwsi_item_get_data_size,
106 (setter) 0,
107 "The size of the item data.",
108 NULL },
109
110 #ifdef TODO
111 { "data",
112 (getter) pyfwsi_item_get_data,
113 (setter) 0,
114 "The item data.",
115 NULL },
116 #endif
117
118 { "number_of_extension_blocks",
119 (getter) pyfwsi_item_get_number_of_extension_blocks,
120 (setter) 0,
121 "The number of extension blocks.",
122 NULL },
123
124 { "extension_blocks",
125 (getter) pyfwsi_item_get_extension_blocks,
126 (setter) 0,
127 "The extension blocks",
128 NULL },
129
130 /* Sentinel */
131 { NULL, NULL, NULL, NULL, NULL }
132 };
133
134 PyTypeObject pyfwsi_item_type_object = {
135 PyVarObject_HEAD_INIT( NULL, 0 )
136
137 /* tp_name */
138 "pyfwsi.item",
139 /* tp_basicsize */
140 sizeof( pyfwsi_item_t ),
141 /* tp_itemsize */
142 0,
143 /* tp_dealloc */
144 (destructor) pyfwsi_item_free,
145 /* tp_print */
146 0,
147 /* tp_getattr */
148 0,
149 /* tp_setattr */
150 0,
151 /* tp_compare */
152 0,
153 /* tp_repr */
154 0,
155 /* tp_as_number */
156 0,
157 /* tp_as_sequence */
158 0,
159 /* tp_as_mapping */
160 0,
161 /* tp_hash */
162 0,
163 /* tp_call */
164 0,
165 /* tp_str */
166 0,
167 /* tp_getattro */
168 0,
169 /* tp_setattro */
170 0,
171 /* tp_as_buffer */
172 0,
173 /* tp_flags */
174 Py_TPFLAGS_DEFAULT,
175 /* tp_doc */
176 "pyfwsi item object (wraps libfwsi_item_t)",
177 /* tp_traverse */
178 0,
179 /* tp_clear */
180 0,
181 /* tp_richcompare */
182 0,
183 /* tp_weaklistoffset */
184 0,
185 /* tp_iter */
186 0,
187 /* tp_iternext */
188 0,
189 /* tp_methods */
190 pyfwsi_item_object_methods,
191 /* tp_members */
192 0,
193 /* tp_getset */
194 pyfwsi_item_object_get_set_definitions,
195 /* tp_base */
196 0,
197 /* tp_dict */
198 0,
199 /* tp_descr_get */
200 0,
201 /* tp_descr_set */
202 0,
203 /* tp_dictoffset */
204 0,
205 /* tp_init */
206 (initproc) pyfwsi_item_init,
207 /* tp_alloc */
208 0,
209 /* tp_new */
210 0,
211 /* tp_free */
212 0,
213 /* tp_is_gc */
214 0,
215 /* tp_bases */
216 NULL,
217 /* tp_mro */
218 NULL,
219 /* tp_cache */
220 NULL,
221 /* tp_subclasses */
222 NULL,
223 /* tp_weaklist */
224 NULL,
225 /* tp_del */
226 0
227 };
228
229 /* Creates a new pyfwsi item object
230 * Returns a Python object if successful or NULL on error
231 */
pyfwsi_item_new(PyTypeObject * type_object,libfwsi_item_t * item,PyObject * parent_object)232 PyObject *pyfwsi_item_new(
233 PyTypeObject *type_object,
234 libfwsi_item_t *item,
235 PyObject *parent_object )
236 {
237 pyfwsi_item_t *pyfwsi_item = NULL;
238 static char *function = "pyfwsi_item_new";
239
240 if( item == NULL )
241 {
242 PyErr_Format(
243 PyExc_TypeError,
244 "%s: invalid item.",
245 function );
246
247 return( NULL );
248 }
249 pyfwsi_item = PyObject_New(
250 struct pyfwsi_item,
251 type_object );
252
253 if( pyfwsi_item == NULL )
254 {
255 PyErr_Format(
256 PyExc_MemoryError,
257 "%s: unable to initialize item.",
258 function );
259
260 goto on_error;
261 }
262 pyfwsi_item->item = item;
263 pyfwsi_item->parent_object = parent_object;
264
265 Py_IncRef(
266 (PyObject *) pyfwsi_item->parent_object );
267
268 return( (PyObject *) pyfwsi_item );
269
270 on_error:
271 if( pyfwsi_item != NULL )
272 {
273 Py_DecRef(
274 (PyObject *) pyfwsi_item );
275 }
276 return( NULL );
277 }
278
279 /* Initializes an item object
280 * Returns 0 if successful or -1 on error
281 */
pyfwsi_item_init(pyfwsi_item_t * pyfwsi_item)282 int pyfwsi_item_init(
283 pyfwsi_item_t *pyfwsi_item )
284 {
285 libcerror_error_t *error = NULL;
286 static char *function = "pyfwsi_item_init";
287
288 if( pyfwsi_item == NULL )
289 {
290 PyErr_Format(
291 PyExc_TypeError,
292 "%s: invalid item.",
293 function );
294
295 return( -1 );
296 }
297 pyfwsi_item->item = NULL;
298 pyfwsi_item->parent_object = NULL;
299
300 if( libfwsi_item_initialize(
301 &( pyfwsi_item->item ),
302 &error ) != 1 )
303 {
304 pyfwsi_error_raise(
305 error,
306 PyExc_MemoryError,
307 "%s: unable to initialize item.",
308 function );
309
310 libcerror_error_free(
311 &error );
312
313 return( -1 );
314 }
315 return( 0 );
316 }
317
318 /* Frees an item object
319 */
pyfwsi_item_free(pyfwsi_item_t * pyfwsi_item)320 void pyfwsi_item_free(
321 pyfwsi_item_t *pyfwsi_item )
322 {
323 libcerror_error_t *error = NULL;
324 struct _typeobject *ob_type = NULL;
325 static char *function = "pyfwsi_item_free";
326 int result = 0;
327
328 if( pyfwsi_item == NULL )
329 {
330 PyErr_Format(
331 PyExc_TypeError,
332 "%s: invalid item.",
333 function );
334
335 return;
336 }
337 if( pyfwsi_item->item == NULL )
338 {
339 PyErr_Format(
340 PyExc_TypeError,
341 "%s: invalid item - missing libfwsi item.",
342 function );
343
344 return;
345 }
346 ob_type = Py_TYPE(
347 pyfwsi_item );
348
349 if( ob_type == NULL )
350 {
351 PyErr_Format(
352 PyExc_ValueError,
353 "%s: missing ob_type.",
354 function );
355
356 return;
357 }
358 if( ob_type->tp_free == NULL )
359 {
360 PyErr_Format(
361 PyExc_ValueError,
362 "%s: invalid ob_type - missing tp_free.",
363 function );
364
365 return;
366 }
367 Py_BEGIN_ALLOW_THREADS
368
369 result = libfwsi_item_free(
370 &( pyfwsi_item->item ),
371 &error );
372
373 Py_END_ALLOW_THREADS
374
375 if( result != 1 )
376 {
377 pyfwsi_error_raise(
378 error,
379 PyExc_MemoryError,
380 "%s: unable to free item.",
381 function );
382
383 libcerror_error_free(
384 &error );
385 }
386 if( pyfwsi_item->parent_object != NULL )
387 {
388 Py_DecRef(
389 (PyObject *) pyfwsi_item->parent_object );
390 }
391 ob_type->tp_free(
392 (PyObject*) pyfwsi_item );
393 }
394
395 /* Copies the item from a byte stream
396 * Returns a Python object if successful or NULL on error
397 */
pyfwsi_item_copy_from_byte_stream(pyfwsi_item_t * pyfwsi_item,PyObject * arguments,PyObject * keywords)398 PyObject *pyfwsi_item_copy_from_byte_stream(
399 pyfwsi_item_t *pyfwsi_item,
400 PyObject *arguments,
401 PyObject *keywords )
402 {
403 PyObject *string_object = NULL;
404 libcerror_error_t *error = NULL;
405 static char *function = "pyfwsi_item_copy_from_byte_stream";
406 static char *keyword_list[] = { "byte_stream", "ascii_codepage", NULL };
407 const char *byte_stream = NULL;
408 char *codepage_string = NULL;
409 Py_ssize_t byte_stream_size = 0;
410 size_t codepage_string_length = 0;
411 uint32_t feature_flags = 0;
412 int ascii_codepage = LIBFWSI_CODEPAGE_WINDOWS_1252;
413 int result = 0;
414
415 if( pyfwsi_item == NULL )
416 {
417 PyErr_Format(
418 PyExc_TypeError,
419 "%s: invalid item.",
420 function );
421
422 return( NULL );
423 }
424 if( PyArg_ParseTupleAndKeywords(
425 arguments,
426 keywords,
427 "O|s",
428 keyword_list,
429 &string_object,
430 &codepage_string ) == 0 )
431 {
432 return( NULL );
433 }
434 PyErr_Clear();
435
436 #if PY_MAJOR_VERSION >= 3
437 result = PyObject_IsInstance(
438 string_object,
439 (PyObject *) &PyBytes_Type );
440 #else
441 result = PyObject_IsInstance(
442 string_object,
443 (PyObject *) &PyString_Type );
444 #endif
445 if( result == -1 )
446 {
447 pyfwsi_error_fetch_and_raise(
448 PyExc_RuntimeError,
449 "%s: unable to determine if string object is of type string.",
450 function );
451
452 return( NULL );
453 }
454 else if( result == 0 )
455 {
456 PyErr_Format(
457 PyExc_TypeError,
458 "%s: unsupported string object type",
459 function );
460
461 return( NULL );
462 }
463 if( codepage_string != NULL )
464 {
465 codepage_string_length = narrow_string_length(
466 codepage_string );
467
468 feature_flags = LIBCLOCALE_CODEPAGE_FEATURE_FLAG_HAVE_WINDOWS;
469
470 if( libclocale_codepage_copy_from_string(
471 &ascii_codepage,
472 codepage_string,
473 codepage_string_length,
474 feature_flags,
475 &error ) != 1 )
476 {
477 pyfwsi_error_raise(
478 error,
479 PyExc_RuntimeError,
480 "%s: unable to determine ASCII codepage.",
481 function );
482
483 libcerror_error_free(
484 &error );
485
486 return( NULL );
487 }
488 }
489 PyErr_Clear();
490
491 #if PY_MAJOR_VERSION >= 3
492 byte_stream = PyBytes_AsString(
493 string_object );
494
495 byte_stream_size = PyBytes_Size(
496 string_object );
497 #else
498 byte_stream = PyString_AsString(
499 string_object );
500
501 byte_stream_size = PyString_Size(
502 string_object );
503 #endif
504 /* TODO size bounds check */
505
506 Py_BEGIN_ALLOW_THREADS
507
508 result = libfwsi_item_copy_from_byte_stream(
509 pyfwsi_item->item,
510 (uint8_t *) byte_stream,
511 (size_t) byte_stream_size,
512 ascii_codepage,
513 &error );
514
515 Py_END_ALLOW_THREADS
516
517 if( result != 1 )
518 {
519 pyfwsi_error_raise(
520 error,
521 PyExc_IOError,
522 "%s: unable to copy item from byte stream.",
523 function );
524
525 libcerror_error_free(
526 &error );
527
528 return( NULL );
529 }
530 Py_IncRef(
531 Py_None );
532
533 return( Py_None );
534 }
535
536 /* Retrieves the class type
537 * Returns a Python object if successful or NULL on error
538 */
pyfwsi_item_get_class_type(pyfwsi_item_t * pyfwsi_item,PyObject * arguments PYFWSI_ATTRIBUTE_UNUSED)539 PyObject *pyfwsi_item_get_class_type(
540 pyfwsi_item_t *pyfwsi_item,
541 PyObject *arguments PYFWSI_ATTRIBUTE_UNUSED )
542 {
543 libcerror_error_t *error = NULL;
544 static char *function = "pyfwsi_item_get_class_type";
545 uint8_t class_type = 0;
546 int result = 0;
547
548 PYFWSI_UNREFERENCED_PARAMETER( arguments )
549
550 if( pyfwsi_item == NULL )
551 {
552 PyErr_Format(
553 PyExc_TypeError,
554 "%s: invalid item.",
555 function );
556
557 return( NULL );
558 }
559 Py_BEGIN_ALLOW_THREADS
560
561 result = libfwsi_item_get_class_type(
562 pyfwsi_item->item,
563 &class_type,
564 &error );
565
566 Py_END_ALLOW_THREADS
567
568 if( result != 1 )
569 {
570 pyfwsi_error_raise(
571 error,
572 PyExc_IOError,
573 "%s: unable to retrieve class type.",
574 function );
575
576 libcerror_error_free(
577 &error );
578
579 return( NULL );
580 }
581 return( PyLong_FromUnsignedLong(
582 (unsigned long) class_type ) );
583 }
584
585 /* Retrieves the data size
586 * Returns a Python object if successful or NULL on error
587 */
pyfwsi_item_get_data_size(pyfwsi_item_t * pyfwsi_item,PyObject * arguments PYFWSI_ATTRIBUTE_UNUSED)588 PyObject *pyfwsi_item_get_data_size(
589 pyfwsi_item_t *pyfwsi_item,
590 PyObject *arguments PYFWSI_ATTRIBUTE_UNUSED )
591 {
592 libcerror_error_t *error = NULL;
593 static char *function = "pyfwsi_item_get_data_size";
594 size_t data_size = 0;
595 int result = 0;
596
597 PYFWSI_UNREFERENCED_PARAMETER( arguments )
598
599 if( pyfwsi_item == NULL )
600 {
601 PyErr_Format(
602 PyExc_TypeError,
603 "%s: invalid item.",
604 function );
605
606 return( NULL );
607 }
608 Py_BEGIN_ALLOW_THREADS
609
610 result = libfwsi_item_get_data_size(
611 pyfwsi_item->item,
612 &data_size,
613 &error );
614
615 Py_END_ALLOW_THREADS
616
617 if( result != 1 )
618 {
619 pyfwsi_error_raise(
620 error,
621 PyExc_IOError,
622 "%s: unable to retrieve data size.",
623 function );
624
625 libcerror_error_free(
626 &error );
627
628 return( NULL );
629 }
630 return( PyLong_FromUnsignedLong(
631 (unsigned long) data_size ) );
632 }
633
634 #ifdef TODO
635 /* Retrieves the data
636 * Returns a Python object if successful or NULL on error
637 */
pyfwsi_item_get_data(pyfwsi_item_t * pyfwsi_item,PyObject * arguments PYFWSI_ATTRIBUTE_UNUSED)638 PyObject *pyfwsi_item_get_data(
639 pyfwsi_item_t *pyfwsi_item,
640 PyObject *arguments PYFWSI_ATTRIBUTE_UNUSED )
641 {
642 libcerror_error_t *error = NULL;
643 PyObject *string_object = NULL;
644 uint8_t *data = NULL;
645 static char *function = "pyfwsi_item_get_data";
646 size_t data_size = 0;
647 int result = 0;
648
649 PYFWSI_UNREFERENCED_PARAMETER( arguments )
650
651 if( pyfwsi_item == NULL )
652 {
653 PyErr_Format(
654 PyExc_TypeError,
655 "%s: invalid item.",
656 function );
657
658 return( NULL );
659 }
660 Py_BEGIN_ALLOW_THREADS
661
662 result = libfwsi_item_get_data_size(
663 pyfwsi_item->item,
664 &data_size,
665 &error );
666
667 Py_END_ALLOW_THREADS
668
669 if( result == -1 )
670 {
671 pyfwsi_error_raise(
672 error,
673 PyExc_IOError,
674 "%s: unable to retrieve data size.",
675 function );
676
677 libcerror_error_free(
678 &error );
679
680 goto on_error;
681 }
682 else if( ( result == 0 )
683 || ( data_size == 0 ) )
684 {
685 Py_IncRef(
686 Py_None );
687
688 return( Py_None );
689 }
690 data = (uint8_t *) PyMem_Malloc(
691 sizeof( uint8_t ) * data_size );
692
693 if( data == NULL )
694 {
695 PyErr_Format(
696 PyExc_IOError,
697 "%s: unable to create data.",
698 function );
699
700 goto on_error;
701 }
702 Py_BEGIN_ALLOW_THREADS
703
704 result = libfwsi_item_get_data(
705 pyfwsi_item->item,
706 data,
707 data_size,
708 &error );
709
710 Py_END_ALLOW_THREADS
711
712 if( result != 1 )
713 {
714 pyfwsi_error_raise(
715 error,
716 PyExc_IOError,
717 "%s: unable to retrieve data.",
718 function );
719
720 libcerror_error_free(
721 &error );
722
723 goto on_error;
724 }
725 #if PY_MAJOR_VERSION >= 3
726 string_object = PyBytes_FromStringAndSize(
727 (char *) data,
728 (Py_ssize_t) data_size );
729 #else
730 string_object = PyString_FromStringAndSize(
731 (char *) data,
732 (Py_ssize_t) data_size );
733 #endif
734 PyMem_Free(
735 data );
736
737 return( string_object );
738
739 on_error:
740 if( data != NULL )
741 {
742 PyMem_Free(
743 data );
744 }
745 return( NULL );
746 }
747 #endif
748
749 /* Retrieves the number of extension blocks
750 * Returns a Python object if successful or NULL on error
751 */
pyfwsi_item_get_number_of_extension_blocks(pyfwsi_item_t * pyfwsi_item,PyObject * arguments PYFWSI_ATTRIBUTE_UNUSED)752 PyObject *pyfwsi_item_get_number_of_extension_blocks(
753 pyfwsi_item_t *pyfwsi_item,
754 PyObject *arguments PYFWSI_ATTRIBUTE_UNUSED )
755 {
756 libcerror_error_t *error = NULL;
757 PyObject *integer_object = NULL;
758 static char *function = "pyfwsi_item_get_number_of_extension_blocks";
759 int number_of_extension_blocks = 0;
760 int result = 0;
761
762 PYFWSI_UNREFERENCED_PARAMETER( arguments )
763
764 if( pyfwsi_item == NULL )
765 {
766 PyErr_Format(
767 PyExc_TypeError,
768 "%s: invalid item.",
769 function );
770
771 return( NULL );
772 }
773 Py_BEGIN_ALLOW_THREADS
774
775 result = libfwsi_item_get_number_of_extension_blocks(
776 pyfwsi_item->item,
777 &number_of_extension_blocks,
778 &error );
779
780 Py_END_ALLOW_THREADS
781
782 if( result != 1 )
783 {
784 pyfwsi_error_raise(
785 error,
786 PyExc_IOError,
787 "%s: unable to retrieve number of extension blocks.",
788 function );
789
790 libcerror_error_free(
791 &error );
792
793 return( NULL );
794 }
795 #if PY_MAJOR_VERSION >= 3
796 integer_object = PyLong_FromLong(
797 (long) number_of_extension_blocks );
798 #else
799 integer_object = PyInt_FromLong(
800 (long) number_of_extension_blocks );
801 #endif
802 return( integer_object );
803 }
804
805 /* Retrieves a specific extension block by index
806 * Returns a Python object if successful or NULL on error
807 */
pyfwsi_item_get_extension_block_by_index(PyObject * pyfwsi_item,int extension_block_index)808 PyObject *pyfwsi_item_get_extension_block_by_index(
809 PyObject *pyfwsi_item,
810 int extension_block_index )
811 {
812 libcerror_error_t *error = NULL;
813 libfwsi_extension_block_t *extension_block = NULL;
814 PyObject *extension_block_object = NULL;
815 PyTypeObject *type_object = NULL;
816 static char *function = "pyfwsi_item_get_extension_block_by_index";
817 uint32_t signature = 0;
818 int result = 0;
819
820 if( pyfwsi_item == NULL )
821 {
822 PyErr_Format(
823 PyExc_TypeError,
824 "%s: invalid item.",
825 function );
826
827 return( NULL );
828 }
829 Py_BEGIN_ALLOW_THREADS
830
831 result = libfwsi_item_get_extension_block(
832 ( (pyfwsi_item_t *) pyfwsi_item )->item,
833 extension_block_index,
834 &extension_block,
835 &error );
836
837 Py_END_ALLOW_THREADS
838
839 if( result != 1 )
840 {
841 pyfwsi_error_raise(
842 error,
843 PyExc_IOError,
844 "%s: unable to retrieve extension block: %d.",
845 function,
846 extension_block_index );
847
848 libcerror_error_free(
849 &error );
850
851 goto on_error;
852 }
853 Py_BEGIN_ALLOW_THREADS
854
855 result = libfwsi_extension_block_get_signature(
856 extension_block,
857 &signature,
858 &error );
859
860 Py_END_ALLOW_THREADS
861
862 if( result != 1 )
863 {
864 pyfwsi_error_raise(
865 error,
866 PyExc_IOError,
867 "%s: unable to retrieve extension block: %d signature.",
868 function,
869 extension_block_index );
870
871 libcerror_error_free(
872 &error );
873
874 goto on_error;
875 }
876 switch( signature )
877 {
878 case 0xbeef0004UL:
879 type_object = &pyfwsi_file_entry_extension_type_object;
880 break;
881
882 default:
883 type_object = &pyfwsi_extension_block_type_object;
884 break;
885 }
886 extension_block_object = pyfwsi_extension_block_new(
887 type_object,
888 extension_block,
889 pyfwsi_item );
890
891 if( extension_block_object == NULL )
892 {
893 PyErr_Format(
894 PyExc_MemoryError,
895 "%s: unable to create extension block object.",
896 function );
897
898 goto on_error;
899 }
900 return( extension_block_object );
901
902 on_error:
903 if( extension_block != NULL )
904 {
905 libfwsi_extension_block_free(
906 &extension_block,
907 NULL );
908 }
909 return( NULL );
910 }
911
912 /* Retrieves a specific extension block
913 * Returns a Python object if successful or NULL on error
914 */
pyfwsi_item_get_extension_block(pyfwsi_item_t * pyfwsi_item,PyObject * arguments,PyObject * keywords)915 PyObject *pyfwsi_item_get_extension_block(
916 pyfwsi_item_t *pyfwsi_item,
917 PyObject *arguments,
918 PyObject *keywords )
919 {
920 PyObject *extension_block_object = NULL;
921 static char *keyword_list[] = { "extension_block_index", NULL };
922 int extension_block_index = 0;
923
924 if( PyArg_ParseTupleAndKeywords(
925 arguments,
926 keywords,
927 "i",
928 keyword_list,
929 &extension_block_index ) == 0 )
930 {
931 return( NULL );
932 }
933 extension_block_object = pyfwsi_item_get_extension_block_by_index(
934 (PyObject *) pyfwsi_item,
935 extension_block_index );
936
937 return( extension_block_object );
938 }
939
940 /* Retrieves an extension blocks sequence and iterator object for the extension blocks
941 * Returns a Python object if successful or NULL on error
942 */
pyfwsi_item_get_extension_blocks(pyfwsi_item_t * pyfwsi_item,PyObject * arguments PYFWSI_ATTRIBUTE_UNUSED)943 PyObject *pyfwsi_item_get_extension_blocks(
944 pyfwsi_item_t *pyfwsi_item,
945 PyObject *arguments PYFWSI_ATTRIBUTE_UNUSED )
946 {
947 libcerror_error_t *error = NULL;
948 PyObject *extension_blocks_object = NULL;
949 static char *function = "pyfwsi_item_get_extension_blocks";
950 int number_of_extension_blocks = 0;
951 int result = 0;
952
953 PYFWSI_UNREFERENCED_PARAMETER( arguments )
954
955 if( pyfwsi_item == NULL )
956 {
957 PyErr_Format(
958 PyExc_TypeError,
959 "%s: invalid item.",
960 function );
961
962 return( NULL );
963 }
964 Py_BEGIN_ALLOW_THREADS
965
966 result = libfwsi_item_get_number_of_extension_blocks(
967 pyfwsi_item->item,
968 &number_of_extension_blocks,
969 &error );
970
971 Py_END_ALLOW_THREADS
972
973 if( result != 1 )
974 {
975 pyfwsi_error_raise(
976 error,
977 PyExc_IOError,
978 "%s: unable to retrieve number of extension blocks.",
979 function );
980
981 libcerror_error_free(
982 &error );
983
984 return( NULL );
985 }
986 extension_blocks_object = pyfwsi_extension_blocks_new(
987 (PyObject *) pyfwsi_item,
988 &pyfwsi_item_get_extension_block_by_index,
989 number_of_extension_blocks );
990
991 if( extension_blocks_object == NULL )
992 {
993 PyErr_Format(
994 PyExc_MemoryError,
995 "%s: unable to create extension blocks object.",
996 function );
997
998 return( NULL );
999 }
1000 return( extension_blocks_object );
1001 }
1002
1003