1 /*
2 * The segments array functions
3 *
4 * Copyright (C) 2010-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 #include "libfdata_libcdata.h"
27 #include "libfdata_libcerror.h"
28 #include "libfdata_libcnotify.h"
29 #include "libfdata_mapped_range.h"
30 #include "libfdata_range.h"
31 #include "libfdata_segments_array.h"
32
33 /* Retrieves a specific segment
34 * Returns 1 if successful or -1 on error
35 */
libfdata_segments_array_get_segment_by_index(libcdata_array_t * segments_array,int segment_index,int * segment_file_index,off64_t * segment_offset,size64_t * segment_size,uint32_t * segment_flags,libcerror_error_t ** error)36 int libfdata_segments_array_get_segment_by_index(
37 libcdata_array_t *segments_array,
38 int segment_index,
39 int *segment_file_index,
40 off64_t *segment_offset,
41 size64_t *segment_size,
42 uint32_t *segment_flags,
43 libcerror_error_t **error )
44 {
45 libfdata_range_t *segment_data_range = NULL;
46 static char *function = "libfdata_segments_array_get_segment_by_index";
47
48 if( libcdata_array_get_entry_by_index(
49 segments_array,
50 segment_index,
51 (intptr_t **) &segment_data_range,
52 error ) != 1 )
53 {
54 libcerror_error_set(
55 error,
56 LIBCERROR_ERROR_DOMAIN_RUNTIME,
57 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
58 "%s: unable to retrieve entry: %d from segments array.",
59 function,
60 segment_index );
61
62 return( -1 );
63 }
64 if( libfdata_range_get(
65 segment_data_range,
66 segment_file_index,
67 segment_offset,
68 segment_size,
69 segment_flags,
70 error ) != 1 )
71 {
72 libcerror_error_set(
73 error,
74 LIBCERROR_ERROR_DOMAIN_RUNTIME,
75 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
76 "%s: unable to retrieve segment: %d data range values.",
77 function,
78 segment_index );
79
80 return( -1 );
81 }
82 return( 1 );
83 }
84
85 /* Sets the offset and size of a specific segment
86 * Returns 1 if successful or -1 on error
87 */
libfdata_segments_array_set_segment_by_index(libcdata_array_t * segments_array,libcdata_array_t * mapped_ranges_array,size64_t * data_size,int segment_index,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)88 int libfdata_segments_array_set_segment_by_index(
89 libcdata_array_t *segments_array,
90 libcdata_array_t *mapped_ranges_array,
91 size64_t *data_size,
92 int segment_index,
93 int segment_file_index,
94 off64_t segment_offset,
95 size64_t segment_size,
96 uint32_t segment_flags,
97 libcerror_error_t **error )
98 {
99 libfdata_mapped_range_t *mapped_range = NULL;
100 libfdata_range_t *segment_data_range = NULL;
101 static char *function = "libfdata_segments_array_set_segment_by_index";
102 off64_t previous_segment_offset = 0;
103 size64_t previous_segment_size = 0;
104 uint32_t previous_segment_flags = 0;
105 int previous_segment_file_index = 0;
106
107 if( data_size == NULL )
108 {
109 libcerror_error_set(
110 error,
111 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
113 "%s: invalid data size.",
114 function );
115
116 return( -1 );
117 }
118 if( segment_file_index < 0 )
119 {
120 libcerror_error_set(
121 error,
122 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
123 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
124 "%s: invalid segment file index value out of bounds.",
125 function );
126
127 return( -1 );
128 }
129 if( segment_offset < 0 )
130 {
131 libcerror_error_set(
132 error,
133 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
134 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
135 "%s: invalid segment offset value out of bounds.",
136 function );
137
138 return( -1 );
139 }
140 if( libcdata_array_get_entry_by_index(
141 segments_array,
142 segment_index,
143 (intptr_t **) &segment_data_range,
144 error ) != 1 )
145 {
146 libcerror_error_set(
147 error,
148 LIBCERROR_ERROR_DOMAIN_RUNTIME,
149 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
150 "%s: unable to retrieve entry: %d from segments array.",
151 function,
152 segment_index );
153
154 return( -1 );
155 }
156 if( segment_data_range == NULL )
157 {
158 if( libfdata_range_initialize(
159 &segment_data_range,
160 error ) != 1 )
161 {
162 libcerror_error_set(
163 error,
164 LIBCERROR_ERROR_DOMAIN_RUNTIME,
165 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
166 "%s: unable to create segment data range.",
167 function );
168
169 return( -1 );
170 }
171 if( libcdata_array_set_entry_by_index(
172 segments_array,
173 segment_index,
174 (intptr_t *) segment_data_range,
175 error ) != 1 )
176 {
177 libcerror_error_set(
178 error,
179 LIBCERROR_ERROR_DOMAIN_RUNTIME,
180 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
181 "%s: unable to set entry: %d to segments array.",
182 function,
183 segment_index );
184
185 libfdata_range_free(
186 &segment_data_range,
187 NULL );
188
189 return( -1 );
190 }
191 }
192 else
193 {
194 if( libfdata_range_get(
195 segment_data_range,
196 &previous_segment_file_index,
197 &previous_segment_offset,
198 &previous_segment_size,
199 &previous_segment_flags,
200 error ) != 1 )
201 {
202 libcerror_error_set(
203 error,
204 LIBCERROR_ERROR_DOMAIN_RUNTIME,
205 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
206 "%s: unable to retrieve segment: %d data range values.",
207 function,
208 segment_index );
209
210 return( -1 );
211 }
212 *data_size -= previous_segment_size;
213 }
214 if( libfdata_range_set(
215 segment_data_range,
216 segment_file_index,
217 segment_offset,
218 segment_size,
219 segment_flags,
220 error ) != 1 )
221 {
222 libcerror_error_set(
223 error,
224 LIBCERROR_ERROR_DOMAIN_RUNTIME,
225 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
226 "%s: unable to set segment data range values.",
227 function );
228
229 return( -1 );
230 }
231 /* Make sure there is a mapped range entry for every segment
232 */
233 if( libcdata_array_get_entry_by_index(
234 mapped_ranges_array,
235 segment_index,
236 (intptr_t **) &mapped_range,
237 error ) != 1 )
238 {
239 libcerror_error_set(
240 error,
241 LIBCERROR_ERROR_DOMAIN_RUNTIME,
242 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
243 "%s: unable to retrieve entry: %d from mapped ranges array.",
244 function,
245 segment_index );
246
247 return( -1 );
248 }
249 if( mapped_range == NULL )
250 {
251 if( libfdata_mapped_range_initialize(
252 &mapped_range,
253 error ) != 1 )
254 {
255 libcerror_error_set(
256 error,
257 LIBCERROR_ERROR_DOMAIN_RUNTIME,
258 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
259 "%s: unable to create mapped range.",
260 function );
261
262 return( -1 );
263 }
264 if( libcdata_array_set_entry_by_index(
265 mapped_ranges_array,
266 segment_index,
267 (intptr_t *) mapped_range,
268 error ) != 1 )
269 {
270 libcerror_error_set(
271 error,
272 LIBCERROR_ERROR_DOMAIN_RUNTIME,
273 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
274 "%s: unable to set entry: %d in mapped ranges array.",
275 function,
276 segment_index );
277
278 libfdata_mapped_range_free(
279 &mapped_range,
280 NULL );
281
282 return( -1 );
283 }
284 }
285 *data_size += segment_size;
286
287 return( 1 );
288 }
289
290 /* Prepends a segment
291 * Returns 1 if successful or -1 on error
292 */
libfdata_segments_array_prepend_segment(libcdata_array_t * segments_array,libcdata_array_t * mapped_ranges_array,size64_t * data_size,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)293 int libfdata_segments_array_prepend_segment(
294 libcdata_array_t *segments_array,
295 libcdata_array_t *mapped_ranges_array,
296 size64_t *data_size,
297 int segment_file_index,
298 off64_t segment_offset,
299 size64_t segment_size,
300 uint32_t segment_flags,
301 libcerror_error_t **error )
302 {
303 libfdata_mapped_range_t *mapped_range = NULL;
304 libfdata_range_t *segment_data_range = NULL;
305 static char *function = "libfdata_segments_array_prepend_segment";
306 int mapped_range_index = -1;
307
308 if( data_size == NULL )
309 {
310 libcerror_error_set(
311 error,
312 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
313 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
314 "%s: invalid data size.",
315 function );
316
317 return( -1 );
318 }
319 if( segment_file_index < 0 )
320 {
321 libcerror_error_set(
322 error,
323 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
324 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
325 "%s: invalid segment file index value out of bounds.",
326 function );
327
328 return( -1 );
329 }
330 if( segment_offset < 0 )
331 {
332 libcerror_error_set(
333 error,
334 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
335 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
336 "%s: invalid segment offset value out of bounds.",
337 function );
338
339 return( -1 );
340 }
341 if( segment_size > (size64_t) INT64_MAX )
342 {
343 libcerror_error_set(
344 error,
345 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
347 "%s: invalid segment size value out of bounds.",
348 function );
349
350 return( -1 );
351 }
352 if( libfdata_mapped_range_initialize(
353 &mapped_range,
354 error ) != 1 )
355 {
356 libcerror_error_set(
357 error,
358 LIBCERROR_ERROR_DOMAIN_RUNTIME,
359 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
360 "%s: unable to create mapped range.",
361 function );
362
363 goto on_error;
364 }
365 if( libfdata_mapped_range_set(
366 mapped_range,
367 (off64_t) *data_size,
368 segment_size,
369 error ) != 1 )
370 {
371 libcerror_error_set(
372 error,
373 LIBCERROR_ERROR_DOMAIN_RUNTIME,
374 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
375 "%s: unable to set mapped range values.",
376 function );
377
378 goto on_error;
379 }
380 if( libcdata_array_append_entry(
381 mapped_ranges_array,
382 &mapped_range_index,
383 (intptr_t *) mapped_range,
384 error ) != 1 )
385 {
386 libcerror_error_set(
387 error,
388 LIBCERROR_ERROR_DOMAIN_RUNTIME,
389 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
390 "%s: unable to append mapped range to array.",
391 function );
392
393 goto on_error;
394 }
395 if( libfdata_range_initialize(
396 &segment_data_range,
397 error ) != 1 )
398 {
399 libcerror_error_set(
400 error,
401 LIBCERROR_ERROR_DOMAIN_RUNTIME,
402 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
403 "%s: unable to create segment data range.",
404 function );
405
406 goto on_error;
407 }
408 if( libfdata_range_set(
409 segment_data_range,
410 segment_file_index,
411 segment_offset,
412 segment_size,
413 segment_flags,
414 error ) != 1 )
415 {
416 libcerror_error_set(
417 error,
418 LIBCERROR_ERROR_DOMAIN_RUNTIME,
419 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
420 "%s: unable to set segment data range values.",
421 function );
422
423 goto on_error;
424 }
425 if( libcdata_array_prepend_entry(
426 segments_array,
427 (intptr_t *) segment_data_range,
428 error ) != 1 )
429 {
430 libcerror_error_set(
431 error,
432 LIBCERROR_ERROR_DOMAIN_RUNTIME,
433 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
434 "%s: unable to prepend data range to segments array.",
435 function );
436
437 goto on_error;
438 }
439 *data_size += segment_size;
440
441 return( 1 );
442
443 on_error:
444 if( segment_data_range != NULL )
445 {
446 libfdata_range_free(
447 &segment_data_range,
448 NULL );
449 }
450 if( mapped_range_index != -1 )
451 {
452 libcdata_array_set_entry_by_index(
453 mapped_ranges_array,
454 mapped_range_index,
455 NULL,
456 NULL );
457 }
458 if( mapped_range != NULL )
459 {
460 libfdata_mapped_range_free(
461 &mapped_range,
462 NULL );
463 }
464 return( -1 );
465 }
466
467 /* Appends a segment
468 * Returns 1 if successful or -1 on error
469 */
libfdata_segments_array_append_segment(libcdata_array_t * segments_array,libcdata_array_t * mapped_ranges_array,size64_t * data_size,int * segment_index,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)470 int libfdata_segments_array_append_segment(
471 libcdata_array_t *segments_array,
472 libcdata_array_t *mapped_ranges_array,
473 size64_t *data_size,
474 int *segment_index,
475 int segment_file_index,
476 off64_t segment_offset,
477 size64_t segment_size,
478 uint32_t segment_flags,
479 libcerror_error_t **error )
480 {
481 libfdata_mapped_range_t *mapped_range = NULL;
482 libfdata_range_t *segment_data_range = NULL;
483 static char *function = "libfdata_segments_array_append_segment";
484 int mapped_range_index = -1;
485
486 if( data_size == NULL )
487 {
488 libcerror_error_set(
489 error,
490 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
491 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
492 "%s: invalid data size.",
493 function );
494
495 return( -1 );
496 }
497 if( segment_file_index < 0 )
498 {
499 libcerror_error_set(
500 error,
501 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
502 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
503 "%s: invalid segment file index value out of bounds.",
504 function );
505
506 return( -1 );
507 }
508 if( segment_offset < 0 )
509 {
510 libcerror_error_set(
511 error,
512 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
513 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
514 "%s: invalid segment offset value out of bounds.",
515 function );
516
517 return( -1 );
518 }
519 if( libfdata_mapped_range_initialize(
520 &mapped_range,
521 error ) != 1 )
522 {
523 libcerror_error_set(
524 error,
525 LIBCERROR_ERROR_DOMAIN_RUNTIME,
526 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
527 "%s: unable to create mapped range.",
528 function );
529
530 goto on_error;
531 }
532 if( libfdata_mapped_range_set(
533 mapped_range,
534 (off64_t) *data_size,
535 segment_size,
536 error ) != 1 )
537 {
538 libcerror_error_set(
539 error,
540 LIBCERROR_ERROR_DOMAIN_RUNTIME,
541 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
542 "%s: unable to set mapped range values.",
543 function );
544
545 goto on_error;
546 }
547 if( libcdata_array_append_entry(
548 mapped_ranges_array,
549 &mapped_range_index,
550 (intptr_t *) mapped_range,
551 error ) != 1 )
552 {
553 libcerror_error_set(
554 error,
555 LIBCERROR_ERROR_DOMAIN_RUNTIME,
556 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
557 "%s: unable to append mapped range to array.",
558 function );
559
560 goto on_error;
561 }
562 if( libfdata_range_initialize(
563 &segment_data_range,
564 error ) != 1 )
565 {
566 libcerror_error_set(
567 error,
568 LIBCERROR_ERROR_DOMAIN_RUNTIME,
569 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
570 "%s: unable to create segment data range.",
571 function );
572
573 goto on_error;
574 }
575 if( libfdata_range_set(
576 segment_data_range,
577 segment_file_index,
578 segment_offset,
579 segment_size,
580 segment_flags,
581 error ) != 1 )
582 {
583 libcerror_error_set(
584 error,
585 LIBCERROR_ERROR_DOMAIN_RUNTIME,
586 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
587 "%s: unable to set segment data range values.",
588 function );
589
590 goto on_error;
591 }
592 if( libcdata_array_append_entry(
593 segments_array,
594 segment_index,
595 (intptr_t *) segment_data_range,
596 error ) != 1 )
597 {
598 libcerror_error_set(
599 error,
600 LIBCERROR_ERROR_DOMAIN_RUNTIME,
601 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
602 "%s: unable to append data range to segments array.",
603 function );
604
605 goto on_error;
606 }
607 #if defined( HAVE_DEBUG_OUTPUT )
608 if( libcnotify_verbose != 0 )
609 {
610 libcnotify_printf(
611 "%s: segment: %03d\tfile index: %03d offset: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
612 function,
613 *segment_index,
614 segment_file_index,
615 segment_offset,
616 segment_offset + segment_size,
617 segment_size );
618
619 libcnotify_printf(
620 "%s: segment: %03d\tmapped range: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
621 function,
622 *segment_index,
623 *data_size,
624 *data_size + segment_size,
625 segment_size );
626
627 libcnotify_printf(
628 "\n" );
629 }
630 #endif
631 *data_size += segment_size;
632
633 return( 1 );
634
635 on_error:
636 if( segment_data_range != NULL )
637 {
638 libfdata_range_free(
639 &segment_data_range,
640 NULL );
641 }
642 if( mapped_range_index != -1 )
643 {
644 libcdata_array_set_entry_by_index(
645 mapped_ranges_array,
646 mapped_range_index,
647 NULL,
648 NULL );
649 }
650 if( mapped_range != NULL )
651 {
652 libfdata_mapped_range_free(
653 &mapped_range,
654 NULL );
655 }
656 return( -1 );
657 }
658
659 /* Calculates the mapped ranges from the segments
660 * Returns 1 if successful or -1 on error
661 */
libfdata_segments_array_calculate_mapped_ranges(libcdata_array_t * segments_array,libcdata_array_t * mapped_ranges_array,libcerror_error_t ** error)662 int libfdata_segments_array_calculate_mapped_ranges(
663 libcdata_array_t *segments_array,
664 libcdata_array_t *mapped_ranges_array,
665 libcerror_error_t **error )
666 {
667 libfdata_mapped_range_t *mapped_range = NULL;
668 libfdata_range_t *segment_data_range = NULL;
669 static char *function = "libfdata_segments_array_calculate_mapped_ranges";
670 off64_t mapped_offset = 0;
671 off64_t segment_offset = 0;
672 size64_t segment_size = 0;
673 uint32_t segment_flags = 0;
674 int number_of_segments = 0;
675 int segment_file_index = 0;
676 int segment_index = 0;
677
678 if( libcdata_array_get_number_of_entries(
679 segments_array,
680 &number_of_segments,
681 error ) != 1 )
682 {
683 libcerror_error_set(
684 error,
685 LIBCERROR_ERROR_DOMAIN_RUNTIME,
686 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
687 "%s: unable to retrieve number of entries from segments array.",
688 function );
689
690 return( -1 );
691 }
692 for( segment_index = 0;
693 segment_index < number_of_segments;
694 segment_index++ )
695 {
696 if( libcdata_array_get_entry_by_index(
697 segments_array,
698 segment_index,
699 (intptr_t **) &segment_data_range,
700 error ) != 1 )
701 {
702 libcerror_error_set(
703 error,
704 LIBCERROR_ERROR_DOMAIN_RUNTIME,
705 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
706 "%s: unable to retrieve entry: %d from segments array.",
707 function,
708 segment_index );
709
710 return( -1 );
711 }
712 if( libcdata_array_get_entry_by_index(
713 mapped_ranges_array,
714 segment_index,
715 (intptr_t **) &mapped_range,
716 error ) != 1 )
717 {
718 libcerror_error_set(
719 error,
720 LIBCERROR_ERROR_DOMAIN_RUNTIME,
721 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
722 "%s: unable to retrieve entry: %d from mapped ranges array.",
723 function,
724 segment_index );
725
726 return( -1 );
727 }
728 if( libfdata_range_get(
729 segment_data_range,
730 &segment_file_index,
731 &segment_offset,
732 &segment_size,
733 &segment_flags,
734 error ) != 1 )
735 {
736 libcerror_error_set(
737 error,
738 LIBCERROR_ERROR_DOMAIN_RUNTIME,
739 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
740 "%s: unable to retrieve segment: %d data range values.",
741 function,
742 segment_index );
743
744 return( -1 );
745 }
746 #if defined( HAVE_DEBUG_OUTPUT )
747 if( libcnotify_verbose != 0 )
748 {
749 libcnotify_printf(
750 "%s: segment: %03d\tfile index: %03d offset: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
751 function,
752 segment_index,
753 segment_file_index,
754 segment_offset,
755 segment_offset + segment_size,
756 segment_size );
757
758 libcnotify_printf(
759 "%s: segment: %03d\tmapped range: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
760 function,
761 segment_index,
762 mapped_offset,
763 mapped_offset + segment_size,
764 segment_size );
765 }
766 #endif
767 if( libfdata_mapped_range_set(
768 mapped_range,
769 mapped_offset,
770 segment_size,
771 error ) != 1 )
772 {
773 libcerror_error_set(
774 error,
775 LIBCERROR_ERROR_DOMAIN_RUNTIME,
776 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
777 "%s: unable to set mapped range: %d values.",
778 function,
779 segment_index );
780
781 return( -1 );
782 }
783 mapped_offset += (off64_t) segment_size;
784 }
785 #if defined( HAVE_DEBUG_OUTPUT )
786 if( libcnotify_verbose != 0 )
787 {
788 libcnotify_printf(
789 "\n" );
790 }
791 #endif
792 return( 1 );
793 }
794
795 /* Retrieves the segment data range for a specific offset
796 * Returns 1 if successful or -1 on error
797 */
libfdata_segments_array_get_data_range_at_offset(libcdata_array_t * segments_array,off64_t value_offset,off64_t * segment_data_offset,libfdata_range_t ** segment_data_range,libcerror_error_t ** error)798 int libfdata_segments_array_get_data_range_at_offset(
799 libcdata_array_t *segments_array,
800 off64_t value_offset,
801 off64_t *segment_data_offset,
802 libfdata_range_t **segment_data_range,
803 libcerror_error_t **error )
804 {
805 static char *function = "libfdata_segments_array_get_data_range_at_offset";
806 size64_t segment_size = 0;
807 int number_of_segments = 0;
808 int segment_index = 0;
809
810 if( segment_data_offset == NULL )
811 {
812 libcerror_error_set(
813 error,
814 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
815 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
816 "%s: invalid segment data offset.",
817 function );
818
819 return( -1 );
820 }
821 if( segment_data_range == NULL )
822 {
823 libcerror_error_set(
824 error,
825 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
826 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
827 "%s: invalid segment data range.",
828 function );
829
830 return( -1 );
831 }
832 if( libcdata_array_get_number_of_entries(
833 segments_array,
834 &number_of_segments,
835 error ) != 1 )
836 {
837 libcerror_error_set(
838 error,
839 LIBCERROR_ERROR_DOMAIN_RUNTIME,
840 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
841 "%s: unable to retrieve number of segments.",
842 function );
843
844 return( -1 );
845 }
846 if( number_of_segments <= 0 )
847 {
848 libcerror_error_set(
849 error,
850 LIBCERROR_ERROR_DOMAIN_RUNTIME,
851 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
852 "%s: invalid number of segments value out of bounds.",
853 function );
854
855 return( -1 );
856 }
857 for( segment_index = 0;
858 segment_index < number_of_segments;
859 segment_index++ )
860 {
861 if( libcdata_array_get_entry_by_index(
862 segments_array,
863 segment_index,
864 (intptr_t **) segment_data_range,
865 error ) != 1 )
866 {
867 libcerror_error_set(
868 error,
869 LIBCERROR_ERROR_DOMAIN_RUNTIME,
870 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
871 "%s: unable to retrieve segment data range: %d from array.",
872 function,
873 segment_index );
874
875 return( -1 );
876 }
877 if( libfdata_range_get_size(
878 *segment_data_range,
879 &segment_size,
880 error ) != 1 )
881 {
882 libcerror_error_set(
883 error,
884 LIBCERROR_ERROR_DOMAIN_RUNTIME,
885 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
886 "%s: unable to retrieve size from segment data range: %d.",
887 function,
888 segment_index );
889
890 return( -1 );
891 }
892 /* TODO what about compressed data ranges */
893 if( (size64_t) value_offset < segment_size )
894 {
895 *segment_data_offset = value_offset;
896
897 break;
898 }
899 value_offset -= segment_size;
900 }
901 if( segment_index >= number_of_segments )
902 {
903 libcerror_error_set(
904 error,
905 LIBCERROR_ERROR_DOMAIN_RUNTIME,
906 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
907 "%s: invalid segment index value out of bounds.",
908 function );
909
910 return( -1 );
911 }
912 return( 1 );
913 }
914
915