Coverage Report

Created: 2025-06-13 07:22

/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