1 /*
2  * Python object definition of the libvshadow store
3  *
4  * Copyright (C) 2011-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <types.h>
24 
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28 
29 #include "pyvshadow_block.h"
30 #include "pyvshadow_blocks.h"
31 #include "pyvshadow_datetime.h"
32 #include "pyvshadow_error.h"
33 #include "pyvshadow_guid.h"
34 #include "pyvshadow_integer.h"
35 #include "pyvshadow_libcerror.h"
36 #include "pyvshadow_libvshadow.h"
37 #include "pyvshadow_python.h"
38 #include "pyvshadow_store.h"
39 #include "pyvshadow_unused.h"
40 #include "pyvshadow_volume.h"
41 
42 PyMethodDef pyvshadow_store_object_methods[] = {
43 
44 	/* Functions to access the store data */
45 
46 	{ "has_in_volume_data",
47 	  (PyCFunction) pyvshadow_store_has_in_volume_data,
48 	  METH_NOARGS,
49 	  "has_in_volume_data() -> Boolean\n"
50 	  "\n"
51 	  "Determines if the store as in-volume data." },
52 
53 	{ "read_buffer",
54 	  (PyCFunction) pyvshadow_store_read_buffer,
55 	  METH_VARARGS | METH_KEYWORDS,
56 	  "read_buffer(size) -> String\n"
57 	  "\n"
58 	  "Reads a buffer of store data." },
59 
60 	{ "read_buffer_at_offset",
61 	  (PyCFunction) pyvshadow_store_read_buffer_at_offset,
62 	  METH_VARARGS | METH_KEYWORDS,
63 	  "read_buffer_at_offset(size, offset) -> String\n"
64 	  "\n"
65 	  "Reads a buffer of store data at a specific offset." },
66 
67 	{ "seek_offset",
68 	  (PyCFunction) pyvshadow_store_seek_offset,
69 	  METH_VARARGS | METH_KEYWORDS,
70 	  "seek_offset(offset, whence) -> None\n"
71 	  "\n"
72 	  "Seeks an offset within the store data." },
73 
74 	{ "get_offset",
75 	  (PyCFunction) pyvshadow_store_get_offset,
76 	  METH_NOARGS,
77 	  "get_offset() -> Integer\n"
78 	  "\n"
79 	  "Retrieves the current offset within the store data." },
80 
81 	/* Some Pythonesque aliases */
82 
83 	{ "read",
84 	  (PyCFunction) pyvshadow_store_read_buffer,
85 	  METH_VARARGS | METH_KEYWORDS,
86 	  "read(size) -> String\n"
87 	  "\n"
88 	  "Reads a buffer of store data." },
89 
90 	{ "seek",
91 	  (PyCFunction) pyvshadow_store_seek_offset,
92 	  METH_VARARGS | METH_KEYWORDS,
93 	  "seek(offset, whence) -> None\n"
94 	  "\n"
95 	  "Seeks an offset within the store data." },
96 
97 	{ "tell",
98 	  (PyCFunction) pyvshadow_store_get_offset,
99 	  METH_NOARGS,
100 	  "tell() -> Integer\n"
101 	  "\n"
102 	  "Retrieves the current offset within the store data." },
103 
104 	/* Functions to access the store values */
105 
106 	{ "get_size",
107 	  (PyCFunction) pyvshadow_store_get_size,
108 	  METH_NOARGS,
109 	  "get_size() -> Integer\n"
110 	  "\n"
111 	  "Retrieves the size of the store data." },
112 
113 	{ "get_volume_size",
114 	  (PyCFunction) pyvshadow_store_get_volume_size,
115 	  METH_NOARGS,
116 	  "get_volume_size() -> Integer\n"
117 	  "\n"
118 	  "Retrieves the size of the volume as stored in the store information." },
119 
120 	{ "get_identifier",
121 	  (PyCFunction) pyvshadow_store_get_identifier,
122 	  METH_NOARGS,
123 	  "get_identifier() -> Unicode string or None\n"
124 	  "\n"
125 	  "Retrieves the identifier (GUID)." },
126 
127 	{ "get_creation_time",
128 	  (PyCFunction) pyvshadow_store_get_creation_time,
129 	  METH_NOARGS,
130 	  "get_creation_time() -> Datetime\n"
131 	  "\n"
132 	  "Returns the creation date and time." },
133 
134 	{ "get_creation_time_as_integer",
135 	  (PyCFunction) pyvshadow_store_get_creation_time_as_integer,
136 	  METH_NOARGS,
137 	  "pyvshadow_store_get_creation_time_as_integer() -> Integer\n"
138 	  "\n"
139 	  "Returns the creation date and time as a 64-bit integer containing a FILETIME value." },
140 
141 	{ "get_copy_identifier",
142 	  (PyCFunction) pyvshadow_store_get_copy_identifier,
143 	  METH_NOARGS,
144 	  "get_copy_identifier() -> Unicode string or None\n"
145 	  "\n"
146 	  "Retrieves the copy identifier (GUID)." },
147 
148 	{ "get_copy_set_identifier",
149 	  (PyCFunction) pyvshadow_store_get_copy_set_identifier,
150 	  METH_NOARGS,
151 	  "get_copy_set_identifier() -> Unicode string or None\n"
152 	  "\n"
153 	  "Retrieves the copy set identifier (GUID)." },
154 
155 	/* Functions to access the blocks */
156 
157 	{ "get_number_of_blocks",
158 	  (PyCFunction) pyvshadow_store_get_number_of_blocks,
159 	  METH_NOARGS,
160 	  "get_number_of_blocks() -> Integer\n"
161 	  "\n"
162 	  "Retrieves the number of blocks." },
163 
164 	{ "get_block",
165 	  (PyCFunction) pyvshadow_store_get_block,
166 	  METH_VARARGS | METH_KEYWORDS,
167 	  "get_block(block_index) -> Object or None\n"
168 	  "\n"
169 	  "Retrieves a specific block." },
170 
171 	{ "get_blocks",
172 	  (PyCFunction) pyvshadow_store_get_blocks,
173 	  METH_VARARGS | METH_KEYWORDS,
174 	  "get_blocks() -> Object\n"
175 	  "\n"
176 	  "Retrieves a sequence object of the blocks." },
177 
178 	/* Sentinel */
179 	{ NULL, NULL, 0, NULL }
180 };
181 
182 PyGetSetDef pyvshadow_store_object_get_set_definitions[] = {
183 
184 	{ "size",
185 	  (getter) pyvshadow_store_get_size,
186 	  (setter) 0,
187 	  "The size.",
188 	  NULL },
189 
190 	{ "volume_size",
191 	  (getter) pyvshadow_store_get_volume_size,
192 	  (setter) 0,
193 	  "The volume size.",
194 	  NULL },
195 
196 	{ "identifier",
197 	  (getter) pyvshadow_store_get_identifier,
198 	  (setter) 0,
199 	  "The identifier.",
200 	  NULL },
201 
202 	{ "creation_time",
203 	  (getter) pyvshadow_store_get_creation_time,
204 	  (setter) 0,
205 	  "The creation date and time.",
206 	  NULL },
207 
208 	{ "copy_identifier",
209 	  (getter) pyvshadow_store_get_copy_identifier,
210 	  (setter) 0,
211 	  "The copy identifier.",
212 	  NULL },
213 
214 	{ "copy_set_identifier",
215 	  (getter) pyvshadow_store_get_copy_set_identifier,
216 	  (setter) 0,
217 	  "The copy set identifier.",
218 	  NULL },
219 
220 	{ "number_of_blocks",
221 	  (getter) pyvshadow_store_get_number_of_blocks,
222 	  (setter) 0,
223 	  "The number of blocks.",
224 	  NULL },
225 
226 	{ "blocks",
227 	  (getter) pyvshadow_store_get_blocks,
228 	  (setter) 0,
229 	  "The blocks.",
230 	  NULL },
231 
232 	/* Sentinel */
233 	{ NULL, NULL, NULL, NULL, NULL }
234 };
235 
236 PyTypeObject pyvshadow_store_type_object = {
237 	PyVarObject_HEAD_INIT( NULL, 0 )
238 
239 	/* tp_name */
240 	"pyvshadow.store",
241 	/* tp_basicsize */
242 	sizeof( pyvshadow_store_t ),
243 	/* tp_itemsize */
244 	0,
245 	/* tp_dealloc */
246 	(destructor) pyvshadow_store_free,
247 	/* tp_print */
248 	0,
249 	/* tp_getattr */
250 	0,
251 	/* tp_setattr */
252 	0,
253 	/* tp_compare */
254 	0,
255 	/* tp_repr */
256 	0,
257 	/* tp_as_number */
258 	0,
259 	/* tp_as_sequence */
260 	0,
261 	/* tp_as_mapping */
262 	0,
263 	/* tp_hash */
264 	0,
265 	/* tp_call */
266 	0,
267 	/* tp_str */
268 	0,
269 	/* tp_getattro */
270 	0,
271 	/* tp_setattro */
272 	0,
273 	/* tp_as_buffer */
274 	0,
275 	/* tp_flags */
276 	Py_TPFLAGS_DEFAULT,
277 	/* tp_doc */
278 	"pyvshadow store object (wraps libvshadow_store_t)",
279 	/* tp_traverse */
280 	0,
281 	/* tp_clear */
282 	0,
283 	/* tp_richcompare */
284 	0,
285 	/* tp_weaklistoffset */
286 	0,
287 	/* tp_iter */
288 	0,
289 	/* tp_iternext */
290 	0,
291 	/* tp_methods */
292 	pyvshadow_store_object_methods,
293 	/* tp_members */
294 	0,
295 	/* tp_getset */
296 	pyvshadow_store_object_get_set_definitions,
297 	/* tp_base */
298 	0,
299 	/* tp_dict */
300 	0,
301 	/* tp_descr_get */
302 	0,
303 	/* tp_descr_set */
304 	0,
305 	/* tp_dictoffset */
306 	0,
307 	/* tp_init */
308 	(initproc) pyvshadow_store_init,
309 	/* tp_alloc */
310 	0,
311 	/* tp_new */
312 	0,
313 	/* tp_free */
314 	0,
315 	/* tp_is_gc */
316 	0,
317 	/* tp_bases */
318 	NULL,
319 	/* tp_mro */
320 	NULL,
321 	/* tp_cache */
322 	NULL,
323 	/* tp_subclasses */
324 	NULL,
325 	/* tp_weaklist */
326 	NULL,
327 	/* tp_del */
328 	0
329 };
330 
331 /* Creates a new store object
332  * Returns a Python object if successful or NULL on error
333  */
pyvshadow_store_new(libvshadow_store_t * store,PyObject * parent_object)334 PyObject *pyvshadow_store_new(
335            libvshadow_store_t *store,
336            PyObject *parent_object )
337 {
338 	pyvshadow_store_t *pyvshadow_store = NULL;
339 	static char *function              = "pyvshadow_store_new";
340 
341 	if( store == NULL )
342 	{
343 		PyErr_Format(
344 		 PyExc_ValueError,
345 		 "%s: invalid store.",
346 		 function );
347 
348 		return( NULL );
349 	}
350 	/* PyObject_New does not invoke tp_init
351 	 */
352 	pyvshadow_store = PyObject_New(
353 	                   struct pyvshadow_store,
354 	                   &pyvshadow_store_type_object );
355 
356 	if( pyvshadow_store == NULL )
357 	{
358 		PyErr_Format(
359 		 PyExc_MemoryError,
360 		 "%s: unable to initialize store.",
361 		 function );
362 
363 		goto on_error;
364 	}
365 	pyvshadow_store->store         = store;
366 	pyvshadow_store->parent_object = parent_object;
367 
368 	if( pyvshadow_store->parent_object != NULL )
369 	{
370 		Py_IncRef(
371 		 pyvshadow_store->parent_object );
372 	}
373 	return( (PyObject *) pyvshadow_store );
374 
375 on_error:
376 	if( pyvshadow_store != NULL )
377 	{
378 		Py_DecRef(
379 		 (PyObject *) pyvshadow_store );
380 	}
381 	return( NULL );
382 }
383 
384 /* Initializes a store object
385  * Returns 0 if successful or -1 on error
386  */
pyvshadow_store_init(pyvshadow_store_t * pyvshadow_store)387 int pyvshadow_store_init(
388      pyvshadow_store_t *pyvshadow_store )
389 {
390 	static char *function = "pyvshadow_store_init";
391 
392 	if( pyvshadow_store == NULL )
393 	{
394 		PyErr_Format(
395 		 PyExc_ValueError,
396 		 "%s: invalid store.",
397 		 function );
398 
399 		return( -1 );
400 	}
401 	/* Make sure libvshadow store is set to NULL
402 	 */
403 	pyvshadow_store->store = NULL;
404 
405 	PyErr_Format(
406 	 PyExc_NotImplementedError,
407 	 "%s: initialize of store not supported.",
408 	 function );
409 
410 	return( -1 );
411 }
412 
413 /* Frees a store object
414  */
pyvshadow_store_free(pyvshadow_store_t * pyvshadow_store)415 void pyvshadow_store_free(
416       pyvshadow_store_t *pyvshadow_store )
417 {
418 	struct _typeobject *ob_type = NULL;
419 	libcerror_error_t *error    = NULL;
420 	static char *function       = "pyvshadow_store_free";
421 	int result                  = 0;
422 
423 	if( pyvshadow_store == NULL )
424 	{
425 		PyErr_Format(
426 		 PyExc_ValueError,
427 		 "%s: invalid store.",
428 		 function );
429 
430 		return;
431 	}
432 	ob_type = Py_TYPE(
433 	           pyvshadow_store );
434 
435 	if( ob_type == NULL )
436 	{
437 		PyErr_Format(
438 		 PyExc_ValueError,
439 		 "%s: missing ob_type.",
440 		 function );
441 
442 		return;
443 	}
444 	if( ob_type->tp_free == NULL )
445 	{
446 		PyErr_Format(
447 		 PyExc_ValueError,
448 		 "%s: invalid ob_type - missing tp_free.",
449 		 function );
450 
451 		return;
452 	}
453 	if( pyvshadow_store->store != NULL )
454 	{
455 		Py_BEGIN_ALLOW_THREADS
456 
457 		result = libvshadow_store_free(
458 		          &( pyvshadow_store->store ),
459 		          &error );
460 
461 		Py_END_ALLOW_THREADS
462 
463 		if( result != 1 )
464 		{
465 			pyvshadow_error_raise(
466 			 error,
467 			 PyExc_MemoryError,
468 			 "%s: unable to free libvshadow store.",
469 			 function );
470 
471 			libcerror_error_free(
472 			 &error );
473 		}
474 	}
475 	if( pyvshadow_store->parent_object != NULL )
476 	{
477 		Py_DecRef(
478 		 pyvshadow_store->parent_object );
479 	}
480 	ob_type->tp_free(
481 	 (PyObject*) pyvshadow_store );
482 }
483 
484 /* Determines if the store has in-volume data
485  * Returns a Python object if successful or NULL on error
486  */
pyvshadow_store_has_in_volume_data(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)487 PyObject *pyvshadow_store_has_in_volume_data(
488            pyvshadow_store_t *pyvshadow_store,
489            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
490 {
491 	libcerror_error_t *error = NULL;
492 	static char *function    = "pyvshadow_store_has_in_volume_data";
493 	int result               = 0;
494 
495 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
496 
497 	if( pyvshadow_store == NULL )
498 	{
499 		PyErr_Format(
500 		 PyExc_TypeError,
501 		 "%s: invalid store.",
502 		 function );
503 
504 		return( NULL );
505 	}
506 	Py_BEGIN_ALLOW_THREADS
507 
508 	result = libvshadow_store_has_in_volume_data(
509 	          pyvshadow_store->store,
510 	          &error );
511 
512 	Py_END_ALLOW_THREADS
513 
514 	if( result == -1 )
515 	{
516 		pyvshadow_error_raise(
517 		 error,
518 		 PyExc_IOError,
519 		 "%s: unable to determine if the store has in-volume data.",
520 		 function );
521 
522 		libcerror_error_free(
523 		 &error );
524 
525 		return( NULL );
526 	}
527 	else if( result == 0 )
528 	{
529 		Py_IncRef(
530 		 (PyObject *) Py_False );
531 
532 		return( Py_False );
533 	}
534 	Py_IncRef(
535 	 (PyObject *) Py_True );
536 
537 	return( Py_True );
538 }
539 
540 /* Reads (store) data at the current offset into a buffer
541  * Returns a Python object if successful or NULL on error
542  */
pyvshadow_store_read_buffer(pyvshadow_store_t * pyvshadow_store,PyObject * arguments,PyObject * keywords)543 PyObject *pyvshadow_store_read_buffer(
544            pyvshadow_store_t *pyvshadow_store,
545            PyObject *arguments,
546            PyObject *keywords )
547 {
548 	libcerror_error_t *error    = NULL;
549 	PyObject *string_object     = NULL;
550 	static char *function       = "pyvshadow_store_read_buffer";
551 	static char *keyword_list[] = { "size", NULL };
552 	char *buffer                = NULL;
553 	ssize_t read_count          = 0;
554 	int read_size               = -1;
555 
556 	if( pyvshadow_store == NULL )
557 	{
558 		PyErr_Format(
559 		 PyExc_TypeError,
560 		 "%s: invalid pyvshadow store.",
561 		 function );
562 
563 		return( NULL );
564 	}
565 	if( PyArg_ParseTupleAndKeywords(
566 	     arguments,
567 	     keywords,
568 	     "|i",
569 	     keyword_list,
570 	     &read_size ) == 0 )
571 	{
572 		return( NULL );
573 	}
574 	if( read_size < 0 )
575 	{
576 		PyErr_Format(
577 		 PyExc_ValueError,
578 		 "%s: invalid argument read size value less than zero.",
579 		 function );
580 
581 		return( NULL );
582 	}
583 	/* Make sure the data fits into the memory buffer
584 	 */
585 	if( read_size > INT_MAX )
586 	{
587 		PyErr_Format(
588 		 PyExc_ValueError,
589 		 "%s: invalid argument read size value exceeds maximum.",
590 		 function );
591 
592 		return( NULL );
593 	}
594 #if PY_MAJOR_VERSION >= 3
595 	string_object = PyBytes_FromStringAndSize(
596 	                 NULL,
597 	                 read_size );
598 
599 	buffer = PyBytes_AsString(
600 	          string_object );
601 #else
602 	string_object = PyString_FromStringAndSize(
603 	                 NULL,
604 	                 read_size );
605 
606 	buffer = PyString_AsString(
607 	          string_object );
608 #endif
609 	Py_BEGIN_ALLOW_THREADS
610 
611 	read_count = libvshadow_store_read_buffer(
612 	              pyvshadow_store->store,
613 	              (uint8_t *) buffer,
614 	              (size_t) read_size,
615 	              &error );
616 
617 	Py_END_ALLOW_THREADS
618 
619 	if( read_count <= -1 )
620 	{
621 		pyvshadow_error_raise(
622 		 error,
623 		 PyExc_IOError,
624 		 "%s: unable to read data.",
625 		 function );
626 
627 		libcerror_error_free(
628 		 &error );
629 
630 		Py_DecRef(
631 		 (PyObject *) string_object );
632 
633 		return( NULL );
634 	}
635 	/* Need to resize the string here in case read_size was not fully read.
636 	 */
637 #if PY_MAJOR_VERSION >= 3
638 	if( _PyBytes_Resize(
639 	     &string_object,
640 	     (Py_ssize_t) read_count ) != 0 )
641 #else
642 	if( _PyString_Resize(
643 	     &string_object,
644 	     (Py_ssize_t) read_count ) != 0 )
645 #endif
646 	{
647 		Py_DecRef(
648 		 (PyObject *) string_object );
649 
650 		return( NULL );
651 	}
652 	return( string_object );
653 }
654 
655 /* Reads (store) data at a specific offset
656  * Returns a Python object if successful or NULL on error
657  */
pyvshadow_store_read_buffer_at_offset(pyvshadow_store_t * pyvshadow_store,PyObject * arguments,PyObject * keywords)658 PyObject *pyvshadow_store_read_buffer_at_offset(
659            pyvshadow_store_t *pyvshadow_store,
660            PyObject *arguments,
661            PyObject *keywords )
662 {
663 	libcerror_error_t *error    = NULL;
664 	PyObject *string_object     = NULL;
665 	static char *function       = "pyvshadow_store_read_buffer_at_offset";
666 	static char *keyword_list[] = { "size", "offset", NULL };
667 	char *buffer                = NULL;
668 	off64_t read_offset         = 0;
669 	ssize_t read_count          = 0;
670 	int read_size               = 0;
671 
672 	if( pyvshadow_store == NULL )
673 	{
674 		PyErr_Format(
675 		 PyExc_TypeError,
676 		 "%s: invalid pyvshadow store.",
677 		 function );
678 
679 		return( NULL );
680 	}
681 	if( PyArg_ParseTupleAndKeywords(
682 	     arguments,
683 	     keywords,
684 	     "i|L",
685 	     keyword_list,
686 	     &read_size,
687 	     &read_offset ) == 0 )
688 	{
689 		return( NULL );
690 	}
691 	if( read_size < 0 )
692 	{
693 		PyErr_Format(
694 		 PyExc_ValueError,
695 		 "%s: invalid argument read size value less than zero.",
696 		 function );
697 
698 		return( NULL );
699 	}
700 	/* Make sure the data fits into the memory buffer
701 	 */
702 	if( read_size > INT_MAX )
703 	{
704 		PyErr_Format(
705 		 PyExc_ValueError,
706 		 "%s: invalid argument read size value exceeds maximum.",
707 		 function );
708 
709 		return( NULL );
710 	}
711 	if( read_offset < 0 )
712 	{
713 		PyErr_Format(
714 		 PyExc_ValueError,
715 		 "%s: invalid argument read offset value less than zero.",
716 		 function );
717 
718 		return( NULL );
719 	}
720 	/* Make sure the data fits into the memory buffer
721 	 */
722 #if PY_MAJOR_VERSION >= 3
723 	string_object = PyBytes_FromStringAndSize(
724 	                 NULL,
725 	                 read_size );
726 
727 	buffer = PyBytes_AsString(
728 	          string_object );
729 #else
730 	string_object = PyString_FromStringAndSize(
731 	                 NULL,
732 	                 read_size );
733 
734 	buffer = PyString_AsString(
735 	          string_object );
736 #endif
737 	Py_BEGIN_ALLOW_THREADS
738 
739 	read_count = libvshadow_store_read_buffer_at_offset(
740 	              pyvshadow_store->store,
741 	              (uint8_t *) buffer,
742 	              (size_t) read_size,
743 	              (off64_t) read_offset,
744 	              &error );
745 
746 	Py_END_ALLOW_THREADS
747 
748 	if( read_count <= -1 )
749 	{
750 		pyvshadow_error_raise(
751 		 error,
752 		 PyExc_IOError,
753 		 "%s: unable to read data.",
754 		 function );
755 
756 		libcerror_error_free(
757 		 &error );
758 
759 		Py_DecRef(
760 		 (PyObject *) string_object );
761 
762 		return( NULL );
763 	}
764 	/* Need to resize the string here in case read_size was not fully read.
765 	 */
766 #if PY_MAJOR_VERSION >= 3
767 	if( _PyBytes_Resize(
768 	     &string_object,
769 	     (Py_ssize_t) read_count ) != 0 )
770 #else
771 	if( _PyString_Resize(
772 	     &string_object,
773 	     (Py_ssize_t) read_count ) != 0 )
774 #endif
775 	{
776 		Py_DecRef(
777 		 (PyObject *) string_object );
778 
779 		return( NULL );
780 	}
781 	return( string_object );
782 }
783 
784 /* Seeks a certain offset in the (store) data
785  * Returns a Python object if successful or NULL on error
786  */
pyvshadow_store_seek_offset(pyvshadow_store_t * pyvshadow_store,PyObject * arguments,PyObject * keywords)787 PyObject *pyvshadow_store_seek_offset(
788            pyvshadow_store_t *pyvshadow_store,
789            PyObject *arguments,
790            PyObject *keywords )
791 {
792 	libcerror_error_t *error    = NULL;
793 	static char *function       = "pyvshadow_store_seek_offset";
794 	static char *keyword_list[] = { "offset", "whence", NULL };
795 	off64_t offset              = 0;
796 	int whence                  = 0;
797 
798 	if( pyvshadow_store == NULL )
799 	{
800 		PyErr_Format(
801 		 PyExc_TypeError,
802 		 "%s: invalid pyvshadow store.",
803 		 function );
804 
805 		return( NULL );
806 	}
807 	if( PyArg_ParseTupleAndKeywords(
808 	     arguments,
809 	     keywords,
810 	     "L|i",
811 	     keyword_list,
812 	     &offset,
813 	     &whence ) == 0 )
814 	{
815 		return( NULL );
816 	}
817 	Py_BEGIN_ALLOW_THREADS
818 
819 	offset = libvshadow_store_seek_offset(
820 	          pyvshadow_store->store,
821 	          offset,
822 	          whence,
823 	          &error );
824 
825 	Py_END_ALLOW_THREADS
826 
827  	if( offset == -1 )
828 	{
829 		pyvshadow_error_raise(
830 		 error,
831 		 PyExc_IOError,
832 		 "%s: unable to seek offset.",
833 		 function );
834 
835 		libcerror_error_free(
836 		 &error );
837 
838 		return( NULL );
839 	}
840 	Py_IncRef(
841 	 Py_None );
842 
843 	return( Py_None );
844 }
845 
846 /* Retrieves the current offset in the (store) data
847  * Returns a Python object if successful or NULL on error
848  */
pyvshadow_store_get_offset(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)849 PyObject *pyvshadow_store_get_offset(
850            pyvshadow_store_t *pyvshadow_store,
851            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
852 {
853 	libcerror_error_t *error = NULL;
854 	PyObject *integer_object = NULL;
855 	static char *function    = "pyvshadow_store_get_offset";
856 	off64_t current_offset   = 0;
857 	int result               = 0;
858 
859 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
860 
861 	if( pyvshadow_store == NULL )
862 	{
863 		PyErr_Format(
864 		 PyExc_TypeError,
865 		 "%s: invalid store.",
866 		 function );
867 
868 		return( NULL );
869 	}
870 	Py_BEGIN_ALLOW_THREADS
871 
872 	result = libvshadow_store_get_offset(
873 	          pyvshadow_store->store,
874 	          &current_offset,
875 	          &error );
876 
877 	Py_END_ALLOW_THREADS
878 
879 	if( result != 1 )
880 	{
881 		pyvshadow_error_raise(
882 		 error,
883 		 PyExc_IOError,
884 		 "%s: unable to retrieve offset.",
885 		 function );
886 
887 		libcerror_error_free(
888 		 &error );
889 
890 		return( NULL );
891 	}
892 	integer_object = pyvshadow_integer_signed_new_from_64bit(
893 	                  (int64_t) current_offset );
894 
895 	return( integer_object );
896 }
897 
898 /* Retrieves the size
899  * Returns a Python object if successful or NULL on error
900  */
pyvshadow_store_get_size(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)901 PyObject *pyvshadow_store_get_size(
902            pyvshadow_store_t *pyvshadow_store,
903            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
904 {
905 	libcerror_error_t *error = NULL;
906 	PyObject *integer_object = NULL;
907 	static char *function    = "pyvshadow_store_get_size";
908 	size64_t size            = 0;
909 	int result               = 0;
910 
911 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
912 
913 	if( pyvshadow_store == NULL )
914 	{
915 		PyErr_Format(
916 		 PyExc_TypeError,
917 		 "%s: invalid store.",
918 		 function );
919 
920 		return( NULL );
921 	}
922 	Py_BEGIN_ALLOW_THREADS
923 
924 	result = libvshadow_store_get_size(
925 	          pyvshadow_store->store,
926 	          &size,
927 	          &error );
928 
929 	Py_END_ALLOW_THREADS
930 
931 	if( result != 1 )
932 	{
933 		pyvshadow_error_raise(
934 		 error,
935 		 PyExc_IOError,
936 		 "%s: failed to retrieve size.",
937 		 function );
938 
939 		libcerror_error_free(
940 		 &error );
941 
942 		return( NULL );
943 	}
944 	integer_object = pyvshadow_integer_unsigned_new_from_64bit(
945 	                  (uint64_t) size );
946 
947 	return( integer_object );
948 }
949 
950 /* Retrieves the volume size as stored in the store information
951  * Returns a Python object if successful or NULL on error
952  */
pyvshadow_store_get_volume_size(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)953 PyObject *pyvshadow_store_get_volume_size(
954            pyvshadow_store_t *pyvshadow_store,
955            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
956 {
957 	libcerror_error_t *error = NULL;
958 	PyObject *integer_object = NULL;
959 	static char *function    = "pyvshadow_store_get_volume_size";
960 	size64_t volume_size     = 0;
961 	int result               = 0;
962 
963 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
964 
965 	if( pyvshadow_store == NULL )
966 	{
967 		PyErr_Format(
968 		 PyExc_TypeError,
969 		 "%s: invalid store.",
970 		 function );
971 
972 		return( NULL );
973 	}
974 	Py_BEGIN_ALLOW_THREADS
975 
976 	result = libvshadow_store_get_volume_size(
977 	          pyvshadow_store->store,
978 	          &volume_size,
979 	          &error );
980 
981 	Py_END_ALLOW_THREADS
982 
983 	if( result != 1 )
984 	{
985 		pyvshadow_error_raise(
986 		 error,
987 		 PyExc_IOError,
988 		 "%s: failed to retrieve volume size.",
989 		 function );
990 
991 		libcerror_error_free(
992 		 &error );
993 
994 		return( NULL );
995 	}
996 	integer_object = pyvshadow_integer_unsigned_new_from_64bit(
997 	                  (uint64_t) volume_size );
998 
999 	return( integer_object );
1000 }
1001 
1002 /* Retrieves the identifier
1003  * Returns a Python object if successful or NULL on error
1004  */
pyvshadow_store_get_identifier(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1005 PyObject *pyvshadow_store_get_identifier(
1006            pyvshadow_store_t *pyvshadow_store,
1007            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1008 {
1009 	uint8_t guid_data[ 16 ];
1010 
1011 	libcerror_error_t *error = NULL;
1012 	PyObject *string_object  = NULL;
1013 	static char *function    = "pyvshadow_store_get_identifier";
1014 	int result               = 0;
1015 
1016 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1017 
1018 	if( pyvshadow_store == NULL )
1019 	{
1020 		PyErr_Format(
1021 		 PyExc_TypeError,
1022 		 "%s: invalid store.",
1023 		 function );
1024 
1025 		return( NULL );
1026 	}
1027 	Py_BEGIN_ALLOW_THREADS
1028 
1029 	result = libvshadow_store_get_identifier(
1030 	          pyvshadow_store->store,
1031 	          guid_data,
1032 	          16,
1033 	          &error );
1034 
1035 	Py_END_ALLOW_THREADS
1036 
1037 	if( result != 1 )
1038 	{
1039 		pyvshadow_error_raise(
1040 		 error,
1041 		 PyExc_IOError,
1042 		 "%s: unable to retrieve identifier.",
1043 		 function );
1044 
1045 		libcerror_error_free(
1046 		 &error );
1047 
1048 		return( NULL );
1049 	}
1050 	string_object = pyvshadow_string_new_from_guid(
1051 			 guid_data,
1052 			 16 );
1053 
1054 	return( string_object );
1055 }
1056 
1057 /* Retrieves the creation date and time
1058  * Returns a Python object if successful or NULL on error
1059  */
pyvshadow_store_get_creation_time(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1060 PyObject *pyvshadow_store_get_creation_time(
1061            pyvshadow_store_t *pyvshadow_store,
1062            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1063 {
1064 	libcerror_error_t *error   = NULL;
1065 	PyObject *date_time_object = NULL;
1066 	static char *function      = "pyvshadow_store_get_creation_time";
1067 	uint64_t filetime          = 0;
1068 	int result                 = 0;
1069 
1070 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1071 
1072 	if( pyvshadow_store == NULL )
1073 	{
1074 		PyErr_Format(
1075 		 PyExc_ValueError,
1076 		 "%s: invalid store.",
1077 		 function );
1078 
1079 		return( NULL );
1080 	}
1081 	Py_BEGIN_ALLOW_THREADS
1082 
1083 	result = libvshadow_store_get_creation_time(
1084 	          pyvshadow_store->store,
1085 	          &filetime,
1086 	          &error );
1087 
1088 	Py_END_ALLOW_THREADS
1089 
1090 	if( result != 1 )
1091 	{
1092 		pyvshadow_error_raise(
1093 		 error,
1094 		 PyExc_IOError,
1095 		 "%s: unable to retrieve creation time.",
1096 		 function );
1097 
1098 		libcerror_error_free(
1099 		 &error );
1100 
1101 		return( NULL );
1102 	}
1103 	date_time_object = pyvshadow_datetime_new_from_filetime(
1104 	                    filetime );
1105 
1106 	return( date_time_object );
1107 }
1108 
1109 /* Retrieves the creation date and time as an integer
1110  * Returns a Python object if successful or NULL on error
1111  */
pyvshadow_store_get_creation_time_as_integer(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1112 PyObject *pyvshadow_store_get_creation_time_as_integer(
1113            pyvshadow_store_t *pyvshadow_store,
1114            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1115 {
1116 	libcerror_error_t *error = NULL;
1117 	PyObject *integer_object = NULL;
1118 	static char *function    = "pyvshadow_store_get_creation_time_as_integer";
1119 	uint64_t filetime        = 0;
1120 	int result               = 0;
1121 
1122 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1123 
1124 	if( pyvshadow_store == NULL )
1125 	{
1126 		PyErr_Format(
1127 		 PyExc_ValueError,
1128 		 "%s: invalid store.",
1129 		 function );
1130 
1131 		return( NULL );
1132 	}
1133 	Py_BEGIN_ALLOW_THREADS
1134 
1135 	result = libvshadow_store_get_creation_time(
1136 	          pyvshadow_store->store,
1137 	          &filetime,
1138 	          &error );
1139 
1140 	Py_END_ALLOW_THREADS
1141 
1142 	if( result != 1 )
1143 	{
1144 		pyvshadow_error_raise(
1145 		 error,
1146 		 PyExc_IOError,
1147 		 "%s: unable to retrieve creation time.",
1148 		 function );
1149 
1150 		libcerror_error_free(
1151 		 &error );
1152 
1153 		return( NULL );
1154 	}
1155 	integer_object = pyvshadow_integer_unsigned_new_from_64bit(
1156 	                  (uint64_t) filetime );
1157 
1158 	return( integer_object );
1159 }
1160 
1161 /* Retrieves the copy identifier
1162  * Returns a Python object if successful or NULL on error
1163  */
pyvshadow_store_get_copy_identifier(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1164 PyObject *pyvshadow_store_get_copy_identifier(
1165            pyvshadow_store_t *pyvshadow_store,
1166            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1167 {
1168 	uint8_t guid_data[ 16 ];
1169 
1170 	libcerror_error_t *error = NULL;
1171 	PyObject *string_object  = NULL;
1172 	static char *function    = "pyvshadow_store_get_copy_identifier";
1173 	int result               = 0;
1174 
1175 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1176 
1177 	if( pyvshadow_store == NULL )
1178 	{
1179 		PyErr_Format(
1180 		 PyExc_TypeError,
1181 		 "%s: invalid store.",
1182 		 function );
1183 
1184 		return( NULL );
1185 	}
1186 	Py_BEGIN_ALLOW_THREADS
1187 
1188 	result = libvshadow_store_get_copy_identifier(
1189 	          pyvshadow_store->store,
1190 	          guid_data,
1191 	          16,
1192 	          &error );
1193 
1194 	Py_END_ALLOW_THREADS
1195 
1196 	if( result == -1 )
1197 	{
1198 		pyvshadow_error_raise(
1199 		 error,
1200 		 PyExc_IOError,
1201 		 "%s: unable to retrieve copy identifier.",
1202 		 function );
1203 
1204 		libcerror_error_free(
1205 		 &error );
1206 
1207 		return( NULL );
1208 	}
1209 	else if( result == 0 )
1210 	{
1211 		Py_IncRef(
1212 		 Py_None );
1213 
1214 		return( Py_None );
1215 	}
1216 	string_object = pyvshadow_string_new_from_guid(
1217 			 guid_data,
1218 			 16 );
1219 
1220 	return( string_object );
1221 }
1222 
1223 /* Retrieves the copy set identifier
1224  * Returns a Python object if successful or NULL on error
1225  */
pyvshadow_store_get_copy_set_identifier(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1226 PyObject *pyvshadow_store_get_copy_set_identifier(
1227            pyvshadow_store_t *pyvshadow_store,
1228            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1229 {
1230 	uint8_t guid_data[ 16 ];
1231 
1232 	libcerror_error_t *error = NULL;
1233 	PyObject *string_object  = NULL;
1234 	static char *function    = "pyvshadow_store_get_copy_set_identifier";
1235 	int result               = 0;
1236 
1237 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1238 
1239 	if( pyvshadow_store == NULL )
1240 	{
1241 		PyErr_Format(
1242 		 PyExc_TypeError,
1243 		 "%s: invalid store.",
1244 		 function );
1245 
1246 		return( NULL );
1247 	}
1248 	Py_BEGIN_ALLOW_THREADS
1249 
1250 	result = libvshadow_store_get_copy_set_identifier(
1251 	          pyvshadow_store->store,
1252 	          guid_data,
1253 	          16,
1254 	          &error );
1255 
1256 	Py_END_ALLOW_THREADS
1257 
1258 	if( result == -1 )
1259 	{
1260 		pyvshadow_error_raise(
1261 		 error,
1262 		 PyExc_IOError,
1263 		 "%s: unable to retrieve copy set identifier.",
1264 		 function );
1265 
1266 		libcerror_error_free(
1267 		 &error );
1268 
1269 		return( NULL );
1270 	}
1271 	else if( result == 0 )
1272 	{
1273 		Py_IncRef(
1274 		 Py_None );
1275 
1276 		return( Py_None );
1277 	}
1278 	string_object = pyvshadow_string_new_from_guid(
1279 			 guid_data,
1280 			 16 );
1281 
1282 	return( string_object );
1283 }
1284 
1285 /* Retrieves the number of blocks
1286  * Returns a Python object if successful or NULL on error
1287  */
pyvshadow_store_get_number_of_blocks(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1288 PyObject *pyvshadow_store_get_number_of_blocks(
1289            pyvshadow_store_t *pyvshadow_store,
1290            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1291 {
1292 	libcerror_error_t *error = NULL;
1293 	PyObject *integer_object = NULL;
1294 	static char *function    = "pyvshadow_store_get_number_of_blocks";
1295 	int number_of_blocks     = 0;
1296 	int result               = 0;
1297 
1298 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1299 
1300 	if( pyvshadow_store == NULL )
1301 	{
1302 		PyErr_Format(
1303 		 PyExc_TypeError,
1304 		 "%s: invalid store.",
1305 		 function );
1306 
1307 		return( NULL );
1308 	}
1309 	Py_BEGIN_ALLOW_THREADS
1310 
1311 	result = libvshadow_store_get_number_of_blocks(
1312 	          pyvshadow_store->store,
1313 	          &number_of_blocks,
1314 	          &error );
1315 
1316 	Py_END_ALLOW_THREADS
1317 
1318 	if( result != 1 )
1319 	{
1320 		pyvshadow_error_raise(
1321 		 error,
1322 		 PyExc_IOError,
1323 		 "%s: unable to retrieve number of blocks.",
1324 		 function );
1325 
1326 		libcerror_error_free(
1327 		 &error );
1328 
1329 		return( NULL );
1330 	}
1331 #if PY_MAJOR_VERSION >= 3
1332 	integer_object = PyLong_FromLong(
1333 	                  (long) number_of_blocks );
1334 #else
1335 	integer_object = PyInt_FromLong(
1336 	                  (long) number_of_blocks );
1337 #endif
1338 	return( integer_object );
1339 }
1340 
1341 /* Retrieves a specific block by index
1342  * Returns a Python object if successful or NULL on error
1343  */
pyvshadow_store_get_block_by_index(PyObject * pyvshadow_store,int block_index)1344 PyObject *pyvshadow_store_get_block_by_index(
1345            PyObject *pyvshadow_store,
1346            int block_index )
1347 {
1348 	libcerror_error_t *error  = NULL;
1349 	libvshadow_block_t *block = NULL;
1350 	PyObject *block_object    = NULL;
1351 	static char *function     = "pyvshadow_store_get_block_by_index";
1352 	int result                = 0;
1353 
1354 	if( pyvshadow_store == NULL )
1355 	{
1356 		PyErr_Format(
1357 		 PyExc_TypeError,
1358 		 "%s: invalid store.",
1359 		 function );
1360 
1361 		return( NULL );
1362 	}
1363 	Py_BEGIN_ALLOW_THREADS
1364 
1365 	result = libvshadow_store_get_block_by_index(
1366 	          ( (pyvshadow_store_t *) pyvshadow_store )->store,
1367 	          block_index,
1368 	          &block,
1369 	          &error );
1370 
1371 	Py_END_ALLOW_THREADS
1372 
1373 	if( result != 1 )
1374 	{
1375 		pyvshadow_error_raise(
1376 		 error,
1377 		 PyExc_IOError,
1378 		 "%s: unable to retrieve block: %d.",
1379 		 function,
1380 		 block_index );
1381 
1382 		libcerror_error_free(
1383 		 &error );
1384 
1385 		goto on_error;
1386 	}
1387 	block_object = pyvshadow_block_new(
1388 	                block,
1389 	                pyvshadow_store );
1390 
1391 	if( block_object == NULL )
1392 	{
1393 		PyErr_Format(
1394 		 PyExc_MemoryError,
1395 		 "%s: unable to create block object.",
1396 		 function );
1397 
1398 		goto on_error;
1399 	}
1400 	return( block_object );
1401 
1402 on_error:
1403 	if( block != NULL )
1404 	{
1405 		libvshadow_block_free(
1406 		 &block,
1407 		 NULL );
1408 	}
1409 	return( NULL );
1410 }
1411 
1412 /* Retrieves a specific block
1413  * Returns a Python object if successful or NULL on error
1414  */
pyvshadow_store_get_block(pyvshadow_store_t * pyvshadow_store,PyObject * arguments,PyObject * keywords)1415 PyObject *pyvshadow_store_get_block(
1416            pyvshadow_store_t *pyvshadow_store,
1417            PyObject *arguments,
1418            PyObject *keywords )
1419 {
1420 	PyObject *block_object      = NULL;
1421 	static char *keyword_list[] = { "block_index", NULL };
1422 	int block_index             = 0;
1423 
1424 	if( PyArg_ParseTupleAndKeywords(
1425 	     arguments,
1426 	     keywords,
1427 	     "i",
1428 	     keyword_list,
1429 	     &block_index ) == 0 )
1430 	{
1431 		return( NULL );
1432 	}
1433 	block_object = pyvshadow_store_get_block_by_index(
1434 	                (PyObject *) pyvshadow_store,
1435 	                block_index );
1436 
1437 	return( block_object );
1438 }
1439 
1440 /* Retrieves a blocks sequence and iterator object for the blocks
1441  * Returns a Python object if successful or NULL on error
1442  */
pyvshadow_store_get_blocks(pyvshadow_store_t * pyvshadow_store,PyObject * arguments PYVSHADOW_ATTRIBUTE_UNUSED)1443 PyObject *pyvshadow_store_get_blocks(
1444            pyvshadow_store_t *pyvshadow_store,
1445            PyObject *arguments PYVSHADOW_ATTRIBUTE_UNUSED )
1446 {
1447 	libcerror_error_t *error = NULL;
1448 	PyObject *blocks_object  = NULL;
1449 	static char *function    = "pyvshadow_store_get_blocks";
1450 	int number_of_blocks     = 0;
1451 	int result               = 0;
1452 
1453 	PYVSHADOW_UNREFERENCED_PARAMETER( arguments )
1454 
1455 	if( pyvshadow_store == NULL )
1456 	{
1457 		PyErr_Format(
1458 		 PyExc_TypeError,
1459 		 "%s: invalid store.",
1460 		 function );
1461 
1462 		return( NULL );
1463 	}
1464 	Py_BEGIN_ALLOW_THREADS
1465 
1466 	result = libvshadow_store_get_number_of_blocks(
1467 	          pyvshadow_store->store,
1468 	          &number_of_blocks,
1469 	          &error );
1470 
1471 	Py_END_ALLOW_THREADS
1472 
1473 	if( result != 1 )
1474 	{
1475 		pyvshadow_error_raise(
1476 		 error,
1477 		 PyExc_IOError,
1478 		 "%s: unable to retrieve number of blocks.",
1479 		 function );
1480 
1481 		libcerror_error_free(
1482 		 &error );
1483 
1484 		return( NULL );
1485 	}
1486 	blocks_object = pyvshadow_blocks_new(
1487 	                 (PyObject *) pyvshadow_store,
1488 	                 &pyvshadow_store_get_block_by_index,
1489 	                 number_of_blocks );
1490 
1491 	if( blocks_object == NULL )
1492 	{
1493 		PyErr_Format(
1494 		 PyExc_MemoryError,
1495 		 "%s: unable to create blocks object.",
1496 		 function );
1497 
1498 		return( NULL );
1499 	}
1500 	return( blocks_object );
1501 }
1502 
1503