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