/src/libpff/libpff/libpff_item_tree.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Item tree functions |
3 | | * |
4 | | * Copyright (C) 2008-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 "libpff_definitions.h" |
27 | | #include "libpff_descriptors_index.h" |
28 | | #include "libpff_index_value.h" |
29 | | #include "libpff_item_descriptor.h" |
30 | | #include "libpff_libbfio.h" |
31 | | #include "libpff_libcdata.h" |
32 | | #include "libpff_libcerror.h" |
33 | | #include "libpff_libcnotify.h" |
34 | | #include "libpff_item_descriptor.h" |
35 | | #include "libpff_item_tree.h" |
36 | | |
37 | | #include "pff_index_node.h" |
38 | | |
39 | | /* Creates an item tree |
40 | | * Make sure the value item_tree is referencing, is set to NULL |
41 | | * Returns 1 if successful or -1 on error |
42 | | */ |
43 | | int libpff_item_tree_initialize( |
44 | | libpff_item_tree_t **item_tree, |
45 | | libcerror_error_t **error ) |
46 | 8.81k | { |
47 | 8.81k | static char *function = "libpff_item_tree_initialize"; |
48 | | |
49 | 8.81k | if( item_tree == NULL ) |
50 | 0 | { |
51 | 0 | libcerror_error_set( |
52 | 0 | error, |
53 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
54 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
55 | 0 | "%s: invalid item tree.", |
56 | 0 | function ); |
57 | |
|
58 | 0 | return( -1 ); |
59 | 0 | } |
60 | 8.81k | if( *item_tree != NULL ) |
61 | 0 | { |
62 | 0 | libcerror_error_set( |
63 | 0 | error, |
64 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
65 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
66 | 0 | "%s: invalid item tree value already set.", |
67 | 0 | function ); |
68 | |
|
69 | 0 | return( -1 ); |
70 | 0 | } |
71 | 8.81k | *item_tree = memory_allocate_structure( |
72 | 8.81k | libpff_item_tree_t ); |
73 | | |
74 | 8.81k | if( *item_tree == NULL ) |
75 | 0 | { |
76 | 0 | libcerror_error_set( |
77 | 0 | error, |
78 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
79 | 0 | LIBCERROR_MEMORY_ERROR_INSUFFICIENT, |
80 | 0 | "%s: unable to create item tree.", |
81 | 0 | function ); |
82 | |
|
83 | 0 | goto on_error; |
84 | 0 | } |
85 | 8.81k | if( memory_set( |
86 | 8.81k | *item_tree, |
87 | 8.81k | 0, |
88 | 8.81k | sizeof( libpff_item_tree_t ) ) == NULL ) |
89 | 0 | { |
90 | 0 | libcerror_error_set( |
91 | 0 | error, |
92 | 0 | LIBCERROR_ERROR_DOMAIN_MEMORY, |
93 | 0 | LIBCERROR_MEMORY_ERROR_SET_FAILED, |
94 | 0 | "%s: unable to clear item tree.", |
95 | 0 | function ); |
96 | |
|
97 | 0 | goto on_error; |
98 | 0 | } |
99 | 8.81k | return( 1 ); |
100 | | |
101 | 0 | on_error: |
102 | 0 | if( *item_tree != NULL ) |
103 | 0 | { |
104 | 0 | memory_free( |
105 | 0 | *item_tree ); |
106 | |
|
107 | 0 | *item_tree = NULL; |
108 | 0 | } |
109 | 0 | return( -1 ); |
110 | 8.81k | } |
111 | | |
112 | | /* Frees an item tree |
113 | | * Returns 1 if successful or -1 on error |
114 | | */ |
115 | | int libpff_item_tree_free( |
116 | | libpff_item_tree_t **item_tree, |
117 | | libcerror_error_t **error ) |
118 | 8.81k | { |
119 | 8.81k | static char *function = "libpff_item_tree_free"; |
120 | 8.81k | int result = 1; |
121 | | |
122 | 8.81k | if( item_tree == NULL ) |
123 | 0 | { |
124 | 0 | libcerror_error_set( |
125 | 0 | error, |
126 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
127 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
128 | 0 | "%s: invalid item tree.", |
129 | 0 | function ); |
130 | |
|
131 | 0 | return( -1 ); |
132 | 0 | } |
133 | 8.81k | if( *item_tree != NULL ) |
134 | 8.81k | { |
135 | 8.81k | if( ( *item_tree )->root_node != NULL ) |
136 | 7.63k | { |
137 | 7.63k | if( libcdata_tree_node_free( |
138 | 7.63k | &( ( *item_tree )->root_node ), |
139 | 7.63k | (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, |
140 | 7.63k | error ) != 1 ) |
141 | 0 | { |
142 | 0 | libcerror_error_set( |
143 | 0 | error, |
144 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
145 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
146 | 0 | "%s: unable to free root node.", |
147 | 0 | function ); |
148 | |
|
149 | 0 | result = -1; |
150 | 0 | } |
151 | 7.63k | } |
152 | 8.81k | memory_free( |
153 | 8.81k | *item_tree ); |
154 | | |
155 | 8.81k | *item_tree = NULL; |
156 | 8.81k | } |
157 | 8.81k | return( result ); |
158 | 8.81k | } |
159 | | |
160 | | /* Frees a recovered item tree node |
161 | | * Returns 1 if successful or -1 on error |
162 | | */ |
163 | | int libpff_item_tree_node_free_recovered( |
164 | | libcdata_tree_node_t **item_tree_node, |
165 | | libcerror_error_t **error ) |
166 | 610k | { |
167 | 610k | static char *function = "libpff_item_tree_node_free_recovered"; |
168 | 610k | int result = 1; |
169 | | |
170 | 610k | if( item_tree_node == NULL ) |
171 | 0 | { |
172 | 0 | libcerror_error_set( |
173 | 0 | error, |
174 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
175 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
176 | 0 | "%s: invalid item tree node.", |
177 | 0 | function ); |
178 | |
|
179 | 0 | return( -1 ); |
180 | 0 | } |
181 | 610k | if( *item_tree_node != NULL ) |
182 | 610k | { |
183 | 610k | if( libcdata_tree_node_free( |
184 | 610k | item_tree_node, |
185 | 610k | (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, |
186 | 610k | error ) != 1 ) |
187 | 0 | { |
188 | 0 | libcerror_error_set( |
189 | 0 | error, |
190 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
191 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
192 | 0 | "%s: unable to free tree node.", |
193 | 0 | function ); |
194 | |
|
195 | 0 | result = -1; |
196 | 0 | } |
197 | 610k | } |
198 | 610k | return( result ); |
199 | 610k | } |
200 | | |
201 | | /* Retrieves the tree node of an item node |
202 | | * Returns 1 if successful, 0 if the item node was not found or -1 on error |
203 | | */ |
204 | | int libpff_item_tree_get_tree_node_by_identifier( |
205 | | libcdata_tree_node_t *item_tree_node, |
206 | | uint32_t item_identifier, |
207 | | libcdata_tree_node_t **result_item_tree_node, |
208 | | int recursion_depth, |
209 | | libcerror_error_t **error ) |
210 | 5.05M | { |
211 | 5.05M | libcdata_tree_node_t *sub_tree_node = NULL; |
212 | 5.05M | libpff_item_descriptor_t *item_descriptor = NULL; |
213 | 5.05M | static char *function = "libpff_item_tree_get_tree_node_by_identifier"; |
214 | 5.05M | int number_of_sub_nodes = 0; |
215 | 5.05M | int result = 0; |
216 | 5.05M | int sub_node_index = 0; |
217 | | |
218 | 5.05M | if( item_tree_node == NULL ) |
219 | 0 | { |
220 | 0 | libcerror_error_set( |
221 | 0 | error, |
222 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
223 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
224 | 0 | "%s: invalid item tree node.", |
225 | 0 | function ); |
226 | |
|
227 | 0 | return( -1 ); |
228 | 0 | } |
229 | 5.05M | if( ( recursion_depth < 0 ) |
230 | 5.05M | || ( recursion_depth > LIBPFF_MAXIMUM_ITEM_TREE_RECURSION_DEPTH ) ) |
231 | 0 | { |
232 | 0 | libcerror_error_set( |
233 | 0 | error, |
234 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
235 | 0 | LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, |
236 | 0 | "%s: invalid recursion depth value out of bounds.", |
237 | 0 | function ); |
238 | |
|
239 | 0 | return( -1 ); |
240 | 0 | } |
241 | 5.05M | if( libcdata_tree_node_get_value( |
242 | 5.05M | item_tree_node, |
243 | 5.05M | (intptr_t **) &item_descriptor, |
244 | 5.05M | error ) != 1 ) |
245 | 0 | { |
246 | 0 | libcerror_error_set( |
247 | 0 | error, |
248 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
249 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
250 | 0 | "%s: unable to retrieve item descriptor.", |
251 | 0 | function ); |
252 | |
|
253 | 0 | return( -1 ); |
254 | 0 | } |
255 | 5.05M | if( item_descriptor == NULL ) |
256 | 0 | { |
257 | 0 | libcerror_error_set( |
258 | 0 | error, |
259 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
260 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
261 | 0 | "%s: missing item descriptor.", |
262 | 0 | function ); |
263 | |
|
264 | 0 | return( -1 ); |
265 | 0 | } |
266 | 5.05M | if( item_descriptor->descriptor_identifier == item_identifier ) |
267 | 492k | { |
268 | 492k | if( result_item_tree_node == NULL ) |
269 | 0 | { |
270 | 0 | libcerror_error_set( |
271 | 0 | error, |
272 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
273 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
274 | 0 | "%s: invalid result item tree node.", |
275 | 0 | function ); |
276 | |
|
277 | 0 | return( -1 ); |
278 | 0 | } |
279 | 492k | if( *result_item_tree_node != NULL ) |
280 | 0 | { |
281 | 0 | libcerror_error_set( |
282 | 0 | error, |
283 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
284 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
285 | 0 | "%s: result item tree node already set.", |
286 | 0 | function ); |
287 | |
|
288 | 0 | return( -1 ); |
289 | 0 | } |
290 | 492k | *result_item_tree_node = item_tree_node; |
291 | | |
292 | 492k | return( 1 ); |
293 | 492k | } |
294 | 4.56M | if( libcdata_tree_node_get_number_of_sub_nodes( |
295 | 4.56M | item_tree_node, |
296 | 4.56M | &number_of_sub_nodes, |
297 | 4.56M | error ) != 1 ) |
298 | 0 | { |
299 | 0 | libcerror_error_set( |
300 | 0 | error, |
301 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
302 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
303 | 0 | "%s: unable to retrieve number of sub nodes.", |
304 | 0 | function ); |
305 | |
|
306 | 0 | return( -1 ); |
307 | 0 | } |
308 | 4.56M | if( number_of_sub_nodes > 0 ) |
309 | 1.38M | { |
310 | 1.38M | if( libcdata_tree_node_get_sub_node_by_index( |
311 | 1.38M | item_tree_node, |
312 | 1.38M | 0, |
313 | 1.38M | &sub_tree_node, |
314 | 1.38M | error ) != 1 ) |
315 | 0 | { |
316 | 0 | libcerror_error_set( |
317 | 0 | error, |
318 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
319 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
320 | 0 | "%s: unable to retrieve first sub node.", |
321 | 0 | function ); |
322 | |
|
323 | 0 | return( -1 ); |
324 | 0 | } |
325 | 1.38M | for( sub_node_index = 0; |
326 | 5.15M | sub_node_index < number_of_sub_nodes; |
327 | 3.77M | sub_node_index++ ) |
328 | 3.90M | { |
329 | 3.90M | if( sub_tree_node == NULL ) |
330 | 0 | { |
331 | 0 | libcerror_error_set( |
332 | 0 | error, |
333 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
334 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
335 | 0 | "%s: corruption detected for sub node: %d.", |
336 | 0 | function, |
337 | 0 | sub_node_index ); |
338 | |
|
339 | 0 | return( -1 ); |
340 | 0 | } |
341 | 3.90M | result = libpff_item_tree_get_tree_node_by_identifier( |
342 | 3.90M | sub_tree_node, |
343 | 3.90M | item_identifier, |
344 | 3.90M | result_item_tree_node, |
345 | 3.90M | recursion_depth + 1, |
346 | 3.90M | error ); |
347 | | |
348 | 3.90M | if( result == -1 ) |
349 | 0 | { |
350 | 0 | libcerror_error_set( |
351 | 0 | error, |
352 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
353 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
354 | 0 | "%s: unable to traverse sub node: %d.", |
355 | 0 | function, |
356 | 0 | sub_node_index ); |
357 | |
|
358 | 0 | return( -1 ); |
359 | 0 | } |
360 | 3.90M | else if( result != 0 ) |
361 | 134k | { |
362 | 134k | break; |
363 | 134k | } |
364 | 3.77M | if( libcdata_tree_node_get_next_node( |
365 | 3.77M | sub_tree_node, |
366 | 3.77M | &sub_tree_node, |
367 | 3.77M | error ) != 1 ) |
368 | 0 | { |
369 | 0 | libcerror_error_set( |
370 | 0 | error, |
371 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
372 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
373 | 0 | "%s: unable to retrieve next node of sub node: %d.", |
374 | 0 | function, |
375 | 0 | sub_node_index ); |
376 | |
|
377 | 0 | return( -1 ); |
378 | 0 | } |
379 | 3.77M | } |
380 | 1.38M | } |
381 | 4.56M | return( result ); |
382 | 4.56M | } |
383 | | |
384 | | /* Retrieves the sub node of an item node |
385 | | * Returns 1 if successful, 0 if the item node was not found or -1 on error |
386 | | */ |
387 | | int libpff_item_tree_get_sub_node_by_identifier( |
388 | | libcdata_tree_node_t *item_tree_node, |
389 | | uint32_t sub_node_identifier, |
390 | | libcdata_tree_node_t **sub_node, |
391 | | libcerror_error_t **error ) |
392 | 0 | { |
393 | 0 | libcdata_tree_node_t *sub_tree_node = NULL; |
394 | 0 | libpff_item_descriptor_t *item_descriptor = NULL; |
395 | 0 | static char *function = "libpff_item_tree_get_sub_node_by_identifier"; |
396 | 0 | int number_of_sub_nodes = 0; |
397 | 0 | int result = 0; |
398 | 0 | int sub_node_index = 0; |
399 | |
|
400 | 0 | if( item_tree_node == NULL ) |
401 | 0 | { |
402 | 0 | libcerror_error_set( |
403 | 0 | error, |
404 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
405 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
406 | 0 | "%s: invalid item tree node.", |
407 | 0 | function ); |
408 | |
|
409 | 0 | return( -1 ); |
410 | 0 | } |
411 | 0 | if( sub_node == NULL ) |
412 | 0 | { |
413 | 0 | libcerror_error_set( |
414 | 0 | error, |
415 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
416 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
417 | 0 | "%s: invalid sub node.", |
418 | 0 | function ); |
419 | |
|
420 | 0 | return( -1 ); |
421 | 0 | } |
422 | 0 | if( *sub_node != NULL ) |
423 | 0 | { |
424 | 0 | libcerror_error_set( |
425 | 0 | error, |
426 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
427 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
428 | 0 | "%s: sub node already set.", |
429 | 0 | function ); |
430 | |
|
431 | 0 | return( -1 ); |
432 | 0 | } |
433 | 0 | if( libcdata_tree_node_get_value( |
434 | 0 | item_tree_node, |
435 | 0 | (intptr_t **) &item_descriptor, |
436 | 0 | error ) != 1 ) |
437 | 0 | { |
438 | 0 | libcerror_error_set( |
439 | 0 | error, |
440 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
441 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
442 | 0 | "%s: unable to retrieve item descriptor.", |
443 | 0 | function ); |
444 | |
|
445 | 0 | return( -1 ); |
446 | 0 | } |
447 | 0 | if( item_descriptor == NULL ) |
448 | 0 | { |
449 | 0 | libcerror_error_set( |
450 | 0 | error, |
451 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
452 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
453 | 0 | "%s: missing item descriptor.", |
454 | 0 | function ); |
455 | |
|
456 | 0 | return( -1 ); |
457 | 0 | } |
458 | 0 | if( libcdata_tree_node_get_number_of_sub_nodes( |
459 | 0 | item_tree_node, |
460 | 0 | &number_of_sub_nodes, |
461 | 0 | error ) != 1 ) |
462 | 0 | { |
463 | 0 | libcerror_error_set( |
464 | 0 | error, |
465 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
466 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
467 | 0 | "%s: unable to retrieve number of sub nodes.", |
468 | 0 | function ); |
469 | |
|
470 | 0 | return( -1 ); |
471 | 0 | } |
472 | 0 | if( number_of_sub_nodes > 0 ) |
473 | 0 | { |
474 | 0 | if( libcdata_tree_node_get_sub_node_by_index( |
475 | 0 | item_tree_node, |
476 | 0 | 0, |
477 | 0 | &sub_tree_node, |
478 | 0 | error ) != 1 ) |
479 | 0 | { |
480 | 0 | libcerror_error_set( |
481 | 0 | error, |
482 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
483 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
484 | 0 | "%s: unable to retrieve first sub node.", |
485 | 0 | function ); |
486 | |
|
487 | 0 | return( -1 ); |
488 | 0 | } |
489 | 0 | for( sub_node_index = 0; |
490 | 0 | sub_node_index < number_of_sub_nodes; |
491 | 0 | sub_node_index++ ) |
492 | 0 | { |
493 | 0 | if( libcdata_tree_node_get_value( |
494 | 0 | sub_tree_node, |
495 | 0 | (intptr_t **) &item_descriptor, |
496 | 0 | error ) != 1 ) |
497 | 0 | { |
498 | 0 | libcerror_error_set( |
499 | 0 | error, |
500 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
501 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
502 | 0 | "%s: unable to retrieve item descriptor from sub node: %d.", |
503 | 0 | function, |
504 | 0 | sub_node_index ); |
505 | |
|
506 | 0 | return( -1 ); |
507 | 0 | } |
508 | 0 | if( item_descriptor == NULL ) |
509 | 0 | { |
510 | 0 | libcerror_error_set( |
511 | 0 | error, |
512 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
513 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
514 | 0 | "%s: missing sub item descriptor: %d.", |
515 | 0 | function, |
516 | 0 | sub_node_index ); |
517 | |
|
518 | 0 | return( -1 ); |
519 | 0 | } |
520 | 0 | if( item_descriptor->descriptor_identifier == sub_node_identifier ) |
521 | 0 | { |
522 | 0 | *sub_node = sub_tree_node; |
523 | |
|
524 | 0 | return( 1 ); |
525 | 0 | } |
526 | 0 | if( libcdata_tree_node_get_next_node( |
527 | 0 | sub_tree_node, |
528 | 0 | &sub_tree_node, |
529 | 0 | error ) != 1 ) |
530 | 0 | { |
531 | 0 | libcerror_error_set( |
532 | 0 | error, |
533 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
534 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
535 | 0 | "%s: unable to retrieve next node of sub node: %d.", |
536 | 0 | function, |
537 | 0 | sub_node_index ); |
538 | |
|
539 | 0 | return( -1 ); |
540 | 0 | } |
541 | 0 | } |
542 | 0 | } |
543 | 0 | return( result ); |
544 | 0 | } |
545 | | |
546 | | /* Appends the identifier of the item |
547 | | * Returns 1 if successful or -1 on error |
548 | | */ |
549 | | int libpff_item_tree_append_identifier( |
550 | | libcdata_tree_node_t *item_tree_node, |
551 | | uint32_t descriptor_identifier, |
552 | | uint64_t data_identifier, |
553 | | uint64_t local_descriptors_identifier, |
554 | | uint8_t recovered, |
555 | | libcerror_error_t **error ) |
556 | 0 | { |
557 | 0 | libpff_item_descriptor_t *item_descriptor = NULL; |
558 | 0 | static char *function = "libpff_item_tree_append_identifier"; |
559 | |
|
560 | 0 | if( item_tree_node == NULL ) |
561 | 0 | { |
562 | 0 | libcerror_error_set( |
563 | 0 | error, |
564 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
565 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
566 | 0 | "%s: invalid item tree node.", |
567 | 0 | function ); |
568 | |
|
569 | 0 | return( -1 ); |
570 | 0 | } |
571 | 0 | if( libpff_item_descriptor_initialize( |
572 | 0 | &item_descriptor, |
573 | 0 | descriptor_identifier, |
574 | 0 | data_identifier, |
575 | 0 | local_descriptors_identifier, |
576 | 0 | recovered, |
577 | 0 | error ) != 1 ) |
578 | 0 | { |
579 | 0 | libcerror_error_set( |
580 | 0 | error, |
581 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
582 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
583 | 0 | "%s: unable to create item descriptor.", |
584 | 0 | function ); |
585 | |
|
586 | 0 | goto on_error; |
587 | 0 | } |
588 | 0 | if( item_descriptor == NULL ) |
589 | 0 | { |
590 | 0 | libcerror_error_set( |
591 | 0 | error, |
592 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
593 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
594 | 0 | "%s: missing item descriptor.", |
595 | 0 | function ); |
596 | |
|
597 | 0 | goto on_error; |
598 | 0 | } |
599 | 0 | if( libcdata_tree_node_append_value( |
600 | 0 | item_tree_node, |
601 | 0 | (intptr_t *) item_descriptor, |
602 | 0 | error ) != 1 ) |
603 | 0 | { |
604 | 0 | libcerror_error_set( |
605 | 0 | error, |
606 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
607 | 0 | LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, |
608 | 0 | "%s: unable to append item descriptor to item tree node.", |
609 | 0 | function ); |
610 | |
|
611 | 0 | goto on_error; |
612 | 0 | } |
613 | 0 | return( 1 ); |
614 | | |
615 | 0 | on_error: |
616 | 0 | if( item_descriptor != NULL ) |
617 | 0 | { |
618 | 0 | libpff_item_descriptor_free( |
619 | 0 | &item_descriptor, |
620 | 0 | NULL ); |
621 | 0 | } |
622 | 0 | return( -1 ); |
623 | 0 | } |
624 | | |
625 | | /* Creates an item tree from the descriptors index |
626 | | * Returns 1 if successful or -1 on error |
627 | | */ |
628 | | int libpff_item_tree_create( |
629 | | libpff_item_tree_t *item_tree, |
630 | | libpff_io_handle_t *io_handle, |
631 | | libbfio_handle_t *file_io_handle, |
632 | | libpff_descriptors_index_t *descriptors_index, |
633 | | libcdata_list_t *orphan_node_list, |
634 | | libcdata_tree_node_t **root_folder_item_tree_node, |
635 | | libcerror_error_t **error ) |
636 | 8.81k | { |
637 | 8.81k | libpff_item_descriptor_t *item_descriptor = NULL; |
638 | 8.81k | static char *function = "libpff_item_tree_create"; |
639 | | |
640 | 8.81k | if( item_tree == NULL ) |
641 | 0 | { |
642 | 0 | libcerror_error_set( |
643 | 0 | error, |
644 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
645 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
646 | 0 | "%s: invalid item tree.", |
647 | 0 | function ); |
648 | |
|
649 | 0 | return( -1 ); |
650 | 0 | } |
651 | 8.81k | if( item_tree->root_node != NULL ) |
652 | 0 | { |
653 | 0 | libcerror_error_set( |
654 | 0 | error, |
655 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
656 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
657 | 0 | "%s: invalid item tree - root node already set.", |
658 | 0 | function ); |
659 | |
|
660 | 0 | return( -1 ); |
661 | 0 | } |
662 | 8.81k | if( descriptors_index == NULL ) |
663 | 0 | { |
664 | 0 | libcerror_error_set( |
665 | 0 | error, |
666 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
667 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
668 | 0 | "%s: invalid descriptors index.", |
669 | 0 | function ); |
670 | |
|
671 | 0 | return( -1 ); |
672 | 0 | } |
673 | 8.81k | if( descriptors_index->index == NULL ) |
674 | 0 | { |
675 | 0 | libcerror_error_set( |
676 | 0 | error, |
677 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
678 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
679 | 0 | "%s: invalid descriptors index - missing index.", |
680 | 0 | function ); |
681 | |
|
682 | 0 | return( -1 ); |
683 | 0 | } |
684 | 8.81k | if( libpff_item_descriptor_initialize( |
685 | 8.81k | &item_descriptor, |
686 | 8.81k | 0, |
687 | 8.81k | 0, |
688 | 8.81k | 0, |
689 | 8.81k | 0, |
690 | 8.81k | error ) != 1 ) |
691 | 0 | { |
692 | 0 | libcerror_error_set( |
693 | 0 | error, |
694 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
695 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
696 | 0 | "%s: unable to create item descriptor.", |
697 | 0 | function ); |
698 | |
|
699 | 0 | goto on_error; |
700 | 0 | } |
701 | 8.81k | if( libcdata_tree_node_initialize( |
702 | 8.81k | &( item_tree->root_node ), |
703 | 8.81k | error ) != 1 ) |
704 | 0 | { |
705 | 0 | libcerror_error_set( |
706 | 0 | error, |
707 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
708 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
709 | 0 | "%s: unable to create item tree root node.", |
710 | 0 | function ); |
711 | |
|
712 | 0 | goto on_error; |
713 | 0 | } |
714 | 8.81k | if( libcdata_tree_node_set_value( |
715 | 8.81k | item_tree->root_node, |
716 | 8.81k | (intptr_t *) item_descriptor, |
717 | 8.81k | error ) != 1 ) |
718 | 0 | { |
719 | 0 | libcerror_error_set( |
720 | 0 | error, |
721 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
722 | 0 | LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
723 | 0 | "%s: unable to set item descriptor in item tree root node.", |
724 | 0 | function ); |
725 | |
|
726 | 0 | goto on_error; |
727 | 0 | } |
728 | | /* The item descriptor is now managed by the item tree root node |
729 | | */ |
730 | 8.81k | item_descriptor = NULL; |
731 | | |
732 | 8.81k | if( libpff_item_tree_create_node_from_descriptor_index_node( |
733 | 8.81k | item_tree, |
734 | 8.81k | io_handle, |
735 | 8.81k | file_io_handle, |
736 | 8.81k | descriptors_index, |
737 | 8.81k | descriptors_index->index->root_node_offset, |
738 | 8.81k | orphan_node_list, |
739 | 8.81k | root_folder_item_tree_node, |
740 | 8.81k | 0, |
741 | 8.81k | error ) != 1 ) |
742 | 1.18k | { |
743 | 1.18k | libcerror_error_set( |
744 | 1.18k | error, |
745 | 1.18k | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
746 | 1.18k | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
747 | 1.18k | "%s: unable to create item tree.", |
748 | 1.18k | function ); |
749 | | |
750 | 1.18k | goto on_error; |
751 | 1.18k | } |
752 | 7.63k | return( 1 ); |
753 | | |
754 | 1.18k | on_error: |
755 | 1.18k | if( item_tree->root_node != NULL ) |
756 | 1.18k | { |
757 | 1.18k | libcdata_tree_node_free( |
758 | 1.18k | &( item_tree->root_node ), |
759 | 1.18k | (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, |
760 | 1.18k | NULL ); |
761 | 1.18k | } |
762 | 1.18k | if( item_descriptor != NULL ) |
763 | 0 | { |
764 | 0 | libpff_item_descriptor_free( |
765 | 0 | &item_descriptor, |
766 | 0 | NULL ); |
767 | 0 | } |
768 | 1.18k | return( -1 ); |
769 | 8.81k | } |
770 | | |
771 | | /* Creates an item tree node from a descriptor index node |
772 | | * |
773 | | * If a descriptor index value has no existing parent it is added to the orphan node list |
774 | | * |
775 | | * Returns 1 if successful or -1 on error |
776 | | */ |
777 | | int libpff_item_tree_create_node_from_descriptor_index_node( |
778 | | libpff_item_tree_t *item_tree, |
779 | | libpff_io_handle_t *io_handle, |
780 | | libbfio_handle_t *file_io_handle, |
781 | | libpff_descriptors_index_t *descriptors_index, |
782 | | off64_t node_offset, |
783 | | libcdata_list_t *orphan_node_list, |
784 | | libcdata_tree_node_t **root_folder_item_tree_node, |
785 | | int recursion_depth, |
786 | | libcerror_error_t **error ) |
787 | 317k | { |
788 | 317k | libpff_index_node_t *index_node = NULL; |
789 | 317k | libpff_index_value_t *index_value = NULL; |
790 | 317k | uint8_t *node_entry_data = NULL; |
791 | 317k | static char *function = "libpff_item_tree_create_node_from_descriptor_index_node"; |
792 | 317k | uint64_t sub_node_back_pointer = 0; |
793 | 317k | uint64_t sub_node_offset = 0; |
794 | 317k | uint16_t entry_index = 0; |
795 | | |
796 | 317k | if( item_tree == NULL ) |
797 | 0 | { |
798 | 0 | libcerror_error_set( |
799 | 0 | error, |
800 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
801 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
802 | 0 | "%s: invalid item tree.", |
803 | 0 | function ); |
804 | |
|
805 | 0 | return( -1 ); |
806 | 0 | } |
807 | 317k | if( io_handle == NULL ) |
808 | 0 | { |
809 | 0 | libcerror_error_set( |
810 | 0 | error, |
811 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
812 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
813 | 0 | "%s: invalid IO handle.", |
814 | 0 | function ); |
815 | |
|
816 | 0 | return( -1 ); |
817 | 0 | } |
818 | 317k | if( descriptors_index == NULL ) |
819 | 0 | { |
820 | 0 | libcerror_error_set( |
821 | 0 | error, |
822 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
823 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
824 | 0 | "%s: invalid descriptors index.", |
825 | 0 | function ); |
826 | |
|
827 | 0 | return( -1 ); |
828 | 0 | } |
829 | 317k | if( root_folder_item_tree_node == NULL ) |
830 | 0 | { |
831 | 0 | libcerror_error_set( |
832 | 0 | error, |
833 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
834 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
835 | 0 | "%s: invalid root folder item tree node.", |
836 | 0 | function ); |
837 | |
|
838 | 0 | return( -1 ); |
839 | 0 | } |
840 | 317k | if( ( recursion_depth < 0 ) |
841 | 317k | || ( recursion_depth > LIBPFF_MAXIMUM_ITEM_TREE_RECURSION_DEPTH ) ) |
842 | 26 | { |
843 | 26 | libcerror_error_set( |
844 | 26 | error, |
845 | 26 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
846 | 26 | LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, |
847 | 26 | "%s: invalid recursion depth value out of bounds.", |
848 | 26 | function ); |
849 | | |
850 | 26 | return( -1 ); |
851 | 26 | } |
852 | 317k | if( libpff_index_node_initialize( |
853 | 317k | &index_node, |
854 | 317k | error ) != 1 ) |
855 | 0 | { |
856 | 0 | libcerror_error_set( |
857 | 0 | error, |
858 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
859 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
860 | 0 | "%s: unable to create index node.", |
861 | 0 | function ); |
862 | |
|
863 | 0 | goto on_error; |
864 | 0 | } |
865 | 317k | if( libpff_index_node_read_file_io_handle( |
866 | 317k | index_node, |
867 | 317k | file_io_handle, |
868 | 317k | node_offset, |
869 | 317k | io_handle->file_type, |
870 | 317k | error ) != 1 ) |
871 | 690 | { |
872 | 690 | libcerror_error_set( |
873 | 690 | error, |
874 | 690 | LIBCERROR_ERROR_DOMAIN_IO, |
875 | 690 | LIBCERROR_IO_ERROR_READ_FAILED, |
876 | 690 | "%s: unable to read index node at offset: %" PRIi64 " (0x%08" PRIx64 ").", |
877 | 690 | function, |
878 | 690 | node_offset, |
879 | 690 | node_offset ); |
880 | | |
881 | 690 | goto on_error; |
882 | 690 | } |
883 | 316k | for( entry_index = 0; |
884 | 1.69M | entry_index < index_node->number_of_entries; |
885 | 1.37M | entry_index++ ) |
886 | 1.39M | { |
887 | 1.39M | if( libpff_index_node_get_entry_data( |
888 | 1.39M | index_node, |
889 | 1.39M | entry_index, |
890 | 1.39M | &node_entry_data, |
891 | 1.39M | error ) != 1 ) |
892 | 0 | { |
893 | 0 | libcerror_error_set( |
894 | 0 | error, |
895 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
896 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
897 | 0 | "%s: unable to retrieve node entry: %" PRIu16 " data.", |
898 | 0 | function, |
899 | 0 | entry_index ); |
900 | |
|
901 | 0 | goto on_error; |
902 | 0 | } |
903 | 1.39M | if( node_entry_data == NULL ) |
904 | 0 | { |
905 | 0 | libcerror_error_set( |
906 | 0 | error, |
907 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
908 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
909 | 0 | "%s: missing node entry: %" PRIu16 " data.", |
910 | 0 | function, |
911 | 0 | entry_index ); |
912 | |
|
913 | 0 | goto on_error; |
914 | 0 | } |
915 | 1.39M | if( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF ) |
916 | 1.08M | { |
917 | 1.08M | if( libpff_index_value_initialize( |
918 | 1.08M | &index_value, |
919 | 1.08M | error ) != 1 ) |
920 | 0 | { |
921 | 0 | libcerror_error_set( |
922 | 0 | error, |
923 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
924 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
925 | 0 | "%s: unable to create index value.", |
926 | 0 | function ); |
927 | |
|
928 | 0 | goto on_error; |
929 | 0 | } |
930 | 1.08M | if( libpff_index_value_read_data( |
931 | 1.08M | index_value, |
932 | 1.08M | io_handle, |
933 | 1.08M | LIBPFF_INDEX_TYPE_DESCRIPTOR, |
934 | 1.08M | node_entry_data, |
935 | 1.08M | (size_t) index_node->entry_size, |
936 | 1.08M | error ) != 1 ) |
937 | 17 | { |
938 | 17 | libcerror_error_set( |
939 | 17 | error, |
940 | 17 | LIBCERROR_ERROR_DOMAIN_IO, |
941 | 17 | LIBCERROR_IO_ERROR_READ_FAILED, |
942 | 17 | "%s: unable to read index value.", |
943 | 17 | function ); |
944 | | |
945 | 17 | goto on_error; |
946 | 17 | } |
947 | 1.08M | if( libpff_item_tree_create_leaf_node_from_descriptor_index_value( |
948 | 1.08M | item_tree, |
949 | 1.08M | io_handle, |
950 | 1.08M | file_io_handle, |
951 | 1.08M | descriptors_index, |
952 | 1.08M | index_value, |
953 | 1.08M | orphan_node_list, |
954 | 1.08M | root_folder_item_tree_node, |
955 | 1.08M | recursion_depth, |
956 | 1.08M | error ) != 1 ) |
957 | 452 | { |
958 | 452 | libcerror_error_set( |
959 | 452 | error, |
960 | 452 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
961 | 452 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
962 | 452 | "%s: unable to create item tree from descriptor index tree leaf node.", |
963 | 452 | function ); |
964 | | |
965 | 452 | goto on_error; |
966 | 452 | } |
967 | 1.08M | if( libpff_index_value_free( |
968 | 1.08M | &index_value, |
969 | 1.08M | error ) != 1 ) |
970 | 0 | { |
971 | 0 | libcerror_error_set( |
972 | 0 | error, |
973 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
974 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
975 | 0 | "%s: unable to free index value.", |
976 | 0 | function ); |
977 | |
|
978 | 0 | goto on_error; |
979 | 0 | } |
980 | 1.08M | } |
981 | 308k | else |
982 | 308k | { |
983 | 308k | if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT ) |
984 | 291k | { |
985 | 291k | byte_stream_copy_to_uint32_little_endian( |
986 | 291k | ( (pff_index_node_branch_entry_32bit_t *) node_entry_data )->file_offset, |
987 | 291k | sub_node_offset ); |
988 | | |
989 | 291k | byte_stream_copy_to_uint32_little_endian( |
990 | 291k | ( (pff_index_node_branch_entry_32bit_t *) node_entry_data )->back_pointer, |
991 | 291k | sub_node_back_pointer ); |
992 | 291k | } |
993 | 17.2k | else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) |
994 | 17.2k | || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) ) |
995 | 17.2k | { |
996 | 17.2k | byte_stream_copy_to_uint64_little_endian( |
997 | 17.2k | ( (pff_index_node_branch_entry_64bit_t *) node_entry_data )->file_offset, |
998 | 17.2k | sub_node_offset ); |
999 | | |
1000 | 17.2k | byte_stream_copy_to_uint64_little_endian( |
1001 | 17.2k | ( (pff_index_node_branch_entry_64bit_t *) node_entry_data )->back_pointer, |
1002 | 17.2k | sub_node_back_pointer ); |
1003 | 17.2k | } |
1004 | | #if defined( HAVE_DEBUG_OUTPUT ) |
1005 | | if( libcnotify_verbose != 0 ) |
1006 | | { |
1007 | | libcnotify_printf( |
1008 | | "%s: node entry: %" PRIu16 " sub node offset\t: %" PRIi64 " (0x%08" PRIx64 ")\n", |
1009 | | function, |
1010 | | entry_index, |
1011 | | sub_node_offset, |
1012 | | sub_node_offset ); |
1013 | | } |
1014 | | #endif /* defined( HAVE_DEBUG_OUTPUT ) */ |
1015 | | |
1016 | 308k | if( libpff_item_tree_create_node_from_descriptor_index_node( |
1017 | 308k | item_tree, |
1018 | 308k | io_handle, |
1019 | 308k | file_io_handle, |
1020 | 308k | descriptors_index, |
1021 | 308k | sub_node_offset, |
1022 | 308k | orphan_node_list, |
1023 | 308k | root_folder_item_tree_node, |
1024 | 308k | recursion_depth + 1, |
1025 | 308k | error ) != 1 ) |
1026 | 14.4k | { |
1027 | 14.4k | libcerror_error_set( |
1028 | 14.4k | error, |
1029 | 14.4k | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1030 | 14.4k | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
1031 | 14.4k | "%s: unable to create item tree node from descriptor index node at offset: %" PRIi64 " (0x%08" PRIx64 ").", |
1032 | 14.4k | function, |
1033 | 14.4k | sub_node_offset, |
1034 | 14.4k | sub_node_offset ); |
1035 | | |
1036 | 14.4k | goto on_error; |
1037 | 14.4k | } |
1038 | 308k | } |
1039 | 1.39M | } |
1040 | 301k | if( libpff_index_node_free( |
1041 | 301k | &index_node, |
1042 | 301k | error ) != 1 ) |
1043 | 0 | { |
1044 | 0 | libcerror_error_set( |
1045 | 0 | error, |
1046 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1047 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
1048 | 0 | "%s: unable to free index node.", |
1049 | 0 | function ); |
1050 | |
|
1051 | 0 | goto on_error; |
1052 | 0 | } |
1053 | 301k | return( 1 ); |
1054 | | |
1055 | 15.6k | on_error: |
1056 | 15.6k | if( index_value != NULL ) |
1057 | 469 | { |
1058 | 469 | libpff_index_value_free( |
1059 | 469 | &index_value, |
1060 | 469 | NULL ); |
1061 | 469 | } |
1062 | 15.6k | if( index_node != NULL ) |
1063 | 15.6k | { |
1064 | 15.6k | libpff_index_node_free( |
1065 | 15.6k | &index_node, |
1066 | 15.6k | NULL ); |
1067 | 15.6k | } |
1068 | 15.6k | if( *root_folder_item_tree_node != NULL ) |
1069 | 1.78k | { |
1070 | 1.78k | libcdata_tree_node_free( |
1071 | 1.78k | root_folder_item_tree_node, |
1072 | 1.78k | NULL, |
1073 | 1.78k | NULL ); |
1074 | 1.78k | } |
1075 | 15.6k | return( -1 ); |
1076 | 301k | } |
1077 | | |
1078 | | /* Creates an item tree leaf node from the descriptor index value |
1079 | | * |
1080 | | * If a descriptor index value has no existing parent it is added to the orphan node list |
1081 | | * |
1082 | | * Returns 1 if successful or -1 on error |
1083 | | */ |
1084 | | int libpff_item_tree_create_leaf_node_from_descriptor_index_value( |
1085 | | libpff_item_tree_t *item_tree, |
1086 | | libpff_io_handle_t *io_handle, |
1087 | | libbfio_handle_t *file_io_handle, |
1088 | | libpff_descriptors_index_t *descriptors_index, |
1089 | | libpff_index_value_t *descriptor_index_value, |
1090 | | libcdata_list_t *orphan_node_list, |
1091 | | libcdata_tree_node_t **root_folder_item_tree_node, |
1092 | | int recursion_depth, |
1093 | | libcerror_error_t **error ) |
1094 | 1.12M | { |
1095 | 1.12M | libcdata_tree_node_t *item_tree_node = NULL; |
1096 | 1.12M | libcdata_tree_node_t *parent_node = NULL; |
1097 | 1.12M | libpff_index_value_t *parent_descriptor_index_value = NULL; |
1098 | 1.12M | libpff_item_descriptor_t *item_descriptor = NULL; |
1099 | 1.12M | static char *function = "libpff_item_tree_create_leaf_node_from_descriptor_index_value"; |
1100 | 1.12M | int result = 0; |
1101 | | |
1102 | 1.12M | if( item_tree == NULL ) |
1103 | 0 | { |
1104 | 0 | libcerror_error_set( |
1105 | 0 | error, |
1106 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1107 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
1108 | 0 | "%s: invalid item tree.", |
1109 | 0 | function ); |
1110 | |
|
1111 | 0 | return( -1 ); |
1112 | 0 | } |
1113 | 1.12M | if( descriptors_index == NULL ) |
1114 | 0 | { |
1115 | 0 | libcerror_error_set( |
1116 | 0 | error, |
1117 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1118 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
1119 | 0 | "%s: invalid descriptors index.", |
1120 | 0 | function ); |
1121 | |
|
1122 | 0 | return( -1 ); |
1123 | 0 | } |
1124 | 1.12M | if( descriptor_index_value == NULL ) |
1125 | 0 | { |
1126 | 0 | libcerror_error_set( |
1127 | 0 | error, |
1128 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1129 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
1130 | 0 | "%s: invalid descriptor index value.", |
1131 | 0 | function ); |
1132 | |
|
1133 | 0 | return( -1 ); |
1134 | 0 | } |
1135 | 1.12M | if( descriptor_index_value->identifier > (uint64_t) UINT32_MAX ) |
1136 | 0 | { |
1137 | 0 | libcerror_error_set( |
1138 | 0 | error, |
1139 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1140 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, |
1141 | 0 | "%s: invalid descriptor index - identifier value exceeds maximum.", |
1142 | 0 | function ); |
1143 | |
|
1144 | 0 | goto on_error; |
1145 | 0 | } |
1146 | 1.12M | if( root_folder_item_tree_node == NULL ) |
1147 | 0 | { |
1148 | 0 | libcerror_error_set( |
1149 | 0 | error, |
1150 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1151 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
1152 | 0 | "%s: invalid root folder item tree node.", |
1153 | 0 | function ); |
1154 | |
|
1155 | 0 | return( -1 ); |
1156 | 0 | } |
1157 | 1.12M | if( ( recursion_depth < 0 ) |
1158 | 1.12M | || ( recursion_depth > LIBPFF_MAXIMUM_ITEM_TREE_RECURSION_DEPTH ) ) |
1159 | 35 | { |
1160 | 35 | libcerror_error_set( |
1161 | 35 | error, |
1162 | 35 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1163 | 35 | LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, |
1164 | 35 | "%s: invalid recursion depth value out of bounds.", |
1165 | 35 | function ); |
1166 | | |
1167 | 35 | return( -1 ); |
1168 | 35 | } |
1169 | | /* Create a new item descriptor |
1170 | | */ |
1171 | 1.12M | if( libpff_item_descriptor_initialize( |
1172 | 1.12M | &item_descriptor, |
1173 | 1.12M | (uint32_t) descriptor_index_value->identifier, |
1174 | 1.12M | descriptor_index_value->data_identifier, |
1175 | 1.12M | descriptor_index_value->local_descriptors_identifier, |
1176 | 1.12M | 0, |
1177 | 1.12M | error ) != 1 ) |
1178 | 0 | { |
1179 | 0 | libcerror_error_set( |
1180 | 0 | error, |
1181 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1182 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
1183 | 0 | "%s: unable to create item descriptor.", |
1184 | 0 | function ); |
1185 | |
|
1186 | 0 | goto on_error; |
1187 | 0 | } |
1188 | | /* The root folder index descriptor points to itself as its parent |
1189 | | */ |
1190 | 1.12M | if( (uint32_t) descriptor_index_value->identifier == descriptor_index_value->parent_identifier ) |
1191 | 22.4k | { |
1192 | 22.4k | if( *root_folder_item_tree_node != NULL ) |
1193 | 118 | { |
1194 | 118 | libcerror_error_set( |
1195 | 118 | error, |
1196 | 118 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1197 | 118 | LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, |
1198 | 118 | "%s: root folder item tree node already set.", |
1199 | 118 | function ); |
1200 | | |
1201 | 118 | goto on_error; |
1202 | 118 | } |
1203 | 22.2k | if( libcdata_tree_node_initialize( |
1204 | 22.2k | root_folder_item_tree_node, |
1205 | 22.2k | error ) != 1 ) |
1206 | 0 | { |
1207 | 0 | libcerror_error_set( |
1208 | 0 | error, |
1209 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1210 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
1211 | 0 | "%s: unable to create root folder item tree node.", |
1212 | 0 | function ); |
1213 | |
|
1214 | 0 | goto on_error; |
1215 | 0 | } |
1216 | 22.2k | if( libcdata_tree_node_set_value( |
1217 | 22.2k | *root_folder_item_tree_node, |
1218 | 22.2k | (intptr_t *) item_descriptor, |
1219 | 22.2k | error ) != 1 ) |
1220 | 0 | { |
1221 | 0 | libcerror_error_set( |
1222 | 0 | error, |
1223 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1224 | 0 | LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
1225 | 0 | "%s: unable to set item descriptor in root folder item tree node.", |
1226 | 0 | function ); |
1227 | |
|
1228 | 0 | goto on_error; |
1229 | 0 | } |
1230 | 22.2k | result = libcdata_tree_node_insert_node( |
1231 | 22.2k | item_tree->root_node, |
1232 | 22.2k | *root_folder_item_tree_node, |
1233 | 22.2k | (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libpff_item_descriptor_compare, |
1234 | 22.2k | LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, |
1235 | 22.2k | NULL ); |
1236 | | |
1237 | | /* Free the node if it could not be inserted |
1238 | | */ |
1239 | 22.2k | if( result != 1 ) |
1240 | 18.7k | { |
1241 | 18.7k | libcdata_tree_node_free( |
1242 | 18.7k | root_folder_item_tree_node, |
1243 | 18.7k | (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, |
1244 | 18.7k | NULL ); |
1245 | 18.7k | } |
1246 | 22.2k | if( result == -1 ) |
1247 | 0 | { |
1248 | 0 | libcerror_error_set( |
1249 | 0 | error, |
1250 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1251 | 0 | LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, |
1252 | 0 | "%s: unable to insert item descriptor in item tree node.", |
1253 | 0 | function ); |
1254 | |
|
1255 | 0 | goto on_error; |
1256 | 0 | } |
1257 | 22.2k | } |
1258 | 1.10M | else |
1259 | 1.10M | { |
1260 | 1.10M | parent_node = NULL; |
1261 | | |
1262 | 1.10M | result = libpff_item_tree_get_tree_node_by_identifier( |
1263 | 1.10M | item_tree->root_node, |
1264 | 1.10M | descriptor_index_value->parent_identifier, |
1265 | 1.10M | &parent_node, |
1266 | 1.10M | 0, |
1267 | 1.10M | error ); |
1268 | | |
1269 | 1.10M | if( result == 0 ) |
1270 | 614k | { |
1271 | | #if defined( HAVE_DEBUG_OUTPUT ) |
1272 | | if( libcnotify_verbose != 0 ) |
1273 | | { |
1274 | | libcnotify_printf( |
1275 | | "%s: reading ahead for descriptor: %" PRIu64 " with parent %" PRIu32 ".\n", |
1276 | | function, |
1277 | | descriptor_index_value->identifier, |
1278 | | descriptor_index_value->parent_identifier ); |
1279 | | } |
1280 | | #endif |
1281 | 614k | result = libpff_index_get_value_by_identifier( |
1282 | 614k | descriptors_index->index, |
1283 | 614k | io_handle, |
1284 | 614k | file_io_handle, |
1285 | 614k | descriptor_index_value->parent_identifier, |
1286 | 614k | &parent_descriptor_index_value, |
1287 | 614k | error ); |
1288 | | |
1289 | 614k | if( result == 1 ) |
1290 | 43.3k | { |
1291 | 43.3k | if( parent_descriptor_index_value == NULL ) |
1292 | 0 | { |
1293 | 0 | libcerror_error_set( |
1294 | 0 | error, |
1295 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1296 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
1297 | 0 | "%s: invalid parent descriptor index value.", |
1298 | 0 | function ); |
1299 | |
|
1300 | 0 | goto on_error; |
1301 | 0 | } |
1302 | 43.3k | if( libpff_item_tree_create_leaf_node_from_descriptor_index_value( |
1303 | 43.3k | item_tree, |
1304 | 43.3k | io_handle, |
1305 | 43.3k | file_io_handle, |
1306 | 43.3k | descriptors_index, |
1307 | 43.3k | parent_descriptor_index_value, |
1308 | 43.3k | orphan_node_list, |
1309 | 43.3k | root_folder_item_tree_node, |
1310 | 43.3k | recursion_depth + 1, |
1311 | 43.3k | error ) != 1 ) |
1312 | 2.17k | { |
1313 | 2.17k | libcerror_error_set( |
1314 | 2.17k | error, |
1315 | 2.17k | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1316 | 2.17k | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
1317 | 2.17k | "%s: unable to create item tree from parent descriptor: %" PRIu32 ".", |
1318 | 2.17k | function, |
1319 | 2.17k | descriptor_index_value->parent_identifier ); |
1320 | | |
1321 | 2.17k | goto on_error; |
1322 | 2.17k | } |
1323 | 41.2k | if( libpff_index_value_free( |
1324 | 41.2k | &parent_descriptor_index_value, |
1325 | 41.2k | error ) != 1 ) |
1326 | 0 | { |
1327 | 0 | libcerror_error_set( |
1328 | 0 | error, |
1329 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1330 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
1331 | 0 | "%s: unable to free parent descriptor index value.", |
1332 | 0 | function ); |
1333 | |
|
1334 | 0 | goto on_error; |
1335 | 0 | } |
1336 | 41.2k | parent_node = NULL; |
1337 | | |
1338 | 41.2k | result = libpff_item_tree_get_tree_node_by_identifier( |
1339 | 41.2k | item_tree->root_node, |
1340 | 41.2k | descriptor_index_value->parent_identifier, |
1341 | 41.2k | &parent_node, |
1342 | 41.2k | 0, |
1343 | 41.2k | error ); |
1344 | 41.2k | } |
1345 | 614k | } |
1346 | 1.10M | if( result == -1 ) |
1347 | 299 | { |
1348 | 299 | libcerror_error_set( |
1349 | 299 | error, |
1350 | 299 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1351 | 299 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
1352 | 299 | "%s: unable to find parent node: %" PRIu32 ".", |
1353 | 299 | function, |
1354 | 299 | descriptor_index_value->parent_identifier ); |
1355 | | |
1356 | 299 | goto on_error; |
1357 | 299 | } |
1358 | 1.10M | else if( result == 0 ) |
1359 | 610k | { |
1360 | | #if defined( HAVE_DEBUG_OUTPUT ) |
1361 | | if( libcnotify_verbose != 0 ) |
1362 | | { |
1363 | | libcnotify_printf( |
1364 | | "%s: parent node: %" PRIu32 " missing - found orphan node: %" PRIu64 ".\n", |
1365 | | function, |
1366 | | descriptor_index_value->parent_identifier, |
1367 | | descriptor_index_value->identifier ); |
1368 | | } |
1369 | | #endif |
1370 | 610k | if( libcdata_tree_node_initialize( |
1371 | 610k | &item_tree_node, |
1372 | 610k | error ) != 1 ) |
1373 | 0 | { |
1374 | 0 | libcerror_error_set( |
1375 | 0 | error, |
1376 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1377 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
1378 | 0 | "%s: unable to create item tree node.", |
1379 | 0 | function ); |
1380 | |
|
1381 | 0 | goto on_error; |
1382 | 0 | } |
1383 | 610k | if( libcdata_tree_node_set_value( |
1384 | 610k | item_tree_node, |
1385 | 610k | (intptr_t *) item_descriptor, |
1386 | 610k | error ) != 1 ) |
1387 | 0 | { |
1388 | 0 | libcerror_error_set( |
1389 | 0 | error, |
1390 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1391 | 0 | LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
1392 | 0 | "%s: unable to set item descriptor in item tree root node.", |
1393 | 0 | function ); |
1394 | |
|
1395 | 0 | goto on_error; |
1396 | 0 | } |
1397 | 610k | item_descriptor = NULL; |
1398 | | |
1399 | 610k | if( libcdata_list_append_value( |
1400 | 610k | orphan_node_list, |
1401 | 610k | (intptr_t *) item_tree_node, |
1402 | 610k | error ) != 1 ) |
1403 | 0 | { |
1404 | 0 | libcerror_error_set( |
1405 | 0 | error, |
1406 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1407 | 0 | LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, |
1408 | 0 | "%s: unable to append orphan node in orphan node list.", |
1409 | 0 | function ); |
1410 | |
|
1411 | 0 | goto on_error; |
1412 | 0 | } |
1413 | 610k | } |
1414 | 492k | else |
1415 | 492k | { |
1416 | 492k | if( parent_node == NULL ) |
1417 | 0 | { |
1418 | 0 | libcerror_error_set( |
1419 | 0 | error, |
1420 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1421 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
1422 | 0 | "%s: invalid parent node.", |
1423 | 0 | function ); |
1424 | |
|
1425 | 0 | goto on_error; |
1426 | 0 | } |
1427 | 492k | result = libcdata_tree_node_insert_value( |
1428 | 492k | parent_node, |
1429 | 492k | (intptr_t *) item_descriptor, |
1430 | 492k | (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libpff_item_descriptor_compare, |
1431 | 492k | LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, |
1432 | 492k | error ); |
1433 | | |
1434 | | /* Free the node if it could not be inserted |
1435 | | */ |
1436 | 492k | if( result != 1 ) |
1437 | 430k | { |
1438 | 430k | libpff_item_descriptor_free( |
1439 | 430k | &item_descriptor, |
1440 | 430k | NULL ); |
1441 | 430k | } |
1442 | 492k | if( result == -1 ) |
1443 | 0 | { |
1444 | 0 | libcerror_error_set( |
1445 | 0 | error, |
1446 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1447 | 0 | LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, |
1448 | 0 | "%s: unable to insert item descriptor in item tree node.", |
1449 | 0 | function ); |
1450 | |
|
1451 | 0 | goto on_error; |
1452 | 0 | } |
1453 | 492k | } |
1454 | 1.10M | } |
1455 | 1.12M | return( 1 ); |
1456 | | |
1457 | 2.59k | on_error: |
1458 | 2.59k | if( parent_descriptor_index_value != NULL ) |
1459 | 2.17k | { |
1460 | 2.17k | libpff_index_value_free( |
1461 | 2.17k | &parent_descriptor_index_value, |
1462 | 2.17k | NULL ); |
1463 | 2.17k | } |
1464 | 2.59k | if( item_tree_node != NULL ) |
1465 | 0 | { |
1466 | 0 | libcdata_tree_node_free( |
1467 | 0 | &item_tree_node, |
1468 | 0 | NULL, |
1469 | 0 | NULL ); |
1470 | 0 | } |
1471 | 2.59k | if( *root_folder_item_tree_node != NULL ) |
1472 | 982 | { |
1473 | 982 | libcdata_tree_node_free( |
1474 | 982 | root_folder_item_tree_node, |
1475 | 982 | NULL, |
1476 | 982 | NULL ); |
1477 | 982 | } |
1478 | 2.59k | if( item_descriptor != NULL ) |
1479 | 2.59k | { |
1480 | 2.59k | libpff_item_descriptor_free( |
1481 | 2.59k | &item_descriptor, |
1482 | 2.59k | NULL ); |
1483 | 2.59k | } |
1484 | 2.59k | return( -1 ); |
1485 | 1.12M | } |
1486 | | |
1487 | | /* Retrieves the tree node of an item node |
1488 | | * Returns 1 if successful, 0 if the item node was not found or -1 on error |
1489 | | */ |
1490 | | int libpff_item_tree_get_node_by_identifier( |
1491 | | libpff_item_tree_t *item_tree, |
1492 | | uint32_t item_identifier, |
1493 | | libcdata_tree_node_t **item_tree_node, |
1494 | | libcerror_error_t **error ) |
1495 | 0 | { |
1496 | 0 | static char *function = "libpff_item_tree_get_node_by_identifier"; |
1497 | 0 | int result = 0; |
1498 | |
|
1499 | 0 | if( item_tree == NULL ) |
1500 | 0 | { |
1501 | 0 | libcerror_error_set( |
1502 | 0 | error, |
1503 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
1504 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
1505 | 0 | "%s: invalid item tree.", |
1506 | 0 | function ); |
1507 | |
|
1508 | 0 | return( -1 ); |
1509 | 0 | } |
1510 | 0 | result = libpff_item_tree_get_tree_node_by_identifier( |
1511 | 0 | item_tree->root_node, |
1512 | 0 | item_identifier, |
1513 | 0 | item_tree_node, |
1514 | 0 | 0, |
1515 | 0 | error ); |
1516 | |
|
1517 | 0 | if( result == -1 ) |
1518 | 0 | { |
1519 | 0 | libcerror_error_set( |
1520 | 0 | error, |
1521 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
1522 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
1523 | 0 | "%s: unable to retrieve item tree node: %" PRIu32 ".", |
1524 | 0 | function, |
1525 | 0 | item_identifier ); |
1526 | |
|
1527 | 0 | return( -1 ); |
1528 | 0 | } |
1529 | 0 | return( result ); |
1530 | 0 | } |
1531 | | |