1 /*
2  * File IO handle functions
3  *
4  * Copyright (C) 2009-2020, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <memory.h>
24 #include <narrow_string.h>
25 #include <system_string.h>
26 #include <types.h>
27 #include <wide_string.h>
28 
29 #include "libbfio_definitions.h"
30 #include "libbfio_file_io_handle.h"
31 #include "libbfio_libcerror.h"
32 #include "libbfio_libcfile.h"
33 #include "libbfio_system_string.h"
34 
35 /* Creates a file IO handle
36  * Make sure the value file_io_handle is referencing, is set to NULL
37  * Returns 1 if successful or -1 on error
38  */
libbfio_file_io_handle_initialize(libbfio_file_io_handle_t ** file_io_handle,libcerror_error_t ** error)39 int libbfio_file_io_handle_initialize(
40      libbfio_file_io_handle_t **file_io_handle,
41      libcerror_error_t **error )
42 {
43 	static char *function = "libbfio_file_io_handle_initialize";
44 
45 	if( file_io_handle == NULL )
46 	{
47 		libcerror_error_set(
48 		 error,
49 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51 		 "%s: invalid file IO handle.",
52 		 function );
53 
54 		return( -1 );
55 	}
56 	if( *file_io_handle != NULL )
57 	{
58 		libcerror_error_set(
59 		 error,
60 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
61 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62 		 "%s: invalid file IO handle value already set.",
63 		 function );
64 
65 		return( -1 );
66 	}
67 	*file_io_handle = memory_allocate_structure(
68 	                   libbfio_file_io_handle_t );
69 
70 	if( *file_io_handle == NULL )
71 	{
72 		libcerror_error_set(
73 		 error,
74 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
75 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
76 		 "%s: unable to create file IO handle.",
77 		 function );
78 
79 		goto on_error;
80 	}
81 	if( memory_set(
82 	     *file_io_handle,
83 	     0,
84 	     sizeof( libbfio_file_io_handle_t ) ) == NULL )
85 	{
86 		libcerror_error_set(
87 		 error,
88 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
89 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
90 		 "%s: unable to clear file IO handle.",
91 		 function );
92 
93 		goto on_error;
94 	}
95 	if( libcfile_file_initialize(
96 	     &( ( *file_io_handle )->file ),
97 	     error ) != 1 )
98 	{
99 		libcerror_error_set(
100 		 error,
101 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
102 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
103 		 "%s: unable to create file.",
104 		 function );
105 
106 		goto on_error;
107 	}
108 	return( 1 );
109 
110 on_error:
111 	if( *file_io_handle != NULL )
112 	{
113 		memory_free(
114 		 *file_io_handle );
115 
116 		*file_io_handle = NULL;
117 	}
118 	return( -1 );
119 }
120 
121 /* Frees a file IO handle
122  * Returns 1 if succesful or -1 on error
123  */
libbfio_file_io_handle_free(libbfio_file_io_handle_t ** file_io_handle,libcerror_error_t ** error)124 int libbfio_file_io_handle_free(
125      libbfio_file_io_handle_t **file_io_handle,
126      libcerror_error_t **error )
127 {
128 	static char *function = "libbfio_file_io_handle_free";
129 	int result            = 1;
130 
131 	if( file_io_handle == NULL )
132 	{
133 		libcerror_error_set(
134 		 error,
135 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
136 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
137 		 "%s: invalid file IO handle.",
138 		 function );
139 
140 		return( -1 );
141 	}
142 	if( *file_io_handle != NULL )
143 	{
144 		if( ( *file_io_handle )->name != NULL )
145 		{
146 			memory_free(
147 			 ( *file_io_handle )->name );
148 		}
149 		if( libcfile_file_free(
150 		     &( ( *file_io_handle )->file ),
151 		     error ) != 1 )
152 		{
153 			libcerror_error_set(
154 			 error,
155 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
156 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
157 			 "%s: unable to free file.",
158 			 function );
159 
160 			result = -1;
161 		}
162 		memory_free(
163 		 *file_io_handle );
164 
165 		*file_io_handle = NULL;
166 	}
167 	return( result );
168 }
169 
170 /* Clones (duplicates) the file IO handle and its attributes
171  * Returns 1 if succesful or -1 on error
172  */
libbfio_file_io_handle_clone(libbfio_file_io_handle_t ** destination_file_io_handle,libbfio_file_io_handle_t * source_file_io_handle,libcerror_error_t ** error)173 int libbfio_file_io_handle_clone(
174      libbfio_file_io_handle_t **destination_file_io_handle,
175      libbfio_file_io_handle_t *source_file_io_handle,
176      libcerror_error_t **error )
177 {
178 	static char *function = "libbfio_file_io_handle_clone";
179 
180 	if( destination_file_io_handle == NULL )
181 	{
182 		libcerror_error_set(
183 		 error,
184 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
185 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
186 		 "%s: invalid destination file IO handle.",
187 		 function );
188 
189 		return( -1 );
190 	}
191 	if( *destination_file_io_handle != NULL )
192 	{
193 		libcerror_error_set(
194 		 error,
195 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
196 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
197 		 "%s: destination file IO handle already set.",
198 		 function );
199 
200 		return( -1 );
201 	}
202 	if( source_file_io_handle == NULL )
203 	{
204 		*destination_file_io_handle = NULL;
205 
206 		return( 1 );
207 	}
208 	if( libbfio_file_io_handle_initialize(
209 	     destination_file_io_handle,
210 	     error ) != 1 )
211 	{
212 		libcerror_error_set(
213 		 error,
214 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
215 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
216 		 "%s: unable to create file IO handle.",
217 		 function );
218 
219 		goto on_error;
220 	}
221 	if( *destination_file_io_handle == NULL )
222 	{
223 		libcerror_error_set(
224 		 error,
225 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
226 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
227 		 "%s: missing destination file IO handle.",
228 		 function );
229 
230 		goto on_error;
231 	}
232 	if( source_file_io_handle->name_size > 0 )
233 	{
234 		if( source_file_io_handle->name == NULL )
235 		{
236 			libcerror_error_set(
237 			 error,
238 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
239 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
240 			 "%s: invalid source file IO handle - missing name.",
241 			 function );
242 
243 			goto on_error;
244 		}
245 		if( source_file_io_handle->name_size > ( (size_t) SSIZE_MAX / sizeof( system_character_t ) ) )
246 		{
247 			libcerror_error_set(
248 			 error,
249 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
250 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
251 			 "%s: invalid source file IO handle - name size value exceeds maximum.",
252 			 function );
253 
254 			goto on_error;
255 		}
256 		( *destination_file_io_handle )->name = system_string_allocate(
257 		                                         source_file_io_handle->name_size );
258 
259 		if( ( *destination_file_io_handle )->name == NULL )
260 		{
261 			libcerror_error_set(
262 			 error,
263 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
264 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
265 			 "%s: unable to create name.",
266 			 function );
267 
268 			goto on_error;
269 		}
270 		if( source_file_io_handle->name_size > 1 )
271 		{
272 			if( system_string_copy(
273 			     ( *destination_file_io_handle )->name,
274 			     source_file_io_handle->name,
275 			     source_file_io_handle->name_size ) == NULL )
276 			{
277 				libcerror_error_set(
278 				 error,
279 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
280 				 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
281 				 "%s: unable to copy name.",
282 				 function );
283 
284 				goto on_error;
285 			}
286 		}
287 		( *destination_file_io_handle )->name[ source_file_io_handle->name_size - 1 ] = 0;
288 
289 		( *destination_file_io_handle )->name_size = source_file_io_handle->name_size;
290 	}
291 	return( 1 );
292 
293 on_error:
294 	if( *destination_file_io_handle != NULL )
295 	{
296 		libbfio_file_io_handle_free(
297 		 destination_file_io_handle,
298 		 NULL );
299 	}
300 	return( -1 );
301 }
302 
303 /* Retrieves the name size of the file IO handle
304  * The name size includes the end of string character
305  * Returns 1 if succesful or -1 on error
306  */
libbfio_file_io_handle_get_name_size(libbfio_file_io_handle_t * file_io_handle,size_t * name_size,libcerror_error_t ** error)307 int libbfio_file_io_handle_get_name_size(
308      libbfio_file_io_handle_t *file_io_handle,
309      size_t *name_size,
310      libcerror_error_t **error )
311 {
312 	static char *function = "libbfio_file_io_handle_get_name_size";
313 
314 	if( file_io_handle == NULL )
315 	{
316 		libcerror_error_set(
317 		 error,
318 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
319 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
320 		 "%s: invalid file IO handle.",
321 		 function );
322 
323 		return( -1 );
324 	}
325 	if( libbfio_system_string_size_to_narrow_string(
326 	     file_io_handle->name,
327 	     file_io_handle->name_size,
328 	     name_size,
329 	     error ) != 1 )
330 	{
331 		libcerror_error_set(
332 		 error,
333 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
334 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
335 		 "%s: unable to determine name size.",
336 		 function );
337 
338 		return( -1 );
339 	}
340 	return( 1 );
341 }
342 
343 /* Retrieves the name of the file IO handle
344  * The name size should include the end of string character
345  * Returns 1 if succesful or -1 on error
346  */
libbfio_file_io_handle_get_name(libbfio_file_io_handle_t * file_io_handle,char * name,size_t name_size,libcerror_error_t ** error)347 int libbfio_file_io_handle_get_name(
348      libbfio_file_io_handle_t *file_io_handle,
349      char *name,
350      size_t name_size,
351      libcerror_error_t **error )
352 {
353 	static char *function = "libbfio_file_io_handle_get_name";
354 
355 	if( file_io_handle == NULL )
356 	{
357 		libcerror_error_set(
358 		 error,
359 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
360 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
361 		 "%s: invalid file IO handle.",
362 		 function );
363 
364 		return( -1 );
365 	}
366 	if( libbfio_system_string_copy_to_narrow_string(
367 	     file_io_handle->name,
368 	     file_io_handle->name_size,
369 	     name,
370 	     name_size,
371 	     error ) != 1 )
372 	{
373 		libcerror_error_set(
374 		 error,
375 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
376 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
377 		 "%s: unable to set name.",
378 		 function );
379 
380 		return( -1 );
381 	}
382 	return( 1 );
383 }
384 
385 /* Sets the name for the file IO handle
386  * Returns 1 if succesful or -1 on error
387  */
libbfio_file_io_handle_set_name(libbfio_file_io_handle_t * file_io_handle,const char * name,size_t name_length,libcerror_error_t ** error)388 int libbfio_file_io_handle_set_name(
389      libbfio_file_io_handle_t *file_io_handle,
390      const char *name,
391      size_t name_length,
392      libcerror_error_t **error )
393 {
394 	static char *function = "libbfio_file_io_handle_set_name";
395 	int result            = 0;
396 
397 	if( file_io_handle == NULL )
398 	{
399 		libcerror_error_set(
400 		 error,
401 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
402 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
403 		 "%s: invalid file IO handle.",
404 		 function );
405 
406 		return( -1 );
407 	}
408 	if( name == NULL )
409 	{
410 		libcerror_error_set(
411 		 error,
412 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
413 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
414 		 "%s: invalid name.",
415 		 function );
416 
417 		return( -1 );
418 	}
419 	if( name_length == 0 )
420 	{
421 		libcerror_error_set(
422 		 error,
423 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
424 		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
425 		 "%s: invalid name length is zero.",
426 		 function );
427 
428 		return( -1 );
429 	}
430 	if( file_io_handle->name != NULL )
431 	{
432 		result = libcfile_file_is_open(
433 		          file_io_handle->file,
434 		          error );
435 
436 		if( result == -1 )
437 		{
438 			libcerror_error_set(
439 			 error,
440 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
441 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
442 			 "%s: unable to determine if file is open.",
443 			 function );
444 
445 			return( -1 );
446 		}
447 		if( result != 0 )
448 		{
449 			libcerror_error_set(
450 			 error,
451 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
452 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
453 			 "%s: unable to set name when file is open.",
454 			 function );
455 
456 			return( -1 );
457 		}
458 		memory_free(
459 		  file_io_handle->name );
460 
461 		 file_io_handle->name      = NULL;
462 		 file_io_handle->name_size = 0;
463 	}
464 	if( libbfio_system_string_size_from_narrow_string(
465 	     name,
466 	     name_length + 1,
467 	     &( file_io_handle->name_size ),
468 	     error ) != 1 )
469 	{
470 		libcerror_error_set(
471 		 error,
472 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
473 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
474 		 "%s: unable to determine name size.",
475 		 function );
476 
477 		goto on_error;
478 	}
479 	if( file_io_handle->name_size > ( (size_t) SSIZE_MAX / sizeof( system_character_t ) ) )
480 	{
481 		libcerror_error_set(
482 		 error,
483 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
484 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
485 		 "%s: invalid file IO handle - name size value exceeds maximum.",
486 		 function );
487 
488 		goto on_error;
489 	}
490 	file_io_handle->name = system_string_allocate(
491 	                        file_io_handle->name_size );
492 
493 	if( file_io_handle->name == NULL )
494 	{
495 		libcerror_error_set(
496 		 error,
497 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
498 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
499 		 "%s: unable to create name.",
500 		 function );
501 
502 		goto on_error;
503 	}
504 	if( libbfio_system_string_copy_from_narrow_string(
505 	     file_io_handle->name,
506 	     file_io_handle->name_size,
507 	     name,
508 	     name_length + 1,
509 	     error ) != 1 )
510 	{
511 		libcerror_error_set(
512 		 error,
513 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
514 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
515 		 "%s: unable to set name.",
516 		 function );
517 
518 		goto on_error;
519 	}
520 	return( 1 );
521 
522 on_error:
523 	if( file_io_handle->name != NULL )
524 	{
525 		memory_free(
526 		 file_io_handle->name );
527 
528 		file_io_handle->name = NULL;
529 	}
530 	file_io_handle->name_size = 0;
531 
532 	return( -1 );
533 }
534 
535 #if defined( HAVE_WIDE_CHARACTER_TYPE )
536 
537 /* Retrieves the name size of the file IO handle
538  * The name size includes the end of string character
539  * Returns 1 if succesful or -1 on error
540  */
libbfio_file_io_handle_get_name_size_wide(libbfio_file_io_handle_t * file_io_handle,size_t * name_size,libcerror_error_t ** error)541 int libbfio_file_io_handle_get_name_size_wide(
542      libbfio_file_io_handle_t *file_io_handle,
543      size_t *name_size,
544      libcerror_error_t **error )
545 {
546 	static char *function = "libbfio_file_io_handle_get_name_size_wide";
547 
548 	if( file_io_handle == NULL )
549 	{
550 		libcerror_error_set(
551 		 error,
552 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
553 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
554 		 "%s: invalid file IO handle.",
555 		 function );
556 
557 		return( -1 );
558 	}
559 	if( libbfio_system_string_size_to_wide_string(
560 	     file_io_handle->name,
561 	     file_io_handle->name_size,
562 	     name_size,
563 	     error ) != 1 )
564 	{
565 		libcerror_error_set(
566 		 error,
567 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
568 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
569 		 "%s: unable to determine name size.",
570 		 function );
571 
572 		return( -1 );
573 	}
574 	return( 1 );
575 }
576 
577 /* Retrieves the name of the file IO handle
578  * The name size should include the end of string character
579  * Returns 1 if succesful or -1 on error
580  */
libbfio_file_io_handle_get_name_wide(libbfio_file_io_handle_t * file_io_handle,wchar_t * name,size_t name_size,libcerror_error_t ** error)581 int libbfio_file_io_handle_get_name_wide(
582      libbfio_file_io_handle_t *file_io_handle,
583      wchar_t *name,
584      size_t name_size,
585      libcerror_error_t **error )
586 {
587 	static char *function = "libbfio_file_io_handle_get_name_wide";
588 
589 	if( file_io_handle == NULL )
590 	{
591 		libcerror_error_set(
592 		 error,
593 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
594 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
595 		 "%s: invalid file IO handle.",
596 		 function );
597 
598 		return( -1 );
599 	}
600 	if( libbfio_system_string_copy_to_wide_string(
601 	     file_io_handle->name,
602 	     file_io_handle->name_size,
603 	     name,
604 	     name_size,
605 	     error ) != 1 )
606 	{
607 		libcerror_error_set(
608 		 error,
609 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
610 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
611 		 "%s: unable to set name.",
612 		 function );
613 
614 		return( -1 );
615 	}
616 	return( 1 );
617 }
618 
619 /* Sets the name for the file IO handle
620  * Returns 1 if succesful or -1 on error
621  */
libbfio_file_io_handle_set_name_wide(libbfio_file_io_handle_t * file_io_handle,const wchar_t * name,size_t name_length,libcerror_error_t ** error)622 int libbfio_file_io_handle_set_name_wide(
623      libbfio_file_io_handle_t *file_io_handle,
624      const wchar_t *name,
625      size_t name_length,
626      libcerror_error_t **error )
627 {
628 	static char *function = "libbfio_file_io_handle_set_name_wide";
629 	int result            = 0;
630 
631 	if( file_io_handle == NULL )
632 	{
633 		libcerror_error_set(
634 		 error,
635 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
636 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
637 		 "%s: invalid file IO handle.",
638 		 function );
639 
640 		return( -1 );
641 	}
642 	if( name == NULL )
643 	{
644 		libcerror_error_set(
645 		 error,
646 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
647 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
648 		 "%s: invalid name.",
649 		 function );
650 
651 		return( -1 );
652 	}
653 	if( name_length == 0 )
654 	{
655 		libcerror_error_set(
656 		 error,
657 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
658 		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
659 		 "%s: invalid name length is zero.",
660 		 function );
661 
662 		return( -1 );
663 	}
664 	if( file_io_handle->name != NULL )
665 	{
666 		result = libcfile_file_is_open(
667 		          file_io_handle->file,
668 		          error );
669 
670 		if( result == -1 )
671 		{
672 			libcerror_error_set(
673 			 error,
674 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
675 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
676 			 "%s: unable to determine if file is open.",
677 			 function );
678 
679 			return( -1 );
680 		}
681 		if( result != 0 )
682 		{
683 			libcerror_error_set(
684 			 error,
685 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
686 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
687 			 "%s: unable to set name when file is open.",
688 			 function );
689 
690 			return( -1 );
691 		}
692 		memory_free(
693 		  file_io_handle->name );
694 
695 		 file_io_handle->name      = NULL;
696 		 file_io_handle->name_size = 0;
697 	}
698 	if( libbfio_system_string_size_from_wide_string(
699 	     name,
700 	     name_length + 1,
701 	     &( file_io_handle->name_size ),
702 	     error ) != 1 )
703 	{
704 		libcerror_error_set(
705 		 error,
706 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
707 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
708 		 "%s: unable to determine name size.",
709 		 function );
710 
711 		goto on_error;
712 	}
713 	if( file_io_handle->name_size > ( (size_t) SSIZE_MAX / sizeof( system_character_t ) ) )
714 	{
715 		libcerror_error_set(
716 		 error,
717 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
718 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
719 		 "%s: invalid file IO handle - name size value exceeds maximum.",
720 		 function );
721 
722 		goto on_error;
723 	}
724 	file_io_handle->name = system_string_allocate(
725 	                        file_io_handle->name_size );
726 
727 	if( file_io_handle->name == NULL )
728 	{
729 		libcerror_error_set(
730 		 error,
731 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
732 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
733 		 "%s: unable to create name.",
734 		 function );
735 
736 		goto on_error;
737 	}
738 	if( libbfio_system_string_copy_from_wide_string(
739 	     file_io_handle->name,
740 	     file_io_handle->name_size,
741 	     name,
742 	     name_length + 1,
743 	     error ) != 1 )
744 	{
745 		libcerror_error_set(
746 		 error,
747 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
748 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
749 		 "%s: unable to set name.",
750 		 function );
751 
752 		goto on_error;
753 	}
754 	return( 1 );
755 
756 on_error:
757 	if( file_io_handle->name != NULL )
758 	{
759 		memory_free(
760 		 file_io_handle->name );
761 
762 		file_io_handle->name = NULL;
763 	}
764 	file_io_handle->name_size = 0;
765 
766 	return( -1 );
767 }
768 
769 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
770 
771 /* Opens the file handle
772  * Returns 1 if successful or -1 on error
773  */
libbfio_file_io_handle_open(libbfio_file_io_handle_t * file_io_handle,int access_flags,libcerror_error_t ** error)774 int libbfio_file_io_handle_open(
775      libbfio_file_io_handle_t *file_io_handle,
776      int access_flags,
777      libcerror_error_t **error )
778 {
779 	static char *function = "libbfio_file_io_handle_open";
780 	int result            = 0;
781 
782 	if( file_io_handle == NULL )
783 	{
784 		libcerror_error_set(
785 		 error,
786 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
787 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
788 		 "%s: invalid file IO handle.",
789 		 function );
790 
791 		return( -1 );
792 	}
793 	if( file_io_handle->name == NULL )
794 	{
795 		libcerror_error_set(
796 		 error,
797 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
798 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
799 		 "%s: invalid file IO handle - missing name.",
800 		 function );
801 
802 		return( -1 );
803 	}
804 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
805 	result = libcfile_file_open_wide(
806 	          file_io_handle->file,
807 	          file_io_handle->name,
808 	          access_flags,
809 	          error );
810 #else
811 	result = libcfile_file_open(
812 	          file_io_handle->file,
813 	          file_io_handle->name,
814 	          access_flags,
815 	          error );
816 #endif
817 	if( result != 1 )
818 	{
819 		libcerror_error_set(
820 		 error,
821 		 LIBCERROR_ERROR_DOMAIN_IO,
822 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
823 		 "%s: unable to open file: %" PRIs_SYSTEM ".",
824 		 function,
825 		 file_io_handle->name );
826 
827 		return( -1 );
828 	}
829 	file_io_handle->access_flags = access_flags;
830 
831 	return( 1 );
832 }
833 
834 /* Closes the file handle
835  * Returns 0 if successful or -1 on error
836  */
libbfio_file_io_handle_close(libbfio_file_io_handle_t * file_io_handle,libcerror_error_t ** error)837 int libbfio_file_io_handle_close(
838      libbfio_file_io_handle_t *file_io_handle,
839      libcerror_error_t **error )
840 {
841 	static char *function = "libbfio_file_close";
842 
843 	if( file_io_handle == NULL )
844 	{
845 		libcerror_error_set(
846 		 error,
847 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
848 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
849 		 "%s: invalid file IO handle.",
850 		 function );
851 
852 		return( -1 );
853 	}
854 	if( file_io_handle->name == NULL )
855 	{
856 		libcerror_error_set(
857 		 error,
858 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
859 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
860 		 "%s: invalid file IO handle - missing name.",
861 		 function );
862 
863 		return( -1 );
864 	}
865 	if( libcfile_file_close(
866 	     file_io_handle->file,
867 	     error ) != 0 )
868 	{
869 		libcerror_error_set(
870 		 error,
871 		 LIBCERROR_ERROR_DOMAIN_IO,
872 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
873 		 "%s: unable to close file: %" PRIs_SYSTEM ".",
874 		 function,
875 		 file_io_handle->name );
876 
877 		return( -1 );
878 	}
879 	file_io_handle->access_flags = 0;
880 
881 	return( 0 );
882 }
883 
884 /* Reads a buffer from the file handle
885  * Returns the number of bytes read if successful, or -1 on error
886  */
libbfio_file_io_handle_read_buffer(libbfio_file_io_handle_t * file_io_handle,uint8_t * buffer,size_t size,libcerror_error_t ** error)887 ssize_t libbfio_file_io_handle_read_buffer(
888          libbfio_file_io_handle_t *file_io_handle,
889          uint8_t *buffer,
890          size_t size,
891          libcerror_error_t **error )
892 {
893 	static char *function = "libbfio_file_io_handle_read_buffer";
894 	ssize_t read_count    = 0;
895 
896 	if( file_io_handle == NULL )
897 	{
898 		libcerror_error_set(
899 		 error,
900 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
901 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
902 		 "%s: invalid file IO handle.",
903 		 function );
904 
905 		return( -1 );
906 	}
907 	if( file_io_handle->name == NULL )
908 	{
909 		libcerror_error_set(
910 		 error,
911 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
912 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
913 		 "%s: invalid file IO handle - missing name.",
914 		 function );
915 
916 		return( -1 );
917 	}
918 	read_count = libcfile_file_read_buffer(
919 	              file_io_handle->file,
920 	              buffer,
921 	              size,
922 	              error );
923 
924 	if( read_count < 0 )
925 	{
926 		libcerror_error_set(
927 		 error,
928 		 LIBCERROR_ERROR_DOMAIN_IO,
929 		 LIBCERROR_IO_ERROR_READ_FAILED,
930 		 "%s: unable to read from file: %" PRIs_SYSTEM ".",
931 		 function,
932 		 file_io_handle->name );
933 
934 		return( -1 );
935 	}
936 	return( read_count );
937 }
938 
939 /* Writes a buffer to the file handle
940  * Returns the number of bytes written if successful, or -1 on error
941  */
libbfio_file_io_handle_write_buffer(libbfio_file_io_handle_t * file_io_handle,const uint8_t * buffer,size_t size,libcerror_error_t ** error)942 ssize_t libbfio_file_io_handle_write_buffer(
943          libbfio_file_io_handle_t *file_io_handle,
944          const uint8_t *buffer,
945          size_t size,
946          libcerror_error_t **error )
947 {
948 	static char *function = "libbfio_file_write_buffer";
949 	ssize_t write_count   = 0;
950 
951 	if( file_io_handle == NULL )
952 	{
953 		libcerror_error_set(
954 		 error,
955 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
956 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
957 		 "%s: invalid file IO handle.",
958 		 function );
959 
960 		return( -1 );
961 	}
962 	if( file_io_handle->name == NULL )
963 	{
964 		libcerror_error_set(
965 		 error,
966 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
967 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
968 		 "%s: invalid file IO handle - missing name.",
969 		 function );
970 
971 		return( -1 );
972 	}
973 	write_count = libcfile_file_write_buffer(
974 	               file_io_handle->file,
975 	               buffer,
976 	               size,
977 	               error );
978 
979 	if( write_count < 0 )
980 	{
981 		libcerror_error_set(
982 		 error,
983 		 LIBCERROR_ERROR_DOMAIN_IO,
984 		 LIBCERROR_IO_ERROR_WRITE_FAILED,
985 		 "%s: unable to write to file: %" PRIs_SYSTEM ".",
986 		 function,
987 		 file_io_handle->name );
988 
989 		return( -1 );
990 	}
991 	return( write_count );
992 }
993 
994 /* Seeks a certain offset within the file handle
995  * Returns the offset if the seek is successful or -1 on error
996  */
libbfio_file_io_handle_seek_offset(libbfio_file_io_handle_t * file_io_handle,off64_t offset,int whence,libcerror_error_t ** error)997 off64_t libbfio_file_io_handle_seek_offset(
998          libbfio_file_io_handle_t *file_io_handle,
999          off64_t offset,
1000          int whence,
1001          libcerror_error_t **error )
1002 {
1003 	static char *function = "libbfio_file_seek_offset";
1004 	off64_t seek_offset   = 0;
1005 
1006 	if( file_io_handle == NULL )
1007 	{
1008 		libcerror_error_set(
1009 		 error,
1010 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1011 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1012 		 "%s: invalid file IO handle.",
1013 		 function );
1014 
1015 		return( -1 );
1016 	}
1017 	if( file_io_handle->name == NULL )
1018 	{
1019 		libcerror_error_set(
1020 		 error,
1021 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1022 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1023 		 "%s: invalid file IO handle - missing name.",
1024 		 function );
1025 
1026 		return( -1 );
1027 	}
1028 	seek_offset = libcfile_file_seek_offset(
1029 	               file_io_handle->file,
1030 	               offset,
1031 	               whence,
1032 	               error );
1033 
1034 	if( seek_offset == -1 )
1035 	{
1036 		libcerror_error_set(
1037 		 error,
1038 		 LIBCERROR_ERROR_DOMAIN_IO,
1039 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
1040 		 "%s: unable to seek offset: %" PRIi64 " in file: %" PRIs_SYSTEM ".",
1041 		 function,
1042 		 offset,
1043 		 file_io_handle->name );
1044 
1045 		return( -1 );
1046 	}
1047 	return( seek_offset );
1048 }
1049 
1050 /* Function to determine if a file exists
1051  * Returns 1 if file exists, 0 if not or -1 on error
1052  */
libbfio_file_io_handle_exists(libbfio_file_io_handle_t * file_io_handle,libcerror_error_t ** error)1053 int libbfio_file_io_handle_exists(
1054      libbfio_file_io_handle_t *file_io_handle,
1055      libcerror_error_t **error )
1056 {
1057 	static char *function = "libbfio_file_exists";
1058 	int result            = 0;
1059 
1060 	if( file_io_handle == NULL )
1061 	{
1062 		libcerror_error_set(
1063 		 error,
1064 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1065 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1066 		 "%s: invalid file IO handle.",
1067 		 function );
1068 
1069 		return( -1 );
1070 	}
1071 	if( file_io_handle->name == NULL )
1072 	{
1073 		libcerror_error_set(
1074 		 error,
1075 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1076 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1077 		 "%s: invalid file IO handle - missing name.",
1078 		 function );
1079 
1080 		return( -1 );
1081 	}
1082 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1083 	result = libcfile_file_exists_wide(
1084 	          file_io_handle->name,
1085 	          error );
1086 #else
1087 	result = libcfile_file_exists(
1088 	          file_io_handle->name,
1089 	          error );
1090 #endif
1091 	if( result == -1 )
1092 	{
1093 		libcerror_error_set(
1094 		 error,
1095 		 LIBCERROR_ERROR_DOMAIN_IO,
1096 		 LIBCERROR_IO_ERROR_GENERIC,
1097 		 "%s: unable to determine if file: %" PRIs_SYSTEM " exists.",
1098 		 function,
1099 		 file_io_handle->name );
1100 
1101 		return( -1 );
1102 	}
1103 	return( result );
1104 }
1105 
1106 /* Check if the file is open
1107  * Returns 1 if open, 0 if not or -1 on error
1108  */
libbfio_file_io_handle_is_open(libbfio_file_io_handle_t * file_io_handle,libcerror_error_t ** error)1109 int libbfio_file_io_handle_is_open(
1110      libbfio_file_io_handle_t *file_io_handle,
1111      libcerror_error_t **error )
1112 {
1113 	static char *function = "libbfio_file_is_open";
1114 	int result            = 0;
1115 
1116 	if( file_io_handle == NULL )
1117 	{
1118 		libcerror_error_set(
1119 		 error,
1120 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1121 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1122 		 "%s: invalid file IO handle.",
1123 		 function );
1124 
1125 		return( -1 );
1126 	}
1127 	result = libcfile_file_is_open(
1128 	          file_io_handle->file,
1129 	          error );
1130 
1131 	if( result == -1 )
1132 	{
1133 		libcerror_error_set(
1134 		 error,
1135 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1136 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1137 		 "%s: unable to determine if file is open.",
1138 		 function );
1139 
1140 		return( -1 );
1141 	}
1142 	return( result );
1143 }
1144 
1145 /* Retrieves the file size
1146  * Returns 1 if successful or -1 on error
1147  */
libbfio_file_io_handle_get_size(libbfio_file_io_handle_t * file_io_handle,size64_t * size,libcerror_error_t ** error)1148 int libbfio_file_io_handle_get_size(
1149      libbfio_file_io_handle_t *file_io_handle,
1150      size64_t *size,
1151      libcerror_error_t **error )
1152 {
1153 	static char *function = "libbfio_file_get_size";
1154 
1155 	if( file_io_handle == NULL )
1156 	{
1157 		libcerror_error_set(
1158 		 error,
1159 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1160 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1161 		 "%s: invalid file IO handle.",
1162 		 function );
1163 
1164 		return( -1 );
1165 	}
1166 	if( file_io_handle->name == NULL )
1167 	{
1168 		libcerror_error_set(
1169 		 error,
1170 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1171 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1172 		 "%s: invalid file IO handle - missing name.",
1173 		 function );
1174 
1175 		return( -1 );
1176 	}
1177 	if( libcfile_file_get_size(
1178 	     file_io_handle->file,
1179 	     size,
1180 	     error ) != 1 )
1181 	{
1182 		libcerror_error_set(
1183 		 error,
1184 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1185 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1186 		 "%s: unable to retrieve size of file: %" PRIs_SYSTEM ".",
1187 		 function,
1188 		 file_io_handle->name );
1189 
1190 		return( -1 );
1191 	}
1192 	return( 1 );
1193 }
1194 
1195