1 /*
2  * Python object wrapper of libevtx_record_t
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 "pyevtx_datetime.h"
30 #include "pyevtx_error.h"
31 #include "pyevtx_integer.h"
32 #include "pyevtx_libcerror.h"
33 #include "pyevtx_libevtx.h"
34 #include "pyevtx_python.h"
35 #include "pyevtx_record.h"
36 #include "pyevtx_strings.h"
37 #include "pyevtx_unused.h"
38 
39 PyMethodDef pyevtx_record_object_methods[] = {
40 
41 	{ "get_offset",
42 	  (PyCFunction) pyevtx_record_get_offset,
43 	  METH_NOARGS,
44 	  "get_offset() -> Integer or None\n"
45 	  "\n"
46 	  "Retrieves the offset." },
47 
48 	{ "get_identifier",
49 	  (PyCFunction) pyevtx_record_get_identifier,
50 	  METH_NOARGS,
51 	  "get_identifier() -> Integer or None\n"
52 	  "\n"
53 	  "Retrieves the identifier." },
54 
55 	{ "get_creation_time",
56 	  (PyCFunction) pyevtx_record_get_creation_time,
57 	  METH_NOARGS,
58 	  "get_creation_time() -> Datetime or None\n"
59 	  "\n"
60 	  "Retrieves the creation time." },
61 
62 	{ "get_creation_time_as_integer",
63 	  (PyCFunction) pyevtx_record_get_creation_time_as_integer,
64 	  METH_NOARGS,
65 	  "get_creation_time_as_integer() -> Integer or None\n"
66 	  "\n"
67 	  "Retrieves the creation time as a 64-bit integer containing a FILETIME value." },
68 
69 	{ "get_written_time",
70 	  (PyCFunction) pyevtx_record_get_written_time,
71 	  METH_NOARGS,
72 	  "get_written_time() -> Datetime or None\n"
73 	  "\n"
74 	  "Retrieves the written time." },
75 
76 	{ "get_written_time_as_integer",
77 	  (PyCFunction) pyevtx_record_get_written_time_as_integer,
78 	  METH_NOARGS,
79 	  "get_written_time_as_integer() -> Integer or None\n"
80 	  "\n"
81 	  "Retrieves the written time as a 64-bit integer containing a FILETIME value." },
82 
83 	{ "get_event_identifier",
84 	  (PyCFunction) pyevtx_record_get_event_identifier,
85 	  METH_NOARGS,
86 	  "get_event_identifier() -> Integer or None\n"
87 	  "\n"
88 	  "Retrieves the event identifier." },
89 
90 	{ "get_event_identifier_qualifiers",
91 	  (PyCFunction) pyevtx_record_get_event_identifier_qualifiers,
92 	  METH_NOARGS,
93 	  "get_event_identifier_qualifiers() -> Integer or None\n"
94 	  "\n"
95 	  "Retrieves the event identifier qualifiers." },
96 
97 	{ "get_event_level",
98 	  (PyCFunction) pyevtx_record_get_event_level,
99 	  METH_NOARGS,
100 	  "get_event_level() -> Integer or None\n"
101 	  "\n"
102 	  "Retrieves the event level." },
103 
104 	{ "get_provider_identifier",
105 	  (PyCFunction) pyevtx_record_get_provider_identifier,
106 	  METH_NOARGS,
107 	  "get_provider_identifier() -> Unicode string or None\n"
108 	  "\n"
109 	  "Retrieves the provider identifier." },
110 
111 	{ "get_source_name",
112 	  (PyCFunction) pyevtx_record_get_source_name,
113 	  METH_NOARGS,
114 	  "get_source_name() -> Unicode string or None\n"
115 	  "\n"
116 	  "Retrieves the source name." },
117 
118 	{ "get_computer_name",
119 	  (PyCFunction) pyevtx_record_get_computer_name,
120 	  METH_NOARGS,
121 	  "get_computer_name() -> Unicode string or None\n"
122 	  "\n"
123 	  "Retrieves the computer name." },
124 
125 	{ "get_user_security_identifier",
126 	  (PyCFunction) pyevtx_record_get_user_security_identifier,
127 	  METH_NOARGS,
128 	  "get_user_security_identifier() -> Unicode string or None\n"
129 	  "\n"
130 	  "Retrieves the user security identifier." },
131 
132 	{ "get_number_of_strings",
133 	  (PyCFunction) pyevtx_record_get_number_of_strings,
134 	  METH_NOARGS,
135 	  "get_number_of_strings() -> Integer or None\n"
136 	  "\n"
137 	  "Retrieves the number of strings." },
138 
139 	{ "get_string",
140 	  (PyCFunction) pyevtx_record_get_string,
141 	  METH_VARARGS | METH_KEYWORDS,
142 	  "get_string(string_index) -> Unicode string or None\n"
143 	  "\n"
144 	  "Retrieves the string specified by the index." },
145 
146 	{ "get_data",
147 	  (PyCFunction) pyevtx_record_get_data,
148 	  METH_NOARGS,
149 	  "get_data() -> Binary string or None\n"
150 	  "\n"
151 	  "Retrieves the data." },
152 
153 	{ "get_xml_string",
154 	  (PyCFunction) pyevtx_record_get_xml_string,
155 	  METH_NOARGS,
156 	  "get_xml_string() -> Unicode string or None\n"
157 	  "\n"
158 	  "Retrieves the XML string." },
159 
160 	/* Sentinel */
161 	{ NULL, NULL, 0, NULL }
162 };
163 
164 PyGetSetDef pyevtx_record_object_get_set_definitions[] = {
165 
166 	{ "offset",
167 	  (getter) pyevtx_record_get_offset,
168 	  (setter) 0,
169 	  "The offset.",
170 	  NULL },
171 
172 	{ "identifier",
173 	  (getter) pyevtx_record_get_identifier,
174 	  (setter) 0,
175 	  "The identifier.",
176 	  NULL },
177 
178 	{ "creation_time",
179 	  (getter) pyevtx_record_get_creation_time,
180 	  (setter) 0,
181 	  "The creation time.",
182 	  NULL },
183 
184 	{ "written_time",
185 	  (getter) pyevtx_record_get_written_time,
186 	  (setter) 0,
187 	  "The written time.",
188 	  NULL },
189 
190 	{ "event_identifier",
191 	  (getter) pyevtx_record_get_event_identifier,
192 	  (setter) 0,
193 	  "The event identifier.",
194 	  NULL },
195 
196 	{ "event_identifier_qualifiers",
197 	  (getter) pyevtx_record_get_event_identifier_qualifiers,
198 	  (setter) 0,
199 	  "The event identifier qualifiers.",
200 	  NULL },
201 
202 	{ "event_level",
203 	  (getter) pyevtx_record_get_event_level,
204 	  (setter) 0,
205 	  "The event level.",
206 	  NULL },
207 
208 	{ "provider_identifier",
209 	  (getter) pyevtx_record_get_provider_identifier,
210 	  (setter) 0,
211 	  "The provider identifier.",
212 	  NULL },
213 
214 	{ "source_name",
215 	  (getter) pyevtx_record_get_source_name,
216 	  (setter) 0,
217 	  "The source name.",
218 	  NULL },
219 
220 	{ "computer_name",
221 	  (getter) pyevtx_record_get_computer_name,
222 	  (setter) 0,
223 	  "The computer name.",
224 	  NULL },
225 
226 	{ "user_security_identifier",
227 	  (getter) pyevtx_record_get_user_security_identifier,
228 	  (setter) 0,
229 	  "The user security identifier.",
230 	  NULL },
231 
232 	{ "number_of_strings",
233 	  (getter) pyevtx_record_get_number_of_strings,
234 	  (setter) 0,
235 	  "The number of strings.",
236 	  NULL },
237 
238 	{ "strings",
239 	  (getter) pyevtx_record_get_strings,
240 	  (setter) 0,
241 	  "The strings.",
242 	  NULL },
243 
244 	{ "data",
245 	  (getter) pyevtx_record_get_data,
246 	  (setter) 0,
247 	  "The data.",
248 	  NULL },
249 
250 	{ "xml_string",
251 	  (getter) pyevtx_record_get_xml_string,
252 	  (setter) 0,
253 	  "The XML string.",
254 	  NULL },
255 
256 	/* Sentinel */
257 	{ NULL, NULL, NULL, NULL, NULL }
258 };
259 
260 PyTypeObject pyevtx_record_type_object = {
261 	PyVarObject_HEAD_INIT( NULL, 0 )
262 
263 	/* tp_name */
264 	"pyevtx.record",
265 	/* tp_basicsize */
266 	sizeof( pyevtx_record_t ),
267 	/* tp_itemsize */
268 	0,
269 	/* tp_dealloc */
270 	(destructor) pyevtx_record_free,
271 	/* tp_print */
272 	0,
273 	/* tp_getattr */
274 	0,
275 	/* tp_setattr */
276 	0,
277 	/* tp_compare */
278 	0,
279 	/* tp_repr */
280 	0,
281 	/* tp_as_number */
282 	0,
283 	/* tp_as_sequence */
284 	0,
285 	/* tp_as_mapping */
286 	0,
287 	/* tp_hash */
288 	0,
289 	/* tp_call */
290 	0,
291 	/* tp_str */
292 	0,
293 	/* tp_getattro */
294 	0,
295 	/* tp_setattro */
296 	0,
297 	/* tp_as_buffer */
298 	0,
299 	/* tp_flags */
300 	Py_TPFLAGS_DEFAULT,
301 	/* tp_doc */
302 	"pyevtx record object (wraps libevtx_record_t)",
303 	/* tp_traverse */
304 	0,
305 	/* tp_clear */
306 	0,
307 	/* tp_richcompare */
308 	0,
309 	/* tp_weaklistoffset */
310 	0,
311 	/* tp_iter */
312 	0,
313 	/* tp_iternext */
314 	0,
315 	/* tp_methods */
316 	pyevtx_record_object_methods,
317 	/* tp_members */
318 	0,
319 	/* tp_getset */
320 	pyevtx_record_object_get_set_definitions,
321 	/* tp_base */
322 	0,
323 	/* tp_dict */
324 	0,
325 	/* tp_descr_get */
326 	0,
327 	/* tp_descr_set */
328 	0,
329 	/* tp_dictoffset */
330 	0,
331 	/* tp_init */
332 	(initproc) pyevtx_record_init,
333 	/* tp_alloc */
334 	0,
335 	/* tp_new */
336 	0,
337 	/* tp_free */
338 	0,
339 	/* tp_is_gc */
340 	0,
341 	/* tp_bases */
342 	NULL,
343 	/* tp_mro */
344 	NULL,
345 	/* tp_cache */
346 	NULL,
347 	/* tp_subclasses */
348 	NULL,
349 	/* tp_weaklist */
350 	NULL,
351 	/* tp_del */
352 	0
353 };
354 
355 /* Creates a new record object
356  * Returns a Python object if successful or NULL on error
357  */
pyevtx_record_new(libevtx_record_t * record,PyObject * parent_object)358 PyObject *pyevtx_record_new(
359            libevtx_record_t *record,
360            PyObject *parent_object )
361 {
362 	pyevtx_record_t *pyevtx_record = NULL;
363 	static char *function          = "pyevtx_record_new";
364 
365 	if( record == NULL )
366 	{
367 		PyErr_Format(
368 		 PyExc_ValueError,
369 		 "%s: invalid record.",
370 		 function );
371 
372 		return( NULL );
373 	}
374 	pyevtx_record = PyObject_New(
375 	                 struct pyevtx_record,
376 	                 &pyevtx_record_type_object );
377 
378 	if( pyevtx_record == NULL )
379 	{
380 		PyErr_Format(
381 		 PyExc_MemoryError,
382 		 "%s: unable to initialize record.",
383 		 function );
384 
385 		goto on_error;
386 	}
387 	if( pyevtx_record_init(
388 	     pyevtx_record ) != 0 )
389 	{
390 		PyErr_Format(
391 		 PyExc_MemoryError,
392 		 "%s: unable to initialize record.",
393 		 function );
394 
395 		goto on_error;
396 	}
397 	pyevtx_record->record        = record;
398 	pyevtx_record->parent_object = parent_object;
399 
400 	Py_IncRef(
401 	 (PyObject *) pyevtx_record->parent_object );
402 
403 	return( (PyObject *) pyevtx_record );
404 
405 on_error:
406 	if( pyevtx_record != NULL )
407 	{
408 		Py_DecRef(
409 		 (PyObject *) pyevtx_record );
410 	}
411 	return( NULL );
412 }
413 
414 /* Initializes a record object
415  * Returns 0 if successful or -1 on error
416  */
pyevtx_record_init(pyevtx_record_t * pyevtx_record)417 int pyevtx_record_init(
418      pyevtx_record_t *pyevtx_record )
419 {
420 	static char *function = "pyevtx_record_init";
421 
422 	if( pyevtx_record == NULL )
423 	{
424 		PyErr_Format(
425 		 PyExc_ValueError,
426 		 "%s: invalid record.",
427 		 function );
428 
429 		return( -1 );
430 	}
431 	/* Make sure libevtx record is set to NULL
432 	 */
433 	pyevtx_record->record = NULL;
434 
435 	return( 0 );
436 }
437 
438 /* Frees a record object
439  */
pyevtx_record_free(pyevtx_record_t * pyevtx_record)440 void pyevtx_record_free(
441       pyevtx_record_t *pyevtx_record )
442 {
443 	struct _typeobject *ob_type = NULL;
444 	libcerror_error_t *error    = NULL;
445 	static char *function       = "pyevtx_record_free";
446 	int result                  = 0;
447 
448 	if( pyevtx_record == NULL )
449 	{
450 		PyErr_Format(
451 		 PyExc_ValueError,
452 		 "%s: invalid record.",
453 		 function );
454 
455 		return;
456 	}
457 	if( pyevtx_record->record == NULL )
458 	{
459 		PyErr_Format(
460 		 PyExc_ValueError,
461 		 "%s: invalid record - missing libevtx record.",
462 		 function );
463 
464 		return;
465 	}
466 	ob_type = Py_TYPE(
467 	           pyevtx_record );
468 
469 	if( ob_type == NULL )
470 	{
471 		PyErr_Format(
472 		 PyExc_ValueError,
473 		 "%s: missing ob_type.",
474 		 function );
475 
476 		return;
477 	}
478 	if( ob_type->tp_free == NULL )
479 	{
480 		PyErr_Format(
481 		 PyExc_ValueError,
482 		 "%s: invalid ob_type - missing tp_free.",
483 		 function );
484 
485 		return;
486 	}
487 	Py_BEGIN_ALLOW_THREADS
488 
489 	result = libevtx_record_free(
490 	          &( pyevtx_record->record ),
491 	          &error );
492 
493 	Py_END_ALLOW_THREADS
494 
495 	if( result != 1 )
496 	{
497 		pyevtx_error_raise(
498 		 error,
499 		 PyExc_IOError,
500 		 "%s: unable to free libevtx record.",
501 		 function );
502 
503 		libcerror_error_free(
504 		 &error );
505 	}
506 	if( pyevtx_record->parent_object != NULL )
507 	{
508 		Py_DecRef(
509 		 (PyObject *) pyevtx_record->parent_object );
510 	}
511 	ob_type->tp_free(
512 	 (PyObject*) pyevtx_record );
513 }
514 
515 /* Retrieves the offset
516  * Returns a Python object if successful or NULL on error
517  */
pyevtx_record_get_offset(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)518 PyObject *pyevtx_record_get_offset(
519            pyevtx_record_t *pyevtx_record,
520            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
521 {
522 	PyObject *integer_object = NULL;
523 	libcerror_error_t *error = NULL;
524 	static char *function    = "pyevtx_record_get_offset";
525 	off64_t offset           = 0;
526 	int result               = 0;
527 
528 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
529 
530 	if( pyevtx_record == NULL )
531 	{
532 		PyErr_Format(
533 		 PyExc_ValueError,
534 		 "%s: invalid record.",
535 		 function );
536 
537 		return( NULL );
538 	}
539 	Py_BEGIN_ALLOW_THREADS
540 
541 	result = libevtx_record_get_offset(
542 	          pyevtx_record->record,
543 	          &offset,
544 	          &error );
545 
546 	Py_END_ALLOW_THREADS
547 
548 	if( result == -1 )
549 	{
550 		pyevtx_error_raise(
551 		 error,
552 		 PyExc_IOError,
553 		 "%s: unable to retrieve offset.",
554 		 function );
555 
556 		libcerror_error_free(
557 		 &error );
558 
559 		return( NULL );
560 	}
561 	else if( result == 0 )
562 	{
563 		Py_IncRef(
564 		 Py_None );
565 
566 		return( Py_None );
567 	}
568 	integer_object = pyevtx_integer_signed_new_from_64bit(
569 	                  (int64_t) offset );
570 
571 	return( integer_object );
572 }
573 
574 /* Retrieves the identifier
575  * Returns a Python object if successful or NULL on error
576  */
pyevtx_record_get_identifier(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)577 PyObject *pyevtx_record_get_identifier(
578            pyevtx_record_t *pyevtx_record,
579            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
580 {
581 	PyObject *integer_object = NULL;
582 	libcerror_error_t *error = NULL;
583 	static char *function    = "pyevtx_record_get_identifier";
584 	uint64_t value_64bit     = 0;
585 	int result               = 0;
586 
587 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
588 
589 	if( pyevtx_record == NULL )
590 	{
591 		PyErr_Format(
592 		 PyExc_ValueError,
593 		 "%s: invalid record.",
594 		 function );
595 
596 		return( NULL );
597 	}
598 	Py_BEGIN_ALLOW_THREADS
599 
600 	result = libevtx_record_get_identifier(
601 	          pyevtx_record->record,
602 	          &value_64bit,
603 	          &error );
604 
605 	Py_END_ALLOW_THREADS
606 
607 	if( result != 1 )
608 	{
609 		pyevtx_error_raise(
610 		 error,
611 		 PyExc_IOError,
612 		 "%s: unable to retrieve identifier.",
613 		 function );
614 
615 		libcerror_error_free(
616 		 &error );
617 
618 		return( NULL );
619 	}
620 	integer_object = pyevtx_integer_unsigned_new_from_64bit(
621 	                  (uint64_t) value_64bit );
622 
623 	return( integer_object );
624 }
625 
626 /* Retrieves the creation time
627  * Returns a Python object if successful or NULL on error
628  */
pyevtx_record_get_creation_time(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)629 PyObject *pyevtx_record_get_creation_time(
630            pyevtx_record_t *pyevtx_record,
631            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
632 {
633 	PyObject *datetime_object = NULL;
634 	libcerror_error_t *error  = NULL;
635 	static char *function     = "pyevtx_record_get_creation_time";
636 	uint64_t filetime         = 0;
637 	int result                = 0;
638 
639 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
640 
641 	if( pyevtx_record == NULL )
642 	{
643 		PyErr_Format(
644 		 PyExc_ValueError,
645 		 "%s: invalid record.",
646 		 function );
647 
648 		return( NULL );
649 	}
650 	Py_BEGIN_ALLOW_THREADS
651 
652 	result = libevtx_record_get_creation_time(
653 	          pyevtx_record->record,
654 	          &filetime,
655 	          &error );
656 
657 	Py_END_ALLOW_THREADS
658 
659 	if( result == -1 )
660 	{
661 		pyevtx_error_raise(
662 		 error,
663 		 PyExc_IOError,
664 		 "%s: unable to retrieve creation time.",
665 		 function );
666 
667 		libcerror_error_free(
668 		 &error );
669 
670 		return( NULL );
671 	}
672 	else if( result == 0 )
673 	{
674 		Py_IncRef(
675 		 Py_None );
676 
677 		return( Py_None );
678 	}
679 	datetime_object = pyevtx_datetime_new_from_filetime(
680 	                   filetime );
681 
682 	return( datetime_object );
683 }
684 
685 /* Retrieves the creation time as an integer
686  * Returns a Python object if successful or NULL on error
687  */
pyevtx_record_get_creation_time_as_integer(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)688 PyObject *pyevtx_record_get_creation_time_as_integer(
689            pyevtx_record_t *pyevtx_record,
690            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
691 {
692 	PyObject *integer_object = NULL;
693 	libcerror_error_t *error = NULL;
694 	static char *function    = "pyevtx_record_get_creation_time_as_integer";
695 	uint64_t filetime        = 0;
696 	int result               = 0;
697 
698 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
699 
700 	if( pyevtx_record == NULL )
701 	{
702 		PyErr_Format(
703 		 PyExc_ValueError,
704 		 "%s: invalid record.",
705 		 function );
706 
707 		return( NULL );
708 	}
709 	Py_BEGIN_ALLOW_THREADS
710 
711 	result = libevtx_record_get_creation_time(
712 	          pyevtx_record->record,
713 	          &filetime,
714 	          &error );
715 
716 	Py_END_ALLOW_THREADS
717 
718 	if( result == -1 )
719 	{
720 		pyevtx_error_raise(
721 		 error,
722 		 PyExc_IOError,
723 		 "%s: unable to retrieve creation time.",
724 		 function );
725 
726 		libcerror_error_free(
727 		 &error );
728 
729 		return( NULL );
730 	}
731 	else if( result == 0 )
732 	{
733 		Py_IncRef(
734 		 Py_None );
735 
736 		return( Py_None );
737 	}
738 	integer_object = pyevtx_integer_unsigned_new_from_64bit(
739 	                  (uint64_t) filetime );
740 
741 	return( integer_object );
742 }
743 
744 /* Retrieves the written time
745  * Returns a Python object if successful or NULL on error
746  */
pyevtx_record_get_written_time(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)747 PyObject *pyevtx_record_get_written_time(
748            pyevtx_record_t *pyevtx_record,
749            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
750 {
751 	PyObject *datetime_object = NULL;
752 	libcerror_error_t *error  = NULL;
753 	static char *function     = "pyevtx_record_get_written_time";
754 	uint64_t filetime         = 0;
755 	int result                = 0;
756 
757 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
758 
759 	if( pyevtx_record == NULL )
760 	{
761 		PyErr_Format(
762 		 PyExc_ValueError,
763 		 "%s: invalid record.",
764 		 function );
765 
766 		return( NULL );
767 	}
768 	Py_BEGIN_ALLOW_THREADS
769 
770 	result = libevtx_record_get_written_time(
771 	          pyevtx_record->record,
772 	          &filetime,
773 	          &error );
774 
775 	Py_END_ALLOW_THREADS
776 
777 	if( result == -1 )
778 	{
779 		pyevtx_error_raise(
780 		 error,
781 		 PyExc_IOError,
782 		 "%s: unable to retrieve written time.",
783 		 function );
784 
785 		libcerror_error_free(
786 		 &error );
787 
788 		return( NULL );
789 	}
790 	else if( result == 0 )
791 	{
792 		Py_IncRef(
793 		 Py_None );
794 
795 		return( Py_None );
796 	}
797 	datetime_object = pyevtx_datetime_new_from_filetime(
798 	                   filetime );
799 
800 	return( datetime_object );
801 }
802 
803 /* Retrieves the written time as an integer
804  * Returns a Python object if successful or NULL on error
805  */
pyevtx_record_get_written_time_as_integer(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)806 PyObject *pyevtx_record_get_written_time_as_integer(
807            pyevtx_record_t *pyevtx_record,
808            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
809 {
810 	PyObject *integer_object = NULL;
811 	libcerror_error_t *error = NULL;
812 	static char *function    = "pyevtx_record_get_written_time_as_integer";
813 	uint64_t filetime        = 0;
814 	int result               = 0;
815 
816 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
817 
818 	if( pyevtx_record == NULL )
819 	{
820 		PyErr_Format(
821 		 PyExc_ValueError,
822 		 "%s: invalid record.",
823 		 function );
824 
825 		return( NULL );
826 	}
827 	Py_BEGIN_ALLOW_THREADS
828 
829 	result = libevtx_record_get_written_time(
830 	          pyevtx_record->record,
831 	          &filetime,
832 	          &error );
833 
834 	Py_END_ALLOW_THREADS
835 
836 	if( result == -1 )
837 	{
838 		pyevtx_error_raise(
839 		 error,
840 		 PyExc_IOError,
841 		 "%s: unable to retrieve written time.",
842 		 function );
843 
844 		libcerror_error_free(
845 		 &error );
846 
847 		return( NULL );
848 	}
849 	else if( result == 0 )
850 	{
851 		Py_IncRef(
852 		 Py_None );
853 
854 		return( Py_None );
855 	}
856 	integer_object = pyevtx_integer_unsigned_new_from_64bit(
857 	                  (uint64_t) filetime );
858 
859 	return( integer_object );
860 }
861 
862 /* Retrieves the event identifier
863  * Returns a Python object if successful or NULL on error
864  */
pyevtx_record_get_event_identifier(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)865 PyObject *pyevtx_record_get_event_identifier(
866            pyevtx_record_t *pyevtx_record,
867            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
868 {
869 	PyObject *integer_object = NULL;
870 	libcerror_error_t *error = NULL;
871 	static char *function    = "pyevtx_record_get_event_identifier";
872 	uint32_t value_32bit     = 0;
873 	int result               = 0;
874 
875 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
876 
877 	if( pyevtx_record == NULL )
878 	{
879 		PyErr_Format(
880 		 PyExc_ValueError,
881 		 "%s: invalid record.",
882 		 function );
883 
884 		return( NULL );
885 	}
886 	Py_BEGIN_ALLOW_THREADS
887 
888 	result = libevtx_record_get_event_identifier(
889 	          pyevtx_record->record,
890 	          &value_32bit,
891 	          &error );
892 
893 	Py_END_ALLOW_THREADS
894 
895 	if( result == -1 )
896 	{
897 		pyevtx_error_raise(
898 		 error,
899 		 PyExc_IOError,
900 		 "%s: unable to retrieve event identifier.",
901 		 function );
902 
903 		libcerror_error_free(
904 		 &error );
905 
906 		return( NULL );
907 	}
908 	else if( result == 0 )
909 	{
910 		Py_IncRef(
911 		 Py_None );
912 
913 		return( Py_None );
914 	}
915 	integer_object = PyLong_FromUnsignedLong(
916 	                  (unsigned long) value_32bit );
917 
918 	return( integer_object );
919 }
920 
921 /* Retrieves the event identifier qualifiers
922  * Returns a Python object if successful or NULL on error
923  */
pyevtx_record_get_event_identifier_qualifiers(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)924 PyObject *pyevtx_record_get_event_identifier_qualifiers(
925            pyevtx_record_t *pyevtx_record,
926            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
927 {
928 	PyObject *integer_object = NULL;
929 	libcerror_error_t *error = NULL;
930 	static char *function    = "pyevtx_record_get_event_identifier_qualifiers";
931 	uint32_t value_32bit     = 0;
932 	int result               = 0;
933 
934 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
935 
936 	if( pyevtx_record == NULL )
937 	{
938 		PyErr_Format(
939 		 PyExc_ValueError,
940 		 "%s: invalid record.",
941 		 function );
942 
943 		return( NULL );
944 	}
945 	Py_BEGIN_ALLOW_THREADS
946 
947 	result = libevtx_record_get_event_identifier_qualifiers(
948 	          pyevtx_record->record,
949 	          &value_32bit,
950 	          &error );
951 
952 	Py_END_ALLOW_THREADS
953 
954 	if( result == -1 )
955 	{
956 		pyevtx_error_raise(
957 		 error,
958 		 PyExc_IOError,
959 		 "%s: unable to retrieve event identifier qualifiers.",
960 		 function );
961 
962 		libcerror_error_free(
963 		 &error );
964 
965 		return( NULL );
966 	}
967 	else if( result == 0 )
968 	{
969 		Py_IncRef(
970 		 Py_None );
971 
972 		return( Py_None );
973 	}
974 	integer_object = PyLong_FromUnsignedLong(
975 	                  (unsigned long) value_32bit );
976 
977 	return( integer_object );
978 }
979 
980 /* Retrieves the event level
981  * Returns a Python object if successful or NULL on error
982  */
pyevtx_record_get_event_level(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)983 PyObject *pyevtx_record_get_event_level(
984            pyevtx_record_t *pyevtx_record,
985            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
986 {
987 	PyObject *integer_object = NULL;
988 	libcerror_error_t *error = NULL;
989 	static char *function    = "pyevtx_record_get_event_level";
990 	uint8_t event_level      = 0;
991 	int result               = 0;
992 
993 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
994 
995 	if( pyevtx_record == NULL )
996 	{
997 		PyErr_Format(
998 		 PyExc_ValueError,
999 		 "%s: invalid record.",
1000 		 function );
1001 
1002 		return( NULL );
1003 	}
1004 	Py_BEGIN_ALLOW_THREADS
1005 
1006 	result = libevtx_record_get_event_level(
1007 	          pyevtx_record->record,
1008 	          &event_level,
1009 	          &error );
1010 
1011 	Py_END_ALLOW_THREADS
1012 
1013 	if( result != 1 )
1014 	{
1015 		pyevtx_error_raise(
1016 		 error,
1017 		 PyExc_IOError,
1018 		 "%s: unable to retrieve event level.",
1019 		 function );
1020 
1021 		libcerror_error_free(
1022 		 &error );
1023 
1024 		return( NULL );
1025 	}
1026 #if PY_MAJOR_VERSION >= 3
1027 	integer_object = PyLong_FromLong(
1028 	                  (long) event_level );
1029 #else
1030 	integer_object = PyInt_FromLong(
1031 	                  (long) event_level );
1032 #endif
1033 	return( integer_object );
1034 }
1035 
1036 /* Retrieves the provider identifier
1037  * Returns a Python object if successful or NULL on error
1038  */
pyevtx_record_get_provider_identifier(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1039 PyObject *pyevtx_record_get_provider_identifier(
1040            pyevtx_record_t *pyevtx_record,
1041            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1042 {
1043 	PyObject *string_object  = NULL;
1044 	libcerror_error_t *error = NULL;
1045 	const char *errors       = NULL;
1046 	static char *function    = "pyevtx_record_get_provider_identifier";
1047 	char *utf8_string        = NULL;
1048 	size_t utf8_string_size  = 0;
1049 	int result               = 0;
1050 
1051 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1052 
1053 	if( pyevtx_record == NULL )
1054 	{
1055 		PyErr_Format(
1056 		 PyExc_ValueError,
1057 		 "%s: invalid record.",
1058 		 function );
1059 
1060 		return( NULL );
1061 	}
1062 	Py_BEGIN_ALLOW_THREADS
1063 
1064 	result = libevtx_record_get_utf8_provider_identifier_size(
1065 	          pyevtx_record->record,
1066 	          &utf8_string_size,
1067 	          &error );
1068 
1069 	Py_END_ALLOW_THREADS
1070 
1071 	if( result == -1 )
1072 	{
1073 		pyevtx_error_raise(
1074 		 error,
1075 		 PyExc_IOError,
1076 		 "%s: unable to determine size of provider identifier as UTF-8 string.",
1077 		 function );
1078 
1079 		libcerror_error_free(
1080 		 &error );
1081 
1082 		goto on_error;
1083 	}
1084 	else if( ( result == 0 )
1085 	      || ( utf8_string_size == 0 ) )
1086 	{
1087 		Py_IncRef(
1088 		 Py_None );
1089 
1090 		return( Py_None );
1091 	}
1092 	utf8_string = (char *) PyMem_Malloc(
1093 	                        sizeof( char ) * utf8_string_size );
1094 
1095 	if( utf8_string == NULL )
1096 	{
1097 		PyErr_Format(
1098 		 PyExc_MemoryError,
1099 		 "%s: unable to create UTF-8 string.",
1100 		 function );
1101 
1102 		goto on_error;
1103 	}
1104 	Py_BEGIN_ALLOW_THREADS
1105 
1106 	result = libevtx_record_get_utf8_provider_identifier(
1107 	          pyevtx_record->record,
1108 	          (uint8_t *) utf8_string,
1109 	          utf8_string_size,
1110 	          &error );
1111 
1112 	Py_END_ALLOW_THREADS
1113 
1114 	if( result != 1 )
1115 	{
1116 		pyevtx_error_raise(
1117 		 error,
1118 		 PyExc_IOError,
1119 		 "%s: unable to retrieve provider identifier as UTF-8 string.",
1120 		 function );
1121 
1122 		libcerror_error_free(
1123 		 &error );
1124 
1125 		goto on_error;
1126 	}
1127 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1128 	 * the end of string character is part of the string
1129 	 */
1130 	string_object = PyUnicode_DecodeUTF8(
1131 	                 utf8_string,
1132 	                 (Py_ssize_t) utf8_string_size - 1,
1133 	                 errors );
1134 
1135 	if( string_object == NULL )
1136 	{
1137 		PyErr_Format(
1138 		 PyExc_IOError,
1139 		 "%s: unable to convert UTF-8 string into Unicode object.",
1140 		 function );
1141 
1142 		goto on_error;
1143 	}
1144 	PyMem_Free(
1145 	 utf8_string );
1146 
1147 	return( string_object );
1148 
1149 on_error:
1150 	if( utf8_string != NULL )
1151 	{
1152 		PyMem_Free(
1153 		 utf8_string );
1154 	}
1155 	return( NULL );
1156 }
1157 
1158 /* Retrieves the source name
1159  * Returns a Python object if successful or NULL on error
1160  */
pyevtx_record_get_source_name(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1161 PyObject *pyevtx_record_get_source_name(
1162            pyevtx_record_t *pyevtx_record,
1163            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1164 {
1165 	PyObject *string_object  = NULL;
1166 	libcerror_error_t *error = NULL;
1167 	const char *errors       = NULL;
1168 	static char *function    = "pyevtx_record_get_source_name";
1169 	char *utf8_string        = NULL;
1170 	size_t utf8_string_size  = 0;
1171 	int result               = 0;
1172 
1173 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1174 
1175 	if( pyevtx_record == NULL )
1176 	{
1177 		PyErr_Format(
1178 		 PyExc_ValueError,
1179 		 "%s: invalid record.",
1180 		 function );
1181 
1182 		return( NULL );
1183 	}
1184 	Py_BEGIN_ALLOW_THREADS
1185 
1186 	result = libevtx_record_get_utf8_source_name_size(
1187 	          pyevtx_record->record,
1188 	          &utf8_string_size,
1189 	          &error );
1190 
1191 	Py_END_ALLOW_THREADS
1192 
1193 	if( result == -1 )
1194 	{
1195 		pyevtx_error_raise(
1196 		 error,
1197 		 PyExc_IOError,
1198 		 "%s: unable to determine size of source name as UTF-8 string.",
1199 		 function );
1200 
1201 		libcerror_error_free(
1202 		 &error );
1203 
1204 		goto on_error;
1205 	}
1206 	else if( ( result == 0 )
1207 	      || ( utf8_string_size == 0 ) )
1208 	{
1209 		Py_IncRef(
1210 		 Py_None );
1211 
1212 		return( Py_None );
1213 	}
1214 	utf8_string = (char *) PyMem_Malloc(
1215 	                        sizeof( char ) * utf8_string_size );
1216 
1217 	if( utf8_string == NULL )
1218 	{
1219 		PyErr_Format(
1220 		 PyExc_MemoryError,
1221 		 "%s: unable to create UTF-8 string.",
1222 		 function );
1223 
1224 		goto on_error;
1225 	}
1226 	Py_BEGIN_ALLOW_THREADS
1227 
1228 	result = libevtx_record_get_utf8_source_name(
1229 	          pyevtx_record->record,
1230 	          (uint8_t *) utf8_string,
1231 	          utf8_string_size,
1232 	          &error );
1233 
1234 	Py_END_ALLOW_THREADS
1235 
1236 	if( result != 1 )
1237 	{
1238 		pyevtx_error_raise(
1239 		 error,
1240 		 PyExc_IOError,
1241 		 "%s: unable to retrieve source name as UTF-8 string.",
1242 		 function );
1243 
1244 		libcerror_error_free(
1245 		 &error );
1246 
1247 		goto on_error;
1248 	}
1249 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1250 	 * the end of string character is part of the string
1251 	 */
1252 	string_object = PyUnicode_DecodeUTF8(
1253 	                 utf8_string,
1254 	                 (Py_ssize_t) utf8_string_size - 1,
1255 	                 errors );
1256 
1257 	if( string_object == NULL )
1258 	{
1259 		PyErr_Format(
1260 		 PyExc_IOError,
1261 		 "%s: unable to convert UTF-8 string into Unicode object.",
1262 		 function );
1263 
1264 		goto on_error;
1265 	}
1266 	PyMem_Free(
1267 	 utf8_string );
1268 
1269 	return( string_object );
1270 
1271 on_error:
1272 	if( utf8_string != NULL )
1273 	{
1274 		PyMem_Free(
1275 		 utf8_string );
1276 	}
1277 	return( NULL );
1278 }
1279 
1280 /* Retrieves the computer name
1281  * Returns a Python object if successful or NULL on error
1282  */
pyevtx_record_get_computer_name(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1283 PyObject *pyevtx_record_get_computer_name(
1284            pyevtx_record_t *pyevtx_record,
1285            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1286 {
1287 	PyObject *string_object  = NULL;
1288 	libcerror_error_t *error = NULL;
1289 	const char *errors       = NULL;
1290 	static char *function    = "pyevtx_record_get_computer_name";
1291 	char *utf8_string        = NULL;
1292 	size_t utf8_string_size  = 0;
1293 	int result               = 0;
1294 
1295 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1296 
1297 	if( pyevtx_record == NULL )
1298 	{
1299 		PyErr_Format(
1300 		 PyExc_ValueError,
1301 		 "%s: invalid record.",
1302 		 function );
1303 
1304 		return( NULL );
1305 	}
1306 	Py_BEGIN_ALLOW_THREADS
1307 
1308 	result = libevtx_record_get_utf8_computer_name_size(
1309 	          pyevtx_record->record,
1310 	          &utf8_string_size,
1311 	          &error );
1312 
1313 	Py_END_ALLOW_THREADS
1314 
1315 	if( result == -1 )
1316 	{
1317 		pyevtx_error_raise(
1318 		 error,
1319 		 PyExc_IOError,
1320 		 "%s: unable to determine size of computer name as UTF-8 string.",
1321 		 function );
1322 
1323 		libcerror_error_free(
1324 		 &error );
1325 
1326 		goto on_error;
1327 	}
1328 	else if( ( result == 0 )
1329 	      || ( utf8_string_size == 0 ) )
1330 	{
1331 		Py_IncRef(
1332 		 Py_None );
1333 
1334 		return( Py_None );
1335 	}
1336 	utf8_string = (char *) PyMem_Malloc(
1337 	                        sizeof( char ) * utf8_string_size );
1338 
1339 	if( utf8_string == NULL )
1340 	{
1341 		PyErr_Format(
1342 		 PyExc_MemoryError,
1343 		 "%s: unable to create UTF-8 string.",
1344 		 function );
1345 
1346 		goto on_error;
1347 	}
1348 	Py_BEGIN_ALLOW_THREADS
1349 
1350 	result = libevtx_record_get_utf8_computer_name(
1351 	          pyevtx_record->record,
1352 	          (uint8_t *) utf8_string,
1353 	          utf8_string_size,
1354 	          &error );
1355 
1356 	Py_END_ALLOW_THREADS
1357 
1358 	if( result != 1 )
1359 	{
1360 		pyevtx_error_raise(
1361 		 error,
1362 		 PyExc_IOError,
1363 		 "%s: unable to retrieve computer name as UTF-8 string.",
1364 		 function );
1365 
1366 		libcerror_error_free(
1367 		 &error );
1368 
1369 		goto on_error;
1370 	}
1371 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1372 	 * the end of string character is part of the string
1373 	 */
1374 	string_object = PyUnicode_DecodeUTF8(
1375 	                 utf8_string,
1376 	                 (Py_ssize_t) utf8_string_size - 1,
1377 	                 errors );
1378 
1379 	if( string_object == NULL )
1380 	{
1381 		PyErr_Format(
1382 		 PyExc_IOError,
1383 		 "%s: unable to convert UTF-8 string into Unicode object.",
1384 		 function );
1385 
1386 		goto on_error;
1387 	}
1388 	PyMem_Free(
1389 	 utf8_string );
1390 
1391 	return( string_object );
1392 
1393 on_error:
1394 	if( utf8_string != NULL )
1395 	{
1396 		PyMem_Free(
1397 		 utf8_string );
1398 	}
1399 	return( NULL );
1400 }
1401 
1402 /* Retrieves the user security identifier
1403  * Returns a Python object if successful or NULL on error
1404  */
pyevtx_record_get_user_security_identifier(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1405 PyObject *pyevtx_record_get_user_security_identifier(
1406            pyevtx_record_t *pyevtx_record,
1407            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1408 {
1409 	PyObject *string_object  = NULL;
1410 	libcerror_error_t *error = NULL;
1411 	const char *errors       = NULL;
1412 	static char *function    = "pyevtx_record_get_user_security_identifier";
1413 	char *utf8_string        = NULL;
1414 	size_t utf8_string_size  = 0;
1415 	int result               = 0;
1416 
1417 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1418 
1419 	if( pyevtx_record == NULL )
1420 	{
1421 		PyErr_Format(
1422 		 PyExc_ValueError,
1423 		 "%s: invalid record.",
1424 		 function );
1425 
1426 		return( NULL );
1427 	}
1428 	Py_BEGIN_ALLOW_THREADS
1429 
1430 	result = libevtx_record_get_utf8_user_security_identifier_size(
1431 	          pyevtx_record->record,
1432 	          &utf8_string_size,
1433 	          &error );
1434 
1435 	Py_END_ALLOW_THREADS
1436 
1437 	if( result == -1 )
1438 	{
1439 		pyevtx_error_raise(
1440 		 error,
1441 		 PyExc_IOError,
1442 		 "%s: unable to determine size of user security identifier as UTF-8 string.",
1443 		 function );
1444 
1445 		libcerror_error_free(
1446 		 &error );
1447 
1448 		goto on_error;
1449 	}
1450 	else if( ( result == 0 )
1451 	      || ( utf8_string_size == 0 ) )
1452 	{
1453 		Py_IncRef(
1454 		 Py_None );
1455 
1456 		return( Py_None );
1457 	}
1458 	utf8_string = (char *) PyMem_Malloc(
1459 	                        sizeof( char ) * utf8_string_size );
1460 
1461 	if( utf8_string == NULL )
1462 	{
1463 		PyErr_Format(
1464 		 PyExc_MemoryError,
1465 		 "%s: unable to create UTF-8 string.",
1466 		 function );
1467 
1468 		goto on_error;
1469 	}
1470 	Py_BEGIN_ALLOW_THREADS
1471 
1472 	result = libevtx_record_get_utf8_user_security_identifier(
1473 	          pyevtx_record->record,
1474 	          (uint8_t *) utf8_string,
1475 	          utf8_string_size,
1476 	          &error );
1477 
1478 	Py_END_ALLOW_THREADS
1479 
1480 	if( result != 1 )
1481 	{
1482 		pyevtx_error_raise(
1483 		 error,
1484 		 PyExc_IOError,
1485 		 "%s: unable to retrieve user security identifier as UTF-8 string.",
1486 		 function );
1487 
1488 		libcerror_error_free(
1489 		 &error );
1490 
1491 		goto on_error;
1492 	}
1493 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1494 	 * the end of string character is part of the string
1495 	 */
1496 	string_object = PyUnicode_DecodeUTF8(
1497 	                 utf8_string,
1498 	                 (Py_ssize_t) utf8_string_size - 1,
1499 	                 errors );
1500 
1501 	if( string_object == NULL )
1502 	{
1503 		PyErr_Format(
1504 		 PyExc_IOError,
1505 		 "%s: unable to convert UTF-8 string into Unicode object.",
1506 		 function );
1507 
1508 		goto on_error;
1509 	}
1510 	PyMem_Free(
1511 	 utf8_string );
1512 
1513 	return( string_object );
1514 
1515 on_error:
1516 	if( utf8_string != NULL )
1517 	{
1518 		PyMem_Free(
1519 		 utf8_string );
1520 	}
1521 	return( NULL );
1522 }
1523 
1524 /* Retrieves the number of strings
1525  * Returns a Python object if successful or NULL on error
1526  */
pyevtx_record_get_number_of_strings(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1527 PyObject *pyevtx_record_get_number_of_strings(
1528            pyevtx_record_t *pyevtx_record,
1529            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1530 {
1531 	PyObject *integer_object = NULL;
1532 	libcerror_error_t *error = NULL;
1533 	static char *function    = "pyevtx_record_get_number_of_strings";
1534 	int number_of_strings    = 0;
1535 	int result               = 0;
1536 
1537 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1538 
1539 	if( pyevtx_record == NULL )
1540 	{
1541 		PyErr_Format(
1542 		 PyExc_ValueError,
1543 		 "%s: invalid record.",
1544 		 function );
1545 
1546 		return( NULL );
1547 	}
1548 	Py_BEGIN_ALLOW_THREADS
1549 
1550 	result = libevtx_record_get_number_of_strings(
1551 	          pyevtx_record->record,
1552 	          &number_of_strings,
1553 	          &error );
1554 
1555 	Py_END_ALLOW_THREADS
1556 
1557 	if( result != 1 )
1558 	{
1559 		pyevtx_error_raise(
1560 		 error,
1561 		 PyExc_IOError,
1562 		 "%s: unable to retrieve number of strings.",
1563 		 function );
1564 
1565 		libcerror_error_free(
1566 		 &error );
1567 
1568 		return( NULL );
1569 	}
1570 #if PY_MAJOR_VERSION >= 3
1571 	integer_object = PyLong_FromLong(
1572 	                  (long) number_of_strings );
1573 #else
1574 	integer_object = PyInt_FromLong(
1575 	                  (long) number_of_strings );
1576 #endif
1577 	return( integer_object );
1578 }
1579 
1580 /* Retrieves a specific string by index
1581  * Returns a Python object if successful or NULL on error
1582  */
pyevtx_record_get_string_by_index(PyObject * pyevtx_record,int string_index)1583 PyObject *pyevtx_record_get_string_by_index(
1584            PyObject *pyevtx_record,
1585            int string_index )
1586 {
1587 	PyObject *string_object  = NULL;
1588 	libcerror_error_t *error = NULL;
1589 	uint8_t *utf8_string     = NULL;
1590 	const char *errors       = NULL;
1591 	static char *function    = "pyevtx_record_get_string_by_index";
1592 	size_t utf8_string_size  = 0;
1593 	int result               = 0;
1594 
1595 	if( pyevtx_record == NULL )
1596 	{
1597 		PyErr_Format(
1598 		 PyExc_ValueError,
1599 		 "%s: invalid record.",
1600 		 function );
1601 
1602 		return( NULL );
1603 	}
1604 	Py_BEGIN_ALLOW_THREADS
1605 
1606 	result = libevtx_record_get_utf8_string_size(
1607 	          ( (pyevtx_record_t *) pyevtx_record )->record,
1608 	          string_index,
1609 	          &utf8_string_size,
1610 	          &error );
1611 
1612 	Py_END_ALLOW_THREADS
1613 
1614 	if( result == -1 )
1615 	{
1616 		pyevtx_error_raise(
1617 		 error,
1618 		 PyExc_IOError,
1619 		 "%s: unable to determine size of string: %d as UTF-8 string.",
1620 		 function,
1621 		 string_index );
1622 
1623 		libcerror_error_free(
1624 		 &error );
1625 
1626 		goto on_error;
1627 	}
1628 	else if( ( result == 0 )
1629 	      || ( utf8_string_size == 0 ) )
1630 	{
1631 		Py_IncRef(
1632 		 Py_None );
1633 
1634 		return( Py_None );
1635 	}
1636 	utf8_string = (uint8_t *) PyMem_Malloc(
1637 	                           sizeof( uint8_t ) * utf8_string_size );
1638 
1639 	if( utf8_string == NULL )
1640 	{
1641 		PyErr_Format(
1642 		 PyExc_MemoryError,
1643 		 "%s: unable to create UTF-8 string.",
1644 		 function );
1645 
1646 		goto on_error;
1647 	}
1648 	Py_BEGIN_ALLOW_THREADS
1649 
1650 	result = libevtx_record_get_utf8_string(
1651 	          ( (pyevtx_record_t *) pyevtx_record )->record,
1652 	          string_index,
1653 	          utf8_string,
1654 	          utf8_string_size,
1655 	          &error );
1656 
1657 	Py_END_ALLOW_THREADS
1658 
1659 	if( result != 1 )
1660 	{
1661 		pyevtx_error_raise(
1662 		 error,
1663 		 PyExc_IOError,
1664 		 "%s: unable to retrieve string: %d as UTF-8 string.",
1665 		 function,
1666 		 string_index );
1667 
1668 		libcerror_error_free(
1669 		 &error );
1670 
1671 		goto on_error;
1672 	}
1673 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1674 	 * the end of string character is part of the string
1675 	 */
1676 	string_object = PyUnicode_DecodeUTF8(
1677 	                 (char *) utf8_string,
1678 	                 (Py_ssize_t) utf8_string_size - 1,
1679 	                 errors );
1680 
1681 	if( string_object == NULL )
1682 	{
1683 		PyErr_Format(
1684 		 PyExc_IOError,
1685 		 "%s: unable to convert UTF-8 string into Unicode object.",
1686 		 function );
1687 
1688 		goto on_error;
1689 	}
1690 	PyMem_Free(
1691 	 utf8_string );
1692 
1693 	return( string_object );
1694 
1695 on_error:
1696 	if( utf8_string != NULL )
1697 	{
1698 		PyMem_Free(
1699 		 utf8_string );
1700 	}
1701 	return( NULL );
1702 }
1703 
1704 /* Retrieves a specific string
1705  * Returns a Python object if successful or NULL on error
1706  */
pyevtx_record_get_string(pyevtx_record_t * pyevtx_record,PyObject * arguments,PyObject * keywords)1707 PyObject *pyevtx_record_get_string(
1708            pyevtx_record_t *pyevtx_record,
1709            PyObject *arguments,
1710            PyObject *keywords )
1711 {
1712 	PyObject *string_object     = NULL;
1713 	static char *keyword_list[] = { "string_index", NULL };
1714 	int string_index            = 0;
1715 
1716 	if( PyArg_ParseTupleAndKeywords(
1717 	     arguments,
1718 	     keywords,
1719 	     "i",
1720 	     keyword_list,
1721 	     &string_index ) == 0 )
1722 	{
1723 		return( NULL );
1724 	}
1725 	string_object = pyevtx_record_get_string_by_index(
1726 	                 (PyObject *) pyevtx_record,
1727 	                 string_index );
1728 
1729 	return( string_object );
1730 }
1731 
1732 /* Retrieves a sequence and iterator object for the strings
1733  * Returns a Python object if successful or NULL on error
1734  */
pyevtx_record_get_strings(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1735 PyObject *pyevtx_record_get_strings(
1736            pyevtx_record_t *pyevtx_record,
1737            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1738 {
1739 	PyObject *sequence_object = NULL;
1740 	libcerror_error_t *error  = NULL;
1741 	static char *function     = "pyevtx_record_get_strings";
1742 	int number_of_strings     = 0;
1743 	int result                = 0;
1744 
1745 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1746 
1747 	if( pyevtx_record == NULL )
1748 	{
1749 		PyErr_Format(
1750 		 PyExc_ValueError,
1751 		 "%s: invalid record.",
1752 		 function );
1753 
1754 		return( NULL );
1755 	}
1756 	Py_BEGIN_ALLOW_THREADS
1757 
1758 	result = libevtx_record_get_number_of_strings(
1759 	          pyevtx_record->record,
1760 	          &number_of_strings,
1761 	          &error );
1762 
1763 	Py_END_ALLOW_THREADS
1764 
1765 	if( result != 1 )
1766 	{
1767 		pyevtx_error_raise(
1768 		 error,
1769 		 PyExc_IOError,
1770 		 "%s: unable to retrieve number of strings.",
1771 		 function );
1772 
1773 		libcerror_error_free(
1774 		 &error );
1775 
1776 		return( NULL );
1777 	}
1778 	sequence_object = pyevtx_strings_new(
1779 	                   (PyObject *) pyevtx_record,
1780 	                   &pyevtx_record_get_string_by_index,
1781 	                   number_of_strings );
1782 
1783 	if( sequence_object == NULL )
1784 	{
1785 		PyErr_Format(
1786 		 PyExc_MemoryError,
1787 		 "%s: unable to create sequence object.",
1788 		 function );
1789 
1790 		return( NULL );
1791 	}
1792 	return( sequence_object );
1793 }
1794 
1795 /* Retrieves the data
1796  * Returns a Python object if successful or NULL on error
1797  */
pyevtx_record_get_data(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1798 PyObject *pyevtx_record_get_data(
1799            pyevtx_record_t *pyevtx_record,
1800            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1801 {
1802 	PyObject *bytes_object   = NULL;
1803 	libcerror_error_t *error = NULL;
1804 	char *data               = NULL;
1805 	static char *function    = "pyevtx_record_get_data";
1806 	size_t data_size         = 0;
1807 	int result               = 0;
1808 
1809 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1810 
1811 	if( pyevtx_record == NULL )
1812 	{
1813 		PyErr_Format(
1814 		 PyExc_ValueError,
1815 		 "%s: invalid record.",
1816 		 function );
1817 
1818 		return( NULL );
1819 	}
1820 	Py_BEGIN_ALLOW_THREADS
1821 
1822 	result = libevtx_record_get_data_size(
1823 	          pyevtx_record->record,
1824 	          &data_size,
1825 	          &error );
1826 
1827 	Py_END_ALLOW_THREADS
1828 
1829 	if( result == -1 )
1830 	{
1831 		pyevtx_error_raise(
1832 		 error,
1833 		 PyExc_IOError,
1834 		 "%s: unable to retrieve data size.",
1835 		 function );
1836 
1837 		libcerror_error_free(
1838 		 &error );
1839 
1840 		goto on_error;
1841 	}
1842 	else if( ( result == 0 )
1843 	      || ( data_size == 0 ) )
1844 	{
1845 		Py_IncRef(
1846 		 Py_None );
1847 
1848 		return( Py_None );
1849 	}
1850 	data = (char *) PyMem_Malloc(
1851 	                 sizeof( char ) * data_size );
1852 
1853 	if( data == NULL )
1854 	{
1855 		PyErr_Format(
1856 		 PyExc_MemoryError,
1857 		 "%s: unable to create data.",
1858 		 function );
1859 
1860 		goto on_error;
1861 	}
1862 	Py_BEGIN_ALLOW_THREADS
1863 
1864 	result = libevtx_record_get_data(
1865 	          pyevtx_record->record,
1866 	          (uint8_t *) data,
1867 	          data_size,
1868 	          &error );
1869 
1870 	Py_END_ALLOW_THREADS
1871 
1872 	if( result != 1 )
1873 	{
1874 		pyevtx_error_raise(
1875 		 error,
1876 		 PyExc_IOError,
1877 		 "%s: unable to retrieve data.",
1878 		 function );
1879 
1880 		libcerror_error_free(
1881 		 &error );
1882 
1883 		goto on_error;
1884 	}
1885 	/* This is a binary string so include the full size
1886 	 */
1887 #if PY_MAJOR_VERSION >= 3
1888 	bytes_object = PyBytes_FromStringAndSize(
1889 	                data,
1890 	                (Py_ssize_t) data_size );
1891 #else
1892 	bytes_object = PyString_FromStringAndSize(
1893 	                data,
1894 	                (Py_ssize_t) data_size );
1895 #endif
1896 	if( bytes_object == NULL )
1897 	{
1898 		PyErr_Format(
1899 		 PyExc_IOError,
1900 		 "%s: unable to convert data into Bytes object.",
1901 		 function );
1902 
1903 		goto on_error;
1904 	}
1905 	PyMem_Free(
1906 	 data );
1907 
1908 	return( bytes_object );
1909 
1910 on_error:
1911 	if( data != NULL )
1912 	{
1913 		PyMem_Free(
1914 		 data );
1915 	}
1916 	return( NULL );
1917 }
1918 
1919 /* Retrieves the xml string
1920  * Returns a Python object if successful or NULL on error
1921  */
pyevtx_record_get_xml_string(pyevtx_record_t * pyevtx_record,PyObject * arguments PYEVTX_ATTRIBUTE_UNUSED)1922 PyObject *pyevtx_record_get_xml_string(
1923            pyevtx_record_t *pyevtx_record,
1924            PyObject *arguments PYEVTX_ATTRIBUTE_UNUSED )
1925 {
1926 	PyObject *string_object  = NULL;
1927 	libcerror_error_t *error = NULL;
1928 	const char *errors       = NULL;
1929 	static char *function    = "pyevtx_record_get_xml_string";
1930 	char *utf8_string        = NULL;
1931 	size_t utf8_string_size  = 0;
1932 	int result               = 0;
1933 
1934 	PYEVTX_UNREFERENCED_PARAMETER( arguments )
1935 
1936 	if( pyevtx_record == NULL )
1937 	{
1938 		PyErr_Format(
1939 		 PyExc_ValueError,
1940 		 "%s: invalid record.",
1941 		 function );
1942 
1943 		return( NULL );
1944 	}
1945 	Py_BEGIN_ALLOW_THREADS
1946 
1947 	result = libevtx_record_get_utf8_xml_string_size(
1948 	          pyevtx_record->record,
1949 	          &utf8_string_size,
1950 	          &error );
1951 
1952 	Py_END_ALLOW_THREADS
1953 
1954 	if( result == -1 )
1955 	{
1956 		pyevtx_error_raise(
1957 		 error,
1958 		 PyExc_IOError,
1959 		 "%s: unable to determine size of xml string as UTF-8 string.",
1960 		 function );
1961 
1962 		libcerror_error_free(
1963 		 &error );
1964 
1965 		goto on_error;
1966 	}
1967 	else if( ( result == 0 )
1968 	      || ( utf8_string_size == 0 ) )
1969 	{
1970 		Py_IncRef(
1971 		 Py_None );
1972 
1973 		return( Py_None );
1974 	}
1975 	utf8_string = (char *) PyMem_Malloc(
1976 	                        sizeof( char ) * utf8_string_size );
1977 
1978 	if( utf8_string == NULL )
1979 	{
1980 		PyErr_Format(
1981 		 PyExc_MemoryError,
1982 		 "%s: unable to create UTF-8 string.",
1983 		 function );
1984 
1985 		goto on_error;
1986 	}
1987 	Py_BEGIN_ALLOW_THREADS
1988 
1989 	result = libevtx_record_get_utf8_xml_string(
1990 	          pyevtx_record->record,
1991 	          (uint8_t *) utf8_string,
1992 	          utf8_string_size,
1993 	          &error );
1994 
1995 	Py_END_ALLOW_THREADS
1996 
1997 	if( result != 1 )
1998 	{
1999 		pyevtx_error_raise(
2000 		 error,
2001 		 PyExc_IOError,
2002 		 "%s: unable to retrieve xml string as UTF-8 string.",
2003 		 function );
2004 
2005 		libcerror_error_free(
2006 		 &error );
2007 
2008 		goto on_error;
2009 	}
2010 	/* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
2011 	 * the end of string character is part of the string
2012 	 */
2013 	string_object = PyUnicode_DecodeUTF8(
2014 	                 utf8_string,
2015 	                 (Py_ssize_t) utf8_string_size - 1,
2016 	                 errors );
2017 
2018 	if( string_object == NULL )
2019 	{
2020 		PyErr_Format(
2021 		 PyExc_IOError,
2022 		 "%s: unable to convert UTF-8 string into Unicode object.",
2023 		 function );
2024 
2025 		goto on_error;
2026 	}
2027 	PyMem_Free(
2028 	 utf8_string );
2029 
2030 	return( string_object );
2031 
2032 on_error:
2033 	if( utf8_string != NULL )
2034 	{
2035 		PyMem_Free(
2036 		 utf8_string );
2037 	}
2038 	return( NULL );
2039 }
2040 
2041