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