Coverage Report

Created: 2023-06-07 06:53

/src/libpff/libpff/libpff_table.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Table functions
3
 *
4
 * Copyright (C) 2008-2023, 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 <byte_stream.h>
24
#include <memory.h>
25
#include <system_string.h>
26
#include <types.h>
27
28
#include "libpff_column_definition.h"
29
#include "libpff_data_array.h"
30
#include "libpff_data_block.h"
31
#include "libpff_debug.h"
32
#include "libpff_definitions.h"
33
#include "libpff_index.h"
34
#include "libpff_io_handle.h"
35
#include "libpff_libbfio.h"
36
#include "libpff_libcdata.h"
37
#include "libpff_libcerror.h"
38
#include "libpff_libcnotify.h"
39
#include "libpff_libfcache.h"
40
#include "libpff_libfdata.h"
41
#include "libpff_libfguid.h"
42
#include "libpff_libfmapi.h"
43
#include "libpff_libuna.h"
44
#include "libpff_local_descriptor_value.h"
45
#include "libpff_local_descriptors_tree.h"
46
#include "libpff_mapi.h"
47
#include "libpff_name_to_id_map.h"
48
#include "libpff_record_entry.h"
49
#include "libpff_record_set.h"
50
#include "libpff_reference_descriptor.h"
51
#include "libpff_table.h"
52
#include "libpff_table_header.h"
53
#include "libpff_table_block_index.h"
54
#include "libpff_table_index_value.h"
55
#include "libpff_types.h"
56
#include "libpff_unused.h"
57
58
#include "pff_table.h"
59
60
/* Creates a table
61
 * Make sure the value table is referencing, is set to NULL
62
 * Returns 1 if successful or -1 on error
63
 */
64
int libpff_table_initialize(
65
     libpff_table_t **table,
66
     uint32_t descriptor_identifier,
67
     uint64_t data_identifier,
68
     uint64_t local_descriptors_identifier,
69
     uint8_t recovered,
70
     libcerror_error_t **error )
71
6.02k
{
72
6.02k
  static char *function = "libpff_table_initialize";
73
74
6.02k
  if( table == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
79
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
80
0
     "%s: invalid table.",
81
0
     function );
82
83
0
    return( -1 );
84
0
  }
85
6.02k
  if( *table != NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
90
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
91
0
     "%s: invalid table value already set.",
92
0
     function );
93
94
0
    return( -1 );
95
0
  }
96
6.02k
  *table = memory_allocate_structure(
97
6.02k
            libpff_table_t );
98
99
6.02k
  if( *table == NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
104
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
105
0
     "%s: unable to create table.",
106
0
     function );
107
108
0
    goto on_error;
109
0
  }
110
6.02k
  if( memory_set(
111
6.02k
       *table,
112
6.02k
       0,
113
6.02k
       sizeof( libpff_table_t ) ) == NULL )
114
0
  {
115
0
    libcerror_error_set(
116
0
     error,
117
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
118
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
119
0
     "%s: unable to clear table.",
120
0
     function );
121
122
0
    memory_free(
123
0
     *table );
124
125
0
    *table = NULL;
126
127
0
    return( -1 );
128
0
  }
129
6.02k
  if( libpff_table_header_initialize(
130
6.02k
       &( ( *table )->header ),
131
6.02k
       error ) != 1 )
132
0
  {
133
0
    libcerror_error_set(
134
0
     error,
135
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
136
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
137
0
     "%s: unable to create table header.",
138
0
     function );
139
140
0
    goto on_error;
141
0
  }
142
6.02k
  if( libcdata_array_initialize(
143
6.02k
       &( ( *table )->index_array ),
144
6.02k
       0,
145
6.02k
       error ) != 1 )
146
0
  {
147
0
    libcerror_error_set(
148
0
     error,
149
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
150
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
151
0
     "%s: unable to create index array.",
152
0
     function );
153
154
0
    goto on_error;
155
0
  }
156
6.02k
  if( libcdata_array_initialize(
157
6.02k
       &( ( *table )->record_sets_array ),
158
6.02k
       0,
159
6.02k
       error ) != 1 )
160
0
  {
161
0
    libcerror_error_set(
162
0
     error,
163
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
164
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
165
0
     "%s: unable to create record sets array.",
166
0
     function );
167
168
0
    goto on_error;
169
0
  }
170
6.02k
  ( *table )->descriptor_identifier        = descriptor_identifier;
171
6.02k
  ( *table )->data_identifier              = data_identifier;
172
6.02k
  ( *table )->local_descriptors_identifier = local_descriptors_identifier;
173
6.02k
  ( *table )->recovered                    = recovered;
174
175
6.02k
  return( 1 );
176
177
0
on_error:
178
0
  if( *table != NULL )
179
0
  {
180
0
    if( ( *table )->index_array != NULL )
181
0
    {
182
0
      libcdata_array_free(
183
0
       &( ( *table )->index_array ),
184
0
       NULL,
185
0
       NULL );
186
0
    }
187
0
    if( ( *table )->header != NULL )
188
0
    {
189
0
      libpff_table_header_free(
190
0
       &( ( *table )->header ),
191
0
       NULL );
192
0
    }
193
0
    memory_free(
194
0
     *table );
195
196
0
    *table = NULL;
197
0
  }
198
0
  return( -1 );
199
6.02k
}
200
201
/* Frees a table
202
 * Returns 1 if successful or -1 on error
203
 */
204
int libpff_table_free(
205
     libpff_table_t **table,
206
     libcerror_error_t **error )
207
6.02k
{
208
6.02k
  static char *function = "libpff_table_free";
209
6.02k
  int result            = 1;
210
211
6.02k
  if( table == NULL )
212
0
  {
213
0
    libcerror_error_set(
214
0
     error,
215
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
216
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
217
0
     "%s: invalid table.",
218
0
     function );
219
220
0
    return( -1 );
221
0
  }
222
6.02k
  if( *table != NULL )
223
6.02k
  {
224
6.02k
    if( ( *table )->descriptor_data_list != NULL )
225
4.19k
    {
226
4.19k
      if( libfdata_list_free(
227
4.19k
           &( ( *table )->descriptor_data_list ),
228
4.19k
           error ) != 1 )
229
0
      {
230
0
        libcerror_error_set(
231
0
         error,
232
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
233
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
234
0
         "%s: unable to free descriptor data list.",
235
0
         function );
236
237
0
        result = -1;
238
0
      }
239
4.19k
    }
240
6.02k
    if( ( *table )->descriptor_data_cache != NULL )
241
4.19k
    {
242
4.19k
      if( libfcache_cache_free(
243
4.19k
           &( ( *table )->descriptor_data_cache ),
244
4.19k
           error ) != 1 )
245
0
      {
246
0
        libcerror_error_set(
247
0
         error,
248
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
249
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
250
0
         "%s: unable to free descriptor data cache.",
251
0
         function );
252
253
0
        result = -1;
254
0
      }
255
4.19k
    }
256
6.02k
    if( ( *table )->local_descriptors_tree != NULL )
257
4.20k
    {
258
4.20k
      if( libpff_local_descriptors_tree_free(
259
4.20k
           &( ( *table )->local_descriptors_tree ),
260
4.20k
           error ) != 1 )
261
0
      {
262
0
        libcerror_error_set(
263
0
         error,
264
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
265
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
266
0
         "%s: unable to free local descriptors tree.",
267
0
         function );
268
269
0
        result = -1;
270
0
      }
271
4.20k
    }
272
6.02k
    if( ( *table )->local_descriptor_values_cache != NULL )
273
4.20k
    {
274
4.20k
      if( libfcache_cache_free(
275
4.20k
           &( ( *table )->local_descriptor_values_cache ),
276
4.20k
           error ) != 1 )
277
0
      {
278
0
        libcerror_error_set(
279
0
         error,
280
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
282
0
         "%s: unable to free local descriptor values cache.",
283
0
         function );
284
285
0
        result = -1;
286
0
      }
287
4.20k
    }
288
6.02k
    if( ( *table )->values_array_data_list != NULL )
289
19
    {
290
19
      if( libfdata_list_free(
291
19
           &( ( *table )->values_array_data_list ),
292
19
           error ) != 1 )
293
0
      {
294
0
        libcerror_error_set(
295
0
         error,
296
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
297
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
298
0
         "%s: unable to free values array data list.",
299
0
         function );
300
301
0
        result = -1;
302
0
      }
303
19
    }
304
6.02k
    if( ( *table )->values_array_data_cache != NULL )
305
19
    {
306
19
      if( libfcache_cache_free(
307
19
           &( ( *table )->values_array_data_cache ),
308
19
           error ) != 1 )
309
0
      {
310
0
        libcerror_error_set(
311
0
         error,
312
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
313
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
314
0
         "%s: unable to free values array data cache.",
315
0
         function );
316
317
0
        result = -1;
318
0
      }
319
19
    }
320
6.02k
    if( libcdata_array_free(
321
6.02k
         &( ( *table )->record_sets_array ),
322
6.02k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
323
6.02k
         error ) != 1 )
324
0
    {
325
0
      libcerror_error_set(
326
0
       error,
327
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
328
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
329
0
       "%s: unable to free index array.",
330
0
       function );
331
332
0
      result = -1;
333
0
    }
334
6.02k
    if( libcdata_array_free(
335
6.02k
         &( ( *table )->index_array ),
336
6.02k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_table_block_index_free,
337
6.02k
         error ) != 1 )
338
0
    {
339
0
      libcerror_error_set(
340
0
       error,
341
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
342
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
343
0
       "%s: unable to free index array.",
344
0
       function );
345
346
0
      result = -1;
347
0
    }
348
6.02k
    if( libpff_table_header_free(
349
6.02k
         &( ( *table )->header ),
350
6.02k
         error ) != 1 )
351
0
    {
352
0
      libcerror_error_set(
353
0
       error,
354
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
355
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
356
0
       "%s: unable to free table header.",
357
0
       function );
358
359
0
      result = -1;
360
0
    }
361
6.02k
    memory_free(
362
6.02k
     *table );
363
364
6.02k
    *table = NULL;
365
6.02k
  }
366
6.02k
  return( result );
367
6.02k
}
368
369
/* Clones the existing table
370
 * Returns 1 if successful or -1 on error
371
 */
372
int libpff_table_clone(
373
     libpff_table_t **destination_table,
374
     libpff_table_t *source_table,
375
     libcerror_error_t **error )
376
0
{
377
0
  static char *function = "libpff_table_clone";
378
379
0
  if( destination_table == NULL )
380
0
  {
381
0
    libcerror_error_set(
382
0
     error,
383
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
384
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
385
0
     "%s: invalid destination table.",
386
0
     function );
387
388
0
    return( -1 );
389
0
  }
390
0
  if( *destination_table != NULL )
391
0
  {
392
0
    libcerror_error_set(
393
0
     error,
394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
395
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
396
0
     "%s: invalid destination table value already set.",
397
0
     function );
398
399
0
    return( -1 );
400
0
  }
401
0
  if( source_table == NULL )
402
0
  {
403
0
    *destination_table = NULL;
404
405
0
    return( 1 );
406
0
  }
407
0
  *destination_table = memory_allocate_structure(
408
0
                        libpff_table_t );
409
410
0
  if( *destination_table == NULL )
411
0
  {
412
0
    libcerror_error_set(
413
0
     error,
414
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
415
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
416
0
     "%s: unable to create destination table.",
417
0
     function );
418
419
0
    goto on_error;
420
0
  }
421
0
  if( memory_set(
422
0
       *destination_table,
423
0
       0,
424
0
       sizeof( libpff_table_t ) ) == NULL )
425
0
  {
426
0
    libcerror_error_set(
427
0
     error,
428
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
429
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
430
0
     "%s: unable to clear destination table.",
431
0
     function );
432
433
0
    memory_free(
434
0
     *destination_table );
435
436
0
    *destination_table = NULL;
437
438
0
    return( -1 );
439
0
  }
440
/* TODO clone index ? */
441
0
  if( libcdata_array_clone(
442
0
       &( ( *destination_table )->record_sets_array ),
443
0
       source_table->record_sets_array,
444
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
445
0
       (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_record_set_clone,
446
0
       error ) != 1 )
447
0
  {
448
0
    libcerror_error_set(
449
0
     error,
450
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
451
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
452
0
     "%s: unable to clone record sets array.",
453
0
     function );
454
455
0
    goto on_error;
456
0
  }
457
0
  ( *destination_table )->descriptor_identifier        = source_table->descriptor_identifier;
458
0
  ( *destination_table )->data_identifier              = source_table->data_identifier;
459
0
  ( *destination_table )->local_descriptors_identifier = source_table->local_descriptors_identifier;
460
0
  ( *destination_table )->recovered                    = source_table->recovered;
461
462
/* TODO is this necessary or should it be re-read on demand ? */
463
0
  if( source_table->local_descriptors_tree != NULL )
464
0
  {
465
0
    if( libpff_local_descriptors_tree_clone(
466
0
         &( ( *destination_table )->local_descriptors_tree ),
467
0
         source_table->local_descriptors_tree,
468
0
         error ) != 1 )
469
0
    {
470
0
      libcerror_error_set(
471
0
       error,
472
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
473
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
474
0
       "%s: unable to create destination local descriptors tree.",
475
0
       function );
476
477
0
      goto on_error;
478
0
    }
479
0
    if( libfcache_cache_clone(
480
0
         &( ( *destination_table )->local_descriptor_values_cache ),
481
0
         source_table->local_descriptor_values_cache,
482
0
         error ) != 1 )
483
0
    {
484
0
      libcerror_error_set(
485
0
       error,
486
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
488
0
       "%s: unable to create destination local descriptor values cache.",
489
0
       function );
490
491
0
      goto on_error;
492
0
    }
493
0
  }
494
0
  return( 1 );
495
496
0
on_error:
497
0
  if( *destination_table != NULL )
498
0
  {
499
0
    libpff_table_free(
500
0
     destination_table,
501
0
     NULL );
502
0
  }
503
0
  return( -1 );
504
0
}
505
506
/* Resizes the record entries
507
 * Returns 1 if successful or -1 on error
508
 */
509
int libpff_table_resize_record_entries(
510
     libpff_table_t *table,
511
     int number_of_sets,
512
     int number_of_entries,
513
     int ascii_codepage,
514
     libcerror_error_t **error )
515
5.78k
{
516
5.78k
  libpff_record_set_t *record_set = NULL;
517
5.78k
  static char *function           = "libpff_table_resize_record_entries";
518
5.78k
  int last_number_of_sets         = 0;
519
5.78k
  int last_number_of_entries      = 0;
520
5.78k
  int set_index                   = 0;
521
522
5.78k
  if( table == NULL )
523
0
  {
524
0
    libcerror_error_set(
525
0
     error,
526
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
527
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
528
0
     "%s: invalid table.",
529
0
     function );
530
531
0
    return( -1 );
532
0
  }
533
5.78k
  if( number_of_sets < 0 )
534
0
  {
535
0
    libcerror_error_set(
536
0
     error,
537
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
538
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
539
0
     "%s: invalid number of sets value less than zero.",
540
0
     function );
541
542
0
    return( -1 );
543
0
  }
544
5.78k
  if( number_of_entries < 0 )
545
0
  {
546
0
    libcerror_error_set(
547
0
     error,
548
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
549
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
550
0
     "%s: invalid number of entries value less than zero.",
551
0
     function );
552
553
0
    return( -1 );
554
0
  }
555
5.78k
  if( libcdata_array_get_number_of_entries(
556
5.78k
       table->record_sets_array,
557
5.78k
       &last_number_of_sets,
558
5.78k
       error ) != 1 )
559
0
  {
560
0
    libcerror_error_set(
561
0
     error,
562
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
563
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
564
0
     "%s: unable to retrieve number of sets.",
565
0
     function );
566
567
0
    return( -1 );
568
0
  }
569
5.78k
  if( last_number_of_sets > 0 )
570
1.59k
  {
571
1.59k
    if( libcdata_array_get_entry_by_index(
572
1.59k
         table->record_sets_array,
573
1.59k
         0,
574
1.59k
         (intptr_t **) &record_set,
575
1.59k
         error ) != 1 )
576
0
    {
577
0
      libcerror_error_set(
578
0
       error,
579
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
580
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
581
0
       "%s: unable to retrieve record set: 0.",
582
0
       function );
583
584
0
      return( -1 );
585
0
    }
586
1.59k
    if( libpff_record_set_get_number_of_entries(
587
1.59k
         record_set,
588
1.59k
         &last_number_of_entries,
589
1.59k
         error ) != 1 )
590
0
    {
591
0
      libcerror_error_set(
592
0
       error,
593
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
594
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
595
0
       "%s: unable to retrieve number of entries of set: 0.",
596
0
       function );
597
598
0
      return( -1 );
599
0
    }
600
1.59k
    record_set = NULL;
601
1.59k
  }
602
5.78k
  if( libcdata_array_resize(
603
5.78k
       table->record_sets_array,
604
5.78k
       number_of_sets,
605
5.78k
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
606
5.78k
       error ) != 1 )
607
0
  {
608
0
    libcerror_error_set(
609
0
     error,
610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
611
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
612
0
     "%s: unable to resize record sets array.",
613
0
     function );
614
615
0
    goto on_error;
616
0
  }
617
5.78k
  if( number_of_sets > last_number_of_sets )
618
3.20k
  {
619
3.20k
    for( set_index = last_number_of_sets;
620
34.5k
         set_index < number_of_sets;
621
31.3k
         set_index++ )
622
31.3k
    {
623
31.3k
      if( libpff_record_set_initialize(
624
31.3k
           &record_set,
625
31.3k
           last_number_of_entries,
626
31.3k
           ascii_codepage,
627
31.3k
           error ) != 1 )
628
0
      {
629
0
        libcerror_error_set(
630
0
         error,
631
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
632
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
633
0
         "%s: unable to create record set: %d.",
634
0
         function,
635
0
         set_index );
636
637
0
        goto on_error;
638
0
      }
639
31.3k
      if( libcdata_array_set_entry_by_index(
640
31.3k
           table->record_sets_array,
641
31.3k
           set_index,
642
31.3k
           (intptr_t *) record_set,
643
31.3k
           error ) != 1 )
644
0
      {
645
0
        libcerror_error_set(
646
0
         error,
647
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
648
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
649
0
         "%s: unable to set record set: %d.",
650
0
         function,
651
0
         set_index );
652
653
0
        goto on_error;
654
0
      }
655
31.3k
      record_set = NULL;
656
31.3k
    }
657
3.20k
    last_number_of_sets = number_of_sets;
658
3.20k
  }
659
5.78k
  if( last_number_of_sets > 0 )
660
4.18k
  {
661
4.18k
    for( set_index = 0;
662
2.29M
         set_index < last_number_of_sets;
663
2.29M
         set_index++ )
664
2.29M
    {
665
2.29M
      if( libcdata_array_get_entry_by_index(
666
2.29M
           table->record_sets_array,
667
2.29M
           set_index,
668
2.29M
           (intptr_t **) &record_set,
669
2.29M
           error ) != 1 )
670
0
      {
671
0
        libcerror_error_set(
672
0
         error,
673
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
674
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
675
0
         "%s: unable to retrieve record set: %d.",
676
0
         function,
677
0
         set_index );
678
679
0
        record_set = NULL;
680
681
0
        goto on_error;
682
0
      }
683
2.29M
      if( libpff_record_set_resize(
684
2.29M
           record_set,
685
2.29M
           number_of_entries,
686
2.29M
           error ) != 1 )
687
0
      {
688
0
        libcerror_error_set(
689
0
         error,
690
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
691
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
692
0
         "%s: unable to resize record set: %d.",
693
0
         function,
694
0
         set_index );
695
696
0
        record_set = NULL;
697
698
0
        goto on_error;
699
0
      }
700
2.29M
    }
701
4.18k
    last_number_of_entries = number_of_entries;
702
4.18k
  }
703
5.78k
  return( 1 );
704
705
0
on_error:
706
0
  if( record_set != NULL )
707
0
  {
708
0
    libpff_internal_record_set_free(
709
0
     (libpff_internal_record_set_t **) &record_set,
710
0
     NULL );
711
0
  }
712
0
  if( last_number_of_entries != number_of_entries )
713
0
  {
714
0
    while( set_index >= last_number_of_sets )
715
0
    {
716
0
      libcdata_array_get_entry_by_index(
717
0
       table->record_sets_array,
718
0
       set_index,
719
0
       (intptr_t **) &record_set,
720
0
       NULL );
721
722
0
      libpff_record_set_resize(
723
0
       record_set,
724
0
       last_number_of_entries,
725
0
       NULL );
726
727
0
      set_index--;
728
0
    }
729
0
  }
730
0
  if( last_number_of_sets != number_of_sets )
731
0
  {
732
0
    libcdata_array_resize(
733
0
     table->record_sets_array,
734
0
                 last_number_of_sets,
735
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
736
0
     NULL );
737
0
  }
738
0
  return( -1 );
739
5.78k
}
740
741
/* Expands the record entries
742
 * Returns 1 if successful or -1 on error
743
 */
744
int libpff_table_expand_record_entries(
745
     libpff_table_t *table,
746
     int number_of_sets,
747
     int number_of_entries,
748
     int ascii_codepage,
749
     libcerror_error_t **error )
750
977
{
751
977
  libpff_record_set_t *record_set = NULL;
752
977
  static char *function           = "libpff_table_expand_record_entries";
753
977
  int last_number_of_sets         = 0;
754
977
  int last_number_of_entries      = 0;
755
756
977
  if( table == NULL )
757
0
  {
758
0
    libcerror_error_set(
759
0
     error,
760
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
761
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
762
0
     "%s: invalid table.",
763
0
     function );
764
765
0
    return( -1 );
766
0
  }
767
977
  if( number_of_sets < 0 )
768
0
  {
769
0
    libcerror_error_set(
770
0
     error,
771
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
772
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
773
0
     "%s: invalid number of sets value less than zero.",
774
0
     function );
775
776
0
    return( -1 );
777
0
  }
778
977
  if( number_of_entries < 0 )
779
0
  {
780
0
    libcerror_error_set(
781
0
     error,
782
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
783
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
784
0
     "%s: invalid number of entries value less than zero.",
785
0
     function );
786
787
0
    return( -1 );
788
0
  }
789
977
  if( libcdata_array_get_number_of_entries(
790
977
       table->record_sets_array,
791
977
       &last_number_of_sets,
792
977
       error ) != 1 )
793
0
  {
794
0
    libcerror_error_set(
795
0
     error,
796
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
797
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
798
0
     "%s: unable to retrieve number of record sets array entries.",
799
0
     function );
800
801
0
    return( -1 );
802
0
  }
803
977
  if( last_number_of_sets > 0 )
804
977
  {
805
977
    if( libcdata_array_get_entry_by_index(
806
977
         table->record_sets_array,
807
977
         0,
808
977
         (intptr_t **) &record_set,
809
977
         error ) != 1 )
810
0
    {
811
0
      libcerror_error_set(
812
0
       error,
813
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
814
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
815
0
       "%s: unable to retrieve record set: 0.",
816
0
       function );
817
818
0
      return( -1 );
819
0
    }
820
977
    if( libpff_record_set_get_number_of_entries(
821
977
         record_set,
822
977
         &last_number_of_entries,
823
977
         error ) != 1 )
824
0
    {
825
0
      libcerror_error_set(
826
0
       error,
827
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
828
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
829
0
       "%s: unable to retrieve number of entries of set: 0.",
830
0
       function );
831
832
0
      return( -1 );
833
0
    }
834
977
  }
835
977
  if( number_of_sets > ( (int) INT_MAX - last_number_of_sets ) )
836
0
  {
837
0
    libcerror_error_set(
838
0
     error,
839
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
840
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
841
0
     "%s: number of sets value out of bounds.",
842
0
     function );
843
844
0
    return( -1 );
845
0
  }
846
977
  if( number_of_entries > ( (int) INT_MAX - last_number_of_entries ) )
847
0
  {
848
0
    libcerror_error_set(
849
0
     error,
850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
851
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
852
0
     "%s: number of entries value out of bounds.",
853
0
     function );
854
855
0
    return( -1 );
856
0
  }
857
977
  if( libpff_table_resize_record_entries(
858
977
       table,
859
977
       last_number_of_sets + number_of_sets,
860
977
       last_number_of_entries + number_of_entries,
861
977
       ascii_codepage,
862
977
       error ) != 1 )
863
0
  {
864
0
    libcerror_error_set(
865
0
     error,
866
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
867
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
868
0
     "%s: unable to resize record entries.",
869
0
     function );
870
871
0
    return( -1 );
872
0
  }
873
977
  return( 1 );
874
977
}
875
876
/* Retrieves the local descriptor value for the specific identifier
877
 * Returns 1 if successful, 0 if no value was found or -1 on error
878
 */
879
int libpff_table_get_local_descriptors_value_by_identifier(
880
     libpff_table_t *table,
881
     libbfio_handle_t *file_io_handle,
882
     uint32_t descriptor_identifier,
883
     libpff_local_descriptor_value_t **local_descriptor_value,
884
     libcerror_error_t **error )
885
0
{
886
0
  static char *function = "libpff_table_get_local_descriptors_value_by_identifier";
887
0
  int result            = 0;
888
889
0
  if( table == NULL )
890
0
  {
891
0
    libcerror_error_set(
892
0
     error,
893
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
894
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
895
0
     "%s: invalid table.",
896
0
     function );
897
898
0
    return( -1 );
899
0
  }
900
0
  if( table->local_descriptors_tree != NULL )
901
0
  {
902
0
    result = libpff_local_descriptors_tree_get_value_by_identifier(
903
0
        table->local_descriptors_tree,
904
0
        file_io_handle,
905
0
        (uint64_t) descriptor_identifier,
906
0
        local_descriptor_value,
907
0
        error );
908
909
0
    if( result == -1 )
910
0
    {
911
0
      libcerror_error_set(
912
0
       error,
913
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
914
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
915
0
       "%s: unable to retrieve local descriptor identifier: %" PRIu32 ".",
916
0
       function,
917
0
       descriptor_identifier );
918
919
0
      return( -1 );
920
0
    }
921
0
  }
922
0
  return( result );
923
0
}
924
925
/* Retrieves the table index value for a specific reference
926
 * Returns 1 if successful or -1 on error
927
 */
928
int libpff_table_get_index_value_by_reference(
929
     libpff_table_t *table,
930
     uint32_t table_index_reference,
931
     libpff_io_handle_t *io_handle,
932
     libpff_table_index_value_t **table_index_value,
933
     libcerror_error_t **error )
934
81.8k
{
935
81.8k
  libpff_table_block_index_t *table_block_index = NULL;
936
81.8k
  static char *function                         = "libpff_table_get_index_value_by_reference";
937
81.8k
  uint16_t table_index_array_reference          = 0;
938
81.8k
  uint16_t table_index_value_reference          = 0;
939
940
81.8k
  if( table == NULL )
941
0
  {
942
0
    libcerror_error_set(
943
0
     error,
944
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
945
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
946
0
     "%s: invalid table.",
947
0
     function );
948
949
0
    return( -1 );
950
0
  }
951
81.8k
  if( io_handle == NULL )
952
0
  {
953
0
    libcerror_error_set(
954
0
     error,
955
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
956
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
957
0
     "%s: invalid IO handle.",
958
0
     function );
959
960
0
    return( -1 );
961
0
  }
962
81.8k
  if( ( io_handle->file_type != LIBPFF_FILE_TYPE_32BIT )
963
81.8k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT )
964
81.8k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
969
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
970
0
     "%s: unsupported file type.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
81.8k
  if( table_index_value == NULL )
976
0
  {
977
0
    libcerror_error_set(
978
0
     error,
979
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
980
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
981
0
     "%s: invalid table index value.",
982
0
     function );
983
984
0
    return( -1 );
985
0
  }
986
81.8k
  if( ( table_index_reference & 0x0000001fUL ) != 0 )
987
0
  {
988
0
    libcerror_error_set(
989
0
     error,
990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
991
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
992
0
     "%s: unsupported table index reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
993
0
     function,
994
0
     table_index_reference & 0x0000001fUL,
995
0
     table_index_reference );
996
997
0
    return( -1 );
998
0
  }
999
  /* Determine the index array reference
1000
   */
1001
81.8k
  if( ( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
1002
81.8k
   || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) )
1003
81.8k
  {
1004
81.8k
    table_index_array_reference = (uint16_t) ( table_index_reference >> 16 );
1005
81.8k
  }
1006
0
  else
1007
0
  {
1008
0
    table_index_array_reference = (uint16_t) ( table_index_reference >> 19 );
1009
0
  }
1010
81.8k
  if( libcdata_array_get_entry_by_index(
1011
81.8k
       table->index_array,
1012
81.8k
       (int) table_index_array_reference,
1013
81.8k
       (intptr_t **) &table_block_index,
1014
81.8k
       error ) != 1 )
1015
5.16k
  {
1016
5.16k
    libcerror_error_set(
1017
5.16k
     error,
1018
5.16k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1019
5.16k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1020
5.16k
     "%s: unable to retrieve table index array entry: %" PRIu16 ".",
1021
5.16k
     function,
1022
5.16k
     table_index_array_reference );
1023
1024
5.16k
    return( -1 );
1025
5.16k
  }
1026
76.6k
  if( ( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
1027
76.6k
   || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) )
1028
76.6k
  {
1029
76.6k
    table_index_value_reference = (uint16_t) ( ( table_index_reference & 0x0000ffe0 ) >> 5 ) - 1;
1030
76.6k
  }
1031
0
  else
1032
0
  {
1033
0
    table_index_value_reference = (uint16_t) ( ( table_index_reference & 0x0007ffe0 ) >> 5 ) - 1;
1034
0
  }
1035
#if defined( HAVE_DEBUG_OUTPUT )
1036
  if( libcnotify_verbose != 0 )
1037
  {
1038
    libcnotify_printf(
1039
     "%s: retrieving table index array entry: %" PRIu16 " value: %" PRIu16 ".\n",
1040
     function,
1041
     table_index_array_reference,
1042
     table_index_value_reference );
1043
  }
1044
#endif
1045
76.6k
  if( libpff_table_block_index_get_value_by_index(
1046
76.6k
       table_block_index,
1047
76.6k
       table_index_value_reference,
1048
76.6k
       table_index_value,
1049
76.6k
       error ) != 1 )
1050
2.84k
  {
1051
2.84k
    libcerror_error_set(
1052
2.84k
     error,
1053
2.84k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1054
2.84k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1055
2.84k
     "%s: unable to retrieve table block index value: %" PRIu16 ".",
1056
2.84k
     function,
1057
2.84k
                 table_index_value_reference );
1058
1059
2.84k
    return( -1 );
1060
2.84k
  }
1061
73.8k
  return( 1 );
1062
76.6k
}
1063
1064
/* Retrieves the table value data for a specific index value
1065
 * Returns 1 if successful or -1 on error
1066
 */
1067
int libpff_table_get_value_data_by_index_value(
1068
     libpff_table_t *table,
1069
     libpff_table_index_value_t *table_index_value,
1070
     libbfio_handle_t *file_io_handle,
1071
     uint8_t **value_data,
1072
     size_t *value_data_size,
1073
     libcerror_error_t **error )
1074
75.7k
{
1075
75.7k
  libpff_data_block_t *data_block = NULL;
1076
75.7k
  static char *function           = "libpff_table_get_value_data_by_index_value";
1077
1078
75.7k
  if( table == NULL )
1079
0
  {
1080
0
    libcerror_error_set(
1081
0
     error,
1082
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1083
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1084
0
     "%s: invalid table.",
1085
0
     function );
1086
1087
0
    return( -1 );
1088
0
  }
1089
75.7k
  if( table_index_value == NULL )
1090
0
  {
1091
0
    libcerror_error_set(
1092
0
     error,
1093
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1094
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1095
0
     "%s: invalid table.",
1096
0
     function );
1097
1098
0
    return( -1 );
1099
0
  }
1100
75.7k
  if( value_data == NULL )
1101
0
  {
1102
0
    libcerror_error_set(
1103
0
     error,
1104
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1105
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1106
0
     "%s: invalid value data.",
1107
0
     function );
1108
1109
0
    return( -1 );
1110
0
  }
1111
75.7k
  if( value_data_size == NULL )
1112
0
  {
1113
0
    libcerror_error_set(
1114
0
     error,
1115
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1116
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1117
0
     "%s: invalid value data size.",
1118
0
     function );
1119
1120
0
    return( -1 );
1121
0
  }
1122
  /* Retrieve the corresponding data block
1123
   */
1124
75.7k
  if( libfdata_list_get_element_value_by_index(
1125
75.7k
       table->descriptor_data_list,
1126
75.7k
       (intptr_t *) file_io_handle,
1127
75.7k
       (libfdata_cache_t *) table->descriptor_data_cache,
1128
75.7k
       (int) table_index_value->array_entry,
1129
75.7k
       (intptr_t **) &data_block,
1130
75.7k
       0,
1131
75.7k
       error ) != 1 )
1132
0
  {
1133
0
    libcerror_error_set(
1134
0
     error,
1135
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1136
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1137
0
     "%s: unable to retrieve data block: %" PRIu32 ".",
1138
0
     function,
1139
0
     table_index_value->array_entry );
1140
1141
0
    return( -1 );
1142
0
  }
1143
75.7k
  if( data_block == NULL )
1144
0
  {
1145
0
    libcerror_error_set(
1146
0
     error,
1147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1148
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1149
0
     "%s: missing data block: %" PRIu32 ".",
1150
0
     function,
1151
0
     table_index_value->array_entry );
1152
1153
0
    return( -1 );
1154
0
  }
1155
75.7k
  if( data_block->data == NULL )
1156
0
  {
1157
0
    libcerror_error_set(
1158
0
     error,
1159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1160
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1161
0
     "%s: invalid data block: %" PRIu32 " - missing data.",
1162
0
     function,
1163
0
     table_index_value->array_entry );
1164
1165
0
    return( -1 );
1166
0
  }
1167
75.7k
  if( (size_t) table_index_value->offset >= data_block->uncompressed_data_size )
1168
0
  {
1169
0
    libcerror_error_set(
1170
0
     error,
1171
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1172
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1173
0
     "%s: table value offset exceeds data block size.",
1174
0
     function );
1175
1176
0
    return( -1 );
1177
0
  }
1178
75.7k
  if( ( (size_t) table_index_value->offset + (size_t) table_index_value->size ) >= data_block->uncompressed_data_size )
1179
0
  {
1180
0
    libcerror_error_set(
1181
0
     error,
1182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1183
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1184
0
     "%s: table value size exceeds data block size.",
1185
0
     function );
1186
1187
0
    return( -1 );
1188
0
  }
1189
75.7k
  *value_data      = &( data_block->data[ table_index_value->offset ] );
1190
75.7k
  *value_data_size = (size_t) table_index_value->size;
1191
1192
75.7k
  return( 1 );
1193
75.7k
}
1194
1195
/* Retrieves the value data for a specific reference
1196
 * Returns 1 if successful or -1 on error
1197
 */
1198
int libpff_table_get_value_data_by_reference(
1199
     libpff_table_t *table,
1200
     libpff_io_handle_t *io_handle,
1201
     libbfio_handle_t *file_io_handle,
1202
     uint32_t table_index_reference,
1203
     uint8_t **value_data,
1204
     size_t *value_data_size,
1205
     libcerror_error_t **error )
1206
40.4k
{
1207
40.4k
  libpff_table_index_value_t *table_index_value = NULL;
1208
40.4k
  static char *function                         = "libpff_table_get_value_data_by_reference";
1209
1210
  /* Retrieve the index value of the record entries reference
1211
   */
1212
40.4k
  if( libpff_table_get_index_value_by_reference(
1213
40.4k
       table,
1214
40.4k
       table_index_reference,
1215
40.4k
       io_handle,
1216
40.4k
       &table_index_value,
1217
40.4k
       error ) != 1 )
1218
155
  {
1219
155
    libcerror_error_set(
1220
155
     error,
1221
155
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1222
155
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1223
155
     "%s: unable to retrieve table index value.",
1224
155
     function );
1225
1226
155
    return( -1 );
1227
155
  }
1228
40.3k
  if( libpff_table_get_value_data_by_index_value(
1229
40.3k
       table,
1230
40.3k
       table_index_value,
1231
40.3k
       file_io_handle,
1232
40.3k
       value_data,
1233
40.3k
       value_data_size,
1234
40.3k
       error ) != 1 )
1235
0
  {
1236
0
    libcerror_error_set(
1237
0
     error,
1238
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1239
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1240
0
     "%s: unable to retrieve value data by index value.",
1241
0
     function );
1242
1243
0
    return( -1 );
1244
0
  }
1245
40.3k
  return( 1 );
1246
40.3k
}
1247
1248
/* Retrieves a copy of the value data for a specific reference
1249
 * Returns 1 if successful or -1 on error
1250
 */
1251
int libpff_table_clone_value_data_by_reference(
1252
     libpff_table_t *table,
1253
     uint32_t table_index_reference,
1254
     libpff_io_handle_t *io_handle,
1255
     libbfio_handle_t *file_io_handle,
1256
     uint8_t **value_data,
1257
     size_t *value_data_size,
1258
     libcerror_error_t **error )
1259
15.8k
{
1260
15.8k
  uint8_t *table_value_data    = NULL;
1261
15.8k
  static char *function        = "libpff_table_clone_value_data_by_reference";
1262
15.8k
  size_t table_value_data_size = 0;
1263
1264
15.8k
  if( value_data == NULL )
1265
0
  {
1266
0
    libcerror_error_set(
1267
0
     error,
1268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1269
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1270
0
     "%s: invalid value data.",
1271
0
     function );
1272
1273
0
    return( -1 );
1274
0
  }
1275
15.8k
  if( value_data_size == NULL )
1276
0
  {
1277
0
    libcerror_error_set(
1278
0
     error,
1279
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1280
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1281
0
     "%s: invalid value data size.",
1282
0
     function );
1283
1284
0
    return( -1 );
1285
0
  }
1286
15.8k
  if( libpff_table_get_value_data_by_reference(
1287
15.8k
       table,
1288
15.8k
       io_handle,
1289
15.8k
       file_io_handle,
1290
15.8k
       table_index_reference,
1291
15.8k
       &table_value_data,
1292
15.8k
       &table_value_data_size,
1293
15.8k
       error ) != 1 )
1294
96
  {
1295
96
    libcerror_error_set(
1296
96
     error,
1297
96
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1298
96
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1299
96
     "%s: unable to retrieve value data.",
1300
96
     function );
1301
1302
96
    goto on_error;
1303
96
  }
1304
15.7k
  if( ( table_value_data == NULL )
1305
15.7k
   || ( table_value_data_size == 0 ) )
1306
3
  {
1307
3
    libcerror_error_set(
1308
3
     error,
1309
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1310
3
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1311
3
     "%s: missing values array data.",
1312
3
     function );
1313
1314
3
    goto on_error;
1315
3
  }
1316
15.7k
  if( table_value_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
1317
0
  {
1318
0
    libcerror_error_set(
1319
0
     error,
1320
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1321
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1322
0
     "%s: invalid table value data size value exceeds maximum allocation size.",
1323
0
     function );
1324
1325
0
    goto on_error;
1326
0
  }
1327
15.7k
  *value_data = (uint8_t *) memory_allocate(
1328
15.7k
                             table_value_data_size );
1329
1330
15.7k
  if( *value_data == NULL )
1331
0
  {
1332
0
    libcerror_error_set(
1333
0
     error,
1334
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1335
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1336
0
     "%s: unable to create value data.",
1337
0
     function );
1338
1339
0
    goto on_error;
1340
0
  }
1341
15.7k
  *value_data_size = table_value_data_size;
1342
1343
15.7k
  if( memory_copy(
1344
15.7k
       *value_data,
1345
15.7k
       table_value_data,
1346
15.7k
       table_value_data_size ) == NULL )
1347
0
  {
1348
0
    libcerror_error_set(
1349
0
     error,
1350
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1351
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1352
0
     "%s: unable to copy value data.",
1353
0
     function );
1354
1355
0
    goto on_error;
1356
0
  }
1357
15.7k
  return( 1 );
1358
1359
99
on_error:
1360
99
  if( *value_data != NULL )
1361
0
  {
1362
0
    memory_free(
1363
0
     *value_data );
1364
1365
0
    *value_data = NULL;
1366
0
  }
1367
99
  *value_data_size = 0;
1368
1369
99
  return( -1 );
1370
15.7k
}
1371
1372
/* Retrieves the number of record sets
1373
 * Returns 1 if successful or -1 on error
1374
 */
1375
int libpff_table_get_number_of_record_sets(
1376
     libpff_table_t *table,
1377
     int *number_of_record_sets,
1378
     libcerror_error_t **error )
1379
67
{
1380
67
  static char *function = "libpff_table_get_number_of_record_sets";
1381
1382
67
  if( table == NULL )
1383
0
  {
1384
0
    libcerror_error_set(
1385
0
     error,
1386
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1387
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1388
0
     "%s: invalid table.",
1389
0
     function );
1390
1391
0
    return( -1 );
1392
0
  }
1393
67
  if( libcdata_array_get_number_of_entries(
1394
67
       table->record_sets_array,
1395
67
       number_of_record_sets,
1396
67
       error ) != 1 )
1397
0
  {
1398
0
    libcerror_error_set(
1399
0
     error,
1400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1402
0
     "%s: unable to retrieve number of record sets array entries.",
1403
0
     function );
1404
1405
0
    return( -1 );
1406
0
  }
1407
67
  return( 1 );
1408
67
}
1409
1410
/* Retrieves a specific record set
1411
 * Returns 1 if successful or -1 on error
1412
 */
1413
int libpff_table_get_record_set_by_index(
1414
     libpff_table_t *table,
1415
     int record_set_index,
1416
     libpff_record_set_t **record_set,
1417
     libcerror_error_t **error )
1418
59
{
1419
59
  static char *function = "libpff_table_get_record_set_by_index";
1420
1421
59
  if( table == NULL )
1422
0
  {
1423
0
    libcerror_error_set(
1424
0
     error,
1425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1427
0
     "%s: invalid table.",
1428
0
     function );
1429
1430
0
    return( -1 );
1431
0
  }
1432
59
  if( libcdata_array_get_entry_by_index(
1433
59
       table->record_sets_array,
1434
59
       record_set_index,
1435
59
       (intptr_t **) record_set,
1436
59
       error ) != 1 )
1437
0
  {
1438
0
    libcerror_error_set(
1439
0
     error,
1440
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1441
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1442
0
     "%s: unable to retrieve record sets array entry: %d.",
1443
0
     function,
1444
0
     record_set_index );
1445
1446
0
    return( -1 );
1447
0
  }
1448
59
  return( 1 );
1449
59
}
1450
1451
/* Retrieves the number of entries
1452
 * Returns 1 if successful or -1 on error
1453
 */
1454
int libpff_table_get_number_of_entries(
1455
     libpff_table_t *table,
1456
     int *number_of_entries,
1457
     libcerror_error_t **error )
1458
0
{
1459
0
  libpff_record_set_t *record_set = NULL;
1460
0
  static char *function           = "libpff_table_get_number_of_entries";
1461
0
  int number_of_sets              = 0;
1462
1463
0
  if( table == NULL )
1464
0
  {
1465
0
    libcerror_error_set(
1466
0
     error,
1467
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1468
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1469
0
     "%s: invalid table.",
1470
0
     function );
1471
1472
0
    return( -1 );
1473
0
  }
1474
0
  if( libcdata_array_get_number_of_entries(
1475
0
       table->record_sets_array,
1476
0
       &number_of_sets,
1477
0
       error ) != 1 )
1478
0
  {
1479
0
    libcerror_error_set(
1480
0
     error,
1481
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1482
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1483
0
     "%s: unable to retrieve number of record sets array entries.",
1484
0
     function );
1485
1486
0
    return( -1 );
1487
0
  }
1488
0
  if( number_of_sets > 0 )
1489
0
  {
1490
0
    if( libcdata_array_get_entry_by_index(
1491
0
         table->record_sets_array,
1492
0
         0,
1493
0
         (intptr_t **) &record_set,
1494
0
         error ) != 1 )
1495
0
    {
1496
0
      libcerror_error_set(
1497
0
       error,
1498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1499
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1500
0
       "%s: unable to retrieve record set: 0.",
1501
0
       function );
1502
1503
0
      return( -1 );
1504
0
    }
1505
0
    if( libpff_record_set_get_number_of_entries(
1506
0
         record_set,
1507
0
         number_of_entries,
1508
0
         error ) != 1 )
1509
0
    {
1510
0
      libcerror_error_set(
1511
0
       error,
1512
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1513
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1514
0
       "%s: unable to retrieve number of entries of set: 0.",
1515
0
       function );
1516
1517
0
      return( -1 );
1518
0
    }
1519
0
  }
1520
0
  else
1521
0
  {
1522
0
    if( number_of_entries == NULL )
1523
0
    {
1524
0
      libcerror_error_set(
1525
0
       error,
1526
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1527
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1528
0
       "%s: invalid number of entries.",
1529
0
       function );
1530
1531
0
      return( -1 );
1532
0
    }
1533
0
    *number_of_entries = 0;
1534
0
  }
1535
0
  return( 1 );
1536
0
}
1537
1538
/* Retrieves the entry and value type of a the entry matching the index from a table
1539
 * Returns 1 if successful or -1 on error
1540
 */
1541
int libpff_table_get_entry_type_by_index(
1542
     libpff_table_t *table,
1543
     int set_index,
1544
     int entry_index,
1545
     uint32_t *entry_type,
1546
     uint32_t *value_type,
1547
     libpff_name_to_id_map_entry_t **name_to_id_map_entry,
1548
     libcerror_error_t **error )
1549
0
{
1550
0
  libpff_internal_record_entry_t *record_entry = NULL;
1551
0
  static char *function                        = "libpff_table_get_entry_type_by_index";
1552
0
  int number_of_sets                           = 0;
1553
1554
0
  if( table == NULL )
1555
0
  {
1556
0
    libcerror_error_set(
1557
0
     error,
1558
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1559
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1560
0
     "%s: invalid table.",
1561
0
     function );
1562
1563
0
    return( -1 );
1564
0
  }
1565
0
  if( entry_type == NULL )
1566
0
  {
1567
0
    libcerror_error_set(
1568
0
     error,
1569
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1570
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1571
0
     "%s: invalid entry type.",
1572
0
     function );
1573
1574
0
    return( -1 );
1575
0
  }
1576
0
  if( value_type == NULL )
1577
0
  {
1578
0
    libcerror_error_set(
1579
0
     error,
1580
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1581
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1582
0
     "%s: invalid value type.",
1583
0
     function );
1584
1585
0
    return( -1 );
1586
0
  }
1587
0
  if( name_to_id_map_entry == NULL )
1588
0
  {
1589
0
    libcerror_error_set(
1590
0
     error,
1591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1593
0
     "%s: invalid name to id map entry.",
1594
0
     function );
1595
1596
0
    return( -1 );
1597
0
  }
1598
0
  if( libcdata_array_get_number_of_entries(
1599
0
       table->record_sets_array,
1600
0
       &number_of_sets,
1601
0
       error ) != 1 )
1602
0
  {
1603
0
    libcerror_error_set(
1604
0
     error,
1605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1606
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1607
0
     "%s: unable to retrieve number of sets.",
1608
0
     function );
1609
1610
0
    return( -1 );
1611
0
  }
1612
0
  if( number_of_sets == 0 )
1613
0
  {
1614
0
    return( 0 );
1615
0
  }
1616
#if defined( HAVE_DEBUG_OUTPUT )
1617
  if( libcnotify_verbose != 0 )
1618
  {
1619
    libcnotify_printf(
1620
     "%s: retrieving table set: %d entry index: %d\n",
1621
     function,
1622
     set_index,
1623
     entry_index );
1624
  }
1625
#endif
1626
0
  if( libpff_table_get_record_entry_by_index(
1627
0
       table,
1628
0
       set_index,
1629
0
       entry_index,
1630
0
       (libpff_record_entry_t **) &record_entry,
1631
0
       error ) != 1 )
1632
0
  {
1633
0
    libcerror_error_set(
1634
0
     error,
1635
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1636
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1637
0
     "%s: unable to retrieve record entry with set index: %d and entry index: %d.",
1638
0
     function,
1639
0
     set_index,
1640
0
     entry_index );
1641
1642
0
    return( -1 );
1643
0
  }
1644
0
  if( record_entry == NULL )
1645
0
  {
1646
0
    libcerror_error_set(
1647
0
     error,
1648
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1649
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1650
0
     "%s: missing record entry with set index: %d and entry index: %d.",
1651
0
     function,
1652
0
     set_index,
1653
0
     entry_index );
1654
1655
0
    return( -1 );
1656
0
  }
1657
0
  if( record_entry->identifier.format != LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_MAPI_PROPERTY )
1658
0
  {
1659
0
    libcerror_error_set(
1660
0
     error,
1661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1662
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1663
0
     "%s: unsupported record entry identifier format: %" PRIu8 ".",
1664
0
     function,
1665
0
     record_entry->identifier.format );
1666
1667
0
    return( -1 );
1668
0
  }
1669
0
  *entry_type           = record_entry->identifier.entry_type;
1670
0
  *value_type           = record_entry->identifier.value_type;
1671
0
  *name_to_id_map_entry = (libpff_name_to_id_map_entry_t *) record_entry->name_to_id_map_entry;
1672
1673
0
  return( 1 );
1674
0
}
1675
1676
/* Retrieves a specific record entry from the table.
1677
 * Returns 1 if successful or -1 on error
1678
 */
1679
int libpff_table_get_record_entry_by_index(
1680
     libpff_table_t *table,
1681
     int set_index,
1682
     int entry_index,
1683
     libpff_record_entry_t **record_entry,
1684
     libcerror_error_t **error )
1685
81.8k
{
1686
81.8k
  libpff_record_set_t *record_set = NULL;
1687
81.8k
  static char *function           = "libpff_table_get_record_entry_by_index";
1688
1689
81.8k
  if( table == NULL )
1690
0
  {
1691
0
    libcerror_error_set(
1692
0
     error,
1693
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1694
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1695
0
     "%s: invalid table.",
1696
0
     function );
1697
1698
0
    return( -1 );
1699
0
  }
1700
81.8k
  if( libcdata_array_get_entry_by_index(
1701
81.8k
       table->record_sets_array,
1702
81.8k
       set_index,
1703
81.8k
       (intptr_t **) &record_set,
1704
81.8k
       error ) != 1 )
1705
0
  {
1706
0
    libcerror_error_set(
1707
0
     error,
1708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1709
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1710
0
     "%s: unable to retrieve record set: %d.",
1711
0
     function,
1712
0
     set_index );
1713
1714
0
    return( -1 );
1715
0
  }
1716
81.8k
  if( libpff_record_set_get_entry_by_index(
1717
81.8k
       record_set,
1718
81.8k
       entry_index,
1719
81.8k
       record_entry,
1720
81.8k
       error ) != 1 )
1721
0
  {
1722
0
    libcerror_error_set(
1723
0
     error,
1724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1725
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1726
0
     "%s: unable to retrieve entry: %d from record set: %d.",
1727
0
     function,
1728
0
     entry_index,
1729
0
     set_index );
1730
1731
0
    return( -1 );
1732
0
  }
1733
81.8k
  return( 1 );
1734
81.8k
}
1735
1736
/* Retrieves the record entry matching the entry and value type pair from the table.
1737
 *
1738
 * When the LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE flag is set
1739
 * the value type is ignored and set. The default behavior is a strict
1740
 * matching of the value type. In this case the value type must be filled
1741
 * with the corresponding value type
1742
 *
1743
 * When the LIBPFF_ENTRY_VALUE_FLAG_IGNORE_NAME_TO_ID_MAP is set
1744
 * the name to identifier mapping is ignored. The default behavior is
1745
 * to use the mapped entry value. In this case named properties are not
1746
 * retrieved.
1747
 *
1748
 * Returns 1 if successful, 0 if not available or -1 on error
1749
 */
1750
int libpff_table_get_record_entry_by_type(
1751
     libpff_table_t *table,
1752
     int set_index,
1753
     uint32_t entry_type,
1754
     uint32_t value_type,
1755
     libpff_record_entry_t **record_entry,
1756
     uint8_t flags,
1757
     libcerror_error_t **error )
1758
1.31k
{
1759
1.31k
  libpff_record_set_t *record_set = NULL;
1760
1.31k
  static char *function           = "libpff_table_get_record_entry_by_type";
1761
1.31k
  int number_of_sets              = 0;
1762
1.31k
  int result                      = 0;
1763
1764
1.31k
  if( table == NULL )
1765
0
  {
1766
0
    libcerror_error_set(
1767
0
     error,
1768
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1769
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1770
0
     "%s: invalid table.",
1771
0
     function );
1772
1773
0
    return( -1 );
1774
0
  }
1775
1.31k
  if( libcdata_array_get_number_of_entries(
1776
1.31k
       table->record_sets_array,
1777
1.31k
       &number_of_sets,
1778
1.31k
       error ) != 1 )
1779
0
  {
1780
0
    libcerror_error_set(
1781
0
     error,
1782
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1783
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1784
0
     "%s: unable to retrieve number of sets.",
1785
0
     function );
1786
1787
0
    return( -1 );
1788
0
  }
1789
1.31k
  if( number_of_sets == 0 )
1790
12
  {
1791
12
    return( 0 );
1792
12
  }
1793
#if defined( HAVE_DEBUG_OUTPUT )
1794
  if( libcnotify_verbose != 0 )
1795
  {
1796
    libcnotify_printf(
1797
     "%s: retrieving table set: %d entry type: 0x%04" PRIx32 "\n",
1798
     function,
1799
     set_index,
1800
     entry_type );
1801
  }
1802
#endif
1803
1.30k
  if( libcdata_array_get_entry_by_index(
1804
1.30k
       table->record_sets_array,
1805
1.30k
       set_index,
1806
1.30k
       (intptr_t **) &record_set,
1807
1.30k
       error ) != 1 )
1808
0
  {
1809
0
    libcerror_error_set(
1810
0
     error,
1811
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1812
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1813
0
     "%s: unable to retrieve record set: %d.",
1814
0
     function,
1815
0
     set_index );
1816
1817
0
    return( -1 );
1818
0
  }
1819
1.30k
  result = libpff_record_set_get_entry_by_type(
1820
1.30k
            record_set,
1821
1.30k
            entry_type,
1822
1.30k
            value_type,
1823
1.30k
            record_entry,
1824
1.30k
            flags,
1825
1.30k
            error );
1826
1827
1.30k
  if( result == -1 )
1828
0
  {
1829
0
    libcerror_error_set(
1830
0
     error,
1831
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1832
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1833
0
     "%s: unable to retrieve entry from record set: %d.",
1834
0
     function,
1835
0
     set_index );
1836
1837
0
    return( -1 );
1838
0
  }
1839
1.30k
  return( result );
1840
1.30k
}
1841
1842
/* Retrieves the record entry matching the UTF-8 encoded name from the table.
1843
 *
1844
 * When the LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE flag is set
1845
 * the value type is ignored and set. The default behavior is a strict
1846
 * matching of the value type. In this case the value type must be filled
1847
 * with the corresponding value type
1848
 *
1849
 * Returns 1 if successful, 0 if not available or -1 on error
1850
 */
1851
int libpff_table_get_record_entry_by_utf8_name(
1852
     libpff_table_t *table,
1853
     int set_index,
1854
     const uint8_t *utf8_string,
1855
     size_t utf8_string_length,
1856
     uint32_t value_type,
1857
     libpff_record_entry_t **record_entry,
1858
     uint8_t flags,
1859
     libcerror_error_t **error )
1860
0
{
1861
0
  libpff_record_set_t *record_set = NULL;
1862
0
  static char *function           = "libpff_table_get_record_entry_by_utf8_name";
1863
0
  int number_of_sets              = 0;
1864
0
  int result                      = 0;
1865
1866
0
  if( table == NULL )
1867
0
  {
1868
0
    libcerror_error_set(
1869
0
     error,
1870
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1871
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1872
0
     "%s: invalid table.",
1873
0
     function );
1874
1875
0
    return( -1 );
1876
0
  }
1877
0
  if( libcdata_array_get_number_of_entries(
1878
0
       table->record_sets_array,
1879
0
       &number_of_sets,
1880
0
       error ) != 1 )
1881
0
  {
1882
0
    libcerror_error_set(
1883
0
     error,
1884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1885
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1886
0
     "%s: unable to retrieve number of sets.",
1887
0
     function );
1888
1889
0
    return( -1 );
1890
0
  }
1891
0
  if( number_of_sets == 0 )
1892
0
  {
1893
0
    return( 0 );
1894
0
  }
1895
#if defined( HAVE_DEBUG_OUTPUT )
1896
  if( libcnotify_verbose != 0 )
1897
  {
1898
/* TODO add system string support
1899
    libcnotify_printf(
1900
     "%s: retrieving table set: %d name: %s\n",
1901
     function,
1902
     set_index,
1903
     utf8_string );
1904
*/
1905
  }
1906
#endif
1907
0
  if( libcdata_array_get_entry_by_index(
1908
0
       table->record_sets_array,
1909
0
       set_index,
1910
0
       (intptr_t **) &record_set,
1911
0
       error ) != 1 )
1912
0
  {
1913
0
    libcerror_error_set(
1914
0
     error,
1915
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1916
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1917
0
     "%s: unable to retrieve record set: %d.",
1918
0
     function,
1919
0
     set_index );
1920
1921
0
    return( -1 );
1922
0
  }
1923
0
  result = libpff_record_set_get_entry_by_utf8_name(
1924
0
            record_set,
1925
0
            utf8_string,
1926
0
            utf8_string_length,
1927
0
            value_type,
1928
0
            record_entry,
1929
0
            flags,
1930
0
            error );
1931
1932
0
  if( result == -1 )
1933
0
  {
1934
0
    libcerror_error_set(
1935
0
     error,
1936
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1937
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1938
0
     "%s: unable to retrieve entry from record set: %d.",
1939
0
     function,
1940
0
     set_index );
1941
1942
0
    return( -1 );
1943
0
  }
1944
0
  return( result );
1945
0
}
1946
1947
/* Retrieves the record entry matching the UTF-16 encoded name from the table.
1948
 *
1949
 * When the LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE flag is set
1950
 * the value type is ignored and set. The default behavior is a strict
1951
 * matching of the value type. In this case the value type must be filled
1952
 * with the corresponding value type
1953
 *
1954
 * Returns 1 if successful, 0 if not available or -1 on error
1955
 */
1956
int libpff_table_get_record_entry_by_utf16_name(
1957
     libpff_table_t *table,
1958
     int set_index,
1959
     const uint16_t *utf16_string,
1960
     size_t utf16_string_length,
1961
     uint32_t value_type,
1962
     libpff_record_entry_t **record_entry,
1963
     uint8_t flags,
1964
     libcerror_error_t **error )
1965
0
{
1966
0
  libpff_record_set_t *record_set = NULL;
1967
0
  static char *function           = "libpff_table_get_record_entry_by_utf16_name";
1968
0
  int number_of_sets              = 0;
1969
0
  int result                      = 0;
1970
1971
0
  if( table == NULL )
1972
0
  {
1973
0
    libcerror_error_set(
1974
0
     error,
1975
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1976
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1977
0
     "%s: invalid table.",
1978
0
     function );
1979
1980
0
    return( -1 );
1981
0
  }
1982
0
  if( libcdata_array_get_number_of_entries(
1983
0
       table->record_sets_array,
1984
0
       &number_of_sets,
1985
0
       error ) != 1 )
1986
0
  {
1987
0
    libcerror_error_set(
1988
0
     error,
1989
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1990
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1991
0
     "%s: unable to retrieve number of sets.",
1992
0
     function );
1993
1994
0
    return( -1 );
1995
0
  }
1996
0
  if( number_of_sets == 0 )
1997
0
  {
1998
0
    return( 0 );
1999
0
  }
2000
#if defined( HAVE_DEBUG_OUTPUT )
2001
  if( libcnotify_verbose != 0 )
2002
  {
2003
/* TODO add system string support
2004
    libcnotify_printf(
2005
     "%s: retrieving table set: %d name: %s\n",
2006
     function,
2007
     set_index,
2008
     utf16_entry_name );
2009
*/
2010
  }
2011
#endif
2012
0
  if( libcdata_array_get_entry_by_index(
2013
0
       table->record_sets_array,
2014
0
       set_index,
2015
0
       (intptr_t **) &record_set,
2016
0
       error ) != 1 )
2017
0
  {
2018
0
    libcerror_error_set(
2019
0
     error,
2020
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2021
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2022
0
     "%s: unable to retrieve record set: %d.",
2023
0
     function,
2024
0
     set_index );
2025
2026
0
    return( -1 );
2027
0
  }
2028
0
  result = libpff_record_set_get_entry_by_utf16_name(
2029
0
            record_set,
2030
0
            utf16_string,
2031
0
            utf16_string_length,
2032
0
            value_type,
2033
0
            record_entry,
2034
0
            flags,
2035
0
            error );
2036
2037
0
  if( result == -1 )
2038
0
  {
2039
0
    libcerror_error_set(
2040
0
     error,
2041
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2042
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2043
0
     "%s: unable to retrieve entry from record set: %d.",
2044
0
     function,
2045
0
     set_index );
2046
2047
0
    return( -1 );
2048
0
  }
2049
0
  return( result );
2050
0
}
2051
2052
/* Reads a table and its values
2053
 * Returns 1 if successful or -1 on error
2054
 */
2055
int libpff_table_read(
2056
     libpff_table_t *table,
2057
     libpff_io_handle_t *io_handle,
2058
     libbfio_handle_t *file_io_handle,
2059
     libpff_offsets_index_t *offsets_index,
2060
     libcdata_list_t *name_to_id_map_list,
2061
     int debug_item_type,
2062
     libcerror_error_t **error )
2063
6.02k
{
2064
6.02k
  libpff_data_block_t *data_block               = NULL;
2065
6.02k
  static char *function                         = "libpff_table_read";
2066
2067
#if defined( HAVE_DEBUG_OUTPUT )
2068
  libpff_table_block_index_t *table_block_index = NULL;
2069
  libpff_table_index_value_t *table_index_value = NULL;
2070
  uint8_t *table_value_data                     = NULL;
2071
  size_t table_value_data_size                  = 0;
2072
  uint16_t number_of_table_index_values         = 0;
2073
  uint16_t table_index_value_iterator           = 0;
2074
  int number_of_table_index_array_entries       = 0;
2075
  int table_index_array_iterator                = 0;
2076
#endif
2077
2078
6.02k
  if( table == NULL )
2079
0
  {
2080
0
    libcerror_error_set(
2081
0
     error,
2082
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2083
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2084
0
     "%s: invalid table.",
2085
0
     function );
2086
2087
0
    return( -1 );
2088
0
  }
2089
6.02k
  if( table->data_identifier == 0 )
2090
9
  {
2091
9
    libcerror_error_set(
2092
9
     error,
2093
9
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2094
9
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2095
9
     "%s: invalid table - missing data identifier.",
2096
9
     function );
2097
2098
9
    return( -1 );
2099
9
  }
2100
6.01k
  if( table->local_descriptors_tree != NULL )
2101
0
  {
2102
0
    libcerror_error_set(
2103
0
     error,
2104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2105
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2106
0
     "%s: invalid table - local descriptors tree already set.",
2107
0
     function );
2108
2109
0
    return( -1 );
2110
0
  }
2111
6.01k
  if( table->local_descriptor_values_cache != NULL )
2112
0
  {
2113
0
    libcerror_error_set(
2114
0
     error,
2115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2116
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2117
0
     "%s: invalid table - local descriptor values cache already set.",
2118
0
     function );
2119
2120
0
    return( -1 );
2121
0
  }
2122
6.01k
  if( io_handle == NULL )
2123
0
  {
2124
0
    libcerror_error_set(
2125
0
     error,
2126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2128
0
     "%s: invalid IO handle.",
2129
0
     function );
2130
2131
0
    return( -1 );
2132
0
  }
2133
6.01k
  if( table->local_descriptors_identifier > 0 )
2134
4.20k
  {
2135
4.20k
    if( libpff_local_descriptors_tree_initialize(
2136
4.20k
         &( table->local_descriptors_tree ),
2137
4.20k
         io_handle,
2138
4.20k
         offsets_index,
2139
4.20k
         table->descriptor_identifier,
2140
4.20k
         table->local_descriptors_identifier,
2141
4.20k
         table->recovered,
2142
4.20k
         table->recovered_local_descriptors_identifier_value_index,
2143
4.20k
         error ) != 1 )
2144
0
    {
2145
0
      libcerror_error_set(
2146
0
       error,
2147
0
       LIBCERROR_ERROR_DOMAIN_IO,
2148
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2149
0
       "%s: unable to read local descriptors tree with identifier: %" PRIu64 ".",
2150
0
       function,
2151
0
       table->local_descriptors_identifier );
2152
2153
0
      return( -1 );
2154
0
    }
2155
4.20k
    if( libfcache_cache_initialize(
2156
4.20k
         &( table->local_descriptor_values_cache ),
2157
4.20k
         LIBPFF_MAXIMUM_CACHE_ENTRIES_LOCAL_DESCRIPTORS_VALUES,
2158
4.20k
         error ) != 1 )
2159
0
    {
2160
0
      libcerror_error_set(
2161
0
       error,
2162
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2163
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2164
0
       "%s: unable to create local descriptor values cache.",
2165
0
       function );
2166
2167
0
      if( table->local_descriptors_tree != NULL )
2168
0
      {
2169
0
        libpff_local_descriptors_tree_free(
2170
0
         &( table->local_descriptors_tree ),
2171
0
         NULL );
2172
0
      }
2173
0
      return( -1 );
2174
0
    }
2175
4.20k
  }
2176
6.01k
  if( libpff_table_read_descriptor_data_list(
2177
6.01k
       table,
2178
6.01k
       io_handle,
2179
6.01k
       file_io_handle,
2180
6.01k
       offsets_index,
2181
6.01k
       table->descriptor_identifier,
2182
6.01k
       table->data_identifier,
2183
6.01k
       table->recovered,
2184
6.01k
       table->recovered_data_identifier_value_index,
2185
6.01k
       &( table->descriptor_data_list ),
2186
6.01k
       &( table->descriptor_data_cache ),
2187
6.01k
       error ) != 1 )
2188
1.82k
  {
2189
1.82k
    libcerror_error_set(
2190
1.82k
     error,
2191
1.82k
     LIBCERROR_ERROR_DOMAIN_IO,
2192
1.82k
     LIBCERROR_IO_ERROR_READ_FAILED,
2193
1.82k
     "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
2194
1.82k
     function,
2195
1.82k
     table->descriptor_identifier,
2196
1.82k
     table->data_identifier );
2197
2198
1.82k
    return( -1 );
2199
1.82k
  }
2200
  /* Retrieve the first table data block
2201
   */
2202
4.19k
  if( libfdata_list_get_element_value_by_index(
2203
4.19k
       table->descriptor_data_list,
2204
4.19k
       (intptr_t *) file_io_handle,
2205
4.19k
       (libfdata_cache_t *) table->descriptor_data_cache,
2206
4.19k
       0,
2207
4.19k
       (intptr_t **) &data_block,
2208
4.19k
       0,
2209
4.19k
       error ) != 1 )
2210
25
  {
2211
25
    libcerror_error_set(
2212
25
     error,
2213
25
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2214
25
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2215
25
     "%s: unable to retrieve data block: 0.",
2216
25
     function );
2217
2218
25
    return( -1 );
2219
25
  }
2220
4.16k
  if( data_block == NULL )
2221
0
  {
2222
0
    libcerror_error_set(
2223
0
     error,
2224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2225
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2226
0
     "%s: missing data block: 0.",
2227
0
     function );
2228
2229
0
    return( -1 );
2230
0
  }
2231
4.16k
  if( data_block->data == NULL )
2232
0
  {
2233
0
    libcerror_error_set(
2234
0
     error,
2235
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2236
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2237
0
     "%s: invalid data block: 0 - missing data.",
2238
0
     function );
2239
2240
0
    return( -1 );
2241
0
  }
2242
4.16k
  if( data_block->uncompressed_data_size < sizeof( pff_table_t ) )
2243
308
  {
2244
#if defined( HAVE_DEBUG_OUTPUT )
2245
    if( libcnotify_verbose != 0 )
2246
    {
2247
      libcnotify_printf(
2248
       "%s: descriptor data:\n",
2249
       function );
2250
      libcnotify_print_data(
2251
       data_block->data,
2252
       data_block->uncompressed_data_size,
2253
       0 );
2254
    }
2255
#endif
2256
308
    libcerror_error_set(
2257
308
     error,
2258
308
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2259
308
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2260
308
     "%s: data block: 0 too small to be a table.",
2261
308
     function );
2262
2263
308
    return( -1 );
2264
308
  }
2265
3.85k
  if( libpff_table_header_read_data(
2266
3.85k
       table->header,
2267
3.85k
       data_block->data,
2268
3.85k
       data_block->uncompressed_data_size,
2269
3.85k
       error ) != 1 )
2270
194
  {
2271
194
    libcerror_error_set(
2272
194
     error,
2273
194
     LIBCERROR_ERROR_DOMAIN_IO,
2274
194
     LIBCERROR_IO_ERROR_READ_FAILED,
2275
194
     "%s: unable to read table header.",
2276
194
     function );
2277
2278
194
    return( -1 );
2279
194
  }
2280
3.66k
  if( libpff_table_read_index(
2281
3.66k
       table,
2282
3.66k
       file_io_handle,
2283
3.66k
       error ) != 1 )
2284
240
  {
2285
240
    libcerror_error_set(
2286
240
     error,
2287
240
     LIBCERROR_ERROR_DOMAIN_IO,
2288
240
     LIBCERROR_IO_ERROR_READ_FAILED,
2289
240
     "%s: unable to read table index.",
2290
240
     function );
2291
2292
240
    return( -1 );
2293
240
  }
2294
#if defined( HAVE_DEBUG_OUTPUT )
2295
  if( libcnotify_verbose != 0 )
2296
  {
2297
    if( libcdata_array_get_number_of_entries(
2298
         table->index_array,
2299
         &number_of_table_index_array_entries,
2300
         error ) != 1 )
2301
    {
2302
      libcerror_error_set(
2303
       error,
2304
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2305
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2306
       "%s: unable to retrieve number of table index array entries.",
2307
       function );
2308
2309
      return( -1 );
2310
    }
2311
    for( table_index_array_iterator = 0;
2312
         table_index_array_iterator < number_of_table_index_array_entries;
2313
         table_index_array_iterator++ )
2314
    {
2315
      libcnotify_printf(
2316
       "%s: table index array entry: %d\n",
2317
       function,
2318
       table_index_array_iterator );
2319
2320
      if( libcdata_array_get_entry_by_index(
2321
           table->index_array,
2322
           table_index_array_iterator,
2323
           (intptr_t **) &table_block_index,
2324
           error ) != 1 )
2325
      {
2326
        libcerror_error_set(
2327
         error,
2328
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2329
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2330
         "%s: unable to retrieve table block index: %d.",
2331
         function,
2332
         table_index_array_iterator );
2333
2334
        return( -1 );
2335
      }
2336
      if( libpff_table_block_index_get_number_of_values(
2337
           table_block_index,
2338
           &number_of_table_index_values,
2339
           error ) != 1 )
2340
      {
2341
        libcerror_error_set(
2342
         error,
2343
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2344
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2345
         "%s: unable to retrieve number of table block index values.",
2346
         function );
2347
2348
        return( -1 );
2349
      }
2350
      for( table_index_value_iterator = 0;
2351
           table_index_value_iterator < number_of_table_index_values;
2352
           table_index_value_iterator++ )
2353
      {
2354
        if( libpff_table_block_index_get_value_by_index(
2355
             table_block_index,
2356
             table_index_value_iterator,
2357
             &table_index_value,
2358
             error ) != 1 )
2359
        {
2360
          libcerror_error_set(
2361
           error,
2362
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2363
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2364
           "%s: unable to retrieve table block index value: %" PRIu16 ".",
2365
           function,
2366
           table_index_value_iterator );
2367
2368
          return( -1 );
2369
        }
2370
        if( table_index_value == NULL )
2371
        {
2372
          libcerror_error_set(
2373
           error,
2374
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2375
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2376
           "%s: missing table index value: %" PRIu16 ".",
2377
           function,
2378
           table_index_value_iterator );
2379
2380
          return( -1 );
2381
        }
2382
        if( libpff_table_get_value_data_by_index_value(
2383
             table,
2384
             table_index_value,
2385
             file_io_handle,
2386
             &table_value_data,
2387
             &table_value_data_size,
2388
             error ) != 1 )
2389
        {
2390
          libcerror_error_set(
2391
           error,
2392
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2393
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2394
           "%s: unable to retrieve table value data by index value: %" PRIu16 ".",
2395
           function,
2396
           table_index_value_iterator );
2397
2398
          return( -1 );
2399
        }
2400
        libcnotify_printf(
2401
         "%s: table value: %" PRIu16 " at offset: %" PRIu16 " of size: %" PRIu16 "\n",
2402
         function,
2403
         table_index_value_iterator,
2404
         table_index_value->offset,
2405
         table_index_value->size );
2406
        libcnotify_print_data(
2407
         table_value_data,
2408
         table_value_data_size,
2409
         0 );
2410
      }
2411
    }
2412
    libcnotify_printf(
2413
     "\n" );
2414
  }
2415
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2416
2417
3.42k
  if( libpff_table_read_values(
2418
3.42k
       table,
2419
3.42k
       io_handle,
2420
3.42k
       file_io_handle,
2421
3.42k
       offsets_index,
2422
3.42k
       name_to_id_map_list,
2423
3.42k
       debug_item_type,
2424
3.42k
       error ) != 1 )
2425
2.68k
  {
2426
2.68k
    libcerror_error_set(
2427
2.68k
     error,
2428
2.68k
     LIBCERROR_ERROR_DOMAIN_IO,
2429
2.68k
     LIBCERROR_IO_ERROR_READ_FAILED,
2430
2.68k
     "%s: unable to read table values.",
2431
2.68k
     function );
2432
2433
2.68k
    return( -1 );
2434
2.68k
  }
2435
#if defined( HAVE_DEBUG_OUTPUT )
2436
  if( libcnotify_verbose != 0 )
2437
  {
2438
    libcnotify_printf(
2439
     "\n" );
2440
  }
2441
#endif
2442
740
  return( 1 );
2443
3.42k
}
2444
2445
/* Reads the data list of a descriptor
2446
 * Returns 1 if successful or -1 on error
2447
 */
2448
int libpff_table_read_descriptor_data_list(
2449
     libpff_table_t *table,
2450
     libpff_io_handle_t *io_handle,
2451
     libbfio_handle_t *file_io_handle,
2452
     libpff_offsets_index_t *offsets_index,
2453
     uint32_t descriptor_identifier,
2454
     uint64_t data_identifier,
2455
     uint8_t recovered,
2456
     int recovered_value_index,
2457
     libfdata_list_t **descriptor_data_list,
2458
     libfcache_cache_t **descriptor_data_cache,
2459
     libcerror_error_t **error )
2460
9.59k
{
2461
9.59k
  libpff_data_array_t *data_array          = NULL;
2462
9.59k
  libpff_data_block_t *data_block          = NULL;
2463
9.59k
  libpff_index_value_t *offset_index_value = NULL;
2464
9.59k
  static char *function                    = "libpff_table_read_descriptor_data_list";
2465
9.59k
  uint32_t total_data_size                 = 0;
2466
9.59k
  int element_index                        = 0;
2467
2468
9.59k
  if( table == NULL )
2469
0
  {
2470
0
    libcerror_error_set(
2471
0
     error,
2472
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2473
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2474
0
     "%s: invalid table.",
2475
0
     function );
2476
2477
0
    return( -1 );
2478
0
  }
2479
9.59k
  if( io_handle == NULL )
2480
0
  {
2481
0
    libcerror_error_set(
2482
0
     error,
2483
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2484
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2485
0
     "%s: invalid IO handle.",
2486
0
     function );
2487
2488
0
    return( -1 );
2489
0
  }
2490
9.59k
  if( descriptor_data_list == NULL )
2491
0
  {
2492
0
    libcerror_error_set(
2493
0
     error,
2494
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2495
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2496
0
     "%s: invalid descriptor data list.",
2497
0
     function );
2498
2499
0
    return( -1 );
2500
0
  }
2501
9.59k
  if( *descriptor_data_list != NULL )
2502
0
  {
2503
0
    libcerror_error_set(
2504
0
     error,
2505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2506
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2507
0
     "%s: descriptor data list already set.",
2508
0
     function );
2509
2510
0
    return( -1 );
2511
0
  }
2512
9.59k
  if( descriptor_data_cache == NULL )
2513
0
  {
2514
0
    libcerror_error_set(
2515
0
     error,
2516
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2517
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2518
0
     "%s: invalid descriptor data cache.",
2519
0
     function );
2520
2521
0
    return( -1 );
2522
0
  }
2523
9.59k
  if( *descriptor_data_cache != NULL )
2524
0
  {
2525
0
    libcerror_error_set(
2526
0
     error,
2527
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2528
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2529
0
     "%s: descriptor data cache already set.",
2530
0
     function );
2531
2532
0
    return( -1 );
2533
0
  }
2534
9.59k
  if( libpff_offsets_index_get_index_value_by_identifier(
2535
9.59k
       offsets_index,
2536
9.59k
       io_handle,
2537
9.59k
       file_io_handle,
2538
9.59k
       data_identifier,
2539
9.59k
       recovered,
2540
9.59k
       recovered_value_index,
2541
9.59k
       &offset_index_value,
2542
9.59k
       error ) != 1 )
2543
2.52k
  {
2544
2.52k
    libcerror_error_set(
2545
2.52k
     error,
2546
2.52k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2547
2.52k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2548
2.52k
     "%s: unable to find offset index value identifier: %" PRIu64 ".",
2549
2.52k
     function,
2550
2.52k
     data_identifier );
2551
2552
2.52k
    goto on_error;
2553
2.52k
  }
2554
7.06k
  if( offset_index_value == NULL )
2555
0
  {
2556
0
    libcerror_error_set(
2557
0
     error,
2558
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2559
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2560
0
     "%s: invalid offset index value.",
2561
0
     function );
2562
2563
0
    goto on_error;
2564
0
  }
2565
#if defined( HAVE_DEBUG_OUTPUT )
2566
  if( libcnotify_verbose != 0 )
2567
  {
2568
    libcnotify_printf(
2569
     "%s: identifier: %" PRIu64 " (%s) at offset: %" PRIi64 " of size: %" PRIu32 "\n",
2570
     function,
2571
     offset_index_value->identifier,
2572
     ( ( offset_index_value->identifier & LIBPFF_OFFSET_INDEX_IDENTIFIER_FLAG_INTERNAL ) ? "internal" : "external" ),
2573
     offset_index_value->file_offset,
2574
     offset_index_value->data_size );
2575
  }
2576
#endif
2577
7.06k
  if( offset_index_value->file_offset <= 0 )
2578
86
  {
2579
86
    libcerror_error_set(
2580
86
     error,
2581
86
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2582
86
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2583
86
     "%s: invalid offset index value - file offset value out of bounds.",
2584
86
     function );
2585
2586
86
    goto on_error;
2587
86
  }
2588
6.98k
  if( offset_index_value->data_size == 0 )
2589
123
  {
2590
123
    libcerror_error_set(
2591
123
     error,
2592
123
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2593
123
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2594
123
     "%s: invalid offset index value - data size value value out of bounds.",
2595
123
     function );
2596
2597
123
    goto on_error;
2598
123
  }
2599
#if UINT32_MAX > SSIZE_MAX
2600
  if( offset_index_value->data_size > (size32_t) SSIZE_MAX )
2601
  {
2602
    libcerror_error_set(
2603
     error,
2604
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2605
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2606
     "%s: invalid offset index value - data size value exceeds maximum.",
2607
     function );
2608
2609
    goto on_error;
2610
  }
2611
#endif
2612
6.85k
  if( libpff_data_block_initialize(
2613
6.85k
       &data_block,
2614
6.85k
       io_handle,
2615
6.85k
       descriptor_identifier,
2616
6.85k
       data_identifier,
2617
6.85k
       error ) != 1 )
2618
0
  {
2619
0
    libcerror_error_set(
2620
0
     error,
2621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2622
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2623
0
     "%s: unable to create data block.",
2624
0
     function );
2625
2626
0
    goto on_error;
2627
0
  }
2628
6.85k
  if( libpff_data_block_read_file_io_handle(
2629
6.85k
       data_block,
2630
6.85k
       file_io_handle,
2631
6.85k
       offset_index_value->file_offset,
2632
6.85k
       offset_index_value->data_size,
2633
6.85k
       io_handle->file_type,
2634
6.85k
       error ) != 1 )
2635
702
  {
2636
702
    libcerror_error_set(
2637
702
     error,
2638
702
     LIBCERROR_ERROR_DOMAIN_IO,
2639
702
     LIBCERROR_IO_ERROR_READ_FAILED,
2640
702
     "%s: unable to read data block at offset: %" PRIi64 ".",
2641
702
     function,
2642
702
     offset_index_value->file_offset );
2643
2644
702
    goto on_error;
2645
702
  }
2646
  /* Check if the data block contains a data array
2647
   * The data array should have the internal flag set in the (data) offset index identifier
2648
   * The data array starts with 0x01 followed by either 0x01 or 0x02
2649
   */
2650
6.15k
  if( ( ( data_identifier & (uint64_t) LIBPFF_OFFSET_INDEX_IDENTIFIER_FLAG_INTERNAL ) != 0 )
2651
6.15k
   && ( ( data_block->data[ 0 ] == 0x01 )
2652
1.72k
    &&  ( ( data_block->data[ 1 ] == 0x01 )
2653
1.46k
     ||   ( data_block->data[ 1 ] == 0x02 ) ) ) )
2654
1.35k
  {
2655
1.35k
    if( libpff_data_array_initialize(
2656
1.35k
         &data_array,
2657
1.35k
         io_handle,
2658
1.35k
         descriptor_identifier,
2659
1.35k
         data_identifier,
2660
1.35k
         error ) != 1 )
2661
0
    {
2662
0
      libcerror_error_set(
2663
0
       error,
2664
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2665
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2666
0
       "%s: unable to create data array.",
2667
0
       function );
2668
2669
0
      goto on_error;
2670
0
    }
2671
1.35k
    if( libfdata_list_initialize(
2672
1.35k
         descriptor_data_list,
2673
1.35k
         (intptr_t *) data_array,
2674
1.35k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_array_free,
2675
1.35k
         (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_array_clone,
2676
1.35k
         (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_data_array_read_element_data,
2677
1.35k
         NULL,
2678
1.35k
         LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
2679
1.35k
         error ) != 1 )
2680
0
    {
2681
0
      libcerror_error_set(
2682
0
       error,
2683
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2684
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2685
0
       "%s: unable to create descriptor data list.",
2686
0
       function );
2687
2688
0
      goto on_error;
2689
0
    }
2690
    /* The data_array is now managed by the list */
2691
2692
1.35k
    if( libpff_data_array_read_entries(
2693
1.35k
         data_array,
2694
1.35k
         io_handle,
2695
1.35k
         file_io_handle,
2696
1.35k
         offsets_index,
2697
1.35k
         *descriptor_data_list,
2698
1.35k
         recovered,
2699
1.35k
         data_block->data,
2700
1.35k
         (size_t) data_block->uncompressed_data_size,
2701
1.35k
         &total_data_size,
2702
1.35k
         0,
2703
1.35k
         error ) != 1 )
2704
1.18k
    {
2705
1.18k
      libcerror_error_set(
2706
1.18k
       error,
2707
1.18k
       LIBCERROR_ERROR_DOMAIN_IO,
2708
1.18k
       LIBCERROR_IO_ERROR_READ_FAILED,
2709
1.18k
       "%s: unable to read data array entries.",
2710
1.18k
       function );
2711
2712
1.18k
      data_array = NULL;
2713
2714
1.18k
      goto on_error;
2715
1.18k
    }
2716
173
    if( libpff_data_block_free(
2717
173
         &data_block,
2718
173
         error ) != 1 )
2719
0
    {
2720
0
      libcerror_error_set(
2721
0
       error,
2722
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2723
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2724
0
       "%s: unable to free data block.",
2725
0
       function );
2726
2727
0
      data_array = NULL;
2728
2729
0
      goto on_error;
2730
0
    }
2731
173
    if( libfcache_cache_initialize(
2732
173
         descriptor_data_cache,
2733
173
         LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_ARRAY,
2734
173
         error ) != 1 )
2735
0
    {
2736
0
      libcerror_error_set(
2737
0
       error,
2738
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2739
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2740
0
       "%s: unable to create descriptor data cache.",
2741
0
       function );
2742
2743
0
      data_array = NULL;
2744
2745
0
      goto on_error;
2746
0
    }
2747
173
  }
2748
4.80k
  else
2749
4.80k
  {
2750
4.80k
    if( libpff_data_block_decrypt_data(
2751
4.80k
         data_block,
2752
4.80k
         0,
2753
4.80k
         error ) != 1 )
2754
0
    {
2755
0
      libcerror_error_set(
2756
0
       error,
2757
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2758
0
       LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
2759
0
       "%s: unable to decrypt data block data.",
2760
0
       function );
2761
2762
0
      goto on_error;
2763
0
    }
2764
/* TODO change data block not be a data handle ? pass a descriptor instead ? */
2765
4.80k
    if( libfdata_list_initialize(
2766
4.80k
         descriptor_data_list,
2767
4.80k
         (intptr_t *) data_block,
2768
4.80k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free,
2769
4.80k
         (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_block_clone,
2770
4.80k
         (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_data_block_read_element_data,
2771
4.80k
         NULL,
2772
4.80k
         LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
2773
4.80k
         error ) != 1 )
2774
0
    {
2775
0
      libcerror_error_set(
2776
0
       error,
2777
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2778
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2779
0
       "%s: unable to create descriptor data list.",
2780
0
       function );
2781
2782
0
      goto on_error;
2783
0
    }
2784
    /* The data_block is now managed by the list */
2785
2786
4.80k
    if( libfdata_list_append_element_with_mapped_size(
2787
4.80k
         *descriptor_data_list,
2788
4.80k
         &element_index,
2789
4.80k
         0,
2790
4.80k
         offset_index_value->file_offset,
2791
4.80k
         (size64_t) offset_index_value->data_size,
2792
4.80k
         0,
2793
4.80k
         (size_t) data_block->uncompressed_data_size,
2794
4.80k
         error ) != 1 )
2795
0
    {
2796
0
      libcerror_error_set(
2797
0
       error,
2798
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2799
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2800
0
       "%s: unable to append data list element.",
2801
0
       function );
2802
2803
0
      data_block = NULL;
2804
2805
0
      goto on_error;
2806
0
    }
2807
4.80k
    if( libfcache_cache_initialize(
2808
4.80k
         descriptor_data_cache,
2809
4.80k
         LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_BLOCK,
2810
4.80k
         error ) != 1 )
2811
0
    {
2812
0
      libcerror_error_set(
2813
0
       error,
2814
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2815
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2816
0
       "%s: unable to create descriptor data cache.",
2817
0
       function );
2818
2819
0
      data_block = NULL;
2820
2821
0
      goto on_error;
2822
0
    }
2823
    /* The data block is managed by the list and should not be managed by the cache as well
2824
     */
2825
4.80k
    if( libfdata_list_set_element_value_by_index(
2826
4.80k
         *descriptor_data_list,
2827
4.80k
         (intptr_t *) file_io_handle,
2828
4.80k
         (libfdata_cache_t *) *descriptor_data_cache,
2829
4.80k
         0,
2830
4.80k
         (intptr_t *) data_block,
2831
4.80k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free,
2832
4.80k
         LIBFDATA_LIST_ELEMENT_VALUE_FLAG_NON_MANAGED,
2833
4.80k
         error ) != 1 )
2834
0
    {
2835
0
      libcerror_error_set(
2836
0
       error,
2837
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2838
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2839
0
       "%s: unable to set data list element: 0.",
2840
0
       function );
2841
2842
0
      data_block = NULL;
2843
2844
0
      goto on_error;
2845
0
    }
2846
4.80k
  }
2847
4.97k
  if( libpff_index_value_free(
2848
4.97k
       &offset_index_value,
2849
4.97k
       error ) != 1 )
2850
0
  {
2851
0
    libcerror_error_set(
2852
0
     error,
2853
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2854
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2855
0
     "%s: unable to free offsets index value.",
2856
0
     function );
2857
2858
0
    goto on_error;
2859
0
  }
2860
4.97k
  return( 1 );
2861
2862
4.62k
on_error:
2863
4.62k
  if( *descriptor_data_cache != NULL )
2864
0
  {
2865
0
    libfcache_cache_free(
2866
0
     descriptor_data_cache,
2867
0
     NULL );
2868
0
  }
2869
4.62k
  if( *descriptor_data_list != NULL )
2870
1.18k
  {
2871
1.18k
    libfdata_list_free(
2872
1.18k
     descriptor_data_list,
2873
1.18k
     NULL );
2874
1.18k
  }
2875
4.62k
  if( data_array != NULL )
2876
0
  {
2877
0
    libpff_data_array_free(
2878
0
     &data_array,
2879
0
     NULL );
2880
0
  }
2881
4.62k
  if( data_block != NULL )
2882
1.88k
  {
2883
1.88k
    libpff_data_block_free(
2884
1.88k
     &data_block,
2885
1.88k
     NULL );
2886
1.88k
  }
2887
4.62k
  if( offset_index_value != NULL )
2888
2.09k
  {
2889
2.09k
    libpff_index_value_free(
2890
2.09k
     &offset_index_value,
2891
2.09k
     NULL );
2892
2.09k
  }
2893
4.62k
  return( -1 );
2894
4.97k
}
2895
2896
/* Reads table index entries
2897
 * Returns 1 if successful or -1 on error
2898
 */
2899
int libpff_table_read_index_entries(
2900
     libpff_table_t *table,
2901
     libpff_data_block_t *data_block,
2902
     libpff_table_block_index_t *table_block_index,
2903
     uint32_t table_array_entry_iterator,
2904
     libcerror_error_t **error )
2905
3.67k
{
2906
3.67k
  libpff_table_index_value_t *table_index_value = NULL;
2907
3.67k
  static char *function                         = "libpff_table_read_index_entries";
2908
3.67k
  size_t data_offset                            = 0;
2909
3.67k
  uint32_t table_index_offsets_data_size        = 0;
2910
3.67k
  uint16_t table_block_value_index              = 0;
2911
3.67k
  uint16_t table_index_offset                   = 0;
2912
3.67k
  uint16_t table_index_value_iterator           = 0;
2913
3.67k
  uint16_t table_number_of_index_offsets        = 0;
2914
3.67k
  uint16_t table_number_of_unused_index_offsets = 0;
2915
3.67k
  uint16_t table_value_end_offset               = 0;
2916
3.67k
  uint16_t table_value_start_offset             = 0;
2917
2918
3.67k
  if( table == NULL )
2919
0
  {
2920
0
    libcerror_error_set(
2921
0
     error,
2922
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2923
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2924
0
     "%s: invalid table.",
2925
0
     function );
2926
2927
0
    return( -1 );
2928
0
  }
2929
3.67k
  if( data_block == NULL )
2930
0
  {
2931
0
    libcerror_error_set(
2932
0
     error,
2933
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2934
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2935
0
     "%s: invalid data block.",
2936
0
     function );
2937
2938
0
    return( -1 );
2939
0
  }
2940
3.67k
  if( data_block->data == NULL )
2941
0
  {
2942
0
    libcerror_error_set(
2943
0
     error,
2944
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2945
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2946
0
     "%s: invalid data block - missing data.",
2947
0
     function );
2948
2949
0
    return( -1 );
2950
0
  }
2951
3.67k
  if( data_block->uncompressed_data_size < 4 )
2952
1
  {
2953
1
    libcerror_error_set(
2954
1
     error,
2955
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2956
1
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2957
1
     "%s: invalid data block - uncompressed data size value out of bounds.",
2958
1
     function );
2959
2960
1
    return( -1 );
2961
1
  }
2962
3.67k
  byte_stream_copy_to_uint16_little_endian(
2963
3.67k
   data_block->data,
2964
3.67k
   table_index_offset );
2965
2966
#if defined( HAVE_DEBUG_OUTPUT )
2967
  if( libcnotify_verbose != 0 )
2968
  {
2969
    libcnotify_printf(
2970
     "%s: table index offset\t\t\t: %" PRIu16 "\n",
2971
     function,
2972
     table_index_offset );
2973
  }
2974
#endif
2975
3.67k
  if( ( table_index_offset == 0 )
2976
3.67k
   || ( (uint32_t) table_index_offset >= ( data_block->uncompressed_data_size - 4 ) ) )
2977
51
  {
2978
51
    libcerror_error_set(
2979
51
     error,
2980
51
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2981
51
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2982
51
     "%s: invalid table index offset value out of bounds: %zd.",
2983
51
     function, table_index_offset );
2984
2985
51
    goto on_error;
2986
51
  }
2987
  /* Determine which values are in the table using the index
2988
   */
2989
3.62k
        data_offset = table_index_offset;
2990
2991
#if defined( HAVE_DEBUG_OUTPUT )
2992
  if( libcnotify_verbose != 0 )
2993
  {
2994
    libcnotify_printf(
2995
     "%s: table index:\n",
2996
     function );
2997
    libcnotify_print_data(
2998
     &( data_block->data[ data_offset ] ),
2999
     4,
3000
     0 );
3001
  }
3002
#endif
3003
3.62k
  byte_stream_copy_to_uint16_little_endian(
3004
3.62k
   ( (pff_table_index_t *) &( data_block->data[ data_offset ] ) )->number_of_offsets,
3005
3.62k
   table_number_of_index_offsets );
3006
3007
3.62k
  byte_stream_copy_to_uint16_little_endian(
3008
3.62k
   ( (pff_table_index_t *) &( data_block->data[ data_offset ] ) )->number_of_unused_offsets,
3009
3.62k
   table_number_of_unused_index_offsets );
3010
3011
3.62k
  data_offset += 4;
3012
3013
#if defined( HAVE_DEBUG_OUTPUT )
3014
  if( libcnotify_verbose != 0 )
3015
  {
3016
    libcnotify_printf(
3017
     "%s: table number of index offsets\t\t: %" PRIu16 "\n",
3018
     function,
3019
     table_number_of_index_offsets );
3020
3021
    libcnotify_printf(
3022
     "%s: table number of unused index offsets\t: %" PRIu16 "\n",
3023
     function,
3024
     table_number_of_unused_index_offsets );
3025
  }
3026
#endif
3027
  /* Fill table block index
3028
   * The table number of index items should be considered more of a last item number
3029
   * The table actually contains 1 additional table index value
3030
   */
3031
3.62k
  if( table_number_of_index_offsets > 0 )
3032
3.55k
  {
3033
3.55k
    table_index_offsets_data_size = (uint32_t) table_number_of_index_offsets * 2;
3034
3035
3.55k
    if( ( table_index_offsets_data_size > ( data_block->uncompressed_data_size - 4 ) )
3036
3.55k
     || ( (uint32_t) table_index_offset >= ( data_block->uncompressed_data_size - 4 - table_index_offsets_data_size ) ) )
3037
72
    {
3038
72
      libcerror_error_set(
3039
72
       error,
3040
72
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3041
72
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3042
72
       "%s: invalid number of index offsets value out of bounds.",
3043
72
       function );
3044
3045
72
      goto on_error;
3046
72
    }
3047
#if defined( HAVE_DEBUG_OUTPUT )
3048
    if( libcnotify_verbose != 0 )
3049
    {
3050
      libcnotify_printf(
3051
       "\n" );
3052
3053
      libcnotify_printf(
3054
       "%s: table index offsets:\n",
3055
       function );
3056
      libcnotify_print_data(
3057
       &( data_block->data[ data_offset ] ),
3058
       (size_t) table_index_offsets_data_size,
3059
       0 );
3060
    }
3061
#endif
3062
    /* Fill the table index values
3063
     */
3064
3.48k
    byte_stream_copy_to_uint16_little_endian(
3065
3.48k
     &( data_block->data[ data_offset ] ),
3066
3.48k
     table_value_start_offset );
3067
3068
3.48k
    data_offset += 2;
3069
3070
3.48k
    for( table_index_value_iterator = 0;
3071
103k
         table_index_value_iterator < table_number_of_index_offsets;
3072
100k
         table_index_value_iterator++ )
3073
100k
    {
3074
100k
      byte_stream_copy_to_uint16_little_endian(
3075
100k
       &( data_block->data[ data_offset ] ),
3076
100k
       table_value_end_offset );
3077
3078
100k
      data_offset += 2;
3079
3080
#if defined( HAVE_DEBUG_OUTPUT )
3081
      if( libcnotify_verbose != 0 )
3082
      {
3083
        libcnotify_printf(
3084
         "%s: table index value: %03" PRIu16 " offset\t\t: %" PRIu16 " - %" PRIu16 "\n",
3085
         function,
3086
         table_index_value_iterator,
3087
         table_value_start_offset,
3088
         table_value_end_offset );
3089
      }
3090
#endif
3091
100k
      if( table_value_start_offset > table_value_end_offset )
3092
54
      {
3093
54
        libcerror_error_set(
3094
54
         error,
3095
54
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3096
54
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3097
54
         "%s: table index start offset: %" PRIu16 " exceeds end offset: %" PRIu16 ".",
3098
54
         function,
3099
54
         table_value_start_offset,
3100
54
         table_value_end_offset );
3101
3102
54
        goto on_error;
3103
54
      }
3104
100k
      if( libpff_table_index_value_initialize(
3105
100k
           &table_index_value,
3106
100k
           error ) != 1 )
3107
0
      {
3108
0
        libcerror_error_set(
3109
0
         error,
3110
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3111
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3112
0
         "%s: unable to create table index value: %" PRIu16 ".",
3113
0
         function,
3114
0
         table_index_value_iterator );
3115
3116
0
        goto on_error;
3117
0
      }
3118
/* TODO add function to set index values ? */
3119
100k
      table_index_value->array_entry = table_array_entry_iterator;
3120
100k
      table_index_value->offset      = table_value_start_offset;
3121
100k
      table_index_value->size        = table_value_end_offset - table_value_start_offset;
3122
3123
100k
      if( libpff_table_block_index_append_value(
3124
100k
           table_block_index,
3125
100k
           &table_block_value_index,
3126
100k
           table_index_value,
3127
100k
           error ) != 1 )
3128
0
      {
3129
0
        libcerror_error_set(
3130
0
         error,
3131
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3132
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3133
0
         "%s: unable to set table block index value: %" PRIu16 ".",
3134
0
         function,
3135
0
         table_index_value_iterator );
3136
3137
0
        goto on_error;
3138
0
      }
3139
100k
      table_index_value = NULL;
3140
3141
100k
      table_value_start_offset = table_value_end_offset;
3142
100k
    }
3143
3.43k
    if( table_value_end_offset > table_index_offset )
3144
62
    {
3145
62
      libcerror_error_set(
3146
62
       error,
3147
62
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3148
62
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3149
62
       "%s: last table index value end offset: %" PRIu16 " exceeds table index offset: %" PRIu16 ".",
3150
62
       function,
3151
62
       table_value_end_offset,
3152
62
       table_index_offset );
3153
3154
62
      goto on_error;
3155
62
    }
3156
3.43k
  }
3157
#if defined( HAVE_DEBUG_OUTPUT )
3158
  if( libcnotify_verbose != 0 )
3159
  {
3160
    if( table_value_end_offset < table_index_offset )
3161
    {
3162
      libcnotify_printf(
3163
       "%s: last table index value end offset: %" PRIu16 " does not match table index offset: %" PRIu16 "\n",
3164
       function,
3165
       table_value_start_offset,
3166
       table_index_offset );
3167
3168
      libcnotify_print_data(
3169
       &( data_block->data[ table_value_end_offset ] ),
3170
       ( table_index_offset - table_value_end_offset ),
3171
       0 );
3172
    }
3173
    if( data_offset < (size_t) data_block->uncompressed_data_size )
3174
    {
3175
      libcnotify_printf(
3176
       "\n" );
3177
      libcnotify_printf(
3178
       "%s: trailing data of size: %" PRIzd "\n",
3179
       function,
3180
       data_block->uncompressed_data_size - data_offset );
3181
      libcnotify_print_data(
3182
       &( data_block->data[ data_offset ] ),
3183
       data_block->uncompressed_data_size - data_offset,
3184
       0 );
3185
    }
3186
  }
3187
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3188
3189
3.43k
  return( 1 );
3190
3191
239
on_error:
3192
239
  if( table_index_value != NULL )
3193
0
  {
3194
0
    libpff_table_index_value_free(
3195
0
     &table_index_value,
3196
0
     NULL );
3197
0
  }
3198
239
  return( -1 );
3199
3.62k
}
3200
3201
/* Reads the table index
3202
 * Returns 1 if successful or -1 on error
3203
 */
3204
int libpff_table_read_index(
3205
     libpff_table_t *table,
3206
     libbfio_handle_t *file_io_handle,
3207
     libcerror_error_t **error )
3208
3.66k
{
3209
3.66k
  libpff_data_block_t *data_block               = NULL;
3210
3.66k
  libpff_table_block_index_t *table_block_index = NULL;
3211
3.66k
  static char *function                         = "libpff_table_read_index";
3212
3.66k
  int number_of_table_array_entries             = 0;
3213
3.66k
  int table_array_entry_iterator                = 0;
3214
3215
#if defined( HAVE_DEBUG_OUTPUT )
3216
  size_t table_data_offset                      = 0;
3217
#endif
3218
3219
3.66k
  if( table == NULL )
3220
0
  {
3221
0
    libcerror_error_set(
3222
0
     error,
3223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3225
0
     "%s: invalid table.",
3226
0
     function );
3227
3228
0
    return( -1 );
3229
0
  }
3230
3.66k
  if( libfdata_list_get_number_of_elements(
3231
3.66k
       table->descriptor_data_list,
3232
3.66k
       &number_of_table_array_entries,
3233
3.66k
       error ) != 1 )
3234
0
  {
3235
0
    libcerror_error_set(
3236
0
     error,
3237
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3238
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3239
0
     "%s: unable to retrieve number of table array entries.",
3240
0
     function );
3241
3242
0
    goto on_error;
3243
0
  }
3244
3.66k
  if( libcdata_array_resize(
3245
3.66k
       table->index_array,
3246
3.66k
       number_of_table_array_entries,
3247
3.66k
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_table_block_index_free,
3248
3.66k
       error ) != 1 )
3249
0
  {
3250
0
    libcerror_error_set(
3251
0
     error,
3252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3253
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
3254
0
     "%s: unable to resize table index array.",
3255
0
     function );
3256
3257
0
    goto on_error;
3258
0
  }
3259
  /* Iterate the table array to fill the table index array
3260
   */
3261
3.66k
  for( table_array_entry_iterator = 0;
3262
7.10k
       table_array_entry_iterator < number_of_table_array_entries;
3263
3.66k
       table_array_entry_iterator++ )
3264
3.67k
  {
3265
3.67k
    if( libfdata_list_get_element_value_by_index(
3266
3.67k
         table->descriptor_data_list,
3267
3.67k
         (intptr_t *) file_io_handle,
3268
3.67k
         (libfdata_cache_t *) table->descriptor_data_cache,
3269
3.67k
         table_array_entry_iterator,
3270
3.67k
         (intptr_t **) &data_block,
3271
3.67k
         0,
3272
3.67k
         error ) != 1 )
3273
0
    {
3274
0
      libcerror_error_set(
3275
0
       error,
3276
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3277
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3278
0
       "%s: unable to retrieve data block: %d.",
3279
0
       function,
3280
0
       table_array_entry_iterator );
3281
3282
0
      goto on_error;
3283
0
    }
3284
3.67k
    if( data_block == NULL )
3285
0
    {
3286
0
      libcerror_error_set(
3287
0
       error,
3288
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3289
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3290
0
       "%s: missing data block: %d.",
3291
0
       function,
3292
0
       table_array_entry_iterator );
3293
3294
0
      goto on_error;
3295
0
    }
3296
#if defined( HAVE_DEBUG_OUTPUT )
3297
    if( libcnotify_verbose != 0 )
3298
    {
3299
      libcnotify_printf(
3300
       "%s: table data offset\t\t\t\t: %" PRIzd "\n",
3301
       function,
3302
       table_data_offset );
3303
3304
      libcnotify_printf(
3305
       "%s: table data size\t\t\t\t: %" PRIzd "\n",
3306
       function,
3307
       data_block->uncompressed_data_size );
3308
    }
3309
#endif
3310
3.67k
    if( libpff_table_block_index_initialize(
3311
3.67k
         &table_block_index,
3312
3.67k
         error ) != 1 )
3313
0
    {
3314
0
      libcerror_error_set(
3315
0
       error,
3316
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3317
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3318
0
       "%s: unable to create table block index.",
3319
0
       function );
3320
3321
0
      goto on_error;
3322
0
    }
3323
3.67k
    if( libpff_table_read_index_entries(
3324
3.67k
         table,
3325
3.67k
         data_block,
3326
3.67k
         table_block_index,
3327
3.67k
         (uint32_t) table_array_entry_iterator,
3328
3.67k
         error ) != 1 )
3329
240
    {
3330
240
      libcerror_error_set(
3331
240
       error,
3332
240
       LIBCERROR_ERROR_DOMAIN_IO,
3333
240
       LIBCERROR_IO_ERROR_READ_FAILED,
3334
240
       "%s: unable to read index entries.",
3335
240
       function );
3336
3337
240
      goto on_error;
3338
240
    }
3339
3.43k
    if( libcdata_array_set_entry_by_index(
3340
3.43k
         table->index_array,
3341
3.43k
         table_array_entry_iterator,
3342
3.43k
         (intptr_t *) table_block_index,
3343
3.43k
         error ) != 1 )
3344
0
    {
3345
0
      libcerror_error_set(
3346
0
       error,
3347
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3348
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3349
0
       "%s: unable to set table index array entry: %d.",
3350
0
       function,
3351
0
       table_array_entry_iterator );
3352
3353
0
      goto on_error;
3354
0
    }
3355
3.43k
    table_block_index = NULL;
3356
3357
#if defined( HAVE_DEBUG_OUTPUT )
3358
    table_data_offset += (size_t) data_block->uncompressed_data_size;
3359
#endif
3360
3.43k
  }
3361
#if defined( HAVE_DEBUG_OUTPUT )
3362
  if( libcnotify_verbose != 0 )
3363
  {
3364
    libcnotify_printf(
3365
     "\n" );
3366
  }
3367
#endif
3368
3.42k
  return( 1 );
3369
3370
240
on_error:
3371
240
  if( table_block_index != NULL )
3372
240
  {
3373
240
    libpff_table_block_index_free(
3374
240
     &table_block_index,
3375
240
     NULL );
3376
240
  }
3377
240
  return( -1 );
3378
3.66k
}
3379
3380
/* Reads the record entries
3381
 * Returns 1 if successful or -1 on error
3382
 */
3383
int libpff_table_read_record_entries(
3384
     libpff_table_t *table,
3385
     libcdata_array_t *record_entries_references_array,
3386
     uint8_t record_entries_level,
3387
     uint8_t record_entry_identifier_size,
3388
     uint32_t record_entries_reference,
3389
     libpff_io_handle_t *io_handle,
3390
     libbfio_handle_t *file_io_handle,
3391
     int recursion_depth,
3392
     libcerror_error_t **error )
3393
54.7k
{
3394
54.7k
  libpff_reference_descriptor_t *reference_descriptor = NULL;
3395
54.7k
  uint8_t *record_entries_data                        = NULL;
3396
54.7k
  uint8_t *record_entry_data                          = NULL;
3397
54.7k
  static char *function                               = "libpff_table_read_record_entries";
3398
54.7k
  size_t number_of_record_entries                     = 0;
3399
54.7k
  size_t record_entries_data_size                     = 0;
3400
54.7k
  size_t record_entry_size                            = 0;
3401
54.7k
  uint32_t sub_record_entries_reference               = 0;
3402
54.7k
  int record_entry_index                              = 0;
3403
3404
#if defined( HAVE_DEBUG_OUTPUT )
3405
  system_character_t guid_string[ 48 ];
3406
3407
  libfguid_identifier_t *guid                         = NULL;
3408
  uint64_t record_entry_identifier                    = 0;
3409
  int result                                          = 0;
3410
#endif
3411
3412
54.7k
  if( table == NULL )
3413
0
  {
3414
0
    libcerror_error_set(
3415
0
     error,
3416
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3417
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3418
0
     "%s: invalid table.",
3419
0
     function );
3420
3421
0
    return( -1 );
3422
0
  }
3423
54.7k
  if( ( record_entry_identifier_size != 2 )
3424
54.7k
   && ( record_entry_identifier_size != 4 )
3425
54.7k
   && ( record_entry_identifier_size != 8 )
3426
54.7k
   && ( record_entry_identifier_size != 16 ) )
3427
0
  {
3428
0
    libcerror_error_set(
3429
0
     error,
3430
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3431
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3432
0
     "%s: unsupported record entry identifier size: %" PRIu8 ".",
3433
0
     function,
3434
0
     record_entry_identifier_size );
3435
3436
0
    return( -1 );
3437
0
  }
3438
54.7k
  if( ( recursion_depth < 0 )
3439
54.7k
   || ( recursion_depth > LIBPFF_MAXIMUM_TABLE_RECORD_ENTRIES_RECURSION_DEPTH ) )
3440
0
  {
3441
0
    libcerror_error_set(
3442
0
     error,
3443
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3444
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3445
0
     "%s: invalid recursion depth value out of bounds.",
3446
0
     function );
3447
3448
0
    return( -1 );
3449
0
  }
3450
#if defined( HAVE_DEBUG_OUTPUT )
3451
  if( libcnotify_verbose != 0 )
3452
  {
3453
    libcnotify_printf(
3454
     "%s: reading record entries at level: %" PRIu8 " with reference: 0x%08" PRIx32 " (%s)\n",
3455
     function,
3456
     record_entries_level,
3457
     record_entries_reference,
3458
     libpff_debug_get_node_identifier_type(
3459
      (uint8_t) ( record_entries_reference & 0x0000001fUL ) ) );
3460
3461
    libcnotify_printf(
3462
     "\n" );
3463
  }
3464
#endif
3465
54.7k
  if( record_entries_reference == 0 )
3466
36.6k
  {
3467
#if defined( HAVE_DEBUG_OUTPUT )
3468
    if( libcnotify_verbose != 0 )
3469
    {
3470
      libcnotify_printf(
3471
       "%s: table contains no record entries.\n",
3472
       function );
3473
    }
3474
#endif
3475
36.6k
    return( 1 );
3476
36.6k
  }
3477
18.0k
  if( ( record_entries_reference & 0x0000001fUL ) != 0 )
3478
177
  {
3479
177
    libcerror_error_set(
3480
177
     error,
3481
177
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3482
177
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3483
177
     "%s: unsupported record entries reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3484
177
     function,
3485
177
     record_entries_reference & 0x0000001fUL,
3486
177
     record_entries_reference );
3487
3488
177
    goto on_error;
3489
177
  }
3490
17.8k
  if( record_entries_level == 0 )
3491
4.20k
  {
3492
4.20k
    if( libpff_reference_descriptor_initialize(
3493
4.20k
         &reference_descriptor,
3494
4.20k
         record_entries_reference,
3495
4.20k
         error ) != 1 )
3496
0
    {
3497
0
      libcerror_error_set(
3498
0
       error,
3499
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3500
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3501
0
       "%s: unable to create reference descriptor.",
3502
0
       function );
3503
3504
0
      goto on_error;
3505
0
    }
3506
4.20k
    if( libcdata_array_append_entry(
3507
4.20k
         record_entries_references_array,
3508
4.20k
         &record_entry_index,
3509
4.20k
         (intptr_t *) reference_descriptor,
3510
4.20k
         error ) != 1 )
3511
0
    {
3512
0
      libcerror_error_set(
3513
0
       error,
3514
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3515
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3516
0
       "%s: unable to append reference descriptor to array.",
3517
0
       function );
3518
3519
0
      goto on_error;
3520
0
    }
3521
4.20k
    reference_descriptor = NULL;
3522
4.20k
  }
3523
13.6k
  else
3524
13.6k
  {
3525
13.6k
    if( libpff_table_clone_value_data_by_reference(
3526
13.6k
         table,
3527
13.6k
         record_entries_reference,
3528
13.6k
         io_handle,
3529
13.6k
         file_io_handle,
3530
13.6k
         &record_entries_data,
3531
13.6k
         &record_entries_data_size,
3532
13.6k
         error ) != 1 )
3533
70
    {
3534
70
      libcerror_error_set(
3535
70
       error,
3536
70
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3537
70
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3538
70
       "%s: unable to retrieve value data by reference.",
3539
70
       function );
3540
3541
70
      goto on_error;
3542
70
    }
3543
13.5k
    if( ( record_entries_data == NULL )
3544
13.5k
     || ( record_entries_data_size == 0 ) )
3545
0
    {
3546
0
      libcerror_error_set(
3547
0
       error,
3548
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3549
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3550
0
       "%s: missing table value data.",
3551
0
       function );
3552
3553
0
      goto on_error;
3554
0
    }
3555
13.5k
    record_entry_data = record_entries_data;
3556
13.5k
    record_entry_size = record_entry_identifier_size + 4;
3557
3558
13.5k
    if( ( record_entries_data_size % record_entry_size ) != 0 )
3559
18
    {
3560
18
      libcerror_error_set(
3561
18
       error,
3562
18
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3563
18
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3564
18
       "%s: unsupported record entries size.",
3565
18
       function );
3566
3567
18
      goto on_error;
3568
18
    }
3569
13.5k
    number_of_record_entries = record_entries_data_size / record_entry_size;
3570
3571
13.5k
    for( record_entry_index = 0;
3572
56.1k
         (size_t) record_entry_index < number_of_record_entries;
3573
42.6k
         record_entry_index++ )
3574
51.7k
    {
3575
#if defined( HAVE_DEBUG_OUTPUT )
3576
      if( libcnotify_verbose != 0 )
3577
      {
3578
        if( ( record_entry_identifier_size == 2 )
3579
         || ( record_entry_identifier_size == 4 )
3580
         || ( record_entry_identifier_size == 8 ) )
3581
        {
3582
          if( record_entry_identifier_size == 2 )
3583
          {
3584
            byte_stream_copy_to_uint16_little_endian(
3585
             record_entry_data,
3586
             record_entry_identifier );
3587
          }
3588
          else if( record_entry_identifier_size == 4 )
3589
          {
3590
            byte_stream_copy_to_uint32_little_endian(
3591
             record_entry_data,
3592
             record_entry_identifier );
3593
          }
3594
          else if( record_entry_identifier_size == 8 )
3595
          {
3596
            byte_stream_copy_to_uint64_little_endian(
3597
             record_entry_data,
3598
             record_entry_identifier );
3599
          }
3600
          libcnotify_printf(
3601
           "%s: record entry: %03d at level: %" PRIu8 " identifier\t\t\t: 0x%08" PRIx64 "\n",
3602
           function,
3603
           record_entry_index,
3604
           record_entries_level,
3605
           record_entry_identifier );
3606
        }
3607
        else if( record_entry_identifier_size == 16 )
3608
        {
3609
          if( libfguid_identifier_initialize(
3610
               &guid,
3611
               error ) != 1 )
3612
          {
3613
            libcerror_error_set(
3614
             error,
3615
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3616
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3617
             "%s: unable to create GUID.",
3618
             function );
3619
3620
            goto on_error;
3621
          }
3622
          if( libfguid_identifier_copy_from_byte_stream(
3623
               guid,
3624
               record_entry_data,
3625
               16,
3626
               LIBFGUID_ENDIAN_LITTLE,
3627
               error ) != 1 )
3628
          {
3629
            libcerror_error_set(
3630
             error,
3631
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3632
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3633
             "%s: unable to copy byte stream to GUID.",
3634
             function );
3635
3636
            goto on_error;
3637
          }
3638
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
3639
          result = libfguid_identifier_copy_to_utf16_string(
3640
              guid,
3641
              (uint16_t *) guid_string,
3642
              48,
3643
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
3644
              error );
3645
#else
3646
          result = libfguid_identifier_copy_to_utf8_string(
3647
              guid,
3648
              (uint8_t *) guid_string,
3649
              48,
3650
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
3651
              error );
3652
#endif
3653
          if( result != 1 )
3654
          {
3655
            libcerror_error_set(
3656
             error,
3657
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3658
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3659
             "%s: unable to copy GUID to string.",
3660
             function );
3661
3662
            goto on_error;
3663
          }
3664
          if( libfguid_identifier_free(
3665
               &guid,
3666
               error ) != 1 )
3667
          {
3668
            libcerror_error_set(
3669
             error,
3670
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3671
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3672
             "%s: unable to free GUID.",
3673
             function );
3674
3675
            goto on_error;
3676
          }
3677
          libcnotify_printf(
3678
           "%s: record entry: %03d at level: %" PRIu8 " identifier\t\t\t: %" PRIs_SYSTEM "s\n",
3679
           function,
3680
           record_entry_index,
3681
           record_entries_level,
3682
           guid_string );
3683
        }
3684
      }
3685
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3686
3687
/* TODO use the record entry identifier to validate sub level record entries */
3688
51.7k
      record_entry_data += record_entry_identifier_size;
3689
3690
51.7k
      byte_stream_copy_to_uint32_little_endian(
3691
51.7k
       record_entry_data,
3692
51.7k
       sub_record_entries_reference );
3693
3694
51.7k
      record_entry_data += 4;
3695
3696
#if defined( HAVE_DEBUG_OUTPUT )
3697
      if( libcnotify_verbose != 0 )
3698
      {
3699
        libcnotify_printf(
3700
         "%s: record entry: %03d at level: %" PRIu8 " reference\t\t\t: 0x%08" PRIx32 " (%s)\n",
3701
         function,
3702
         record_entry_index,
3703
         record_entries_level,
3704
         sub_record_entries_reference,
3705
         libpff_debug_get_node_identifier_type(
3706
          (uint8_t) ( sub_record_entries_reference & 0x0000001fUL ) ) );
3707
3708
        libcnotify_printf(
3709
         "\n" );
3710
      }
3711
#endif
3712
51.7k
      if( sub_record_entries_reference == record_entries_reference )
3713
4
      {
3714
4
        libcerror_error_set(
3715
4
         error,
3716
4
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3717
4
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3718
4
         "%s: invalid sub record entries reference same as parent.",
3719
4
         function );
3720
3721
4
        goto on_error;
3722
4
      }
3723
51.7k
      if( libpff_table_read_record_entries(
3724
51.7k
           table,
3725
51.7k
           record_entries_references_array,
3726
51.7k
           record_entries_level - 1,
3727
51.7k
           record_entry_identifier_size,
3728
51.7k
           sub_record_entries_reference,
3729
51.7k
           io_handle,
3730
51.7k
           file_io_handle,
3731
51.7k
           recursion_depth + 1,
3732
51.7k
           error ) != 1 )
3733
9.15k
      {
3734
9.15k
        libcerror_error_set(
3735
9.15k
         error,
3736
9.15k
         LIBCERROR_ERROR_DOMAIN_IO,
3737
9.15k
         LIBCERROR_IO_ERROR_READ_FAILED,
3738
9.15k
         "%s: unable to read record entries.",
3739
9.15k
         function );
3740
3741
9.15k
        goto on_error;
3742
9.15k
      }
3743
51.7k
    }
3744
#if defined( HAVE_DEBUG_OUTPUT )
3745
    if( libcnotify_verbose != 0 )
3746
    {
3747
      libcnotify_printf(
3748
       "\n" );
3749
    }
3750
#endif
3751
4.41k
    memory_free(
3752
4.41k
     record_entries_data );
3753
4.41k
  }
3754
8.62k
  return( 1 );
3755
3756
9.42k
on_error:
3757
#if defined( HAVE_DEBUG_OUTPUT )
3758
  if( guid != NULL )
3759
  {
3760
    libfguid_identifier_free(
3761
     &guid,
3762
     NULL );
3763
  }
3764
#endif
3765
9.42k
  if( record_entries_data != NULL )
3766
9.17k
  {
3767
9.17k
    memory_free(
3768
9.17k
     record_entries_data );
3769
9.17k
  }
3770
9.42k
  if( reference_descriptor != NULL )
3771
0
  {
3772
0
    libpff_reference_descriptor_free(
3773
0
     &reference_descriptor,
3774
0
     NULL );
3775
0
  }
3776
9.42k
  if( record_entries_references_array != NULL )
3777
9.42k
  {
3778
9.42k
    libcdata_array_empty(
3779
9.42k
     record_entries_references_array,
3780
9.42k
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
3781
9.42k
     NULL );
3782
9.42k
  }
3783
9.42k
  return( -1 );
3784
17.8k
}
3785
3786
/* Reads the table values
3787
 * Returns 1 if successful or -1 on error
3788
 */
3789
int libpff_table_read_values(
3790
     libpff_table_t *table,
3791
     libpff_io_handle_t *io_handle,
3792
     libbfio_handle_t *file_io_handle,
3793
     libpff_offsets_index_t *offsets_index,
3794
     libcdata_list_t *name_to_id_map_list,
3795
     int debug_item_type,
3796
     libcerror_error_t **error )
3797
3.42k
{
3798
3.42k
  uint8_t *table_header_data         = NULL;
3799
3.42k
  static char *function              = "libpff_table_read_values";
3800
3.42k
  size_t table_header_data_size      = 0;
3801
3.42k
  uint32_t b5_table_header_reference = 0;
3802
3.42k
  int result                         = 0;
3803
3804
3.42k
  if( table == NULL )
3805
0
  {
3806
0
    libcerror_error_set(
3807
0
     error,
3808
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3809
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3810
0
     "%s: invalid table.",
3811
0
     function );
3812
3813
0
    return( -1 );
3814
0
  }
3815
3.42k
  if( table->header == NULL )
3816
0
  {
3817
0
    libcerror_error_set(
3818
0
     error,
3819
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3820
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3821
0
     "%s: invalid table - missing header.",
3822
0
     function );
3823
3824
0
    return( -1 );
3825
0
  }
3826
  /* Read type specific table header
3827
   */
3828
3.42k
  if( ( table->header->type == 0x8c )
3829
3.42k
   || ( table->header->type == 0xa5 )
3830
3.42k
   || ( table->header->type == 0xbc ) )
3831
1.39k
  {
3832
1.39k
    b5_table_header_reference = table->header->table_value_reference;
3833
1.39k
  }
3834
2.02k
  else
3835
2.02k
  {
3836
2.02k
    if( ( table->header->table_value_reference & 0x0000001fUL ) != 0 )
3837
12
    {
3838
12
      libcerror_error_set(
3839
12
       error,
3840
12
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3841
12
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3842
12
       "%s: unsupported table header reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3843
12
       function,
3844
12
       table->header->table_value_reference & 0x0000001fUL,
3845
12
       table->header->table_value_reference );
3846
3847
12
      return( -1 );
3848
12
    }
3849
2.01k
    if( libpff_table_get_value_data_by_reference(
3850
2.01k
         table,
3851
2.01k
         io_handle,
3852
2.01k
         file_io_handle,
3853
2.01k
         table->header->table_value_reference,
3854
2.01k
         &table_header_data,
3855
2.01k
         &table_header_data_size,
3856
2.01k
         error ) != 1 )
3857
15
    {
3858
15
      libcerror_error_set(
3859
15
       error,
3860
15
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3861
15
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3862
15
       "%s: unable to retrieve table header data.",
3863
15
       function );
3864
3865
15
      return( -1 );
3866
15
    }
3867
2.00k
    switch( table->header->type )
3868
2.00k
    {
3869
13
      case 0x6c:
3870
13
        result = libpff_table_header_read_6c_data(
3871
13
            table->header,
3872
13
            table_header_data,
3873
13
            table_header_data_size,
3874
13
            error );
3875
13
        break;
3876
3877
1.92k
      case 0x7c:
3878
1.92k
        result = libpff_table_header_read_7c_data(
3879
1.92k
            table->header,
3880
1.92k
            table_header_data,
3881
1.92k
            table_header_data_size,
3882
1.92k
            error );
3883
1.92k
        break;
3884
3885
18
      case 0x9c:
3886
18
        result = libpff_table_header_read_9c_data(
3887
18
            table->header,
3888
18
            table_header_data,
3889
18
            table_header_data_size,
3890
18
            error );
3891
18
        break;
3892
3893
45
      case 0xac:
3894
45
        result = libpff_table_header_read_ac_data(
3895
45
            table->header,
3896
45
            table_header_data,
3897
45
            table_header_data_size,
3898
45
            error );
3899
45
        break;
3900
2.00k
    }
3901
2.00k
    if( result != 1 )
3902
134
    {
3903
134
      libcerror_error_set(
3904
134
       error,
3905
134
       LIBCERROR_ERROR_DOMAIN_IO,
3906
134
       LIBCERROR_IO_ERROR_READ_FAILED,
3907
134
       "%s: unable to read %02" PRIx8 " table header.",
3908
134
       function,
3909
134
       table->header->type );
3910
3911
134
      return( -1 );
3912
134
    }
3913
1.86k
    b5_table_header_reference = table->header->b5_table_header_reference;
3914
1.86k
  }
3915
  /* Read b5 table header
3916
   */
3917
3.26k
  if( table->header->type == 0xa5 )
3918
119
  {
3919
    /* The a5 table contains no b5 table header
3920
     */
3921
119
    if( b5_table_header_reference != 0 )
3922
82
    {
3923
82
      libcerror_error_set(
3924
82
       error,
3925
82
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3926
82
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3927
82
       "%s: unsupported table header reference: 0x%08" PRIx32 ".",
3928
82
       function,
3929
82
       b5_table_header_reference );
3930
3931
82
      return( -1 );
3932
82
    }
3933
119
  }
3934
3.14k
  else
3935
3.14k
  {
3936
3.14k
    if( ( b5_table_header_reference & 0x0000001fUL ) != 0 )
3937
14
    {
3938
14
      libcerror_error_set(
3939
14
       error,
3940
14
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3941
14
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3942
14
       "%s: unsupported b5 table header reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3943
14
       function,
3944
14
       b5_table_header_reference & 0x0000001fUL,
3945
14
       b5_table_header_reference );
3946
3947
14
      return( -1 );
3948
14
    }
3949
3.13k
    if( libpff_table_get_value_data_by_reference(
3950
3.13k
         table,
3951
3.13k
         io_handle,
3952
3.13k
         file_io_handle,
3953
3.13k
         b5_table_header_reference,
3954
3.13k
         &table_header_data,
3955
3.13k
         &table_header_data_size,
3956
3.13k
         error ) != 1 )
3957
11
    {
3958
11
      libcerror_error_set(
3959
11
       error,
3960
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3961
11
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3962
11
       "%s: unable to retrieve b5 table header data.",
3963
11
       function );
3964
3965
11
      return( -1 );
3966
11
    }
3967
3.12k
    if( ( table_header_data == NULL )
3968
3.12k
     || ( table_header_data_size == 0 ) )
3969
4
    {
3970
4
      libcerror_error_set(
3971
4
       error,
3972
4
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3973
4
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3974
4
       "%s: missing b5 table header data.",
3975
4
       function );
3976
3977
4
      return( -1 );
3978
4
    }
3979
3.11k
    if( libpff_table_header_read_b5_data(
3980
3.11k
         table->header,
3981
3.11k
         table_header_data,
3982
3.11k
         table_header_data_size,
3983
3.11k
         error ) != 1 )
3984
70
    {
3985
70
      libcerror_error_set(
3986
70
       error,
3987
70
       LIBCERROR_ERROR_DOMAIN_IO,
3988
70
       LIBCERROR_IO_ERROR_READ_FAILED,
3989
70
       "%s: unable to read b5 table header.",
3990
70
       function );
3991
3992
70
      return( -1 );
3993
70
    }
3994
3.11k
  }
3995
  /* Read table values
3996
   */
3997
3.08k
  switch( table->header->type )
3998
3.08k
  {
3999
0
    case 0x6c:
4000
0
      result = libpff_table_read_6c_values(
4001
0
          table,
4002
0
          io_handle,
4003
0
          file_io_handle,
4004
0
          error );
4005
0
      break;
4006
4007
1.83k
    case 0x7c:
4008
1.83k
      result = libpff_table_read_7c_values(
4009
1.83k
          table,
4010
1.83k
          io_handle,
4011
1.83k
          file_io_handle,
4012
1.83k
          offsets_index,
4013
1.83k
          name_to_id_map_list,
4014
1.83k
          error );
4015
1.83k
      break;
4016
4017
12
    case 0x8c:
4018
12
      result = libpff_table_read_8c_values(
4019
12
          table,
4020
12
          io_handle,
4021
12
          file_io_handle,
4022
12
          error );
4023
12
      break;
4024
4025
0
    case 0x9c:
4026
0
      result = libpff_table_read_9c_values(
4027
0
          table,
4028
0
          io_handle,
4029
0
          file_io_handle,
4030
0
          error );
4031
0
      break;
4032
4033
37
    case 0xa5:
4034
37
      result = libpff_table_read_a5_values(
4035
37
          table,
4036
37
          io_handle,
4037
37
          file_io_handle,
4038
37
          error );
4039
37
      break;
4040
4041
0
    case 0xac:
4042
0
      result = libpff_table_read_ac_values(
4043
0
          table,
4044
0
          io_handle,
4045
0
          file_io_handle,
4046
0
          offsets_index,
4047
0
          name_to_id_map_list,
4048
0
          error );
4049
0
      break;
4050
4051
1.19k
    case 0xbc:
4052
1.19k
      result = libpff_table_read_bc_values(
4053
1.19k
          table,
4054
1.19k
          io_handle,
4055
1.19k
          file_io_handle,
4056
1.19k
          offsets_index,
4057
1.19k
          name_to_id_map_list,
4058
1.19k
          debug_item_type,
4059
1.19k
          error );
4060
1.19k
      break;
4061
3.08k
  }
4062
3.08k
  if( result != 1 )
4063
2.34k
  {
4064
2.34k
    libcerror_error_set(
4065
2.34k
     error,
4066
2.34k
     LIBCERROR_ERROR_DOMAIN_IO,
4067
2.34k
     LIBCERROR_IO_ERROR_READ_FAILED,
4068
2.34k
     "%s: unable to read %02" PRIx8 " table values.",
4069
2.34k
     function,
4070
2.34k
     table->header->type );
4071
4072
2.34k
    return( -1 );
4073
2.34k
  }
4074
740
  return( 1 );
4075
3.08k
}
4076
4077
/* Reads the 6c table values
4078
 * Returns 1 if successful or -1 on error
4079
 */
4080
int libpff_table_read_6c_values(
4081
     libpff_table_t *table,
4082
     libpff_io_handle_t *io_handle,
4083
     libbfio_handle_t *file_io_handle,
4084
     libcerror_error_t **error )
4085
0
{
4086
0
  libcdata_array_t *record_entries_references_array = NULL;
4087
0
  static char *function                             = "libpff_table_read_6c_values";
4088
4089
0
  if( table == NULL )
4090
0
  {
4091
0
    libcerror_error_set(
4092
0
     error,
4093
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4094
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4095
0
     "%s: invalid table.",
4096
0
     function );
4097
4098
0
    return( -1 );
4099
0
  }
4100
0
  if( table->header == NULL )
4101
0
  {
4102
0
    libcerror_error_set(
4103
0
     error,
4104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4105
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4106
0
     "%s: invalid table - missing header.",
4107
0
     function );
4108
4109
0
    return( -1 );
4110
0
  }
4111
0
  if( ( table->header->record_entry_identifier_size != 16 )
4112
0
   || ( table->header->record_entry_value_size != 2 ) )
4113
0
  {
4114
0
    libcerror_error_set(
4115
0
     error,
4116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4117
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4118
0
     "%s: unsupported record entry identifier size: %" PRIu8 " and record entry value size: %" PRIu8 ".",
4119
0
     function,
4120
0
     table->header->record_entry_identifier_size,
4121
0
     table->header->record_entry_value_size );
4122
4123
0
    goto on_error;
4124
0
  }
4125
  /* Check if the table contains any entries
4126
   */
4127
0
  if( ( table->header->record_entries_reference == 0 )
4128
0
   && ( table->header->values_array_reference == 0 ) )
4129
0
  {
4130
#if defined( HAVE_DEBUG_OUTPUT )
4131
    if( libcnotify_verbose != 0 )
4132
    {
4133
      libcnotify_printf(
4134
       "%s: table contains no entries.\n",
4135
       function );
4136
    }
4137
#endif
4138
0
    goto on_error;
4139
0
  }
4140
0
  if( table->header->record_entries_reference == 0 )
4141
0
  {
4142
0
    libcerror_error_set(
4143
0
     error,
4144
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4145
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4146
0
     "%s: table contains value array but no record entries.",
4147
0
     function );
4148
4149
0
    goto on_error;
4150
0
  }
4151
0
  if( table->header->values_array_reference == 0 )
4152
0
  {
4153
0
    libcerror_error_set(
4154
0
     error,
4155
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4156
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4157
0
     "%s: table contains record entries but no value array.",
4158
0
     function );
4159
4160
0
    goto on_error;
4161
0
  }
4162
0
  if( libcdata_array_initialize(
4163
0
       &record_entries_references_array,
4164
0
       0,
4165
0
       error ) != 1 )
4166
0
  {
4167
0
    libcerror_error_set(
4168
0
     error,
4169
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4170
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4171
0
     "%s: unable to create record entries references array.",
4172
0
     function );
4173
4174
0
    goto on_error;
4175
0
  }
4176
0
  if( libpff_table_read_record_entries(
4177
0
       table,
4178
0
       record_entries_references_array,
4179
0
       table->header->record_entries_level,
4180
0
       table->header->record_entry_identifier_size,
4181
0
       table->header->record_entries_reference,
4182
0
       io_handle,
4183
0
       file_io_handle,
4184
0
       0,
4185
0
       error ) != 1 )
4186
0
  {
4187
0
    libcerror_error_set(
4188
0
     error,
4189
0
     LIBCERROR_ERROR_DOMAIN_IO,
4190
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4191
0
     "%s: unable to read record entries.",
4192
0
     function );
4193
4194
0
    goto on_error;
4195
0
  }
4196
0
  if( libpff_table_read_6c_record_entries(
4197
0
       table,
4198
0
       record_entries_references_array,
4199
0
       table->header->values_array_reference,
4200
0
       io_handle,
4201
0
       file_io_handle,
4202
0
       error ) != 1 )
4203
0
  {
4204
0
    libcerror_error_set(
4205
0
     error,
4206
0
     LIBCERROR_ERROR_DOMAIN_IO,
4207
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4208
0
     "%s: unable to read 6c table record entries.",
4209
0
     function );
4210
4211
0
    goto on_error;
4212
0
  }
4213
0
  if( libcdata_array_free(
4214
0
       &record_entries_references_array,
4215
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4216
0
       error ) != 1 )
4217
0
  {
4218
0
    libcerror_error_set(
4219
0
     error,
4220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4221
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4222
0
     "%s: unable to free record entries references array.",
4223
0
     function );
4224
4225
0
    goto on_error;
4226
0
  }
4227
0
  return( 1 );
4228
4229
0
on_error:
4230
0
  if( record_entries_references_array != NULL )
4231
0
  {
4232
0
    libcdata_array_free(
4233
0
     &record_entries_references_array,
4234
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4235
0
     NULL );
4236
0
  }
4237
0
  return( -1 );
4238
0
}
4239
4240
/* Reads the 7c table values
4241
 * Returns 1 if successful or -1 on error
4242
 */
4243
int libpff_table_read_7c_values(
4244
     libpff_table_t *table,
4245
     libpff_io_handle_t *io_handle,
4246
     libbfio_handle_t *file_io_handle,
4247
     libpff_offsets_index_t *offsets_index,
4248
     libcdata_list_t *name_to_id_map_list,
4249
     libcerror_error_t **error )
4250
1.83k
{
4251
1.83k
  libcdata_array_t *column_definitions_array        = NULL;
4252
1.83k
  libcdata_array_t *record_entries_references_array = NULL;
4253
1.83k
  static char *function                             = "libpff_table_read_7c_values";
4254
4255
1.83k
  if( table == NULL )
4256
0
  {
4257
0
    libcerror_error_set(
4258
0
     error,
4259
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4260
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4261
0
     "%s: invalid table.",
4262
0
     function );
4263
4264
0
    return( -1 );
4265
0
  }
4266
1.83k
  if( table->header == NULL )
4267
0
  {
4268
0
    libcerror_error_set(
4269
0
     error,
4270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4271
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4272
0
     "%s: invalid table - missing header.",
4273
0
     function );
4274
4275
0
    return( -1 );
4276
0
  }
4277
1.83k
  if( ( table->header->record_entry_identifier_size != 4 )
4278
1.83k
   || ( ( table->header->record_entry_value_size != 2 )
4279
1.83k
    &&  ( table->header->record_entry_value_size != 4 ) ) )
4280
12
  {
4281
12
    libcerror_error_set(
4282
12
     error,
4283
12
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4284
12
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4285
12
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4286
12
     function,
4287
12
     table->header->record_entry_identifier_size,
4288
12
     table->header->record_entry_value_size );
4289
4290
12
    goto on_error;
4291
12
  }
4292
  /* Create the column definitions array
4293
   */
4294
1.82k
  if( libcdata_array_initialize(
4295
1.82k
       &column_definitions_array,
4296
1.82k
       0,
4297
1.82k
       error ) != 1 )
4298
0
  {
4299
0
    libcerror_error_set(
4300
0
     error,
4301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4302
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4303
0
     "%s: unable to create column definitions array.",
4304
0
     function );
4305
4306
0
    goto on_error;
4307
0
  }
4308
1.82k
  if( libpff_table_read_7c_column_definitions(
4309
1.82k
       table,
4310
1.82k
       column_definitions_array,
4311
1.82k
       table->header->column_definitions_data,
4312
1.82k
       table->header->column_definitions_data_size,
4313
1.82k
       table->header->number_of_column_definitions,
4314
1.82k
       file_io_handle,
4315
1.82k
       name_to_id_map_list,
4316
1.82k
       error ) != 1 )
4317
32
  {
4318
32
    libcerror_error_set(
4319
32
     error,
4320
32
     LIBCERROR_ERROR_DOMAIN_IO,
4321
32
     LIBCERROR_IO_ERROR_READ_FAILED,
4322
32
     "%s: unable to read 7c table column definitions.",
4323
32
     function );
4324
4325
32
    goto on_error;
4326
32
  }
4327
1.79k
  if( libcdata_array_initialize(
4328
1.79k
       &record_entries_references_array,
4329
1.79k
       0,
4330
1.79k
       error ) != 1 )
4331
0
  {
4332
0
    libcerror_error_set(
4333
0
     error,
4334
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4335
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4336
0
     "%s: unable to create record entries references array.",
4337
0
     function );
4338
4339
0
    goto on_error;
4340
0
  }
4341
1.79k
  if( libpff_table_read_record_entries(
4342
1.79k
       table,
4343
1.79k
       record_entries_references_array,
4344
1.79k
       table->header->record_entries_level,
4345
1.79k
       table->header->record_entry_identifier_size,
4346
1.79k
       table->header->record_entries_reference,
4347
1.79k
       io_handle,
4348
1.79k
       file_io_handle,
4349
1.79k
       0,
4350
1.79k
       error ) != 1 )
4351
119
  {
4352
119
    libcerror_error_set(
4353
119
     error,
4354
119
     LIBCERROR_ERROR_DOMAIN_IO,
4355
119
     LIBCERROR_IO_ERROR_READ_FAILED,
4356
119
     "%s: unable to read record entries.",
4357
119
     function );
4358
4359
119
    goto on_error;
4360
119
  }
4361
1.67k
  if( table->header->number_of_column_definitions > 0 )
4362
1.67k
  {
4363
1.67k
    if( libpff_table_read_values_array(
4364
1.67k
         table,
4365
1.67k
         record_entries_references_array,
4366
1.67k
         table->header->values_array_reference,
4367
1.67k
         table->header->record_entry_identifier_size,
4368
1.67k
         table->header->record_entry_value_size,
4369
1.67k
         table->header->values_array_entry_size,
4370
1.67k
         column_definitions_array,
4371
1.67k
         io_handle,
4372
1.67k
         file_io_handle,
4373
1.67k
         offsets_index,
4374
1.67k
         error ) != 1 )
4375
1.41k
    {
4376
1.41k
      libcerror_error_set(
4377
1.41k
       error,
4378
1.41k
       LIBCERROR_ERROR_DOMAIN_IO,
4379
1.41k
       LIBCERROR_IO_ERROR_READ_FAILED,
4380
1.41k
       "%s: unable to read values array.",
4381
1.41k
       function );
4382
4383
1.41k
      goto on_error;
4384
1.41k
    }
4385
1.67k
  }
4386
263
  if( libcdata_array_free(
4387
263
       &record_entries_references_array,
4388
263
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4389
263
       error ) != 1 )
4390
0
  {
4391
0
    libcerror_error_set(
4392
0
     error,
4393
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4394
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4395
0
     "%s: unable to free record entries references array.",
4396
0
     function );
4397
4398
0
    goto on_error;
4399
0
  }
4400
263
  if( libcdata_array_free(
4401
263
       &column_definitions_array,
4402
263
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4403
263
       error ) != 1 )
4404
0
  {
4405
0
    libcerror_error_set(
4406
0
     error,
4407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4408
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4409
0
     "%s: unable to free the column definitions array.",
4410
0
     function );
4411
4412
0
    goto on_error;
4413
0
  }
4414
263
  return( 1 );
4415
4416
1.57k
on_error:
4417
1.57k
  if( record_entries_references_array != NULL )
4418
1.53k
  {
4419
1.53k
    libcdata_array_free(
4420
1.53k
     &record_entries_references_array,
4421
1.53k
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4422
1.53k
     NULL );
4423
1.53k
  }
4424
1.57k
  if( column_definitions_array != NULL )
4425
1.56k
  {
4426
1.56k
    libcdata_array_free(
4427
1.56k
     &column_definitions_array,
4428
1.56k
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4429
1.56k
     NULL );
4430
1.56k
  }
4431
1.57k
  return( -1 );
4432
263
}
4433
4434
/* Reads the 8c table values
4435
 * Returns 1 if successful or -1 on error
4436
 */
4437
int libpff_table_read_8c_values(
4438
     libpff_table_t *table,
4439
     libpff_io_handle_t *io_handle,
4440
     libbfio_handle_t *file_io_handle,
4441
     libcerror_error_t **error )
4442
12
{
4443
12
  libcdata_array_t *record_entries_references_array = NULL;
4444
12
  static char *function                             = "libpff_table_read_8c_values";
4445
4446
12
  if( table == NULL )
4447
0
  {
4448
0
    libcerror_error_set(
4449
0
     error,
4450
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4451
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4452
0
     "%s: invalid table.",
4453
0
     function );
4454
4455
0
    return( -1 );
4456
0
  }
4457
12
  if( table->header == NULL )
4458
0
  {
4459
0
    libcerror_error_set(
4460
0
     error,
4461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4462
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4463
0
     "%s: invalid table - missing header.",
4464
0
     function );
4465
4466
0
    return( -1 );
4467
0
  }
4468
12
  if( ( table->header->record_entry_identifier_size != 8 )
4469
12
   || ( table->header->record_entry_value_size != 4 ) )
4470
12
  {
4471
12
    libcerror_error_set(
4472
12
     error,
4473
12
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4474
12
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4475
12
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4476
12
     function,
4477
12
     table->header->record_entry_identifier_size,
4478
12
     table->header->record_entry_value_size );
4479
4480
12
    goto on_error;
4481
12
  }
4482
0
  if( libcdata_array_initialize(
4483
0
       &record_entries_references_array,
4484
0
       0,
4485
0
       error ) != 1 )
4486
0
  {
4487
0
    libcerror_error_set(
4488
0
     error,
4489
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4490
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4491
0
     "%s: unable to create record entries references array.",
4492
0
     function );
4493
4494
0
    goto on_error;
4495
0
  }
4496
0
  if( libpff_table_read_record_entries(
4497
0
       table,
4498
0
       record_entries_references_array,
4499
0
       table->header->record_entries_level,
4500
0
       table->header->record_entry_identifier_size,
4501
0
       table->header->record_entries_reference,
4502
0
       io_handle,
4503
0
       file_io_handle,
4504
0
       0,
4505
0
       error ) != 1 )
4506
0
  {
4507
0
    libcerror_error_set(
4508
0
     error,
4509
0
     LIBCERROR_ERROR_DOMAIN_IO,
4510
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4511
0
     "%s: unable to read record entries.",
4512
0
     function );
4513
4514
0
    goto on_error;
4515
0
  }
4516
0
  if( libpff_table_read_8c_record_entries(
4517
0
       table,
4518
0
       record_entries_references_array,
4519
0
       io_handle,
4520
0
       file_io_handle,
4521
0
       error ) != 1 )
4522
0
  {
4523
0
    libcerror_error_set(
4524
0
     error,
4525
0
     LIBCERROR_ERROR_DOMAIN_IO,
4526
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4527
0
     "%s: unable to read table record entries.",
4528
0
     function );
4529
4530
0
    goto on_error;
4531
0
  }
4532
0
  if( libcdata_array_free(
4533
0
       &record_entries_references_array,
4534
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4535
0
       error ) != 1 )
4536
0
  {
4537
0
    libcerror_error_set(
4538
0
     error,
4539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4540
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4541
0
     "%s: unable to free record entries references array.",
4542
0
     function );
4543
4544
0
    goto on_error;
4545
0
  }
4546
0
  return( 1 );
4547
4548
12
on_error:
4549
12
  if( record_entries_references_array != NULL )
4550
0
  {
4551
0
    libcdata_array_free(
4552
0
     &record_entries_references_array,
4553
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4554
0
     NULL );
4555
0
  }
4556
12
  return( -1 );
4557
0
}
4558
4559
/* Reads the 9c table values
4560
 * Returns 1 if successful or -1 on error
4561
 */
4562
int libpff_table_read_9c_values(
4563
     libpff_table_t *table,
4564
     libpff_io_handle_t *io_handle,
4565
     libbfio_handle_t *file_io_handle,
4566
     libcerror_error_t **error )
4567
0
{
4568
0
  libcdata_array_t *record_entries_references_array = NULL;
4569
0
  static char *function                             = "libpff_table_read_9c_values";
4570
4571
0
  if( table == NULL )
4572
0
  {
4573
0
    libcerror_error_set(
4574
0
     error,
4575
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4576
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4577
0
     "%s: invalid table.",
4578
0
     function );
4579
4580
0
    return( -1 );
4581
0
  }
4582
0
  if( table->header == NULL )
4583
0
  {
4584
0
    libcerror_error_set(
4585
0
     error,
4586
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4587
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4588
0
     "%s: invalid table - missing header.",
4589
0
     function );
4590
4591
0
    return( -1 );
4592
0
  }
4593
0
  if( ( table->header->record_entry_identifier_size != 16 )
4594
0
   || ( table->header->record_entry_value_size != 4 ) )
4595
0
  {
4596
0
    libcerror_error_set(
4597
0
     error,
4598
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4599
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4600
0
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4601
0
     function,
4602
0
     table->header->record_entry_identifier_size,
4603
0
     table->header->record_entry_value_size );
4604
4605
0
    goto on_error;
4606
0
  }
4607
0
  if( libcdata_array_initialize(
4608
0
       &record_entries_references_array,
4609
0
       0,
4610
0
       error ) != 1 )
4611
0
  {
4612
0
    libcerror_error_set(
4613
0
     error,
4614
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4615
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4616
0
     "%s: unable to create record entries references array.",
4617
0
     function );
4618
4619
0
    goto on_error;
4620
0
  }
4621
0
  if( libpff_table_read_record_entries(
4622
0
       table,
4623
0
       record_entries_references_array,
4624
0
       table->header->record_entries_level,
4625
0
       table->header->record_entry_identifier_size,
4626
0
       table->header->record_entries_reference,
4627
0
       io_handle,
4628
0
       file_io_handle,
4629
0
       0,
4630
0
       error ) != 1 )
4631
0
  {
4632
0
    libcerror_error_set(
4633
0
     error,
4634
0
     LIBCERROR_ERROR_DOMAIN_IO,
4635
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4636
0
     "%s: unable to read record entries.",
4637
0
     function );
4638
4639
0
    goto on_error;
4640
0
  }
4641
0
  if( libpff_table_read_9c_record_entries(
4642
0
       table,
4643
0
       record_entries_references_array,
4644
0
       io_handle,
4645
0
       file_io_handle,
4646
0
       error ) != 1 )
4647
0
  {
4648
0
    libcerror_error_set(
4649
0
     error,
4650
0
     LIBCERROR_ERROR_DOMAIN_IO,
4651
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4652
0
     "%s: unable to read 9c table record entries.",
4653
0
     function );
4654
4655
0
    goto on_error;
4656
0
  }
4657
0
  if( libcdata_array_free(
4658
0
       &record_entries_references_array,
4659
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4660
0
       error ) != 1 )
4661
0
  {
4662
0
    libcerror_error_set(
4663
0
     error,
4664
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4665
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4666
0
     "%s: unable to free record entries references array.",
4667
0
     function );
4668
4669
0
    goto on_error;
4670
0
  }
4671
0
  return( 1 );
4672
4673
0
on_error:
4674
0
  if( record_entries_references_array != NULL )
4675
0
  {
4676
0
    libcdata_array_free(
4677
0
     &record_entries_references_array,
4678
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4679
0
     NULL );
4680
0
  }
4681
0
  return( -1 );
4682
0
}
4683
4684
/* Reads the a5 table values
4685
 * Returns 1 if successful or -1 on error
4686
 */
4687
int libpff_table_read_a5_values(
4688
     libpff_table_t *table,
4689
     libpff_io_handle_t *io_handle,
4690
     libbfio_handle_t *file_io_handle,
4691
     libcerror_error_t **error )
4692
37
{
4693
37
  libpff_table_block_index_t *table_block_index = NULL;
4694
37
  static char *function                         = "libpff_table_read_a5_values";
4695
37
  uint16_t number_of_table_index_values         = 0;
4696
4697
37
  if( table == NULL )
4698
0
  {
4699
0
    libcerror_error_set(
4700
0
     error,
4701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4702
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4703
0
     "%s: invalid table.",
4704
0
     function );
4705
4706
0
    return( -1 );
4707
0
  }
4708
37
  if( table->header == NULL )
4709
0
  {
4710
0
    libcerror_error_set(
4711
0
     error,
4712
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4713
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4714
0
     "%s: invalid table - missing header.",
4715
0
     function );
4716
4717
0
    return( -1 );
4718
0
  }
4719
37
  if( libcdata_array_get_entry_by_index(
4720
37
       table->index_array,
4721
37
       0,
4722
37
       (intptr_t **) &table_block_index,
4723
37
       error ) != 1 )
4724
0
  {
4725
0
    libcerror_error_set(
4726
0
     error,
4727
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4728
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4729
0
     "%s: unable to retrieve table index array entry: 0.",
4730
0
     function );
4731
4732
0
    return( -1 );
4733
0
  }
4734
37
  if( table_block_index == NULL )
4735
0
  {
4736
0
    libcerror_error_set(
4737
0
     error,
4738
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4739
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4740
0
     "%s: missing table block index: 0.",
4741
0
     function );
4742
4743
0
    return( -1 );
4744
0
  }
4745
37
  if( libpff_table_block_index_get_number_of_values(
4746
37
       table_block_index,
4747
37
       &number_of_table_index_values,
4748
37
       error ) != 1 )
4749
0
  {
4750
0
    libcerror_error_set(
4751
0
     error,
4752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4753
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4754
0
     "%s: unable to retrieve number of table block index values.",
4755
0
     function );
4756
4757
0
    return( -1 );
4758
0
  }
4759
37
  if( number_of_table_index_values > 1 )
4760
32
  {
4761
32
    if( libpff_table_read_a5_record_entries(
4762
32
         table,
4763
32
         0x00000020,
4764
32
         io_handle,
4765
32
         file_io_handle,
4766
32
         error ) != 1 )
4767
0
    {
4768
0
      libcerror_error_set(
4769
0
       error,
4770
0
       LIBCERROR_ERROR_DOMAIN_IO,
4771
0
       LIBCERROR_IO_ERROR_READ_FAILED,
4772
0
       "%s: unable to read a5 table record entries.",
4773
0
       function );
4774
4775
0
      return( -1 );
4776
0
    }
4777
32
  }
4778
#if defined( HAVE_DEBUG_OUTPUT )
4779
  else if( libcnotify_verbose != 0 )
4780
  {
4781
    libcnotify_printf(
4782
     "%s: table contains no entries.\n",
4783
     function );
4784
  }
4785
#endif
4786
37
  return( 1 );
4787
37
}
4788
4789
/* Reads the ac table values
4790
 * Returns 1 if successful or -1 on error
4791
 */
4792
int libpff_table_read_ac_values(
4793
     libpff_table_t *table,
4794
     libpff_io_handle_t *io_handle,
4795
     libbfio_handle_t *file_io_handle,
4796
     libpff_offsets_index_t *offsets_index,
4797
     libcdata_list_t *name_to_id_map_list,
4798
     libcerror_error_t **error )
4799
0
{
4800
0
  libcdata_array_t *column_definitions_array        = NULL;
4801
0
  libcdata_array_t *record_entries_references_array = NULL;
4802
0
  static char *function                             = "libpff_table_read_ac_values";
4803
0
  int number_of_column_definitions                  = 0;
4804
4805
0
  if( table == NULL )
4806
0
  {
4807
0
    libcerror_error_set(
4808
0
     error,
4809
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4810
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4811
0
     "%s: invalid table.",
4812
0
     function );
4813
4814
0
    return( -1 );
4815
0
  }
4816
0
  if( table->header == NULL )
4817
0
  {
4818
0
    libcerror_error_set(
4819
0
     error,
4820
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4821
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4822
0
     "%s: invalid table - missing header.",
4823
0
     function );
4824
4825
0
    return( -1 );
4826
0
  }
4827
0
  if( ( table->header->record_entry_identifier_size != 4 )
4828
0
   || ( table->header->record_entry_value_size != 4 ) )
4829
0
  {
4830
0
    libcerror_error_set(
4831
0
     error,
4832
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4833
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4834
0
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4835
0
     function,
4836
0
     table->header->record_entry_identifier_size,
4837
0
     table->header->record_entry_value_size );
4838
4839
0
    goto on_error;
4840
0
  }
4841
  /* Create the column definitions array
4842
   */
4843
0
  if( libcdata_array_initialize(
4844
0
       &column_definitions_array,
4845
0
       0,
4846
0
       error ) != 1 )
4847
0
  {
4848
0
    libcerror_error_set(
4849
0
     error,
4850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4851
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4852
0
     "%s: unable to create column definitions array.",
4853
0
     function );
4854
4855
0
    goto on_error;
4856
0
  }
4857
0
  if( libpff_table_read_ac_column_definitions(
4858
0
       table,
4859
0
       column_definitions_array,
4860
0
       table->header->column_definitions_reference,
4861
0
       table->header->number_of_column_definitions,
4862
0
       io_handle,
4863
0
       file_io_handle,
4864
0
       offsets_index,
4865
0
       name_to_id_map_list,
4866
0
       error ) != 1 )
4867
0
  {
4868
0
    libcerror_error_set(
4869
0
     error,
4870
0
     LIBCERROR_ERROR_DOMAIN_IO,
4871
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4872
0
     "%s: unable to read ac table column definitions.",
4873
0
     function );
4874
4875
0
    goto on_error;
4876
0
  }
4877
0
  if( libcdata_array_initialize(
4878
0
       &record_entries_references_array,
4879
0
       0,
4880
0
       error ) != 1 )
4881
0
  {
4882
0
    libcerror_error_set(
4883
0
     error,
4884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4885
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4886
0
     "%s: unable to create record entries reference array.",
4887
0
     function );
4888
4889
0
    goto on_error;
4890
0
  }
4891
0
  if( libpff_table_read_record_entries(
4892
0
       table,
4893
0
       record_entries_references_array,
4894
0
       table->header->record_entries_level,
4895
0
       table->header->record_entry_identifier_size,
4896
0
       table->header->record_entries_reference,
4897
0
       io_handle,
4898
0
       file_io_handle,
4899
0
       0,
4900
0
       error ) != 1 )
4901
0
  {
4902
0
    libcerror_error_set(
4903
0
     error,
4904
0
     LIBCERROR_ERROR_DOMAIN_IO,
4905
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4906
0
     "%s: unable to read record entries.",
4907
0
     function );
4908
4909
0
    goto on_error;
4910
0
  }
4911
0
  if( libcdata_array_get_number_of_entries(
4912
0
       table->index_array,
4913
0
       &number_of_column_definitions,
4914
0
       error ) != 1 )
4915
0
  {
4916
0
    libcerror_error_set(
4917
0
     error,
4918
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4919
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4920
0
     "%s: unable to retrieve number of column definitions.",
4921
0
     function );
4922
4923
0
    goto on_error;
4924
0
  }
4925
0
  if( number_of_column_definitions > 0 )
4926
0
  {
4927
0
    if( libpff_table_read_values_array(
4928
0
         table,
4929
0
         record_entries_references_array,
4930
0
         table->header->values_array_reference,
4931
0
         table->header->record_entry_identifier_size,
4932
0
         table->header->record_entry_value_size,
4933
0
         table->header->values_array_entry_size,
4934
0
         column_definitions_array,
4935
0
         io_handle,
4936
0
         file_io_handle,
4937
0
         offsets_index,
4938
0
         error ) != 1 )
4939
0
    {
4940
0
      libcerror_error_set(
4941
0
       error,
4942
0
       LIBCERROR_ERROR_DOMAIN_IO,
4943
0
       LIBCERROR_IO_ERROR_READ_FAILED,
4944
0
       "%s: unable to read values array.",
4945
0
       function );
4946
4947
0
      goto on_error;
4948
0
    }
4949
0
  }
4950
0
  if( libcdata_array_free(
4951
0
       &column_definitions_array,
4952
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4953
0
       error ) != 1 )
4954
0
  {
4955
0
    libcerror_error_set(
4956
0
     error,
4957
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4958
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4959
0
     "%s: unable to free the column definitions array.",
4960
0
     function );
4961
4962
0
    goto on_error;
4963
0
  }
4964
0
  if( libcdata_array_free(
4965
0
       &record_entries_references_array,
4966
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4967
0
       error ) != 1 )
4968
0
  {
4969
0
    libcerror_error_set(
4970
0
     error,
4971
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4972
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4973
0
     "%s: unable to free record entries reference array.",
4974
0
     function );
4975
4976
0
    goto on_error;
4977
0
  }
4978
0
  return( 1 );
4979
4980
0
on_error:
4981
0
  if( record_entries_references_array != NULL )
4982
0
  {
4983
0
    libcdata_array_free(
4984
0
     &record_entries_references_array,
4985
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4986
0
     NULL );
4987
0
  }
4988
0
  if( column_definitions_array != NULL )
4989
0
  {
4990
0
    libcdata_array_free(
4991
0
     &column_definitions_array,
4992
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4993
0
     NULL );
4994
0
  }
4995
0
  return( -1 );
4996
0
}
4997
4998
/* Reads the bc table values
4999
 * Returns 1 if successful or -1 on error
5000
 */
5001
int libpff_table_read_bc_values(
5002
     libpff_table_t *table,
5003
     libpff_io_handle_t *io_handle,
5004
     libbfio_handle_t *file_io_handle,
5005
     libpff_offsets_index_t *offsets_index,
5006
     libcdata_list_t *name_to_id_map_list,
5007
     int debug_item_type,
5008
     libcerror_error_t **error )
5009
1.19k
{
5010
1.19k
  libcdata_array_t *record_entries_references_array = NULL;
5011
1.19k
  static char *function                             = "libpff_table_read_bc_values";
5012
5013
1.19k
  if( table == NULL )
5014
0
  {
5015
0
    libcerror_error_set(
5016
0
     error,
5017
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5018
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5019
0
     "%s: invalid table.",
5020
0
     function );
5021
5022
0
    return( -1 );
5023
0
  }
5024
1.19k
  if( table->header == NULL )
5025
0
  {
5026
0
    libcerror_error_set(
5027
0
     error,
5028
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5029
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5030
0
     "%s: invalid table - missing header.",
5031
0
     function );
5032
5033
0
    return( -1 );
5034
0
  }
5035
1.19k
  if( ( table->header->record_entry_identifier_size != 2 )
5036
1.19k
   || ( table->header->record_entry_value_size != 6 ) )
5037
40
  {
5038
40
    libcerror_error_set(
5039
40
     error,
5040
40
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5041
40
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5042
40
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
5043
40
     function,
5044
40
     table->header->record_entry_identifier_size,
5045
40
     table->header->record_entry_value_size );
5046
5047
40
    goto on_error;
5048
40
  }
5049
1.15k
  if( libcdata_array_initialize(
5050
1.15k
       &record_entries_references_array,
5051
1.15k
       0,
5052
1.15k
       error ) != 1 )
5053
0
  {
5054
0
    libcerror_error_set(
5055
0
     error,
5056
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5057
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5058
0
     "%s: unable to create record entries references array.",
5059
0
     function );
5060
5061
0
    goto on_error;
5062
0
  }
5063
1.15k
  if( libpff_table_read_record_entries(
5064
1.15k
       table,
5065
1.15k
       record_entries_references_array,
5066
1.15k
       table->header->record_entries_level,
5067
1.15k
       table->header->record_entry_identifier_size,
5068
1.15k
       table->header->record_entries_reference,
5069
1.15k
       io_handle,
5070
1.15k
       file_io_handle,
5071
1.15k
       0,
5072
1.15k
       error ) != 1 )
5073
150
  {
5074
150
    libcerror_error_set(
5075
150
     error,
5076
150
     LIBCERROR_ERROR_DOMAIN_IO,
5077
150
     LIBCERROR_IO_ERROR_READ_FAILED,
5078
150
     "%s: unable to read record entries.",
5079
150
     function );
5080
5081
150
    goto on_error;
5082
150
  }
5083
1.00k
  if( libpff_table_read_bc_record_entries(
5084
1.00k
       table,
5085
1.00k
       record_entries_references_array,
5086
1.00k
       io_handle,
5087
1.00k
       file_io_handle,
5088
1.00k
       offsets_index,
5089
1.00k
       name_to_id_map_list,
5090
1.00k
       debug_item_type,
5091
1.00k
       error ) != 1 )
5092
565
  {
5093
565
    libcerror_error_set(
5094
565
     error,
5095
565
     LIBCERROR_ERROR_DOMAIN_IO,
5096
565
     LIBCERROR_IO_ERROR_READ_FAILED,
5097
565
     "%s: unable to read table record entries.",
5098
565
     function );
5099
5100
565
    goto on_error;
5101
565
  }
5102
440
  if( libcdata_array_free(
5103
440
       &record_entries_references_array,
5104
440
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
5105
440
       error ) != 1 )
5106
0
  {
5107
0
    libcerror_error_set(
5108
0
     error,
5109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5110
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5111
0
     "%s: unable to free record entries references array.",
5112
0
     function );
5113
5114
0
    goto on_error;
5115
0
  }
5116
440
  return( 1 );
5117
5118
755
on_error:
5119
755
  if( record_entries_references_array != NULL )
5120
715
  {
5121
715
    libcdata_array_free(
5122
715
     &record_entries_references_array,
5123
715
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
5124
715
     NULL );
5125
715
  }
5126
755
  return( -1 );
5127
440
}
5128
5129
/* Reads the 6c table record entries and their values
5130
 * Returns 1 if successful or -1 on error
5131
 */
5132
int libpff_table_read_6c_record_entries(
5133
     libpff_table_t *table,
5134
     libcdata_array_t *record_entries_references_array,
5135
     uint32_t values_array_reference,
5136
     libpff_io_handle_t *io_handle,
5137
     libbfio_handle_t *file_io_handle,
5138
     libcerror_error_t **error )
5139
0
{
5140
0
  libpff_internal_record_entry_t *record_entry        = NULL;
5141
0
  libpff_reference_descriptor_t *reference_descriptor = NULL;
5142
0
  uint8_t *record_entries_data                        = NULL;
5143
0
  uint8_t *table_values_array_data                    = NULL;
5144
0
  static char *function                               = "libpff_table_read_6c_record_entries";
5145
0
  size_t number_of_record_entries                     = 0;
5146
0
  size_t record_entries_data_size                     = 0;
5147
0
  size_t table_values_array_data_size                 = 0;
5148
0
  uint16_t values_array_number                        = 0;
5149
0
  int number_of_record_entries_references             = 0;
5150
0
  int record_entries_reference_index                  = 0;
5151
0
  int record_entry_index                              = 0;
5152
5153
#if defined( HAVE_DEBUG_OUTPUT )
5154
  system_character_t guid_string[ 48 ];
5155
5156
  libfguid_identifier_t *guid                         = NULL;
5157
  int result                                          = 0;
5158
#endif
5159
5160
0
  if( table == NULL )
5161
0
  {
5162
0
    libcerror_error_set(
5163
0
     error,
5164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5165
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5166
0
     "%s: invalid table.",
5167
0
     function );
5168
5169
0
    return( -1 );
5170
0
  }
5171
0
  if( values_array_reference == 0 )
5172
0
  {
5173
0
    libcerror_error_set(
5174
0
     error,
5175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5176
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5177
0
     "%s: table contains no value array.",
5178
0
     function );
5179
5180
0
    return( -1 );
5181
0
  }
5182
0
  if( ( values_array_reference & 0x0000001fUL ) != 0 )
5183
0
  {
5184
0
    libcerror_error_set(
5185
0
     error,
5186
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5187
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
5188
0
     "%s: unsupported values array entries reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
5189
0
     function,
5190
0
     values_array_reference & 0x0000001fUL,
5191
0
     values_array_reference );
5192
5193
0
    return( -1 );
5194
0
  }
5195
0
  if( io_handle == NULL )
5196
0
  {
5197
0
    libcerror_error_set(
5198
0
     error,
5199
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5200
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5201
0
     "%s: invalid IO handle.",
5202
0
     function );
5203
5204
0
    return( -1 );
5205
0
  }
5206
0
  if( libpff_table_clone_value_data_by_reference(
5207
0
       table,
5208
0
       values_array_reference,
5209
0
       io_handle,
5210
0
       file_io_handle,
5211
0
       &table_values_array_data,
5212
0
       &table_values_array_data_size,
5213
0
       error ) != 1 )
5214
0
  {
5215
0
    libcerror_error_set(
5216
0
     error,
5217
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5218
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5219
0
     "%s: unable to retrieve values array data.",
5220
0
     function );
5221
5222
0
    goto on_error;
5223
0
  }
5224
0
  if( ( table_values_array_data == NULL )
5225
0
   || ( table_values_array_data_size == 0 ) )
5226
0
  {
5227
0
    libcerror_error_set(
5228
0
     error,
5229
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5230
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5231
0
     "%s: missing values array data.",
5232
0
     function );
5233
5234
0
    goto on_error;
5235
0
  }
5236
0
  if( libcdata_array_get_number_of_entries(
5237
0
       record_entries_references_array,
5238
0
       &number_of_record_entries_references,
5239
0
       error ) != 1 )
5240
0
  {
5241
0
    libcerror_error_set(
5242
0
     error,
5243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5244
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5245
0
     "%s: unable to retrieve number of record entries references.",
5246
0
     function );
5247
5248
0
    goto on_error;
5249
0
  }
5250
0
  if( number_of_record_entries_references > 0 )
5251
0
  {
5252
0
    if( libpff_table_resize_record_entries(
5253
0
         table,
5254
0
         1,
5255
0
         0,
5256
0
         io_handle->ascii_codepage,
5257
0
         error ) != 1 )
5258
0
    {
5259
0
      libcerror_error_set(
5260
0
       error,
5261
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5262
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
5263
0
       "%s: unable to resize record entries.",
5264
0
       function );
5265
5266
0
      goto on_error;
5267
0
    }
5268
0
    for( record_entries_reference_index = 0;
5269
0
         record_entries_reference_index < number_of_record_entries_references;
5270
0
         record_entries_reference_index++ )
5271
0
    {
5272
#if defined( HAVE_DEBUG_OUTPUT )
5273
      if( libcnotify_verbose != 0 )
5274
      {
5275
        libcnotify_printf(
5276
         "%s: record entries reference: %d\n",
5277
         function,
5278
         record_entries_reference_index );
5279
      }
5280
#endif
5281
0
      if( libcdata_array_get_entry_by_index(
5282
0
           record_entries_references_array,
5283
0
           record_entries_reference_index,
5284
0
           (intptr_t **) &reference_descriptor,
5285
0
           error ) != 1 )
5286
0
      {
5287
0
        libcerror_error_set(
5288
0
         error,
5289
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5290
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5291
0
         "%s: unable to retrieve record entries reference: %d.",
5292
0
         function,
5293
0
         record_entries_reference_index );
5294
5295
0
        goto on_error;
5296
0
      }
5297
0
      if( reference_descriptor == NULL )
5298
0
      {
5299
0
        libcerror_error_set(
5300
0
         error,
5301
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5302
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5303
0
         "%s: missing reference descriptor.",
5304
0
         function );
5305
5306
0
        goto on_error;
5307
0
      }
5308
0
      if( libpff_table_get_value_data_by_reference(
5309
0
           table,
5310
0
           io_handle,
5311
0
           file_io_handle,
5312
0
           reference_descriptor->value,
5313
0
           &record_entries_data,
5314
0
           &record_entries_data_size,
5315
0
           error ) != 1 )
5316
0
      {
5317
0
        libcerror_error_set(
5318
0
         error,
5319
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5320
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5321
0
         "%s: unable to retrieve record entries data.",
5322
0
         function );
5323
5324
0
        goto on_error;
5325
0
      }
5326
0
      if( ( record_entries_data == NULL )
5327
0
       || ( record_entries_data_size == 0 ) )
5328
0
      {
5329
0
        libcerror_error_set(
5330
0
         error,
5331
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5332
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5333
0
         "%s: missing record entries data.",
5334
0
         function );
5335
5336
0
        goto on_error;
5337
0
      }
5338
0
      if( ( record_entries_data_size % sizeof( pff_table_record_entry_6c_t ) ) != 0 )
5339
0
      {
5340
0
        libcerror_error_set(
5341
0
         error,
5342
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5343
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5344
0
         "%s: unsupported record entries data size.",
5345
0
         function );
5346
5347
0
        goto on_error;
5348
0
      }
5349
0
      number_of_record_entries = record_entries_data_size / sizeof( pff_table_record_entry_6c_t );
5350
5351
0
      if( number_of_record_entries > (size_t) INT_MAX )
5352
0
      {
5353
0
        libcerror_error_set(
5354
0
         error,
5355
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5356
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5357
0
         "%s: number of record entries value exceeds maximum.",
5358
0
         function );
5359
5360
0
        goto on_error;
5361
0
      }
5362
0
      if( libpff_table_expand_record_entries(
5363
0
           table,
5364
0
           0,
5365
0
           (int) number_of_record_entries,
5366
0
           io_handle->ascii_codepage,
5367
0
           error ) != 1 )
5368
0
      {
5369
0
        libcerror_error_set(
5370
0
         error,
5371
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5372
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
5373
0
         "%s: unable to expand record entries.",
5374
0
         function );
5375
5376
0
        goto on_error;
5377
0
      }
5378
0
      while( record_entries_data_size > 0 )
5379
0
      {
5380
0
        if( libpff_table_get_record_entry_by_index(
5381
0
             table,
5382
0
             0,
5383
0
             record_entry_index,
5384
0
             (libpff_record_entry_t **) &record_entry,
5385
0
             error ) != 1 )
5386
0
        {
5387
0
          libcerror_error_set(
5388
0
           error,
5389
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5390
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5391
0
           "%s: unable to retrieve record entry with set index: 0 and entry index: %d.",
5392
0
           function,
5393
0
           record_entry_index );
5394
5395
0
          goto on_error;
5396
0
        }
5397
0
        if( record_entry == NULL )
5398
0
        {
5399
0
          libcerror_error_set(
5400
0
           error,
5401
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5402
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5403
0
           "%s: missing record entry with set index: 0 and entry index: %d.",
5404
0
           function,
5405
0
           record_entry_index );
5406
5407
0
          return( -1 );
5408
0
        }
5409
0
        record_entry->identifier.format = LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_GUID;
5410
5411
0
        if( memory_copy(
5412
0
             record_entry->identifier.guid,
5413
0
             ( (pff_table_record_entry_6c_t *) record_entries_data )->record_entry_guid,
5414
0
             16 ) == NULL )
5415
0
        {
5416
0
          libcerror_error_set(
5417
0
           error,
5418
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
5419
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5420
0
           "%s: unable to copy record entry identifier GUID.",
5421
0
           function );
5422
5423
0
          goto on_error;
5424
0
        }
5425
0
        byte_stream_copy_to_uint16_little_endian(
5426
0
         ( (pff_table_record_entry_6c_t *) record_entries_data )->values_array_number,
5427
0
         values_array_number );
5428
5429
0
        if( (size_t) ( 16 * values_array_number ) > table_values_array_data_size )
5430
0
        {
5431
0
          libcerror_error_set(
5432
0
           error,
5433
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5434
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5435
0
           "%s: values array number exceeds table values array data size.",
5436
0
           function );
5437
5438
0
          goto on_error;
5439
0
        }
5440
0
        if( libpff_record_entry_set_value_data(
5441
0
             (libpff_record_entry_t *) record_entry,
5442
0
             &( table_values_array_data[ 16 * values_array_number ] ),
5443
0
             16,
5444
0
             error ) != 1 )
5445
0
        {
5446
0
          libcerror_error_set(
5447
0
           error,
5448
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5449
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5450
0
           "%s: unable to set value data in record entry.",
5451
0
           function );
5452
5453
0
          goto on_error;
5454
0
        }
5455
/* TODO do something with values_array_number ? */
5456
5457
#if defined( HAVE_DEBUG_OUTPUT )
5458
        if( libcnotify_verbose != 0 )
5459
        {
5460
          if( libfguid_identifier_initialize(
5461
               &guid,
5462
               error ) != 1 )
5463
          {
5464
            libcerror_error_set(
5465
             error,
5466
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5467
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5468
             "%s: unable to create GUID.",
5469
             function );
5470
5471
            goto on_error;
5472
          }
5473
          if( libfguid_identifier_copy_from_byte_stream(
5474
               guid,
5475
               record_entry->identifier.guid,
5476
               16,
5477
               LIBFGUID_ENDIAN_LITTLE,
5478
               error ) != 1 )
5479
          {
5480
            libcerror_error_set(
5481
             error,
5482
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5483
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5484
             "%s: unable to copy byte stream to GUID.",
5485
             function );
5486
5487
            goto on_error;
5488
          }
5489
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5490
          result = libfguid_identifier_copy_to_utf16_string(
5491
              guid,
5492
              (uint16_t *) guid_string,
5493
              48,
5494
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
5495
              error );
5496
#else
5497
          result = libfguid_identifier_copy_to_utf8_string(
5498
              guid,
5499
              (uint8_t *) guid_string,
5500
              48,
5501
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
5502
              error );
5503
#endif
5504
          if( result != 1 )
5505
          {
5506
            libcerror_error_set(
5507
             error,
5508
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5509
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5510
             "%s: unable to copy GUID to string.",
5511
             function );
5512
5513
            goto on_error;
5514
          }
5515
          libcnotify_printf(
5516
           "%s: table set: %03d entry: %03d record entry guid\t\t\t: %" PRIs_SYSTEM "\n",
5517
           function,
5518
           0,
5519
           record_entry_index,
5520
           guid_string );
5521
5522
          if( libfguid_identifier_copy_from_byte_stream(
5523
               guid,
5524
               &( table_values_array_data[ 16 * values_array_number ] ),
5525
               16,
5526
               LIBFGUID_ENDIAN_LITTLE,
5527
               error ) != 1 )
5528
          {
5529
            libcerror_error_set(
5530
             error,
5531
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5532
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5533
             "%s: unable to copy byte stream to GUID.",
5534
             function );
5535
5536
            goto on_error;
5537
          }
5538
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5539
          result = libfguid_identifier_copy_to_utf16_string(
5540
              guid,
5541
              (uint16_t *) guid_string,
5542
              48,
5543
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
5544
              error );
5545
#else
5546
          result = libfguid_identifier_copy_to_utf8_string(
5547
              guid,
5548
              (uint8_t *) guid_string,
5549
              48,
5550
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
5551
              error );
5552
#endif
5553
          if( result != 1 )
5554
          {
5555
            libcerror_error_set(
5556
             error,
5557
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5558
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
5559
             "%s: unable to copy GUID to string.",
5560
             function );
5561
5562
            goto on_error;
5563
          }
5564
          if( libfguid_identifier_free(
5565
               &guid,
5566
               error ) != 1 )
5567
          {
5568
            libcerror_error_set(
5569
             error,
5570
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
5571
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5572
             "%s: unable to free GUID.",
5573
             function );
5574
5575
            goto on_error;
5576
          }
5577
          libcnotify_printf(
5578
           "%s: table set: %03d entry: %03d record entry value guid\t\t: %" PRIs_SYSTEM "\n",
5579
           function,
5580
           0,
5581
           record_entry_index,
5582
           guid_string );
5583
5584
          libcnotify_printf(
5585
           "%s: table set: %03d entry: %03d record entry value identifier\t: 0x%04" PRIx16 "\n",
5586
           function,
5587
           0,
5588
           record_entry_index,
5589
           values_array_number );
5590
5591
          libcnotify_printf(
5592
           "\n" );
5593
        }
5594
#endif
5595
0
        record_entries_data      += sizeof( pff_table_record_entry_6c_t );
5596
0
        record_entries_data_size -= sizeof( pff_table_record_entry_6c_t );
5597
5598
0
        record_entry_index++;
5599
0
      }
5600
0
    }
5601
0
  }
5602
0
  memory_free(
5603
0
   table_values_array_data );
5604
5605
0
  return( 1 );
5606
5607
0
on_error:
5608
#if defined( HAVE_DEBUG_OUTPUT )
5609
  if( guid != NULL )
5610
  {
5611
    libfguid_identifier_free(
5612
     &guid,
5613
     NULL );
5614
  }
5615
#endif
5616
0
  if( table_values_array_data != NULL )
5617
0
  {
5618
0
    memory_free(
5619
0
     table_values_array_data );
5620
0
  }
5621
0
  return( -1 );
5622
0
}
5623
5624
/* Reads the 7c table column definitions
5625
 * Returns 1 if successful or -1 on error
5626
 */
5627
int libpff_table_read_7c_column_definitions(
5628
     libpff_table_t *table,
5629
     libcdata_array_t *column_definitions_array,
5630
     uint8_t *column_definitions_data,
5631
     size_t column_definitions_data_size,
5632
     int number_of_column_definitions,
5633
     libbfio_handle_t *file_io_handle LIBPFF_ATTRIBUTE_UNUSED,
5634
     libcdata_list_t *name_to_id_map_list,
5635
     libcerror_error_t **error )
5636
1.82k
{
5637
1.82k
  libpff_column_definition_t *column_definition        = NULL;
5638
1.82k
  libpff_column_definition_t *lookup_column_definition = NULL;
5639
1.82k
  static char *function                                = "libpff_table_read_7c_column_definitions";
5640
1.82k
  uint8_t column_definition_number                     = 0;
5641
1.82k
  int column_definition_index                          = 0;
5642
1.82k
  int result                                           = 0;
5643
5644
1.82k
  LIBPFF_UNREFERENCED_PARAMETER( file_io_handle )
5645
5646
1.82k
  if( table == NULL )
5647
0
  {
5648
0
    libcerror_error_set(
5649
0
     error,
5650
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5651
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5652
0
     "%s: invalid table.",
5653
0
     function );
5654
5655
0
    return( -1 );
5656
0
  }
5657
1.82k
  if( column_definitions_array == NULL )
5658
0
  {
5659
0
    libcerror_error_set(
5660
0
     error,
5661
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5662
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5663
0
     "%s: invalid column definitions array.",
5664
0
     function );
5665
5666
0
    return( -1 );
5667
0
  }
5668
1.82k
  if( column_definitions_data == NULL )
5669
0
  {
5670
0
    libcerror_error_set(
5671
0
     error,
5672
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5673
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5674
0
     "%s: invalid column definitions data.",
5675
0
     function );
5676
5677
0
    return( -1 );
5678
0
  }
5679
1.82k
  if( column_definitions_data_size > (size_t) SSIZE_MAX )
5680
0
  {
5681
0
    libcerror_error_set(
5682
0
     error,
5683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5684
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5685
0
     "%s: invalid column definitions data size value exceeds maximum.",
5686
0
     function );
5687
5688
0
    return( -1 );
5689
0
  }
5690
1.82k
  if( number_of_column_definitions == 0 )
5691
1
  {
5692
#if defined( HAVE_DEBUG_OUTPUT )
5693
    if( libcnotify_verbose != 0 )
5694
    {
5695
      libcnotify_printf(
5696
       "%s: table contains no column definitions.\n",
5697
       function );
5698
    }
5699
#endif
5700
1
    return( 1 );
5701
1
  }
5702
1.82k
  if( libcdata_array_resize(
5703
1.82k
       column_definitions_array,
5704
1.82k
       number_of_column_definitions,
5705
1.82k
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
5706
1.82k
       error ) != 1 )
5707
0
  {
5708
0
    libcerror_error_set(
5709
0
     error,
5710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5711
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
5712
0
     "%s: unable to resize column definition array.",
5713
0
     function );
5714
5715
0
    goto on_error;
5716
0
  }
5717
1.82k
  for( column_definition_index = 0;
5718
23.4k
       column_definition_index < number_of_column_definitions;
5719
21.6k
       column_definition_index++ )
5720
21.6k
  {
5721
21.6k
    if( column_definitions_data_size < sizeof( pff_table_column_definition_7c_t ) )
5722
0
    {
5723
0
      libcerror_error_set(
5724
0
       error,
5725
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5726
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5727
0
       "%s: invalid column definitions data size value out of bounds.",
5728
0
       function );
5729
5730
0
      goto on_error;
5731
0
    }
5732
21.6k
    if( libpff_column_definition_initialize(
5733
21.6k
         &column_definition,
5734
21.6k
         error ) != 1 )
5735
0
    {
5736
0
      libcerror_error_set(
5737
0
       error,
5738
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5739
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5740
0
       "%s: unable to create column definition.",
5741
0
       function );
5742
5743
0
      goto on_error;
5744
0
    }
5745
21.6k
    byte_stream_copy_to_uint16_little_endian(
5746
21.6k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->record_entry_type,
5747
21.6k
     column_definition->entry_type );
5748
5749
21.6k
    byte_stream_copy_to_uint16_little_endian(
5750
21.6k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->record_entry_value_type,
5751
21.6k
     column_definition->value_type );
5752
5753
21.6k
    byte_stream_copy_to_uint16_little_endian(
5754
21.6k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->values_array_offset,
5755
21.6k
     column_definition->values_array_offset );
5756
5757
21.6k
    column_definition->values_array_size = ( (pff_table_column_definition_7c_t *) column_definitions_data )->values_array_size;
5758
21.6k
    column_definition_number             = ( (pff_table_column_definition_7c_t *) column_definitions_data )->values_array_number;
5759
5760
#if defined( HAVE_DEBUG_OUTPUT )
5761
    if( libcnotify_verbose != 0 )
5762
    {
5763
      libcnotify_printf(
5764
       "%s: column definition: %03d record entry type\t: 0x%04" PRIx16 "",
5765
       function,
5766
       column_definition_index,
5767
       column_definition->entry_type );
5768
    }
5769
#endif
5770
21.6k
    if( ( column_definition->entry_type >= 0x8000 )
5771
21.6k
     || ( column_definition->entry_type <= 0xfffe ) )
5772
21.6k
    {
5773
21.6k
      result = libpff_name_to_id_map_entry_get_entry_by_identifier(
5774
21.6k
                name_to_id_map_list,
5775
21.6k
                (uint32_t) column_definition->entry_type,
5776
21.6k
                &( column_definition->name_to_id_map_entry ),
5777
21.6k
                error );
5778
5779
21.6k
      if( result == -1 )
5780
0
      {
5781
0
        libcerror_error_set(
5782
0
         error,
5783
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5784
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5785
0
         "%s: unable to retrieve name to id map entry: %" PRIu16 ".",
5786
0
         function,
5787
0
         column_definition->entry_type );
5788
5789
0
        goto on_error;
5790
0
      }
5791
21.6k
    }
5792
#if defined( HAVE_DEBUG_OUTPUT )
5793
    if( libcnotify_verbose != 0 )
5794
    {
5795
      if( column_definition->name_to_id_map_entry != NULL )
5796
      {
5797
        if( column_definition->name_to_id_map_entry->type == LIBPFF_NAME_TO_ID_MAP_ENTRY_TYPE_STRING )
5798
        {
5799
          libcnotify_printf(
5800
           " maps to: %s (%s : %s)\n",
5801
           (char *) column_definition->name_to_id_map_entry->debug_string,
5802
           libfmapi_named_property_type_get_identifier(
5803
            column_definition->name_to_id_map_entry->guid,
5804
            (char *) column_definition->name_to_id_map_entry->debug_string,
5805
            column_definition->name_to_id_map_entry->value_size,
5806
            column_definition->value_type ),
5807
           libfmapi_named_property_type_get_description(
5808
            column_definition->name_to_id_map_entry->guid,
5809
            (char *) column_definition->name_to_id_map_entry->debug_string,
5810
            column_definition->name_to_id_map_entry->value_size,
5811
            column_definition->value_type ) );
5812
        }
5813
        else
5814
        {
5815
          libcnotify_printf(
5816
           " maps to: 0x%04" PRIx32 " (%s : %s)\n",
5817
           column_definition->name_to_id_map_entry->numeric_value,
5818
           libfmapi_property_type_get_identifier(
5819
            column_definition->name_to_id_map_entry->guid,
5820
            column_definition->name_to_id_map_entry->numeric_value,
5821
            column_definition->value_type ),
5822
           libfmapi_property_type_get_description(
5823
            column_definition->name_to_id_map_entry->guid,
5824
            column_definition->name_to_id_map_entry->numeric_value,
5825
            column_definition->value_type ) );
5826
        }
5827
      }
5828
      else
5829
      {
5830
        libcnotify_printf(
5831
         " (%s : %s)\n",
5832
         libfmapi_property_type_get_identifier(
5833
          NULL,
5834
          column_definition->entry_type,
5835
          column_definition->value_type ),
5836
         libfmapi_property_type_get_description(
5837
          NULL,
5838
          column_definition->entry_type,
5839
          column_definition->value_type ) );
5840
      }
5841
      libcnotify_printf(
5842
       "%s: column definition: %03d record entry value type\t: 0x%04" PRIx16 " (%s : %s)\n",
5843
       function,
5844
       column_definition_index,
5845
       column_definition->value_type,
5846
       libfmapi_value_type_get_identifier(
5847
        column_definition->value_type ),
5848
       libfmapi_value_type_get_description(
5849
        column_definition->value_type ) );
5850
5851
      libcnotify_printf(
5852
       "%s: column definition: %03d values array offset\t: %" PRIu16 "\n",
5853
       function,
5854
       column_definition_index,
5855
       column_definition->values_array_offset );
5856
5857
      libcnotify_printf(
5858
       "%s: column definition: %03d values array size\t: %" PRIu16 "\n",
5859
       function,
5860
       column_definition_index,
5861
       column_definition->values_array_size );
5862
5863
      libcnotify_printf(
5864
       "%s: column definition: %03d values array number\t: %" PRIu8 "\n",
5865
       function,
5866
       column_definition_index,
5867
       column_definition_number );
5868
5869
      libcnotify_printf(
5870
       "\n" );
5871
    }
5872
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5873
5874
21.6k
    if( libcdata_array_get_entry_by_index(
5875
21.6k
         column_definitions_array,
5876
21.6k
         (int) column_definition_number,
5877
21.6k
         (intptr_t **) &lookup_column_definition,
5878
21.6k
         error ) != 1 )
5879
25
    {
5880
25
      libcerror_error_set(
5881
25
       error,
5882
25
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5883
25
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5884
25
       "%s: unable to retrieve column definitions: %" PRIu8 " in array.",
5885
25
       function,
5886
25
       column_definition_number );
5887
5888
25
      goto on_error;
5889
25
    }
5890
21.6k
    if( lookup_column_definition != NULL )
5891
7
    {
5892
7
      libcerror_error_set(
5893
7
       error,
5894
7
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5895
7
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5896
7
       "%s: column definitions: %" PRIu8 " already set in array.",
5897
7
       function,
5898
7
       column_definition_number );
5899
5900
7
      goto on_error;
5901
7
    }
5902
21.6k
    if( libcdata_array_set_entry_by_index(
5903
21.6k
         column_definitions_array,
5904
21.6k
         (int) column_definition_number,
5905
21.6k
         (intptr_t *) column_definition,
5906
21.6k
         error ) != 1 )
5907
0
    {
5908
0
      libcerror_error_set(
5909
0
       error,
5910
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5911
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5912
0
       "%s: unable to set column definitions: %" PRIu8 " in array.",
5913
0
       function,
5914
0
       column_definition_number );
5915
5916
0
      goto on_error;
5917
0
    }
5918
21.6k
    column_definition = NULL;
5919
5920
21.6k
    column_definitions_data      += sizeof( pff_table_column_definition_7c_t );
5921
21.6k
    column_definitions_data_size -= sizeof( pff_table_column_definition_7c_t );
5922
21.6k
  }
5923
1.79k
  return( 1 );
5924
5925
32
on_error:
5926
32
  if( column_definition != NULL )
5927
32
  {
5928
32
    libpff_column_definition_free(
5929
32
     &column_definition,
5930
32
     NULL );
5931
32
  }
5932
32
  return( -1 );
5933
1.82k
}
5934
5935
/* Reads the 8c table record entries and their values
5936
 * Returns 1 if successful or -1 on error
5937
 */
5938
int libpff_table_read_8c_record_entries(
5939
     libpff_table_t *table,
5940
     libcdata_array_t *record_entries_references_array,
5941
     libpff_io_handle_t *io_handle,
5942
     libbfio_handle_t *file_io_handle,
5943
     libcerror_error_t **error )
5944
0
{
5945
0
  libpff_reference_descriptor_t *reference_descriptor = NULL;
5946
0
  libpff_internal_record_entry_t *record_entry        = NULL;
5947
0
  uint8_t *record_entries_data                        = NULL;
5948
0
  static char *function                               = "libpff_table_read_8c_record_entries";
5949
0
  size_t number_of_record_entries                     = 0;
5950
0
  size_t record_entries_data_size                     = 0;
5951
0
  int number_of_record_entries_references             = 0;
5952
0
  int record_entries_reference_index                  = 0;
5953
0
  int record_entry_index                              = 0;
5954
5955
#if defined( HAVE_DEBUG_OUTPUT )
5956
  uint32_t value_32bit                                = 0;
5957
#endif
5958
5959
0
  if( table == NULL )
5960
0
  {
5961
0
    libcerror_error_set(
5962
0
     error,
5963
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5964
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5965
0
     "%s: invalid table.",
5966
0
     function );
5967
5968
0
    return( -1 );
5969
0
  }
5970
0
  if( io_handle == NULL )
5971
0
  {
5972
0
    libcerror_error_set(
5973
0
     error,
5974
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5975
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5976
0
     "%s: invalid IO handle.",
5977
0
     function );
5978
5979
0
    return( -1 );
5980
0
  }
5981
0
  if( libcdata_array_get_number_of_entries(
5982
0
       record_entries_references_array,
5983
0
       &number_of_record_entries_references,
5984
0
       error ) != 1 )
5985
0
  {
5986
0
    libcerror_error_set(
5987
0
     error,
5988
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5989
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5990
0
     "%s: unable to retrieve number of record entries references.",
5991
0
     function );
5992
5993
0
    return( -1 );
5994
0
  }
5995
0
  if( number_of_record_entries_references > 0 )
5996
0
  {
5997
0
    if( libpff_table_resize_record_entries(
5998
0
         table,
5999
0
         1,
6000
0
         0,
6001
0
         io_handle->ascii_codepage,
6002
0
         error ) != 1 )
6003
0
    {
6004
0
      libcerror_error_set(
6005
0
       error,
6006
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6007
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
6008
0
       "%s: unable to resize record entries.",
6009
0
       function );
6010
6011
0
      return( -1 );
6012
0
    }
6013
0
    for( record_entries_reference_index = 0;
6014
0
         record_entries_reference_index < number_of_record_entries_references;
6015
0
         record_entries_reference_index++ )
6016
0
    {
6017
#if defined( HAVE_DEBUG_OUTPUT )
6018
      if( libcnotify_verbose != 0 )
6019
      {
6020
        libcnotify_printf(
6021
         "%s: record entries reference: %d\n",
6022
         function,
6023
         record_entries_reference_index );
6024
      }
6025
#endif
6026
0
      if( libcdata_array_get_entry_by_index(
6027
0
           record_entries_references_array,
6028
0
           record_entries_reference_index,
6029
0
           (intptr_t **) &reference_descriptor,
6030
0
           error ) != 1 )
6031
0
      {
6032
0
        libcerror_error_set(
6033
0
         error,
6034
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6035
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6036
0
         "%s: unable to retrieve record entries reference: %d.",
6037
0
         function,
6038
0
         record_entries_reference_index );
6039
6040
0
        return( -1 );
6041
0
      }
6042
0
      if( reference_descriptor == NULL )
6043
0
      {
6044
0
        libcerror_error_set(
6045
0
         error,
6046
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6047
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6048
0
         "%s: missing reference descriptor.",
6049
0
         function );
6050
6051
0
        return( -1 );
6052
0
      }
6053
0
      if( libpff_table_get_value_data_by_reference(
6054
0
           table,
6055
0
           io_handle,
6056
0
           file_io_handle,
6057
0
           reference_descriptor->value,
6058
0
           &record_entries_data,
6059
0
           &record_entries_data_size,
6060
0
           error ) != 1 )
6061
0
      {
6062
0
        libcerror_error_set(
6063
0
         error,
6064
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6065
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6066
0
         "%s: unable to retrieve record entries data.",
6067
0
         function );
6068
6069
0
        return( -1 );
6070
0
      }
6071
0
      if( ( record_entries_data == NULL )
6072
0
       || ( record_entries_data_size == 0 ) )
6073
0
      {
6074
0
        libcerror_error_set(
6075
0
         error,
6076
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6077
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6078
0
         "%s: missing record entries data.",
6079
0
         function );
6080
6081
0
        return( -1 );
6082
0
      }
6083
0
      if( ( record_entries_data_size % sizeof( pff_table_record_entry_8c_t ) ) != 0 )
6084
0
      {
6085
0
        libcerror_error_set(
6086
0
         error,
6087
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6088
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6089
0
         "%s: unsupported record entries data size.",
6090
0
         function );
6091
6092
0
        return( -1 );
6093
0
      }
6094
0
      number_of_record_entries = record_entries_data_size / sizeof( pff_table_record_entry_8c_t );
6095
6096
0
      if( number_of_record_entries > (size_t) INT_MAX )
6097
0
      {
6098
0
        libcerror_error_set(
6099
0
         error,
6100
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6101
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
6102
0
         "%s: number of record entries value exceeds maximum.",
6103
0
         function );
6104
6105
0
        return( -1 );
6106
0
      }
6107
0
      if( libpff_table_expand_record_entries(
6108
0
           table,
6109
0
           0,
6110
0
           (int) number_of_record_entries,
6111
0
           io_handle->ascii_codepage,
6112
0
           error ) != 1 )
6113
0
      {
6114
0
        libcerror_error_set(
6115
0
         error,
6116
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6117
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
6118
0
         "%s: unable to expand record entries.",
6119
0
         function );
6120
6121
0
        return( -1 );
6122
0
      }
6123
0
      while( record_entries_data_size > 0 )
6124
0
      {
6125
0
        if( libpff_table_get_record_entry_by_index(
6126
0
             table,
6127
0
             0,
6128
0
             record_entry_index,
6129
0
             (libpff_record_entry_t **) &record_entry,
6130
0
             error ) != 1 )
6131
0
        {
6132
0
          libcerror_error_set(
6133
0
           error,
6134
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6135
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6136
0
           "%s: unable to retrieve record entry with set index: 0 and entry index: %d.",
6137
0
           function,
6138
0
           record_entry_index );
6139
6140
0
          return( -1 );
6141
0
        }
6142
0
        if( record_entry == NULL )
6143
0
        {
6144
0
          libcerror_error_set(
6145
0
           error,
6146
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6147
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6148
0
           "%s: missing record entry with set index: 0 and entry index: %d.",
6149
0
           function,
6150
0
           record_entry_index );
6151
6152
0
          return( -1 );
6153
0
        }
6154
0
        record_entry->identifier.format = LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_SECURE4;
6155
6156
0
        byte_stream_copy_to_uint64_little_endian(
6157
0
         ( (pff_table_record_entry_8c_t *) record_entries_data )->identifier,
6158
0
         record_entry->identifier.secure4 );
6159
6160
/* TODO use a union for this value data ?  */
6161
0
        if( libpff_record_entry_set_value_data(
6162
0
             (libpff_record_entry_t *) record_entry,
6163
0
             ( (pff_table_record_entry_8c_t *) record_entries_data )->descriptor_identifier,
6164
0
             sizeof( uint32_t ),
6165
0
             error ) != 1 )
6166
0
        {
6167
0
          libcerror_error_set(
6168
0
           error,
6169
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6170
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6171
0
           "%s: unable to set value data in record entry.",
6172
0
           function );
6173
6174
0
          return( -1 );
6175
0
        }
6176
#if defined( HAVE_DEBUG_OUTPUT )
6177
        if( libcnotify_verbose != 0 )
6178
        {
6179
          libcnotify_printf(
6180
           "%s: table set: %03d entry: %03d identifier\t\t\t: 0x%" PRIx64 "\n",
6181
           function,
6182
           0,
6183
           record_entry_index,
6184
           record_entry->identifier.secure4 );
6185
6186
          byte_stream_copy_to_uint32_little_endian(
6187
           ( (pff_table_record_entry_8c_t *) record_entries_data )->descriptor_identifier,
6188
           value_32bit );
6189
          libcnotify_printf(
6190
           "%s: table set: %03d entry: %03d descriptor identifier\t: 0x%08" PRIx32 "\n",
6191
           function,
6192
           0,
6193
           record_entry_index,
6194
           value_32bit );
6195
6196
          libcnotify_printf(
6197
           "\n" );
6198
        }
6199
#endif
6200
0
        record_entries_data      += sizeof( pff_table_record_entry_8c_t );
6201
0
        record_entries_data_size -= sizeof( pff_table_record_entry_8c_t );
6202
6203
0
        record_entry_index++;
6204
0
      }
6205
0
    }
6206
0
  }
6207
0
  return( 1 );
6208
0
}
6209
6210
/* Reads the 9c table record entries and their values
6211
 * Returns 1 if successful or -1 on error
6212
 */
6213
int libpff_table_read_9c_record_entries(
6214
     libpff_table_t *table,
6215
     libcdata_array_t *record_entries_references_array,
6216
     libpff_io_handle_t *io_handle,
6217
     libbfio_handle_t *file_io_handle,
6218
     libcerror_error_t **error )
6219
0
{
6220
0
  libpff_reference_descriptor_t *reference_descriptor = NULL;
6221
0
  libpff_internal_record_entry_t *record_entry        = NULL;
6222
0
  uint8_t *record_entries_data                        = NULL;
6223
0
  static char *function                               = "libpff_table_read_9c_record_entries";
6224
0
  size_t number_of_record_entries                     = 0;
6225
0
  size_t record_entries_data_size                     = 0;
6226
0
  int number_of_record_entries_references             = 0;
6227
0
  int record_entries_reference_index                  = 0;
6228
0
  int record_entry_index                              = 0;
6229
6230
#if defined( HAVE_DEBUG_OUTPUT )
6231
  system_character_t guid_string[ 48 ];
6232
6233
  libfguid_identifier_t *guid                         = NULL;
6234
  uint32_t value_32bit                                = 0;
6235
  int result                                          = 0;
6236
#endif
6237
6238
0
  if( table == NULL )
6239
0
  {
6240
0
    libcerror_error_set(
6241
0
     error,
6242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6243
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6244
0
     "%s: invalid table.",
6245
0
     function );
6246
6247
0
    return( -1 );
6248
0
  }
6249
0
  if( io_handle == NULL )
6250
0
  {
6251
0
    libcerror_error_set(
6252
0
     error,
6253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6254
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6255
0
     "%s: invalid IO handle.",
6256
0
     function );
6257
6258
0
    return( -1 );
6259
0
  }
6260
0
  if( libcdata_array_get_number_of_entries(
6261
0
       record_entries_references_array,
6262
0
       &number_of_record_entries_references,
6263
0
       error ) != 1 )
6264
0
  {
6265
0
    libcerror_error_set(
6266
0
     error,
6267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6268
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6269
0
     "%s: unable to retrieve number of record entries references.",
6270
0
     function );
6271
6272
0
    goto on_error;
6273
0
  }
6274
0
  if( number_of_record_entries_references > 0 )
6275
0
  {
6276
0
    if( libpff_table_resize_record_entries(
6277
0
         table,
6278
0
         1,
6279
0
         0,
6280
0
         io_handle->ascii_codepage,
6281
0
         error ) != 1 )
6282
0
    {
6283
0
      libcerror_error_set(
6284
0
       error,
6285
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6286
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
6287
0
       "%s: unable to resize record entries.",
6288
0
       function );
6289
6290
0
      goto on_error;
6291
0
    }
6292
0
    for( record_entries_reference_index = 0;
6293
0
         record_entries_reference_index < number_of_record_entries_references;
6294
0
         record_entries_reference_index++ )
6295
0
    {
6296
#if defined( HAVE_DEBUG_OUTPUT )
6297
      if( libcnotify_verbose != 0 )
6298
      {
6299
        libcnotify_printf(
6300
         "%s: record entries reference: %d\n",
6301
         function,
6302
         record_entries_reference_index );
6303
      }
6304
#endif
6305
0
      if( libcdata_array_get_entry_by_index(
6306
0
           record_entries_references_array,
6307
0
           record_entries_reference_index,
6308
0
           (intptr_t **) &reference_descriptor,
6309
0
           error ) != 1 )
6310
0
      {
6311
0
        libcerror_error_set(
6312
0
         error,
6313
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6314
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6315
0
         "%s: unable to retrieve record entries reference: %d.",
6316
0
         function,
6317
0
         record_entries_reference_index );
6318
6319
0
        return( -1 );
6320
0
      }
6321
0
      if( reference_descriptor == NULL )
6322
0
      {
6323
0
        libcerror_error_set(
6324
0
         error,
6325
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6326
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6327
0
         "%s: missing reference descriptor.",
6328
0
         function );
6329
6330
0
        return( -1 );
6331
0
      }
6332
0
      if( libpff_table_get_value_data_by_reference(
6333
0
           table,
6334
0
           io_handle,
6335
0
           file_io_handle,
6336
0
           reference_descriptor->value,
6337
0
           &record_entries_data,
6338
0
           &record_entries_data_size,
6339
0
           error ) != 1 )
6340
0
      {
6341
0
        libcerror_error_set(
6342
0
         error,
6343
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6344
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6345
0
         "%s: unable to retrieve record entries data.",
6346
0
         function );
6347
6348
0
        return( -1 );
6349
0
      }
6350
0
      if( ( record_entries_data == NULL )
6351
0
       || ( record_entries_data_size == 0 ) )
6352
0
      {
6353
0
        libcerror_error_set(
6354
0
         error,
6355
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6356
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6357
0
         "%s: missing record entries data.",
6358
0
         function );
6359
6360
0
        return( -1 );
6361
0
      }
6362
0
      if( ( record_entries_data_size % sizeof( pff_table_record_entry_9c_t ) ) != 0 )
6363
0
      {
6364
0
        libcerror_error_set(
6365
0
         error,
6366
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6367
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6368
0
         "%s: unsupported record entries data size.",
6369
0
         function );
6370
6371
0
        goto on_error;
6372
0
      }
6373
0
      number_of_record_entries = record_entries_data_size / sizeof( pff_table_record_entry_9c_t );
6374
6375
0
      if( number_of_record_entries > (size_t) INT_MAX )
6376
0
      {
6377
0
        libcerror_error_set(
6378
0
         error,
6379
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6380
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
6381
0
         "%s: number of record entries value exceeds maximum.",
6382
0
         function );
6383
6384
0
        goto on_error;
6385
0
      }
6386
0
      if( libpff_table_expand_record_entries(
6387
0
           table,
6388
0
           0,
6389
0
           (int) number_of_record_entries,
6390
0
           io_handle->ascii_codepage,
6391
0
           error ) != 1 )
6392
0
      {
6393
0
        libcerror_error_set(
6394
0
         error,
6395
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6396
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
6397
0
         "%s: unable to expand record entries.",
6398
0
         function );
6399
6400
0
        goto on_error;
6401
0
      }
6402
0
      while( record_entries_data_size > 0 )
6403
0
      {
6404
0
        if( libpff_table_get_record_entry_by_index(
6405
0
             table,
6406
0
             0,
6407
0
             record_entry_index,
6408
0
             (libpff_record_entry_t **) &record_entry,
6409
0
             error ) != 1 )
6410
0
        {
6411
0
          libcerror_error_set(
6412
0
           error,
6413
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6414
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6415
0
           "%s: unable to retrieve record entry with set index: 0 and entry index: %d.",
6416
0
           function,
6417
0
           record_entry_index );
6418
6419
0
          goto on_error;
6420
0
        }
6421
0
        if( record_entry == NULL )
6422
0
        {
6423
0
          libcerror_error_set(
6424
0
           error,
6425
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6426
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6427
0
           "%s: missing record entry with set index: 0 and entry index: %d.",
6428
0
           function,
6429
0
           record_entry_index );
6430
6431
0
          goto on_error;
6432
0
        }
6433
0
        record_entry->identifier.format = LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_GUID;
6434
6435
0
        if( memory_copy(
6436
0
             record_entry->identifier.guid,
6437
0
             ( (pff_table_record_entry_9c_t *) record_entries_data )->record_entry_guid,
6438
0
             16 ) == NULL )
6439
0
        {
6440
0
          libcerror_error_set(
6441
0
           error,
6442
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
6443
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
6444
0
           "%s: unable to copy record entry identifier GUID.",
6445
0
           function );
6446
6447
0
          goto on_error;
6448
0
        }
6449
/* TODO use a union for this value data ?  */
6450
0
        if( libpff_record_entry_set_value_data(
6451
0
             (libpff_record_entry_t *) record_entry,
6452
0
             ( (pff_table_record_entry_9c_t *) record_entries_data )->descriptor_identifier,
6453
0
             sizeof( uint32_t ),
6454
0
             error ) != 1 )
6455
0
        {
6456
0
          libcerror_error_set(
6457
0
           error,
6458
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6459
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6460
0
           "%s: unable to set value data in record entry.",
6461
0
           function );
6462
6463
0
          goto on_error;
6464
0
        }
6465
#if defined( HAVE_DEBUG_OUTPUT )
6466
        if( libcnotify_verbose != 0 )
6467
        {
6468
          if( libfguid_identifier_initialize(
6469
               &guid,
6470
               error ) != 1 )
6471
          {
6472
            libcerror_error_set(
6473
             error,
6474
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6475
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6476
             "%s: unable to create GUID.",
6477
             function );
6478
6479
            goto on_error;
6480
          }
6481
          if( libfguid_identifier_copy_from_byte_stream(
6482
               guid,
6483
               record_entry->identifier.guid,
6484
               16,
6485
               LIBFGUID_ENDIAN_LITTLE,
6486
               error ) != 1 )
6487
          {
6488
            libcerror_error_set(
6489
             error,
6490
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6491
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
6492
             "%s: unable to copy byte stream to GUID.",
6493
             function );
6494
6495
            goto on_error;
6496
          }
6497
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
6498
          result = libfguid_identifier_copy_to_utf16_string(
6499
              guid,
6500
              (uint16_t *) guid_string,
6501
              48,
6502
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
6503
              error );
6504
#else
6505
          result = libfguid_identifier_copy_to_utf8_string(
6506
              guid,
6507
              (uint8_t *) guid_string,
6508
              48,
6509
              LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
6510
              error );
6511
#endif
6512
          if( result != 1 )
6513
          {
6514
            libcerror_error_set(
6515
             error,
6516
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6517
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
6518
             "%s: unable to copy GUID to string.",
6519
             function );
6520
6521
            goto on_error;
6522
          }
6523
          if( libfguid_identifier_free(
6524
               &guid,
6525
               error ) != 1 )
6526
          {
6527
            libcerror_error_set(
6528
             error,
6529
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
6530
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6531
             "%s: unable to free GUID.",
6532
             function );
6533
6534
            goto on_error;
6535
          }
6536
          libcnotify_printf(
6537
           "%s: table set: %03d entry: %03d record entry guid\t\t\t: %" PRIs_SYSTEM "\n",
6538
           function,
6539
           0,
6540
           record_entry_index,
6541
           guid_string );
6542
6543
          byte_stream_copy_to_uint32_little_endian(
6544
           ( (pff_table_record_entry_9c_t *) record_entries_data )->descriptor_identifier,
6545
           value_32bit );
6546
6547
          libcnotify_printf(
6548
           "%s: table set: %03d entry: %03d record entry descriptor identifier\t: 0x%08" PRIx32 "\n",
6549
           function,
6550
           0,
6551
           record_entry_index,
6552
           value_32bit );
6553
6554
          libcnotify_printf(
6555
           "\n" );
6556
        }
6557
#endif
6558
0
        record_entries_data      += sizeof( pff_table_record_entry_9c_t );
6559
0
        record_entries_data_size -= sizeof( pff_table_record_entry_9c_t );
6560
6561
0
        record_entry_index++;
6562
0
      }
6563
0
    }
6564
0
  }
6565
0
  return( 1 );
6566
6567
0
on_error:
6568
#if defined( HAVE_DEBUG_OUTPUT )
6569
  if( guid != NULL )
6570
  {
6571
    libfguid_identifier_free(
6572
     &guid,
6573
     NULL );
6574
  }
6575
#endif
6576
0
  return( -1 );
6577
0
}
6578
6579
/* Reads the a5 table record entry values
6580
 * Returns 1 if successful or -1 on error
6581
 */
6582
int libpff_table_read_a5_record_entries(
6583
     libpff_table_t *table,
6584
     uint32_t record_entries_reference,
6585
     libpff_io_handle_t *io_handle,
6586
     libbfio_handle_t *file_io_handle,
6587
     libcerror_error_t **error )
6588
32
{
6589
32
  libpff_internal_record_entry_t *record_entry  = NULL;
6590
32
  libpff_record_set_t *record_set               = NULL;
6591
32
  libpff_table_block_index_t *table_block_index = NULL;
6592
32
  libpff_table_index_value_t *table_index_value = NULL;
6593
32
  uint8_t *table_value_data                     = NULL;
6594
32
  static char *function                         = "libpff_table_read_a5_record_entries";
6595
32
  size_t table_value_data_size                  = 0;
6596
32
        uint16_t number_of_table_index_values         = 0;
6597
32
  uint16_t table_index_value_iterator           = 0;
6598
32
  int number_of_entries                         = 0;
6599
32
  int number_of_sets                            = 0;
6600
32
  int number_of_table_index_array_entries       = 0;
6601
32
  int table_index_array_entries_iterator        = 0;
6602
6603
32
  if( table == NULL )
6604
0
  {
6605
0
    libcerror_error_set(
6606
0
     error,
6607
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6608
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6609
0
     "%s: invalid table.",
6610
0
     function );
6611
6612
0
    return( -1 );
6613
0
  }
6614
  /* Check if the table contains any entries
6615
   */
6616
32
  if( record_entries_reference == 0 )
6617
0
  {
6618
#if defined( HAVE_DEBUG_OUTPUT )
6619
    if( libcnotify_verbose != 0 )
6620
    {
6621
      libcnotify_printf(
6622
       "%s: table contains no entries.\n",
6623
       function );
6624
    }
6625
#endif
6626
0
    return( 1 );
6627
0
  }
6628
32
  if( ( record_entries_reference & 0x0000001fUL ) != 0 )
6629
0
  {
6630
0
    libcerror_error_set(
6631
0
     error,
6632
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6633
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6634
0
     "%s: unsupported record entries reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
6635
0
     function,
6636
0
     record_entries_reference & 0x0000001fUL,
6637
0
     record_entries_reference );
6638
6639
0
    return( -1 );
6640
0
  }
6641
32
  if( io_handle == NULL )
6642
0
  {
6643
0
    libcerror_error_set(
6644
0
     error,
6645
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6646
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6647
0
     "%s: invalid IO handle.",
6648
0
     function );
6649
6650
0
    return( -1 );
6651
0
  }
6652
32
  if( libcdata_array_get_number_of_entries(
6653
32
       table->record_sets_array,
6654
32
       &number_of_sets,
6655
32
       error ) != 1 )
6656
0
  {
6657
0
    libcerror_error_set(
6658
0
     error,
6659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6660
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6661
0
     "%s: unable to retrieve number of sets.",
6662
0
     function );
6663
6664
0
    return( -1 );
6665
0
  }
6666
32
  if( number_of_sets > 0 )
6667
0
  {
6668
0
    if( libcdata_array_get_entry_by_index(
6669
0
         table->record_sets_array,
6670
0
         0,
6671
0
         (intptr_t **) &record_set,
6672
0
         error ) != 1 )
6673
0
    {
6674
0
      libcerror_error_set(
6675
0
       error,
6676
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6677
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6678
0
       "%s: unable to retrieve record set: 0.",
6679
0
       function );
6680
6681
0
      return( -1 );
6682
0
    }
6683
0
    if( libpff_record_set_get_number_of_entries(
6684
0
         record_set,
6685
0
         &number_of_entries,
6686
0
         error ) != 1 )
6687
0
    {
6688
0
      libcerror_error_set(
6689
0
       error,
6690
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6691
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6692
0
       "%s: unable to retrieve number of entries of set: 0.",
6693
0
       function );
6694
6695
0
      return( -1 );
6696
0
    }
6697
0
  }
6698
32
  if( libcdata_array_get_number_of_entries(
6699
32
       table->index_array,
6700
32
       &number_of_table_index_array_entries,
6701
32
       error ) != 1 )
6702
0
  {
6703
0
    libcerror_error_set(
6704
0
     error,
6705
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6706
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6707
0
     "%s: unable to retrieve number of table index array entries.",
6708
0
     function );
6709
6710
0
    return( -1 );
6711
0
  }
6712
32
  for( table_index_array_entries_iterator = 0;
6713
67
       table_index_array_entries_iterator < number_of_table_index_array_entries;
6714
35
       table_index_array_entries_iterator++ )
6715
35
  {
6716
35
    if( libcdata_array_get_entry_by_index(
6717
35
         table->index_array,
6718
35
         table_index_array_entries_iterator,
6719
35
         (intptr_t **) &table_block_index,
6720
35
         error ) != 1 )
6721
0
    {
6722
0
      libcerror_error_set(
6723
0
       error,
6724
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6725
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6726
0
       "%s: unable to retrieve table block index: %" PRIu16 ".",
6727
0
       function,
6728
0
       table_index_array_entries_iterator );
6729
6730
0
      return( -1 );
6731
0
    }
6732
35
    if( libpff_table_block_index_get_number_of_values(
6733
35
         table_block_index,
6734
35
         &number_of_table_index_values,
6735
35
         error ) != 1 )
6736
0
    {
6737
0
      libcerror_error_set(
6738
0
       error,
6739
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6740
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6741
0
       "%s: unable to retrieve number of table block index values.",
6742
0
       function );
6743
6744
0
      return( -1 );
6745
0
    }
6746
35
    if( ( number_of_table_index_array_entries > number_of_sets )
6747
35
     || ( number_of_table_index_values > number_of_entries ) )
6748
35
    {
6749
35
      if( libpff_table_resize_record_entries(
6750
35
           table,
6751
35
           number_of_table_index_array_entries,
6752
35
           number_of_table_index_values,
6753
35
           io_handle->ascii_codepage,
6754
35
           error ) != 1 )
6755
0
      {
6756
0
        libcerror_error_set(
6757
0
         error,
6758
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6759
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
6760
0
         "%s: unable to resize record entries.",
6761
0
         function );
6762
6763
0
        return( -1 );
6764
0
      }
6765
35
    }
6766
35
    for( table_index_value_iterator = 0;
6767
1.97k
         table_index_value_iterator < number_of_table_index_values;
6768
1.93k
         table_index_value_iterator++ )
6769
1.93k
    {
6770
1.93k
      if( libpff_table_get_record_entry_by_index(
6771
1.93k
           table,
6772
1.93k
           table_index_array_entries_iterator,
6773
1.93k
           table_index_value_iterator,
6774
1.93k
           (libpff_record_entry_t **) &record_entry,
6775
1.93k
           error ) != 1 )
6776
0
      {
6777
0
        libcerror_error_set(
6778
0
         error,
6779
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6780
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6781
0
         "%s: unable to retrieve record entry with set index: %d and entry index: %" PRIu16 ".",
6782
0
         function,
6783
0
         table_index_array_entries_iterator,
6784
0
         table_index_value_iterator );
6785
6786
0
        return( -1 );
6787
0
      }
6788
1.93k
      if( record_entry == NULL )
6789
0
      {
6790
0
        libcerror_error_set(
6791
0
         error,
6792
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6793
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6794
0
         "%s: missing record entry with set index: %d and entry index: %" PRIu16 ".",
6795
0
         function,
6796
0
         table_index_array_entries_iterator,
6797
0
         table_index_value_iterator );
6798
6799
0
        return( -1 );
6800
0
      }
6801
1.93k
      if( libpff_table_block_index_get_value_by_index(
6802
1.93k
           table_block_index,
6803
1.93k
           table_index_value_iterator,
6804
1.93k
           &table_index_value,
6805
1.93k
           error ) != 1 )
6806
0
      {
6807
0
        libcerror_error_set(
6808
0
         error,
6809
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6810
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6811
0
         "%s: unable to retrieve table block index value: %" PRIu16 ".",
6812
0
         function,
6813
0
         table_index_value_iterator );
6814
6815
0
        return( -1 );
6816
0
      }
6817
1.93k
      if( table_index_value == NULL )
6818
0
      {
6819
0
        libcerror_error_set(
6820
0
         error,
6821
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6822
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6823
0
         "%s: missing table index value.",
6824
0
         function );
6825
6826
0
        return( -1 );
6827
0
      }
6828
#if defined( HAVE_DEBUG_OUTPUT )
6829
      if( libcnotify_verbose != 0 )
6830
      {
6831
        libcnotify_printf(
6832
         "%s: table set: %03" PRIu32 " entry: %03" PRIu16 " value at offset: %" PRIu32 " with size: %" PRIu16 ".\n",
6833
         function,
6834
         table_index_array_entries_iterator,
6835
         table_index_value_iterator,
6836
         table_index_value->offset,
6837
         table_index_value->size );
6838
      }
6839
#endif
6840
1.93k
      if( libpff_table_get_value_data_by_index_value(
6841
1.93k
           table,
6842
1.93k
           table_index_value,
6843
1.93k
           file_io_handle,
6844
1.93k
           &table_value_data,
6845
1.93k
           &table_value_data_size,
6846
1.93k
           error ) != 1 )
6847
0
      {
6848
0
        libcerror_error_set(
6849
0
         error,
6850
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6851
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6852
0
         "%s: unable to retrieve table value data by index value: %" PRIu16 ".",
6853
0
         function,
6854
0
         table_index_value_iterator );
6855
6856
0
        return( -1 );
6857
0
      }
6858
1.93k
      if( libpff_record_entry_set_value_data(
6859
1.93k
           (libpff_record_entry_t *) record_entry,
6860
1.93k
           table_value_data,
6861
1.93k
           table_value_data_size,
6862
1.93k
           error ) != 1 )
6863
0
      {
6864
0
        libcerror_error_set(
6865
0
         error,
6866
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6867
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6868
0
         "%s: unable to set value data in record entry.",
6869
0
         function );
6870
6871
0
        return( -1 );
6872
0
      }
6873
1.93k
    }
6874
35
  }
6875
#if defined( HAVE_DEBUG_OUTPUT )
6876
  if( libcnotify_verbose != 0 )
6877
  {
6878
    libcnotify_printf(
6879
     "\n" );
6880
  }
6881
#endif
6882
32
  return( 1 );
6883
32
}
6884
6885
/* Reads the ac table column definitions
6886
 * Returns 1 if successful or -1 on error
6887
 */
6888
int libpff_table_read_ac_column_definitions(
6889
     libpff_table_t *table,
6890
     libcdata_array_t *column_definitions_array,
6891
     uint32_t column_definitions_reference,
6892
     int number_of_column_definitions,
6893
     libpff_io_handle_t *io_handle,
6894
     libbfio_handle_t *file_io_handle,
6895
     libpff_offsets_index_t *offsets_index,
6896
     libcdata_list_t *name_to_id_map_list,
6897
     libcerror_error_t **error )
6898
0
{
6899
0
  libfcache_cache_t *column_definitions_data_cache         = NULL;
6900
0
  libfdata_list_t *column_definitions_data_list            = NULL;
6901
0
  libpff_column_definition_t *column_definition            = NULL;
6902
0
  libpff_column_definition_t *lookup_column_definition     = NULL;
6903
0
  libpff_data_block_t *column_definition_data_block        = NULL;
6904
0
  libpff_data_block_t *column_definitions_data_block       = NULL;
6905
0
  libpff_local_descriptor_value_t *local_descriptor_value  = NULL;
6906
0
  pff_table_column_definition_ac_t *column_definition_data = NULL;
6907
0
  static char *function                                    = "libpff_table_read_ac_column_definitions";
6908
0
  size_t column_definition_data_offset                     = 0;
6909
0
  size_t column_definition_data_size                       = 0;
6910
0
  off64_t column_definition_data_block_offset              = 0;
6911
0
  uint32_t record_entry_values_table_descriptor            = 0;
6912
0
  uint16_t column_definition_number                        = 0;
6913
0
  int column_definition_index                              = 0;
6914
0
  int element_index                                        = 0;
6915
0
  int result                                               = 0;
6916
6917
0
  if( table == NULL )
6918
0
  {
6919
0
    libcerror_error_set(
6920
0
     error,
6921
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6922
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6923
0
     "%s: invalid table.",
6924
0
     function );
6925
6926
0
    return( -1 );
6927
0
  }
6928
0
  if( column_definitions_array == NULL )
6929
0
  {
6930
0
    libcerror_error_set(
6931
0
     error,
6932
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6933
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6934
0
     "%s: invalid column definitions array.",
6935
0
     function );
6936
6937
0
    return( -1 );
6938
0
  }
6939
0
  if( number_of_column_definitions == 0 )
6940
0
  {
6941
#if defined( HAVE_DEBUG_OUTPUT )
6942
    if( libcnotify_verbose != 0 )
6943
    {
6944
      libcnotify_printf(
6945
       "%s: table contains no column definitions.\n",
6946
       function );
6947
    }
6948
#endif
6949
0
    return( 1 );
6950
0
  }
6951
  /* Read the column definitions
6952
   */
6953
0
  result = libpff_local_descriptors_tree_get_value_by_identifier(
6954
0
      table->local_descriptors_tree,
6955
0
      file_io_handle,
6956
0
      column_definitions_reference,
6957
0
      &local_descriptor_value,
6958
0
            error );
6959
6960
0
  if( result == -1 )
6961
0
  {
6962
0
    libcerror_error_set(
6963
0
     error,
6964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6965
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6966
0
     "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
6967
0
     function,
6968
0
     column_definitions_reference );
6969
6970
0
    goto on_error;
6971
0
  }
6972
0
  else if( result == 0 )
6973
0
  {
6974
0
    libcerror_error_set(
6975
0
     error,
6976
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6977
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6978
0
     "%s: missing column definitions descriptor: 0x%08" PRIx32 " (%" PRIu32 ").",
6979
0
     function,
6980
0
     column_definitions_reference,
6981
0
     column_definitions_reference );
6982
6983
0
    goto on_error;
6984
0
  }
6985
0
  if( local_descriptor_value == NULL )
6986
0
  {
6987
0
    libcerror_error_set(
6988
0
     error,
6989
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6990
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6991
0
     "%s: invalid column definitions descriptor: 0x%08" PRIx32 " (%" PRIu32 ") local descriptor value.",
6992
0
     function,
6993
0
     column_definitions_reference,
6994
0
     column_definitions_reference );
6995
6996
0
    goto on_error;
6997
0
  }
6998
#if defined( HAVE_DEBUG_OUTPUT )
6999
  if( libcnotify_verbose != 0 )
7000
  {
7001
    libcnotify_printf(
7002
     "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
7003
     function,
7004
     local_descriptor_value->identifier,
7005
     libpff_debug_get_node_identifier_type(
7006
      (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
7007
     local_descriptor_value->data_identifier,
7008
     local_descriptor_value->local_descriptors_identifier );
7009
  }
7010
#endif
7011
/* TODO handle multiple recovered offset index values */
7012
0
  if( libpff_table_read_descriptor_data_list(
7013
0
       table,
7014
0
       io_handle,
7015
0
       file_io_handle,
7016
0
       offsets_index,
7017
0
       column_definitions_reference,
7018
0
       local_descriptor_value->data_identifier,
7019
0
       table->recovered,
7020
0
       0,
7021
0
       &column_definitions_data_list,
7022
0
       &column_definitions_data_cache,
7023
0
       error ) != 1 )
7024
0
  {
7025
0
    libcerror_error_set(
7026
0
     error,
7027
0
     LIBCERROR_ERROR_DOMAIN_IO,
7028
0
     LIBCERROR_IO_ERROR_READ_FAILED,
7029
0
     "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
7030
0
     function,
7031
0
     column_definitions_reference,
7032
0
     local_descriptor_value->data_identifier );
7033
7034
0
    goto on_error;
7035
0
  }
7036
0
  if( libpff_local_descriptor_value_free(
7037
0
       &local_descriptor_value,
7038
0
       error ) != 1 )
7039
0
  {
7040
0
    libcerror_error_set(
7041
0
     error,
7042
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7043
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7044
0
     "%s: unable to free column definitions descriptor: 0x%08" PRIx32 " (%" PRIu32 ") local descriptor value.",
7045
0
     function,
7046
0
     column_definitions_reference,
7047
0
     column_definitions_reference );
7048
7049
0
    goto on_error;
7050
0
  }
7051
  /* Retrieve the corresponding column definitions data reference segment
7052
   */
7053
0
  if( libfdata_list_get_element_value_by_index(
7054
0
       column_definitions_data_list,
7055
0
       (intptr_t *) file_io_handle,
7056
0
       (libfdata_cache_t *) column_definitions_data_cache,
7057
0
       0,
7058
0
       (intptr_t **) &column_definitions_data_block,
7059
0
       0,
7060
0
       error ) != 1 )
7061
0
  {
7062
0
    libcerror_error_set(
7063
0
     error,
7064
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7065
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7066
0
     "%s: unable to retrieve column definitions data block: 0.",
7067
0
     function );
7068
7069
0
    goto on_error;
7070
0
  }
7071
0
  if( column_definitions_data_block == NULL )
7072
0
  {
7073
0
    libcerror_error_set(
7074
0
     error,
7075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7076
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7077
0
     "%s: missing column definitions data block: 0.",
7078
0
     function );
7079
7080
0
    goto on_error;
7081
0
  }
7082
0
  if( column_definitions_data_block->data == NULL )
7083
0
  {
7084
0
    libcerror_error_set(
7085
0
     error,
7086
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7087
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7088
0
     "%s: invalid column definitions data block: 0 - missing data.",
7089
0
     function );
7090
7091
0
    goto on_error;
7092
0
  }
7093
#if defined( HAVE_DEBUG_OUTPUT )
7094
  if( libcnotify_verbose != 0 )
7095
  {
7096
    libcnotify_printf(
7097
     "%s: ac column definitions:\n",
7098
     function );
7099
    libcnotify_print_data(
7100
     column_definitions_data_block->data,
7101
     column_definitions_data_block->uncompressed_data_size,
7102
     0 );
7103
  }
7104
#endif
7105
0
  column_definition_data_size = (size_t) number_of_column_definitions * sizeof( pff_table_column_definition_ac_t );
7106
7107
0
  if( column_definition_data_size != (size_t) column_definitions_data_block->uncompressed_data_size )
7108
0
  {
7109
0
    libcerror_error_set(
7110
0
     error,
7111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7112
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
7113
0
     "%s: mismatch in number of column definitions and the data size.",
7114
0
     function );
7115
7116
0
    goto on_error;
7117
0
  }
7118
0
  if( libcdata_array_resize(
7119
0
       column_definitions_array,
7120
0
       number_of_column_definitions,
7121
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
7122
0
       error ) != 1 )
7123
0
  {
7124
0
    libcerror_error_set(
7125
0
     error,
7126
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7127
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
7128
0
     "%s: unable to resize column definition array.",
7129
0
     function );
7130
7131
0
    goto on_error;
7132
0
  }
7133
0
  column_definition_data_offset = 0;
7134
7135
0
  for( column_definition_index = 0;
7136
0
       column_definition_index < number_of_column_definitions;
7137
0
       column_definition_index++ )
7138
0
  {
7139
0
    if( libpff_column_definition_initialize(
7140
0
         &column_definition,
7141
0
         error ) != 1 )
7142
0
    {
7143
0
      libcerror_error_set(
7144
0
       error,
7145
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7146
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
7147
0
       "%s: unable to create column definition.",
7148
0
       function );
7149
7150
0
      goto on_error;
7151
0
    }
7152
0
    if( libfdata_list_get_element_value_at_offset(
7153
0
         column_definitions_data_list,
7154
0
         (intptr_t *) file_io_handle,
7155
0
         (libfdata_cache_t *) column_definitions_data_cache,
7156
0
         (off64_t) column_definition_data_offset,
7157
0
         &element_index,
7158
0
         &column_definition_data_block_offset,
7159
0
         (intptr_t **) &column_definition_data_block,
7160
0
         0,
7161
0
         error ) != 1 )
7162
0
    {
7163
0
      libcerror_error_set(
7164
0
       error,
7165
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7166
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7167
0
       "%s: unable to retrieve column definition data block at offset: %" PRIzd ".",
7168
0
       function,
7169
0
       column_definition_data_offset );
7170
7171
0
      goto on_error;
7172
0
    }
7173
0
    if( column_definition_data_block == NULL )
7174
0
    {
7175
0
      libcerror_error_set(
7176
0
       error,
7177
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7178
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7179
0
       "%s: missing column definition data block at offset: %" PRIzd ".",
7180
0
       function,
7181
0
       column_definition_data_offset );
7182
7183
0
      goto on_error;
7184
0
    }
7185
0
    if( column_definition_data_block->data == NULL )
7186
0
    {
7187
0
      libcerror_error_set(
7188
0
       error,
7189
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7190
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7191
0
       "%s: invalid column definition data block at offset: %" PRIzd " - missing data.",
7192
0
       function,
7193
0
       column_definition_data_offset );
7194
7195
0
      goto on_error;
7196
0
    }
7197
0
    if( column_definition_data_block_offset > column_definition_data_block->uncompressed_data_size )
7198
0
    {
7199
0
      libcerror_error_set(
7200
0
       error,
7201
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7202
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
7203
0
       "%s: invalid column definitions data block offset value out of bounds.",
7204
0
       function );
7205
7206
0
      goto on_error;
7207
0
    }
7208
0
    if( column_definition_data_block->uncompressed_data_size < sizeof( pff_table_column_definition_ac_t ) )
7209
0
    {
7210
0
      libcerror_error_set(
7211
0
       error,
7212
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7213
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
7214
0
       "%s: invalid column definitions data size value out of bounds.",
7215
0
       function );
7216
7217
0
      goto on_error;
7218
0
    }
7219
0
    column_definition_data = (pff_table_column_definition_ac_t *) &( column_definition_data_block->data[ column_definition_data_block_offset ] );
7220
7221
0
    byte_stream_copy_to_uint16_little_endian(
7222
0
     column_definition_data->record_entry_type,
7223
0
     column_definition->entry_type );
7224
7225
0
    byte_stream_copy_to_uint16_little_endian(
7226
0
     column_definition_data->record_entry_value_type,
7227
0
     column_definition->value_type );
7228
7229
0
    byte_stream_copy_to_uint16_little_endian(
7230
0
     column_definition_data->values_array_offset,
7231
0
     column_definition->values_array_offset );
7232
7233
0
    byte_stream_copy_to_uint16_little_endian(
7234
0
     column_definition_data->values_array_size,
7235
0
     column_definition->values_array_size );
7236
7237
0
    byte_stream_copy_to_uint16_little_endian(
7238
0
     column_definition_data->values_array_number,
7239
0
     column_definition_number );
7240
7241
0
    byte_stream_copy_to_uint32_little_endian(
7242
0
     column_definition_data->record_entry_values_table_descriptor,
7243
0
     record_entry_values_table_descriptor );
7244
7245
#if defined( HAVE_DEBUG_OUTPUT )
7246
    if( libcnotify_verbose != 0 )
7247
    {
7248
      libcnotify_printf(
7249
       "%s: column definition: %03d record entry type\t\t\t: 0x%04" PRIx16 "",
7250
       function,
7251
       column_definition_index,
7252
       column_definition->entry_type );
7253
    }
7254
#endif
7255
0
    if( ( column_definition->entry_type >= 0x8000 )
7256
0
     || ( column_definition->entry_type <= 0xfffe ) )
7257
0
    {
7258
0
      result = libpff_name_to_id_map_entry_get_entry_by_identifier(
7259
0
                name_to_id_map_list,
7260
0
                (uint32_t) column_definition->entry_type,
7261
0
                &( column_definition->name_to_id_map_entry ),
7262
0
                error );
7263
7264
0
      if( result == -1 )
7265
0
      {
7266
0
        libcerror_error_set(
7267
0
         error,
7268
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7269
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7270
0
         "%s: unable to retrieve name to id map entry: %" PRIu16 ".",
7271
0
         function,
7272
0
         column_definition->entry_type );
7273
7274
0
        goto on_error;
7275
0
      }
7276
0
    }
7277
#if defined( HAVE_DEBUG_OUTPUT )
7278
    if( libcnotify_verbose != 0 )
7279
    {
7280
      if( column_definition->name_to_id_map_entry != NULL )
7281
      {
7282
        if( column_definition->name_to_id_map_entry->type == LIBPFF_NAME_TO_ID_MAP_ENTRY_TYPE_STRING )
7283
        {
7284
          libcnotify_printf(
7285
           " maps to: %s (%s : %s)\n",
7286
           (char *) column_definition->name_to_id_map_entry->debug_string,
7287
           libfmapi_named_property_type_get_identifier(
7288
            column_definition->name_to_id_map_entry->guid,
7289
            (char *) column_definition->name_to_id_map_entry->debug_string,
7290
            column_definition->name_to_id_map_entry->value_size,
7291
            column_definition->value_type ),
7292
           libfmapi_named_property_type_get_description(
7293
            column_definition->name_to_id_map_entry->guid,
7294
            (char *) column_definition->name_to_id_map_entry->debug_string,
7295
            column_definition->name_to_id_map_entry->value_size,
7296
            column_definition->value_type ) );
7297
        }
7298
        else
7299
        {
7300
          libcnotify_printf(
7301
           " maps to: 0x%04" PRIx32 " (%s : %s)\n",
7302
           column_definition->name_to_id_map_entry->numeric_value,
7303
           libfmapi_property_type_get_identifier(
7304
            column_definition->name_to_id_map_entry->guid,
7305
            column_definition->name_to_id_map_entry->numeric_value,
7306
            column_definition->value_type ),
7307
           libfmapi_property_type_get_description(
7308
            column_definition->name_to_id_map_entry->guid,
7309
            column_definition->name_to_id_map_entry->numeric_value,
7310
            column_definition->value_type ) );
7311
        }
7312
      }
7313
      else
7314
      {
7315
        libcnotify_printf(
7316
         " (%s : %s)\n",
7317
         libfmapi_property_type_get_identifier(
7318
          NULL,
7319
          column_definition->entry_type,
7320
          column_definition->value_type ),
7321
         libfmapi_property_type_get_description(
7322
          NULL,
7323
          column_definition->entry_type,
7324
          column_definition->value_type ) );
7325
      }
7326
      libcnotify_printf(
7327
       "%s: column definition: %03d record entry value type\t\t: 0x%04" PRIx16 " (%s : %s)\n",
7328
       function,
7329
       column_definition_index,
7330
       column_definition->value_type,
7331
       libfmapi_value_type_get_identifier(
7332
        column_definition->value_type ),
7333
       libfmapi_value_type_get_description(
7334
        column_definition->value_type ) );
7335
7336
      libcnotify_printf(
7337
       "%s: column definition: %03d values array offset\t\t: %" PRIu16 "\n",
7338
       function,
7339
       column_definition_index,
7340
       column_definition->values_array_offset );
7341
7342
      libcnotify_printf(
7343
       "%s: column definition: %03d values array size\t\t: %" PRIu16 "\n",
7344
       function,
7345
       column_definition_index,
7346
       column_definition->values_array_size );
7347
7348
      libcnotify_printf(
7349
       "%s: column definition: %03d values array number\t\t: %" PRIu16 "\n",
7350
       function,
7351
       column_definition_index,
7352
       column_definition_number );
7353
7354
      libcnotify_printf(
7355
       "%s: padding1:\n",
7356
       function );
7357
      libcnotify_print_data(
7358
       column_definition_data->padding1,
7359
       2,
7360
       0 );
7361
7362
      libcnotify_printf(
7363
       "%s: column definition: %03d record entry values table descriptor\t: %" PRIu32 "\n",
7364
       function,
7365
       column_definition_index,
7366
       record_entry_values_table_descriptor );
7367
7368
      libcnotify_printf(
7369
       "\n" );
7370
    }
7371
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
7372
7373
    /* Read the record entry values table if necessary
7374
     */
7375
0
    if( record_entry_values_table_descriptor > 0 )
7376
0
    {
7377
0
      result = libpff_local_descriptors_tree_get_value_by_identifier(
7378
0
          table->local_descriptors_tree,
7379
0
          file_io_handle,
7380
0
          record_entry_values_table_descriptor,
7381
0
          &local_descriptor_value,
7382
0
          error );
7383
7384
0
      if( result == -1 )
7385
0
      {
7386
0
        libcerror_error_set(
7387
0
         error,
7388
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7389
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7390
0
         "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
7391
0
         function,
7392
0
         record_entry_values_table_descriptor );
7393
7394
0
        goto on_error;
7395
0
      }
7396
0
      else if( result == 0 )
7397
0
      {
7398
0
        libcerror_error_set(
7399
0
         error,
7400
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7401
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7402
0
         "%s: missing local descriptor identifier: %" PRIu32 ".",
7403
0
         function,
7404
0
         record_entry_values_table_descriptor );
7405
7406
0
        goto on_error;
7407
0
      }
7408
0
      if( local_descriptor_value == NULL )
7409
0
      {
7410
0
        libcerror_error_set(
7411
0
         error,
7412
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7413
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7414
0
         "%s: invalid local descriptor value.",
7415
0
         function );
7416
7417
0
        goto on_error;
7418
0
      }
7419
#if defined( HAVE_DEBUG_OUTPUT )
7420
      if( libcnotify_verbose != 0 )
7421
      {
7422
        libcnotify_printf(
7423
         "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
7424
         function,
7425
         local_descriptor_value->identifier,
7426
         libpff_debug_get_node_identifier_type(
7427
          (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
7428
         local_descriptor_value->data_identifier,
7429
         local_descriptor_value->local_descriptors_identifier );
7430
      }
7431
#endif
7432
0
      if( local_descriptor_value->data_identifier == 0 )
7433
0
      {
7434
0
        libcerror_error_set(
7435
0
         error,
7436
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7437
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7438
0
         "%s: invalid local descriptor identifier: %" PRIu32 " - missing data identifier.",
7439
0
         function,
7440
0
         record_entry_values_table_descriptor );
7441
7442
0
        goto on_error;
7443
0
      }
7444
0
      if( libpff_table_initialize(
7445
0
           &( column_definition->record_entry_values_table ),
7446
0
           record_entry_values_table_descriptor,
7447
0
           local_descriptor_value->data_identifier,
7448
0
           local_descriptor_value->local_descriptors_identifier,
7449
0
           table->recovered,
7450
0
           error ) != 1 )
7451
0
      {
7452
0
        libcerror_error_set(
7453
0
         error,
7454
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7455
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
7456
0
         "%s: unable to create record entry values table.",
7457
0
         function );
7458
7459
0
        goto on_error;
7460
0
      }
7461
0
      if( libpff_local_descriptor_value_free(
7462
0
           &local_descriptor_value,
7463
0
           error ) != 1 )
7464
0
      {
7465
0
        libcerror_error_set(
7466
0
         error,
7467
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7468
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7469
0
         "%s: unable to free local descriptor values.",
7470
0
         function );
7471
7472
0
        goto on_error;
7473
0
      }
7474
0
      if( libpff_table_read(
7475
0
           column_definition->record_entry_values_table,
7476
0
           io_handle,
7477
0
           file_io_handle,
7478
0
           offsets_index,
7479
0
           name_to_id_map_list,
7480
0
           LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
7481
0
           error ) != 1 )
7482
0
      {
7483
0
        libcerror_error_set(
7484
0
         error,
7485
0
         LIBCERROR_ERROR_DOMAIN_IO,
7486
0
         LIBCERROR_IO_ERROR_READ_FAILED,
7487
0
         "%s: unable to read record entry values table.",
7488
0
         function );
7489
7490
0
        goto on_error;
7491
0
      }
7492
0
    }
7493
0
    if( libcdata_array_get_entry_by_index(
7494
0
         column_definitions_array,
7495
0
         (int) column_definition_number,
7496
0
         (intptr_t **) &lookup_column_definition,
7497
0
         error ) != 1 )
7498
0
    {
7499
0
      libcerror_error_set(
7500
0
       error,
7501
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7502
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7503
0
       "%s: unable to retrieve column definitions: %" PRIu8 " in array.",
7504
0
       function,
7505
0
       column_definition_number );
7506
7507
0
      goto on_error;
7508
0
    }
7509
0
    if( lookup_column_definition != NULL )
7510
0
    {
7511
0
      libcerror_error_set(
7512
0
       error,
7513
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7514
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7515
0
       "%s: column definitions: %" PRIu8 " already set in array.",
7516
0
       function,
7517
0
       column_definition_number );
7518
7519
0
      goto on_error;
7520
0
    }
7521
0
    if( libcdata_array_set_entry_by_index(
7522
0
         column_definitions_array,
7523
0
         (int) column_definition_number,
7524
0
         (intptr_t *) column_definition,
7525
0
         error ) != 1 )
7526
0
    {
7527
0
      libcerror_error_set(
7528
0
       error,
7529
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7530
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7531
0
       "%s: unable to set column definition: %" PRIu16 " in array.",
7532
0
       function,
7533
0
       column_definition_number );
7534
7535
0
      goto on_error;
7536
0
    }
7537
0
    column_definition = NULL;
7538
7539
0
    column_definition_data_offset += sizeof( pff_table_column_definition_ac_t );
7540
0
  }
7541
0
  if( libfcache_cache_free(
7542
0
       &column_definitions_data_cache,
7543
0
       error ) != 1 )
7544
0
  {
7545
0
    libcerror_error_set(
7546
0
     error,
7547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7548
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7549
0
     "%s: unable to free column definitions data cache.",
7550
0
     function );
7551
7552
0
    goto on_error;
7553
0
  }
7554
0
  if( libfdata_list_free(
7555
0
       &column_definitions_data_list,
7556
0
       error ) != 1 )
7557
0
  {
7558
0
    libcerror_error_set(
7559
0
     error,
7560
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7561
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7562
0
     "%s: unable to free column definitions data list.",
7563
0
     function );
7564
7565
0
    goto on_error;
7566
0
  }
7567
0
  return( 1 );
7568
7569
0
on_error:
7570
0
  if( column_definition != NULL )
7571
0
  {
7572
0
    libpff_column_definition_free(
7573
0
     &column_definition,
7574
0
     NULL );
7575
0
  }
7576
0
  if( column_definitions_data_cache != NULL )
7577
0
  {
7578
0
    libfcache_cache_free(
7579
0
     &column_definitions_data_cache,
7580
0
     NULL );
7581
0
  }
7582
0
  if( column_definitions_data_list != NULL )
7583
0
  {
7584
0
    libfdata_list_free(
7585
0
     &column_definitions_data_list,
7586
0
     NULL );
7587
0
  }
7588
0
  if( local_descriptor_value != NULL )
7589
0
  {
7590
0
    libpff_local_descriptor_value_free(
7591
0
     &local_descriptor_value,
7592
0
     NULL );
7593
0
  }
7594
0
  return( -1 );
7595
0
}
7596
7597
/* Reads the bc table record entries and their values
7598
 * Returns 1 if successful or -1 on error
7599
 */
7600
int libpff_table_read_bc_record_entries(
7601
     libpff_table_t *table,
7602
     libcdata_array_t *record_entries_references_array,
7603
     libpff_io_handle_t *io_handle,
7604
     libbfio_handle_t *file_io_handle,
7605
     libpff_offsets_index_t *offsets_index,
7606
     libcdata_list_t *name_to_id_map_list,
7607
     int debug_item_type,
7608
     libcerror_error_t **error )
7609
1.00k
{
7610
1.00k
  libpff_reference_descriptor_t *reference_descriptor = NULL;
7611
1.00k
  uint8_t *record_entries_data                        = NULL;
7612
1.00k
  static char *function                               = "libpff_table_read_bc_record_entries";
7613
1.00k
  size_t number_of_record_entries                     = 0;
7614
1.00k
  size_t record_entries_data_size                     = 0;
7615
1.00k
  uint16_t record_entry_type                          = 0;
7616
1.00k
  uint16_t record_entry_value_type                    = 0;
7617
1.00k
  int number_of_record_entries_references             = 0;
7618
1.00k
  int record_entries_reference_index                  = 0;
7619
1.00k
  int record_entry_index                              = 0;
7620
7621
1.00k
  if( table == NULL )
7622
0
  {
7623
0
    libcerror_error_set(
7624
0
     error,
7625
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7626
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7627
0
     "%s: invalid table.",
7628
0
     function );
7629
7630
0
    return( -1 );
7631
0
  }
7632
1.00k
  if( io_handle == NULL )
7633
0
  {
7634
0
    libcerror_error_set(
7635
0
     error,
7636
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7637
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7638
0
     "%s: invalid IO handle.",
7639
0
     function );
7640
7641
0
    return( -1 );
7642
0
  }
7643
1.00k
  if( libcdata_array_get_number_of_entries(
7644
1.00k
       record_entries_references_array,
7645
1.00k
       &number_of_record_entries_references,
7646
1.00k
       error ) != 1 )
7647
0
  {
7648
0
    libcerror_error_set(
7649
0
     error,
7650
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7651
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7652
0
     "%s: unable to retrieve number of record entries references.",
7653
0
     function );
7654
7655
0
    return( -1 );
7656
0
  }
7657
1.00k
  if( number_of_record_entries_references > 0 )
7658
1.00k
  {
7659
1.00k
    if( libpff_table_resize_record_entries(
7660
1.00k
         table,
7661
1.00k
         1,
7662
1.00k
         0,
7663
1.00k
         io_handle->ascii_codepage,
7664
1.00k
         error ) != 1 )
7665
0
    {
7666
0
      libcerror_error_set(
7667
0
       error,
7668
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7669
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
7670
0
       "%s: unable to resize record entries.",
7671
0
       function );
7672
7673
0
      return( -1 );
7674
0
    }
7675
1.00k
    for( record_entries_reference_index = 0;
7676
1.43k
         record_entries_reference_index < number_of_record_entries_references;
7677
1.00k
         record_entries_reference_index++ )
7678
1.00k
    {
7679
#if defined( HAVE_DEBUG_OUTPUT )
7680
      if( libcnotify_verbose != 0 )
7681
      {
7682
        libcnotify_printf(
7683
         "%s: record entries reference: %d\n",
7684
         function,
7685
         record_entries_reference_index );
7686
      }
7687
#endif
7688
1.00k
      if( libcdata_array_get_entry_by_index(
7689
1.00k
           record_entries_references_array,
7690
1.00k
           record_entries_reference_index,
7691
1.00k
           (intptr_t **) &reference_descriptor,
7692
1.00k
           error ) != 1 )
7693
0
      {
7694
0
        libcerror_error_set(
7695
0
         error,
7696
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7697
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7698
0
         "%s: unable to retrieve record entries reference: %d.",
7699
0
         function,
7700
0
         record_entries_reference_index );
7701
7702
0
        return( -1 );
7703
0
      }
7704
1.00k
      if( reference_descriptor == NULL )
7705
0
      {
7706
0
        libcerror_error_set(
7707
0
         error,
7708
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7709
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7710
0
         "%s: missing reference descriptor.",
7711
0
         function );
7712
7713
0
        return( -1 );
7714
0
      }
7715
1.00k
      if( libpff_table_get_value_data_by_reference(
7716
1.00k
           table,
7717
1.00k
           io_handle,
7718
1.00k
           file_io_handle,
7719
1.00k
           reference_descriptor->value,
7720
1.00k
           &record_entries_data,
7721
1.00k
           &record_entries_data_size,
7722
1.00k
           error ) != 1 )
7723
13
      {
7724
13
        libcerror_error_set(
7725
13
         error,
7726
13
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7727
13
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7728
13
         "%s: unable to retrieve record entries data.",
7729
13
         function );
7730
7731
13
        return( -1 );
7732
13
      }
7733
988
      if( ( record_entries_data == NULL )
7734
988
       || ( record_entries_data_size == 0 ) )
7735
3
      {
7736
3
        libcerror_error_set(
7737
3
         error,
7738
3
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7739
3
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7740
3
         "%s: missing record entries data.",
7741
3
         function );
7742
7743
3
        return( -1 );
7744
3
      }
7745
985
      if( ( record_entries_data_size % sizeof( pff_table_record_entry_bc_t ) ) != 0 )
7746
8
      {
7747
8
        libcerror_error_set(
7748
8
         error,
7749
8
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7750
8
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
7751
8
         "%s: unsupported record entries data size.",
7752
8
         function );
7753
7754
8
        return( -1 );
7755
8
      }
7756
977
      number_of_record_entries = record_entries_data_size / sizeof( pff_table_record_entry_bc_t );
7757
7758
977
      if( number_of_record_entries > (size_t) INT_MAX )
7759
0
      {
7760
0
        libcerror_error_set(
7761
0
         error,
7762
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7763
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
7764
0
         "%s: number of record entries value exceeds maximum.",
7765
0
         function );
7766
7767
0
        return( -1 );
7768
0
      }
7769
977
      if( libpff_table_expand_record_entries(
7770
977
           table,
7771
977
           0,
7772
977
           (int) number_of_record_entries,
7773
977
           io_handle->ascii_codepage,
7774
977
           error ) != 1 )
7775
0
      {
7776
0
        libcerror_error_set(
7777
0
         error,
7778
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7779
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
7780
0
         "%s: unable to expand record entries.",
7781
0
         function );
7782
7783
0
        return( -1 );
7784
0
      }
7785
39.3k
      while( record_entries_data_size > 0 )
7786
38.8k
      {
7787
38.8k
        byte_stream_copy_to_uint16_little_endian(
7788
38.8k
         ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_type,
7789
38.8k
         record_entry_type );
7790
7791
38.8k
        byte_stream_copy_to_uint16_little_endian(
7792
38.8k
         ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_value_type,
7793
38.8k
         record_entry_value_type );
7794
7795
38.8k
        if( libpff_table_read_entry_value(
7796
38.8k
             table,
7797
38.8k
             0,
7798
38.8k
             record_entry_index,
7799
38.8k
             (uint32_t) record_entry_type,
7800
38.8k
             (uint32_t) record_entry_value_type,
7801
38.8k
             (uint8_t *) ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_value,
7802
38.8k
             4,
7803
38.8k
             io_handle,
7804
38.8k
             file_io_handle,
7805
38.8k
             offsets_index,
7806
38.8k
             name_to_id_map_list,
7807
38.8k
             NULL,
7808
38.8k
             NULL,
7809
38.8k
             debug_item_type,
7810
38.8k
             error ) != 1 )
7811
541
        {
7812
541
          libcerror_error_set(
7813
541
           error,
7814
541
           LIBCERROR_ERROR_DOMAIN_IO,
7815
541
           LIBCERROR_IO_ERROR_READ_FAILED,
7816
541
           "%s: unable to read entry value: %" PRIu32 ".",
7817
541
           function,
7818
541
           record_entry_index );
7819
7820
541
          return( -1 );
7821
541
        }
7822
38.3k
        record_entries_data      += sizeof( pff_table_record_entry_bc_t );
7823
38.3k
        record_entries_data_size -= sizeof( pff_table_record_entry_bc_t );
7824
7825
38.3k
        record_entry_index++;
7826
38.3k
      }
7827
977
    }
7828
1.00k
  }
7829
440
  return( 1 );
7830
1.00k
}
7831
7832
/* Retrieves a specific values array data entry
7833
 * Returns 1 if successful, 0 if not or -1 on error
7834
 */
7835
int libpff_table_values_array_get_value_data_by_entry_number(
7836
     libpff_table_t *table,
7837
     uint32_t values_array_reference,
7838
     libpff_io_handle_t *io_handle,
7839
     libbfio_handle_t *file_io_handle,
7840
     libpff_offsets_index_t *offsets_index,
7841
     uint32_t values_array_entry_number,
7842
     uint16_t values_array_entry_size,
7843
     uint8_t **values_array_data,
7844
     size_t *values_array_data_size,
7845
     uint8_t read_flags,
7846
     libcerror_error_t **error )
7847
18.5k
{
7848
18.5k
  libpff_data_block_t *data_block                         = NULL;
7849
18.5k
  libpff_local_descriptor_value_t *local_descriptor_value = NULL;
7850
18.5k
  static char *function                                   = "libpff_table_values_array_get_value_data_by_entry_number";
7851
18.5k
  size64_t values_array_block_size                        = 0;
7852
18.5k
  size_t values_array_data_offset                         = 0;
7853
18.5k
  int result                                              = 0;
7854
18.5k
  int values_array_block_index                            = 0;
7855
7856
18.5k
  if( table == NULL )
7857
0
  {
7858
0
    libcerror_error_set(
7859
0
     error,
7860
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7861
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7862
0
     "%s: invalid table.",
7863
0
     function );
7864
7865
0
    return( -1 );
7866
0
  }
7867
18.5k
  if( values_array_entry_size == 0 )
7868
3
  {
7869
3
    libcerror_error_set(
7870
3
     error,
7871
3
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7872
3
     LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
7873
3
     "%s: invalid values array entry size value zero or less.",
7874
3
     function );
7875
7876
3
    return( -1 );
7877
3
  }
7878
18.5k
  if( values_array_data == NULL )
7879
0
  {
7880
0
    libcerror_error_set(
7881
0
     error,
7882
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7883
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7884
0
     "%s: invalid values array data.",
7885
0
     function );
7886
7887
0
    return( -1 );
7888
0
  }
7889
18.5k
  if( values_array_data_size == NULL )
7890
0
  {
7891
0
    libcerror_error_set(
7892
0
     error,
7893
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7894
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7895
0
     "%s: invalid values array data size.",
7896
0
     function );
7897
7898
0
    return( -1 );
7899
0
  }
7900
/* TODO find the right offset within the data */
7901
18.5k
  if( ( values_array_reference & 0x0000001fUL ) != 0 )
7902
84
  {
7903
84
    if( table->values_array_data_list == NULL )
7904
80
    {
7905
80
      result = libpff_local_descriptors_tree_get_value_by_identifier(
7906
80
          table->local_descriptors_tree,
7907
80
          file_io_handle,
7908
80
          values_array_reference,
7909
80
          &local_descriptor_value,
7910
80
          error );
7911
7912
80
      if( result == -1 )
7913
47
      {
7914
47
        libcerror_error_set(
7915
47
         error,
7916
47
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7917
47
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7918
47
         "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
7919
47
         function,
7920
47
         values_array_reference );
7921
7922
47
        goto on_error;
7923
47
      }
7924
33
      else if( result == 0 )
7925
12
      {
7926
12
        libcerror_error_set(
7927
12
         error,
7928
12
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7929
12
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7930
12
         "%s: missing values array descriptor: 0x%08" PRIx32 " (%" PRIu32 ").",
7931
12
         function,
7932
12
         values_array_reference,
7933
12
         values_array_reference );
7934
7935
12
        goto on_error;
7936
12
      }
7937
21
      if( local_descriptor_value == NULL )
7938
0
      {
7939
0
        libcerror_error_set(
7940
0
         error,
7941
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7942
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7943
0
         "%s: invalid local descriptor value.",
7944
0
         function );
7945
7946
0
        goto on_error;
7947
0
      }
7948
#if defined( HAVE_DEBUG_OUTPUT )
7949
      if( libcnotify_verbose != 0 )
7950
      {
7951
        libcnotify_printf(
7952
         "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
7953
         function,
7954
         local_descriptor_value->identifier,
7955
         libpff_debug_get_node_identifier_type(
7956
          (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
7957
         local_descriptor_value->data_identifier,
7958
         local_descriptor_value->local_descriptors_identifier );
7959
      }
7960
#endif
7961
/* TODO handle multiple recovered offset index values */
7962
21
      if( libpff_table_read_descriptor_data_list(
7963
21
           table,
7964
21
           io_handle,
7965
21
           file_io_handle,
7966
21
           offsets_index,
7967
21
           values_array_reference,
7968
21
           local_descriptor_value->data_identifier,
7969
21
           table->recovered,
7970
21
           0,
7971
21
           &( table->values_array_data_list ),
7972
21
           &( table->values_array_data_cache ),
7973
21
           error ) != 1 )
7974
2
      {
7975
2
        libcerror_error_set(
7976
2
         error,
7977
2
         LIBCERROR_ERROR_DOMAIN_IO,
7978
2
         LIBCERROR_IO_ERROR_READ_FAILED,
7979
2
         "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
7980
2
         function,
7981
2
         values_array_reference,
7982
2
         local_descriptor_value->data_identifier );
7983
7984
2
        goto on_error;
7985
2
      }
7986
19
      if( libpff_local_descriptor_value_free(
7987
19
           &local_descriptor_value,
7988
19
           error ) != 1 )
7989
0
      {
7990
0
        libcerror_error_set(
7991
0
         error,
7992
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7993
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7994
0
         "%s: unable to free values array descriptor: 0x%08" PRIx32 " (%" PRIu32 ") local descriptor value.",
7995
0
         function,
7996
0
         values_array_reference,
7997
0
         values_array_reference );
7998
7999
0
        goto on_error;
8000
0
      }
8001
19
      if( libfdata_list_get_mapped_size_by_index(
8002
19
           table->values_array_data_list,
8003
19
           0,
8004
19
           &values_array_block_size,
8005
19
           error ) != 1 )
8006
0
      {
8007
0
        libcerror_error_set(
8008
0
         error,
8009
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8010
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8011
0
         "%s: unable to retrieve mapped size of data block: 0.",
8012
0
         function );
8013
8014
0
        goto on_error;
8015
0
      }
8016
19
      table->value_array_entries_per_block = (int) ( values_array_block_size / values_array_entry_size );
8017
19
    }
8018
23
    if( table->value_array_entries_per_block == 0 )
8019
2
    {
8020
2
      libcerror_error_set(
8021
2
       error,
8022
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8023
2
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8024
2
       "%s: invalid table - missing value array entries per block value.",
8025
2
       function );
8026
8027
2
      goto on_error;
8028
2
    }
8029
21
    values_array_block_index = values_array_entry_number / table->value_array_entries_per_block;
8030
8031
    /* Retrieve the corresponding data block
8032
     */
8033
21
    if( libfdata_list_get_element_value_by_index(
8034
21
         table->values_array_data_list,
8035
21
         (intptr_t *) file_io_handle,
8036
21
         (libfdata_cache_t *) table->values_array_data_cache,
8037
21
         values_array_block_index,
8038
21
         (intptr_t **) &data_block,
8039
21
         read_flags,
8040
21
         error ) != 1 )
8041
11
    {
8042
11
      libcerror_error_set(
8043
11
       error,
8044
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8045
11
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8046
11
       "%s: unable to retrieve data block: %" PRIu32 ".",
8047
11
       function,
8048
11
       values_array_block_index );
8049
8050
11
      goto on_error;
8051
11
    }
8052
10
    if( data_block == NULL )
8053
0
    {
8054
0
      libcerror_error_set(
8055
0
       error,
8056
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8057
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8058
0
       "%s: missing data block: %" PRIu32 ".",
8059
0
       function,
8060
0
       values_array_block_index );
8061
8062
0
      goto on_error;
8063
0
    }
8064
10
    if( data_block->data == NULL )
8065
0
    {
8066
0
      libcerror_error_set(
8067
0
       error,
8068
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8069
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8070
0
       "%s: invalid data block: %" PRIu32 " - missing data.",
8071
0
       function,
8072
0
       values_array_block_index );
8073
8074
0
      goto on_error;
8075
0
    }
8076
10
    values_array_data_offset = ( values_array_entry_number % table->value_array_entries_per_block )
8077
10
                             * values_array_entry_size;
8078
8079
10
    if( values_array_data_offset >= data_block->uncompressed_data_size )
8080
0
    {
8081
#if defined( HAVE_DEBUG_OUTPUT )
8082
      if( libcnotify_verbose != 0 )
8083
      {
8084
        libcnotify_printf(
8085
         "%s: invalid values array entry number value out of bounds.",
8086
               function );
8087
      }
8088
#endif
8089
0
      return( 0 );
8090
0
    }
8091
10
    *values_array_data      = data_block->data + values_array_data_offset;
8092
10
    *values_array_data_size = (size_t) values_array_entry_size;
8093
10
  }
8094
18.4k
  else
8095
18.4k
  {
8096
18.4k
    if( libpff_table_get_value_data_by_reference(
8097
18.4k
         table,
8098
18.4k
         io_handle,
8099
18.4k
         file_io_handle,
8100
18.4k
         values_array_reference,
8101
18.4k
         values_array_data,
8102
18.4k
         values_array_data_size,
8103
18.4k
         error ) != 1 )
8104
20
    {
8105
20
      libcerror_error_set(
8106
20
       error,
8107
20
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8108
20
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8109
20
       "%s: unable to retrieve value data by reference.",
8110
20
       function );
8111
8112
20
      goto on_error;
8113
20
    }
8114
18.4k
    if( ( *values_array_data == NULL )
8115
18.4k
     || ( *values_array_data_size == 0 ) )
8116
3
    {
8117
3
      libcerror_error_set(
8118
3
       error,
8119
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8120
3
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8121
3
       "%s: missing values array data.",
8122
3
       function );
8123
8124
3
      goto on_error;
8125
3
    }
8126
18.4k
    values_array_data_offset = (size_t) values_array_entry_number * (size_t) values_array_entry_size;
8127
8128
18.4k
    if( ( values_array_data_offset >= *values_array_data_size )
8129
18.4k
     || ( values_array_entry_size > ( *values_array_data_size - values_array_data_offset ) ) )
8130
13.4k
    {
8131
#if defined( HAVE_DEBUG_OUTPUT )
8132
      if( libcnotify_verbose != 0 )
8133
      {
8134
        libcnotify_printf(
8135
         "%s: invalid values array entry number: %" PRIu32 " value out of bounds.\n",
8136
               function,
8137
         values_array_entry_number );
8138
      }
8139
#endif
8140
13.4k
      return( 0 );
8141
13.4k
    }
8142
4.95k
    *values_array_data     += values_array_data_offset;
8143
4.95k
    *values_array_data_size = (size_t) values_array_entry_size;
8144
4.95k
  }
8145
#if defined( HAVE_DEBUG_OUTPUT )
8146
  if( libcnotify_verbose != 0 )
8147
  {
8148
    libcnotify_printf(
8149
     "%s: values array data entry: %" PRIu32 ":\n",
8150
     function,
8151
     values_array_entry_number );
8152
    libcnotify_print_data(
8153
     *values_array_data,
8154
     *values_array_data_size,
8155
     0 );
8156
  }
8157
#endif
8158
4.96k
  return( 1 );
8159
8160
97
on_error:
8161
97
  if( local_descriptor_value != NULL )
8162
2
  {
8163
2
    libpff_local_descriptor_value_free(
8164
2
     &local_descriptor_value,
8165
2
     NULL );
8166
2
  }
8167
97
  return( -1 );
8168
18.5k
}
8169
8170
/* Reads the table values array
8171
 * Returns 1 if successful or -1 on error
8172
 */
8173
int libpff_table_read_values_array(
8174
     libpff_table_t *table,
8175
     libcdata_array_t *record_entries_references_array,
8176
     uint32_t values_array_reference,
8177
     uint8_t record_entry_identifier_size,
8178
     uint8_t record_entry_value_size,
8179
     uint16_t values_array_entry_size,
8180
     libcdata_array_t *column_definitions_array,
8181
     libpff_io_handle_t *io_handle,
8182
     libbfio_handle_t *file_io_handle,
8183
     libpff_offsets_index_t *offsets_index,
8184
     libcerror_error_t **error )
8185
1.67k
{
8186
1.67k
  libpff_column_definition_t *column_definition       = NULL;
8187
1.67k
  libpff_reference_descriptor_t *reference_descriptor = NULL;
8188
1.67k
  uint8_t *record_entries_data                        = NULL;
8189
1.67k
  uint8_t *record_entry_data                          = NULL;
8190
1.67k
  uint8_t *record_entry_values_data                   = NULL;
8191
1.67k
  static char *function                               = "libpff_table_read_values_array";
8192
1.67k
  size_t number_of_record_entries                     = 0;
8193
1.67k
  size_t record_entries_data_size                     = 0;
8194
1.67k
  size_t record_entry_size                            = 0;
8195
1.67k
  size_t record_entry_values_data_size                = 0;
8196
1.67k
  uint32_t record_entry_values_array_identifier       = 0;
8197
1.67k
  uint32_t record_entry_values_array_number           = 0;
8198
1.67k
  uint32_t table_values_array_identifier              = 0;
8199
1.67k
  int column_definition_index                         = 0;
8200
1.67k
  int number_of_column_definitions                    = 0;
8201
1.67k
  int number_of_record_entries_references             = 0;
8202
1.67k
  int number_of_sets                                  = 0;
8203
1.67k
  int record_entries_reference_index                  = 0;
8204
1.67k
  int record_entry_index                              = 0;
8205
1.67k
  int result                                          = 0;
8206
8207
1.67k
  if( table == NULL )
8208
0
  {
8209
0
    libcerror_error_set(
8210
0
     error,
8211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8213
0
     "%s: invalid table.",
8214
0
     function );
8215
8216
0
    return( -1 );
8217
0
  }
8218
1.67k
  if( ( record_entry_identifier_size != 4 )
8219
1.67k
   || ( ( record_entry_value_size != 2 )
8220
1.67k
    &&  ( record_entry_value_size != 4 ) ) )
8221
0
  {
8222
0
    libcerror_error_set(
8223
0
     error,
8224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8225
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8226
0
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
8227
0
     function,
8228
0
     record_entry_identifier_size,
8229
0
     record_entry_value_size );
8230
8231
0
    return( -1 );
8232
0
  }
8233
1.67k
  if( column_definitions_array == NULL )
8234
0
  {
8235
0
    libcerror_error_set(
8236
0
     error,
8237
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8238
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8239
0
     "%s: invalid column definitions array.",
8240
0
     function );
8241
8242
0
    return( -1 );
8243
0
  }
8244
1.67k
  if( io_handle == NULL )
8245
0
  {
8246
0
    libcerror_error_set(
8247
0
     error,
8248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8250
0
     "%s: invalid IO handle.",
8251
0
     function );
8252
8253
0
    return( -1 );
8254
0
  }
8255
1.67k
  if( libcdata_array_get_number_of_entries(
8256
1.67k
       record_entries_references_array,
8257
1.67k
       &number_of_record_entries_references,
8258
1.67k
       error ) != 1 )
8259
0
  {
8260
0
    libcerror_error_set(
8261
0
     error,
8262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8263
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8264
0
     "%s: unable to retrieve number of record entries references.",
8265
0
     function );
8266
8267
0
    goto on_error;
8268
0
  }
8269
  /* Check if the table contains any entries
8270
   */
8271
1.67k
  if( ( number_of_record_entries_references == 0 )
8272
1.67k
   && ( values_array_reference == 0 ) )
8273
10
  {
8274
#if defined( HAVE_DEBUG_OUTPUT )
8275
    if( libcnotify_verbose != 0 )
8276
    {
8277
      libcnotify_printf(
8278
       "%s: table contains no entries.\n",
8279
       function );
8280
    }
8281
#endif
8282
10
    return( 1 );
8283
10
  }
8284
1.66k
  if( number_of_record_entries_references == 0 )
8285
59
  {
8286
59
    libcerror_error_set(
8287
59
     error,
8288
59
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8289
59
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8290
59
     "%s: table contains value array but no record entries.",
8291
59
     function );
8292
8293
59
    goto on_error;
8294
59
  }
8295
1.60k
  if( values_array_reference == 0 )
8296
4
  {
8297
4
    libcerror_error_set(
8298
4
     error,
8299
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8300
4
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8301
4
     "%s: table contains record entries but no value array.",
8302
4
     function );
8303
8304
4
    goto on_error;
8305
4
  }
8306
1.60k
  if( libcdata_array_get_number_of_entries(
8307
1.60k
       column_definitions_array,
8308
1.60k
       &number_of_column_definitions,
8309
1.60k
       error ) != 1 )
8310
0
  {
8311
0
    libcerror_error_set(
8312
0
     error,
8313
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8314
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8315
0
     "%s: unable to retrieve number of column definitions.",
8316
0
     function );
8317
8318
0
    goto on_error;
8319
0
  }
8320
1.60k
  record_entry_size = record_entry_identifier_size + record_entry_value_size;
8321
8322
1.60k
  if( libpff_table_resize_record_entries(
8323
1.60k
       table,
8324
1.60k
       0,
8325
1.60k
       0,
8326
1.60k
       io_handle->ascii_codepage,
8327
1.60k
       error ) != 1 )
8328
0
  {
8329
0
    libcerror_error_set(
8330
0
     error,
8331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8332
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
8333
0
     "%s: unable to resize record entries.",
8334
0
     function );
8335
8336
0
    goto on_error;
8337
0
  }
8338
1.60k
  for( record_entries_reference_index = 0;
8339
2.43k
       record_entries_reference_index < number_of_record_entries_references;
8340
1.60k
       record_entries_reference_index++ )
8341
2.18k
  {
8342
2.18k
    if( libcdata_array_get_entry_by_index(
8343
2.18k
         record_entries_references_array,
8344
2.18k
         record_entries_reference_index,
8345
2.18k
         (intptr_t **) &reference_descriptor,
8346
2.18k
         error ) != 1 )
8347
0
    {
8348
0
      libcerror_error_set(
8349
0
       error,
8350
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8351
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8352
0
       "%s: unable to retrieve record entries reference: %d.",
8353
0
       function,
8354
0
       record_entries_reference_index );
8355
8356
0
      goto on_error;
8357
0
    }
8358
2.18k
    if( reference_descriptor == NULL )
8359
0
    {
8360
0
      libcerror_error_set(
8361
0
       error,
8362
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8363
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8364
0
       "%s: missing reference descriptor.",
8365
0
       function );
8366
8367
0
      goto on_error;
8368
0
    }
8369
#if defined( HAVE_DEBUG_OUTPUT )
8370
    if( libcnotify_verbose != 0 )
8371
    {
8372
      libcnotify_printf(
8373
       "%s: record entries reference: %d\t\t\t: 0x%08" PRIx32 "\n",
8374
       function,
8375
       record_entries_reference_index,
8376
       reference_descriptor->value );
8377
    }
8378
#endif
8379
2.18k
    if( libpff_table_clone_value_data_by_reference(
8380
2.18k
         table,
8381
2.18k
         reference_descriptor->value,
8382
2.18k
         io_handle,
8383
2.18k
         file_io_handle,
8384
2.18k
         &record_entries_data,
8385
2.18k
         &record_entries_data_size,
8386
2.18k
         error ) != 1 )
8387
29
    {
8388
29
      libcerror_error_set(
8389
29
       error,
8390
29
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8391
29
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8392
29
       "%s: unable to retrieve record entries data.",
8393
29
       function );
8394
8395
29
      goto on_error;
8396
29
    }
8397
2.15k
    if( ( record_entries_data == NULL )
8398
2.15k
     || ( record_entries_data_size == 0 ) )
8399
0
    {
8400
0
      libcerror_error_set(
8401
0
       error,
8402
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8403
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8404
0
       "%s: missing record entries data.",
8405
0
       function );
8406
8407
0
      goto on_error;
8408
0
    }
8409
#if defined( HAVE_DEBUG_OUTPUT )
8410
    if( libcnotify_verbose != 0 )
8411
    {
8412
      libcnotify_printf(
8413
       "%s: record entries data:\n",
8414
       function );
8415
      libcnotify_print_data(
8416
       record_entries_data,
8417
       record_entries_data_size,
8418
       0 );
8419
    }
8420
#endif
8421
2.15k
    if( ( record_entries_data_size % record_entry_size ) != 0 )
8422
20
    {
8423
20
      libcerror_error_set(
8424
20
       error,
8425
20
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8426
20
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8427
20
       "%s: unsupported record entries data size.",
8428
20
       function );
8429
8430
20
      goto on_error;
8431
20
    }
8432
2.13k
    number_of_record_entries = record_entries_data_size / record_entry_size;
8433
8434
#if defined( HAVE_DEBUG_OUTPUT )
8435
    if( libcnotify_verbose != 0 )
8436
    {
8437
      libcnotify_printf(
8438
       "%s: number of record entries\t\t\t: %" PRIzd "\n",
8439
       function,
8440
       number_of_record_entries );
8441
    }
8442
#endif
8443
2.13k
    if( number_of_record_entries > (size_t) ( INT_MAX - record_entry_index ) )
8444
0
    {
8445
0
      libcerror_error_set(
8446
0
       error,
8447
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8448
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
8449
0
       "%s: number of record entries value exceeds maximum.",
8450
0
       function );
8451
8452
0
      goto on_error;
8453
0
    }
8454
2.13k
    if( number_of_record_entries >= (size_t) ( number_of_sets - record_entry_index ) )
8455
2.13k
    {
8456
2.13k
      number_of_sets = record_entry_index + (int) number_of_record_entries;
8457
8458
2.13k
      if( libpff_table_resize_record_entries(
8459
2.13k
           table,
8460
2.13k
           number_of_sets,
8461
2.13k
           number_of_column_definitions,
8462
2.13k
           io_handle->ascii_codepage,
8463
2.13k
           error ) != 1 )
8464
0
      {
8465
0
        libcerror_error_set(
8466
0
         error,
8467
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8468
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
8469
0
         "%s: unable to resize record entries.",
8470
0
         function );
8471
8472
0
        goto on_error;
8473
0
      }
8474
2.13k
    }
8475
2.13k
    record_entry_data = record_entries_data;
8476
8477
19.3k
    while( record_entries_data_size > 0 )
8478
18.4k
    {
8479
18.4k
      byte_stream_copy_to_uint32_little_endian(
8480
18.4k
       record_entry_data,
8481
18.4k
       record_entry_values_array_identifier );
8482
8483
18.4k
      record_entry_data        += 4;
8484
18.4k
      record_entries_data_size -= 4;
8485
8486
18.4k
      if( record_entry_value_size == 2 )
8487
84
      {
8488
84
        byte_stream_copy_to_uint16_little_endian(
8489
84
         record_entry_data,
8490
84
         record_entry_values_array_number );
8491
8492
84
        record_entry_data        += 2;
8493
84
        record_entries_data_size -= 2;
8494
84
      }
8495
18.3k
      else if( record_entry_value_size == 4 )
8496
18.3k
      {
8497
18.3k
        byte_stream_copy_to_uint32_little_endian(
8498
18.3k
         record_entry_data,
8499
18.3k
         record_entry_values_array_number );
8500
8501
18.3k
        record_entry_data        += 4;
8502
18.3k
        record_entries_data_size -= 4;
8503
18.3k
      }
8504
#if defined( HAVE_DEBUG_OUTPUT )
8505
      if( libcnotify_verbose != 0 )
8506
      {
8507
        libcnotify_printf(
8508
         "%s: record entry: %03" PRIu32 " values array identifier\t: 0x%08" PRIx32 "\n",
8509
         function,
8510
         record_entry_index,
8511
         record_entry_values_array_identifier );
8512
8513
        libcnotify_printf(
8514
         "%s: record entry: %03" PRIu32 " values array number\t\t: %" PRIu32 "\n",
8515
         function,
8516
         record_entry_index,
8517
         record_entry_values_array_number );
8518
8519
        libcnotify_printf(
8520
         "\n" );
8521
      }
8522
#endif
8523
18.4k
      result = libpff_table_values_array_get_value_data_by_entry_number(
8524
18.4k
                table,
8525
18.4k
                values_array_reference,
8526
18.4k
                io_handle,
8527
18.4k
                file_io_handle,
8528
18.4k
                offsets_index,
8529
18.4k
                record_entry_values_array_number,
8530
18.4k
                values_array_entry_size,
8531
18.4k
                &record_entry_values_data,
8532
18.4k
                &record_entry_values_data_size,
8533
18.4k
                0,
8534
18.4k
                error );
8535
8536
18.4k
      if( result == -1 )
8537
100
      {
8538
100
        libcerror_error_set(
8539
100
         error,
8540
100
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8541
100
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8542
100
         "%s: unable to retrieve record entry values data for index: %" PRIu32 ".",
8543
100
         function,
8544
100
         record_entry_values_array_number );
8545
8546
100
        goto on_error;
8547
100
      }
8548
18.3k
      else if( result == 0 )
8549
13.4k
      {
8550
13.4k
        record_entry_index++;
8551
8552
13.4k
        table->flags |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
8553
8554
13.4k
        continue;
8555
13.4k
      }
8556
4.88k
      if( record_entry_values_data == NULL )
8557
0
      {
8558
0
        libcerror_error_set(
8559
0
         error,
8560
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8561
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8562
0
         "%s: missing record entry values data.",
8563
0
         function );
8564
8565
0
        goto on_error;
8566
0
      }
8567
4.88k
      if( record_entry_values_data_size < (size_t) values_array_entry_size )
8568
0
      {
8569
0
        libcerror_error_set(
8570
0
         error,
8571
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8572
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8573
0
         "%s: invalid table values data size value out of bounds.",
8574
0
         function );
8575
8576
0
        goto on_error;
8577
0
      }
8578
      /* If the value array numbers are not stored sequential
8579
       * resize the record entries to the required size.
8580
       * Make sure the value entry exists first.
8581
       */
8582
4.88k
#if SIZEOF_INT <= 4
8583
4.88k
      if( record_entry_values_array_number >= (uint32_t) number_of_sets )
8584
#else
8585
      if( (int) record_entry_values_array_number >= number_of_sets )
8586
#endif
8587
32
      {
8588
32
#if SIZEOF_INT <= 4
8589
32
        if( record_entry_values_array_number > (uint32_t) ( INT_MAX - 1 ) )
8590
#else
8591
        if( (int) record_entry_values_array_number > (int) ( INT_MAX - 1 ) )
8592
#endif
8593
0
        {
8594
0
          libcerror_error_set(
8595
0
           error,
8596
0
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8597
0
           LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
8598
0
           "%s: number of record entries value exceeds maximum.",
8599
0
           function );
8600
8601
0
          goto on_error;
8602
0
        }
8603
32
        number_of_sets = (int) ( record_entry_values_array_number + 1 );
8604
8605
32
        if( libpff_table_resize_record_entries(
8606
32
             table,
8607
32
             number_of_sets,
8608
32
             number_of_column_definitions,
8609
32
             io_handle->ascii_codepage,
8610
32
             error ) != 1 )
8611
0
        {
8612
0
          libcerror_error_set(
8613
0
           error,
8614
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
8615
0
           LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
8616
0
           "%s: unable to resize record entries.",
8617
0
           function );
8618
8619
0
          goto on_error;
8620
0
        }
8621
32
      }
8622
4.88k
      for( column_definition_index = 0;
8623
45.3k
           column_definition_index < number_of_column_definitions;
8624
40.4k
           column_definition_index++ )
8625
41.6k
      {
8626
41.6k
        if( libcdata_array_get_entry_by_index(
8627
41.6k
             column_definitions_array,
8628
41.6k
             column_definition_index,
8629
41.6k
             (intptr_t **) &column_definition,
8630
41.6k
             error ) != 1 )
8631
0
        {
8632
0
          libcerror_error_set(
8633
0
           error,
8634
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
8635
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8636
0
           "%s: unable to retrieve column definitions array entry: %d.",
8637
0
           function,
8638
0
           column_definition_index );
8639
8640
0
          goto on_error;
8641
0
        }
8642
41.6k
        if( column_definition == NULL )
8643
0
        {
8644
0
          libcerror_error_set(
8645
0
           error,
8646
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
8647
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8648
0
           "%s: missing column definition: %d.",
8649
0
           function,
8650
0
           column_definition_index );
8651
8652
0
          goto on_error;
8653
0
        }
8654
        /* For some unknown reason when the values array is read
8655
         * the data array is padded with zero or remnant values
8656
         * therefore the values array entries do not align
8657
         * this check is makes sure the aligment is correct
8658
         */
8659
41.6k
        if( column_definition_index == 0 )
8660
4.88k
        {
8661
4.88k
          if( column_definition->values_array_offset != 0 )
8662
36
          {
8663
36
            libcerror_error_set(
8664
36
             error,
8665
36
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8666
36
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8667
36
             "%s: unsupported first column definition values array offset.",
8668
36
             function );
8669
8670
36
            goto on_error;
8671
36
          }
8672
4.85k
          if( column_definition->values_array_size != 4 )
8673
19
          {
8674
19
            libcerror_error_set(
8675
19
             error,
8676
19
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8677
19
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8678
19
             "%s: unsupported first column definition values array size.",
8679
19
             function );
8680
8681
19
            goto on_error;
8682
19
          }
8683
4.83k
          byte_stream_copy_to_uint32_little_endian(
8684
4.83k
           record_entry_values_data,
8685
4.83k
           table_values_array_identifier );
8686
8687
          /* If decryption was forced reread the entry without decryption
8688
           */
8689
4.83k
          if( ( io_handle->force_decryption != 0 )
8690
4.83k
           && ( record_entry_values_array_identifier != table_values_array_identifier ) )
8691
79
          {
8692
79
            result = libpff_table_values_array_get_value_data_by_entry_number(
8693
79
                      table,
8694
79
                      values_array_reference,
8695
79
                      io_handle,
8696
79
                      file_io_handle,
8697
79
                      offsets_index,
8698
79
                      record_entry_values_array_number,
8699
79
                      values_array_entry_size,
8700
79
                      &record_entry_values_data,
8701
79
                      &record_entry_values_data_size,
8702
79
                      LIBFDATA_READ_FLAG_IGNORE_CACHE | LIBPFF_READ_FLAG_IGNORE_FORCE_DECRYPTION,
8703
79
                      error );
8704
8705
79
            if( result != 1 )
8706
0
            {
8707
0
              libcerror_error_set(
8708
0
               error,
8709
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
8710
0
               LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8711
0
               "%s: unable to retrieve record entry values data for index: %" PRIu32 ".",
8712
0
               function,
8713
0
               record_entry_values_array_number );
8714
8715
0
              goto on_error;
8716
0
            }
8717
79
            if( record_entry_values_data == NULL )
8718
0
            {
8719
0
              libcerror_error_set(
8720
0
               error,
8721
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
8722
0
               LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8723
0
               "%s: missing record entry values data.",
8724
0
               function );
8725
8726
0
              goto on_error;
8727
0
            }
8728
79
            if( record_entry_values_data_size < (size_t) values_array_entry_size )
8729
0
            {
8730
0
              libcerror_error_set(
8731
0
               error,
8732
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
8733
0
               LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8734
0
               "%s: invalid table values data size value out of bounds.",
8735
0
               function );
8736
8737
0
              goto on_error;
8738
0
            }
8739
79
            byte_stream_copy_to_uint32_little_endian(
8740
79
             record_entry_values_data,
8741
79
             table_values_array_identifier );
8742
79
          }
8743
4.83k
          if( record_entry_values_array_identifier != table_values_array_identifier )
8744
475
          {
8745
475
            libcerror_error_set(
8746
475
             error,
8747
475
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8748
475
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8749
475
             "%s: mismatch in values array identifier (0x%08" PRIx32 " != 0x%08" PRIx32 ").",
8750
475
             function,
8751
475
             record_entry_values_array_identifier,
8752
475
             table_values_array_identifier );
8753
8754
475
            goto on_error;
8755
475
          }
8756
#if defined( HAVE_DEBUG_OUTPUT )
8757
          if( libcnotify_verbose != 0 )
8758
          {
8759
            libcnotify_printf(
8760
             "%s: values array data:\n",
8761
             function );
8762
            libcnotify_print_data(
8763
             record_entry_values_data,
8764
             values_array_entry_size,
8765
             0 );
8766
          }
8767
#endif
8768
4.83k
        }
8769
41.0k
        if( column_definition->values_array_offset > values_array_entry_size )
8770
104
        {
8771
104
          libcerror_error_set(
8772
104
           error,
8773
104
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8774
104
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8775
104
           "%s: invalid column definition values array offset value exceeds values array size.",
8776
104
           function );
8777
8778
104
          goto on_error;
8779
104
        }
8780
#if defined( HAVE_DEBUG_OUTPUT )
8781
        if( libcnotify_verbose != 0 )
8782
        {
8783
          libcnotify_printf(
8784
           "%s: values array data at offset: %" PRIu16 " of size: %" PRIu16 "\n",
8785
           function,
8786
           column_definition->values_array_offset,
8787
           column_definition->values_array_size );
8788
          libcnotify_print_data(
8789
           &( record_entry_values_data[ column_definition->values_array_offset ] ),
8790
           (size_t) column_definition->values_array_size,
8791
           0 );
8792
        }
8793
#endif
8794
        /* To prevent multiple lookups the name to id map is not passed
8795
         */
8796
40.9k
        if( libpff_table_read_entry_value(
8797
40.9k
             table,
8798
40.9k
             record_entry_index,
8799
40.9k
             column_definition_index,
8800
40.9k
             column_definition->entry_type,
8801
40.9k
             column_definition->value_type,
8802
40.9k
             &( record_entry_values_data[ column_definition->values_array_offset ] ),
8803
40.9k
             (size_t) column_definition->values_array_size,
8804
40.9k
             io_handle,
8805
40.9k
             file_io_handle,
8806
40.9k
             offsets_index,
8807
40.9k
             NULL,
8808
40.9k
             column_definition->name_to_id_map_entry,
8809
40.9k
             column_definition->record_entry_values_table,
8810
40.9k
             LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
8811
40.9k
             error ) != 1 )
8812
567
        {
8813
567
          libcerror_error_set(
8814
567
           error,
8815
567
           LIBCERROR_ERROR_DOMAIN_IO,
8816
567
           LIBCERROR_IO_ERROR_READ_FAILED,
8817
567
           "%s: unable to read entry value: %" PRIu32 ".",
8818
567
           function,
8819
567
           record_entry_values_array_number );
8820
8821
567
          goto on_error;
8822
567
        }
8823
40.9k
      }
8824
3.68k
      record_entry_index++;
8825
3.68k
    }
8826
834
    memory_free(
8827
834
     record_entries_data );
8828
8829
834
    record_entries_data = NULL;
8830
834
  }
8831
252
  return( 1 );
8832
8833
1.41k
on_error:
8834
1.41k
  if( record_entries_data != NULL )
8835
1.32k
  {
8836
1.32k
    memory_free(
8837
1.32k
     record_entries_data );
8838
1.32k
  }
8839
1.41k
  return( -1 );
8840
1.60k
}
8841
8842
/* Reads a table record entry value
8843
 * Returns 1 if successful or -1 on error
8844
 */
8845
int libpff_table_read_entry_value(
8846
     libpff_table_t *table,
8847
     int set_index,
8848
     int entry_index,
8849
     uint32_t record_entry_type,
8850
     uint32_t record_entry_value_type,
8851
     uint8_t *record_entry_value,
8852
     size_t record_entry_value_size,
8853
     libpff_io_handle_t *io_handle,
8854
     libbfio_handle_t *file_io_handle,
8855
     libpff_offsets_index_t *offsets_index,
8856
     libcdata_list_t *name_to_id_map_list,
8857
     libpff_internal_name_to_id_map_entry_t *name_to_id_map_entry,
8858
     libpff_table_t *record_entry_values_table,
8859
     int debug_item_type LIBPFF_ATTRIBUTE_UNUSED,
8860
     libcerror_error_t **error )
8861
79.8k
{
8862
79.8k
  libfcache_cache_t *value_data_cache                     = NULL;
8863
79.8k
  libfdata_list_t *value_data_list                        = NULL;
8864
79.8k
  libpff_local_descriptor_value_t *local_descriptor_value = NULL;
8865
79.8k
  libpff_internal_record_entry_t *record_entry            = NULL;
8866
79.8k
  libpff_internal_record_entry_t *value_record_entry      = NULL;
8867
79.8k
  libpff_table_index_value_t *table_index_value           = NULL;
8868
79.8k
  uint8_t *record_entry_value_data                        = NULL;
8869
79.8k
  static char *function                                   = "libpff_table_read_entry_value";
8870
79.8k
  size_t record_entry_value_data_size                     = 0;
8871
79.8k
  uint64_t entry_value                                    = 0;
8872
79.8k
  uint16_t table_index_array_reference                    = 0;
8873
79.8k
  uint16_t table_index_value_reference                    = 0;
8874
79.8k
  int result                                              = 0;
8875
8876
79.8k
  LIBPFF_UNREFERENCED_PARAMETER( debug_item_type )
8877
8878
79.8k
  if( table == NULL )
8879
0
  {
8880
0
    libcerror_error_set(
8881
0
     error,
8882
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8883
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8884
0
     "%s: invalid table.",
8885
0
     function );
8886
8887
0
    return( -1 );
8888
0
  }
8889
79.8k
  if( record_entry_value == NULL )
8890
0
  {
8891
0
    libcerror_error_set(
8892
0
     error,
8893
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8894
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8895
0
     "%s: invalid record entry value.",
8896
0
     function );
8897
8898
0
    return( -1 );
8899
0
  }
8900
79.8k
  if( io_handle == NULL )
8901
0
  {
8902
0
    libcerror_error_set(
8903
0
     error,
8904
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8905
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8906
0
     "%s: invalid IO handle.",
8907
0
     function );
8908
8909
0
    return( -1 );
8910
0
  }
8911
79.8k
  if( ( io_handle->file_type != LIBPFF_FILE_TYPE_32BIT )
8912
79.8k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT )
8913
79.8k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
8914
0
  {
8915
0
    libcerror_error_set(
8916
0
     error,
8917
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8918
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
8919
0
     "%s: unsupported file type.",
8920
0
     function );
8921
8922
0
    return( -1 );
8923
0
  }
8924
79.8k
  if( libpff_table_get_record_entry_by_index(
8925
79.8k
       table,
8926
79.8k
       set_index,
8927
79.8k
       entry_index,
8928
79.8k
       (libpff_record_entry_t **) &record_entry,
8929
79.8k
       error ) != 1 )
8930
0
  {
8931
0
    libcerror_error_set(
8932
0
     error,
8933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8934
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8935
0
     "%s: unable to retrieve record entry with set index: %d and entry index: %d.",
8936
0
     function,
8937
0
     set_index,
8938
0
     entry_index );
8939
8940
0
    goto on_error;
8941
0
  }
8942
79.8k
  if( record_entry == NULL )
8943
0
  {
8944
0
    libcerror_error_set(
8945
0
     error,
8946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8947
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8948
0
     "%s: missing record entry with set index: %d and entry index: %d.",
8949
0
     function,
8950
0
     set_index,
8951
0
     entry_index );
8952
8953
0
    goto on_error;
8954
0
  }
8955
#if defined( HAVE_DEBUG_OUTPUT )
8956
  if( libcnotify_verbose != 0 )
8957
  {
8958
    libcnotify_printf(
8959
     "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry type\t\t\t: 0x%04" PRIx32 "",
8960
     function,
8961
     set_index,
8962
     entry_index,
8963
     record_entry_type );
8964
  }
8965
#endif
8966
79.8k
  if( ( record_entry_type >= 0x8000 )
8967
79.8k
   || ( record_entry_type <= 0xfffe ) )
8968
79.8k
  {
8969
    /* The corresponding name to id map entry was already determined
8970
     */
8971
79.8k
    if( name_to_id_map_entry != NULL )
8972
21
    {
8973
21
      record_entry->name_to_id_map_entry = name_to_id_map_entry;
8974
21
    }
8975
79.8k
    else if( name_to_id_map_list != NULL )
8976
914
    {
8977
914
      result = libpff_name_to_id_map_entry_get_entry_by_identifier(
8978
914
                name_to_id_map_list,
8979
914
                record_entry_type,
8980
914
                &( record_entry->name_to_id_map_entry ),
8981
914
                error );
8982
8983
914
      if( result == -1 )
8984
0
      {
8985
0
        libcerror_error_set(
8986
0
         error,
8987
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8988
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8989
0
         "%s: unable to retrieve name to id map entry: %" PRIu32 ".",
8990
0
         function,
8991
0
         record_entry_type );
8992
8993
0
        goto on_error;
8994
0
      }
8995
914
    }
8996
79.8k
  }
8997
79.8k
  record_entry->identifier.format     = LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_MAPI_PROPERTY;
8998
79.8k
  record_entry->identifier.entry_type = record_entry_type;
8999
79.8k
  record_entry->identifier.value_type = record_entry_value_type;
9000
9001
#if defined( HAVE_DEBUG_OUTPUT )
9002
  if( libcnotify_verbose != 0 )
9003
  {
9004
    if( debug_item_type == LIBPFF_DEBUG_ITEM_TYPE_NAME_TO_ID_MAP )
9005
    {
9006
      libcnotify_printf(
9007
       " (%s : %s)\n",
9008
       libpff_debug_get_name_to_id_map_property_type_identifier(
9009
        record_entry_type,
9010
        record_entry_value_type ),
9011
       libpff_debug_get_name_to_id_map_property_type_description(
9012
        record_entry_type,
9013
        record_entry_value_type ) );
9014
    }
9015
    else if( record_entry->name_to_id_map_entry != NULL )
9016
    {
9017
      if( record_entry->name_to_id_map_entry->type == LIBPFF_NAME_TO_ID_MAP_ENTRY_TYPE_STRING )
9018
      {
9019
        libcnotify_printf(
9020
         " maps to: %s (%s : %s)\n",
9021
         (char *) record_entry->name_to_id_map_entry->debug_string,
9022
         libfmapi_named_property_type_get_identifier(
9023
          record_entry->name_to_id_map_entry->guid,
9024
          (char *) record_entry->name_to_id_map_entry->debug_string,
9025
          record_entry->name_to_id_map_entry->value_size,
9026
          record_entry->identifier.value_type ),
9027
         libfmapi_named_property_type_get_description(
9028
          record_entry->name_to_id_map_entry->guid,
9029
          (char *) record_entry->name_to_id_map_entry->debug_string,
9030
          record_entry->name_to_id_map_entry->value_size,
9031
          record_entry->identifier.value_type ) );
9032
      }
9033
      else
9034
      {
9035
        libcnotify_printf(
9036
         " maps to: 0x%04" PRIx32 " (%s : %s)\n",
9037
         record_entry->name_to_id_map_entry->numeric_value,
9038
         libfmapi_property_type_get_identifier(
9039
          record_entry->name_to_id_map_entry->guid,
9040
          record_entry->name_to_id_map_entry->numeric_value,
9041
          record_entry->identifier.value_type ),
9042
         libfmapi_property_type_get_description(
9043
          record_entry->name_to_id_map_entry->guid,
9044
          record_entry->name_to_id_map_entry->numeric_value,
9045
          record_entry->identifier.value_type ) );
9046
      }
9047
    }
9048
    else
9049
    {
9050
      libcnotify_printf(
9051
       " (%s : %s)\n",
9052
       libfmapi_property_type_get_identifier(
9053
        NULL,
9054
        record_entry->identifier.entry_type,
9055
        record_entry->identifier.value_type ),
9056
       libfmapi_property_type_get_description(
9057
        NULL,
9058
        record_entry->identifier.entry_type,
9059
        record_entry->identifier.value_type ) );
9060
    }
9061
    libcnotify_printf(
9062
     "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value type\t\t: 0x%04" PRIx16 " (%s : %s)\n",
9063
     function,
9064
     set_index,
9065
     entry_index,
9066
     record_entry_value_type,
9067
     libfmapi_value_type_get_identifier(
9068
      record_entry->identifier.value_type ),
9069
     libfmapi_value_type_get_description(
9070
      record_entry->identifier.value_type ) );
9071
  }
9072
#endif
9073
79.8k
  if( record_entry_value_size == 1 )
9074
8.18k
  {
9075
8.18k
    entry_value = record_entry_value[ 0 ];
9076
8.18k
  }
9077
71.6k
  else if( record_entry_value_size == 2 )
9078
146
  {
9079
146
    byte_stream_copy_to_uint16_little_endian(
9080
146
     record_entry_value,
9081
146
     entry_value );
9082
146
  }
9083
71.5k
  else if( record_entry_value_size == 4 )
9084
71.1k
  {
9085
71.1k
    byte_stream_copy_to_uint32_little_endian(
9086
71.1k
     record_entry_value,
9087
71.1k
     entry_value );
9088
71.1k
  }
9089
423
  else if( record_entry_value_size == 8 )
9090
373
  {
9091
373
    byte_stream_copy_to_uint64_little_endian(
9092
373
     record_entry_value,
9093
373
     entry_value );
9094
373
  }
9095
50
  else
9096
50
  {
9097
50
    libcerror_error_set(
9098
50
     error,
9099
50
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9100
50
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9101
50
     "%s: unsupported record entry value size: %" PRIu8 ".",
9102
50
     function,
9103
50
     record_entry_value_size );
9104
9105
50
    goto on_error;
9106
50
  }
9107
  /* Check if there is a record entry values (a5) table
9108
   */
9109
79.8k
  if( record_entry_values_table != NULL )
9110
0
  {
9111
#if defined( HAVE_DEBUG_OUTPUT )
9112
    if( libcnotify_verbose != 0 )
9113
    {
9114
      libcnotify_printf(
9115
       "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry values table reference\t: 0x%08" PRIx64 "\n",
9116
       function,
9117
       set_index,
9118
       entry_index,
9119
       entry_value );
9120
    }
9121
#endif
9122
/* TODO check entry value type */
9123
0
    if( ( entry_value & 0x0000001fUL ) != 0 )
9124
0
    {
9125
0
      result = libpff_local_descriptors_tree_get_value_by_identifier(
9126
0
          table->local_descriptors_tree,
9127
0
          file_io_handle,
9128
0
          (uint32_t) entry_value,
9129
0
          &local_descriptor_value,
9130
0
          error );
9131
9132
0
      if( result == -1 )
9133
0
      {
9134
0
        libcerror_error_set(
9135
0
         error,
9136
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
9137
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9138
0
         "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
9139
0
         function,
9140
0
         (uint32_t) entry_value );
9141
9142
0
        goto on_error;
9143
0
      }
9144
0
      else if( result == 0 )
9145
0
      {
9146
#if defined( HAVE_DEBUG_OUTPUT )
9147
        if( libcnotify_verbose != 0 )
9148
        {
9149
          libcnotify_printf(
9150
           "%s: missing descriptor: %" PRIu32 " - marked as missing.\n",
9151
           function,
9152
           (uint32_t) entry_value );
9153
        }
9154
#endif
9155
0
        record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9156
0
        table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9157
0
      }
9158
0
      else
9159
0
      {
9160
0
        if( local_descriptor_value == NULL )
9161
0
        {
9162
0
          libcerror_error_set(
9163
0
           error,
9164
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9165
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9166
0
           "%s: invalid local descriptor value.",
9167
0
           function );
9168
9169
0
          goto on_error;
9170
0
        }
9171
#if defined( HAVE_DEBUG_OUTPUT )
9172
        if( libcnotify_verbose != 0 )
9173
        {
9174
          libcnotify_printf(
9175
           "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
9176
           function,
9177
           local_descriptor_value->identifier,
9178
           libpff_debug_get_node_identifier_type(
9179
            (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
9180
           local_descriptor_value->data_identifier,
9181
           local_descriptor_value->local_descriptors_identifier );
9182
        }
9183
#endif
9184
/* TODO handle multiple recovered offset index values */
9185
0
        if( libpff_table_read_descriptor_data_list(
9186
0
             table,
9187
0
             io_handle,
9188
0
             file_io_handle,
9189
0
             offsets_index,
9190
0
             (uint32_t) entry_value,
9191
0
             local_descriptor_value->data_identifier,
9192
0
             table->recovered,
9193
0
             0,
9194
0
             &value_data_list,
9195
0
             &value_data_cache,
9196
0
             error ) != 1 )
9197
0
        {
9198
0
          libcerror_error_set(
9199
0
           error,
9200
0
           LIBCERROR_ERROR_DOMAIN_IO,
9201
0
           LIBCERROR_IO_ERROR_READ_FAILED,
9202
0
           "%s: unable to read record entry value data with descriptor: %" PRIu32 " - marked as missing.",
9203
0
           function,
9204
0
           (uint32_t) entry_value );
9205
9206
#if defined( HAVE_DEBUG_OUTPUT )
9207
          if( ( libcnotify_verbose != 0 )
9208
           && ( error != NULL )
9209
           && ( *error != NULL ) )
9210
          {
9211
            libcnotify_print_error_backtrace(
9212
             *error );
9213
          }
9214
#endif
9215
0
          libcerror_error_free(
9216
0
           error );
9217
9218
          /* If the data descriptor could not be read mark it as missing
9219
           * and give it an empty value data reference
9220
           */
9221
0
          record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9222
0
          table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9223
0
        }
9224
0
        if( libpff_local_descriptor_value_free(
9225
0
             &local_descriptor_value,
9226
0
             error ) != 1 )
9227
0
        {
9228
0
          libcerror_error_set(
9229
0
           error,
9230
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9231
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
9232
0
           "%s: unable to free local descriptor values.",
9233
0
           function );
9234
9235
0
          goto on_error;
9236
0
        }
9237
0
      }
9238
0
    }
9239
    /* Check if the entry value is a value within the record entry values (a5) table
9240
     */
9241
0
    else if( entry_value > 0 )
9242
0
    {
9243
0
      if( ( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
9244
0
       || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) )
9245
0
      {
9246
0
        table_index_array_reference = (uint16_t) ( entry_value >> 16 );
9247
0
        table_index_value_reference = (uint16_t) ( ( entry_value & 0x0000ffe0 ) >> 5 ) - 1;
9248
0
      }
9249
0
      else
9250
0
      {
9251
0
        table_index_array_reference = (uint16_t) ( entry_value >> 19 );
9252
0
        table_index_value_reference = (uint16_t) ( ( entry_value & 0x0007ffe0 ) >> 5 ) - 1;
9253
0
      }
9254
      /* The record entry value reference needs to be transformed into a table set and entry
9255
       * value. Table array entries have been stored as separate sets.
9256
       */
9257
0
      result = libpff_table_get_record_entry_by_index(
9258
0
          record_entry_values_table,
9259
0
          (int) table_index_array_reference,
9260
0
          (int) table_index_value_reference,
9261
0
          (libpff_record_entry_t **) &value_record_entry,
9262
0
          error );
9263
9264
0
      if( result == -1 )
9265
0
      {
9266
0
        libcerror_error_set(
9267
0
         error,
9268
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
9269
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9270
0
         "%s: unable to retrieve record entry value index: 0x%08" PRIx64 " (set: %" PRIu16 ", entry: %" PRIu16 ")",
9271
0
         function,
9272
0
         entry_value,
9273
0
         table_index_array_reference,
9274
0
         table_index_value_reference );
9275
9276
0
        goto on_error;
9277
0
      }
9278
      /* A missing record entry value reference signifies an empty value (NULL)
9279
       */
9280
0
      else if( result != 0 )
9281
0
      {
9282
0
        if( libpff_record_entry_get_data_size(
9283
0
             (libpff_record_entry_t *) value_record_entry,
9284
0
             &record_entry_value_data_size,
9285
0
             error ) != 1 )
9286
0
        {
9287
0
          libcerror_error_set(
9288
0
           error,
9289
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9290
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9291
0
           "%s: unable to retrieve record entry value data size.",
9292
0
           function );
9293
9294
0
          goto on_error;
9295
0
        }
9296
0
        if( record_entry_value_data_size == 0 )
9297
0
        {
9298
0
          libcerror_error_set(
9299
0
           error,
9300
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9301
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9302
0
           "%s: missing value record entry value data.",
9303
0
           function );
9304
9305
0
          goto on_error;
9306
0
        }
9307
0
      }
9308
0
    }
9309
0
  }
9310
79.8k
  else
9311
79.8k
  {
9312
    /* The Boolean (0x000b)
9313
     * is 1 byte of size in the 7c table
9314
     * is 4 bytes of size in the bc table
9315
     *
9316
     * the first byte contains the value
9317
     * the value is 0x00 if false or true otherwise
9318
     */
9319
79.8k
    if( record_entry_value_type == LIBPFF_VALUE_TYPE_BOOLEAN )
9320
6.53k
    {
9321
#if defined( HAVE_DEBUG_OUTPUT )
9322
      if( libcnotify_verbose != 0 )
9323
      {
9324
        libcnotify_printf(
9325
         "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value\t\t\t: 0x%08" PRIx64 "\n",
9326
         function,
9327
         set_index,
9328
         entry_index,
9329
         entry_value );
9330
9331
        if( ( record_entry_value_size != 1 )
9332
         && ( record_entry_value_size != 4 ) )
9333
        {
9334
          libcerror_error_set(
9335
           error,
9336
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9337
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9338
           "%s: unsupported value type: 0x%08" PRIx32 " with value size: %" PRIu8 ".",
9339
           function,
9340
           record_entry_value_type,
9341
           record_entry_value_size );
9342
9343
          goto on_error;
9344
        }
9345
      }
9346
#endif
9347
      /* The first byte in the record entry value buffer
9348
       * contains the actual value of the boolean
9349
       */
9350
6.53k
      record_entry_value_data      = record_entry_value;
9351
6.53k
      record_entry_value_data_size = sizeof( uint8_t );
9352
6.53k
    }
9353
    /* The Integer 16-bit signed (0x0002)
9354
     * is 2 bytes of size in the 7c table
9355
     * is 4 bytes of size in the bc table
9356
     *
9357
     * the first two bytes contains the value
9358
     */
9359
73.2k
    else if( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_16BIT_SIGNED )
9360
296
    {
9361
#if defined( HAVE_DEBUG_OUTPUT )
9362
      if( libcnotify_verbose != 0 )
9363
      {
9364
        libcnotify_printf(
9365
         "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value\t\t\t: 0x%08" PRIx64 "\n",
9366
         function,
9367
         set_index,
9368
         entry_index,
9369
         entry_value );
9370
9371
        if( ( record_entry_value_size != 2 )
9372
         && ( record_entry_value_size != 4 ) )
9373
        {
9374
          libcerror_error_set(
9375
           error,
9376
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9377
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9378
           "%s: unsupported value type: 0x%08" PRIx32 " with value size: %" PRIu8 ".",
9379
           function,
9380
           record_entry_value_type,
9381
           record_entry_value_size );
9382
9383
          goto on_error;
9384
        }
9385
      }
9386
#endif
9387
296
      record_entry_value_data      = record_entry_value;
9388
296
      record_entry_value_data_size = sizeof( uint16_t );
9389
296
    }
9390
    /* The Integer 32-bit signed (0x0003)
9391
     *     Floating point single precision (0x0004)
9392
     *     Error scode (0x000a)
9393
     *
9394
     * is 4 bytes of size in the 7c and bc table
9395
     */
9396
72.9k
    else if( ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_32BIT_SIGNED )
9397
72.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FLOAT_32BIT )
9398
72.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_ERROR ) )
9399
20.3k
    {
9400
#if defined( HAVE_DEBUG_OUTPUT )
9401
      if( libcnotify_verbose != 0 )
9402
      {
9403
        libcnotify_printf(
9404
         "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value\t\t\t: 0x%08" PRIx64 "\n",
9405
         function,
9406
         set_index,
9407
         entry_index,
9408
         entry_value );
9409
9410
        if( record_entry_value_size != 4 )
9411
        {
9412
          libcerror_error_set(
9413
           error,
9414
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9415
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9416
           "%s: unsupported value type: 0x%08" PRIx32 " with value size: %" PRIu8 ".",
9417
           function,
9418
           record_entry_value_type,
9419
           record_entry_value_size );
9420
9421
          goto on_error;
9422
        }
9423
      }
9424
#endif
9425
20.3k
      record_entry_value_data      = record_entry_value;
9426
20.3k
      record_entry_value_data_size = sizeof( uint32_t );
9427
20.3k
    }
9428
    /* The Floating point double precision (0x0005)
9429
     *     Currency (64-bit) (0x0006)
9430
     *     Application time (64-bit) (0x0007)
9431
     *     Integer 64-bit signed (0x0014)
9432
     *     Windows Filetime (64-bit) (0x0040)
9433
     *
9434
     * is 8 bytes of size in the 7c table
9435
     */
9436
52.6k
    else if( ( record_entry_value_size == 8 )
9437
52.6k
          && ( ( record_entry_value_type == LIBPFF_VALUE_TYPE_DOUBLE_64BIT )
9438
356
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_CURRENCY )
9439
356
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_APPLICATION_TIME )
9440
356
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_64BIT_SIGNED )
9441
356
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FILETIME ) ) )
9442
97
    {
9443
#if defined( HAVE_DEBUG_OUTPUT )
9444
      if( libcnotify_verbose != 0 )
9445
      {
9446
        libcnotify_printf(
9447
         "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value\t\t\t: 0x%08" PRIx64 "\n",
9448
         function,
9449
         set_index,
9450
         entry_index,
9451
         entry_value );
9452
      }
9453
#endif
9454
97
      record_entry_value_data      = record_entry_value;
9455
97
      record_entry_value_data_size = sizeof( uint64_t );
9456
97
    }
9457
    /* These values are references in the bc table
9458
     */
9459
52.5k
    else if( ( record_entry_value_type == LIBPFF_VALUE_TYPE_DOUBLE_64BIT )
9460
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_CURRENCY )
9461
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_APPLICATION_TIME )
9462
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_OBJECT )
9463
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_64BIT_SIGNED )
9464
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
9465
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_STRING_UNICODE )
9466
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FILETIME )
9467
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_GUID )
9468
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_SERVER_IDENTIFIER )
9469
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_RESTRICTION )
9470
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_RULE_ACTION )
9471
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_BINARY_DATA )
9472
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_16BIT_SIGNED )
9473
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_32BIT_SIGNED )
9474
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_FLOAT_32BIT )
9475
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_DOUBLE_64BIT )
9476
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_CURRENCY )
9477
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_APPLICATION_TIME )
9478
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_64BIT_SIGNED )
9479
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_STRING_ASCII )
9480
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_STRING_UNICODE )
9481
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_FILETIME )
9482
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_GUID )
9483
52.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_BINARY_DATA ) )
9484
52.1k
    {
9485
      /* Check if the entry value is a referenced local descriptor
9486
       */
9487
/* TODO check entry value type */
9488
52.1k
      if( ( entry_value & 0x0000001fUL ) != 0 )
9489
6.91k
      {
9490
#if defined( HAVE_DEBUG_OUTPUT )
9491
        if( libcnotify_verbose != 0 )
9492
        {
9493
          libcnotify_printf(
9494
           "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value reference\t\t: %" PRIu64 " (%s)\n",
9495
           function,
9496
           set_index,
9497
           entry_index,
9498
           entry_value,
9499
           libpff_debug_get_node_identifier_type(
9500
            (uint8_t) ( entry_value & 0x0000001fUL ) ) );
9501
        }
9502
#endif
9503
6.91k
        if( entry_value > (uint64_t) UINT32_MAX )
9504
44
        {
9505
44
          libcerror_error_set(
9506
44
           error,
9507
44
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9508
44
           LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
9509
44
           "%s: entry value reference value exceeds maximum.",
9510
44
           function );
9511
9512
44
          goto on_error;
9513
44
        }
9514
6.86k
        result = libpff_local_descriptors_tree_get_value_by_identifier(
9515
6.86k
            table->local_descriptors_tree,
9516
6.86k
            file_io_handle,
9517
6.86k
            (uint32_t) entry_value,
9518
6.86k
            &local_descriptor_value,
9519
6.86k
            error );
9520
9521
6.86k
        if( result == -1 )
9522
552
        {
9523
552
          libcerror_error_set(
9524
552
           error,
9525
552
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9526
552
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9527
552
           "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
9528
552
           function,
9529
552
           (uint32_t) entry_value );
9530
9531
552
          goto on_error;
9532
552
        }
9533
6.31k
        else if( result == 0 )
9534
2.75k
        {
9535
#if defined( HAVE_DEBUG_OUTPUT )
9536
          if( libcnotify_verbose != 0 )
9537
          {
9538
            libcnotify_printf(
9539
             "%s: missing descriptor: %" PRIu32 " - marked as missing.\n",
9540
             function,
9541
             (uint32_t) entry_value );
9542
          }
9543
#endif
9544
2.75k
          record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9545
2.75k
          table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9546
2.75k
        }
9547
3.55k
        else
9548
3.55k
        {
9549
3.55k
          if( local_descriptor_value == NULL )
9550
0
          {
9551
0
            libcerror_error_set(
9552
0
             error,
9553
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
9554
0
             LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9555
0
             "%s: invalid local descriptor value.",
9556
0
             function );
9557
9558
0
            goto on_error;
9559
0
          }
9560
#if defined( HAVE_DEBUG_OUTPUT )
9561
          if( libcnotify_verbose != 0 )
9562
          {
9563
            libcnotify_printf(
9564
             "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
9565
             function,
9566
             local_descriptor_value->identifier,
9567
             libpff_debug_get_node_identifier_type(
9568
              (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
9569
             local_descriptor_value->data_identifier,
9570
             local_descriptor_value->local_descriptors_identifier );
9571
          }
9572
#endif
9573
/* TODO handle multiple recovered offset index values */
9574
3.55k
          if( libpff_table_read_descriptor_data_list(
9575
3.55k
               table,
9576
3.55k
               io_handle,
9577
3.55k
               file_io_handle,
9578
3.55k
               offsets_index,
9579
3.55k
               (uint32_t) entry_value,
9580
3.55k
               local_descriptor_value->data_identifier,
9581
3.55k
               table->recovered,
9582
3.55k
               0,
9583
3.55k
               &value_data_list,
9584
3.55k
               &value_data_cache,
9585
3.55k
               error ) != 1 )
9586
2.79k
          {
9587
2.79k
            libcerror_error_set(
9588
2.79k
             error,
9589
2.79k
             LIBCERROR_ERROR_DOMAIN_IO,
9590
2.79k
             LIBCERROR_IO_ERROR_READ_FAILED,
9591
2.79k
             "%s: unable to read record entry value data with descriptor: %" PRIu32 " - marked as missing.",
9592
2.79k
             function,
9593
2.79k
             (uint32_t) entry_value );
9594
9595
#if defined( HAVE_DEBUG_OUTPUT )
9596
            if( ( libcnotify_verbose != 0 )
9597
             && ( error != NULL )
9598
             && ( *error != NULL ) )
9599
            {
9600
              libcnotify_print_error_backtrace(
9601
               *error );
9602
            }
9603
#endif
9604
2.79k
            libcerror_error_free(
9605
2.79k
             error );
9606
9607
            /* If the data descriptor could not be read mark it as missing
9608
             * and give it an empty value data reference
9609
             */
9610
2.79k
            record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9611
2.79k
            table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9612
2.79k
          }
9613
3.55k
          if( libpff_local_descriptor_value_free(
9614
3.55k
               &local_descriptor_value,
9615
3.55k
               error ) != 1 )
9616
0
          {
9617
0
            libcerror_error_set(
9618
0
             error,
9619
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
9620
0
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
9621
0
             "%s: unable to free local descriptor values.",
9622
0
             function );
9623
9624
0
            goto on_error;
9625
0
          }
9626
3.55k
        }
9627
6.86k
      }
9628
      /* Check if the entry value is empty
9629
       */
9630
45.2k
      else if( entry_value == 0 )
9631
3.82k
      {
9632
#if defined( HAVE_DEBUG_OUTPUT )
9633
        if( libcnotify_verbose != 0 )
9634
        {
9635
          libcnotify_printf(
9636
           "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value\t\t\t: <NULL>\n",
9637
           function,
9638
           set_index,
9639
           entry_index );
9640
        }
9641
#endif
9642
3.82k
      }
9643
      /* Otherwise the entry value is a referenced table value
9644
       */
9645
41.3k
      else
9646
41.3k
      {
9647
#if defined( HAVE_DEBUG_OUTPUT )
9648
        if( libcnotify_verbose != 0 )
9649
        {
9650
          libcnotify_printf(
9651
           "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value (reference)\t\t: 0x%08" PRIx64 "\n",
9652
           function,
9653
           set_index,
9654
           entry_index,
9655
           entry_value );
9656
          libcnotify_printf(
9657
           "\n" );
9658
        }
9659
#endif
9660
        /* Fetch the record entry value reference
9661
         */
9662
41.3k
        result = libpff_table_get_index_value_by_reference(
9663
41.3k
            table,
9664
41.3k
            (uint32_t) entry_value,
9665
41.3k
            io_handle,
9666
41.3k
            &table_index_value,
9667
41.3k
            error );
9668
9669
41.3k
        if( result != 1 )
9670
7.85k
        {
9671
7.85k
          libcerror_error_set(
9672
7.85k
           error,
9673
7.85k
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9674
7.85k
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9675
7.85k
           "%s: unable to retrieve record entry value reference: 0x%08" PRIx64 ".",
9676
7.85k
           function,
9677
7.85k
           entry_value );
9678
9679
#if defined( HAVE_DEBUG_OUTPUT )
9680
          if( ( libcnotify_verbose != 0 )
9681
           && ( error != NULL )
9682
           && ( *error != NULL ) )
9683
          {
9684
            libcnotify_print_error_backtrace(
9685
             *error );
9686
          }
9687
#endif
9688
7.85k
          libcerror_error_free(
9689
7.85k
           error );
9690
9691
7.85k
          record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9692
7.85k
          table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9693
7.85k
        }
9694
33.5k
        else
9695
33.5k
        {
9696
33.5k
          if( libpff_table_get_value_data_by_index_value(
9697
33.5k
               table,
9698
33.5k
               table_index_value,
9699
33.5k
               file_io_handle,
9700
33.5k
               &record_entry_value_data,
9701
33.5k
               &record_entry_value_data_size,
9702
33.5k
               error ) != 1 )
9703
0
          {
9704
0
            libcerror_error_set(
9705
0
             error,
9706
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
9707
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9708
0
             "%s: unable to retrieve table value data by index value.",
9709
0
             function );
9710
9711
0
            goto on_error;
9712
0
          }
9713
33.5k
        }
9714
41.3k
      }
9715
52.1k
    }
9716
462
    else
9717
462
    {
9718
#if defined( HAVE_DEBUG_OUTPUT )
9719
      if( libcnotify_verbose != 0 )
9720
      {
9721
        libcnotify_printf(
9722
         "%s: table set: %03" PRIu32 " entry: %03" PRIu32 " record entry value (reference)\t\t: 0x%08" PRIx64 "\n",
9723
         function,
9724
         set_index,
9725
         entry_index,
9726
         entry_value );
9727
        libcnotify_printf(
9728
         "\n" );
9729
      }
9730
#endif
9731
462
      libcerror_error_set(
9732
462
       error,
9733
462
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9734
462
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9735
462
       "%s: unsupported value type: 0x%08" PRIx32 " with value size: %" PRIu8 ".",
9736
462
       function,
9737
462
       record_entry_value_type,
9738
462
       record_entry_value_size );
9739
9740
462
      goto on_error;
9741
462
    }
9742
79.8k
  }
9743
/* TODO is this check necessary do entry values get read more than once ? */
9744
78.7k
  if( record_entry->value_data == NULL )
9745
78.7k
  {
9746
78.7k
    if( value_data_list != NULL )
9747
762
    {
9748
762
      result = libpff_record_entry_set_value_data_from_list(
9749
762
                (libpff_record_entry_t *) record_entry,
9750
762
                file_io_handle,
9751
762
                value_data_list,
9752
762
                value_data_cache,
9753
762
                error );
9754
762
    }
9755
78.0k
    else
9756
78.0k
    {
9757
78.0k
      result = libpff_record_entry_set_value_data(
9758
78.0k
                (libpff_record_entry_t *) record_entry,
9759
78.0k
                record_entry_value_data,
9760
78.0k
                record_entry_value_data_size,
9761
78.0k
                error );
9762
78.0k
    }
9763
78.7k
    if( result != 1 )
9764
0
    {
9765
0
      libcerror_error_set(
9766
0
       error,
9767
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9768
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9769
0
       "%s: unable to set value data in record entry.",
9770
0
       function );
9771
9772
0
      goto on_error;
9773
0
    }
9774
78.7k
  }
9775
78.7k
  if( value_data_cache != NULL )
9776
762
  {
9777
762
    if( libfcache_cache_free(
9778
762
         &value_data_cache,
9779
762
         error ) != 1 )
9780
0
    {
9781
0
      libcerror_error_set(
9782
0
       error,
9783
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9784
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
9785
0
       "%s: unable to free value data cache.",
9786
0
       function );
9787
9788
0
      goto on_error;
9789
0
    }
9790
762
  }
9791
78.7k
  if( value_data_list != NULL )
9792
762
  {
9793
762
    if( libfdata_list_free(
9794
762
         &value_data_list,
9795
762
         error ) != 1 )
9796
0
    {
9797
0
      libcerror_error_set(
9798
0
       error,
9799
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9800
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
9801
0
       "%s: unable to free value data list.",
9802
0
       function );
9803
9804
0
      goto on_error;
9805
0
    }
9806
762
  }
9807
#if defined( HAVE_DEBUG_OUTPUT )
9808
  if( libcnotify_verbose != 0 )
9809
  {
9810
    if( libpff_debug_print_record_entry(
9811
         (libpff_record_entry_t *) record_entry,
9812
         name_to_id_map_list,
9813
         debug_item_type,
9814
         io_handle->ascii_codepage,
9815
         error ) != 1 )
9816
    {
9817
      libcerror_error_set(
9818
       error,
9819
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9820
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
9821
       "%s: unable to print record entry value reference.",
9822
       function );
9823
9824
      goto on_error;
9825
    }
9826
  }
9827
#endif
9828
78.7k
  return( 1 );
9829
9830
1.10k
on_error:
9831
1.10k
  if( value_data_cache != NULL )
9832
0
  {
9833
0
    libfcache_cache_free(
9834
0
     &value_data_cache,
9835
0
     NULL );
9836
0
  }
9837
1.10k
  if( value_data_list != NULL )
9838
0
  {
9839
0
    libfdata_list_free(
9840
0
     &value_data_list,
9841
0
     NULL );
9842
0
  }
9843
1.10k
  if( local_descriptor_value != NULL )
9844
0
  {
9845
0
    libpff_local_descriptor_value_free(
9846
0
     &local_descriptor_value,
9847
0
     NULL );
9848
0
  }
9849
1.10k
  return( -1 );
9850
78.7k
}
9851