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