1 /*
2 * The vector 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_mapped_range.h"
32 #include "libfdata_range.h"
33 #include "libfdata_segments_array.h"
34 #include "libfdata_types.h"
35 #include "libfdata_unused.h"
36 #include "libfdata_vector.h"
37
38 /* Creates a vector
39 * Make sure the value vector is referencing, is set to NULL
40 *
41 * If the flag LIBFDATA_DATA_HANDLE_FLAG_MANAGED is set the vector
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_vector_initialize(libfdata_vector_t ** vector,size64_t element_data_size,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_vector_t * vector,libfdata_cache_t * cache,int element_index,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_vector_t * vector,libfdata_cache_t * cache,int element_index,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_vector_initialize(
48 libfdata_vector_t **vector,
49 size64_t element_data_size,
50 intptr_t *data_handle,
51 int (*free_data_handle)(
52 intptr_t **data_handle,
53 libcerror_error_t **error ),
54 int (*clone_data_handle)(
55 intptr_t **destination_data_handle,
56 intptr_t *source_data_handle,
57 libcerror_error_t **error ),
58 int (*read_element_data)(
59 intptr_t *data_handle,
60 intptr_t *file_io_handle,
61 libfdata_vector_t *vector,
62 libfdata_cache_t *cache,
63 int element_index,
64 int element_data_file_index,
65 off64_t element_data_offset,
66 size64_t element_data_size,
67 uint32_t element_data_flags,
68 uint8_t read_flags,
69 libcerror_error_t **error ),
70 int (*write_element_data)(
71 intptr_t *data_handle,
72 intptr_t *file_io_handle,
73 libfdata_vector_t *vector,
74 libfdata_cache_t *cache,
75 int element_index,
76 int element_data_file_index,
77 off64_t element_data_offset,
78 size64_t element_data_size,
79 uint32_t element_data_flags,
80 uint8_t write_flags,
81 libcerror_error_t **error ),
82 uint8_t flags,
83 libcerror_error_t **error )
84 {
85 libfdata_internal_vector_t *internal_vector = NULL;
86 static char *function = "libfdata_vector_initialize";
87
88 if( vector == NULL )
89 {
90 libcerror_error_set(
91 error,
92 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
93 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
94 "%s: invalid vector.",
95 function );
96
97 return( -1 );
98 }
99 if( *vector != NULL )
100 {
101 libcerror_error_set(
102 error,
103 LIBCERROR_ERROR_DOMAIN_RUNTIME,
104 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
105 "%s: invalid vector value already set.",
106 function );
107
108 return( -1 );
109 }
110 if( element_data_size == 0 )
111 {
112 libcerror_error_set(
113 error,
114 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
115 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
116 "%s: invalid element data size value zero or less.",
117 function );
118
119 return( -1 );
120 }
121 internal_vector = memory_allocate_structure(
122 libfdata_internal_vector_t );
123
124 if( internal_vector == NULL )
125 {
126 libcerror_error_set(
127 error,
128 LIBCERROR_ERROR_DOMAIN_MEMORY,
129 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
130 "%s: unable to create vector.",
131 function );
132
133 goto on_error;
134 }
135 if( memory_set(
136 internal_vector,
137 0,
138 sizeof( libfdata_internal_vector_t ) ) == NULL )
139 {
140 libcerror_error_set(
141 error,
142 LIBCERROR_ERROR_DOMAIN_MEMORY,
143 LIBCERROR_MEMORY_ERROR_SET_FAILED,
144 "%s: unable to clear vector.",
145 function );
146
147 memory_free(
148 internal_vector );
149
150 return( -1 );
151 }
152 if( libcdata_array_initialize(
153 &( internal_vector->segments_array ),
154 0,
155 error ) != 1 )
156 {
157 libcerror_error_set(
158 error,
159 LIBCERROR_ERROR_DOMAIN_RUNTIME,
160 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
161 "%s: unable to create segments array.",
162 function );
163
164 goto on_error;
165 }
166 if( libcdata_array_initialize(
167 &( internal_vector->mapped_ranges_array ),
168 0,
169 error ) != 1 )
170 {
171 libcerror_error_set(
172 error,
173 LIBCERROR_ERROR_DOMAIN_RUNTIME,
174 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
175 "%s: unable to create mapped ranges array.",
176 function );
177
178 goto on_error;
179 }
180 if( libfcache_date_time_get_timestamp(
181 &( internal_vector->timestamp ),
182 error ) != 1 )
183 {
184 libcerror_error_set(
185 error,
186 LIBCERROR_ERROR_DOMAIN_RUNTIME,
187 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
188 "%s: unable to retrieve cache timestamp.",
189 function );
190
191 goto on_error;
192 }
193 internal_vector->element_data_size = element_data_size;
194 internal_vector->flags |= flags;
195 internal_vector->data_handle = data_handle;
196 internal_vector->free_data_handle = free_data_handle;
197 internal_vector->clone_data_handle = clone_data_handle;
198 internal_vector->read_element_data = read_element_data;
199 internal_vector->write_element_data = write_element_data;
200
201 *vector = (libfdata_vector_t *) internal_vector;
202
203 return( 1 );
204
205 on_error:
206 if( internal_vector != NULL )
207 {
208 if( internal_vector->mapped_ranges_array != NULL )
209 {
210 libcdata_array_free(
211 &( internal_vector->mapped_ranges_array ),
212 NULL,
213 NULL );
214 }
215 if( internal_vector->segments_array != NULL )
216 {
217 libcdata_array_free(
218 &( internal_vector->segments_array ),
219 NULL,
220 NULL );
221 }
222 memory_free(
223 internal_vector );
224 }
225 return( -1 );
226 }
227
228 /* Frees a vector
229 * Returns 1 if successful or -1 on error
230 */
libfdata_vector_free(libfdata_vector_t ** vector,libcerror_error_t ** error)231 int libfdata_vector_free(
232 libfdata_vector_t **vector,
233 libcerror_error_t **error )
234 {
235 libfdata_internal_vector_t *internal_vector = NULL;
236 static char *function = "libfdata_vector_free";
237 int result = 1;
238
239 if( vector == NULL )
240 {
241 libcerror_error_set(
242 error,
243 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
244 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
245 "%s: invalid vector.",
246 function );
247
248 return( -1 );
249 }
250 if( *vector != NULL )
251 {
252 internal_vector = (libfdata_internal_vector_t *) *vector;
253 *vector = NULL;
254
255 if( libcdata_array_free(
256 &( internal_vector->segments_array ),
257 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
258 error ) != 1 )
259 {
260 libcerror_error_set(
261 error,
262 LIBCERROR_ERROR_DOMAIN_RUNTIME,
263 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
264 "%s: unable to free the segments array.",
265 function );
266
267 result = -1;
268 }
269 if( libcdata_array_free(
270 &( internal_vector->mapped_ranges_array ),
271 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
272 error ) != 1 )
273 {
274 libcerror_error_set(
275 error,
276 LIBCERROR_ERROR_DOMAIN_RUNTIME,
277 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
278 "%s: unable to free the mapped ranges array.",
279 function );
280
281 result = -1;
282 }
283 if( ( internal_vector->flags & LIBFDATA_DATA_HANDLE_FLAG_MANAGED ) != 0 )
284 {
285 if( internal_vector->data_handle != NULL )
286 {
287 if( internal_vector->free_data_handle == NULL )
288 {
289 libcerror_error_set(
290 error,
291 LIBCERROR_ERROR_DOMAIN_RUNTIME,
292 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
293 "%s: invalid vector - missing free data handle function.",
294 function );
295
296 result = -1;
297 }
298 else if( internal_vector->free_data_handle(
299 &( internal_vector->data_handle ),
300 error ) != 1 )
301 {
302 libcerror_error_set(
303 error,
304 LIBCERROR_ERROR_DOMAIN_RUNTIME,
305 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
306 "%s: unable to free data handle.",
307 function );
308
309 result = -1;
310 }
311 }
312 }
313 memory_free(
314 internal_vector );
315 }
316 return( result );
317 }
318
319 /* Clones (duplicates) the vector
320 * Returns 1 if successful or -1 on error
321 */
libfdata_vector_clone(libfdata_vector_t ** destination_vector,libfdata_vector_t * source_vector,libcerror_error_t ** error)322 int libfdata_vector_clone(
323 libfdata_vector_t **destination_vector,
324 libfdata_vector_t *source_vector,
325 libcerror_error_t **error )
326 {
327 libfdata_internal_vector_t *internal_destination_vector = NULL;
328 libfdata_internal_vector_t *internal_source_vector = NULL;
329 static char *function = "libfdata_vector_clone";
330
331 if( destination_vector == NULL )
332 {
333 libcerror_error_set(
334 error,
335 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
336 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
337 "%s: invalid destination vector.",
338 function );
339
340 return( -1 );
341 }
342 if( *destination_vector != NULL )
343 {
344 libcerror_error_set(
345 error,
346 LIBCERROR_ERROR_DOMAIN_RUNTIME,
347 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
348 "%s: invalid destination vector value already set.",
349 function );
350
351 return( -1 );
352 }
353 if( source_vector == NULL )
354 {
355 *destination_vector = source_vector;
356
357 return( 1 );
358 }
359 internal_source_vector = (libfdata_internal_vector_t *) source_vector;
360
361 internal_destination_vector = memory_allocate_structure(
362 libfdata_internal_vector_t );
363
364 if( internal_destination_vector == NULL )
365 {
366 libcerror_error_set(
367 error,
368 LIBCERROR_ERROR_DOMAIN_MEMORY,
369 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
370 "%s: unable to create destination vector.",
371 function );
372
373 goto on_error;
374 }
375 if( memory_set(
376 internal_destination_vector,
377 0,
378 sizeof( libfdata_internal_vector_t ) ) == NULL )
379 {
380 libcerror_error_set(
381 error,
382 LIBCERROR_ERROR_DOMAIN_MEMORY,
383 LIBCERROR_MEMORY_ERROR_SET_FAILED,
384 "%s: unable to clear destination vector.",
385 function );
386
387 memory_free(
388 internal_destination_vector );
389
390 return( -1 );
391 }
392 if( internal_source_vector->data_handle != NULL )
393 {
394 if( internal_source_vector->free_data_handle == NULL )
395 {
396 libcerror_error_set(
397 error,
398 LIBCERROR_ERROR_DOMAIN_RUNTIME,
399 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
400 "%s: invalid source vector - missing free data handle function.",
401 function );
402
403 goto on_error;
404 }
405 if( internal_source_vector->clone_data_handle == NULL )
406 {
407 libcerror_error_set(
408 error,
409 LIBCERROR_ERROR_DOMAIN_RUNTIME,
410 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
411 "%s: invalid source vector - missing clone data handle function.",
412 function );
413
414 goto on_error;
415 }
416 if( internal_source_vector->clone_data_handle(
417 &( internal_destination_vector->data_handle ),
418 internal_source_vector->data_handle,
419 error ) != 1 )
420 {
421 libcerror_error_set(
422 error,
423 LIBCERROR_ERROR_DOMAIN_RUNTIME,
424 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
425 "%s: unable to create destination data handle.",
426 function );
427
428 goto on_error;
429 }
430 }
431 if( libcdata_array_clone(
432 &( internal_destination_vector->segments_array ),
433 internal_source_vector->segments_array,
434 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
435 (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_range_clone,
436 error ) != 1 )
437 {
438 libcerror_error_set(
439 error,
440 LIBCERROR_ERROR_DOMAIN_RUNTIME,
441 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
442 "%s: unable to create destination segments array.",
443 function );
444
445 goto on_error;
446 }
447 if( libcdata_array_clone(
448 &( internal_destination_vector->mapped_ranges_array ),
449 internal_source_vector->mapped_ranges_array,
450 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
451 (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libfdata_mapped_range_clone,
452 error ) != 1 )
453 {
454 libcerror_error_set(
455 error,
456 LIBCERROR_ERROR_DOMAIN_RUNTIME,
457 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
458 "%s: unable to create destination mapped ranges array.",
459 function );
460
461 goto on_error;
462 }
463 internal_destination_vector->element_data_size = internal_source_vector->element_data_size;
464 internal_destination_vector->timestamp = internal_source_vector->timestamp;
465 internal_destination_vector->flags = internal_source_vector->flags | LIBFDATA_DATA_HANDLE_FLAG_MANAGED;
466 internal_destination_vector->data_handle = internal_source_vector->data_handle;
467 internal_destination_vector->free_data_handle = internal_source_vector->free_data_handle;
468 internal_destination_vector->clone_data_handle = internal_source_vector->clone_data_handle;
469 internal_destination_vector->read_element_data = internal_source_vector->read_element_data;
470 internal_destination_vector->write_element_data = internal_source_vector->write_element_data;
471
472 *destination_vector = (libfdata_vector_t *) internal_destination_vector;
473
474 return( 1 );
475
476 on_error:
477 if( internal_destination_vector != NULL )
478 {
479 if( internal_destination_vector->segments_array != NULL )
480 {
481 libcdata_array_free(
482 &( internal_destination_vector->segments_array ),
483 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
484 NULL );
485 }
486 if( ( internal_destination_vector->data_handle != NULL )
487 && ( internal_source_vector->free_data_handle != NULL ) )
488 {
489 internal_source_vector->free_data_handle(
490 &( internal_destination_vector->data_handle ),
491 NULL );
492 }
493 memory_free(
494 internal_destination_vector );
495 }
496 return( -1 );
497 }
498
499 /* Segment functions
500 */
501
502 /* Empties the vector
503 * Returns 1 if successful or -1 on error
504 */
libfdata_vector_empty(libfdata_vector_t * vector,libcerror_error_t ** error)505 int libfdata_vector_empty(
506 libfdata_vector_t *vector,
507 libcerror_error_t **error )
508 {
509 libfdata_internal_vector_t *internal_vector = NULL;
510 static char *function = "libfdata_vector_empty";
511
512 if( vector == NULL )
513 {
514 libcerror_error_set(
515 error,
516 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
517 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
518 "%s: invalid vector.",
519 function );
520
521 return( -1 );
522 }
523 internal_vector = (libfdata_internal_vector_t *) vector;
524
525 if( libcdata_array_empty(
526 internal_vector->segments_array,
527 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
528 error ) != 1 )
529 {
530 libcerror_error_set(
531 error,
532 LIBCERROR_ERROR_DOMAIN_RUNTIME,
533 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
534 "%s: unable to empty segments array.",
535 function );
536
537 return( -1 );
538 }
539 if( libcdata_array_empty(
540 internal_vector->mapped_ranges_array,
541 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
542 error ) != 1 )
543 {
544 libcerror_error_set(
545 error,
546 LIBCERROR_ERROR_DOMAIN_RUNTIME,
547 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
548 "%s: unable to empty mapped ranges array.",
549 function );
550
551 return( -1 );
552 }
553 internal_vector->size = 0;
554
555 return( 1 );
556 }
557
558 /* Resizes the segments
559 * Returns 1 if successful or -1 on error
560 */
libfdata_vector_resize(libfdata_vector_t * vector,int number_of_segments,libcerror_error_t ** error)561 int libfdata_vector_resize(
562 libfdata_vector_t *vector,
563 int number_of_segments,
564 libcerror_error_t **error )
565 {
566 libfdata_internal_vector_t *internal_vector = NULL;
567 static char *function = "libfdata_vector_resize";
568
569 if( vector == NULL )
570 {
571 libcerror_error_set(
572 error,
573 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
574 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
575 "%s: invalid vector.",
576 function );
577
578 return( -1 );
579 }
580 internal_vector = (libfdata_internal_vector_t *) vector;
581
582 if( libcdata_array_resize(
583 internal_vector->segments_array,
584 number_of_segments,
585 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
586 error ) != 1 )
587 {
588 libcerror_error_set(
589 error,
590 LIBCERROR_ERROR_DOMAIN_RUNTIME,
591 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
592 "%s: unable to resize segments array.",
593 function );
594
595 return( -1 );
596 }
597 if( libcdata_array_resize(
598 internal_vector->mapped_ranges_array,
599 number_of_segments,
600 (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
601 error ) != 1 )
602 {
603 libcerror_error_set(
604 error,
605 LIBCERROR_ERROR_DOMAIN_RUNTIME,
606 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
607 "%s: unable to resize mapped ranges array.",
608 function );
609
610 return( -1 );
611 }
612 internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
613
614 return( 1 );
615 }
616
617 /* Retrieves the number of segments of the vector
618 * Returns 1 if successful or -1 on error
619 */
libfdata_vector_get_number_of_segments(libfdata_vector_t * vector,int * number_of_segments,libcerror_error_t ** error)620 int libfdata_vector_get_number_of_segments(
621 libfdata_vector_t *vector,
622 int *number_of_segments,
623 libcerror_error_t **error )
624 {
625 libfdata_internal_vector_t *internal_vector = NULL;
626 static char *function = "libfdata_vector_get_number_of_segments";
627
628 if( vector == NULL )
629 {
630 libcerror_error_set(
631 error,
632 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
633 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
634 "%s: invalid vector.",
635 function );
636
637 return( -1 );
638 }
639 internal_vector = (libfdata_internal_vector_t *) vector;
640
641 if( libcdata_array_get_number_of_entries(
642 internal_vector->segments_array,
643 number_of_segments,
644 error ) != 1 )
645 {
646 libcerror_error_set(
647 error,
648 LIBCERROR_ERROR_DOMAIN_RUNTIME,
649 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
650 "%s: unable to retrieve number of entries from segments array.",
651 function );
652
653 return( -1 );
654 }
655 return( 1 );
656 }
657
658 /* Retrieves the offset and size of a specific segment
659 * Returns 1 if successful or -1 on error
660 */
libfdata_vector_get_segment_by_index(libfdata_vector_t * vector,int segment_index,int * segment_file_index,off64_t * segment_offset,size64_t * segment_size,uint32_t * segment_flags,libcerror_error_t ** error)661 int libfdata_vector_get_segment_by_index(
662 libfdata_vector_t *vector,
663 int segment_index,
664 int *segment_file_index,
665 off64_t *segment_offset,
666 size64_t *segment_size,
667 uint32_t *segment_flags,
668 libcerror_error_t **error )
669 {
670 libfdata_internal_vector_t *internal_vector = NULL;
671 static char *function = "libfdata_vector_get_segment_by_index";
672
673 if( vector == NULL )
674 {
675 libcerror_error_set(
676 error,
677 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
678 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
679 "%s: invalid vector.",
680 function );
681
682 return( -1 );
683 }
684 internal_vector = (libfdata_internal_vector_t *) vector;
685
686 if( libfdata_segments_array_get_segment_by_index(
687 internal_vector->segments_array,
688 segment_index,
689 segment_file_index,
690 segment_offset,
691 segment_size,
692 segment_flags,
693 error ) != 1 )
694 {
695 libcerror_error_set(
696 error,
697 LIBCERROR_ERROR_DOMAIN_RUNTIME,
698 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
699 "%s: unable to retrieve segment: %d.",
700 function,
701 segment_index );
702
703 return( -1 );
704 }
705 return( 1 );
706 }
707
708 /* Sets the offset and size of a specific segment
709 * Returns 1 if successful or -1 on error
710 */
libfdata_vector_set_segment_by_index(libfdata_vector_t * vector,int segment_index,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)711 int libfdata_vector_set_segment_by_index(
712 libfdata_vector_t *vector,
713 int segment_index,
714 int segment_file_index,
715 off64_t segment_offset,
716 size64_t segment_size,
717 uint32_t segment_flags,
718 libcerror_error_t **error )
719 {
720 libfdata_internal_vector_t *internal_vector = NULL;
721 static char *function = "libfdata_vector_set_segment_by_index";
722
723 if( vector == NULL )
724 {
725 libcerror_error_set(
726 error,
727 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
728 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
729 "%s: invalid vector.",
730 function );
731
732 return( -1 );
733 }
734 internal_vector = (libfdata_internal_vector_t *) vector;
735
736 if( libfdata_segments_array_set_segment_by_index(
737 internal_vector->segments_array,
738 internal_vector->mapped_ranges_array,
739 &( internal_vector->size ),
740 segment_index,
741 segment_file_index,
742 segment_offset,
743 segment_size,
744 segment_flags,
745 error ) != 1 )
746 {
747 libcerror_error_set(
748 error,
749 LIBCERROR_ERROR_DOMAIN_RUNTIME,
750 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
751 "%s: unable to set segment: %d.",
752 function,
753 segment_index );
754
755 return( -1 );
756 }
757 internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
758
759 return( 1 );
760 }
761
762 /* Prepends a segment
763 * Returns 1 if successful or -1 on error
764 */
libfdata_vector_prepend_segment(libfdata_vector_t * vector,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)765 int libfdata_vector_prepend_segment(
766 libfdata_vector_t *vector,
767 int segment_file_index,
768 off64_t segment_offset,
769 size64_t segment_size,
770 uint32_t segment_flags,
771 libcerror_error_t **error )
772 {
773 libfdata_internal_vector_t *internal_vector = NULL;
774 static char *function = "libfdata_vector_prepend_segment";
775
776 if( vector == NULL )
777 {
778 libcerror_error_set(
779 error,
780 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
781 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
782 "%s: invalid vector.",
783 function );
784
785 return( -1 );
786 }
787 internal_vector = (libfdata_internal_vector_t *) vector;
788
789 if( libfdata_segments_array_prepend_segment(
790 internal_vector->segments_array,
791 internal_vector->mapped_ranges_array,
792 &( internal_vector->size ),
793 segment_file_index,
794 segment_offset,
795 segment_size,
796 segment_flags,
797 error ) != 1 )
798 {
799 libcerror_error_set(
800 error,
801 LIBCERROR_ERROR_DOMAIN_RUNTIME,
802 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
803 "%s: unable to prepend segment.",
804 function );
805
806 return( -1 );
807 }
808 internal_vector->flags |= LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES;
809
810 return( 1 );
811 }
812
813 /* Appends a segment
814 * Returns 1 if successful or -1 on error
815 */
libfdata_vector_append_segment(libfdata_vector_t * vector,int * segment_index,int segment_file_index,off64_t segment_offset,size64_t segment_size,uint32_t segment_flags,libcerror_error_t ** error)816 int libfdata_vector_append_segment(
817 libfdata_vector_t *vector,
818 int *segment_index,
819 int segment_file_index,
820 off64_t segment_offset,
821 size64_t segment_size,
822 uint32_t segment_flags,
823 libcerror_error_t **error )
824 {
825 libfdata_internal_vector_t *internal_vector = NULL;
826 static char *function = "libfdata_vector_append_segment";
827
828 if( vector == NULL )
829 {
830 libcerror_error_set(
831 error,
832 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
833 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
834 "%s: invalid vector.",
835 function );
836
837 return( -1 );
838 }
839 internal_vector = (libfdata_internal_vector_t *) vector;
840
841 if( libfdata_segments_array_append_segment(
842 internal_vector->segments_array,
843 internal_vector->mapped_ranges_array,
844 &( internal_vector->size ),
845 segment_index,
846 segment_file_index,
847 segment_offset,
848 segment_size,
849 segment_flags,
850 error ) != 1 )
851 {
852 libcerror_error_set(
853 error,
854 LIBCERROR_ERROR_DOMAIN_RUNTIME,
855 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
856 "%s: unable to append segment.",
857 function );
858
859 return( -1 );
860 }
861 return( 1 );
862 }
863
864 /* Vector element functions
865 */
866
867 /* Retrieves the element data size of the vector
868 * Returns 1 if successful or -1 on error
869 */
libfdata_vector_get_element_data_size(libfdata_vector_t * vector,size64_t * element_data_size,libcerror_error_t ** error)870 int libfdata_vector_get_element_data_size(
871 libfdata_vector_t *vector,
872 size64_t *element_data_size,
873 libcerror_error_t **error )
874 {
875 libfdata_internal_vector_t *internal_vector = NULL;
876 static char *function = "libfdata_vector_get_element_data_size";
877
878 if( vector == NULL )
879 {
880 libcerror_error_set(
881 error,
882 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
883 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
884 "%s: invalid vector.",
885 function );
886
887 return( -1 );
888 }
889 internal_vector = (libfdata_internal_vector_t *) vector;
890
891 if( element_data_size == NULL )
892 {
893 libcerror_error_set(
894 error,
895 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
896 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
897 "%s: invalid element data size.",
898 function );
899
900 return( -1 );
901 }
902 *element_data_size = internal_vector->element_data_size;
903
904 return( 1 );
905 }
906
907 /* Retrieves the number of elements of the vector
908 * Returns 1 if successful or -1 on error
909 */
libfdata_vector_get_number_of_elements(libfdata_vector_t * vector,int * number_of_elements,libcerror_error_t ** error)910 int libfdata_vector_get_number_of_elements(
911 libfdata_vector_t *vector,
912 int *number_of_elements,
913 libcerror_error_t **error )
914 {
915 libfdata_internal_vector_t *internal_vector = NULL;
916 static char *function = "libfdata_vector_get_number_of_elements";
917 size64_t safe_number_of_elements = 0;
918
919 if( vector == NULL )
920 {
921 libcerror_error_set(
922 error,
923 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
924 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
925 "%s: invalid vector.",
926 function );
927
928 return( -1 );
929 }
930 internal_vector = (libfdata_internal_vector_t *) vector;
931
932 if( internal_vector->element_data_size == 0 )
933 {
934 libcerror_error_set(
935 error,
936 LIBCERROR_ERROR_DOMAIN_RUNTIME,
937 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
938 "%s: invalid vector - element data size value out of bounds.",
939 function );
940
941 return( -1 );
942 }
943 if( number_of_elements == NULL )
944 {
945 libcerror_error_set(
946 error,
947 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
948 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
949 "%s: invalid number of elements.",
950 function );
951
952 return( -1 );
953 }
954 safe_number_of_elements = internal_vector->size / internal_vector->element_data_size;
955
956 if( ( internal_vector->size % internal_vector->element_data_size ) != 0 )
957 {
958 safe_number_of_elements++;
959 }
960 if( safe_number_of_elements > (size64_t) INT_MAX )
961 {
962 libcerror_error_set(
963 error,
964 LIBCERROR_ERROR_DOMAIN_RUNTIME,
965 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
966 "%s: number of elements value out of bounds.",
967 function );
968
969 return( -1 );
970 }
971 *number_of_elements = (int) safe_number_of_elements;
972
973 return( 1 );
974 }
975
976 /* Mapped range functions
977 */
978
979 /* Retrieves the element index for a specific offset
980 * Returns 1 if successful or -1 on error
981 */
libfdata_vector_get_element_index_at_offset(libfdata_vector_t * vector,off64_t element_value_offset,int * element_index,off64_t * element_data_offset,libcerror_error_t ** error)982 int libfdata_vector_get_element_index_at_offset(
983 libfdata_vector_t *vector,
984 off64_t element_value_offset,
985 int *element_index,
986 off64_t *element_data_offset,
987 libcerror_error_t **error )
988 {
989 libfdata_internal_vector_t *internal_vector = NULL;
990 libfdata_mapped_range_t *mapped_range = NULL;
991 static char *function = "libfdata_vector_get_element_index_at_offset";
992 off64_t mapped_range_end_offset = 0;
993 off64_t mapped_range_start_offset = 0;
994 off64_t segment_data_offset = 0;
995 size64_t mapped_range_size = 0;
996 uint64_t calculated_element_index = 0;
997 int initial_segment_index = 0;
998 int number_of_segments = 0;
999 int segment_index = 0;
1000 int result = 0;
1001
1002 #if defined( HAVE_DEBUG_OUTPUT )
1003 libfdata_range_t *segment_data_range = NULL;
1004 off64_t segment_offset = 0;
1005 size64_t segment_size = 0;
1006 uint32_t segment_flags = 0;
1007 int segment_file_index = -1;
1008 #endif
1009
1010 if( vector == NULL )
1011 {
1012 libcerror_error_set(
1013 error,
1014 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1015 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1016 "%s: invalid vector.",
1017 function );
1018
1019 return( -1 );
1020 }
1021 internal_vector = (libfdata_internal_vector_t *) vector;
1022
1023 if( internal_vector->element_data_size == 0 )
1024 {
1025 libcerror_error_set(
1026 error,
1027 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1028 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1029 "%s: invalid vector - element data size value out of bounds.",
1030 function );
1031
1032 return( -1 );
1033 }
1034 if( internal_vector->size == 0 )
1035 {
1036 libcerror_error_set(
1037 error,
1038 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1040 "%s: invalid vector - size value out of bounds.",
1041 function );
1042
1043 return( -1 );
1044 }
1045 if( element_value_offset < 0 )
1046 {
1047 libcerror_error_set(
1048 error,
1049 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1050 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
1051 "%s: invalid element value offset value less than zero.",
1052 function );
1053
1054 return( -1 );
1055 }
1056 if( element_index == NULL )
1057 {
1058 libcerror_error_set(
1059 error,
1060 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1061 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1062 "%s: invalid element index.",
1063 function );
1064
1065 return( -1 );
1066 }
1067 if( element_data_offset == NULL )
1068 {
1069 libcerror_error_set(
1070 error,
1071 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1072 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1073 "%s: invalid element data offset.",
1074 function );
1075
1076 return( -1 );
1077 }
1078 if( ( internal_vector->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1079 {
1080 if( libfdata_segments_array_calculate_mapped_ranges(
1081 internal_vector->segments_array,
1082 internal_vector->mapped_ranges_array,
1083 error ) != 1 )
1084 {
1085 libcerror_error_set(
1086 error,
1087 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1088 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1089 "%s: unable to calculate mapped ranges from segments array.",
1090 function );
1091
1092 return( -1 );
1093 }
1094 internal_vector->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
1095 }
1096 #if defined( HAVE_DEBUG_OUTPUT )
1097 if( libcnotify_verbose != 0 )
1098 {
1099 libcnotify_printf(
1100 "%s: requested offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1101 function,
1102 element_value_offset,
1103 element_value_offset );
1104 }
1105 #endif
1106 if( internal_vector->size == 0 )
1107 {
1108 return( 0 );
1109 }
1110 if( libcdata_array_get_number_of_entries(
1111 internal_vector->mapped_ranges_array,
1112 &number_of_segments,
1113 error ) != 1 )
1114 {
1115 libcerror_error_set(
1116 error,
1117 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1118 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1119 "%s: unable to retrieve number of entries from mapped ranges array.",
1120 function );
1121
1122 return( -1 );
1123 }
1124 /* This assumes a fairly even distribution of the sizes of the segments
1125 */
1126 initial_segment_index = (int) ( ( number_of_segments * element_value_offset ) / internal_vector->size );
1127
1128 /* Look for the corresponding segment upwards in the array
1129 */
1130 for( segment_index = initial_segment_index;
1131 segment_index < number_of_segments;
1132 segment_index++ )
1133 {
1134 if( libcdata_array_get_entry_by_index(
1135 internal_vector->mapped_ranges_array,
1136 segment_index,
1137 (intptr_t **) &mapped_range,
1138 error ) != 1 )
1139 {
1140 libcerror_error_set(
1141 error,
1142 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1143 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1144 "%s: unable to retrieve entry: %d from mapped ranges array.",
1145 function,
1146 segment_index );
1147
1148 return( -1 );
1149 }
1150 if( libfdata_mapped_range_get(
1151 mapped_range,
1152 &mapped_range_start_offset,
1153 &mapped_range_size,
1154 error ) != 1 )
1155 {
1156 libcerror_error_set(
1157 error,
1158 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1160 "%s: unable to retrieve values from mapped range: %d.",
1161 function,
1162 segment_index );
1163
1164 return( -1 );
1165 }
1166 mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
1167
1168 if( mapped_range_end_offset < mapped_range_start_offset )
1169 {
1170 libcerror_error_set(
1171 error,
1172 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1173 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1174 "%s: invalid segment: %d - mapped range value out of bounds.",
1175 function,
1176 segment_index );
1177
1178 return( -1 );
1179 }
1180 #if defined( HAVE_DEBUG_OUTPUT )
1181 if( libcnotify_verbose != 0 )
1182 {
1183 libcnotify_printf(
1184 "%s: segment: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1185 function,
1186 segment_index,
1187 mapped_range_start_offset,
1188 mapped_range_end_offset,
1189 mapped_range_start_offset,
1190 mapped_range_end_offset,
1191 mapped_range_size );
1192 }
1193 #endif
1194 /* Check if the element value offset is in the mapped range
1195 */
1196 if( ( element_value_offset >= mapped_range_start_offset )
1197 && ( element_value_offset < mapped_range_end_offset ) )
1198 {
1199 break;
1200 }
1201 /* Check if the element value offset is out of bounds
1202 */
1203 if( element_value_offset < mapped_range_start_offset )
1204 {
1205 segment_index = number_of_segments;
1206
1207 break;
1208 }
1209 }
1210 if( segment_index >= number_of_segments )
1211 {
1212 /* Look for the corresponding segment downwards in the array
1213 */
1214 for( segment_index = initial_segment_index;
1215 segment_index >= 0;
1216 segment_index-- )
1217 {
1218 if( libcdata_array_get_entry_by_index(
1219 internal_vector->mapped_ranges_array,
1220 segment_index,
1221 (intptr_t **) &mapped_range,
1222 error ) != 1 )
1223 {
1224 libcerror_error_set(
1225 error,
1226 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1227 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1228 "%s: unable to retrieve entry: %d from mapped ranges array.",
1229 function,
1230 segment_index );
1231
1232 return( -1 );
1233 }
1234 if( libfdata_mapped_range_get(
1235 mapped_range,
1236 &mapped_range_start_offset,
1237 &mapped_range_size,
1238 error ) != 1 )
1239 {
1240 libcerror_error_set(
1241 error,
1242 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1243 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1244 "%s: unable to retrieve values from mapped range: %d.",
1245 function,
1246 segment_index );
1247
1248 return( -1 );
1249 }
1250 mapped_range_end_offset = mapped_range_start_offset + (off64_t) mapped_range_size;
1251
1252 if( mapped_range_end_offset < mapped_range_start_offset )
1253 {
1254 libcerror_error_set(
1255 error,
1256 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1257 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1258 "%s: invalid segment: %d - mapped range value out of bounds.",
1259 function,
1260 segment_index );
1261
1262 return( -1 );
1263 }
1264 #if defined( HAVE_DEBUG_OUTPUT )
1265 if( libcnotify_verbose != 0 )
1266 {
1267 libcnotify_printf(
1268 "%s: segment: %03d\tmapped range: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1269 function,
1270 segment_index,
1271 mapped_range_start_offset,
1272 mapped_range_end_offset,
1273 mapped_range_start_offset,
1274 mapped_range_end_offset,
1275 mapped_range_size );
1276 }
1277 #endif
1278 /* Check if the element value offset is in the mapped range
1279 */
1280 if( ( element_value_offset >= mapped_range_start_offset )
1281 && ( element_value_offset < mapped_range_end_offset ) )
1282 {
1283 break;
1284 }
1285 /* Check if the element value offset is out of bounds
1286 */
1287 if( element_value_offset > mapped_range_start_offset )
1288 {
1289 segment_index = -1;
1290
1291 break;
1292 }
1293 segment_data_offset += (off64_t) mapped_range_size;
1294 }
1295 }
1296 if( ( segment_index >= 0 )
1297 && ( segment_index < number_of_segments ) )
1298 {
1299 #if defined( HAVE_DEBUG_OUTPUT )
1300 if( libcnotify_verbose != 0 )
1301 {
1302 if( libcdata_array_get_entry_by_index(
1303 internal_vector->segments_array,
1304 segment_index,
1305 (intptr_t **) &segment_data_range,
1306 error ) != 1 )
1307 {
1308 libcerror_error_set(
1309 error,
1310 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1311 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1312 "%s: unable to retrieve entry: %d from segments array.",
1313 function,
1314 segment_index );
1315
1316 return( -1 );
1317 }
1318 if( libfdata_range_get(
1319 segment_data_range,
1320 &segment_file_index,
1321 &segment_offset,
1322 &segment_size,
1323 &segment_flags,
1324 error ) != 1 )
1325 {
1326 libcerror_error_set(
1327 error,
1328 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1329 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1330 "%s: unable to retrieve segment: %d data range values.",
1331 function,
1332 segment_index );
1333
1334 return( -1 );
1335 }
1336 libcnotify_printf(
1337 "%s: segment: %03d\tfile index: %03d offset: %" PRIi64 " - %" PRIi64 " (0x%08" PRIx64 " - 0x%08" PRIx64 ") (size: %" PRIu64 ")\n",
1338 function,
1339 segment_index,
1340 segment_file_index,
1341 segment_offset,
1342 segment_offset + segment_size,
1343 segment_offset,
1344 segment_offset + segment_size,
1345 segment_size );
1346 }
1347 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1348
1349 calculated_element_index = (uint64_t) element_value_offset / internal_vector->element_data_size;
1350
1351 if( calculated_element_index > (uint64_t) INT_MAX )
1352 {
1353 libcerror_error_set(
1354 error,
1355 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1356 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1357 "%s: invalid element index value exceeds maximum.",
1358 function );
1359
1360 return( -1 );
1361 }
1362 /* The element data offset is relative from the start of the vector element not the underlying segment
1363 */
1364 *element_index = (int) calculated_element_index;
1365 *element_data_offset = element_value_offset % internal_vector->element_data_size;
1366
1367 result = 1;
1368 }
1369 #if defined( HAVE_DEBUG_OUTPUT )
1370 if( libcnotify_verbose != 0 )
1371 {
1372 libcnotify_printf(
1373 "\n" );
1374 }
1375 #endif
1376 return( result );
1377 }
1378
1379 /* Vector element value functions
1380 */
1381
1382 /* Retrieves the value of a specific element
1383 * Returns 1 if successful or -1 on error
1384 */
libfdata_vector_get_element_value_by_index(libfdata_vector_t * vector,intptr_t * file_io_handle,libfdata_cache_t * cache,int element_index,intptr_t ** element_value,uint8_t read_flags,libcerror_error_t ** error)1385 int libfdata_vector_get_element_value_by_index(
1386 libfdata_vector_t *vector,
1387 intptr_t *file_io_handle,
1388 libfdata_cache_t *cache,
1389 int element_index,
1390 intptr_t **element_value,
1391 uint8_t read_flags,
1392 libcerror_error_t **error )
1393 {
1394 libfcache_cache_value_t *cache_value = NULL;
1395 libfdata_internal_vector_t *internal_vector = NULL;
1396 libfdata_range_t *segment_data_range = NULL;
1397 static char *function = "libfdata_vector_get_element_value_by_index";
1398 off64_t cache_value_offset = (off64_t) -1;
1399 off64_t element_data_offset = 0;
1400 int64_t cache_value_timestamp = 0;
1401 uint32_t element_data_flags = 0;
1402 int cache_value_file_index = -1;
1403 int element_data_file_index = -1;
1404 int result = 0;
1405
1406 #if defined( HAVE_DEBUG_OUTPUT )
1407 const char *hit_or_miss = NULL;
1408 #endif
1409
1410 if( vector == NULL )
1411 {
1412 libcerror_error_set(
1413 error,
1414 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1415 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1416 "%s: invalid vector.",
1417 function );
1418
1419 return( -1 );
1420 }
1421 internal_vector = (libfdata_internal_vector_t *) vector;
1422
1423 if( internal_vector->read_element_data == NULL )
1424 {
1425 libcerror_error_set(
1426 error,
1427 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1428 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1429 "%s: invalid vector - missing read element data function.",
1430 function );
1431
1432 return( -1 );
1433 }
1434 if( internal_vector->element_data_size == 0 )
1435 {
1436 libcerror_error_set(
1437 error,
1438 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1439 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1440 "%s: invalid vector - element data size value out of bounds.",
1441 function );
1442
1443 return( -1 );
1444 }
1445 if( ( internal_vector->size == 0 )
1446 || ( internal_vector->size > (off64_t) INT64_MAX ) )
1447 {
1448 libcerror_error_set(
1449 error,
1450 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1451 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1452 "%s: invalid vector - size value out of bounds.",
1453 function );
1454
1455 return( -1 );
1456 }
1457 if( ( element_index < 0 )
1458 || ( (uint64_t) element_index > ( (uint64_t) INT64_MAX / internal_vector->element_data_size ) ) )
1459 {
1460 libcerror_error_set(
1461 error,
1462 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1463 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1464 "%s: invalid element index value out of bounds.",
1465 function );
1466
1467 return( -1 );
1468 }
1469 element_data_offset = (off64_t) ( element_index * internal_vector->element_data_size );
1470
1471 if( (size64_t) element_data_offset > internal_vector->size )
1472 {
1473 libcerror_error_set(
1474 error,
1475 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1477 "%s: invalid element index value out of bounds.",
1478 function );
1479
1480 return( -1 );
1481 }
1482 if( libfdata_segments_array_get_data_range_at_offset(
1483 internal_vector->segments_array,
1484 element_data_offset,
1485 &element_data_offset,
1486 &segment_data_range,
1487 error ) != 1 )
1488 {
1489 libcerror_error_set(
1490 error,
1491 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1492 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1493 "%s: unable to retrieve segment data range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
1494 function,
1495 element_data_offset,
1496 element_data_offset );
1497
1498 return( -1 );
1499 }
1500 if( segment_data_range == NULL )
1501 {
1502 libcerror_error_set(
1503 error,
1504 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1505 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1506 "%s: missing segment data range.",
1507 function );
1508
1509 return( -1 );
1510 }
1511 if( segment_data_range->offset > ( (off64_t) INT64_MAX - element_data_offset ) )
1512 {
1513 libcerror_error_set(
1514 error,
1515 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1516 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1517 "%s: invalid element data offset value out of bounds.",
1518 function );
1519
1520 return( -1 );
1521 }
1522 element_data_file_index = segment_data_range->file_index;
1523 element_data_offset += segment_data_range->offset;
1524 element_data_flags = segment_data_range->flags;
1525
1526 if( ( read_flags & LIBFDATA_READ_FLAG_IGNORE_CACHE ) == 0 )
1527 {
1528 result = libfcache_cache_get_value_by_identifier(
1529 (libfcache_cache_t *) cache,
1530 element_data_file_index,
1531 element_data_offset,
1532 internal_vector->timestamp,
1533 &cache_value,
1534 error );
1535
1536 if( result == -1 )
1537 {
1538 libcerror_error_set(
1539 error,
1540 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1541 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1542 "%s: unable to retrieve value from cache.",
1543 function );
1544
1545 return( -1 );
1546 }
1547 #if defined( HAVE_DEBUG_OUTPUT )
1548 if( libcnotify_verbose != 0 )
1549 {
1550 if( result == 0 )
1551 {
1552 hit_or_miss = "miss";
1553 }
1554 else
1555 {
1556 hit_or_miss = "hit";
1557 }
1558 libcnotify_printf(
1559 "%s: cache: 0x%08" PRIjx " %s\n",
1560 function,
1561 (intptr_t) cache,
1562 hit_or_miss );
1563 }
1564 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1565 }
1566 if( result == 0 )
1567 {
1568 #if defined( HAVE_DEBUG_OUTPUT )
1569 if( libcnotify_verbose != 0 )
1570 {
1571 libcnotify_printf(
1572 "%s: reading element data at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIu64 "\n",
1573 function,
1574 element_data_offset,
1575 element_data_offset,
1576 internal_vector->element_data_size );
1577 }
1578 #endif
1579 if( internal_vector->read_element_data(
1580 internal_vector->data_handle,
1581 file_io_handle,
1582 vector,
1583 cache,
1584 element_index,
1585 element_data_file_index,
1586 element_data_offset,
1587 internal_vector->element_data_size,
1588 element_data_flags,
1589 read_flags,
1590 error ) != 1 )
1591 {
1592 libcerror_error_set(
1593 error,
1594 LIBCERROR_ERROR_DOMAIN_IO,
1595 LIBCERROR_IO_ERROR_READ_FAILED,
1596 "%s: unable to read element data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1597 function,
1598 element_data_offset,
1599 element_data_offset );
1600
1601 return( -1 );
1602 }
1603 if( libfcache_cache_get_value_by_identifier(
1604 (libfcache_cache_t *) cache,
1605 element_data_file_index,
1606 element_data_offset,
1607 internal_vector->timestamp,
1608 &cache_value,
1609 error ) != 1 )
1610 {
1611 libcerror_error_set(
1612 error,
1613 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1614 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1615 "%s: unable to retrieve value from cache.",
1616 function );
1617
1618 return( -1 );
1619 }
1620 if( libfcache_cache_value_get_identifier(
1621 cache_value,
1622 &cache_value_file_index,
1623 &cache_value_offset,
1624 &cache_value_timestamp,
1625 error ) != 1 )
1626 {
1627 libcerror_error_set(
1628 error,
1629 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1630 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1631 "%s: unable to retrieve cache value identifier.",
1632 function );
1633
1634 return( -1 );
1635 }
1636 if( ( element_data_file_index != cache_value_file_index )
1637 || ( element_data_offset != cache_value_offset )
1638 || ( internal_vector->timestamp != cache_value_timestamp ) )
1639 {
1640 libcerror_error_set(
1641 error,
1642 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1643 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1644 "%s: invalid cache value - identifier value out of bounds.",
1645 function );
1646
1647 return( -1 );
1648 }
1649 }
1650 if( libfcache_cache_value_get_value(
1651 cache_value,
1652 element_value,
1653 error ) != 1 )
1654 {
1655 libcerror_error_set(
1656 error,
1657 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1658 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1659 "%s: unable to retrieve element value.",
1660 function );
1661
1662 return( -1 );
1663 }
1664 return( 1 );
1665 }
1666
1667 /* Retrieves the value an element at a specific offset
1668 * Returns 1 if successful or -1 on error
1669 */
libfdata_vector_get_element_value_at_offset(libfdata_vector_t * vector,intptr_t * file_io_handle,libfdata_cache_t * cache,off64_t element_value_offset,off64_t * element_data_offset,intptr_t ** element_value,uint8_t read_flags,libcerror_error_t ** error)1670 int libfdata_vector_get_element_value_at_offset(
1671 libfdata_vector_t *vector,
1672 intptr_t *file_io_handle,
1673 libfdata_cache_t *cache,
1674 off64_t element_value_offset,
1675 off64_t *element_data_offset,
1676 intptr_t **element_value,
1677 uint8_t read_flags,
1678 libcerror_error_t **error )
1679 {
1680 static char *function = "libfdata_vector_get_element_value_at_offset";
1681 int element_index = 0;
1682
1683 if( libfdata_vector_get_element_index_at_offset(
1684 vector,
1685 element_value_offset,
1686 &element_index,
1687 element_data_offset,
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 element index at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1695 function,
1696 element_value_offset,
1697 element_value_offset );
1698
1699 return( -1 );
1700 }
1701 if( libfdata_vector_get_element_value_by_index(
1702 vector,
1703 file_io_handle,
1704 cache,
1705 element_index,
1706 element_value,
1707 read_flags,
1708 error ) != 1 )
1709 {
1710 libcerror_error_set(
1711 error,
1712 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1713 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1714 "%s: unable to retrieve element: %d value.",
1715 function,
1716 element_index );
1717
1718 return( -1 );
1719 }
1720 return( 1 );
1721 }
1722
1723 /* Sets the value of a specific element
1724 *
1725 * If the flag LIBFDATA_VECTOR_ELEMENT_VALUE_FLAG_MANAGED is set the vector
1726 * takes over management of the value and the value is freed when
1727 * no longer needed.
1728 *
1729 * Returns 1 if successful or -1 on error
1730 */
libfdata_vector_set_element_value_by_index(libfdata_vector_t * vector,intptr_t * file_io_handle LIBFDATA_ATTRIBUTE_UNUSED,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)1731 int libfdata_vector_set_element_value_by_index(
1732 libfdata_vector_t *vector,
1733 intptr_t *file_io_handle LIBFDATA_ATTRIBUTE_UNUSED,
1734 libfdata_cache_t *cache,
1735 int element_index,
1736 intptr_t *element_value,
1737 int (*free_element_value)(
1738 intptr_t **element_value,
1739 libcerror_error_t **error ),
1740 uint8_t write_flags,
1741 libcerror_error_t **error )
1742 {
1743 libfdata_internal_vector_t *internal_vector = NULL;
1744 libfdata_range_t *segment_data_range = NULL;
1745 static char *function = "libfdata_vector_set_element_value_by_index";
1746 off64_t element_data_offset = 0;
1747
1748 LIBFDATA_UNREFERENCED_PARAMETER( file_io_handle )
1749
1750 if( vector == NULL )
1751 {
1752 libcerror_error_set(
1753 error,
1754 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1755 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1756 "%s: invalid vector.",
1757 function );
1758
1759 return( -1 );
1760 }
1761 internal_vector = (libfdata_internal_vector_t *) vector;
1762
1763 if( internal_vector->element_data_size == 0 )
1764 {
1765 libcerror_error_set(
1766 error,
1767 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1769 "%s: invalid vector - element data size value out of bounds.",
1770 function );
1771
1772 return( -1 );
1773 }
1774 if( ( internal_vector->size == 0 )
1775 || ( internal_vector->size > (off64_t) INT64_MAX ) )
1776 {
1777 libcerror_error_set(
1778 error,
1779 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1780 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1781 "%s: invalid vector - size value out of bounds.",
1782 function );
1783
1784 return( -1 );
1785 }
1786 if( ( element_index < 0 )
1787 || ( (uint64_t) element_index > ( (uint64_t) INT64_MAX / internal_vector->element_data_size ) ) )
1788 {
1789 libcerror_error_set(
1790 error,
1791 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1792 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1793 "%s: invalid element index value out of bounds.",
1794 function );
1795
1796 return( -1 );
1797 }
1798 element_data_offset = (off64_t) ( element_index * internal_vector->element_data_size );
1799
1800 if( (size64_t) element_data_offset > internal_vector->size )
1801 {
1802 libcerror_error_set(
1803 error,
1804 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1805 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1806 "%s: invalid element index value out of bounds.",
1807 function );
1808
1809 return( -1 );
1810 }
1811 if( libfdata_segments_array_get_data_range_at_offset(
1812 internal_vector->segments_array,
1813 element_data_offset,
1814 &element_data_offset,
1815 &segment_data_range,
1816 error ) != 1 )
1817 {
1818 libcerror_error_set(
1819 error,
1820 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1821 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1822 "%s: unable to retrieve segment data range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
1823 function,
1824 element_data_offset,
1825 element_data_offset );
1826
1827 return( -1 );
1828 }
1829 if( segment_data_range == NULL )
1830 {
1831 libcerror_error_set(
1832 error,
1833 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1834 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1835 "%s: missing segment data range.",
1836 function );
1837
1838 return( -1 );
1839 }
1840 if( segment_data_range->offset > ( (off64_t) INT64_MAX - element_data_offset ) )
1841 {
1842 libcerror_error_set(
1843 error,
1844 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1845 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1846 "%s: invalid element data offset value out of bounds.",
1847 function );
1848
1849 return( -1 );
1850 }
1851 element_data_offset += segment_data_range->offset;
1852
1853 if( libfcache_cache_set_value_by_identifier(
1854 (libfcache_cache_t *) cache,
1855 segment_data_range->file_index,
1856 element_data_offset,
1857 internal_vector->timestamp,
1858 element_value,
1859 free_element_value,
1860 write_flags,
1861 error ) != 1 )
1862 {
1863 libcerror_error_set(
1864 error,
1865 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1866 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1867 "%s: unable to set value in cache.",
1868 function );
1869
1870 return( -1 );
1871 }
1872 return( 1 );
1873 }
1874
1875 /* Retrieves the size
1876 * Returns 1 if successful or -1 on error
1877 */
libfdata_vector_get_size(libfdata_vector_t * vector,size64_t * size,libcerror_error_t ** error)1878 int libfdata_vector_get_size(
1879 libfdata_vector_t *vector,
1880 size64_t *size,
1881 libcerror_error_t **error )
1882 {
1883 libfdata_internal_vector_t *internal_vector = NULL;
1884 static char *function = "libfdata_vector_get_size";
1885
1886 if( vector == NULL )
1887 {
1888 libcerror_error_set(
1889 error,
1890 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1891 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1892 "%s: invalid vector.",
1893 function );
1894
1895 return( -1 );
1896 }
1897 internal_vector = (libfdata_internal_vector_t *) vector;
1898
1899 if( size == NULL )
1900 {
1901 libcerror_error_set(
1902 error,
1903 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1904 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1905 "%s: invalid size.",
1906 function );
1907
1908 return( -1 );
1909 }
1910 if( ( internal_vector->flags & LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES ) != 0 )
1911 {
1912 if( libfdata_segments_array_calculate_mapped_ranges(
1913 internal_vector->segments_array,
1914 internal_vector->mapped_ranges_array,
1915 error ) != 1 )
1916 {
1917 libcerror_error_set(
1918 error,
1919 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1920 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1921 "%s: unable to calculate mapped ranges.",
1922 function );
1923
1924 return( -1 );
1925 }
1926 internal_vector->flags &= ~( LIBFDATA_FLAG_CALCULATE_MAPPED_RANGES );
1927 }
1928 *size = internal_vector->size;
1929
1930 return( 1 );
1931 }
1932
1933