1 /*
2 * The list 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_definitions.h"
27 #include "libfdata_libcdata.h"
28 #include "libfdata_libcerror.h"
29 #include "libfdata_libcnotify.h"
30 #include "libfdata_libfcache.h"
31 #include "libfdata_list.h"
32 #include "libfdata_list_element.h"
33 #include "libfdata_mapped_range.h"
34 #include "libfdata_range.h"
35 #include "libfdata_types.h"
36 #include "libfdata_unused.h"
37
38 /* Creates a list
39 * Make sure the value list is referencing, is set to NULL
40 *
41 * If the flag LIBFDATA_DATA_HANDLE_FLAG_MANAGED is set the list
42 * takes over management of the data handle and the data handle is freed when
43 * no longer needed
44 *
45 * Returns 1 if successful or -1 on error
46 */
libfdata_list_initialize(libfdata_list_t ** list,intptr_t * data_handle,int (* free_data_handle)(intptr_t ** data_handle,libcerror_error_t ** error),int (* clone_data_handle)(intptr_t ** destination_data_handle,intptr_t * source_data_handle,libcerror_error_t ** error),int (* read_element_data)(intptr_t * data_handle,intptr_t * file_io_handle,libfdata_list_element_t * list_element,libfdata_cache_t * cache,int element_data_file_index,off64_t element_data_offset,size64_t element_data_size,uint32_t element_data_flags,uint8_t read_flags,libcerror_error_t ** error),int (* write_element_data)(intptr_t * data_handle,intptr_t * file_io_handle,libfdata_list_element_t * list_element,libfdata_cache_t * cache,int element_data_file_index,off64_t element_data_offset,size64_t element_data_size,uint32_t element_data_flags,uint8_t write_flags,libcerror_error_t ** error),uint8_t flags,libcerror_error_t ** error)47 int libfdata_list_initialize(
48 libfdata_list_t **list,
49 intptr_t *data_handle,
50 int (*free_data_handle)(
51 intptr_t **data_handle,
52 libcerror_error_t **error ),
53 int (*clone_data_handle)(
54 intptr_t **destination_data_handle,
55 intptr_t *source_data_handle,
56 libcerror_error_t **error ),
57 int (*read_element_data)(
58 intptr_t *data_handle,
59 intptr_t *file_io_handle,
60 libfdata_list_element_t *list_element,
61 libfdata_cache_t *cache,
62 int element_data_file_index,
63 off64_t element_data_offset,
64 size64_t element_data_size,
65 uint32_t element_data_flags,
66 uint8_t read_flags,
67 libcerror_error_t **error ),
68 int (*write_element_data)(
69 intptr_t *data_handle,
70 intptr_t *file_io_handle,
71 libfdata_list_element_t *list_element,
72 libfdata_cache_t *cache,
73 int element_data_file_index,
74 off64_t element_data_offset,
75 size64_t element_data_size,
76 uint32_t element_data_flags,
77 uint8_t write_flags,
78 libcerror_error_t **error ),
79 uint8_t flags,
80 libcerror_error_t **error )
81 {
82 libfdata_internal_list_t *internal_list = NULL;
83 static char *function = "libfdata_list_initialize";
84
85 if( list == NULL )
86 {
87 libcerror_error_set(
88 error,
89 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
90 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
91 "%s: invalid list.",
92 function );
93
94 return( -1 );
95 }
96 if( *list != NULL )
97 {
98 libcerror_error_set(
99 error,
100 LIBCERROR_ERROR_DOMAIN_RUNTIME,
101 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
102 "%s: invalid list value already set.",
103 function );
104
105 return( -1 );
106 }
107 if( ( flags & 0xfe ) != 0 )
108 {
109 libcerror_error_set(
110 error,
111 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
113 "%s: unsupported flags: 0x%02" PRIx8 ".",
114 function );
115
116 return( -1 );
117 }
118 internal_list = memory_allocate_structure(
119 libfdata_internal_list_t );
120
121 if( internal_list == NULL )
122 {
123 libcerror_error_set(
124 error,
125 LIBCERROR_ERROR_DOMAIN_MEMORY,
126 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
127 "%s: unable to create list.",
128 function );
129
130 goto on_error;
131 }
132 if( memory_set(
133 internal_list,
134 0,
135 sizeof( libfdata_internal_list_t ) ) == NULL )
136 {
137 libcerror_error_set(
138 error,
139 LIBCERROR_ERROR_DOMAIN_MEMORY,
140 LIBCERROR_MEMORY_ERROR_SET_FAILED,
141 "%s: unable to clear list.",
142 function );
143
144 memory_free(
145 internal_list );
146
147 return( -1 );
148 }
149 if( libcdata_array_initialize(
150 &( internal_list->elements_array ),
151 0,
152 error ) != 1 )
153 {
154 libcerror_error_set(
155 error,
156 LIBCERROR_ERROR_DOMAIN_RUNTIME,
157 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
158 "%s: unable to create elements array.",
159 function );
160
161 goto on_error;
162 }
163 if( libcdata_array_initialize(
164 &( internal_list->mapped_ranges_array ),
165 0,
166 error ) != 1 )
167 {
168 libcerror_error_set(
169 error,
170 LIBCERROR_ERROR_DOMAIN_RUNTIME,
171 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
172 "%s: unable to create mapped ranges array.",
173 function );
174
175 goto on_error;
176 }
177 internal_list->flags |= flags;
178 internal_list->data_handle = data_handle;
179 internal_list->free_data_handle = free_data_handle;
180 internal_list->clone_data_handle = clone_data_handle;
181 internal_list->read_element_data = read_element_data;
182 internal_list->write_element_data = write_element_data;
183
184 *list = (libfdata_list_t *) internal_list;
185
186 return( 1 );
187
188 on_error:
189 if( internal_list != NULL )
190 {
191 if( internal_list->elements_array != NULL )
192 {
193 libcdata_array_free(
194 &( internal_list->elements_array ),
195 NULL,
196 NULL );
197 }
198 memory_free(
199 internal_list );
200 }
201 return( -1 );
202 }
203
204 /* Frees a list
205 * Returns 1 if successful or -1 on error
206 */
libfdata_list_free(libfdata_list_t ** list,libcerror_error_t ** error)207 int libfdata_list_free(
208 libfdata_list_t **list,
209 libcerror_error_t **error )
210 {
211 libfdata_internal_list_t *internal_list = NULL;
212 static char *function = "libfdata_list_free";
213 int result = 1;
214
215 if( list == NULL )
216 {
217 libcerror_error_set(
218 error,
219 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
221 "%s: invalid list.",
222 function );
223
224 return( -1 );
225 }
226 if( *list != NULL )
227 {
228 internal_list = (libfdata_internal_list_t *) *list;
229 *list = NULL;
230
231 if( libcdata_array_free(
232 &( internal_list->elements_array ),
233 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
234 error ) != 1 )
235 {
236 libcerror_error_set(
237 error,
238 LIBCERROR_ERROR_DOMAIN_RUNTIME,
239 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
240 "%s: unable to free the elements array.",
241 function );
242
243 result = -1;
244 }
245 if( libcdata_array_free(
246 &( internal_list->mapped_ranges_array ),
247 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
248 error ) != 1 )
249 {
250 libcerror_error_set(
251 error,
252 LIBCERROR_ERROR_DOMAIN_RUNTIME,
253 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
254 "%s: unable to free the mapped ranges array.",
255 function );
256
257 result = -1;
258 }
259 if( ( internal_list->flags & LIBFDATA_DATA_HANDLE_FLAG_MANAGED ) != 0 )
260 {
261 if( internal_list->data_handle != NULL )
262 {
263 if( internal_list->free_data_handle == NULL )
264 {
265 libcerror_error_set(
266 error,
267 LIBCERROR_ERROR_DOMAIN_RUNTIME,
268 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
269 "%s: invalid list - missing free data handle function.",
270 function );
271
272 result = -1;
273 }
274 else if( internal_list->free_data_handle(
275 &( internal_list->data_handle ),
276 error ) != 1 )
277 {
278 libcerror_error_set(
279 error,
280 LIBCERROR_ERROR_DOMAIN_RUNTIME,
281 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
282 "%s: unable to free data handle.",
283 function );
284
285 result = -1;
286 }
287 }
288 }
289 memory_free(
290 internal_list );
291 }
292 return( result );
293 }
294
295 /* Clones (duplicates) the list
296 * Returns 1 if successful or -1 on error
297 */
libfdata_list_clone(libfdata_list_t ** destination_list,libfdata_list_t * source_list,libcerror_error_t ** error)298 int libfdata_list_clone(
299 libfdata_list_t **destination_list,
300 libfdata_list_t *source_list,
301 libcerror_error_t **error )
302 {
303 libfdata_internal_list_t *internal_destination_list = NULL;
304 libfdata_internal_list_t *internal_source_list = NULL;
305 static char *function = "libfdata_list_clone";
306
307 if( destination_list == NULL )
308 {
309 libcerror_error_set(
310 error,
311 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
312 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
313 "%s: invalid destination list.",
314 function );
315
316 return( -1 );
317 }
318 if( *destination_list != NULL )
319 {
320 libcerror_error_set(
321 error,
322 LIBCERROR_ERROR_DOMAIN_RUNTIME,
323 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
324 "%s: invalid destination list value already set.",
325 function );
326
327 return( -1 );
328 }
329 if( source_list == NULL )
330 {
331 *destination_list = NULL;
332
333 return( 1 );
334 }
335 internal_source_list = (libfdata_internal_list_t *) source_list;
336
337 internal_destination_list = memory_allocate_structure(
338 libfdata_internal_list_t );
339
340 if( internal_destination_list == NULL )
341 {
342 libcerror_error_set(
343 error,
344 LIBCERROR_ERROR_DOMAIN_MEMORY,
345 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
346 "%s: unable to create destination list.",
347 function );
348
349 goto on_error;
350 }
351 if( memory_set(
352 internal_destination_list,
353 0,
354 sizeof( libfdata_internal_list_t ) ) == NULL )
355 {
356 libcerror_error_set(
357 error,
358 LIBCERROR_ERROR_DOMAIN_MEMORY,
359 LIBCERROR_MEMORY_ERROR_SET_FAILED,
360 "%s: unable to clear destination list.",
361 function );
362
363 memory_free(
364 internal_destination_list );
365
366 return( -1 );
367 }
368 if( internal_source_list->data_handle != NULL )
369 {
370 if( internal_source_list->free_data_handle == NULL )
371 {
372 libcerror_error_set(
373 error,
374 LIBCERROR_ERROR_DOMAIN_RUNTIME,
375 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
376 "%s: invalid source list - missing free data handle function.",
377 function );
378
379 goto on_error;
380 }
381 if( internal_source_list->clone_data_handle == NULL )
382 {
383 libcerror_error_set(
384 error,
385 LIBCERROR_ERROR_DOMAIN_RUNTIME,
386 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
387 "%s: invalid source list - missing clone data handle function.",
388 function );
389
390 goto on_error;
391 }
392 if( internal_source_list->clone_data_handle(
393 &( internal_destination_list->data_handle ),
394 internal_source_list->data_handle,
395 error ) != 1 )
396 {
397 libcerror_error_set(
398 error,
399 LIBCERROR_ERROR_DOMAIN_RUNTIME,
400 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
401 "%s: unable to clone data handle.",
402 function );
403
404 goto on_error;
405 }
406 }
407 /* TODO set destination list in destination elements */
408 if( libcdata_array_clone(
409 &( internal_destination_list->elements_array ),
410 internal_source_list->elements_array,
411 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
412 (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_list_element_clone,
413 error ) != 1 )
414 {
415 libcerror_error_set(
416 error,
417 LIBCERROR_ERROR_DOMAIN_RUNTIME,
418 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
419 "%s: unable to create destination elements array.",
420 function );
421
422 goto on_error;
423 }
424 if( libcdata_array_clone(
425 &( internal_destination_list->mapped_ranges_array ),
426 internal_source_list->mapped_ranges_array,
427 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
428 (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_mapped_range_clone,
429 error ) != 1 )
430 {
431 libcerror_error_set(
432 error,
433 LIBCERROR_ERROR_DOMAIN_RUNTIME,
434 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
435 "%s: unable to create destination mapped ranges array.",
436 function );
437
438 goto on_error;
439 }
440 internal_destination_list->flags = internal_source_list->flags | LIBFDATA_DATA_HANDLE_FLAG_MANAGED;
441 internal_destination_list->free_data_handle = internal_source_list->free_data_handle;
442 internal_destination_list->clone_data_handle = internal_source_list->clone_data_handle;
443 internal_destination_list->read_element_data = internal_source_list->read_element_data;
444 internal_destination_list->write_element_data = internal_source_list->write_element_data;
445
446 *destination_list = (libfdata_list_t *) internal_destination_list;
447
448 return( 1 );
449
450 on_error:
451 if( internal_destination_list != NULL )
452 {
453 if( internal_destination_list->elements_array != NULL )
454 {
455 libcdata_array_free(
456 &( internal_destination_list->elements_array ),
457 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
458 NULL );
459 }
460 if( ( internal_destination_list->data_handle != NULL )
461 && ( internal_source_list->free_data_handle != NULL ) )
462 {
463 internal_source_list->free_data_handle(
464 &( internal_destination_list->data_handle ),
465 NULL );
466 }
467 memory_free(
468 internal_destination_list );
469 }
470 return( -1 );
471 }
472
473 /* Sets the calculate mapped ranges flag
474 * Returns 1 if successful or -1 on error
475 */
libfdata_list_set_calculate_mapped_ranges_flag(libfdata_list_t * list,libcerror_error_t ** error)476 int libfdata_list_set_calculate_mapped_ranges_flag(
477 libfdata_list_t *list,
478 libcerror_error_t **error )
479 {
480 libfdata_internal_list_t *internal_list = NULL;
481 static char *function = "libfdata_list_set_calculate_mapped_ranges_flag";
482
483 if( list == NULL )
484 {
485 libcerror_error_set(
486 error,
487 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
488 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
489 "%s: invalid list.",
490 function );
491
492 return( -1 );
493 }
494 internal_list = (libfdata_internal_list_t *) list;
495
496 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
497
498 return( 1 );
499 }
500
501 /* List elements functions
502 */
503
504 /* Empties the list
505 * Returns 1 if successful or -1 on error
506 */
libfdata_list_empty(libfdata_list_t * list,libcerror_error_t ** error)507 int libfdata_list_empty(
508 libfdata_list_t *list,
509 libcerror_error_t **error )
510 {
511 libfdata_internal_list_t *internal_list = NULL;
512 static char *function = "libfdata_list_empty";
513
514 if( list == NULL )
515 {
516 libcerror_error_set(
517 error,
518 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
519 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
520 "%s: invalid list.",
521 function );
522
523 return( -1 );
524 }
525 internal_list = (libfdata_internal_list_t *) list;
526
527 if( libcdata_array_empty(
528 internal_list->elements_array,
529 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
530 error ) != 1 )
531 {
532 libcerror_error_set(
533 error,
534 LIBCERROR_ERROR_DOMAIN_RUNTIME,
535 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
536 "%s: unable to empty elements array.",
537 function );
538
539 return( -1 );
540 }
541 if( libcdata_array_empty(
542 internal_list->mapped_ranges_array,
543 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
544 error ) != 1 )
545 {
546 libcerror_error_set(
547 error,
548 LIBCERROR_ERROR_DOMAIN_RUNTIME,
549 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
550 "%s: unable to empty mapped ranges array.",
551 function );
552
553 return( -1 );
554 }
555 internal_list->size = 0;
556
557 return( 1 );
558 }
559
560 /* Resizes the list
561 * Returns 1 if successful or -1 on error
562 */
libfdata_list_resize(libfdata_list_t * list,int number_of_elements,libcerror_error_t ** error)563 int libfdata_list_resize(
564 libfdata_list_t *list,
565 int number_of_elements,
566 libcerror_error_t **error )
567 {
568 libfdata_internal_list_t *internal_list = NULL;
569 static char *function = "libfdata_list_resize";
570
571 if( list == NULL )
572 {
573 libcerror_error_set(
574 error,
575 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
576 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
577 "%s: invalid list.",
578 function );
579
580 return( -1 );
581 }
582 internal_list = (libfdata_internal_list_t *) list;
583
584 if( libcdata_array_resize(
585 internal_list->elements_array,
586 number_of_elements,
587 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
588 error ) != 1 )
589 {
590 libcerror_error_set(
591 error,
592 LIBCERROR_ERROR_DOMAIN_RUNTIME,
593 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
594 "%s: unable to resize elements array.",
595 function );
596
597 return( -1 );
598 }
599 if( libcdata_array_resize(
600 internal_list->mapped_ranges_array,
601 number_of_elements,
602 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
603 error ) != 1 )
604 {
605 libcerror_error_set(
606 error,
607 LIBCERROR_ERROR_DOMAIN_RUNTIME,
608 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
609 "%s: unable to resize mapped ranges array.",
610 function );
611
612 return( -1 );
613 }
614 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
615
616 return( 1 );
617 }
618
619 /* Reverses the order of the elements
620 * Returns 1 if successful or -1 on error
621 */
libfdata_list_reverse(libfdata_list_t * list,libcerror_error_t ** error)622 int libfdata_list_reverse(
623 libfdata_list_t *list,
624 libcerror_error_t **error )
625 {
626 libfdata_internal_list_t *internal_list = NULL;
627 libfdata_list_element_t *list_element = NULL;
628 static char *function = "libfdata_list_reverse";
629 int element_index = 0;
630 int number_of_elements = 0;
631
632 if( list == NULL )
633 {
634 libcerror_error_set(
635 error,
636 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
637 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
638 "%s: invalid list.",
639 function );
640
641 return( -1 );
642 }
643 internal_list = (libfdata_internal_list_t *) list;
644
645 if( libcdata_array_reverse(
646 internal_list->elements_array,
647 error ) != 1 )
648 {
649 libcerror_error_set(
650 error,
651 LIBCERROR_ERROR_DOMAIN_RUNTIME,
652 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
653 "%s: unable to reverse elements array.",
654 function );
655
656 return( -1 );
657 }
658 if( libcdata_array_get_number_of_entries(
659 internal_list->elements_array,
660 &number_of_elements,
661 error ) != 1 )
662 {
663 libcerror_error_set(
664 error,
665 LIBCERROR_ERROR_DOMAIN_RUNTIME,
666 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
667 "%s: unable to retrieve number of elements from elements array.",
668 function );
669
670 return( -1 );
671 }
672 for( element_index = 0;
673 element_index < number_of_elements;
674 element_index++ )
675 {
676 if( libcdata_array_get_entry_by_index(
677 internal_list->elements_array,
678 element_index,
679 (intptr_t **) &list_element,
680 error ) != 1 )
681 {
682 libcerror_error_set(
683 error,
684 LIBCERROR_ERROR_DOMAIN_RUNTIME,
685 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
686 "%s: unable to retrieve entry: %d from elements array.",
687 function,
688 element_index );
689
690 return( -1 );
691 }
692 if( libfdata_list_element_set_element_index(
693 list_element,
694 element_index,
695 error ) != 1 )
696 {
697 libcerror_error_set(
698 error,
699 LIBCERROR_ERROR_DOMAIN_RUNTIME,
700 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
701 "%s: unable to set list element: %d index.",
702 function,
703 element_index );
704
705 return( -1 );
706 }
707 }
708 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
709
710 return( 1 );
711 }
712
713 /* Retrieves the number of elements of the list
714 * Returns 1 if successful or -1 on error
715 */
libfdata_list_get_number_of_elements(libfdata_list_t * list,int * number_of_elements,libcerror_error_t ** error)716 int libfdata_list_get_number_of_elements(
717 libfdata_list_t *list,
718 int *number_of_elements,
719 libcerror_error_t **error )
720 {
721 libfdata_internal_list_t *internal_list = NULL;
722 static char *function = "libfdata_list_get_number_of_elements";
723
724 if( list == NULL )
725 {
726 libcerror_error_set(
727 error,
728 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
729 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
730 "%s: invalid list.",
731 function );
732
733 return( -1 );
734 }
735 internal_list = (libfdata_internal_list_t *) list;
736
737 if( libcdata_array_get_number_of_entries(
738 internal_list->elements_array,
739 number_of_elements,
740 error ) != 1 )
741 {
742 libcerror_error_set(
743 error,
744 LIBCERROR_ERROR_DOMAIN_RUNTIME,
745 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
746 "%s: unable to retrieve number of elements from elements array.",
747 function );
748
749 return( -1 );
750 }
751 return( 1 );
752 }
753
754 /* Retrieves a specific list element
755 * Returns 1 if successful or -1 on error
756 */
libfdata_list_get_list_element_by_index(libfdata_list_t * list,int element_index,libfdata_list_element_t ** element,libcerror_error_t ** error)757 int libfdata_list_get_list_element_by_index(
758 libfdata_list_t *list,
759 int element_index,
760 libfdata_list_element_t **element,
761 libcerror_error_t **error )
762 {
763 libfdata_internal_list_t *internal_list = NULL;
764 static char *function = "libfdata_list_get_list_element_by_index";
765
766 if( list == NULL )
767 {
768 libcerror_error_set(
769 error,
770 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
771 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
772 "%s: invalid list.",
773 function );
774
775 return( -1 );
776 }
777 internal_list = (libfdata_internal_list_t *) list;
778
779 if( libcdata_array_get_entry_by_index(
780 internal_list->elements_array,
781 element_index,
782 (intptr_t **) element,
783 error ) != 1 )
784 {
785 libcerror_error_set(
786 error,
787 LIBCERROR_ERROR_DOMAIN_RUNTIME,
788 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
789 "%s: unable to retrieve entry: %d from elements array.",
790 function,
791 element_index );
792
793 return( -1 );
794 }
795 internal_list->current_element_index = element_index;
796
797 return( 1 );
798 }
799
800 /* Retrieves the data range of a specific element
801 * Returns 1 if successful or -1 on error
802 */
libfdata_list_get_element_by_index(libfdata_list_t * list,int element_index,int * element_file_index,off64_t * element_offset,size64_t * element_size,uint32_t * element_flags,libcerror_error_t ** error)803 int libfdata_list_get_element_by_index(
804 libfdata_list_t *list,
805 int element_index,
806 int *element_file_index,
807 off64_t *element_offset,
808 size64_t *element_size,
809 uint32_t *element_flags,
810 libcerror_error_t **error )
811 {
812 libfdata_internal_list_t *internal_list = NULL;
813 libfdata_list_element_t *list_element = NULL;
814 static char *function = "libfdata_list_get_element_by_index";
815
816 if( list == NULL )
817 {
818 libcerror_error_set(
819 error,
820 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
821 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
822 "%s: invalid list.",
823 function );
824
825 return( -1 );
826 }
827 internal_list = (libfdata_internal_list_t *) list;
828
829 if( libcdata_array_get_entry_by_index(
830 internal_list->elements_array,
831 element_index,
832 (intptr_t **) &list_element,
833 error ) != 1 )
834 {
835 libcerror_error_set(
836 error,
837 LIBCERROR_ERROR_DOMAIN_RUNTIME,
838 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
839 "%s: unable to retrieve entry: %d from elements array.",
840 function,
841 element_index );
842
843 return( -1 );
844 }
845 if( libfdata_list_element_get_data_range(
846 list_element,
847 element_file_index,
848 element_offset,
849 element_size,
850 element_flags,
851 error ) != 1 )
852 {
853 libcerror_error_set(
854 error,
855 LIBCERROR_ERROR_DOMAIN_RUNTIME,
856 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
857 "%s: unable to retrieve data range from list element: %d.",
858 function,
859 element_index );
860
861 return( -1 );
862 }
863 internal_list->current_element_index = element_index;
864
865 return( 1 );
866 }
867
868 /* Sets the data range of a specific element
869 * Returns 1 if successful or -1 on error
870 */
libfdata_list_set_element_by_index(libfdata_list_t * list,int element_index,int element_file_index,off64_t element_offset,size64_t element_size,uint32_t element_flags,libcerror_error_t ** error)871 int libfdata_list_set_element_by_index(
872 libfdata_list_t *list,
873 int element_index,
874 int element_file_index,
875 off64_t element_offset,
876 size64_t element_size,
877 uint32_t element_flags,
878 libcerror_error_t **error )
879 {
880 libfdata_internal_list_t *internal_list = NULL;
881 libfdata_list_element_t *list_element = NULL;
882 libfdata_mapped_range_t *mapped_range = NULL;
883 static char *function = "libfdata_list_set_element_by_index";
884 off64_t previous_element_offset = 0;
885 size64_t mapped_size = 0;
886 size64_t previous_element_size = 0;
887 uint32_t previous_element_flags = 0;
888 int previous_element_file_index = 0;
889 int result = 0;
890
891 #if defined( HAVE_DEBUG_OUTPUT )
892 off64_t mapped_range_offset = 0;
893 size64_t mapped_range_size = 0;
894 #endif
895
896 if( list == NULL )
897 {
898 libcerror_error_set(
899 error,
900 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
901 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
902 "%s: invalid list.",
903 function );
904
905 return( -1 );
906 }
907 internal_list = (libfdata_internal_list_t *) list;
908
909 if( libcdata_array_get_entry_by_index(
910 internal_list->elements_array,
911 element_index,
912 (intptr_t **) &list_element,
913 error ) != 1 )
914 {
915 libcerror_error_set(
916 error,
917 LIBCERROR_ERROR_DOMAIN_RUNTIME,
918 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
919 "%s: unable to retrieve entry: %d from elements array.",
920 function,
921 element_index );
922
923 return( -1 );
924 }
925 if( list_element == NULL )
926 {
927 if( libfdata_list_element_initialize(
928 &list_element,
929 list,
930 element_index,
931 error ) != 1 )
932 {
933 libcerror_error_set(
934 error,
935 LIBCERROR_ERROR_DOMAIN_RUNTIME,
936 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
937 "%s: unable to create list element.",
938 function );
939
940 return( -1 );
941 }
942 if( libcdata_array_set_entry_by_index(
943 internal_list->elements_array,
944 element_index,
945 (intptr_t *) list_element,
946 error ) != 1 )
947 {
948 libcerror_error_set(
949 error,
950 LIBCERROR_ERROR_DOMAIN_RUNTIME,
951 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
952 "%s: unable to set entry: %d in elements array.",
953 function,
954 element_index );
955
956 libfdata_list_element_free(
957 &list_element,
958 NULL );
959
960 return( -1 );
961 }
962 }
963 else
964 {
965 result = libfdata_list_element_get_mapped_size(
966 list_element,
967 &mapped_size,
968 error );
969
970 if( result == -1 )
971 {
972 libcerror_error_set(
973 error,
974 LIBCERROR_ERROR_DOMAIN_RUNTIME,
975 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
976 "%s: unable to retrieve mapped size of list element: %d.",
977 function,
978 element_index );
979
980 return( -1 );
981 }
982 else if( result == 0 )
983 {
984 if( libfdata_list_element_get_data_range(
985 list_element,
986 &previous_element_file_index,
987 &previous_element_offset,
988 &previous_element_size,
989 &previous_element_flags,
990 error ) != 1 )
991 {
992 libcerror_error_set(
993 error,
994 LIBCERROR_ERROR_DOMAIN_RUNTIME,
995 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
996 "%s: unable to retrieve data range of list element: %d.",
997 function,
998 element_index );
999
1000 return( -1 );
1001 }
1002 }
1003 }
1004 if( libfdata_list_element_set_data_range(
1005 list_element,
1006 element_file_index,
1007 element_offset,
1008 element_size,
1009 element_flags,
1010 error ) != 1 )
1011 {
1012 libcerror_error_set(
1013 error,
1014 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1015 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1016 "%s: unable to set data range of list element: %d.",
1017 function,
1018 element_index );
1019
1020 return( -1 );
1021 }
1022 /* Make sure the list has a mapped range entry for every element
1023 */
1024 if( libcdata_array_get_entry_by_index(
1025 internal_list->mapped_ranges_array,
1026 element_index,
1027 (intptr_t **) &mapped_range,
1028 error ) != 1 )
1029 {
1030 libcerror_error_set(
1031 error,
1032 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1033 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1034 "%s: unable to retrieve entry: %d from mapped ranges array.",
1035 function,
1036 element_index );
1037
1038 return( -1 );
1039 }
1040 if( mapped_range == NULL )
1041 {
1042 if( libfdata_mapped_range_initialize(
1043 &mapped_range,
1044 error ) != 1 )
1045 {
1046 libcerror_error_set(
1047 error,
1048 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1049 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1050 "%s: unable to create mapped range.",
1051 function );
1052
1053 return( -1 );
1054 }
1055 if( libcdata_array_set_entry_by_index(
1056 internal_list->mapped_ranges_array,
1057 element_index,
1058 (intptr_t *) mapped_range,
1059 error ) != 1 )
1060 {
1061 libcerror_error_set(
1062 error,
1063 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1064 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1065 "%s: unable to set entry: %d in mapped ranges array.",
1066 function,
1067 element_index );
1068
1069 libfdata_mapped_range_free(
1070 &mapped_range,
1071 NULL );
1072
1073 return( -1 );
1074 }
1075 internal_list->size += element_size;
1076 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
1077 }
1078 /* If the size of the element is mapped or if the element size did not change
1079 * there is no need to recalculate the mapped range
1080 */
1081 else if( ( mapped_size == 0 )
1082 && ( previous_element_size != element_size ) )
1083 {
1084 internal_list->size -= previous_element_size;
1085 internal_list->size += element_size;
1086 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
1087 }
1088 #if defined( HAVE_DEBUG_OUTPUT )
1089 if( libcnotify_verbose != 0 )
1090 {
1091 libcnotify_printf(
1092 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1093 function,
1094 element_index,
1095 element_file_index,
1096 element_offset,
1097 element_offset + element_size,
1098 element_offset,
1099 element_offset + element_size,
1100 element_size );
1101
1102 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) == 0 )
1103 {
1104 if( libfdata_mapped_range_get(
1105 mapped_range,
1106 &mapped_range_offset,
1107 &mapped_range_size,
1108 error ) != 1 )
1109 {
1110 libcerror_error_set(
1111 error,
1112 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1113 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1114 "%s: unable to retrieve values from mapped range: %d.",
1115 function,
1116 element_index );
1117
1118 return( -1 );
1119 }
1120 libcnotify_printf(
1121 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1122 function,
1123 element_index,
1124 mapped_range_offset,
1125 mapped_range_offset + mapped_range_size,
1126 mapped_range_offset,
1127 mapped_range_offset + mapped_range_size,
1128 mapped_range_size );
1129 }
1130 libcnotify_printf(
1131 "\n" );
1132 }
1133 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1134
1135 internal_list->current_element_index = element_index;
1136
1137 return( 1 );
1138 }
1139
1140 /* Prepends an element data range
1141 * Returns 1 if successful or -1 on error
1142 */
libfdata_list_prepend_element(libfdata_list_t * list,int element_file_index,off64_t element_offset,size64_t element_size,uint32_t element_flags,libcerror_error_t ** error)1143 int libfdata_list_prepend_element(
1144 libfdata_list_t *list,
1145 int element_file_index,
1146 off64_t element_offset,
1147 size64_t element_size,
1148 uint32_t element_flags,
1149 libcerror_error_t **error )
1150 {
1151 libfdata_internal_list_t *internal_list = NULL;
1152 libfdata_list_element_t *list_element = NULL;
1153 libfdata_mapped_range_t *mapped_range = NULL;
1154 static char *function = "libfdata_list_prepend_element";
1155 off64_t mapped_offset = 0;
1156 int element_index = 0;
1157 int mapped_range_index = -1;
1158 int number_of_elements = 0;
1159
1160 if( list == NULL )
1161 {
1162 libcerror_error_set(
1163 error,
1164 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1165 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1166 "%s: invalid list.",
1167 function );
1168
1169 return( -1 );
1170 }
1171 internal_list = (libfdata_internal_list_t *) list;
1172
1173 if( libfdata_mapped_range_initialize(
1174 &mapped_range,
1175 error ) != 1 )
1176 {
1177 libcerror_error_set(
1178 error,
1179 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1180 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1181 "%s: unable to create mapped range.",
1182 function );
1183
1184 goto on_error;
1185 }
1186 mapped_offset = internal_list->mapped_offset + (off64_t) internal_list->size;
1187
1188 if( libfdata_mapped_range_set(
1189 mapped_range,
1190 mapped_offset,
1191 element_size,
1192 error ) != 1 )
1193 {
1194 libcerror_error_set(
1195 error,
1196 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1197 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1198 "%s: unable to set mapped range values.",
1199 function );
1200
1201 goto on_error;
1202 }
1203 if( libcdata_array_append_entry(
1204 internal_list->mapped_ranges_array,
1205 &mapped_range_index,
1206 (intptr_t *) mapped_range,
1207 error ) != 1 )
1208 {
1209 libcerror_error_set(
1210 error,
1211 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1212 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1213 "%s: unable to append mapped range to array.",
1214 function );
1215
1216 goto on_error;
1217 }
1218 if( libfdata_list_element_initialize(
1219 &list_element,
1220 list,
1221 0,
1222 error ) != 1 )
1223 {
1224 libcerror_error_set(
1225 error,
1226 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1227 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1228 "%s: unable to create list element.",
1229 function );
1230
1231 goto on_error;
1232 }
1233 if( libfdata_list_element_set_data_range(
1234 list_element,
1235 element_file_index,
1236 element_offset,
1237 element_size,
1238 element_flags,
1239 error ) != 1 )
1240 {
1241 libcerror_error_set(
1242 error,
1243 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1244 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1245 "%s: unable to set data range of list element.",
1246 function );
1247
1248 goto on_error;
1249 }
1250 if( libcdata_array_prepend_entry(
1251 internal_list->elements_array,
1252 (intptr_t *) list_element,
1253 error ) != 1 )
1254 {
1255 libcerror_error_set(
1256 error,
1257 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1258 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1259 "%s: unable to prepend list element to elements array.",
1260 function );
1261
1262 goto on_error;
1263 }
1264 mapped_range_index = -1;
1265 mapped_range = NULL;
1266
1267 if( libcdata_array_get_number_of_entries(
1268 internal_list->elements_array,
1269 &number_of_elements,
1270 error ) != 1 )
1271 {
1272 libcerror_error_set(
1273 error,
1274 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1275 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1276 "%s: unable to retrieve number of entries from elements array.",
1277 function );
1278
1279 goto on_error;
1280 }
1281 for( element_index = 0;
1282 element_index < number_of_elements;
1283 element_index++ )
1284 {
1285 if( libcdata_array_get_entry_by_index(
1286 internal_list->elements_array,
1287 element_index,
1288 (intptr_t **) &list_element,
1289 error ) != 1 )
1290 {
1291 libcerror_error_set(
1292 error,
1293 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1294 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1295 "%s: unable to retrieve entry: %d from elements array.",
1296 function,
1297 element_index );
1298
1299 list_element = NULL;
1300
1301 goto on_error;
1302 }
1303 if( libfdata_list_element_set_element_index(
1304 list_element,
1305 element_index,
1306 error ) != 1 )
1307 {
1308 libcerror_error_set(
1309 error,
1310 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1311 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1312 "%s: unable to set list element: %d index.",
1313 function,
1314 element_index );
1315
1316 list_element = NULL;
1317
1318 goto on_error;
1319 }
1320 }
1321 internal_list->current_element_index = 0;
1322 internal_list->size += element_size;
1323 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
1324
1325 return( 1 );
1326
1327 on_error:
1328 if( list_element != NULL )
1329 {
1330 libfdata_list_element_free(
1331 &list_element,
1332 NULL );
1333 }
1334 if( mapped_range_index != -1 )
1335 {
1336 libcdata_array_set_entry_by_index(
1337 internal_list->mapped_ranges_array,
1338 mapped_range_index,
1339 NULL,
1340 NULL );
1341 }
1342 if( mapped_range != NULL )
1343 {
1344 libfdata_mapped_range_free(
1345 &mapped_range,
1346 NULL );
1347 }
1348 return( -1 );
1349 }
1350
1351 /* Appends an element data range
1352 * Returns 1 if successful or -1 on error
1353 */
libfdata_list_append_element(libfdata_list_t * list,int * element_index,int element_file_index,off64_t element_offset,size64_t element_size,uint32_t element_flags,libcerror_error_t ** error)1354 int libfdata_list_append_element(
1355 libfdata_list_t *list,
1356 int *element_index,
1357 int element_file_index,
1358 off64_t element_offset,
1359 size64_t element_size,
1360 uint32_t element_flags,
1361 libcerror_error_t **error )
1362 {
1363 libfdata_internal_list_t *internal_list = NULL;
1364 libfdata_list_element_t *list_element = NULL;
1365 libfdata_mapped_range_t *mapped_range = NULL;
1366 static char *function = "libfdata_list_append_element";
1367 off64_t mapped_offset = 0;
1368 int mapped_range_index = -1;
1369
1370 if( list == NULL )
1371 {
1372 libcerror_error_set(
1373 error,
1374 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1375 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1376 "%s: invalid list.",
1377 function );
1378
1379 return( -1 );
1380 }
1381 internal_list = (libfdata_internal_list_t *) list;
1382
1383 if( element_index == NULL )
1384 {
1385 libcerror_error_set(
1386 error,
1387 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1388 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1389 "%s: invalid element index.",
1390 function );
1391
1392 return( -1 );
1393 }
1394 if( libfdata_mapped_range_initialize(
1395 &mapped_range,
1396 error ) != 1 )
1397 {
1398 libcerror_error_set(
1399 error,
1400 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1402 "%s: unable to create mapped range.",
1403 function );
1404
1405 goto on_error;
1406 }
1407 mapped_offset = internal_list->mapped_offset + (off64_t) internal_list->size;
1408
1409 if( libfdata_mapped_range_set(
1410 mapped_range,
1411 mapped_offset,
1412 element_size,
1413 error ) != 1 )
1414 {
1415 libcerror_error_set(
1416 error,
1417 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1418 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1419 "%s: unable to set mapped range values.",
1420 function );
1421
1422 goto on_error;
1423 }
1424 if( libcdata_array_append_entry(
1425 internal_list->mapped_ranges_array,
1426 &mapped_range_index,
1427 (intptr_t *) mapped_range,
1428 error ) != 1 )
1429 {
1430 libcerror_error_set(
1431 error,
1432 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1433 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1434 "%s: unable to append mapped range to array.",
1435 function );
1436
1437 goto on_error;
1438 }
1439 if( libfdata_list_element_initialize(
1440 &list_element,
1441 list,
1442 0,
1443 error ) != 1 )
1444 {
1445 libcerror_error_set(
1446 error,
1447 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1448 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1449 "%s: unable to create list element.",
1450 function );
1451
1452 goto on_error;
1453 }
1454 if( libfdata_list_element_set_data_range(
1455 list_element,
1456 element_file_index,
1457 element_offset,
1458 element_size,
1459 element_flags,
1460 error ) != 1 )
1461 {
1462 libcerror_error_set(
1463 error,
1464 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1465 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1466 "%s: unable to set data range of list element.",
1467 function );
1468
1469 goto on_error;
1470 }
1471 if( libcdata_array_append_entry(
1472 internal_list->elements_array,
1473 element_index,
1474 (intptr_t *) list_element,
1475 error ) != 1 )
1476 {
1477 libcerror_error_set(
1478 error,
1479 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1480 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1481 "%s: unable to append list element to elements array.",
1482 function );
1483
1484 goto on_error;
1485 }
1486 mapped_range_index = -1;
1487 mapped_range = NULL;
1488
1489 if( libfdata_list_element_set_element_index(
1490 list_element,
1491 *element_index,
1492 error ) != 1 )
1493 {
1494 libcerror_error_set(
1495 error,
1496 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1497 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1498 "%s: unable to set list element index.",
1499 function );
1500
1501 list_element = NULL;
1502
1503 goto on_error;
1504 }
1505 #if defined( HAVE_DEBUG_OUTPUT )
1506 if( libcnotify_verbose != 0 )
1507 {
1508 libcnotify_printf(
1509 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1510 function,
1511 *element_index,
1512 element_file_index,
1513 element_offset,
1514 element_offset + element_size,
1515 element_offset,
1516 element_offset + element_size,
1517 element_size );
1518
1519 libcnotify_printf(
1520 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1521 function,
1522 *element_index,
1523 mapped_offset,
1524 mapped_offset + element_size,
1525 mapped_offset,
1526 mapped_offset + element_size,
1527 element_size );
1528
1529 libcnotify_printf(
1530 "\n" );
1531 }
1532 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1533
1534 internal_list->current_element_index = *element_index;
1535 internal_list->size += element_size;
1536
1537 return( 1 );
1538
1539 on_error:
1540 if( list_element != NULL )
1541 {
1542 libfdata_list_element_free(
1543 &list_element,
1544 NULL );
1545 }
1546 if( mapped_range_index != -1 )
1547 {
1548 libcdata_array_set_entry_by_index(
1549 internal_list->mapped_ranges_array,
1550 mapped_range_index,
1551 NULL,
1552 NULL );
1553 }
1554 if( mapped_range != NULL )
1555 {
1556 libfdata_mapped_range_free(
1557 &mapped_range,
1558 NULL );
1559 }
1560 return( -1 );
1561 }
1562
1563 /* Appends the element of the source list to the list
1564 * The source list is emptied if successful
1565 * Returns 1 if successful or -1 on error
1566 */
libfdata_list_append_list(libfdata_list_t * list,libfdata_list_t * source_list,libcerror_error_t ** error)1567 int libfdata_list_append_list(
1568 libfdata_list_t *list,
1569 libfdata_list_t *source_list,
1570 libcerror_error_t **error )
1571 {
1572 libfdata_internal_list_t *internal_list = NULL;
1573 libfdata_internal_list_t *internal_source_list = NULL;
1574 libfdata_list_element_t *list_element = NULL;
1575 libfdata_mapped_range_t *mapped_range = NULL;
1576 static char *function = "libfdata_list_append_list";
1577 off64_t mapped_range_offset = 0;
1578 size64_t mapped_range_size = 0;
1579 int element_index = 0;
1580 int new_number_of_elements = 0;
1581 int number_of_elements = 0;
1582 int result = 1;
1583 int source_element_index = 0;
1584 int source_number_of_elements = 0;
1585
1586 if( list == NULL )
1587 {
1588 libcerror_error_set(
1589 error,
1590 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1591 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1592 "%s: invalid list.",
1593 function );
1594
1595 return( -1 );
1596 }
1597 internal_list = (libfdata_internal_list_t *) list;
1598
1599 if( source_list == NULL )
1600 {
1601 libcerror_error_set(
1602 error,
1603 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1604 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1605 "%s: invalid source list.",
1606 function );
1607
1608 return( -1 );
1609 }
1610 internal_source_list = (libfdata_internal_list_t *) source_list;
1611
1612 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1613 {
1614 if( libfdata_list_calculate_mapped_ranges(
1615 internal_list,
1616 error ) != 1 )
1617 {
1618 libcerror_error_set(
1619 error,
1620 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1621 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1622 "%s: unable to calculate mapped ranges.",
1623 function );
1624
1625 goto on_error;
1626 }
1627 }
1628 if( ( internal_source_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1629 {
1630 if( libfdata_list_calculate_mapped_ranges(
1631 internal_source_list,
1632 error ) != 1 )
1633 {
1634 libcerror_error_set(
1635 error,
1636 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1637 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1638 "%s: unable to calculate mapped ranges of source list.",
1639 function );
1640
1641 goto on_error;
1642 }
1643 }
1644 if( ( internal_list->mapped_offset != 0 )
1645 || ( internal_source_list->mapped_offset != 0 ) )
1646 {
1647 if( ( (size64_t) internal_list->mapped_offset + internal_list->size ) != (size64_t) internal_source_list->mapped_offset )
1648 {
1649 libcerror_error_set(
1650 error,
1651 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1652 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1653 "%s: invalid source mapped offset value out of bounds.",
1654 function );
1655
1656 goto on_error;
1657 }
1658 }
1659 #if defined( HAVE_DEBUG_OUTPUT )
1660 if( libcnotify_verbose != 0 )
1661 {
1662 libcnotify_printf(
1663 "%s: appending source list with mapped offset: %" PRIi64 " and size: %" PRIu64 " to list with mapped offset: %" PRIi64 " and size: %" PRIu64 "\n",
1664 function,
1665 internal_source_list->mapped_offset,
1666 internal_source_list->size,
1667 internal_list->mapped_offset,
1668 internal_list->size );
1669 }
1670 #endif
1671 if( libcdata_array_get_number_of_entries(
1672 internal_list->elements_array,
1673 &number_of_elements,
1674 error ) != 1 )
1675 {
1676 libcerror_error_set(
1677 error,
1678 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1679 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1680 "%s: unable to retrieve number of elements from elements array.",
1681 function );
1682
1683 goto on_error;
1684 }
1685 if( libcdata_array_get_number_of_entries(
1686 internal_source_list->elements_array,
1687 &source_number_of_elements,
1688 error ) != 1 )
1689 {
1690 libcerror_error_set(
1691 error,
1692 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1693 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1694 "%s: unable to retrieve number of elements from source list elements array.",
1695 function );
1696
1697 goto on_error;
1698 }
1699 element_index = number_of_elements;
1700 new_number_of_elements = number_of_elements + source_number_of_elements;
1701
1702 if( libcdata_array_resize(
1703 internal_list->elements_array,
1704 new_number_of_elements,
1705 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_list_element_free,
1706 error ) != 1 )
1707 {
1708 libcerror_error_set(
1709 error,
1710 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1711 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1712 "%s: unable to resize elements array.",
1713 function );
1714
1715 goto on_error;
1716 }
1717 if( libcdata_array_resize(
1718 internal_list->mapped_ranges_array,
1719 new_number_of_elements,
1720 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
1721 error ) != 1 )
1722 {
1723 libcerror_error_set(
1724 error,
1725 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1726 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1727 "%s: unable to resize mapped ranges array.",
1728 function );
1729
1730 goto on_error;
1731 }
1732 for( source_element_index = 0;
1733 source_element_index < source_number_of_elements;
1734 source_element_index++ )
1735 {
1736 if( libcdata_array_get_entry_by_index(
1737 internal_source_list->elements_array,
1738 source_element_index,
1739 (intptr_t **) &list_element,
1740 error ) != 1 )
1741 {
1742 libcerror_error_set(
1743 error,
1744 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1745 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1746 "%s: unable to retrieve entry: %d from source list elements array.",
1747 function,
1748 source_element_index );
1749
1750 goto on_error;
1751 }
1752 if( libcdata_array_set_entry_by_index(
1753 internal_list->elements_array,
1754 element_index,
1755 (intptr_t *) list_element,
1756 error ) != 1 )
1757 {
1758 libcerror_error_set(
1759 error,
1760 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1761 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1762 "%s: unable to set entry: %d in elements array.",
1763 function,
1764 element_index );
1765
1766 goto on_error;
1767 }
1768 if( libcdata_array_get_entry_by_index(
1769 internal_source_list->mapped_ranges_array,
1770 source_element_index,
1771 (intptr_t **) &mapped_range,
1772 error ) != 1 )
1773 {
1774 libcerror_error_set(
1775 error,
1776 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1777 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1778 "%s: unable to retrieve entry: %d from source list mapped ranges array.",
1779 function,
1780 source_element_index );
1781
1782 goto on_error;
1783 }
1784 if( libcdata_array_set_entry_by_index(
1785 internal_list->mapped_ranges_array,
1786 element_index,
1787 (intptr_t *) mapped_range,
1788 error ) != 1 )
1789 {
1790 libcerror_error_set(
1791 error,
1792 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1793 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1794 "%s: unable to set entry: %d in mapped ranges array.",
1795 function,
1796 element_index );
1797
1798 goto on_error;
1799 }
1800 element_index++;
1801 }
1802 element_index = number_of_elements;
1803 number_of_elements = new_number_of_elements;
1804 new_number_of_elements = 0;
1805
1806 if( libcdata_array_empty(
1807 internal_source_list->elements_array,
1808 NULL,
1809 error ) != 1 )
1810 {
1811 libcerror_error_set(
1812 error,
1813 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1814 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1815 "%s: unable to empty source list elements array.",
1816 function );
1817
1818 result = -1;
1819 }
1820 if( libcdata_array_empty(
1821 internal_source_list->mapped_ranges_array,
1822 NULL,
1823 error ) != 1 )
1824 {
1825 libcerror_error_set(
1826 error,
1827 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1828 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1829 "%s: unable to empty source list mapped ranges array.",
1830 function );
1831
1832 result = -1;
1833 }
1834 internal_source_list->size = 0;
1835
1836 while( element_index < number_of_elements )
1837 {
1838 if( libcdata_array_get_entry_by_index(
1839 internal_list->elements_array,
1840 element_index,
1841 (intptr_t **) &list_element,
1842 error ) != 1 )
1843 {
1844 libcerror_error_set(
1845 error,
1846 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1847 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1848 "%s: unable to retrieve entry: %d from elements array.",
1849 function,
1850 element_index );
1851
1852 goto on_error;
1853 }
1854 ( (libfdata_internal_list_element_t *) list_element )->list = list;
1855 ( (libfdata_internal_list_element_t *) list_element )->element_index = element_index;
1856
1857 if( libcdata_array_get_entry_by_index(
1858 internal_list->mapped_ranges_array,
1859 element_index,
1860 (intptr_t **) &mapped_range,
1861 error ) != 1 )
1862 {
1863 libcerror_error_set(
1864 error,
1865 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1866 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1867 "%s: unable to retrieve entry: %d from mapped ranges array.",
1868 function,
1869 element_index );
1870
1871 goto on_error;
1872 }
1873 if( libfdata_mapped_range_get(
1874 mapped_range,
1875 &mapped_range_offset,
1876 &mapped_range_size,
1877 error ) != 1 )
1878 {
1879 libcerror_error_set(
1880 error,
1881 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1882 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1883 "%s: unable to retrieve values from mapped range: %d.",
1884 function,
1885 element_index );
1886
1887 goto on_error;
1888 }
1889 if( libfdata_mapped_range_set(
1890 mapped_range,
1891 internal_list->size,
1892 mapped_range_size,
1893 error ) != 1 )
1894 {
1895 libcerror_error_set(
1896 error,
1897 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1898 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1899 "%s: unable to set values of mapped range: %d.",
1900 function,
1901 element_index );
1902
1903 goto on_error;
1904 }
1905 internal_list->size += mapped_range_size;
1906
1907 element_index++;
1908 }
1909 #if defined( HAVE_DEBUG_OUTPUT )
1910 if( libcnotify_verbose != 0 )
1911 {
1912 libcnotify_printf(
1913 "\n" );
1914 }
1915 #endif
1916 return( result );
1917
1918 on_error:
1919 if( new_number_of_elements != 0 )
1920 {
1921 libcdata_array_resize(
1922 internal_list->mapped_ranges_array,
1923 number_of_elements,
1924 NULL,
1925 NULL );
1926
1927 libcdata_array_resize(
1928 internal_list->elements_array,
1929 number_of_elements,
1930 NULL,
1931 NULL );
1932 }
1933 return( -1 );
1934 }
1935
1936 /* Determines if a specific element is set
1937 * Returns 1 if element is set, 0 if not or -1 on error
1938 */
libfdata_list_is_element_set(libfdata_list_t * list,int element_index,libcerror_error_t ** error)1939 int libfdata_list_is_element_set(
1940 libfdata_list_t *list,
1941 int element_index,
1942 libcerror_error_t **error )
1943 {
1944 libfdata_internal_list_t *internal_list = NULL;
1945 libfdata_list_element_t *list_element = NULL;
1946 static char *function = "libfdata_list_is_element_set";
1947
1948 if( list == NULL )
1949 {
1950 libcerror_error_set(
1951 error,
1952 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1953 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1954 "%s: invalid list.",
1955 function );
1956
1957 return( -1 );
1958 }
1959 internal_list = (libfdata_internal_list_t *) list;
1960
1961 if( libcdata_array_get_entry_by_index(
1962 internal_list->elements_array,
1963 element_index,
1964 (intptr_t **) &list_element,
1965 error ) != 1 )
1966 {
1967 libcerror_error_set(
1968 error,
1969 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1970 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1971 "%s: unable to retrieve entry: %d from elements array.",
1972 function,
1973 element_index );
1974
1975 return( -1 );
1976 }
1977 if( list_element == NULL )
1978 {
1979 return( 0 );
1980 }
1981 internal_list->current_element_index = element_index;
1982
1983 return( 1 );
1984 }
1985
1986 /* Mapped range functions
1987 */
1988
1989 /* Retrieves the mapped range of a specific element
1990 * Returns 1 if successful or -1 on error
1991 */
libfdata_list_get_element_mapped_range(libfdata_list_t * list,int element_index,off64_t * mapped_range_offset,size64_t * mapped_range_size,libcerror_error_t ** error)1992 int libfdata_list_get_element_mapped_range(
1993 libfdata_list_t *list,
1994 int element_index,
1995 off64_t *mapped_range_offset,
1996 size64_t *mapped_range_size,
1997 libcerror_error_t **error )
1998 {
1999 libfdata_internal_list_t *internal_list = NULL;
2000 libfdata_mapped_range_t *mapped_range = NULL;
2001 static char *function = "libfdata_list_get_element_mapped_range";
2002
2003 if( list == NULL )
2004 {
2005 libcerror_error_set(
2006 error,
2007 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2008 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2009 "%s: invalid list.",
2010 function );
2011
2012 return( -1 );
2013 }
2014 internal_list = (libfdata_internal_list_t *) list;
2015
2016 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
2017 {
2018 if( libfdata_list_calculate_mapped_ranges(
2019 internal_list,
2020 error ) != 1 )
2021 {
2022 libcerror_error_set(
2023 error,
2024 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2025 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2026 "%s: unable to calculate mapped ranges.",
2027 function );
2028
2029 return( -1 );
2030 }
2031 }
2032 if( libcdata_array_get_entry_by_index(
2033 internal_list->mapped_ranges_array,
2034 element_index,
2035 (intptr_t **) &mapped_range,
2036 error ) != 1 )
2037 {
2038 libcerror_error_set(
2039 error,
2040 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2041 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2042 "%s: unable to retrieve entry: %d from mapped ranges array.",
2043 function,
2044 element_index );
2045
2046 return( -1 );
2047 }
2048 if( libfdata_mapped_range_get(
2049 mapped_range,
2050 mapped_range_offset,
2051 mapped_range_size,
2052 error ) != 1 )
2053 {
2054 libcerror_error_set(
2055 error,
2056 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2057 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2058 "%s: unable to retrieve values from mapped range: %d.",
2059 function,
2060 element_index );
2061
2062 return( -1 );
2063 }
2064 return( 1 );
2065 }
2066
2067 /* Retrieves the mapped offset
2068 * Returns 1 if successful, 0 if not set or -1 on error
2069 */
libfdata_list_get_mapped_offset(libfdata_list_t * list,off64_t * mapped_offset,libcerror_error_t ** error)2070 int libfdata_list_get_mapped_offset(
2071 libfdata_list_t *list,
2072 off64_t *mapped_offset,
2073 libcerror_error_t **error )
2074 {
2075 libfdata_internal_list_t *internal_list = NULL;
2076 static char *function = "libfdata_list_get_mapped_offset";
2077
2078 if( list == NULL )
2079 {
2080 libcerror_error_set(
2081 error,
2082 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2083 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2084 "%s: invalid list.",
2085 function );
2086
2087 return( -1 );
2088 }
2089 internal_list = (libfdata_internal_list_t *) list;
2090
2091 if( mapped_offset == NULL )
2092 {
2093 libcerror_error_set(
2094 error,
2095 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2096 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2097 "%s: invalid mapped offset.",
2098 function );
2099
2100 return( -1 );
2101 }
2102 if( ( internal_list->flags & LIBFDATA_LIST_FLAG_HAS_MAPPED_OFFSET ) == 0 )
2103 {
2104 return( 0 );
2105 }
2106 *mapped_offset = internal_list->mapped_offset;
2107
2108 return( 1 );
2109 }
2110
2111 /* Sets the mapped offset
2112 * Returns 1 if successful or -1 on error
2113 */
libfdata_list_set_mapped_offset(libfdata_list_t * list,off64_t mapped_offset,libcerror_error_t ** error)2114 int libfdata_list_set_mapped_offset(
2115 libfdata_list_t *list,
2116 off64_t mapped_offset,
2117 libcerror_error_t **error )
2118 {
2119 libfdata_internal_list_t *internal_list = NULL;
2120 static char *function = "libfdata_list_set_mapped_offset";
2121
2122 if( list == NULL )
2123 {
2124 libcerror_error_set(
2125 error,
2126 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2127 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2128 "%s: invalid list.",
2129 function );
2130
2131 return( -1 );
2132 }
2133 internal_list = (libfdata_internal_list_t *) list;
2134
2135 if( mapped_offset < 0 )
2136 {
2137 libcerror_error_set(
2138 error,
2139 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2140 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2141 "%s: invalid offset value out of bounds.",
2142 function );
2143
2144 return( -1 );
2145 }
2146 #if defined( HAVE_DEBUG_OUTPUT )
2147 if( libcnotify_verbose != 0 )
2148 {
2149 libcnotify_printf(
2150 "%s: mapped offset: %" PRIi64 "\n",
2151 function,
2152 mapped_offset );
2153
2154 libcnotify_printf(
2155 "\n" );
2156 }
2157 #endif
2158 internal_list->mapped_offset = mapped_offset;
2159 internal_list->flags |= LIBFDATA_LIST_FLAG_HAS_MAPPED_OFFSET | LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
2160
2161 return( 1 );
2162 }
2163
2164 /* Retrieves the mapped size of a specific element
2165 * Returns 1 if successful, 0 if not set or -1 on error
2166 */
libfdata_list_get_mapped_size_by_index(libfdata_list_t * list,int element_index,size64_t * mapped_size,libcerror_error_t ** error)2167 int libfdata_list_get_mapped_size_by_index(
2168 libfdata_list_t *list,
2169 int element_index,
2170 size64_t *mapped_size,
2171 libcerror_error_t **error )
2172 {
2173 libfdata_internal_list_t *internal_list = NULL;
2174 libfdata_list_element_t *list_element = NULL;
2175 static char *function = "libfdata_list_get_mapped_size_by_index";
2176 int result = 0;
2177
2178 if( list == NULL )
2179 {
2180 libcerror_error_set(
2181 error,
2182 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2183 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2184 "%s: invalid list.",
2185 function );
2186
2187 return( -1 );
2188 }
2189 internal_list = (libfdata_internal_list_t *) list;
2190
2191 if( libcdata_array_get_entry_by_index(
2192 internal_list->elements_array,
2193 element_index,
2194 (intptr_t **) &list_element,
2195 error ) != 1 )
2196 {
2197 libcerror_error_set(
2198 error,
2199 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2200 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2201 "%s: unable to retrieve entry: %d from elements array.",
2202 function,
2203 element_index );
2204
2205 return( -1 );
2206 }
2207 result = libfdata_list_element_get_mapped_size(
2208 list_element,
2209 mapped_size,
2210 error );
2211
2212 if( result == -1 )
2213 {
2214 libcerror_error_set(
2215 error,
2216 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2217 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2218 "%s: unable to retrieve mapped size of element: %d.",
2219 function,
2220 element_index );
2221
2222 return( -1 );
2223 }
2224 internal_list->current_element_index = element_index;
2225
2226 return( result );
2227 }
2228
2229 /* Sets the mapped size of a specific element
2230 * Returns 1 if successful or -1 on error
2231 */
libfdata_list_set_mapped_size_by_index(libfdata_list_t * list,int element_index,size64_t mapped_size,libcerror_error_t ** error)2232 int libfdata_list_set_mapped_size_by_index(
2233 libfdata_list_t *list,
2234 int element_index,
2235 size64_t mapped_size,
2236 libcerror_error_t **error )
2237 {
2238 libfdata_internal_list_t *internal_list = NULL;
2239 libfdata_list_element_t *list_element = NULL;
2240 static char *function = "libfdata_list_set_mapped_size_by_index";
2241
2242 if( list == NULL )
2243 {
2244 libcerror_error_set(
2245 error,
2246 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2247 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2248 "%s: invalid list.",
2249 function );
2250
2251 return( -1 );
2252 }
2253 internal_list = (libfdata_internal_list_t *) list;
2254
2255 if( libcdata_array_get_entry_by_index(
2256 internal_list->elements_array,
2257 element_index,
2258 (intptr_t **) &list_element,
2259 error ) != 1 )
2260 {
2261 libcerror_error_set(
2262 error,
2263 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2264 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2265 "%s: unable to retrieve entry: %d from elements array.",
2266 function,
2267 element_index );
2268
2269 return( -1 );
2270 }
2271 if( libfdata_list_element_set_mapped_size(
2272 list_element,
2273 mapped_size,
2274 error ) != 1 )
2275 {
2276 libcerror_error_set(
2277 error,
2278 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2279 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2280 "%s: unable to set mapped size of element: %d.",
2281 function,
2282 element_index );
2283
2284 return( -1 );
2285 }
2286 internal_list->current_element_index = element_index;
2287
2288 return( 1 );
2289 }
2290
2291 /* Retrieves the data range with its mapped size of a specific element
2292 * Returns 1 if successful, 0 if the element has no mapped size or -1 on error
2293 */
libfdata_list_get_element_by_index_with_mapped_size(libfdata_list_t * list,int element_index,int * element_file_index,off64_t * element_offset,size64_t * element_size,uint32_t * element_flags,size64_t * mapped_size,libcerror_error_t ** error)2294 int libfdata_list_get_element_by_index_with_mapped_size(
2295 libfdata_list_t *list,
2296 int element_index,
2297 int *element_file_index,
2298 off64_t *element_offset,
2299 size64_t *element_size,
2300 uint32_t *element_flags,
2301 size64_t *mapped_size,
2302 libcerror_error_t **error )
2303 {
2304 libfdata_internal_list_t *internal_list = NULL;
2305 libfdata_list_element_t *list_element = NULL;
2306 static char *function = "libfdata_list_get_element_by_index_with_mapped_size";
2307 int result = 0;
2308
2309 if( list == NULL )
2310 {
2311 libcerror_error_set(
2312 error,
2313 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2314 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2315 "%s: invalid list.",
2316 function );
2317
2318 return( -1 );
2319 }
2320 internal_list = (libfdata_internal_list_t *) list;
2321
2322 if( libcdata_array_get_entry_by_index(
2323 internal_list->elements_array,
2324 element_index,
2325 (intptr_t **) &list_element,
2326 error ) != 1 )
2327 {
2328 libcerror_error_set(
2329 error,
2330 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2331 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2332 "%s: unable to retrieve entry: %d from elements array.",
2333 function,
2334 element_index );
2335
2336 return( -1 );
2337 }
2338 if( libfdata_list_element_get_data_range(
2339 list_element,
2340 element_file_index,
2341 element_offset,
2342 element_size,
2343 element_flags,
2344 error ) != 1 )
2345 {
2346 libcerror_error_set(
2347 error,
2348 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2349 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2350 "%s: unable to retrieve data range from list element: %d.",
2351 function,
2352 element_index );
2353
2354 return( -1 );
2355 }
2356 result = libfdata_list_element_get_mapped_size(
2357 list_element,
2358 mapped_size,
2359 error );
2360
2361 if( result == -1 )
2362 {
2363 libcerror_error_set(
2364 error,
2365 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2366 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2367 "%s: unable to retrieve mapped size of list element: %d.",
2368 function,
2369 element_index );
2370
2371 return( -1 );
2372 }
2373 internal_list->current_element_index = element_index;
2374
2375 return( result );
2376 }
2377
2378 /* Sets the data range of a specific element with its mapped size
2379 * Returns 1 if successful or -1 on error
2380 */
libfdata_list_set_element_by_index_with_mapped_size(libfdata_list_t * list,int element_index,int element_file_index,off64_t element_offset,size64_t element_size,uint32_t element_flags,size64_t mapped_size,libcerror_error_t ** error)2381 int libfdata_list_set_element_by_index_with_mapped_size(
2382 libfdata_list_t *list,
2383 int element_index,
2384 int element_file_index,
2385 off64_t element_offset,
2386 size64_t element_size,
2387 uint32_t element_flags,
2388 size64_t mapped_size,
2389 libcerror_error_t **error )
2390 {
2391 libfdata_internal_list_t *internal_list = NULL;
2392 libfdata_list_element_t *list_element = NULL;
2393 libfdata_mapped_range_t *mapped_range = NULL;
2394 static char *function = "libfdata_list_set_element_by_index_with_mapped_size";
2395 off64_t previous_element_offset = 0;
2396 size64_t previous_element_size = 0;
2397 size64_t previous_mapped_size = 0;
2398 uint32_t previous_element_flags = 0;
2399 int previous_element_file_index = 0;
2400 int result = 0;
2401
2402 #if defined( HAVE_DEBUG_OUTPUT )
2403 off64_t mapped_range_offset = 0;
2404 size64_t mapped_range_size = 0;
2405 #endif
2406
2407 if( list == NULL )
2408 {
2409 libcerror_error_set(
2410 error,
2411 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2412 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2413 "%s: invalid list.",
2414 function );
2415
2416 return( -1 );
2417 }
2418 internal_list = (libfdata_internal_list_t *) list;
2419
2420 if( libcdata_array_get_entry_by_index(
2421 internal_list->elements_array,
2422 element_index,
2423 (intptr_t **) &list_element,
2424 error ) != 1 )
2425 {
2426 libcerror_error_set(
2427 error,
2428 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2429 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2430 "%s: unable to retrieve entry: %d from elements array.",
2431 function,
2432 element_index );
2433
2434 return( -1 );
2435 }
2436 if( list_element == NULL )
2437 {
2438 if( libfdata_list_element_initialize(
2439 &list_element,
2440 list,
2441 element_index,
2442 error ) != 1 )
2443 {
2444 libcerror_error_set(
2445 error,
2446 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2447 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2448 "%s: unable to create list element.",
2449 function );
2450
2451 return( -1 );
2452 }
2453 if( libcdata_array_set_entry_by_index(
2454 internal_list->elements_array,
2455 element_index,
2456 (intptr_t *) list_element,
2457 error ) != 1 )
2458 {
2459 libcerror_error_set(
2460 error,
2461 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2462 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2463 "%s: unable to set entry: %d in elements array.",
2464 function,
2465 element_index );
2466
2467 libfdata_list_element_free(
2468 &list_element,
2469 NULL );
2470
2471 return( -1 );
2472 }
2473 }
2474 else
2475 {
2476 result = libfdata_list_element_get_mapped_size(
2477 list_element,
2478 &previous_mapped_size,
2479 error );
2480
2481 if( result == -1 )
2482 {
2483 libcerror_error_set(
2484 error,
2485 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2486 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2487 "%s: unable to retrieve mapped size of list element: %d.",
2488 function,
2489 element_index );
2490
2491 return( -1 );
2492 }
2493 else if( result == 0 )
2494 {
2495 if( libfdata_list_element_get_data_range(
2496 list_element,
2497 &previous_element_file_index,
2498 &previous_element_offset,
2499 &previous_element_size,
2500 &previous_element_flags,
2501 error ) != 1 )
2502 {
2503 libcerror_error_set(
2504 error,
2505 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2506 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2507 "%s: unable to retrieve data range of list element: %d.",
2508 function,
2509 element_index );
2510
2511 return( -1 );
2512 }
2513 }
2514 }
2515 if( libfdata_list_element_set_data_range(
2516 list_element,
2517 element_file_index,
2518 element_offset,
2519 element_size,
2520 element_flags,
2521 error ) != 1 )
2522 {
2523 libcerror_error_set(
2524 error,
2525 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2526 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2527 "%s: unable to set data range of list element: %d.",
2528 function,
2529 element_index );
2530
2531 return( -1 );
2532 }
2533 if( libfdata_list_element_set_mapped_size(
2534 list_element,
2535 mapped_size,
2536 error ) != 1 )
2537 {
2538 libcerror_error_set(
2539 error,
2540 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2541 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2542 "%s: unable to set mapped size of list element.",
2543 function );
2544
2545 return( -1 );
2546 }
2547 /* Make sure the list has a mapped range entry for every element
2548 */
2549 if( libcdata_array_get_entry_by_index(
2550 internal_list->mapped_ranges_array,
2551 element_index,
2552 (intptr_t **) &mapped_range,
2553 error ) != 1 )
2554 {
2555 libcerror_error_set(
2556 error,
2557 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2558 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2559 "%s: unable to retrieve entry: %d from mapped ranges array.",
2560 function,
2561 element_index );
2562
2563 return( -1 );
2564 }
2565 if( mapped_range == NULL )
2566 {
2567 if( libfdata_mapped_range_initialize(
2568 &mapped_range,
2569 error ) != 1 )
2570 {
2571 libcerror_error_set(
2572 error,
2573 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2574 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2575 "%s: unable to create mapped range.",
2576 function );
2577
2578 return( -1 );
2579 }
2580 if( libcdata_array_set_entry_by_index(
2581 internal_list->mapped_ranges_array,
2582 element_index,
2583 (intptr_t *) mapped_range,
2584 error ) != 1 )
2585 {
2586 libcerror_error_set(
2587 error,
2588 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2589 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2590 "%s: unable to set entry: %d in mapped ranges array.",
2591 function,
2592 element_index );
2593
2594 libfdata_mapped_range_free(
2595 &mapped_range,
2596 NULL );
2597
2598 return( -1 );
2599 }
2600 internal_list->size += mapped_size;
2601 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
2602 }
2603 else if( previous_mapped_size != mapped_size )
2604 {
2605 if( previous_mapped_size != 0 )
2606 {
2607 internal_list->size -= previous_mapped_size;
2608 }
2609 else
2610 {
2611 internal_list->size -= previous_element_size;
2612 }
2613 if( mapped_size != 0 )
2614 {
2615 internal_list->size += mapped_size;
2616 }
2617 else
2618 {
2619 internal_list->size += element_size;
2620 }
2621 internal_list->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
2622 }
2623 #if defined( HAVE_DEBUG_OUTPUT )
2624 if( libcnotify_verbose != 0 )
2625 {
2626 libcnotify_printf(
2627 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
2628 function,
2629 element_index,
2630 element_file_index,
2631 element_offset,
2632 element_offset + element_size,
2633 element_offset,
2634 element_offset + element_size,
2635 element_size );
2636
2637 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) == 0 )
2638 {
2639 if( libfdata_mapped_range_get(
2640 mapped_range,
2641 &mapped_range_offset,
2642 &mapped_range_size,
2643 error ) != 1 )
2644 {
2645 libcerror_error_set(
2646 error,
2647 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2648 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2649 "%s: unable to retrieve values from mapped range: %d.",
2650 function,
2651 element_index );
2652
2653 return( -1 );
2654 }
2655 libcnotify_printf(
2656 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
2657 function,
2658 element_index,
2659 mapped_range_offset,
2660 mapped_range_offset + mapped_range_size,
2661 mapped_range_offset,
2662 mapped_range_offset + mapped_range_size,
2663 mapped_range_size );
2664 }
2665 libcnotify_printf(
2666 "\n" );
2667 }
2668 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
2669
2670 internal_list->current_element_index = element_index;
2671
2672 return( 1 );
2673 }
2674
2675 /* Appends an element data range with its mapped size
2676 * Returns 1 if successful or -1 on error
2677 */
libfdata_list_append_element_with_mapped_size(libfdata_list_t * list,int * element_index,int element_file_index,off64_t element_offset,size64_t element_size,uint32_t element_flags,size64_t mapped_size,libcerror_error_t ** error)2678 int libfdata_list_append_element_with_mapped_size(
2679 libfdata_list_t *list,
2680 int *element_index,
2681 int element_file_index,
2682 off64_t element_offset,
2683 size64_t element_size,
2684 uint32_t element_flags,
2685 size64_t mapped_size,
2686 libcerror_error_t **error )
2687 {
2688 libfdata_internal_list_t *internal_list = NULL;
2689 libfdata_list_element_t *list_element = NULL;
2690 libfdata_mapped_range_t *mapped_range = NULL;
2691 static char *function = "libfdata_list_append_element_with_mapped_size";
2692 off64_t mapped_offset = 0;
2693 int mapped_range_index = -1;
2694 uint8_t list_flags = 0;
2695
2696 if( list == NULL )
2697 {
2698 libcerror_error_set(
2699 error,
2700 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2701 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2702 "%s: invalid list.",
2703 function );
2704
2705 return( -1 );
2706 }
2707 internal_list = (libfdata_internal_list_t *) list;
2708
2709 if( element_index == NULL )
2710 {
2711 libcerror_error_set(
2712 error,
2713 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2714 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2715 "%s: invalid element index.",
2716 function );
2717
2718 return( -1 );
2719 }
2720 if( libfdata_mapped_range_initialize(
2721 &mapped_range,
2722 error ) != 1 )
2723 {
2724 libcerror_error_set(
2725 error,
2726 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2727 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2728 "%s: unable to create mapped range.",
2729 function );
2730
2731 goto on_error;
2732 }
2733 mapped_offset = internal_list->mapped_offset + (off64_t) internal_list->size;
2734
2735 if( libfdata_mapped_range_set(
2736 mapped_range,
2737 mapped_offset,
2738 mapped_size,
2739 error ) != 1 )
2740 {
2741 libcerror_error_set(
2742 error,
2743 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2744 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2745 "%s: unable to set mapped range values.",
2746 function );
2747
2748 goto on_error;
2749 }
2750 if( libcdata_array_append_entry(
2751 internal_list->mapped_ranges_array,
2752 &mapped_range_index,
2753 (intptr_t *) mapped_range,
2754 error ) != 1 )
2755 {
2756 libcerror_error_set(
2757 error,
2758 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2759 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2760 "%s: unable to append mapped range to array.",
2761 function );
2762
2763 goto on_error;
2764 }
2765 if( libfdata_list_element_initialize(
2766 &list_element,
2767 list,
2768 0,
2769 error ) != 1 )
2770 {
2771 libcerror_error_set(
2772 error,
2773 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2774 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2775 "%s: unable to create list element.",
2776 function );
2777
2778 goto on_error;
2779 }
2780 if( libfdata_list_element_set_data_range(
2781 list_element,
2782 element_file_index,
2783 element_offset,
2784 element_size,
2785 element_flags,
2786 error ) != 1 )
2787 {
2788 libcerror_error_set(
2789 error,
2790 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2791 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2792 "%s: unable to set data range of list element.",
2793 function );
2794
2795 goto on_error;
2796 }
2797 list_flags = internal_list->flags;
2798
2799 if( libfdata_list_element_set_mapped_size(
2800 list_element,
2801 mapped_size,
2802 error ) != 1 )
2803 {
2804 libcerror_error_set(
2805 error,
2806 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2807 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2808 "%s: unable to set mapped size of list element.",
2809 function );
2810
2811 goto on_error;
2812 }
2813 /* Setting the mapped size in the list element will set the calculate mapped ranges flag in the list
2814 * Reset the flag if it was not set before setting the mapped size in the list element
2815 */
2816 if( ( list_flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) == 0 )
2817 {
2818 internal_list->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
2819 }
2820 if( libcdata_array_append_entry(
2821 internal_list->elements_array,
2822 element_index,
2823 (intptr_t *) list_element,
2824 error ) != 1 )
2825 {
2826 libcerror_error_set(
2827 error,
2828 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2829 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2830 "%s: unable to append list element to elements array.",
2831 function );
2832
2833 goto on_error;
2834 }
2835 mapped_range_index = -1;
2836 mapped_range = NULL;
2837
2838 if( libfdata_list_element_set_element_index(
2839 list_element,
2840 *element_index,
2841 error ) != 1 )
2842 {
2843 libcerror_error_set(
2844 error,
2845 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2846 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2847 "%s: unable to set list element index.",
2848 function );
2849
2850 list_element = NULL;
2851
2852 goto on_error;
2853 }
2854 #if defined( HAVE_DEBUG_OUTPUT )
2855 if( libcnotify_verbose != 0 )
2856 {
2857 libcnotify_printf(
2858 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
2859 function,
2860 *element_index,
2861 element_file_index,
2862 element_offset,
2863 element_offset + element_size,
2864 element_offset,
2865 element_offset + element_size,
2866 element_size );
2867
2868 libcnotify_printf(
2869 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
2870 function,
2871 *element_index,
2872 mapped_offset,
2873 mapped_offset + mapped_size,
2874 mapped_offset,
2875 mapped_offset + mapped_size,
2876 mapped_size );
2877
2878 libcnotify_printf(
2879 "\n" );
2880 }
2881 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
2882
2883 internal_list->current_element_index = *element_index;
2884 internal_list->size += mapped_size;
2885
2886 return( 1 );
2887
2888 on_error:
2889 if( list_element != NULL )
2890 {
2891 libfdata_list_element_free(
2892 &list_element,
2893 NULL );
2894 }
2895 if( mapped_range_index != -1 )
2896 {
2897 libcdata_array_set_entry_by_index(
2898 internal_list->mapped_ranges_array,
2899 mapped_range_index,
2900 NULL,
2901 NULL );
2902 }
2903 if( mapped_range != NULL )
2904 {
2905 libfdata_mapped_range_free(
2906 &mapped_range,
2907 NULL );
2908 }
2909 return( -1 );
2910 }
2911
2912 /* Calculates the mapped ranges
2913 * Returns 1 if successful or -1 on error
2914 */
libfdata_list_calculate_mapped_ranges(libfdata_internal_list_t * internal_list,libcerror_error_t ** error)2915 int libfdata_list_calculate_mapped_ranges(
2916 libfdata_internal_list_t *internal_list,
2917 libcerror_error_t **error )
2918 {
2919 libfdata_list_element_t *list_element = NULL;
2920 libfdata_mapped_range_t *mapped_range = NULL;
2921 static char *function = "libfdata_list_calculate_mapped_ranges";
2922 off64_t mapped_offset = 0;
2923 off64_t element_offset = 0;
2924 size64_t element_size = 0;
2925 size64_t mapped_size = 0;
2926 uint32_t element_flags = 0;
2927 int element_file_index = -1;
2928 int element_index = -1;
2929 int number_of_elements = 0;
2930 int result = 0;
2931
2932 if( internal_list == NULL )
2933 {
2934 libcerror_error_set(
2935 error,
2936 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2937 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2938 "%s: invalid list.",
2939 function );
2940
2941 return( -1 );
2942 }
2943 if( libcdata_array_get_number_of_entries(
2944 internal_list->elements_array,
2945 &number_of_elements,
2946 error ) != 1 )
2947 {
2948 libcerror_error_set(
2949 error,
2950 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2951 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2952 "%s: unable to retrieve number of elements from elements array.",
2953 function );
2954
2955 return( -1 );
2956 }
2957 mapped_offset = internal_list->mapped_offset;
2958
2959 for( element_index = 0;
2960 element_index < number_of_elements;
2961 element_index++ )
2962 {
2963 if( libcdata_array_get_entry_by_index(
2964 internal_list->elements_array,
2965 element_index,
2966 (intptr_t **) &list_element,
2967 error ) != 1 )
2968 {
2969 libcerror_error_set(
2970 error,
2971 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2972 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2973 "%s: unable to retrieve entry: %d from elements array.",
2974 function,
2975 element_index );
2976
2977 return( -1 );
2978 }
2979 if( libcdata_array_get_entry_by_index(
2980 internal_list->mapped_ranges_array,
2981 element_index,
2982 (intptr_t **) &mapped_range,
2983 error ) != 1 )
2984 {
2985 libcerror_error_set(
2986 error,
2987 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2988 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2989 "%s: unable to retrieve entry: %d from mapped ranges array.",
2990 function,
2991 element_index );
2992
2993 return( -1 );
2994 }
2995 if( libfdata_list_element_get_data_range(
2996 list_element,
2997 &element_file_index,
2998 &element_offset,
2999 &element_size,
3000 &element_flags,
3001 error ) != 1 )
3002 {
3003 libcerror_error_set(
3004 error,
3005 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3006 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3007 "%s: unable to retrieve data range of list element: %d.",
3008 function,
3009 element_index );
3010
3011 return( -1 );
3012 }
3013 result = libfdata_list_element_get_mapped_size(
3014 list_element,
3015 &mapped_size,
3016 error );
3017
3018 if( result == -1 )
3019 {
3020 libcerror_error_set(
3021 error,
3022 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3023 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3024 "%s: unable to retrieve mapped size of list element: %d.",
3025 function,
3026 element_index );
3027
3028 return( -1 );
3029 }
3030 else if( result == 0 )
3031 {
3032 mapped_size = element_size;
3033 }
3034 #if defined( HAVE_DEBUG_OUTPUT )
3035 if( libcnotify_verbose != 0 )
3036 {
3037 libcnotify_printf(
3038 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
3039 function,
3040 element_index,
3041 element_file_index,
3042 element_offset,
3043 element_offset + element_size,
3044 element_size );
3045
3046 libcnotify_printf(
3047 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
3048 function,
3049 element_index,
3050 mapped_offset,
3051 mapped_offset + mapped_size,
3052 mapped_size );
3053 }
3054 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
3055
3056 if( libfdata_mapped_range_set(
3057 mapped_range,
3058 mapped_offset,
3059 mapped_size,
3060 error ) != 1 )
3061 {
3062 libcerror_error_set(
3063 error,
3064 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3065 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3066 "%s: unable to set mapped range: %d values.",
3067 function,
3068 element_index );
3069
3070 return( -1 );
3071 }
3072 mapped_offset += (off64_t) mapped_size;
3073 }
3074 internal_list->size = (size64_t) mapped_offset - internal_list->mapped_offset;
3075 internal_list->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
3076
3077 #if defined( HAVE_DEBUG_OUTPUT )
3078 if( libcnotify_verbose != 0 )
3079 {
3080 libcnotify_printf(
3081 "\n" );
3082 }
3083 #endif
3084 return( 1 );
3085 }
3086
3087 /* Retrieves the element index for a specific offset
3088 * The element_data_offset value is set to the offset relative to the start of the element
3089 * Returns 1 if successful, 0 if not or -1 on error
3090 */
libfdata_list_get_element_index_at_offset(libfdata_list_t * list,off64_t offset,int * element_index,off64_t * element_data_offset,libcerror_error_t ** error)3091 int libfdata_list_get_element_index_at_offset(
3092 libfdata_list_t *list,
3093 off64_t offset,
3094 int *element_index,
3095 off64_t *element_data_offset,
3096 libcerror_error_t **error )
3097 {
3098 libfdata_internal_list_t *internal_list = NULL;
3099 libfdata_mapped_range_t *mapped_range = NULL;
3100 static char *function = "libfdata_list_get_element_index_at_offset";
3101 off64_t list_offset = 0;
3102 off64_t mapped_range_end_offset = 0;
3103 off64_t mapped_range_start_offset = 0;
3104 size64_t mapped_range_size = 0;
3105 int initial_element_index = 0;
3106 int number_of_elements = 0;
3107 int result = 0;
3108 int search_element_index = 0;
3109
3110 #if defined( HAVE_DEBUG_OUTPUT )
3111 libfdata_list_element_t *element = NULL;
3112 off64_t element_offset = 0;
3113 size64_t element_size = 0;
3114 uint32_t element_flags = 0;
3115 int element_file_index = -1;
3116 #endif
3117
3118 if( list == NULL )
3119 {
3120 libcerror_error_set(
3121 error,
3122 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3123 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3124 "%s: invalid list.",
3125 function );
3126
3127 return( -1 );
3128 }
3129 internal_list = (libfdata_internal_list_t *) list;
3130
3131 if( offset < 0 )
3132 {
3133 libcerror_error_set(
3134 error,
3135 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3136 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
3137 "%s: invalid offset value less than zero.",
3138 function );
3139
3140 return( -1 );
3141 }
3142 if( element_index == NULL )
3143 {
3144 libcerror_error_set(
3145 error,
3146 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3147 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3148 "%s: invalid element index.",
3149 function );
3150
3151 return( -1 );
3152 }
3153 if( element_data_offset == NULL )
3154 {
3155 libcerror_error_set(
3156 error,
3157 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3158 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3159 "%s: invalid element data offset.",
3160 function );
3161
3162 return( -1 );
3163 }
3164 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
3165 {
3166 if( libfdata_list_calculate_mapped_ranges(
3167 internal_list,
3168 error ) != 1 )
3169 {
3170 libcerror_error_set(
3171 error,
3172 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3173 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3174 "%s: unable to calculate mapped ranges.",
3175 function );
3176
3177 return( -1 );
3178 }
3179 }
3180 #if defined( HAVE_DEBUG_OUTPUT )
3181 if( libcnotify_verbose != 0 )
3182 {
3183 libcnotify_printf(
3184 "%s: requested offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
3185 function,
3186 offset,
3187 offset );
3188 }
3189 #endif
3190 if( internal_list->size == 0 )
3191 {
3192 return( 0 );
3193 }
3194 if( offset < internal_list->mapped_offset )
3195 {
3196 return( 0 );
3197 }
3198 list_offset = offset - internal_list->mapped_offset;
3199
3200 if( (size64_t) list_offset >= internal_list->size )
3201 {
3202 return( 0 );
3203 }
3204 if( libcdata_array_get_number_of_entries(
3205 internal_list->mapped_ranges_array,
3206 &number_of_elements,
3207 error ) != 1 )
3208 {
3209 libcerror_error_set(
3210 error,
3211 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3212 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3213 "%s: unable to retrieve number of entries from mapped ranges array.",
3214 function );
3215
3216 return( -1 );
3217 }
3218 #if defined( HAVE_DEBUG_OUTPUT )
3219 if( libcnotify_verbose != 0 )
3220 {
3221 libcnotify_printf(
3222 "%s: number of elements: %d\n",
3223 function,
3224 number_of_elements );
3225 }
3226 #endif
3227 /* This assumes a fairly even distribution of the sizes of the elements
3228 */
3229 initial_element_index = (int) ( ( number_of_elements * list_offset ) / internal_list->size );
3230
3231 /* Look for the corresponding element upwards in the array
3232 */
3233 for( search_element_index = initial_element_index;
3234 search_element_index < number_of_elements;
3235 search_element_index++ )
3236 {
3237 if( libcdata_array_get_entry_by_index(
3238 internal_list->mapped_ranges_array,
3239 search_element_index,
3240 (intptr_t **) &mapped_range,
3241 error ) != 1 )
3242 {
3243 libcerror_error_set(
3244 error,
3245 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3246 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3247 "%s: unable to retrieve entry: %d from mapped ranges array.",
3248 function,
3249 search_element_index );
3250
3251 return( -1 );
3252 }
3253 if( libfdata_mapped_range_get(
3254 mapped_range,
3255 &mapped_range_start_offset,
3256 &mapped_range_size,
3257 error ) != 1 )
3258 {
3259 libcerror_error_set(
3260 error,
3261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3262 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3263 "%s: unable to retrieve values from mapped range: %d.",
3264 function,
3265 search_element_index );
3266
3267 return( -1 );
3268 }
3269 mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
3270
3271 if( mapped_range_end_offset < mapped_range_start_offset )
3272 {
3273 libcerror_error_set(
3274 error,
3275 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3276 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3277 "%s: invalid element: %d - mapped range value out of bounds.",
3278 function,
3279 search_element_index );
3280
3281 return( -1 );
3282 }
3283 #if defined( HAVE_DEBUG_OUTPUT )
3284 if( libcnotify_verbose != 0 )
3285 {
3286 libcnotify_printf(
3287 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
3288 function,
3289 search_element_index,
3290 mapped_range_start_offset,
3291 mapped_range_end_offset,
3292 mapped_range_start_offset,
3293 mapped_range_end_offset,
3294 mapped_range_size );
3295 }
3296 #endif
3297 /* Check if the offset is in the mapped range
3298 */
3299 if( ( offset >= mapped_range_start_offset )
3300 && ( offset < mapped_range_end_offset ) )
3301 {
3302 offset -= mapped_range_start_offset;
3303
3304 break;
3305 }
3306 /* Check if the offset is out of bounds
3307 */
3308 if( offset < mapped_range_start_offset )
3309 {
3310 search_element_index = number_of_elements;
3311
3312 break;
3313 }
3314 }
3315 if( search_element_index >= number_of_elements )
3316 {
3317 /* Look for the corresponding element downwards in the array
3318 */
3319 for( search_element_index = initial_element_index;
3320 search_element_index >= 0;
3321 search_element_index-- )
3322 {
3323 if( libcdata_array_get_entry_by_index(
3324 internal_list->mapped_ranges_array,
3325 search_element_index,
3326 (intptr_t **) &mapped_range,
3327 error ) != 1 )
3328 {
3329 libcerror_error_set(
3330 error,
3331 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3332 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3333 "%s: unable to retrieve entry: %d from mapped ranges array.",
3334 function,
3335 search_element_index );
3336
3337 return( -1 );
3338 }
3339 if( libfdata_mapped_range_get(
3340 mapped_range,
3341 &mapped_range_start_offset,
3342 &mapped_range_size,
3343 error ) != 1 )
3344 {
3345 libcerror_error_set(
3346 error,
3347 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3348 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3349 "%s: unable to retrieve values from mapped range: %d.",
3350 function,
3351 search_element_index );
3352
3353 return( -1 );
3354 }
3355 mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
3356
3357 if( mapped_range_end_offset < mapped_range_start_offset )
3358 {
3359 libcerror_error_set(
3360 error,
3361 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3362 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3363 "%s: invalid element: %d - mapped range value out of bounds.",
3364 function,
3365 search_element_index );
3366
3367 return( -1 );
3368 }
3369 #if defined( HAVE_DEBUG_OUTPUT )
3370 if( libcnotify_verbose != 0 )
3371 {
3372 libcnotify_printf(
3373 "%s: element: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
3374 function,
3375 search_element_index,
3376 mapped_range_start_offset,
3377 mapped_range_end_offset,
3378 mapped_range_start_offset,
3379 mapped_range_end_offset,
3380 mapped_range_size );
3381 }
3382 #endif
3383 /* Check if the offset is in the mapped range
3384 */
3385 if( ( offset >= mapped_range_start_offset )
3386 && ( offset < mapped_range_end_offset ) )
3387 {
3388 offset -= mapped_range_start_offset;
3389
3390 break;
3391 }
3392 /* Check if the offset is out of bounds
3393 */
3394 if( offset > mapped_range_start_offset )
3395 {
3396 search_element_index--;
3397
3398 break;
3399 }
3400 }
3401 }
3402 if( ( search_element_index >= 0 )
3403 && ( search_element_index < number_of_elements ) )
3404 {
3405 if( offset < 0 )
3406 {
3407 libcerror_error_set(
3408 error,
3409 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3410 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3411 "%s: invalid offset value out of bounds.",
3412 function );
3413
3414 return( -1 );
3415 }
3416 *element_data_offset = offset;
3417
3418 #if defined( HAVE_DEBUG_OUTPUT )
3419 if( libcnotify_verbose != 0 )
3420 {
3421 if( libcdata_array_get_entry_by_index(
3422 internal_list->elements_array,
3423 search_element_index,
3424 (intptr_t **) &element,
3425 error ) != 1 )
3426 {
3427 libcerror_error_set(
3428 error,
3429 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3430 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3431 "%s: unable to retrieve entry: %d from elements array.",
3432 function,
3433 search_element_index );
3434
3435 return( -1 );
3436 }
3437 if( libfdata_list_element_get_data_range(
3438 element,
3439 &element_file_index,
3440 &element_offset,
3441 &element_size,
3442 &element_flags,
3443 error ) != 1 )
3444 {
3445 libcerror_error_set(
3446 error,
3447 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3448 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3449 "%s: unable to retrieve data range of list element: %d.",
3450 function,
3451 search_element_index );
3452
3453 return( -1 );
3454 }
3455 libcnotify_printf(
3456 "%s: element: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
3457 function,
3458 search_element_index,
3459 element_file_index,
3460 element_offset,
3461 element_offset + element_size,
3462 element_offset,
3463 element_offset + element_size,
3464 element_size );
3465 }
3466 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
3467
3468 internal_list->current_element_index = search_element_index;
3469
3470 result = 1;
3471 }
3472 if( result == 1 )
3473 {
3474 *element_index = search_element_index;
3475 }
3476 #if defined( HAVE_DEBUG_OUTPUT )
3477 if( libcnotify_verbose != 0 )
3478 {
3479 libcnotify_printf(
3480 "\n" );
3481 }
3482 #endif
3483 return( result );
3484 }
3485
3486 /* Retrieves the list element for a specific offset
3487 * The element_data_offset value is set to the offset relative to the start of the element
3488 * Returns 1 if successful, 0 if not or -1 on error
3489 */
libfdata_list_get_list_element_at_offset(libfdata_list_t * list,off64_t offset,int * element_index,off64_t * element_data_offset,libfdata_list_element_t ** element,libcerror_error_t ** error)3490 int libfdata_list_get_list_element_at_offset(
3491 libfdata_list_t *list,
3492 off64_t offset,
3493 int *element_index,
3494 off64_t *element_data_offset,
3495 libfdata_list_element_t **element,
3496 libcerror_error_t **error )
3497 {
3498 libfdata_internal_list_t *internal_list = NULL;
3499 static char *function = "libfdata_list_get_list_element_at_offset";
3500 int result = 0;
3501
3502 if( list == NULL )
3503 {
3504 libcerror_error_set(
3505 error,
3506 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3507 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3508 "%s: invalid list.",
3509 function );
3510
3511 return( -1 );
3512 }
3513 internal_list = (libfdata_internal_list_t *) list;
3514
3515 if( offset < 0 )
3516 {
3517 libcerror_error_set(
3518 error,
3519 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3520 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
3521 "%s: invalid offset value less than zero.",
3522 function );
3523
3524 return( -1 );
3525 }
3526 if( element_index == NULL )
3527 {
3528 libcerror_error_set(
3529 error,
3530 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3531 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3532 "%s: invalid element index.",
3533 function );
3534
3535 return( -1 );
3536 }
3537 if( element == NULL )
3538 {
3539 libcerror_error_set(
3540 error,
3541 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3542 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3543 "%s: invalid element.",
3544 function );
3545
3546 return( -1 );
3547 }
3548 result = libfdata_list_get_element_index_at_offset(
3549 list,
3550 offset,
3551 element_index,
3552 element_data_offset,
3553 error );
3554
3555 if( result == -1 )
3556 {
3557 libcerror_error_set(
3558 error,
3559 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3560 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3561 "%s: unable to retrieve element index at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3562 function,
3563 offset,
3564 offset );
3565
3566 return( -1 );
3567 }
3568 else if( result != 0 )
3569 {
3570 if( libcdata_array_get_entry_by_index(
3571 internal_list->elements_array,
3572 *element_index,
3573 (intptr_t **) element,
3574 error ) != 1 )
3575 {
3576 libcerror_error_set(
3577 error,
3578 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3579 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3580 "%s: unable to retrieve entry: %d from elements array.",
3581 function,
3582 *element_index );
3583
3584 return( -1 );
3585 }
3586 }
3587 return( result );
3588 }
3589
3590 /* Retrieves the data range of an element at a specific offset
3591 * Returns 1 if successful, 0 if not or -1 on error
3592 */
libfdata_list_get_element_at_offset(libfdata_list_t * list,off64_t offset,int * element_index,off64_t * element_data_offset,int * element_file_index,off64_t * element_offset,size64_t * element_size,uint32_t * element_flags,libcerror_error_t ** error)3593 int libfdata_list_get_element_at_offset(
3594 libfdata_list_t *list,
3595 off64_t offset,
3596 int *element_index,
3597 off64_t *element_data_offset,
3598 int *element_file_index,
3599 off64_t *element_offset,
3600 size64_t *element_size,
3601 uint32_t *element_flags,
3602 libcerror_error_t **error )
3603 {
3604 libfdata_internal_list_t *internal_list = NULL;
3605 libfdata_list_element_t *list_element = NULL;
3606 static char *function = "libfdata_list_get_element_at_offset";
3607 int result = 0;
3608
3609 if( list == NULL )
3610 {
3611 libcerror_error_set(
3612 error,
3613 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3614 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3615 "%s: invalid list.",
3616 function );
3617
3618 return( -1 );
3619 }
3620 internal_list = (libfdata_internal_list_t *) list;
3621
3622 if( element_index == NULL )
3623 {
3624 libcerror_error_set(
3625 error,
3626 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3627 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3628 "%s: invalid element index.",
3629 function );
3630
3631 return( -1 );
3632 }
3633 result = libfdata_list_get_element_index_at_offset(
3634 list,
3635 offset,
3636 element_index,
3637 element_data_offset,
3638 error );
3639
3640 if( result == -1 )
3641 {
3642 libcerror_error_set(
3643 error,
3644 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3645 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3646 "%s: unable to retrieve element index at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3647 function,
3648 offset,
3649 offset );
3650
3651 return( -1 );
3652 }
3653 else if( result != 0 )
3654 {
3655 if( libcdata_array_get_entry_by_index(
3656 internal_list->elements_array,
3657 *element_index,
3658 (intptr_t **) &list_element,
3659 error ) != 1 )
3660 {
3661 libcerror_error_set(
3662 error,
3663 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3664 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3665 "%s: unable to retrieve entry: %d from elements array.",
3666 function,
3667 *element_index );
3668
3669 return( -1 );
3670 }
3671 if( libfdata_list_element_get_data_range(
3672 list_element,
3673 element_file_index,
3674 element_offset,
3675 element_size,
3676 element_flags,
3677 error ) != 1 )
3678 {
3679 libcerror_error_set(
3680 error,
3681 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3682 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3683 "%s: unable to retrieve data range of list element: %d.",
3684 function,
3685 *element_index );
3686
3687 return( -1 );
3688 }
3689 }
3690 return( result );
3691 }
3692
3693 /* List element value functions
3694 */
3695
3696 /* Caches the element value
3697 * Returns 1 if successful or -1 on error
3698 */
libfdata_list_cache_element_value(libfdata_list_t * list,libfdata_cache_t * cache,int element_index LIBFDATA_ATTRIBUTE_UNUSED,int element_file_index,off64_t element_data_offset,size64_t element_data_size LIBFDATA_ATTRIBUTE_UNUSED,uint32_t element_data_flags LIBFDATA_ATTRIBUTE_UNUSED,int64_t element_timestamp,intptr_t * element_value,int (* free_element_value)(intptr_t ** element_value,libcerror_error_t ** error),uint8_t write_flags,libcerror_error_t ** error)3699 int libfdata_list_cache_element_value(
3700 libfdata_list_t *list,
3701 libfdata_cache_t *cache,
3702 int element_index LIBFDATA_ATTRIBUTE_UNUSED,
3703 int element_file_index,
3704 off64_t element_data_offset,
3705 size64_t element_data_size LIBFDATA_ATTRIBUTE_UNUSED,
3706 uint32_t element_data_flags LIBFDATA_ATTRIBUTE_UNUSED,
3707 int64_t element_timestamp,
3708 intptr_t *element_value,
3709 int (*free_element_value)(
3710 intptr_t **element_value,
3711 libcerror_error_t **error ),
3712 uint8_t write_flags,
3713 libcerror_error_t **error )
3714 {
3715 static char *function = "libfdata_list_cache_element_value";
3716
3717 LIBFDATA_UNREFERENCED_PARAMETER( element_index )
3718 LIBFDATA_UNREFERENCED_PARAMETER( element_data_size )
3719 LIBFDATA_UNREFERENCED_PARAMETER( element_data_flags )
3720
3721 if( list == NULL )
3722 {
3723 libcerror_error_set(
3724 error,
3725 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3726 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3727 "%s: invalid list.",
3728 function );
3729
3730 return( -1 );
3731 }
3732 if( libfcache_cache_set_value_by_identifier(
3733 (libfcache_cache_t *) cache,
3734 element_file_index,
3735 element_data_offset,
3736 element_timestamp,
3737 element_value,
3738 free_element_value,
3739 write_flags,
3740 error ) != 1 )
3741 {
3742 libcerror_error_set(
3743 error,
3744 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3745 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3746 "%s: unable to set value in cache.",
3747 function );
3748
3749 return( -1 );
3750 }
3751 return( 1 );
3752 }
3753
3754 /* Retrieves the element value
3755 * Returns 1 if successful or -1 on error
3756 */
libfdata_list_get_element_value(libfdata_list_t * list,intptr_t * file_io_handle,libfdata_cache_t * cache,libfdata_list_element_t * element,intptr_t ** element_value,uint8_t read_flags,libcerror_error_t ** error)3757 int libfdata_list_get_element_value(
3758 libfdata_list_t *list,
3759 intptr_t *file_io_handle,
3760 libfdata_cache_t *cache,
3761 libfdata_list_element_t *element,
3762 intptr_t **element_value,
3763 uint8_t read_flags,
3764 libcerror_error_t **error )
3765 {
3766 libfcache_cache_value_t *cache_value = NULL;
3767 libfdata_internal_list_t *internal_list = NULL;
3768 static char *function = "libfdata_list_get_element_value";
3769 size64_t element_data_size = 0;
3770 off64_t cache_value_offset = (off64_t) -1;
3771 off64_t element_data_offset = 0;
3772 int64_t cache_value_timestamp = 0;
3773 int64_t element_timestamp = 0;
3774 uint32_t element_data_flags = 0;
3775 int cache_value_file_index = -1;
3776 int element_file_index = -1;
3777 int result = 0;
3778
3779 #if defined( HAVE_DEBUG_OUTPUT )
3780 const char *hit_or_miss = NULL;
3781 #endif
3782
3783 if( list == NULL )
3784 {
3785 libcerror_error_set(
3786 error,
3787 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3788 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3789 "%s: invalid list.",
3790 function );
3791
3792 return( -1 );
3793 }
3794 internal_list = (libfdata_internal_list_t *) list;
3795
3796 if( internal_list->read_element_data == NULL )
3797 {
3798 libcerror_error_set(
3799 error,
3800 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3801 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3802 "%s: invalid list - missing read element data function.",
3803 function );
3804
3805 return( -1 );
3806 }
3807 if( libfdata_list_element_get_data_range(
3808 element,
3809 &element_file_index,
3810 &element_data_offset,
3811 &element_data_size,
3812 &element_data_flags,
3813 error ) != 1 )
3814 {
3815 libcerror_error_set(
3816 error,
3817 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3818 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3819 "%s: unable to retrieve data range from list element.",
3820 function );
3821
3822 return( -1 );
3823 }
3824 if( libfdata_list_element_get_timestamp(
3825 element,
3826 &element_timestamp,
3827 error ) != 1 )
3828 {
3829 libcerror_error_set(
3830 error,
3831 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3832 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3833 "%s: unable to retrieve time stamp from list element.",
3834 function );
3835
3836 return( -1 );
3837 }
3838 if( ( read_flags & LIBFDATA_READ_FLAG_IGNORE_CACHE ) == 0 )
3839 {
3840 result = libfcache_cache_get_value_by_identifier(
3841 (libfcache_cache_t *) cache,
3842 element_file_index,
3843 element_data_offset,
3844 element_timestamp,
3845 &cache_value,
3846 error );
3847
3848 if( result == -1 )
3849 {
3850 libcerror_error_set(
3851 error,
3852 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3853 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3854 "%s: unable to retrieve value from cache.",
3855 function );
3856
3857 return( -1 );
3858 }
3859 #if defined( HAVE_DEBUG_OUTPUT )
3860 if( libcnotify_verbose != 0 )
3861 {
3862 if( result == 0 )
3863 {
3864 hit_or_miss = "miss";
3865 }
3866 else
3867 {
3868 hit_or_miss = "hit";
3869 }
3870 libcnotify_printf(
3871 "%s: cache: 0x%08" PRIjx " %s\n",
3872 function,
3873 (intptr_t) cache,
3874 hit_or_miss );
3875 }
3876 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
3877 }
3878 if( result == 0 )
3879 {
3880 #if defined( HAVE_DEBUG_OUTPUT )
3881 if( libcnotify_verbose != 0 )
3882 {
3883 libcnotify_printf(
3884 "%s: reading element data at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIu64 "\n",
3885 function,
3886 element_data_offset,
3887 element_data_offset,
3888 element_data_size );
3889 }
3890 #endif
3891 if( internal_list->read_element_data(
3892 internal_list->data_handle,
3893 file_io_handle,
3894 element,
3895 cache,
3896 element_file_index,
3897 element_data_offset,
3898 element_data_size,
3899 element_data_flags,
3900 read_flags,
3901 error ) != 1 )
3902 {
3903 libcerror_error_set(
3904 error,
3905 LIBCERROR_ERROR_DOMAIN_IO,
3906 LIBCERROR_IO_ERROR_READ_FAILED,
3907 "%s: unable to read element data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3908 function,
3909 element_data_offset,
3910 element_data_offset );
3911
3912 return( -1 );
3913 }
3914 if( libfcache_cache_get_value_by_identifier(
3915 (libfcache_cache_t *) cache,
3916 element_file_index,
3917 element_data_offset,
3918 element_timestamp,
3919 &cache_value,
3920 error ) != 1 )
3921 {
3922 libcerror_error_set(
3923 error,
3924 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3925 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3926 "%s: unable to retrieve value from cache.",
3927 function );
3928
3929 return( -1 );
3930 }
3931 if( libfcache_cache_value_get_identifier(
3932 cache_value,
3933 &cache_value_file_index,
3934 &cache_value_offset,
3935 &cache_value_timestamp,
3936 error ) != 1 )
3937 {
3938 libcerror_error_set(
3939 error,
3940 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3941 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3942 "%s: unable to retrieve cache value identifier.",
3943 function );
3944
3945 return( -1 );
3946 }
3947 if( ( element_file_index != cache_value_file_index )
3948 || ( element_data_offset != cache_value_offset )
3949 || ( element_timestamp != cache_value_timestamp ) )
3950 {
3951 libcerror_error_set(
3952 error,
3953 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3954 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3955 "%s: missing cache value.",
3956 function );
3957
3958 return( -1 );
3959 }
3960 }
3961 if( libfcache_cache_value_get_value(
3962 cache_value,
3963 element_value,
3964 error ) != 1 )
3965 {
3966 libcerror_error_set(
3967 error,
3968 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3969 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3970 "%s: unable to retrieve element value.",
3971 function );
3972
3973 return( -1 );
3974 }
3975 return( 1 );
3976 }
3977
3978 /* Retrieves the value of a specific element
3979 * Returns 1 if successful or -1 on error
3980 */
libfdata_list_get_element_value_by_index(libfdata_list_t * list,intptr_t * file_io_handle,libfdata_cache_t * cache,int element_index,intptr_t ** element_value,uint8_t read_flags,libcerror_error_t ** error)3981 int libfdata_list_get_element_value_by_index(
3982 libfdata_list_t *list,
3983 intptr_t *file_io_handle,
3984 libfdata_cache_t *cache,
3985 int element_index,
3986 intptr_t **element_value,
3987 uint8_t read_flags,
3988 libcerror_error_t **error )
3989 {
3990 libfdata_internal_list_t *internal_list = NULL;
3991 libfdata_list_element_t *list_element = NULL;
3992 static char *function = "libfdata_list_get_element_value_by_index";
3993
3994 if( list == NULL )
3995 {
3996 libcerror_error_set(
3997 error,
3998 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3999 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4000 "%s: invalid list.",
4001 function );
4002
4003 return( -1 );
4004 }
4005 internal_list = (libfdata_internal_list_t *) list;
4006
4007 if( libcdata_array_get_entry_by_index(
4008 internal_list->elements_array,
4009 element_index,
4010 (intptr_t **) &list_element,
4011 error ) != 1 )
4012 {
4013 libcerror_error_set(
4014 error,
4015 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4016 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4017 "%s: unable to retrieve entry: %d from elements array.",
4018 function,
4019 element_index );
4020
4021 return( -1 );
4022 }
4023 if( libfdata_list_get_element_value(
4024 list,
4025 file_io_handle,
4026 cache,
4027 list_element,
4028 element_value,
4029 read_flags,
4030 error ) != 1 )
4031 {
4032 libcerror_error_set(
4033 error,
4034 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4035 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4036 "%s: unable to retrieve element value.",
4037 function );
4038
4039 return( -1 );
4040 }
4041 internal_list->current_element_index = element_index;
4042
4043 return( 1 );
4044 }
4045
4046 /* Retrieves the value an element at a specific offset
4047 * Returns 1 if successful, 0 if not or -1 on error
4048 */
libfdata_list_get_element_value_at_offset(libfdata_list_t * list,intptr_t * file_io_handle,libfdata_cache_t * cache,off64_t offset,int * element_index,off64_t * element_data_offset,intptr_t ** element_value,uint8_t read_flags,libcerror_error_t ** error)4049 int libfdata_list_get_element_value_at_offset(
4050 libfdata_list_t *list,
4051 intptr_t *file_io_handle,
4052 libfdata_cache_t *cache,
4053 off64_t offset,
4054 int *element_index,
4055 off64_t *element_data_offset,
4056 intptr_t **element_value,
4057 uint8_t read_flags,
4058 libcerror_error_t **error )
4059 {
4060 libfdata_list_element_t *list_element = NULL;
4061 static char *function = "libfdata_list_get_element_value_at_offset";
4062 int result = 0;
4063
4064 if( element_index == NULL )
4065 {
4066 libcerror_error_set(
4067 error,
4068 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4069 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4070 "%s: invalid element index.",
4071 function );
4072
4073 return( -1 );
4074 }
4075 result = libfdata_list_get_list_element_at_offset(
4076 list,
4077 offset,
4078 element_index,
4079 element_data_offset,
4080 &list_element,
4081 error );
4082
4083 if( result == -1 )
4084 {
4085 libcerror_error_set(
4086 error,
4087 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4088 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4089 "%s: unable to retrieve element at offset: %" PRIi64 " (0x%08" PRIx64 ").",
4090 function,
4091 offset,
4092 offset );
4093
4094 return( -1 );
4095 }
4096 else if( result != 0 )
4097 {
4098 if( libfdata_list_get_element_value(
4099 list,
4100 file_io_handle,
4101 cache,
4102 list_element,
4103 element_value,
4104 read_flags,
4105 error ) != 1 )
4106 {
4107 libcerror_error_set(
4108 error,
4109 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4110 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4111 "%s: unable to retrieve element: %d value.",
4112 function,
4113 *element_index );
4114
4115 return( -1 );
4116 }
4117 }
4118 return( result );
4119 }
4120
4121 /* Sets the value of a specific element
4122 *
4123 * If the flag LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED is set the list
4124 * takes over management of the value and the value is freed when
4125 * no longer needed.
4126 *
4127 * Returns 1 if successful or -1 on error
4128 */
libfdata_list_set_element_value(libfdata_list_t * list,intptr_t * file_io_handle LIBFDATA_ATTRIBUTE_UNUSED,libfdata_cache_t * cache,libfdata_list_element_t * element,intptr_t * element_value,int (* free_element_value)(intptr_t ** element_value,libcerror_error_t ** error),uint8_t write_flags,libcerror_error_t ** error)4129 int libfdata_list_set_element_value(
4130 libfdata_list_t *list,
4131 intptr_t *file_io_handle LIBFDATA_ATTRIBUTE_UNUSED,
4132 libfdata_cache_t *cache,
4133 libfdata_list_element_t *element,
4134 intptr_t *element_value,
4135 int (*free_element_value)(
4136 intptr_t **element_value,
4137 libcerror_error_t **error ),
4138 uint8_t write_flags,
4139 libcerror_error_t **error )
4140 {
4141 static char *function = "libfdata_list_set_element_value";
4142 size64_t element_data_size = 0;
4143 off64_t element_data_offset = 0;
4144 int64_t element_timestamp = 0;
4145 uint32_t element_data_flags = 0;
4146 int element_file_index = -1;
4147
4148 LIBFDATA_UNREFERENCED_PARAMETER( file_io_handle )
4149
4150 if( list == NULL )
4151 {
4152 libcerror_error_set(
4153 error,
4154 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4155 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4156 "%s: invalid list.",
4157 function );
4158
4159 return( -1 );
4160 }
4161 if( libfdata_list_element_get_data_range(
4162 element,
4163 &element_file_index,
4164 &element_data_offset,
4165 &element_data_size,
4166 &element_data_flags,
4167 error ) != 1 )
4168 {
4169 libcerror_error_set(
4170 error,
4171 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4172 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4173 "%s: unable to retrieve data range from list element.",
4174 function );
4175
4176 return( -1 );
4177 }
4178 if( libfdata_list_element_get_timestamp(
4179 element,
4180 &element_timestamp,
4181 error ) != 1 )
4182 {
4183 libcerror_error_set(
4184 error,
4185 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4186 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4187 "%s: unable to retrieve time stamp from list element.",
4188 function );
4189
4190 return( -1 );
4191 }
4192 if( libfcache_cache_set_value_by_identifier(
4193 (libfcache_cache_t *) cache,
4194 element_file_index,
4195 element_data_offset,
4196 element_timestamp,
4197 element_value,
4198 free_element_value,
4199 write_flags,
4200 error ) != 1 )
4201 {
4202 libcerror_error_set(
4203 error,
4204 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4205 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4206 "%s: unable to set value in cache.",
4207 function );
4208
4209 return( -1 );
4210 }
4211 return( 1 );
4212 }
4213
4214 /* Sets the value of a specific element
4215 *
4216 * If the flag LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED is set the list
4217 * takes over management of the value and the value is freed when
4218 * no longer needed.
4219 *
4220 * Returns 1 if successful or -1 on error
4221 */
libfdata_list_set_element_value_by_index(libfdata_list_t * list,intptr_t * file_io_handle,libfdata_cache_t * cache,int element_index,intptr_t * element_value,int (* free_element_value)(intptr_t ** element_value,libcerror_error_t ** error),uint8_t write_flags,libcerror_error_t ** error)4222 int libfdata_list_set_element_value_by_index(
4223 libfdata_list_t *list,
4224 intptr_t *file_io_handle,
4225 libfdata_cache_t *cache,
4226 int element_index,
4227 intptr_t *element_value,
4228 int (*free_element_value)(
4229 intptr_t **element_value,
4230 libcerror_error_t **error ),
4231 uint8_t write_flags,
4232 libcerror_error_t **error )
4233 {
4234 libfdata_internal_list_t *internal_list = NULL;
4235 libfdata_list_element_t *list_element = NULL;
4236 static char *function = "libfdata_list_set_element_value_by_index";
4237
4238 if( list == NULL )
4239 {
4240 libcerror_error_set(
4241 error,
4242 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4243 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4244 "%s: invalid list.",
4245 function );
4246
4247 return( -1 );
4248 }
4249 internal_list = (libfdata_internal_list_t *) list;
4250
4251 if( libcdata_array_get_entry_by_index(
4252 internal_list->elements_array,
4253 element_index,
4254 (intptr_t **) &list_element,
4255 error ) != 1 )
4256 {
4257 libcerror_error_set(
4258 error,
4259 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4260 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4261 "%s: unable to retrieve entry: %d from elements array.",
4262 function,
4263 element_index );
4264
4265 return( -1 );
4266 }
4267 if( libfdata_list_set_element_value(
4268 list,
4269 file_io_handle,
4270 cache,
4271 list_element,
4272 element_value,
4273 free_element_value,
4274 write_flags,
4275 error ) != 1 )
4276 {
4277 libcerror_error_set(
4278 error,
4279 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4280 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4281 "%s: unable to set element value.",
4282 function );
4283
4284 return( -1 );
4285 }
4286 internal_list->current_element_index = element_index;
4287
4288 return( 1 );
4289 }
4290
4291 /* Sets the value of an element at a specific offset
4292 *
4293 * If the flag LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED is set the list
4294 * takes over management of the value and the value is freed when
4295 * no longer needed.
4296 *
4297 * Returns 1 if successful, 0 if not or -1 on error
4298 */
libfdata_list_set_element_value_at_offset(libfdata_list_t * list,intptr_t * file_io_handle,libfdata_cache_t * cache,off64_t offset,intptr_t * element_value,int (* free_element_value)(intptr_t ** element_value,libcerror_error_t ** error),uint8_t write_flags,libcerror_error_t ** error)4299 int libfdata_list_set_element_value_at_offset(
4300 libfdata_list_t *list,
4301 intptr_t *file_io_handle,
4302 libfdata_cache_t *cache,
4303 off64_t offset,
4304 intptr_t *element_value,
4305 int (*free_element_value)(
4306 intptr_t **element_value,
4307 libcerror_error_t **error ),
4308 uint8_t write_flags,
4309 libcerror_error_t **error )
4310 {
4311 libfdata_list_element_t *list_element = NULL;
4312 static char *function = "libfdata_list_set_element_value_at_offset";
4313 off64_t element_data_offset = 0;
4314 int element_index = 0;
4315 int result = 0;
4316
4317 result = libfdata_list_get_list_element_at_offset(
4318 list,
4319 offset,
4320 &element_index,
4321 &element_data_offset,
4322 &list_element,
4323 error );
4324
4325 if( result == -1 )
4326 {
4327 libcerror_error_set(
4328 error,
4329 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4330 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4331 "%s: unable to retrieve element at offset: %" PRIi64 " (0x%08" PRIx64 ").",
4332 function,
4333 offset,
4334 offset );
4335
4336 return( -1 );
4337 }
4338 else if( result != 0 )
4339 {
4340 if( libfdata_list_set_element_value(
4341 list,
4342 file_io_handle,
4343 cache,
4344 list_element,
4345 element_value,
4346 free_element_value,
4347 write_flags,
4348 error ) != 1 )
4349 {
4350 libcerror_error_set(
4351 error,
4352 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4353 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4354 "%s: unable to set value of element: %d.",
4355 function,
4356 element_index );
4357
4358 return( -1 );
4359 }
4360 }
4361 return( result );
4362 }
4363
4364 /* Retrieves the size of the list
4365 * Returns 1 if successful or -1 on error
4366 */
libfdata_list_get_size(libfdata_list_t * list,size64_t * size,libcerror_error_t ** error)4367 int libfdata_list_get_size(
4368 libfdata_list_t *list,
4369 size64_t *size,
4370 libcerror_error_t **error )
4371 {
4372 libfdata_internal_list_t *internal_list = NULL;
4373 static char *function = "libfdata_list_get_size";
4374
4375 if( list == NULL )
4376 {
4377 libcerror_error_set(
4378 error,
4379 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4380 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4381 "%s: invalid list.",
4382 function );
4383
4384 return( -1 );
4385 }
4386 internal_list = (libfdata_internal_list_t *) list;
4387
4388 if( size == NULL )
4389 {
4390 libcerror_error_set(
4391 error,
4392 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4393 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4394 "%s: invalid size.",
4395 function );
4396
4397 return( -1 );
4398 }
4399 if( ( internal_list->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
4400 {
4401 if( libfdata_list_calculate_mapped_ranges(
4402 internal_list,
4403 error ) != 1 )
4404 {
4405 libcerror_error_set(
4406 error,
4407 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4408 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4409 "%s: unable to calculate mapped ranges.",
4410 function );
4411
4412 return( -1 );
4413 }
4414 }
4415 *size = internal_list->size;
4416
4417 return( 1 );
4418 }
4419
4420