1 /*
2  * Python file object IO handle functions
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 <memory.h>
24 #include <types.h>
25 
26 #include "pyevt_error.h"
27 #include "pyevt_file_object_io_handle.h"
28 #include "pyevt_integer.h"
29 #include "pyevt_libbfio.h"
30 #include "pyevt_libcerror.h"
31 #include "pyevt_python.h"
32 
33 /* Creates a file object IO handle
34  * Make sure the value file_object_io_handle is referencing, is set to NULL
35  * Returns 1 if successful or -1 on error
36  */
pyevt_file_object_io_handle_initialize(pyevt_file_object_io_handle_t ** file_object_io_handle,PyObject * file_object,libcerror_error_t ** error)37 int pyevt_file_object_io_handle_initialize(
38      pyevt_file_object_io_handle_t **file_object_io_handle,
39      PyObject *file_object,
40      libcerror_error_t **error )
41 {
42 	static char *function = "pyevt_file_object_io_handle_initialize";
43 
44 	if( file_object_io_handle == NULL )
45 	{
46 		libcerror_error_set(
47 		 error,
48 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 		 "%s: invalid file object IO handle.",
51 		 function );
52 
53 		return( -1 );
54 	}
55 	if( *file_object_io_handle != NULL )
56 	{
57 		libcerror_error_set(
58 		 error,
59 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 		 "%s: invalid file object IO handle value already set.",
62 		 function );
63 
64 		return( -1 );
65 	}
66 	if( file_object == NULL )
67 	{
68 		libcerror_error_set(
69 		 error,
70 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
72 		 "%s: invalid file object.",
73 		 function );
74 
75 		return( -1 );
76 	}
77 	*file_object_io_handle = (pyevt_file_object_io_handle_t *) PyMem_Malloc(
78 	                                                            sizeof( pyevt_file_object_io_handle_t ) );
79 
80 	if( *file_object_io_handle == NULL )
81 	{
82 		libcerror_error_set(
83 		 error,
84 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
85 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86 		 "%s: unable to create file object IO handle.",
87 		 function );
88 
89 		goto on_error;
90 	}
91 	if( memory_set(
92 	     *file_object_io_handle,
93 	     0,
94 	     sizeof( pyevt_file_object_io_handle_t ) ) == NULL )
95 	{
96 		libcerror_error_set(
97 		 error,
98 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
99 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
100 		 "%s: unable to clear file object IO handle.",
101 		 function );
102 
103 		goto on_error;
104 	}
105 	( *file_object_io_handle )->file_object = file_object;
106 
107 	Py_IncRef(
108 	 ( *file_object_io_handle )->file_object );
109 
110 	return( 1 );
111 
112 on_error:
113 	if( *file_object_io_handle != NULL )
114 	{
115 		PyMem_Free(
116 		 *file_object_io_handle );
117 
118 		*file_object_io_handle = NULL;
119 	}
120 	return( -1 );
121 }
122 
123 /* Initializes the file object IO handle
124  * Returns 1 if successful or -1 on error
125  */
pyevt_file_object_initialize(libbfio_handle_t ** handle,PyObject * file_object,libcerror_error_t ** error)126 int pyevt_file_object_initialize(
127      libbfio_handle_t **handle,
128      PyObject *file_object,
129      libcerror_error_t **error )
130 {
131 	pyevt_file_object_io_handle_t *file_object_io_handle = NULL;
132 	static char *function                                = "pyevt_file_object_initialize";
133 
134 	if( handle == NULL )
135 	{
136 		libcerror_error_set(
137 		 error,
138 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
139 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
140 		 "%s: invalid handle.",
141 		 function );
142 
143 		return( -1 );
144 	}
145 	if( *handle != NULL )
146 	{
147 		libcerror_error_set(
148 		 error,
149 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
150 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
151 		 "%s: invalid handle value already set.",
152 		 function );
153 
154 		return( -1 );
155 	}
156 	if( pyevt_file_object_io_handle_initialize(
157 	     &file_object_io_handle,
158 	     file_object,
159 	     error ) != 1 )
160 	{
161 		libcerror_error_set(
162 		 error,
163 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
164 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
165 		 "%s: unable to create file object IO handle.",
166 		 function );
167 
168 		goto on_error;
169 	}
170 	if( libbfio_handle_initialize(
171 	     handle,
172 	     (intptr_t *) file_object_io_handle,
173 	     (int (*)(intptr_t **, libcerror_error_t **)) pyevt_file_object_io_handle_free,
174 	     (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) pyevt_file_object_io_handle_clone,
175 	     (int (*)(intptr_t *, int, libcerror_error_t **)) pyevt_file_object_io_handle_open,
176 	     (int (*)(intptr_t *, libcerror_error_t **)) pyevt_file_object_io_handle_close,
177 	     (ssize_t (*)(intptr_t *, uint8_t *, size_t, libcerror_error_t **)) pyevt_file_object_io_handle_read,
178 	     (ssize_t (*)(intptr_t *, const uint8_t *, size_t, libcerror_error_t **)) pyevt_file_object_io_handle_write,
179 	     (off64_t (*)(intptr_t *, off64_t, int, libcerror_error_t **)) pyevt_file_object_io_handle_seek_offset,
180 	     (int (*)(intptr_t *, libcerror_error_t **)) pyevt_file_object_io_handle_exists,
181 	     (int (*)(intptr_t *, libcerror_error_t **)) pyevt_file_object_io_handle_is_open,
182 	     (int (*)(intptr_t *, size64_t *, libcerror_error_t **)) pyevt_file_object_io_handle_get_size,
183 	     LIBBFIO_FLAG_IO_HANDLE_MANAGED | LIBBFIO_FLAG_IO_HANDLE_CLONE_BY_FUNCTION,
184 	     error ) != 1 )
185 	{
186 		libcerror_error_set(
187 		 error,
188 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
189 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
190 		 "%s: unable to create handle.",
191 		 function );
192 
193 		goto on_error;
194 	}
195 	return( 1 );
196 
197 on_error:
198 	if( file_object_io_handle != NULL )
199 	{
200 		pyevt_file_object_io_handle_free(
201 		 &file_object_io_handle,
202 		 NULL );
203 	}
204 	return( -1 );
205 }
206 
207 /* Frees a file object IO handle
208  * Returns 1 if succesful or -1 on error
209  */
pyevt_file_object_io_handle_free(pyevt_file_object_io_handle_t ** file_object_io_handle,libcerror_error_t ** error)210 int pyevt_file_object_io_handle_free(
211      pyevt_file_object_io_handle_t **file_object_io_handle,
212      libcerror_error_t **error )
213 {
214 	static char *function      = "pyevt_file_object_io_handle_free";
215 	PyGILState_STATE gil_state = 0;
216 
217 	if( file_object_io_handle == NULL )
218 	{
219 		libcerror_error_set(
220 		 error,
221 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
222 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
223 		 "%s: invalid file object IO handle.",
224 		 function );
225 
226 		return( -1 );
227 	}
228 	if( *file_object_io_handle != NULL )
229 	{
230 		gil_state = PyGILState_Ensure();
231 
232 		Py_DecRef(
233 		 ( *file_object_io_handle )->file_object );
234 
235 		PyGILState_Release(
236 		 gil_state );
237 
238 		PyMem_Free(
239 		 *file_object_io_handle );
240 
241 		*file_object_io_handle = NULL;
242 	}
243 	return( 1 );
244 }
245 
246 /* Clones (duplicates) the file object IO handle and its attributes
247  * Returns 1 if succesful or -1 on error
248  */
pyevt_file_object_io_handle_clone(pyevt_file_object_io_handle_t ** destination_file_object_io_handle,pyevt_file_object_io_handle_t * source_file_object_io_handle,libcerror_error_t ** error)249 int pyevt_file_object_io_handle_clone(
250      pyevt_file_object_io_handle_t **destination_file_object_io_handle,
251      pyevt_file_object_io_handle_t *source_file_object_io_handle,
252      libcerror_error_t **error )
253 {
254 	static char *function = "pyevt_file_object_io_handle_clone";
255 
256 	if( destination_file_object_io_handle == NULL )
257 	{
258 		libcerror_error_set(
259 		 error,
260 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
261 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
262 		 "%s: invalid destination file object IO handle.",
263 		 function );
264 
265 		return( -1 );
266 	}
267 	if( *destination_file_object_io_handle != NULL )
268 	{
269 		libcerror_error_set(
270 		 error,
271 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
272 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
273 		 "%s: destination file object IO handle already set.",
274 		 function );
275 
276 		return( -1 );
277 	}
278 	if( source_file_object_io_handle == NULL )
279 	{
280 		*destination_file_object_io_handle = NULL;
281 
282 		return( 1 );
283 	}
284 	if( pyevt_file_object_io_handle_initialize(
285 	     destination_file_object_io_handle,
286 	     source_file_object_io_handle->file_object,
287 	     error ) != 1 )
288 	{
289 		libcerror_error_set(
290 		 error,
291 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
292 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
293 		 "%s: unable to create file object IO handle.",
294 		 function );
295 
296 		return( -1 );
297 	}
298 	if( *destination_file_object_io_handle == NULL )
299 	{
300 		libcerror_error_set(
301 		 error,
302 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
303 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
304 		 "%s: missing destination file object IO handle.",
305 		 function );
306 
307 		return( -1 );
308 	}
309 	return( 1 );
310 }
311 
312 /* Opens the file object IO handle
313  * Returns 1 if successful or -1 on error
314  */
pyevt_file_object_io_handle_open(pyevt_file_object_io_handle_t * file_object_io_handle,int access_flags,libcerror_error_t ** error)315 int pyevt_file_object_io_handle_open(
316      pyevt_file_object_io_handle_t *file_object_io_handle,
317      int access_flags,
318      libcerror_error_t **error )
319 {
320 	static char *function = "pyevt_file_object_io_handle_open";
321 
322 	if( file_object_io_handle == NULL )
323 	{
324 		libcerror_error_set(
325 		 error,
326 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
327 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
328 		 "%s: invalid file object IO handle.",
329 		 function );
330 
331 		return( -1 );
332 	}
333 	if( file_object_io_handle->file_object == NULL )
334 	{
335 		libcerror_error_set(
336 		 error,
337 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
338 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
339 		 "%s: invalid file object IO handle - missing file object.",
340 		 function );
341 
342 		return( -1 );
343 	}
344 	if( ( ( access_flags & LIBBFIO_ACCESS_FLAG_READ ) != 0 )
345 	 && ( ( access_flags & LIBBFIO_ACCESS_FLAG_WRITE ) != 0 ) )
346 	{
347 		libcerror_error_set(
348 		 error,
349 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
351 		 "%s: unsupported access flags.",
352 		 function );
353 
354 		return( -1 );
355 	}
356 	if( ( access_flags & LIBBFIO_ACCESS_FLAG_WRITE ) != 0 )
357 	{
358 		libcerror_error_set(
359 		 error,
360 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
362 		 "%s: write access currently not supported.",
363 		 function );
364 
365 		return( -1 );
366 	}
367 	/* No need to do anything here, because the file object is already open
368 	 */
369 	file_object_io_handle->access_flags = access_flags;
370 
371 	return( 1 );
372 }
373 
374 /* Closes the file object IO handle
375  * Returns 0 if successful or -1 on error
376  */
pyevt_file_object_io_handle_close(pyevt_file_object_io_handle_t * file_object_io_handle,libcerror_error_t ** error)377 int pyevt_file_object_io_handle_close(
378      pyevt_file_object_io_handle_t *file_object_io_handle,
379      libcerror_error_t **error )
380 {
381 	static char *function = "pyevt_file_object_io_handle_close";
382 
383 	if( file_object_io_handle == NULL )
384 	{
385 		libcerror_error_set(
386 		 error,
387 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
388 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
389 		 "%s: invalid file object IO handle.",
390 		 function );
391 
392 		return( -1 );
393 	}
394 	if( file_object_io_handle->file_object == NULL )
395 	{
396 		libcerror_error_set(
397 		 error,
398 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
399 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
400 		 "%s: invalid file object IO handle - missing file object.",
401 		 function );
402 
403 		return( -1 );
404 	}
405 	/* Do not close the file object, have Python deal with it
406 	 */
407 	file_object_io_handle->access_flags = 0;
408 
409 	return( 0 );
410 }
411 
412 /* Reads a buffer from the file object
413  * Make sure to hold the GIL state before calling this function
414  * Returns the number of bytes read if successful, or -1 on error
415  */
pyevt_file_object_read_buffer(PyObject * file_object,uint8_t * buffer,size_t size,libcerror_error_t ** error)416 ssize_t pyevt_file_object_read_buffer(
417          PyObject *file_object,
418          uint8_t *buffer,
419          size_t size,
420          libcerror_error_t **error )
421 {
422 	PyObject *argument_size    = NULL;
423 	PyObject *method_name      = NULL;
424 	PyObject *method_result    = NULL;
425 	static char *function      = "pyevt_file_object_read_buffer";
426 	char *safe_buffer          = NULL;
427 	Py_ssize_t safe_read_count = 0;
428 	ssize_t read_count         = 0;
429 	int result                 = 0;
430 
431 	if( file_object == NULL )
432 	{
433 		libcerror_error_set(
434 		 error,
435 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
436 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
437 		 "%s: invalid file object.",
438 		 function );
439 
440 		return( -1 );
441 	}
442 	if( buffer == NULL )
443 	{
444 		libcerror_error_set(
445 		 error,
446 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
447 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
448 		 "%s: invalid buffer.",
449 		 function );
450 
451 		return( -1 );
452 	}
453 	if( size > (size_t) SSIZE_MAX )
454 	{
455 		libcerror_error_set(
456 		 error,
457 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
458 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
459 		 "%s: invalid size value exceeds maximum.",
460 		 function );
461 
462 		return( -1 );
463 	}
464 	if( size > 0 )
465 	{
466 #if PY_MAJOR_VERSION >= 3
467 		method_name = PyUnicode_FromString(
468 			       "read" );
469 #else
470 		method_name = PyString_FromString(
471 			       "read" );
472 #endif
473 		argument_size = PyLong_FromSize_t(
474 				 size );
475 
476 		PyErr_Clear();
477 
478 		method_result = PyObject_CallMethodObjArgs(
479 				 file_object,
480 				 method_name,
481 				 argument_size,
482 				 NULL );
483 
484 		if( PyErr_Occurred() )
485 		{
486 			pyevt_error_fetch(
487 			 error,
488 			 LIBCERROR_ERROR_DOMAIN_IO,
489 			 LIBCERROR_IO_ERROR_READ_FAILED,
490 			 "%s: unable to read from file object.",
491 			 function );
492 
493 			goto on_error;
494 		}
495 		if( method_result == NULL )
496 		{
497 			libcerror_error_set(
498 			 error,
499 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
500 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
501 			 "%s: missing method result.",
502 			 function );
503 
504 			goto on_error;
505 		}
506 #if PY_MAJOR_VERSION >= 3
507 		result = PyObject_IsInstance(
508 		          method_result,
509 		          (PyObject *) &PyBytes_Type );
510 #else
511 		result = PyObject_IsInstance(
512 		          method_result,
513 		          (PyObject *) &PyString_Type );
514 #endif
515 		if( result == -1 )
516 		{
517 			libcerror_error_set(
518 			 error,
519 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
520 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
521 			 "%s: unable to determine if method result is a binary string object.",
522 			 function );
523 
524 			goto on_error;
525 		}
526 		else if( result == 0 )
527 		{
528 			libcerror_error_set(
529 			 error,
530 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
531 			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
532 			 "%s: invalid method result value is not a binary string object.",
533 			 function );
534 
535 			goto on_error;
536 		}
537 #if PY_MAJOR_VERSION >= 3
538 		result = PyBytes_AsStringAndSize(
539 			  method_result,
540 			  &safe_buffer,
541 			  &safe_read_count );
542 #else
543 		result = PyString_AsStringAndSize(
544 			  method_result,
545 			  &safe_buffer,
546 			  &safe_read_count );
547 #endif
548 		if( result == -1 )
549 		{
550 			pyevt_error_fetch(
551 			 error,
552 			 LIBCERROR_ERROR_DOMAIN_IO,
553 			 LIBCERROR_IO_ERROR_READ_FAILED,
554 			 "%s: unable to read from file object.",
555 			 function );
556 
557 			goto on_error;
558 		}
559 		if( safe_read_count > (Py_ssize_t) SSIZE_MAX )
560 		{
561 			libcerror_error_set(
562 			 error,
563 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
564 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
565 			 "%s: invalid read count value exceeds maximum.",
566 			 function );
567 
568 			goto on_error;
569 		}
570 		read_count = (ssize_t) safe_read_count;
571 
572 		if( memory_copy(
573 		     buffer,
574 		     safe_buffer,
575 		     read_count ) == NULL )
576 		{
577 			libcerror_error_set(
578 			 error,
579 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
580 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
581 			 "%s: unable to data to buffer.",
582 			 function );
583 
584 			goto on_error;
585 		}
586 		Py_DecRef(
587 		 method_result );
588 
589 		Py_DecRef(
590 		 argument_size );
591 
592 		Py_DecRef(
593 		 method_name );
594 	}
595 	return( read_count );
596 
597 on_error:
598 	if( method_result != NULL )
599 	{
600 		Py_DecRef(
601 		 method_result );
602 	}
603 	if( argument_size != NULL )
604 	{
605 		Py_DecRef(
606 		 argument_size );
607 	}
608 	if( method_name != NULL )
609 	{
610 		Py_DecRef(
611 		 method_name );
612 	}
613 	return( -1 );
614 }
615 
616 /* Reads a buffer from the file object IO handle
617  * Returns the number of bytes read if successful, or -1 on error
618  */
pyevt_file_object_io_handle_read(pyevt_file_object_io_handle_t * file_object_io_handle,uint8_t * buffer,size_t size,libcerror_error_t ** error)619 ssize_t pyevt_file_object_io_handle_read(
620          pyevt_file_object_io_handle_t *file_object_io_handle,
621          uint8_t *buffer,
622          size_t size,
623          libcerror_error_t **error )
624 {
625 	static char *function      = "pyevt_file_object_io_handle_read";
626 	PyGILState_STATE gil_state = 0;
627 	ssize_t read_count         = 0;
628 
629 	if( file_object_io_handle == NULL )
630 	{
631 		libcerror_error_set(
632 		 error,
633 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
634 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
635 		 "%s: invalid file object IO handle.",
636 		 function );
637 
638 		return( -1 );
639 	}
640 	gil_state = PyGILState_Ensure();
641 
642 	read_count = pyevt_file_object_read_buffer(
643 	              file_object_io_handle->file_object,
644 	              buffer,
645 	              size,
646 	              error );
647 
648 	if( read_count == -1 )
649 	{
650 		libcerror_error_set(
651 		 error,
652 		 LIBCERROR_ERROR_DOMAIN_IO,
653 		 LIBCERROR_IO_ERROR_READ_FAILED,
654 		 "%s: unable to read from file object.",
655 		 function );
656 
657 		goto on_error;
658 	}
659 	PyGILState_Release(
660 	 gil_state );
661 
662 	return( read_count );
663 
664 on_error:
665 	PyGILState_Release(
666 	 gil_state );
667 
668 	return( -1 );
669 }
670 
671 /* Writes a buffer to the file object
672  * Make sure to hold the GIL state before calling this function
673  * Returns the number of bytes written if successful, or -1 on error
674  */
pyevt_file_object_write_buffer(PyObject * file_object,const uint8_t * buffer,size_t size,libcerror_error_t ** error)675 ssize_t pyevt_file_object_write_buffer(
676          PyObject *file_object,
677          const uint8_t *buffer,
678          size_t size,
679          libcerror_error_t **error )
680 {
681 	PyObject *argument_string = NULL;
682 	PyObject *method_name     = NULL;
683 	PyObject *method_result   = NULL;
684 	static char *function     = "pyevt_file_object_write_buffer";
685 
686 	if( file_object == NULL )
687 	{
688 		libcerror_error_set(
689 		 error,
690 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
691 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
692 		 "%s: invalid file object.",
693 		 function );
694 
695 		return( -1 );
696 	}
697 	if( buffer == NULL )
698 	{
699 		libcerror_error_set(
700 		 error,
701 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
702 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
703 		 "%s: invalid buffer.",
704 		 function );
705 
706 		return( -1 );
707 	}
708 #if SIZEOF_SIZE_T > SIZEOF_INT
709 	if( size > (size_t) INT_MAX )
710 #else
711 	if( size > (size_t) SSIZE_MAX )
712 #endif
713 	{
714 		libcerror_error_set(
715 		 error,
716 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
717 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
718 		 "%s: invalid size value exceeds maximum.",
719 		 function );
720 
721 		return( -1 );
722 	}
723 	if( size > 0 )
724 	{
725 #if PY_MAJOR_VERSION >= 3
726 		method_name = PyUnicode_FromString(
727 			       "write" );
728 #else
729 		method_name = PyString_FromString(
730 			       "write" );
731 #endif
732 #if PY_MAJOR_VERSION >= 3
733 		argument_string = PyBytes_FromStringAndSize(
734 		                   (char *) buffer,
735 		                   size );
736 #else
737 		argument_string = PyString_FromStringAndSize(
738 		                   (char *) buffer,
739 		                   size );
740 #endif
741 		PyErr_Clear();
742 
743 		method_result = PyObject_CallMethodObjArgs(
744 				 file_object,
745 				 method_name,
746 				 argument_string,
747 				 NULL );
748 
749 		if( PyErr_Occurred() )
750 		{
751 			pyevt_error_fetch(
752 			 error,
753 			 LIBCERROR_ERROR_DOMAIN_IO,
754 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
755 			 "%s: unable to write to file object.",
756 			 function );
757 
758 			goto on_error;
759 		}
760 		if( method_result == NULL )
761 		{
762 			libcerror_error_set(
763 			 error,
764 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
765 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
766 			 "%s: missing method result.",
767 			 function );
768 
769 			goto on_error;
770 		}
771 		Py_DecRef(
772 		 method_result );
773 
774 		Py_DecRef(
775 		 argument_string );
776 
777 		Py_DecRef(
778 		 method_name );
779 	}
780 	return( (ssize_t) size );
781 
782 on_error:
783 	if( method_result != NULL )
784 	{
785 		Py_DecRef(
786 		 method_result );
787 	}
788 	if( argument_string != NULL )
789 	{
790 		Py_DecRef(
791 		 argument_string );
792 	}
793 	if( method_name != NULL )
794 	{
795 		Py_DecRef(
796 		 method_name );
797 	}
798 	return( -1 );
799 }
800 
801 /* Writes a buffer to the file object IO handle
802  * Returns the number of bytes written if successful, or -1 on error
803  */
pyevt_file_object_io_handle_write(pyevt_file_object_io_handle_t * file_object_io_handle,const uint8_t * buffer,size_t size,libcerror_error_t ** error)804 ssize_t pyevt_file_object_io_handle_write(
805          pyevt_file_object_io_handle_t *file_object_io_handle,
806          const uint8_t *buffer,
807          size_t size,
808          libcerror_error_t **error )
809 {
810 	static char *function      = "pyevt_file_object_io_handle_write";
811 	PyGILState_STATE gil_state = 0;
812 	ssize_t write_count        = 0;
813 
814 	if( file_object_io_handle == NULL )
815 	{
816 		libcerror_error_set(
817 		 error,
818 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
819 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
820 		 "%s: invalid file object IO handle.",
821 		 function );
822 
823 		return( -1 );
824 	}
825 	gil_state = PyGILState_Ensure();
826 
827 	write_count = pyevt_file_object_write_buffer(
828 	               file_object_io_handle->file_object,
829 	               buffer,
830 	               size,
831 	               error );
832 
833 	if( write_count == -1 )
834 	{
835 		libcerror_error_set(
836 		 error,
837 		 LIBCERROR_ERROR_DOMAIN_IO,
838 		 LIBCERROR_IO_ERROR_WRITE_FAILED,
839 		 "%s: unable to write from file object.",
840 		 function );
841 
842 		goto on_error;
843 	}
844 	PyGILState_Release(
845 	 gil_state );
846 
847 	return( write_count );
848 
849 on_error:
850 	PyGILState_Release(
851 	 gil_state );
852 
853 	return( -1 );
854 }
855 
856 /* Seeks a certain offset within the file object
857  * Make sure to hold the GIL state before calling this function
858  * Returns 1 if successful or -1 on error
859  */
pyevt_file_object_seek_offset(PyObject * file_object,off64_t offset,int whence,libcerror_error_t ** error)860 int pyevt_file_object_seek_offset(
861      PyObject *file_object,
862      off64_t offset,
863      int whence,
864      libcerror_error_t **error )
865 {
866 	PyObject *argument_offset = NULL;
867 	PyObject *argument_whence = NULL;
868 	PyObject *method_name     = NULL;
869 	PyObject *method_result   = NULL;
870 	static char *function     = "pyevt_file_object_seek_offset";
871 
872 	if( file_object == NULL )
873 	{
874 		libcerror_error_set(
875 		 error,
876 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
877 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
878 		 "%s: invalid file object.",
879 		 function );
880 
881 		return( -1 );
882 	}
883 #if defined( HAVE_LONG_LONG )
884 	if( offset > (off64_t) INT64_MAX )
885 #else
886 	if( offset > (off64_t) LONG_MAX )
887 #endif
888 	{
889 		libcerror_error_set(
890 		 error,
891 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
892 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
893 		 "%s: invalid offset value exceeds maximum.",
894 		 function );
895 
896 		return( -1 );
897 	}
898 	if( ( whence != SEEK_CUR )
899 	 && ( whence != SEEK_END )
900 	 && ( whence != SEEK_SET ) )
901 	{
902 		libcerror_error_set(
903 		 error,
904 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
905 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
906 		 "%s: unsupported whence.",
907 		 function );
908 
909 		return( -1 );
910 	}
911 #if PY_MAJOR_VERSION >= 3
912 	method_name = PyUnicode_FromString(
913 	               "seek" );
914 #else
915 	method_name = PyString_FromString(
916 	               "seek" );
917 #endif
918 #if defined( HAVE_LONG_LONG )
919 	argument_offset = PyLong_FromLongLong(
920 	                   (PY_LONG_LONG) offset );
921 #else
922 	argument_offset = PyLong_FromLongLong(
923 	                   (long) offset );
924 #endif
925 #if PY_MAJOR_VERSION >= 3
926 	argument_whence = PyLong_FromLong(
927 	                   (long) whence );
928 #else
929 	argument_whence = PyInt_FromLong(
930 	                   (long) whence );
931 #endif
932 	PyErr_Clear();
933 
934 	method_result = PyObject_CallMethodObjArgs(
935 	                 file_object,
936 	                 method_name,
937 	                 argument_offset,
938 	                 argument_whence,
939 	                 NULL );
940 
941 	if( PyErr_Occurred() )
942 	{
943 		pyevt_error_fetch(
944 		 error,
945 		 LIBCERROR_ERROR_DOMAIN_IO,
946 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
947 		 "%s: unable to seek in file object.",
948 		 function );
949 
950 		goto on_error;
951 	}
952 	if( method_result == NULL )
953 	{
954 		libcerror_error_set(
955 		 error,
956 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
957 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
958 		 "%s: missing method result.",
959 		 function );
960 
961 		goto on_error;
962 	}
963 	Py_DecRef(
964 	 method_result );
965 
966 	Py_DecRef(
967 	 argument_whence );
968 
969 	Py_DecRef(
970 	 argument_offset );
971 
972 	Py_DecRef(
973 	 method_name );
974 
975 	return( 1 );
976 
977 on_error:
978 	if( method_result != NULL )
979 	{
980 		Py_DecRef(
981 		 method_result );
982 	}
983 	if( argument_whence != NULL )
984 	{
985 		Py_DecRef(
986 		 argument_whence );
987 	}
988 	if( argument_offset != NULL )
989 	{
990 		Py_DecRef(
991 		 argument_offset );
992 	}
993 	if( method_name != NULL )
994 	{
995 		Py_DecRef(
996 		 method_name );
997 	}
998 	return( -1 );
999 }
1000 
1001 /* Retrieves the current offset within the file object
1002  * Make sure to hold the GIL state before calling this function
1003  * Returns 1 if successful or -1 on error
1004  */
pyevt_file_object_get_offset(PyObject * file_object,off64_t * offset,libcerror_error_t ** error)1005 int pyevt_file_object_get_offset(
1006      PyObject *file_object,
1007      off64_t *offset,
1008      libcerror_error_t **error )
1009 {
1010 	PyObject *method_name   = NULL;
1011 	PyObject *method_result = NULL;
1012 	static char *function   = "pyevt_file_object_get_offset";
1013 	int result              = 0;
1014 
1015 	if( file_object == NULL )
1016 	{
1017 		libcerror_error_set(
1018 		 error,
1019 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1020 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1021 		 "%s: invalid file object.",
1022 		 function );
1023 
1024 		return( -1 );
1025 	}
1026 	if( offset == NULL )
1027 	{
1028 		libcerror_error_set(
1029 		 error,
1030 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1031 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1032 		 "%s: invalid offset.",
1033 		 function );
1034 
1035 		return( -1 );
1036 	}
1037 #if PY_MAJOR_VERSION >= 3
1038 	method_name = PyUnicode_FromString(
1039 	               "get_offset" );
1040 #else
1041 	method_name = PyString_FromString(
1042 	               "get_offset" );
1043 #endif
1044 	PyErr_Clear();
1045 
1046 	/* Determine if the file object has the get_offset method
1047 	 */
1048 	result = PyObject_HasAttr(
1049 	          file_object,
1050 	          method_name );
1051 
1052 	if( result == 0 )
1053 	{
1054 		Py_DecRef(
1055 		 method_name );
1056 
1057 		/* Fall back to the tell method
1058 		 */
1059 #if PY_MAJOR_VERSION >= 3
1060 		method_name = PyUnicode_FromString(
1061 		               "tell" );
1062 #else
1063 		method_name = PyString_FromString(
1064 		               "tell" );
1065 #endif
1066 	}
1067 	PyErr_Clear();
1068 
1069 	method_result = PyObject_CallMethodObjArgs(
1070 	                 file_object,
1071 	                 method_name,
1072 	                 NULL );
1073 
1074 	if( PyErr_Occurred() )
1075 	{
1076 		pyevt_error_fetch(
1077 		 error,
1078 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1079 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1080 		 "%s: unable to retrieve current offset in file object.",
1081 		 function );
1082 
1083 		goto on_error;
1084 	}
1085 	if( method_result == NULL )
1086 	{
1087 		libcerror_error_set(
1088 		 error,
1089 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1090 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1091 		 "%s: missing method result.",
1092 		 function );
1093 
1094 		goto on_error;
1095 	}
1096 	if( pyevt_integer_signed_copy_to_64bit(
1097 	     method_result,
1098 	     offset,
1099 	     error ) != 1 )
1100 	{
1101 		libcerror_error_set(
1102 		 error,
1103 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1104 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1105 		 "%s: unable to convert method result into current offset of file object.",
1106 		 function );
1107 
1108 		goto on_error;
1109 	}
1110 	Py_DecRef(
1111 	 method_result );
1112 
1113 	Py_DecRef(
1114 	 method_name );
1115 
1116 	return( 1 );
1117 
1118 on_error:
1119 	if( method_result != NULL )
1120 	{
1121 		Py_DecRef(
1122 		 method_result );
1123 	}
1124 	if( method_name != NULL )
1125 	{
1126 		Py_DecRef(
1127 		 method_name );
1128 	}
1129 	return( -1 );
1130 }
1131 
1132 /* Seeks a certain offset within the file object IO handle
1133  * Returns the offset if the seek is successful or -1 on error
1134  */
pyevt_file_object_io_handle_seek_offset(pyevt_file_object_io_handle_t * file_object_io_handle,off64_t offset,int whence,libcerror_error_t ** error)1135 off64_t pyevt_file_object_io_handle_seek_offset(
1136          pyevt_file_object_io_handle_t *file_object_io_handle,
1137          off64_t offset,
1138          int whence,
1139          libcerror_error_t **error )
1140 {
1141 	static char *function      = "pyevt_file_object_io_handle_seek_offset";
1142 	PyGILState_STATE gil_state = 0;
1143 
1144 	if( file_object_io_handle == NULL )
1145 	{
1146 		libcerror_error_set(
1147 		 error,
1148 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1149 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1150 		 "%s: invalid file object IO handle.",
1151 		 function );
1152 
1153 		return( -1 );
1154 	}
1155 	gil_state = PyGILState_Ensure();
1156 
1157 	if( pyevt_file_object_seek_offset(
1158 	     file_object_io_handle->file_object,
1159 	     offset,
1160 	     whence,
1161 	     error ) != 1 )
1162 	{
1163 		libcerror_error_set(
1164 		 error,
1165 		 LIBCERROR_ERROR_DOMAIN_IO,
1166 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
1167 		 "%s: unable to seek in file object.",
1168 		 function );
1169 
1170 		goto on_error;
1171 	}
1172 	if( pyevt_file_object_get_offset(
1173 	     file_object_io_handle->file_object,
1174 	     &offset,
1175 	     error ) != 1 )
1176 	{
1177 		libcerror_error_set(
1178 		 error,
1179 		 LIBCERROR_ERROR_DOMAIN_IO,
1180 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
1181 		 "%s: unable to retrieve current offset in file object.",
1182 		 function );
1183 
1184 		goto on_error;
1185 	}
1186 	PyGILState_Release(
1187 	 gil_state );
1188 
1189 	return( offset );
1190 
1191 on_error:
1192 	PyGILState_Release(
1193 	 gil_state );
1194 
1195 	return( -1 );
1196 }
1197 
1198 /* Function to determine if a file exists
1199  * Returns 1 if file exists, 0 if not or -1 on error
1200  */
pyevt_file_object_io_handle_exists(pyevt_file_object_io_handle_t * file_object_io_handle,libcerror_error_t ** error)1201 int pyevt_file_object_io_handle_exists(
1202      pyevt_file_object_io_handle_t *file_object_io_handle,
1203      libcerror_error_t **error )
1204 {
1205 	static char *function = "pyevt_file_object_io_handle_exists";
1206 
1207 	if( file_object_io_handle == NULL )
1208 	{
1209 		libcerror_error_set(
1210 		 error,
1211 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1212 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1213 		 "%s: invalid file object IO handle.",
1214 		 function );
1215 
1216 		return( -1 );
1217 	}
1218 	if( file_object_io_handle->file_object == NULL )
1219 	{
1220 		return( 0 );
1221 	}
1222 	return( 1 );
1223 }
1224 
1225 /* Check if the file is open
1226  * Returns 1 if open, 0 if not or -1 on error
1227  */
pyevt_file_object_io_handle_is_open(pyevt_file_object_io_handle_t * file_object_io_handle,libcerror_error_t ** error)1228 int pyevt_file_object_io_handle_is_open(
1229      pyevt_file_object_io_handle_t *file_object_io_handle,
1230      libcerror_error_t **error )
1231 {
1232 	static char *function = "pyevt_file_object_io_handle_is_open";
1233 
1234 	if( file_object_io_handle == NULL )
1235 	{
1236 		libcerror_error_set(
1237 		 error,
1238 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1239 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1240 		 "%s: invalid file object IO handle.",
1241 		 function );
1242 
1243 		return( -1 );
1244 	}
1245 	if( file_object_io_handle->file_object == NULL )
1246 	{
1247 		libcerror_error_set(
1248 		 error,
1249 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1250 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1251 		 "%s: invalid file object IO handle - missing file object.",
1252 		 function );
1253 
1254 		return( -1 );
1255 	}
1256 	/* As far as BFIO is concerned the file object is always open
1257 	 */
1258 	return( 1 );
1259 }
1260 
1261 /* Retrieves the size of the file object
1262  * Make sure to hold the GIL state before calling this function
1263  * Returns 1 if successful or -1 on error
1264  */
pyevt_file_object_get_size(PyObject * file_object,size64_t * size,libcerror_error_t ** error)1265 int pyevt_file_object_get_size(
1266      PyObject *file_object,
1267      size64_t *size,
1268      libcerror_error_t **error )
1269 {
1270 	PyObject *method_name   = NULL;
1271 	PyObject *method_result = NULL;
1272 	static char *function   = "pyevt_file_object_get_size";
1273 
1274 	if( file_object == NULL )
1275 	{
1276 		libcerror_error_set(
1277 		 error,
1278 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1279 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1280 		 "%s: invalid file object.",
1281 		 function );
1282 
1283 		return( -1 );
1284 	}
1285 	if( size == NULL )
1286 	{
1287 		libcerror_error_set(
1288 		 error,
1289 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1290 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1291 		 "%s: invalid size.",
1292 		 function );
1293 
1294 		return( -1 );
1295 	}
1296 #if PY_MAJOR_VERSION >= 3
1297 	method_name = PyUnicode_FromString(
1298 	               "get_size" );
1299 #else
1300 	method_name = PyString_FromString(
1301 	               "get_size" );
1302 #endif
1303 	PyErr_Clear();
1304 
1305 	method_result = PyObject_CallMethodObjArgs(
1306 	                 file_object,
1307 	                 method_name,
1308 	                 NULL );
1309 
1310 	if( PyErr_Occurred() )
1311 	{
1312 		pyevt_error_fetch(
1313 		 error,
1314 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1315 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1316 		 "%s: unable to retrieve size of file object.",
1317 		 function );
1318 
1319 		goto on_error;
1320 	}
1321 	if( method_result == NULL )
1322 	{
1323 		libcerror_error_set(
1324 		 error,
1325 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1326 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1327 		 "%s: missing method result.",
1328 		 function );
1329 
1330 		goto on_error;
1331 	}
1332 	if( pyevt_integer_unsigned_copy_to_64bit(
1333 	     method_result,
1334 	     size,
1335 	     error ) != 1 )
1336 	{
1337 		libcerror_error_set(
1338 		 error,
1339 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1340 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1341 		 "%s: unable to convert method result into size of file object.",
1342 		 function );
1343 
1344 		goto on_error;
1345 	}
1346 	Py_DecRef(
1347 	 method_result );
1348 
1349 	Py_DecRef(
1350 	 method_name );
1351 
1352 	return( 1 );
1353 
1354 on_error:
1355 	if( method_result != NULL )
1356 	{
1357 		Py_DecRef(
1358 		 method_result );
1359 	}
1360 	if( method_name != NULL )
1361 	{
1362 		Py_DecRef(
1363 		 method_name );
1364 	}
1365 	return( -1 );
1366 }
1367 
1368 /* Retrieves the file size
1369  * Returns 1 if successful or -1 on error
1370  */
pyevt_file_object_io_handle_get_size(pyevt_file_object_io_handle_t * file_object_io_handle,size64_t * size,libcerror_error_t ** error)1371 int pyevt_file_object_io_handle_get_size(
1372      pyevt_file_object_io_handle_t *file_object_io_handle,
1373      size64_t *size,
1374      libcerror_error_t **error )
1375 {
1376 	PyObject *method_name      = NULL;
1377 	static char *function      = "pyevt_file_object_io_handle_get_size";
1378 	PyGILState_STATE gil_state = 0;
1379 	off64_t current_offset     = 0;
1380 	int result                 = 0;
1381 
1382 	if( file_object_io_handle == NULL )
1383 	{
1384 		libcerror_error_set(
1385 		 error,
1386 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1387 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1388 		 "%s: invalid file object IO handle.",
1389 		 function );
1390 
1391 		return( -1 );
1392 	}
1393 	if( file_object_io_handle->file_object == NULL )
1394 	{
1395 		libcerror_error_set(
1396 		 error,
1397 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1398 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1399 		 "%s: invalid file object IO handle - missing file object.",
1400 		 function );
1401 
1402 		return( -1 );
1403 	}
1404 	gil_state = PyGILState_Ensure();
1405 
1406 #if PY_MAJOR_VERSION >= 3
1407 	method_name = PyUnicode_FromString(
1408 	               "get_size" );
1409 #else
1410 	method_name = PyString_FromString(
1411 	               "get_size" );
1412 #endif
1413 	PyErr_Clear();
1414 
1415 	/* Determine if the file object has the get_size method
1416 	 */
1417 	result = PyObject_HasAttr(
1418 	          file_object_io_handle->file_object,
1419 	          method_name );
1420 
1421 	if( result != 0 )
1422 	{
1423 		if( pyevt_file_object_get_size(
1424 		     file_object_io_handle->file_object,
1425 		     size,
1426 		     error ) != 1 )
1427 		{
1428 			libcerror_error_set(
1429 			 error,
1430 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1431 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1432 			 "%s: unable to retrieve size of file object.",
1433 			 function );
1434 
1435 			goto on_error;
1436 		}
1437 	}
1438 	else
1439 	{
1440 		if( pyevt_file_object_get_offset(
1441 		     file_object_io_handle->file_object,
1442 		     &current_offset,
1443 		     error ) != 1 )
1444 		{
1445 			libcerror_error_set(
1446 			 error,
1447 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1448 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1449 			 "%s: unable to retrieve current offset in file object.",
1450 			 function );
1451 
1452 			goto on_error;
1453 		}
1454 		if( pyevt_file_object_seek_offset(
1455 		     file_object_io_handle->file_object,
1456 		     0,
1457 		     SEEK_END,
1458 		     error ) != 1 )
1459 		{
1460 			libcerror_error_set(
1461 			 error,
1462 			 LIBCERROR_ERROR_DOMAIN_IO,
1463 			 LIBCERROR_IO_ERROR_SEEK_FAILED,
1464 			 "%s: unable to seek end of file object.",
1465 			 function );
1466 
1467 			goto on_error;
1468 		}
1469 		if( pyevt_file_object_get_offset(
1470 		     file_object_io_handle->file_object,
1471 		     (off64_t *) size,
1472 		     error ) != 1 )
1473 		{
1474 			libcerror_error_set(
1475 			 error,
1476 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1477 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1478 			 "%s: unable to retrieve end offset in file object.",
1479 			 function );
1480 
1481 			pyevt_file_object_seek_offset(
1482 			 file_object_io_handle->file_object,
1483 			 current_offset,
1484 			 SEEK_SET,
1485 			 NULL );
1486 
1487 			goto on_error;
1488 		}
1489 		if( pyevt_file_object_seek_offset(
1490 		     file_object_io_handle->file_object,
1491 		     current_offset,
1492 		     SEEK_SET,
1493 		     error ) != 1 )
1494 		{
1495 			libcerror_error_set(
1496 			 error,
1497 			 LIBCERROR_ERROR_DOMAIN_IO,
1498 			 LIBCERROR_IO_ERROR_SEEK_FAILED,
1499 			 "%s: unable to seek current offset in file object.",
1500 			 function );
1501 
1502 			goto on_error;
1503 		}
1504 	}
1505 	Py_DecRef(
1506 	 method_name );
1507 
1508 	PyGILState_Release(
1509 	 gil_state );
1510 
1511 	return( 1 );
1512 
1513 on_error:
1514 	if( method_name != NULL )
1515 	{
1516 		Py_DecRef(
1517 		 method_name );
1518 	}
1519 	PyGILState_Release(
1520 	 gil_state );
1521 
1522 	return( 1 );
1523 }
1524 
1525