Coverage Report

Created: 2025-06-13 07:21

/src/libpff/libpff/libpff_table.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Table functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <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
2.10k
{
72
2.10k
  static char *function = "libpff_table_initialize";
73
74
2.10k
  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
2.10k
  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
2.10k
  *table = memory_allocate_structure(
97
2.10k
            libpff_table_t );
98
99
2.10k
  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
2.10k
  if( memory_set(
111
2.10k
       *table,
112
2.10k
       0,
113
2.10k
       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
2.10k
  if( libpff_table_header_initialize(
130
2.10k
       &( ( *table )->header ),
131
2.10k
       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
2.10k
  if( libcdata_array_initialize(
143
2.10k
       &( ( *table )->index_array ),
144
2.10k
       0,
145
2.10k
       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
2.10k
  if( libcdata_array_initialize(
157
2.10k
       &( ( *table )->record_sets_array ),
158
2.10k
       0,
159
2.10k
       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
2.10k
  ( *table )->descriptor_identifier        = descriptor_identifier;
171
2.10k
  ( *table )->data_identifier              = data_identifier;
172
2.10k
  ( *table )->local_descriptors_identifier = local_descriptors_identifier;
173
2.10k
  ( *table )->recovered                    = recovered;
174
175
2.10k
  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
2.10k
}
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
2.10k
{
208
2.10k
  static char *function = "libpff_table_free";
209
2.10k
  int result            = 1;
210
211
2.10k
  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
2.10k
  if( *table != NULL )
223
2.10k
  {
224
2.10k
    if( ( *table )->descriptor_data_list != NULL )
225
1.58k
    {
226
1.58k
      if( libfdata_list_free(
227
1.58k
           &( ( *table )->descriptor_data_list ),
228
1.58k
           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
1.58k
    }
240
2.10k
    if( ( *table )->descriptor_data_cache != NULL )
241
1.58k
    {
242
1.58k
      if( libfcache_cache_free(
243
1.58k
           &( ( *table )->descriptor_data_cache ),
244
1.58k
           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
1.58k
    }
256
2.10k
    if( ( *table )->local_descriptors_tree != NULL )
257
1.68k
    {
258
1.68k
      if( libpff_local_descriptors_tree_free(
259
1.68k
           &( ( *table )->local_descriptors_tree ),
260
1.68k
           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
1.68k
    }
272
2.10k
    if( ( *table )->local_descriptor_values_cache != NULL )
273
1.68k
    {
274
1.68k
      if( libfcache_cache_free(
275
1.68k
           &( ( *table )->local_descriptor_values_cache ),
276
1.68k
           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
1.68k
    }
288
2.10k
    if( ( *table )->values_array_data_list != NULL )
289
22
    {
290
22
      if( libfdata_list_free(
291
22
           &( ( *table )->values_array_data_list ),
292
22
           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
22
    }
304
2.10k
    if( ( *table )->values_array_data_cache != NULL )
305
22
    {
306
22
      if( libfcache_cache_free(
307
22
           &( ( *table )->values_array_data_cache ),
308
22
           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
22
    }
320
2.10k
    if( libcdata_array_free(
321
2.10k
         &( ( *table )->record_sets_array ),
322
2.10k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
323
2.10k
         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
2.10k
    if( libcdata_array_free(
335
2.10k
         &( ( *table )->index_array ),
336
2.10k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_table_block_index_free,
337
2.10k
         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
2.10k
    if( libpff_table_header_free(
349
2.10k
         &( ( *table )->header ),
350
2.10k
         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
2.10k
    memory_free(
362
2.10k
     *table );
363
364
2.10k
    *table = NULL;
365
2.10k
  }
366
2.10k
  return( result );
367
2.10k
}
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
3.02k
{
516
3.02k
  libpff_record_set_t *record_set = NULL;
517
3.02k
  static char *function           = "libpff_table_resize_record_entries";
518
3.02k
  int last_number_of_sets         = 0;
519
3.02k
  int last_number_of_entries      = 0;
520
3.02k
  int set_index                   = 0;
521
522
3.02k
  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
3.02k
  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
3.02k
  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
3.02k
  if( libcdata_array_get_number_of_entries(
556
3.02k
       table->record_sets_array,
557
3.02k
       &last_number_of_sets,
558
3.02k
       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
3.02k
  if( last_number_of_sets > 0 )
570
1.41k
  {
571
1.41k
    if( libcdata_array_get_entry_by_index(
572
1.41k
         table->record_sets_array,
573
1.41k
         0,
574
1.41k
         (intptr_t **) &record_set,
575
1.41k
         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.41k
    if( libpff_record_set_get_number_of_entries(
587
1.41k
         record_set,
588
1.41k
         &last_number_of_entries,
589
1.41k
         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.41k
    record_set = NULL;
601
1.41k
  }
602
3.02k
  if( libcdata_array_resize(
603
3.02k
       table->record_sets_array,
604
3.02k
       number_of_sets,
605
3.02k
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_internal_record_set_free,
606
3.02k
       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
3.02k
  if( number_of_sets > last_number_of_sets )
618
2.09k
  {
619
2.09k
    for( set_index = last_number_of_sets;
620
12.9k
         set_index < number_of_sets;
621
10.8k
         set_index++ )
622
10.8k
    {
623
10.8k
      if( libpff_record_set_initialize(
624
10.8k
           &record_set,
625
10.8k
           last_number_of_entries,
626
10.8k
           ascii_codepage,
627
10.8k
           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
10.8k
      if( libcdata_array_set_entry_by_index(
640
10.8k
           table->record_sets_array,
641
10.8k
           set_index,
642
10.8k
           (intptr_t *) record_set,
643
10.8k
           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
10.8k
      record_set = NULL;
656
10.8k
    }
657
2.09k
    last_number_of_sets = number_of_sets;
658
2.09k
  }
659
3.02k
  if( last_number_of_sets > 0 )
660
2.34k
  {
661
2.34k
    for( set_index = 0;
662
545k
         set_index < last_number_of_sets;
663
543k
         set_index++ )
664
543k
    {
665
543k
      if( libcdata_array_get_entry_by_index(
666
543k
           table->record_sets_array,
667
543k
           set_index,
668
543k
           (intptr_t **) &record_set,
669
543k
           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
543k
      if( libpff_record_set_resize(
684
543k
           record_set,
685
543k
           number_of_entries,
686
543k
           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
543k
    }
701
2.34k
    last_number_of_entries = number_of_entries;
702
2.34k
  }
703
3.02k
  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
3.02k
}
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
243
{
751
243
  libpff_record_set_t *record_set = NULL;
752
243
  static char *function           = "libpff_table_expand_record_entries";
753
243
  int last_number_of_sets         = 0;
754
243
  int last_number_of_entries      = 0;
755
756
243
  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
243
  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
243
  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
243
  if( libcdata_array_get_number_of_entries(
790
243
       table->record_sets_array,
791
243
       &last_number_of_sets,
792
243
       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
243
  if( last_number_of_sets > 0 )
804
243
  {
805
243
    if( libcdata_array_get_entry_by_index(
806
243
         table->record_sets_array,
807
243
         0,
808
243
         (intptr_t **) &record_set,
809
243
         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
243
    if( libpff_record_set_get_number_of_entries(
821
243
         record_set,
822
243
         &last_number_of_entries,
823
243
         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
243
  }
835
243
  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
243
  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
243
  if( libpff_table_resize_record_entries(
858
243
       table,
859
243
       last_number_of_sets + number_of_sets,
860
243
       last_number_of_entries + number_of_entries,
861
243
       ascii_codepage,
862
243
       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
243
  return( 1 );
874
243
}
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
105k
{
935
105k
  libpff_table_block_index_t *table_block_index = NULL;
936
105k
  static char *function                         = "libpff_table_get_index_value_by_reference";
937
105k
  uint16_t table_index_array_reference          = 0;
938
105k
  uint16_t table_index_value_reference          = 0;
939
940
105k
  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
105k
  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
105k
  if( ( io_handle->file_type != LIBPFF_FILE_TYPE_32BIT )
963
105k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT )
964
105k
   && ( 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
105k
  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
105k
  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
105k
  if( ( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
1002
105k
   || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) )
1003
105k
  {
1004
105k
    table_index_array_reference = (uint16_t) ( table_index_reference >> 16 );
1005
105k
  }
1006
0
  else
1007
0
  {
1008
0
    table_index_array_reference = (uint16_t) ( table_index_reference >> 19 );
1009
0
  }
1010
105k
  if( libcdata_array_get_entry_by_index(
1011
105k
       table->index_array,
1012
105k
       (int) table_index_array_reference,
1013
105k
       (intptr_t **) &table_block_index,
1014
105k
       error ) != 1 )
1015
1.61k
  {
1016
1.61k
    libcerror_error_set(
1017
1.61k
     error,
1018
1.61k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1019
1.61k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1020
1.61k
     "%s: unable to retrieve table index array entry: %" PRIu16 ".",
1021
1.61k
     function,
1022
1.61k
     table_index_array_reference );
1023
1024
1.61k
    return( -1 );
1025
1.61k
  }
1026
103k
  if( ( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
1027
103k
   || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT ) )
1028
103k
  {
1029
103k
    table_index_value_reference = (uint16_t) ( ( table_index_reference & 0x0000ffe0 ) >> 5 ) - 1;
1030
103k
  }
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
103k
  if( libpff_table_block_index_get_value_by_index(
1046
103k
       table_block_index,
1047
103k
       table_index_value_reference,
1048
103k
       table_index_value,
1049
103k
       error ) != 1 )
1050
1.16k
  {
1051
1.16k
    libcerror_error_set(
1052
1.16k
     error,
1053
1.16k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1054
1.16k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1055
1.16k
     "%s: unable to retrieve table block index value: %" PRIu16 ".",
1056
1.16k
     function,
1057
1.16k
                 table_index_value_reference );
1058
1059
1.16k
    return( -1 );
1060
1.16k
  }
1061
102k
  return( 1 );
1062
103k
}
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
102k
{
1075
102k
  libpff_data_block_t *data_block = NULL;
1076
102k
  static char *function           = "libpff_table_get_value_data_by_index_value";
1077
1078
102k
  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
102k
  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
102k
  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
102k
  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
102k
  if( libfdata_list_get_element_value_by_index(
1125
102k
       table->descriptor_data_list,
1126
102k
       (intptr_t *) file_io_handle,
1127
102k
       (libfdata_cache_t *) table->descriptor_data_cache,
1128
102k
       (int) table_index_value->array_entry,
1129
102k
       (intptr_t **) &data_block,
1130
102k
       0,
1131
102k
       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
102k
  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
102k
  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
102k
  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
102k
  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
102k
  *value_data      = &( data_block->data[ table_index_value->offset ] );
1190
102k
  *value_data_size = (size_t) table_index_value->size;
1191
1192
102k
  return( 1 );
1193
102k
}
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
96.9k
{
1207
96.9k
  libpff_table_index_value_t *table_index_value = NULL;
1208
96.9k
  static char *function                         = "libpff_table_get_value_data_by_reference";
1209
1210
  /* Retrieve the index value of the record entries reference
1211
   */
1212
96.9k
  if( libpff_table_get_index_value_by_reference(
1213
96.9k
       table,
1214
96.9k
       table_index_reference,
1215
96.9k
       io_handle,
1216
96.9k
       &table_index_value,
1217
96.9k
       error ) != 1 )
1218
62
  {
1219
62
    libcerror_error_set(
1220
62
     error,
1221
62
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1222
62
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1223
62
     "%s: unable to retrieve table index value.",
1224
62
     function );
1225
1226
62
    return( -1 );
1227
62
  }
1228
96.8k
  if( libpff_table_get_value_data_by_index_value(
1229
96.8k
       table,
1230
96.8k
       table_index_value,
1231
96.8k
       file_io_handle,
1232
96.8k
       value_data,
1233
96.8k
       value_data_size,
1234
96.8k
       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
96.8k
  return( 1 );
1246
96.8k
}
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
88.2k
{
1260
88.2k
  uint8_t *table_value_data    = NULL;
1261
88.2k
  static char *function        = "libpff_table_clone_value_data_by_reference";
1262
88.2k
  size_t table_value_data_size = 0;
1263
1264
88.2k
  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
88.2k
  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
88.2k
  if( libpff_table_get_value_data_by_reference(
1287
88.2k
       table,
1288
88.2k
       io_handle,
1289
88.2k
       file_io_handle,
1290
88.2k
       table_index_reference,
1291
88.2k
       &table_value_data,
1292
88.2k
       &table_value_data_size,
1293
88.2k
       error ) != 1 )
1294
49
  {
1295
49
    libcerror_error_set(
1296
49
     error,
1297
49
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1298
49
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1299
49
     "%s: unable to retrieve value data.",
1300
49
     function );
1301
1302
49
    goto on_error;
1303
49
  }
1304
88.1k
  if( ( table_value_data == NULL )
1305
88.1k
   || ( table_value_data_size == 0 ) )
1306
1
  {
1307
1
    libcerror_error_set(
1308
1
     error,
1309
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1310
1
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1311
1
     "%s: missing values array data.",
1312
1
     function );
1313
1314
1
    goto on_error;
1315
1
  }
1316
88.1k
  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
88.1k
  *value_data = (uint8_t *) memory_allocate(
1328
88.1k
                             table_value_data_size );
1329
1330
88.1k
  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
88.1k
  *value_data_size = table_value_data_size;
1342
1343
88.1k
  if( memory_copy(
1344
88.1k
       *value_data,
1345
88.1k
       table_value_data,
1346
88.1k
       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
88.1k
  return( 1 );
1358
1359
50
on_error:
1360
50
  if( *value_data != NULL )
1361
0
  {
1362
0
    memory_free(
1363
0
     *value_data );
1364
1365
0
    *value_data = NULL;
1366
0
  }
1367
50
  *value_data_size = 0;
1368
1369
50
  return( -1 );
1370
88.1k
}
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
0
{
1380
0
  static char *function = "libpff_table_get_number_of_record_sets";
1381
1382
0
  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
0
  if( libcdata_array_get_number_of_entries(
1394
0
       table->record_sets_array,
1395
0
       number_of_record_sets,
1396
0
       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
0
  return( 1 );
1408
0
}
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
0
{
1419
0
  static char *function = "libpff_table_get_record_set_by_index";
1420
1421
0
  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
0
  if( libcdata_array_get_entry_by_index(
1433
0
       table->record_sets_array,
1434
0
       record_set_index,
1435
0
       (intptr_t **) record_set,
1436
0
       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
0
  return( 1 );
1449
0
}
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
30.1k
{
1686
30.1k
  libpff_record_set_t *record_set = NULL;
1687
30.1k
  static char *function           = "libpff_table_get_record_entry_by_index";
1688
1689
30.1k
  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
30.1k
  if( libcdata_array_get_entry_by_index(
1701
30.1k
       table->record_sets_array,
1702
30.1k
       set_index,
1703
30.1k
       (intptr_t **) &record_set,
1704
30.1k
       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
30.1k
  if( libpff_record_set_get_entry_by_index(
1717
30.1k
       record_set,
1718
30.1k
       entry_index,
1719
30.1k
       record_entry,
1720
30.1k
       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
30.1k
  return( 1 );
1734
30.1k
}
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
367
{
1759
367
  libpff_record_set_t *record_set = NULL;
1760
367
  static char *function           = "libpff_table_get_record_entry_by_type";
1761
367
  int number_of_sets              = 0;
1762
367
  int result                      = 0;
1763
1764
367
  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
367
  if( libcdata_array_get_number_of_entries(
1776
367
       table->record_sets_array,
1777
367
       &number_of_sets,
1778
367
       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
367
  if( number_of_sets == 0 )
1790
5
  {
1791
5
    return( 0 );
1792
5
  }
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
362
  if( libcdata_array_get_entry_by_index(
1804
362
       table->record_sets_array,
1805
362
       set_index,
1806
362
       (intptr_t **) &record_set,
1807
362
       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
362
  result = libpff_record_set_get_entry_by_type(
1820
362
            record_set,
1821
362
            entry_type,
1822
362
            value_type,
1823
362
            record_entry,
1824
362
            flags,
1825
362
            error );
1826
1827
362
  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
362
  return( result );
1840
362
}
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
2.10k
{
2064
2.10k
  libpff_data_block_t *data_block               = NULL;
2065
2.10k
  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
2.10k
  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
2.10k
  if( table->data_identifier == 0 )
2090
1
  {
2091
1
    libcerror_error_set(
2092
1
     error,
2093
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2094
1
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2095
1
     "%s: invalid table - missing data identifier.",
2096
1
     function );
2097
2098
1
    return( -1 );
2099
1
  }
2100
2.10k
  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
2.10k
  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
2.10k
  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
2.10k
  if( table->local_descriptors_identifier > 0 )
2134
1.68k
  {
2135
1.68k
    if( libpff_local_descriptors_tree_initialize(
2136
1.68k
         &( table->local_descriptors_tree ),
2137
1.68k
         io_handle,
2138
1.68k
         offsets_index,
2139
1.68k
         table->descriptor_identifier,
2140
1.68k
         table->local_descriptors_identifier,
2141
1.68k
         table->recovered,
2142
1.68k
         table->recovered_local_descriptors_identifier_value_index,
2143
1.68k
         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
1.68k
    if( libfcache_cache_initialize(
2156
1.68k
         &( table->local_descriptor_values_cache ),
2157
1.68k
         LIBPFF_MAXIMUM_CACHE_ENTRIES_LOCAL_DESCRIPTORS_VALUES,
2158
1.68k
         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
1.68k
  }
2176
2.10k
  if( libpff_table_read_descriptor_data_list(
2177
2.10k
       table,
2178
2.10k
       io_handle,
2179
2.10k
       file_io_handle,
2180
2.10k
       offsets_index,
2181
2.10k
       table->descriptor_identifier,
2182
2.10k
       table->data_identifier,
2183
2.10k
       table->recovered,
2184
2.10k
       table->recovered_data_identifier_value_index,
2185
2.10k
       &( table->descriptor_data_list ),
2186
2.10k
       &( table->descriptor_data_cache ),
2187
2.10k
       error ) != 1 )
2188
522
  {
2189
522
    libcerror_error_set(
2190
522
     error,
2191
522
     LIBCERROR_ERROR_DOMAIN_IO,
2192
522
     LIBCERROR_IO_ERROR_READ_FAILED,
2193
522
     "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
2194
522
     function,
2195
522
     table->descriptor_identifier,
2196
522
     table->data_identifier );
2197
2198
522
    return( -1 );
2199
522
  }
2200
  /* Retrieve the first table data block
2201
   */
2202
1.58k
  if( libfdata_list_get_element_value_by_index(
2203
1.58k
       table->descriptor_data_list,
2204
1.58k
       (intptr_t *) file_io_handle,
2205
1.58k
       (libfdata_cache_t *) table->descriptor_data_cache,
2206
1.58k
       0,
2207
1.58k
       (intptr_t **) &data_block,
2208
1.58k
       0,
2209
1.58k
       error ) != 1 )
2210
4
  {
2211
4
    libcerror_error_set(
2212
4
     error,
2213
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2214
4
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2215
4
     "%s: unable to retrieve data block: 0.",
2216
4
     function );
2217
2218
4
    return( -1 );
2219
4
  }
2220
1.58k
  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
1.58k
  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
1.58k
  if( data_block->uncompressed_data_size < sizeof( pff_table_t ) )
2243
134
  {
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
134
    libcerror_error_set(
2257
134
     error,
2258
134
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2259
134
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2260
134
     "%s: data block: 0 too small to be a table.",
2261
134
     function );
2262
2263
134
    return( -1 );
2264
134
  }
2265
1.44k
  if( libpff_table_header_read_data(
2266
1.44k
       table->header,
2267
1.44k
       data_block->data,
2268
1.44k
       data_block->uncompressed_data_size,
2269
1.44k
       error ) != 1 )
2270
92
  {
2271
92
    libcerror_error_set(
2272
92
     error,
2273
92
     LIBCERROR_ERROR_DOMAIN_IO,
2274
92
     LIBCERROR_IO_ERROR_READ_FAILED,
2275
92
     "%s: unable to read table header.",
2276
92
     function );
2277
2278
92
    return( -1 );
2279
92
  }
2280
1.35k
  if( libpff_table_read_index(
2281
1.35k
       table,
2282
1.35k
       file_io_handle,
2283
1.35k
       error ) != 1 )
2284
84
  {
2285
84
    libcerror_error_set(
2286
84
     error,
2287
84
     LIBCERROR_ERROR_DOMAIN_IO,
2288
84
     LIBCERROR_IO_ERROR_READ_FAILED,
2289
84
     "%s: unable to read table index.",
2290
84
     function );
2291
2292
84
    return( -1 );
2293
84
  }
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
1.27k
  if( libpff_table_read_values(
2418
1.27k
       table,
2419
1.27k
       io_handle,
2420
1.27k
       file_io_handle,
2421
1.27k
       offsets_index,
2422
1.27k
       name_to_id_map_list,
2423
1.27k
       debug_item_type,
2424
1.27k
       error ) != 1 )
2425
1.02k
  {
2426
1.02k
    libcerror_error_set(
2427
1.02k
     error,
2428
1.02k
     LIBCERROR_ERROR_DOMAIN_IO,
2429
1.02k
     LIBCERROR_IO_ERROR_READ_FAILED,
2430
1.02k
     "%s: unable to read table values.",
2431
1.02k
     function );
2432
2433
1.02k
    return( -1 );
2434
1.02k
  }
2435
#if defined( HAVE_DEBUG_OUTPUT )
2436
  if( libcnotify_verbose != 0 )
2437
  {
2438
    libcnotify_printf(
2439
     "\n" );
2440
  }
2441
#endif
2442
243
  return( 1 );
2443
1.27k
}
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
5.21k
{
2461
5.21k
  libpff_data_array_t *data_array          = NULL;
2462
5.21k
  libpff_data_block_t *data_block          = NULL;
2463
5.21k
  libpff_index_value_t *offset_index_value = NULL;
2464
5.21k
  static char *function                    = "libpff_table_read_descriptor_data_list";
2465
5.21k
  uint32_t total_data_size                 = 0;
2466
5.21k
  int element_index                        = 0;
2467
2468
5.21k
  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
5.21k
  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
5.21k
  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
5.21k
  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
5.21k
  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
5.21k
  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
5.21k
  if( libpff_offsets_index_get_index_value_by_identifier(
2535
5.21k
       offsets_index,
2536
5.21k
       io_handle,
2537
5.21k
       file_io_handle,
2538
5.21k
       data_identifier,
2539
5.21k
       recovered,
2540
5.21k
       recovered_value_index,
2541
5.21k
       &offset_index_value,
2542
5.21k
       error ) != 1 )
2543
1.18k
  {
2544
1.18k
    libcerror_error_set(
2545
1.18k
     error,
2546
1.18k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2547
1.18k
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2548
1.18k
     "%s: unable to find offset index value identifier: %" PRIu64 ".",
2549
1.18k
     function,
2550
1.18k
     data_identifier );
2551
2552
1.18k
    goto on_error;
2553
1.18k
  }
2554
4.03k
  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
4.03k
  if( offset_index_value->file_offset <= 0 )
2578
80
  {
2579
80
    libcerror_error_set(
2580
80
     error,
2581
80
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2582
80
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2583
80
     "%s: invalid offset index value - file offset value out of bounds.",
2584
80
     function );
2585
2586
80
    goto on_error;
2587
80
  }
2588
3.95k
  if( offset_index_value->data_size == 0 )
2589
72
  {
2590
72
    libcerror_error_set(
2591
72
     error,
2592
72
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2593
72
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2594
72
     "%s: invalid offset index value - data size value value out of bounds.",
2595
72
     function );
2596
2597
72
    goto on_error;
2598
72
  }
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
3.88k
  if( libpff_data_block_initialize(
2613
3.88k
       &data_block,
2614
3.88k
       io_handle,
2615
3.88k
       descriptor_identifier,
2616
3.88k
       data_identifier,
2617
3.88k
       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
3.88k
  if( libpff_data_block_read_file_io_handle(
2629
3.88k
       data_block,
2630
3.88k
       file_io_handle,
2631
3.88k
       offset_index_value->file_offset,
2632
3.88k
       offset_index_value->data_size,
2633
3.88k
       io_handle->file_type,
2634
3.88k
       error ) != 1 )
2635
383
  {
2636
383
    libcerror_error_set(
2637
383
     error,
2638
383
     LIBCERROR_ERROR_DOMAIN_IO,
2639
383
     LIBCERROR_IO_ERROR_READ_FAILED,
2640
383
     "%s: unable to read data block at offset: %" PRIi64 ".",
2641
383
     function,
2642
383
     offset_index_value->file_offset );
2643
2644
383
    goto on_error;
2645
383
  }
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
3.49k
  if( ( ( data_identifier & (uint64_t) LIBPFF_OFFSET_INDEX_IDENTIFIER_FLAG_INTERNAL ) != 0 )
2651
3.49k
   && ( ( data_block->data[ 0 ] == 0x01 )
2652
1.83k
    &&  ( ( data_block->data[ 1 ] == 0x01 )
2653
1.69k
     ||   ( data_block->data[ 1 ] == 0x02 ) ) ) )
2654
1.60k
  {
2655
1.60k
    if( libpff_data_array_initialize(
2656
1.60k
         &data_array,
2657
1.60k
         io_handle,
2658
1.60k
         descriptor_identifier,
2659
1.60k
         data_identifier,
2660
1.60k
         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.60k
    if( libfdata_list_initialize(
2672
1.60k
         descriptor_data_list,
2673
1.60k
         (intptr_t *) data_array,
2674
1.60k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_array_free,
2675
1.60k
         (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_array_clone,
2676
1.60k
         (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.60k
         NULL,
2678
1.60k
         LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
2679
1.60k
         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.60k
    if( libpff_data_array_read_entries(
2693
1.60k
         data_array,
2694
1.60k
         io_handle,
2695
1.60k
         file_io_handle,
2696
1.60k
         offsets_index,
2697
1.60k
         *descriptor_data_list,
2698
1.60k
         recovered,
2699
1.60k
         data_block->data,
2700
1.60k
         (size_t) data_block->uncompressed_data_size,
2701
1.60k
         &total_data_size,
2702
1.60k
         0,
2703
1.60k
         error ) != 1 )
2704
1.16k
    {
2705
1.16k
      libcerror_error_set(
2706
1.16k
       error,
2707
1.16k
       LIBCERROR_ERROR_DOMAIN_IO,
2708
1.16k
       LIBCERROR_IO_ERROR_READ_FAILED,
2709
1.16k
       "%s: unable to read data array entries.",
2710
1.16k
       function );
2711
2712
1.16k
      data_array = NULL;
2713
2714
1.16k
      goto on_error;
2715
1.16k
    }
2716
440
    if( libpff_data_block_free(
2717
440
         &data_block,
2718
440
         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
440
    if( libfcache_cache_initialize(
2732
440
         descriptor_data_cache,
2733
440
         LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_ARRAY,
2734
440
         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
440
  }
2748
1.89k
  else
2749
1.89k
  {
2750
1.89k
    if( libpff_data_block_decrypt_data(
2751
1.89k
         data_block,
2752
1.89k
         0,
2753
1.89k
         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
1.89k
    if( libfdata_list_initialize(
2766
1.89k
         descriptor_data_list,
2767
1.89k
         (intptr_t *) data_block,
2768
1.89k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free,
2769
1.89k
         (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_block_clone,
2770
1.89k
         (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
1.89k
         NULL,
2772
1.89k
         LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
2773
1.89k
         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
1.89k
    if( libfdata_list_append_element_with_mapped_size(
2787
1.89k
         *descriptor_data_list,
2788
1.89k
         &element_index,
2789
1.89k
         0,
2790
1.89k
         offset_index_value->file_offset,
2791
1.89k
         (size64_t) offset_index_value->data_size,
2792
1.89k
         0,
2793
1.89k
         (size_t) data_block->uncompressed_data_size,
2794
1.89k
         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
1.89k
    if( libfcache_cache_initialize(
2808
1.89k
         descriptor_data_cache,
2809
1.89k
         LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_BLOCK,
2810
1.89k
         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
1.89k
    if( libfdata_list_set_element_value_by_index(
2826
1.89k
         *descriptor_data_list,
2827
1.89k
         (intptr_t *) file_io_handle,
2828
1.89k
         (libfdata_cache_t *) *descriptor_data_cache,
2829
1.89k
         0,
2830
1.89k
         (intptr_t *) data_block,
2831
1.89k
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free,
2832
1.89k
         LIBFDATA_LIST_ELEMENT_VALUE_FLAG_NON_MANAGED,
2833
1.89k
         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
1.89k
  }
2847
2.33k
  if( libpff_index_value_free(
2848
2.33k
       &offset_index_value,
2849
2.33k
       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
2.33k
  return( 1 );
2861
2862
2.88k
on_error:
2863
2.88k
  if( *descriptor_data_cache != NULL )
2864
0
  {
2865
0
    libfcache_cache_free(
2866
0
     descriptor_data_cache,
2867
0
     NULL );
2868
0
  }
2869
2.88k
  if( *descriptor_data_list != NULL )
2870
1.16k
  {
2871
1.16k
    libfdata_list_free(
2872
1.16k
     descriptor_data_list,
2873
1.16k
     NULL );
2874
1.16k
  }
2875
2.88k
  if( data_array != NULL )
2876
0
  {
2877
0
    libpff_data_array_free(
2878
0
     &data_array,
2879
0
     NULL );
2880
0
  }
2881
2.88k
  if( data_block != NULL )
2882
1.54k
  {
2883
1.54k
    libpff_data_block_free(
2884
1.54k
     &data_block,
2885
1.54k
     NULL );
2886
1.54k
  }
2887
2.88k
  if( offset_index_value != NULL )
2888
1.69k
  {
2889
1.69k
    libpff_index_value_free(
2890
1.69k
     &offset_index_value,
2891
1.69k
     NULL );
2892
1.69k
  }
2893
2.88k
  return( -1 );
2894
2.33k
}
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
1.35k
{
2906
1.35k
  libpff_table_index_value_t *table_index_value = NULL;
2907
1.35k
  static char *function                         = "libpff_table_read_index_entries";
2908
1.35k
  size_t data_offset                            = 0;
2909
1.35k
  uint32_t table_index_offsets_data_size        = 0;
2910
1.35k
  uint16_t table_block_value_index              = 0;
2911
1.35k
  uint16_t table_index_offset                   = 0;
2912
1.35k
  uint16_t table_index_value_iterator           = 0;
2913
1.35k
  uint16_t table_number_of_index_offsets        = 0;
2914
1.35k
  uint16_t table_number_of_unused_index_offsets = 0;
2915
1.35k
  uint16_t table_value_end_offset               = 0;
2916
1.35k
  uint16_t table_value_start_offset             = 0;
2917
2918
1.35k
  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
1.35k
  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
1.35k
  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
1.35k
  if( data_block->uncompressed_data_size < 4 )
2952
0
  {
2953
0
    libcerror_error_set(
2954
0
     error,
2955
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2956
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2957
0
     "%s: invalid data block - uncompressed data size value out of bounds.",
2958
0
     function );
2959
2960
0
    return( -1 );
2961
0
  }
2962
1.35k
  byte_stream_copy_to_uint16_little_endian(
2963
1.35k
   data_block->data,
2964
1.35k
   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
1.35k
  if( ( table_index_offset == 0 )
2976
1.35k
   || ( (uint32_t) table_index_offset >= ( data_block->uncompressed_data_size - 4 ) ) )
2977
22
  {
2978
22
    libcerror_error_set(
2979
22
     error,
2980
22
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2981
22
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2982
22
     "%s: invalid table index offset value out of bounds: %zd.",
2983
22
     function, table_index_offset );
2984
2985
22
    goto on_error;
2986
22
  }
2987
  /* Determine which values are in the table using the index
2988
   */
2989
1.33k
        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
1.33k
  byte_stream_copy_to_uint16_little_endian(
3004
1.33k
   ( (pff_table_index_t *) &( data_block->data[ data_offset ] ) )->number_of_offsets,
3005
1.33k
   table_number_of_index_offsets );
3006
3007
1.33k
  byte_stream_copy_to_uint16_little_endian(
3008
1.33k
   ( (pff_table_index_t *) &( data_block->data[ data_offset ] ) )->number_of_unused_offsets,
3009
1.33k
   table_number_of_unused_index_offsets );
3010
3011
1.33k
  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
1.33k
  if( table_number_of_index_offsets > 0 )
3032
1.29k
  {
3033
1.29k
    table_index_offsets_data_size = (uint32_t) table_number_of_index_offsets * 2;
3034
3035
1.29k
    if( ( table_index_offsets_data_size > ( data_block->uncompressed_data_size - 4 ) )
3036
1.29k
     || ( (uint32_t) table_index_offset >= ( data_block->uncompressed_data_size - 4 - table_index_offsets_data_size ) ) )
3037
26
    {
3038
26
      libcerror_error_set(
3039
26
       error,
3040
26
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3041
26
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3042
26
       "%s: invalid number of index offsets value out of bounds.",
3043
26
       function );
3044
3045
26
      goto on_error;
3046
26
    }
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
1.27k
    byte_stream_copy_to_uint16_little_endian(
3065
1.27k
     &( data_block->data[ data_offset ] ),
3066
1.27k
     table_value_start_offset );
3067
3068
1.27k
    data_offset += 2;
3069
3070
1.27k
    for( table_index_value_iterator = 0;
3071
34.4k
         table_index_value_iterator < table_number_of_index_offsets;
3072
33.2k
         table_index_value_iterator++ )
3073
33.2k
    {
3074
33.2k
      byte_stream_copy_to_uint16_little_endian(
3075
33.2k
       &( data_block->data[ data_offset ] ),
3076
33.2k
       table_value_end_offset );
3077
3078
33.2k
      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
33.2k
      if( table_value_start_offset > table_value_end_offset )
3092
15
      {
3093
15
        libcerror_error_set(
3094
15
         error,
3095
15
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3096
15
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3097
15
         "%s: table index start offset: %" PRIu16 " exceeds end offset: %" PRIu16 ".",
3098
15
         function,
3099
15
         table_value_start_offset,
3100
15
         table_value_end_offset );
3101
3102
15
        goto on_error;
3103
15
      }
3104
33.2k
      if( libpff_table_index_value_initialize(
3105
33.2k
           &table_index_value,
3106
33.2k
           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
33.2k
      table_index_value->array_entry = table_array_entry_iterator;
3120
33.2k
      table_index_value->offset      = table_value_start_offset;
3121
33.2k
      table_index_value->size        = table_value_end_offset - table_value_start_offset;
3122
3123
33.2k
      if( libpff_table_block_index_append_value(
3124
33.2k
           table_block_index,
3125
33.2k
           &table_block_value_index,
3126
33.2k
           table_index_value,
3127
33.2k
           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
33.2k
      table_index_value = NULL;
3140
3141
33.2k
      table_value_start_offset = table_value_end_offset;
3142
33.2k
    }
3143
1.25k
    if( table_value_end_offset > table_index_offset )
3144
21
    {
3145
21
      libcerror_error_set(
3146
21
       error,
3147
21
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3148
21
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3149
21
       "%s: last table index value end offset: %" PRIu16 " exceeds table index offset: %" PRIu16 ".",
3150
21
       function,
3151
21
       table_value_end_offset,
3152
21
       table_index_offset );
3153
3154
21
      goto on_error;
3155
21
    }
3156
1.25k
  }
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
1.27k
  return( 1 );
3190
3191
84
on_error:
3192
84
  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
84
  return( -1 );
3199
1.33k
}
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
1.35k
{
3209
1.35k
  libpff_data_block_t *data_block               = NULL;
3210
1.35k
  libpff_table_block_index_t *table_block_index = NULL;
3211
1.35k
  static char *function                         = "libpff_table_read_index";
3212
1.35k
  int number_of_table_array_entries             = 0;
3213
1.35k
  int table_array_entry_iterator                = 0;
3214
3215
#if defined( HAVE_DEBUG_OUTPUT )
3216
  size_t table_data_offset                      = 0;
3217
#endif
3218
3219
1.35k
  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
1.35k
  if( libfdata_list_get_number_of_elements(
3231
1.35k
       table->descriptor_data_list,
3232
1.35k
       &number_of_table_array_entries,
3233
1.35k
       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
1.35k
  if( libcdata_array_resize(
3245
1.35k
       table->index_array,
3246
1.35k
       number_of_table_array_entries,
3247
1.35k
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_table_block_index_free,
3248
1.35k
       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
1.35k
  for( table_array_entry_iterator = 0;
3262
2.62k
       table_array_entry_iterator < number_of_table_array_entries;
3263
1.35k
       table_array_entry_iterator++ )
3264
1.35k
  {
3265
1.35k
    if( libfdata_list_get_element_value_by_index(
3266
1.35k
         table->descriptor_data_list,
3267
1.35k
         (intptr_t *) file_io_handle,
3268
1.35k
         (libfdata_cache_t *) table->descriptor_data_cache,
3269
1.35k
         table_array_entry_iterator,
3270
1.35k
         (intptr_t **) &data_block,
3271
1.35k
         0,
3272
1.35k
         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
1.35k
    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
1.35k
    if( libpff_table_block_index_initialize(
3311
1.35k
         &table_block_index,
3312
1.35k
         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
1.35k
    if( libpff_table_read_index_entries(
3324
1.35k
         table,
3325
1.35k
         data_block,
3326
1.35k
         table_block_index,
3327
1.35k
         (uint32_t) table_array_entry_iterator,
3328
1.35k
         error ) != 1 )
3329
84
    {
3330
84
      libcerror_error_set(
3331
84
       error,
3332
84
       LIBCERROR_ERROR_DOMAIN_IO,
3333
84
       LIBCERROR_IO_ERROR_READ_FAILED,
3334
84
       "%s: unable to read index entries.",
3335
84
       function );
3336
3337
84
      goto on_error;
3338
84
    }
3339
1.27k
    if( libcdata_array_set_entry_by_index(
3340
1.27k
         table->index_array,
3341
1.27k
         table_array_entry_iterator,
3342
1.27k
         (intptr_t *) table_block_index,
3343
1.27k
         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
1.27k
    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
1.27k
  }
3361
#if defined( HAVE_DEBUG_OUTPUT )
3362
  if( libcnotify_verbose != 0 )
3363
  {
3364
    libcnotify_printf(
3365
     "\n" );
3366
  }
3367
#endif
3368
1.27k
  return( 1 );
3369
3370
84
on_error:
3371
84
  if( table_block_index != NULL )
3372
84
  {
3373
84
    libpff_table_block_index_free(
3374
84
     &table_block_index,
3375
84
     NULL );
3376
84
  }
3377
84
  return( -1 );
3378
1.35k
}
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
320k
{
3394
320k
  libpff_reference_descriptor_t *reference_descriptor = NULL;
3395
320k
  uint8_t *record_entries_data                        = NULL;
3396
320k
  uint8_t *record_entry_data                          = NULL;
3397
320k
  static char *function                               = "libpff_table_read_record_entries";
3398
320k
  size_t number_of_record_entries                     = 0;
3399
320k
  size_t record_entries_data_size                     = 0;
3400
320k
  size_t record_entry_size                            = 0;
3401
320k
  uint32_t sub_record_entries_reference               = 0;
3402
320k
  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
320k
  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
320k
  if( ( record_entry_identifier_size != 2 )
3424
320k
   && ( record_entry_identifier_size != 4 )
3425
320k
   && ( record_entry_identifier_size != 8 )
3426
320k
   && ( 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
320k
  if( ( recursion_depth < 0 )
3439
320k
   || ( 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
320k
  if( record_entries_reference == 0 )
3466
194k
  {
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
194k
    return( 1 );
3476
194k
  }
3477
126k
  if( ( record_entries_reference & 0x0000001fUL ) != 0 )
3478
65
  {
3479
65
    libcerror_error_set(
3480
65
     error,
3481
65
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3482
65
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3483
65
     "%s: unsupported record entries reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3484
65
     function,
3485
65
     record_entries_reference & 0x0000001fUL,
3486
65
     record_entries_reference );
3487
3488
65
    goto on_error;
3489
65
  }
3490
126k
  if( record_entries_level == 0 )
3491
39.9k
  {
3492
39.9k
    if( libpff_reference_descriptor_initialize(
3493
39.9k
         &reference_descriptor,
3494
39.9k
         record_entries_reference,
3495
39.9k
         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
39.9k
    if( libcdata_array_append_entry(
3507
39.9k
         record_entries_references_array,
3508
39.9k
         &record_entry_index,
3509
39.9k
         (intptr_t *) reference_descriptor,
3510
39.9k
         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
39.9k
    reference_descriptor = NULL;
3522
39.9k
  }
3523
86.3k
  else
3524
86.3k
  {
3525
86.3k
    if( libpff_table_clone_value_data_by_reference(
3526
86.3k
         table,
3527
86.3k
         record_entries_reference,
3528
86.3k
         io_handle,
3529
86.3k
         file_io_handle,
3530
86.3k
         &record_entries_data,
3531
86.3k
         &record_entries_data_size,
3532
86.3k
         error ) != 1 )
3533
18
    {
3534
18
      libcerror_error_set(
3535
18
       error,
3536
18
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3537
18
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3538
18
       "%s: unable to retrieve value data by reference.",
3539
18
       function );
3540
3541
18
      goto on_error;
3542
18
    }
3543
86.3k
    if( ( record_entries_data == NULL )
3544
86.3k
     || ( 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
86.3k
    record_entry_data = record_entries_data;
3556
86.3k
    record_entry_size = record_entry_identifier_size + 4;
3557
3558
86.3k
    if( ( record_entries_data_size % record_entry_size ) != 0 )
3559
6
    {
3560
6
      libcerror_error_set(
3561
6
       error,
3562
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3563
6
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3564
6
       "%s: unsupported record entries size.",
3565
6
       function );
3566
3567
6
      goto on_error;
3568
6
    }
3569
86.3k
    number_of_record_entries = record_entries_data_size / record_entry_size;
3570
3571
86.3k
    for( record_entry_index = 0;
3572
401k
         (size_t) record_entry_index < number_of_record_entries;
3573
314k
         record_entry_index++ )
3574
319k
    {
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
319k
      record_entry_data += record_entry_identifier_size;
3689
3690
319k
      byte_stream_copy_to_uint32_little_endian(
3691
319k
       record_entry_data,
3692
319k
       sub_record_entries_reference );
3693
3694
319k
      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
319k
      if( sub_record_entries_reference == record_entries_reference )
3713
1
      {
3714
1
        libcerror_error_set(
3715
1
         error,
3716
1
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3717
1
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3718
1
         "%s: invalid sub record entries reference same as parent.",
3719
1
         function );
3720
3721
1
        goto on_error;
3722
1
      }
3723
319k
      if( libpff_table_read_record_entries(
3724
319k
           table,
3725
319k
           record_entries_references_array,
3726
319k
           record_entries_level - 1,
3727
319k
           record_entry_identifier_size,
3728
319k
           sub_record_entries_reference,
3729
319k
           io_handle,
3730
319k
           file_io_handle,
3731
319k
           recursion_depth + 1,
3732
319k
           error ) != 1 )
3733
4.77k
      {
3734
4.77k
        libcerror_error_set(
3735
4.77k
         error,
3736
4.77k
         LIBCERROR_ERROR_DOMAIN_IO,
3737
4.77k
         LIBCERROR_IO_ERROR_READ_FAILED,
3738
4.77k
         "%s: unable to read record entries.",
3739
4.77k
         function );
3740
3741
4.77k
        goto on_error;
3742
4.77k
      }
3743
319k
    }
3744
#if defined( HAVE_DEBUG_OUTPUT )
3745
    if( libcnotify_verbose != 0 )
3746
    {
3747
      libcnotify_printf(
3748
       "\n" );
3749
    }
3750
#endif
3751
81.5k
    memory_free(
3752
81.5k
     record_entries_data );
3753
81.5k
  }
3754
121k
  return( 1 );
3755
3756
4.86k
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
4.86k
  if( record_entries_data != NULL )
3766
4.78k
  {
3767
4.78k
    memory_free(
3768
4.78k
     record_entries_data );
3769
4.78k
  }
3770
4.86k
  if( reference_descriptor != NULL )
3771
0
  {
3772
0
    libpff_reference_descriptor_free(
3773
0
     &reference_descriptor,
3774
0
     NULL );
3775
0
  }
3776
4.86k
  if( record_entries_references_array != NULL )
3777
4.86k
  {
3778
4.86k
    libcdata_array_empty(
3779
4.86k
     record_entries_references_array,
3780
4.86k
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
3781
4.86k
     NULL );
3782
4.86k
  }
3783
4.86k
  return( -1 );
3784
126k
}
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
1.27k
{
3798
1.27k
  uint8_t *table_header_data         = NULL;
3799
1.27k
  static char *function              = "libpff_table_read_values";
3800
1.27k
  size_t table_header_data_size      = 0;
3801
1.27k
  uint32_t b5_table_header_reference = 0;
3802
1.27k
  int result                         = 0;
3803
3804
1.27k
  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
1.27k
  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
1.27k
  if( ( table->header->type == 0x8c )
3829
1.27k
   || ( table->header->type == 0xa5 )
3830
1.27k
   || ( table->header->type == 0xbc ) )
3831
433
  {
3832
433
    b5_table_header_reference = table->header->table_value_reference;
3833
433
  }
3834
839
  else
3835
839
  {
3836
839
    if( ( table->header->table_value_reference & 0x0000001fUL ) != 0 )
3837
5
    {
3838
5
      libcerror_error_set(
3839
5
       error,
3840
5
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3841
5
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3842
5
       "%s: unsupported table header reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3843
5
       function,
3844
5
       table->header->table_value_reference & 0x0000001fUL,
3845
5
       table->header->table_value_reference );
3846
3847
5
      return( -1 );
3848
5
    }
3849
834
    if( libpff_table_get_value_data_by_reference(
3850
834
         table,
3851
834
         io_handle,
3852
834
         file_io_handle,
3853
834
         table->header->table_value_reference,
3854
834
         &table_header_data,
3855
834
         &table_header_data_size,
3856
834
         error ) != 1 )
3857
3
    {
3858
3
      libcerror_error_set(
3859
3
       error,
3860
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3861
3
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3862
3
       "%s: unable to retrieve table header data.",
3863
3
       function );
3864
3865
3
      return( -1 );
3866
3
    }
3867
831
    switch( table->header->type )
3868
831
    {
3869
15
      case 0x6c:
3870
15
        result = libpff_table_header_read_6c_data(
3871
15
            table->header,
3872
15
            table_header_data,
3873
15
            table_header_data_size,
3874
15
            error );
3875
15
        break;
3876
3877
795
      case 0x7c:
3878
795
        result = libpff_table_header_read_7c_data(
3879
795
            table->header,
3880
795
            table_header_data,
3881
795
            table_header_data_size,
3882
795
            error );
3883
795
        break;
3884
3885
3
      case 0x9c:
3886
3
        result = libpff_table_header_read_9c_data(
3887
3
            table->header,
3888
3
            table_header_data,
3889
3
            table_header_data_size,
3890
3
            error );
3891
3
        break;
3892
3893
18
      case 0xac:
3894
18
        result = libpff_table_header_read_ac_data(
3895
18
            table->header,
3896
18
            table_header_data,
3897
18
            table_header_data_size,
3898
18
            error );
3899
18
        break;
3900
831
    }
3901
831
    if( result != 1 )
3902
54
    {
3903
54
      libcerror_error_set(
3904
54
       error,
3905
54
       LIBCERROR_ERROR_DOMAIN_IO,
3906
54
       LIBCERROR_IO_ERROR_READ_FAILED,
3907
54
       "%s: unable to read %02" PRIx8 " table header.",
3908
54
       function,
3909
54
       table->header->type );
3910
3911
54
      return( -1 );
3912
54
    }
3913
777
    b5_table_header_reference = table->header->b5_table_header_reference;
3914
777
  }
3915
  /* Read b5 table header
3916
   */
3917
1.21k
  if( table->header->type == 0xa5 )
3918
57
  {
3919
    /* The a5 table contains no b5 table header
3920
     */
3921
57
    if( b5_table_header_reference != 0 )
3922
42
    {
3923
42
      libcerror_error_set(
3924
42
       error,
3925
42
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3926
42
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3927
42
       "%s: unsupported table header reference: 0x%08" PRIx32 ".",
3928
42
       function,
3929
42
       b5_table_header_reference );
3930
3931
42
      return( -1 );
3932
42
    }
3933
57
  }
3934
1.15k
  else
3935
1.15k
  {
3936
1.15k
    if( ( b5_table_header_reference & 0x0000001fUL ) != 0 )
3937
6
    {
3938
6
      libcerror_error_set(
3939
6
       error,
3940
6
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3941
6
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3942
6
       "%s: unsupported b5 table header reference: 0x%08" PRIx32 " (0x%08" PRIx32 ").",
3943
6
       function,
3944
6
       b5_table_header_reference & 0x0000001fUL,
3945
6
       b5_table_header_reference );
3946
3947
6
      return( -1 );
3948
6
    }
3949
1.14k
    if( libpff_table_get_value_data_by_reference(
3950
1.14k
         table,
3951
1.14k
         io_handle,
3952
1.14k
         file_io_handle,
3953
1.14k
         b5_table_header_reference,
3954
1.14k
         &table_header_data,
3955
1.14k
         &table_header_data_size,
3956
1.14k
         error ) != 1 )
3957
4
    {
3958
4
      libcerror_error_set(
3959
4
       error,
3960
4
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3961
4
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3962
4
       "%s: unable to retrieve b5 table header data.",
3963
4
       function );
3964
3965
4
      return( -1 );
3966
4
    }
3967
1.14k
    if( ( table_header_data == NULL )
3968
1.14k
     || ( table_header_data_size == 0 ) )
3969
2
    {
3970
2
      libcerror_error_set(
3971
2
       error,
3972
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3973
2
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3974
2
       "%s: missing b5 table header data.",
3975
2
       function );
3976
3977
2
      return( -1 );
3978
2
    }
3979
1.14k
    if( libpff_table_header_read_b5_data(
3980
1.14k
         table->header,
3981
1.14k
         table_header_data,
3982
1.14k
         table_header_data_size,
3983
1.14k
         error ) != 1 )
3984
19
    {
3985
19
      libcerror_error_set(
3986
19
       error,
3987
19
       LIBCERROR_ERROR_DOMAIN_IO,
3988
19
       LIBCERROR_IO_ERROR_READ_FAILED,
3989
19
       "%s: unable to read b5 table header.",
3990
19
       function );
3991
3992
19
      return( -1 );
3993
19
    }
3994
1.14k
  }
3995
  /* Read table values
3996
   */
3997
1.13k
  switch( table->header->type )
3998
1.13k
  {
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
767
    case 0x7c:
4008
767
      result = libpff_table_read_7c_values(
4009
767
          table,
4010
767
          io_handle,
4011
767
          file_io_handle,
4012
767
          offsets_index,
4013
767
          name_to_id_map_list,
4014
767
          error );
4015
767
      break;
4016
4017
15
    case 0x8c:
4018
15
      result = libpff_table_read_8c_values(
4019
15
          table,
4020
15
          io_handle,
4021
15
          file_io_handle,
4022
15
          error );
4023
15
      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
15
    case 0xa5:
4034
15
      result = libpff_table_read_a5_values(
4035
15
          table,
4036
15
          io_handle,
4037
15
          file_io_handle,
4038
15
          error );
4039
15
      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
340
    case 0xbc:
4052
340
      result = libpff_table_read_bc_values(
4053
340
          table,
4054
340
          io_handle,
4055
340
          file_io_handle,
4056
340
          offsets_index,
4057
340
          name_to_id_map_list,
4058
340
          debug_item_type,
4059
340
          error );
4060
340
      break;
4061
1.13k
  }
4062
1.13k
  if( result != 1 )
4063
894
  {
4064
894
    libcerror_error_set(
4065
894
     error,
4066
894
     LIBCERROR_ERROR_DOMAIN_IO,
4067
894
     LIBCERROR_IO_ERROR_READ_FAILED,
4068
894
     "%s: unable to read %02" PRIx8 " table values.",
4069
894
     function,
4070
894
     table->header->type );
4071
4072
894
    return( -1 );
4073
894
  }
4074
243
  return( 1 );
4075
1.13k
}
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
767
{
4251
767
  libcdata_array_t *column_definitions_array        = NULL;
4252
767
  libcdata_array_t *record_entries_references_array = NULL;
4253
767
  static char *function                             = "libpff_table_read_7c_values";
4254
4255
767
  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
767
  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
767
  if( ( table->header->record_entry_identifier_size != 4 )
4278
767
   || ( ( table->header->record_entry_value_size != 2 )
4279
759
    &&  ( table->header->record_entry_value_size != 4 ) ) )
4280
17
  {
4281
17
    libcerror_error_set(
4282
17
     error,
4283
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4284
17
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4285
17
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4286
17
     function,
4287
17
     table->header->record_entry_identifier_size,
4288
17
     table->header->record_entry_value_size );
4289
4290
17
    goto on_error;
4291
17
  }
4292
  /* Create the column definitions array
4293
   */
4294
750
  if( libcdata_array_initialize(
4295
750
       &column_definitions_array,
4296
750
       0,
4297
750
       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
750
  if( libpff_table_read_7c_column_definitions(
4309
750
       table,
4310
750
       column_definitions_array,
4311
750
       table->header->column_definitions_data,
4312
750
       table->header->column_definitions_data_size,
4313
750
       table->header->number_of_column_definitions,
4314
750
       file_io_handle,
4315
750
       name_to_id_map_list,
4316
750
       error ) != 1 )
4317
6
  {
4318
6
    libcerror_error_set(
4319
6
     error,
4320
6
     LIBCERROR_ERROR_DOMAIN_IO,
4321
6
     LIBCERROR_IO_ERROR_READ_FAILED,
4322
6
     "%s: unable to read 7c table column definitions.",
4323
6
     function );
4324
4325
6
    goto on_error;
4326
6
  }
4327
744
  if( libcdata_array_initialize(
4328
744
       &record_entries_references_array,
4329
744
       0,
4330
744
       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
744
  if( libpff_table_read_record_entries(
4342
744
       table,
4343
744
       record_entries_references_array,
4344
744
       table->header->record_entries_level,
4345
744
       table->header->record_entry_identifier_size,
4346
744
       table->header->record_entries_reference,
4347
744
       io_handle,
4348
744
       file_io_handle,
4349
744
       0,
4350
744
       error ) != 1 )
4351
14
  {
4352
14
    libcerror_error_set(
4353
14
     error,
4354
14
     LIBCERROR_ERROR_DOMAIN_IO,
4355
14
     LIBCERROR_IO_ERROR_READ_FAILED,
4356
14
     "%s: unable to read record entries.",
4357
14
     function );
4358
4359
14
    goto on_error;
4360
14
  }
4361
730
  if( table->header->number_of_column_definitions > 0 )
4362
729
  {
4363
729
    if( libpff_table_read_values_array(
4364
729
         table,
4365
729
         record_entries_references_array,
4366
729
         table->header->values_array_reference,
4367
729
         table->header->record_entry_identifier_size,
4368
729
         table->header->record_entry_value_size,
4369
729
         table->header->values_array_entry_size,
4370
729
         column_definitions_array,
4371
729
         io_handle,
4372
729
         file_io_handle,
4373
729
         offsets_index,
4374
729
         error ) != 1 )
4375
598
    {
4376
598
      libcerror_error_set(
4377
598
       error,
4378
598
       LIBCERROR_ERROR_DOMAIN_IO,
4379
598
       LIBCERROR_IO_ERROR_READ_FAILED,
4380
598
       "%s: unable to read values array.",
4381
598
       function );
4382
4383
598
      goto on_error;
4384
598
    }
4385
729
  }
4386
132
  if( libcdata_array_free(
4387
132
       &record_entries_references_array,
4388
132
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4389
132
       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
132
  if( libcdata_array_free(
4401
132
       &column_definitions_array,
4402
132
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4403
132
       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
132
  return( 1 );
4415
4416
635
on_error:
4417
635
  if( record_entries_references_array != NULL )
4418
612
  {
4419
612
    libcdata_array_free(
4420
612
     &record_entries_references_array,
4421
612
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4422
612
     NULL );
4423
612
  }
4424
635
  if( column_definitions_array != NULL )
4425
618
  {
4426
618
    libcdata_array_free(
4427
618
     &column_definitions_array,
4428
618
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
4429
618
     NULL );
4430
618
  }
4431
635
  return( -1 );
4432
132
}
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
15
{
4443
15
  libcdata_array_t *record_entries_references_array = NULL;
4444
15
  static char *function                             = "libpff_table_read_8c_values";
4445
4446
15
  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
15
  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
15
  if( ( table->header->record_entry_identifier_size != 8 )
4469
15
   || ( table->header->record_entry_value_size != 4 ) )
4470
10
  {
4471
10
    libcerror_error_set(
4472
10
     error,
4473
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4474
10
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4475
10
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
4476
10
     function,
4477
10
     table->header->record_entry_identifier_size,
4478
10
     table->header->record_entry_value_size );
4479
4480
10
    goto on_error;
4481
10
  }
4482
5
  if( libcdata_array_initialize(
4483
5
       &record_entries_references_array,
4484
5
       0,
4485
5
       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
5
  if( libpff_table_read_record_entries(
4497
5
       table,
4498
5
       record_entries_references_array,
4499
5
       table->header->record_entries_level,
4500
5
       table->header->record_entry_identifier_size,
4501
5
       table->header->record_entries_reference,
4502
5
       io_handle,
4503
5
       file_io_handle,
4504
5
       0,
4505
5
       error ) != 1 )
4506
3
  {
4507
3
    libcerror_error_set(
4508
3
     error,
4509
3
     LIBCERROR_ERROR_DOMAIN_IO,
4510
3
     LIBCERROR_IO_ERROR_READ_FAILED,
4511
3
     "%s: unable to read record entries.",
4512
3
     function );
4513
4514
3
    goto on_error;
4515
3
  }
4516
2
  if( libpff_table_read_8c_record_entries(
4517
2
       table,
4518
2
       record_entries_references_array,
4519
2
       io_handle,
4520
2
       file_io_handle,
4521
2
       error ) != 1 )
4522
1
  {
4523
1
    libcerror_error_set(
4524
1
     error,
4525
1
     LIBCERROR_ERROR_DOMAIN_IO,
4526
1
     LIBCERROR_IO_ERROR_READ_FAILED,
4527
1
     "%s: unable to read table record entries.",
4528
1
     function );
4529
4530
1
    goto on_error;
4531
1
  }
4532
1
  if( libcdata_array_free(
4533
1
       &record_entries_references_array,
4534
1
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4535
1
       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
1
  return( 1 );
4547
4548
14
on_error:
4549
14
  if( record_entries_references_array != NULL )
4550
4
  {
4551
4
    libcdata_array_free(
4552
4
     &record_entries_references_array,
4553
4
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
4554
4
     NULL );
4555
4
  }
4556
14
  return( -1 );
4557
1
}
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
15
{
4693
15
  libpff_table_block_index_t *table_block_index = NULL;
4694
15
  static char *function                         = "libpff_table_read_a5_values";
4695
15
  uint16_t number_of_table_index_values         = 0;
4696
4697
15
  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
15
  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
15
  if( libcdata_array_get_entry_by_index(
4720
15
       table->index_array,
4721
15
       0,
4722
15
       (intptr_t **) &table_block_index,
4723
15
       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
15
  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
15
  if( libpff_table_block_index_get_number_of_values(
4746
15
       table_block_index,
4747
15
       &number_of_table_index_values,
4748
15
       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
15
  if( number_of_table_index_values > 1 )
4760
14
  {
4761
14
    if( libpff_table_read_a5_record_entries(
4762
14
         table,
4763
14
         0x00000020,
4764
14
         io_handle,
4765
14
         file_io_handle,
4766
14
         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
14
  }
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
15
  return( 1 );
4787
15
}
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
340
{
5010
340
  libcdata_array_t *record_entries_references_array = NULL;
5011
340
  static char *function                             = "libpff_table_read_bc_values";
5012
5013
340
  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
340
  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
340
  if( ( table->header->record_entry_identifier_size != 2 )
5036
340
   || ( table->header->record_entry_value_size != 6 ) )
5037
15
  {
5038
15
    libcerror_error_set(
5039
15
     error,
5040
15
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5041
15
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5042
15
     "%s: unsupported record entry identifier size: 0x%02" PRIx8 " and record entry value size: 0x%02" PRIx8 ".",
5043
15
     function,
5044
15
     table->header->record_entry_identifier_size,
5045
15
     table->header->record_entry_value_size );
5046
5047
15
    goto on_error;
5048
15
  }
5049
325
  if( libcdata_array_initialize(
5050
325
       &record_entries_references_array,
5051
325
       0,
5052
325
       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
325
  if( libpff_table_read_record_entries(
5064
325
       table,
5065
325
       record_entries_references_array,
5066
325
       table->header->record_entries_level,
5067
325
       table->header->record_entry_identifier_size,
5068
325
       table->header->record_entries_reference,
5069
325
       io_handle,
5070
325
       file_io_handle,
5071
325
       0,
5072
325
       error ) != 1 )
5073
73
  {
5074
73
    libcerror_error_set(
5075
73
     error,
5076
73
     LIBCERROR_ERROR_DOMAIN_IO,
5077
73
     LIBCERROR_IO_ERROR_READ_FAILED,
5078
73
     "%s: unable to read record entries.",
5079
73
     function );
5080
5081
73
    goto on_error;
5082
73
  }
5083
252
  if( libpff_table_read_bc_record_entries(
5084
252
       table,
5085
252
       record_entries_references_array,
5086
252
       io_handle,
5087
252
       file_io_handle,
5088
252
       offsets_index,
5089
252
       name_to_id_map_list,
5090
252
       debug_item_type,
5091
252
       error ) != 1 )
5092
157
  {
5093
157
    libcerror_error_set(
5094
157
     error,
5095
157
     LIBCERROR_ERROR_DOMAIN_IO,
5096
157
     LIBCERROR_IO_ERROR_READ_FAILED,
5097
157
     "%s: unable to read table record entries.",
5098
157
     function );
5099
5100
157
    goto on_error;
5101
157
  }
5102
95
  if( libcdata_array_free(
5103
95
       &record_entries_references_array,
5104
95
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
5105
95
       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
95
  return( 1 );
5117
5118
245
on_error:
5119
245
  if( record_entries_references_array != NULL )
5120
230
  {
5121
230
    libcdata_array_free(
5122
230
     &record_entries_references_array,
5123
230
     (int (*)(intptr_t **, libcerror_error_t **)) &libpff_reference_descriptor_free,
5124
230
     NULL );
5125
230
  }
5126
245
  return( -1 );
5127
95
}
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
750
{
5637
750
  libpff_column_definition_t *column_definition        = NULL;
5638
750
  libpff_column_definition_t *lookup_column_definition = NULL;
5639
750
  static char *function                                = "libpff_table_read_7c_column_definitions";
5640
750
  uint8_t column_definition_number                     = 0;
5641
750
  int column_definition_index                          = 0;
5642
750
  int result                                           = 0;
5643
5644
750
  LIBPFF_UNREFERENCED_PARAMETER( file_io_handle )
5645
5646
750
  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
750
  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
750
  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
750
  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
750
  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
749
  if( libcdata_array_resize(
5703
749
       column_definitions_array,
5704
749
       number_of_column_definitions,
5705
749
       (int (*)(intptr_t **, libcerror_error_t **)) &libpff_column_definition_free,
5706
749
       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
749
  for( column_definition_index = 0;
5718
6.88k
       column_definition_index < number_of_column_definitions;
5719
6.13k
       column_definition_index++ )
5720
6.14k
  {
5721
6.14k
    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
6.14k
    if( libpff_column_definition_initialize(
5733
6.14k
         &column_definition,
5734
6.14k
         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
6.14k
    byte_stream_copy_to_uint16_little_endian(
5746
6.14k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->record_entry_type,
5747
6.14k
     column_definition->entry_type );
5748
5749
6.14k
    byte_stream_copy_to_uint16_little_endian(
5750
6.14k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->record_entry_value_type,
5751
6.14k
     column_definition->value_type );
5752
5753
6.14k
    byte_stream_copy_to_uint16_little_endian(
5754
6.14k
     ( (pff_table_column_definition_7c_t *) column_definitions_data )->values_array_offset,
5755
6.14k
     column_definition->values_array_offset );
5756
5757
6.14k
    column_definition->values_array_size = ( (pff_table_column_definition_7c_t *) column_definitions_data )->values_array_size;
5758
6.14k
    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
6.14k
    if( ( column_definition->entry_type >= 0x8000 )
5771
6.14k
     || ( column_definition->entry_type <= 0xfffe ) )
5772
6.14k
    {
5773
6.14k
      result = libpff_name_to_id_map_entry_get_entry_by_identifier(
5774
6.14k
                name_to_id_map_list,
5775
6.14k
                (uint32_t) column_definition->entry_type,
5776
6.14k
                &( column_definition->name_to_id_map_entry ),
5777
6.14k
                error );
5778
5779
6.14k
      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
6.14k
    }
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
6.14k
    if( libcdata_array_get_entry_by_index(
5875
6.14k
         column_definitions_array,
5876
6.14k
         (int) column_definition_number,
5877
6.14k
         (intptr_t **) &lookup_column_definition,
5878
6.14k
         error ) != 1 )
5879
5
    {
5880
5
      libcerror_error_set(
5881
5
       error,
5882
5
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5883
5
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5884
5
       "%s: unable to retrieve column definitions: %" PRIu8 " in array.",
5885
5
       function,
5886
5
       column_definition_number );
5887
5888
5
      goto on_error;
5889
5
    }
5890
6.13k
    if( lookup_column_definition != NULL )
5891
1
    {
5892
1
      libcerror_error_set(
5893
1
       error,
5894
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5895
1
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5896
1
       "%s: column definitions: %" PRIu8 " already set in array.",
5897
1
       function,
5898
1
       column_definition_number );
5899
5900
1
      goto on_error;
5901
1
    }
5902
6.13k
    if( libcdata_array_set_entry_by_index(
5903
6.13k
         column_definitions_array,
5904
6.13k
         (int) column_definition_number,
5905
6.13k
         (intptr_t *) column_definition,
5906
6.13k
         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
6.13k
    column_definition = NULL;
5919
5920
6.13k
    column_definitions_data      += sizeof( pff_table_column_definition_7c_t );
5921
6.13k
    column_definitions_data_size -= sizeof( pff_table_column_definition_7c_t );
5922
6.13k
  }
5923
743
  return( 1 );
5924
5925
6
on_error:
5926
6
  if( column_definition != NULL )
5927
6
  {
5928
6
    libpff_column_definition_free(
5929
6
     &column_definition,
5930
6
     NULL );
5931
6
  }
5932
6
  return( -1 );
5933
749
}
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
2
{
5945
2
  libpff_reference_descriptor_t *reference_descriptor = NULL;
5946
2
  libpff_internal_record_entry_t *record_entry        = NULL;
5947
2
  uint8_t *record_entries_data                        = NULL;
5948
2
  static char *function                               = "libpff_table_read_8c_record_entries";
5949
2
  size_t number_of_record_entries                     = 0;
5950
2
  size_t record_entries_data_size                     = 0;
5951
2
  int number_of_record_entries_references             = 0;
5952
2
  int record_entries_reference_index                  = 0;
5953
2
  int record_entry_index                              = 0;
5954
5955
#if defined( HAVE_DEBUG_OUTPUT )
5956
  uint32_t value_32bit                                = 0;
5957
#endif
5958
5959
2
  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
2
  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
2
  if( libcdata_array_get_number_of_entries(
5982
2
       record_entries_references_array,
5983
2
       &number_of_record_entries_references,
5984
2
       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
2
  if( number_of_record_entries_references > 0 )
5996
1
  {
5997
1
    if( libpff_table_resize_record_entries(
5998
1
         table,
5999
1
         1,
6000
1
         0,
6001
1
         io_handle->ascii_codepage,
6002
1
         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
1
    for( record_entries_reference_index = 0;
6014
1
         record_entries_reference_index < number_of_record_entries_references;
6015
1
         record_entries_reference_index++ )
6016
1
    {
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
1
      if( libcdata_array_get_entry_by_index(
6027
1
           record_entries_references_array,
6028
1
           record_entries_reference_index,
6029
1
           (intptr_t **) &reference_descriptor,
6030
1
           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
1
      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
1
      if( libpff_table_get_value_data_by_reference(
6054
1
           table,
6055
1
           io_handle,
6056
1
           file_io_handle,
6057
1
           reference_descriptor->value,
6058
1
           &record_entries_data,
6059
1
           &record_entries_data_size,
6060
1
           error ) != 1 )
6061
1
      {
6062
1
        libcerror_error_set(
6063
1
         error,
6064
1
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6065
1
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6066
1
         "%s: unable to retrieve record entries data.",
6067
1
         function );
6068
6069
1
        return( -1 );
6070
1
      }
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
1
  }
6207
1
  return( 1 );
6208
2
}
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
14
{
6589
14
  libpff_internal_record_entry_t *record_entry  = NULL;
6590
14
  libpff_record_set_t *record_set               = NULL;
6591
14
  libpff_table_block_index_t *table_block_index = NULL;
6592
14
  libpff_table_index_value_t *table_index_value = NULL;
6593
14
  uint8_t *table_value_data                     = NULL;
6594
14
  static char *function                         = "libpff_table_read_a5_record_entries";
6595
14
  size_t table_value_data_size                  = 0;
6596
14
        uint16_t number_of_table_index_values         = 0;
6597
14
  uint16_t table_index_value_iterator           = 0;
6598
14
  int number_of_entries                         = 0;
6599
14
  int number_of_sets                            = 0;
6600
14
  int number_of_table_index_array_entries       = 0;
6601
14
  int table_index_array_entries_iterator        = 0;
6602
6603
14
  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
14
  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
14
  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
14
  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
14
  if( libcdata_array_get_number_of_entries(
6653
14
       table->record_sets_array,
6654
14
       &number_of_sets,
6655
14
       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
14
  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
14
  if( libcdata_array_get_number_of_entries(
6699
14
       table->index_array,
6700
14
       &number_of_table_index_array_entries,
6701
14
       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
14
  for( table_index_array_entries_iterator = 0;
6713
28
       table_index_array_entries_iterator < number_of_table_index_array_entries;
6714
14
       table_index_array_entries_iterator++ )
6715
14
  {
6716
14
    if( libcdata_array_get_entry_by_index(
6717
14
         table->index_array,
6718
14
         table_index_array_entries_iterator,
6719
14
         (intptr_t **) &table_block_index,
6720
14
         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
14
    if( libpff_table_block_index_get_number_of_values(
6733
14
         table_block_index,
6734
14
         &number_of_table_index_values,
6735
14
         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
14
    if( ( number_of_table_index_array_entries > number_of_sets )
6747
14
     || ( number_of_table_index_values > number_of_entries ) )
6748
14
    {
6749
14
      if( libpff_table_resize_record_entries(
6750
14
           table,
6751
14
           number_of_table_index_array_entries,
6752
14
           number_of_table_index_values,
6753
14
           io_handle->ascii_codepage,
6754
14
           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
14
    }
6766
14
    for( table_index_value_iterator = 0;
6767
381
         table_index_value_iterator < number_of_table_index_values;
6768
367
         table_index_value_iterator++ )
6769
367
    {
6770
367
      if( libpff_table_get_record_entry_by_index(
6771
367
           table,
6772
367
           table_index_array_entries_iterator,
6773
367
           table_index_value_iterator,
6774
367
           (libpff_record_entry_t **) &record_entry,
6775
367
           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
367
      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
367
      if( libpff_table_block_index_get_value_by_index(
6802
367
           table_block_index,
6803
367
           table_index_value_iterator,
6804
367
           &table_index_value,
6805
367
           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
367
      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
367
      if( libpff_table_get_value_data_by_index_value(
6841
367
           table,
6842
367
           table_index_value,
6843
367
           file_io_handle,
6844
367
           &table_value_data,
6845
367
           &table_value_data_size,
6846
367
           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
367
      if( libpff_record_entry_set_value_data(
6859
367
           (libpff_record_entry_t *) record_entry,
6860
367
           table_value_data,
6861
367
           table_value_data_size,
6862
367
           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
367
    }
6874
14
  }
6875
#if defined( HAVE_DEBUG_OUTPUT )
6876
  if( libcnotify_verbose != 0 )
6877
  {
6878
    libcnotify_printf(
6879
     "\n" );
6880
  }
6881
#endif
6882
14
  return( 1 );
6883
14
}
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
252
{
7610
252
  libpff_reference_descriptor_t *reference_descriptor = NULL;
7611
252
  uint8_t *record_entries_data                        = NULL;
7612
252
  static char *function                               = "libpff_table_read_bc_record_entries";
7613
252
  size_t number_of_record_entries                     = 0;
7614
252
  size_t record_entries_data_size                     = 0;
7615
252
  uint16_t record_entry_type                          = 0;
7616
252
  uint16_t record_entry_value_type                    = 0;
7617
252
  int number_of_record_entries_references             = 0;
7618
252
  int record_entries_reference_index                  = 0;
7619
252
  int record_entry_index                              = 0;
7620
7621
252
  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
252
  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
252
  if( libcdata_array_get_number_of_entries(
7644
252
       record_entries_references_array,
7645
252
       &number_of_record_entries_references,
7646
252
       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
252
  if( number_of_record_entries_references > 0 )
7658
251
  {
7659
251
    if( libpff_table_resize_record_entries(
7660
251
         table,
7661
251
         1,
7662
251
         0,
7663
251
         io_handle->ascii_codepage,
7664
251
         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
251
    for( record_entries_reference_index = 0;
7676
346
         record_entries_reference_index < number_of_record_entries_references;
7677
251
         record_entries_reference_index++ )
7678
252
    {
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
252
      if( libcdata_array_get_entry_by_index(
7689
252
           record_entries_references_array,
7690
252
           record_entries_reference_index,
7691
252
           (intptr_t **) &reference_descriptor,
7692
252
           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
252
      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
252
      if( libpff_table_get_value_data_by_reference(
7716
252
           table,
7717
252
           io_handle,
7718
252
           file_io_handle,
7719
252
           reference_descriptor->value,
7720
252
           &record_entries_data,
7721
252
           &record_entries_data_size,
7722
252
           error ) != 1 )
7723
3
      {
7724
3
        libcerror_error_set(
7725
3
         error,
7726
3
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7727
3
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7728
3
         "%s: unable to retrieve record entries data.",
7729
3
         function );
7730
7731
3
        return( -1 );
7732
3
      }
7733
249
      if( ( record_entries_data == NULL )
7734
249
       || ( record_entries_data_size == 0 ) )
7735
1
      {
7736
1
        libcerror_error_set(
7737
1
         error,
7738
1
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7739
1
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7740
1
         "%s: missing record entries data.",
7741
1
         function );
7742
7743
1
        return( -1 );
7744
1
      }
7745
248
      if( ( record_entries_data_size % sizeof( pff_table_record_entry_bc_t ) ) != 0 )
7746
5
      {
7747
5
        libcerror_error_set(
7748
5
         error,
7749
5
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7750
5
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
7751
5
         "%s: unsupported record entries data size.",
7752
5
         function );
7753
7754
5
        return( -1 );
7755
5
      }
7756
243
      number_of_record_entries = record_entries_data_size / sizeof( pff_table_record_entry_bc_t );
7757
7758
243
      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
243
      if( libpff_table_expand_record_entries(
7770
243
           table,
7771
243
           0,
7772
243
           (int) number_of_record_entries,
7773
243
           io_handle->ascii_codepage,
7774
243
           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
7.60k
      while( record_entries_data_size > 0 )
7786
7.51k
      {
7787
7.51k
        byte_stream_copy_to_uint16_little_endian(
7788
7.51k
         ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_type,
7789
7.51k
         record_entry_type );
7790
7791
7.51k
        byte_stream_copy_to_uint16_little_endian(
7792
7.51k
         ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_value_type,
7793
7.51k
         record_entry_value_type );
7794
7795
7.51k
        if( libpff_table_read_entry_value(
7796
7.51k
             table,
7797
7.51k
             0,
7798
7.51k
             record_entry_index,
7799
7.51k
             (uint32_t) record_entry_type,
7800
7.51k
             (uint32_t) record_entry_value_type,
7801
7.51k
             (uint8_t *) ( (pff_table_record_entry_bc_t *) record_entries_data )->record_entry_value,
7802
7.51k
             4,
7803
7.51k
             io_handle,
7804
7.51k
             file_io_handle,
7805
7.51k
             offsets_index,
7806
7.51k
             name_to_id_map_list,
7807
7.51k
             NULL,
7808
7.51k
             NULL,
7809
7.51k
             debug_item_type,
7810
7.51k
             error ) != 1 )
7811
148
        {
7812
148
          libcerror_error_set(
7813
148
           error,
7814
148
           LIBCERROR_ERROR_DOMAIN_IO,
7815
148
           LIBCERROR_IO_ERROR_READ_FAILED,
7816
148
           "%s: unable to read entry value: %" PRIu32 ".",
7817
148
           function,
7818
148
           record_entry_index );
7819
7820
148
          return( -1 );
7821
148
        }
7822
7.36k
        record_entries_data      += sizeof( pff_table_record_entry_bc_t );
7823
7.36k
        record_entries_data_size -= sizeof( pff_table_record_entry_bc_t );
7824
7825
7.36k
        record_entry_index++;
7826
7.36k
      }
7827
243
    }
7828
251
  }
7829
95
  return( 1 );
7830
252
}
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
6.54k
{
7848
6.54k
  libpff_data_block_t *data_block                         = NULL;
7849
6.54k
  libpff_local_descriptor_value_t *local_descriptor_value = NULL;
7850
6.54k
  static char *function                                   = "libpff_table_values_array_get_value_data_by_entry_number";
7851
6.54k
  size64_t values_array_block_size                        = 0;
7852
6.54k
  size_t values_array_data_offset                         = 0;
7853
6.54k
  int result                                              = 0;
7854
6.54k
  int values_array_block_index                            = 0;
7855
7856
6.54k
  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
6.54k
  if( values_array_entry_size == 0 )
7868
1
  {
7869
1
    libcerror_error_set(
7870
1
     error,
7871
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7872
1
     LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
7873
1
     "%s: invalid values array entry size value zero or less.",
7874
1
     function );
7875
7876
1
    return( -1 );
7877
1
  }
7878
6.54k
  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
6.54k
  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
6.54k
  if( ( values_array_reference & 0x0000001fUL ) != 0 )
7902
97
  {
7903
97
    if( table->values_array_data_list == NULL )
7904
93
    {
7905
93
      result = libpff_local_descriptors_tree_get_value_by_identifier(
7906
93
          table->local_descriptors_tree,
7907
93
          file_io_handle,
7908
93
          values_array_reference,
7909
93
          &local_descriptor_value,
7910
93
          error );
7911
7912
93
      if( result == -1 )
7913
58
      {
7914
58
        libcerror_error_set(
7915
58
         error,
7916
58
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
7917
58
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7918
58
         "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
7919
58
         function,
7920
58
         values_array_reference );
7921
7922
58
        goto on_error;
7923
58
      }
7924
35
      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
23
      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
23
      if( libpff_table_read_descriptor_data_list(
7963
23
           table,
7964
23
           io_handle,
7965
23
           file_io_handle,
7966
23
           offsets_index,
7967
23
           values_array_reference,
7968
23
           local_descriptor_value->data_identifier,
7969
23
           table->recovered,
7970
23
           0,
7971
23
           &( table->values_array_data_list ),
7972
23
           &( table->values_array_data_cache ),
7973
23
           error ) != 1 )
7974
1
      {
7975
1
        libcerror_error_set(
7976
1
         error,
7977
1
         LIBCERROR_ERROR_DOMAIN_IO,
7978
1
         LIBCERROR_IO_ERROR_READ_FAILED,
7979
1
         "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
7980
1
         function,
7981
1
         values_array_reference,
7982
1
         local_descriptor_value->data_identifier );
7983
7984
1
        goto on_error;
7985
1
      }
7986
22
      if( libpff_local_descriptor_value_free(
7987
22
           &local_descriptor_value,
7988
22
           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
22
      if( libfdata_list_get_mapped_size_by_index(
8002
22
           table->values_array_data_list,
8003
22
           0,
8004
22
           &values_array_block_size,
8005
22
           error ) != 1 )
8006
1
      {
8007
1
        libcerror_error_set(
8008
1
         error,
8009
1
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8010
1
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8011
1
         "%s: unable to retrieve mapped size of data block: 0.",
8012
1
         function );
8013
8014
1
        goto on_error;
8015
1
      }
8016
21
      table->value_array_entries_per_block = (int) ( values_array_block_size / values_array_entry_size );
8017
21
    }
8018
25
    if( table->value_array_entries_per_block == 0 )
8019
1
    {
8020
1
      libcerror_error_set(
8021
1
       error,
8022
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8023
1
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8024
1
       "%s: invalid table - missing value array entries per block value.",
8025
1
       function );
8026
8027
1
      goto on_error;
8028
1
    }
8029
24
    values_array_block_index = values_array_entry_number / table->value_array_entries_per_block;
8030
8031
    /* Retrieve the corresponding data block
8032
     */
8033
24
    if( libfdata_list_get_element_value_by_index(
8034
24
         table->values_array_data_list,
8035
24
         (intptr_t *) file_io_handle,
8036
24
         (libfdata_cache_t *) table->values_array_data_cache,
8037
24
         values_array_block_index,
8038
24
         (intptr_t **) &data_block,
8039
24
         read_flags,
8040
24
         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
13
    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
13
    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
13
    values_array_data_offset = ( values_array_entry_number % table->value_array_entries_per_block )
8077
13
                             * values_array_entry_size;
8078
8079
13
    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
13
    *values_array_data      = data_block->data + values_array_data_offset;
8092
13
    *values_array_data_size = (size_t) values_array_entry_size;
8093
13
  }
8094
6.44k
  else
8095
6.44k
  {
8096
6.44k
    if( libpff_table_get_value_data_by_reference(
8097
6.44k
         table,
8098
6.44k
         io_handle,
8099
6.44k
         file_io_handle,
8100
6.44k
         values_array_reference,
8101
6.44k
         values_array_data,
8102
6.44k
         values_array_data_size,
8103
6.44k
         error ) != 1 )
8104
2
    {
8105
2
      libcerror_error_set(
8106
2
       error,
8107
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8108
2
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8109
2
       "%s: unable to retrieve value data by reference.",
8110
2
       function );
8111
8112
2
      goto on_error;
8113
2
    }
8114
6.44k
    if( ( *values_array_data == NULL )
8115
6.44k
     || ( *values_array_data_size == 0 ) )
8116
1
    {
8117
1
      libcerror_error_set(
8118
1
       error,
8119
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8120
1
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8121
1
       "%s: missing values array data.",
8122
1
       function );
8123
8124
1
      goto on_error;
8125
1
    }
8126
6.44k
    values_array_data_offset = (size_t) values_array_entry_number * (size_t) values_array_entry_size;
8127
8128
6.44k
    if( ( values_array_data_offset >= *values_array_data_size )
8129
6.44k
     || ( values_array_entry_size > ( *values_array_data_size - values_array_data_offset ) ) )
8130
3.77k
    {
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
3.77k
      return( 0 );
8141
3.77k
    }
8142
2.67k
    *values_array_data     += values_array_data_offset;
8143
2.67k
    *values_array_data_size = (size_t) values_array_entry_size;
8144
2.67k
  }
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
2.68k
  return( 1 );
8159
8160
87
on_error:
8161
87
  if( local_descriptor_value != NULL )
8162
1
  {
8163
1
    libpff_local_descriptor_value_free(
8164
1
     &local_descriptor_value,
8165
1
     NULL );
8166
1
  }
8167
87
  return( -1 );
8168
6.54k
}
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
729
{
8186
729
  libpff_column_definition_t *column_definition       = NULL;
8187
729
  libpff_reference_descriptor_t *reference_descriptor = NULL;
8188
729
  uint8_t *record_entries_data                        = NULL;
8189
729
  uint8_t *record_entry_data                          = NULL;
8190
729
  uint8_t *record_entry_values_data                   = NULL;
8191
729
  static char *function                               = "libpff_table_read_values_array";
8192
729
  size_t number_of_record_entries                     = 0;
8193
729
  size_t record_entries_data_size                     = 0;
8194
729
  size_t record_entry_size                            = 0;
8195
729
  size_t record_entry_values_data_size                = 0;
8196
729
  uint32_t record_entry_values_array_identifier       = 0;
8197
729
  uint32_t record_entry_values_array_number           = 0;
8198
729
  uint32_t table_values_array_identifier              = 0;
8199
729
  int column_definition_index                         = 0;
8200
729
  int number_of_column_definitions                    = 0;
8201
729
  int number_of_record_entries_references             = 0;
8202
729
  int number_of_sets                                  = 0;
8203
729
  int record_entries_reference_index                  = 0;
8204
729
  int record_entry_index                              = 0;
8205
729
  int result                                          = 0;
8206
8207
729
  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
729
  if( ( record_entry_identifier_size != 4 )
8219
729
   || ( ( record_entry_value_size != 2 )
8220
729
    &&  ( 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
729
  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
729
  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
729
  if( libcdata_array_get_number_of_entries(
8256
729
       record_entries_references_array,
8257
729
       &number_of_record_entries_references,
8258
729
       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
729
  if( ( number_of_record_entries_references == 0 )
8272
729
   && ( values_array_reference == 0 ) )
8273
1
  {
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
1
    return( 1 );
8283
1
  }
8284
728
  if( number_of_record_entries_references == 0 )
8285
41
  {
8286
41
    libcerror_error_set(
8287
41
     error,
8288
41
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8289
41
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8290
41
     "%s: table contains value array but no record entries.",
8291
41
     function );
8292
8293
41
    goto on_error;
8294
41
  }
8295
687
  if( values_array_reference == 0 )
8296
3
  {
8297
3
    libcerror_error_set(
8298
3
     error,
8299
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8300
3
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8301
3
     "%s: table contains record entries but no value array.",
8302
3
     function );
8303
8304
3
    goto on_error;
8305
3
  }
8306
684
  if( libcdata_array_get_number_of_entries(
8307
684
       column_definitions_array,
8308
684
       &number_of_column_definitions,
8309
684
       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
684
  record_entry_size = record_entry_identifier_size + record_entry_value_size;
8321
8322
684
  if( libpff_table_resize_record_entries(
8323
684
       table,
8324
684
       0,
8325
684
       0,
8326
684
       io_handle->ascii_codepage,
8327
684
       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
684
  for( record_entries_reference_index = 0;
8339
1.98k
       record_entries_reference_index < number_of_record_entries_references;
8340
1.30k
       record_entries_reference_index++ )
8341
1.85k
  {
8342
1.85k
    if( libcdata_array_get_entry_by_index(
8343
1.85k
         record_entries_references_array,
8344
1.85k
         record_entries_reference_index,
8345
1.85k
         (intptr_t **) &reference_descriptor,
8346
1.85k
         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
1.85k
    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
1.85k
    if( libpff_table_clone_value_data_by_reference(
8380
1.85k
         table,
8381
1.85k
         reference_descriptor->value,
8382
1.85k
         io_handle,
8383
1.85k
         file_io_handle,
8384
1.85k
         &record_entries_data,
8385
1.85k
         &record_entries_data_size,
8386
1.85k
         error ) != 1 )
8387
32
    {
8388
32
      libcerror_error_set(
8389
32
       error,
8390
32
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8391
32
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8392
32
       "%s: unable to retrieve record entries data.",
8393
32
       function );
8394
8395
32
      goto on_error;
8396
32
    }
8397
1.82k
    if( ( record_entries_data == NULL )
8398
1.82k
     || ( 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
1.82k
    if( ( record_entries_data_size % record_entry_size ) != 0 )
8422
8
    {
8423
8
      libcerror_error_set(
8424
8
       error,
8425
8
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8426
8
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8427
8
       "%s: unsupported record entries data size.",
8428
8
       function );
8429
8430
8
      goto on_error;
8431
8
    }
8432
1.81k
    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
1.81k
    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
1.81k
    if( number_of_record_entries >= (size_t) ( number_of_sets - record_entry_index ) )
8455
1.81k
    {
8456
1.81k
      number_of_sets = record_entry_index + (int) number_of_record_entries;
8457
8458
1.81k
      if( libpff_table_resize_record_entries(
8459
1.81k
           table,
8460
1.81k
           number_of_sets,
8461
1.81k
           number_of_column_definitions,
8462
1.81k
           io_handle->ascii_codepage,
8463
1.81k
           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
1.81k
    }
8475
1.81k
    record_entry_data = record_entries_data;
8476
8477
7.78k
    while( record_entries_data_size > 0 )
8478
6.48k
    {
8479
6.48k
      byte_stream_copy_to_uint32_little_endian(
8480
6.48k
       record_entry_data,
8481
6.48k
       record_entry_values_array_identifier );
8482
8483
6.48k
      record_entry_data        += 4;
8484
6.48k
      record_entries_data_size -= 4;
8485
8486
6.48k
      if( record_entry_value_size == 2 )
8487
41
      {
8488
41
        byte_stream_copy_to_uint16_little_endian(
8489
41
         record_entry_data,
8490
41
         record_entry_values_array_number );
8491
8492
41
        record_entry_data        += 2;
8493
41
        record_entries_data_size -= 2;
8494
41
      }
8495
6.43k
      else if( record_entry_value_size == 4 )
8496
6.43k
      {
8497
6.43k
        byte_stream_copy_to_uint32_little_endian(
8498
6.43k
         record_entry_data,
8499
6.43k
         record_entry_values_array_number );
8500
8501
6.43k
        record_entry_data        += 4;
8502
6.43k
        record_entries_data_size -= 4;
8503
6.43k
      }
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
6.48k
      result = libpff_table_values_array_get_value_data_by_entry_number(
8524
6.48k
                table,
8525
6.48k
                values_array_reference,
8526
6.48k
                io_handle,
8527
6.48k
                file_io_handle,
8528
6.48k
                offsets_index,
8529
6.48k
                record_entry_values_array_number,
8530
6.48k
                values_array_entry_size,
8531
6.48k
                &record_entry_values_data,
8532
6.48k
                &record_entry_values_data_size,
8533
6.48k
                0,
8534
6.48k
                error );
8535
8536
6.48k
      if( result == -1 )
8537
88
      {
8538
88
        libcerror_error_set(
8539
88
         error,
8540
88
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8541
88
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8542
88
         "%s: unable to retrieve record entry values data for index: %" PRIu32 ".",
8543
88
         function,
8544
88
         record_entry_values_array_number );
8545
8546
88
        goto on_error;
8547
88
      }
8548
6.39k
      else if( result == 0 )
8549
3.77k
      {
8550
3.77k
        record_entry_index++;
8551
8552
3.77k
        table->flags |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
8553
8554
3.77k
        continue;
8555
3.77k
      }
8556
2.61k
      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
2.61k
      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
2.61k
#if SIZEOF_INT <= 4
8583
2.61k
      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
16
      {
8588
16
#if SIZEOF_INT <= 4
8589
16
        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
16
        number_of_sets = (int) ( record_entry_values_array_number + 1 );
8604
8605
16
        if( libpff_table_resize_record_entries(
8606
16
             table,
8607
16
             number_of_sets,
8608
16
             number_of_column_definitions,
8609
16
             io_handle->ascii_codepage,
8610
16
             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
16
      }
8622
2.61k
      for( column_definition_index = 0;
8623
24.7k
           column_definition_index < number_of_column_definitions;
8624
22.1k
           column_definition_index++ )
8625
22.5k
      {
8626
22.5k
        if( libcdata_array_get_entry_by_index(
8627
22.5k
             column_definitions_array,
8628
22.5k
             column_definition_index,
8629
22.5k
             (intptr_t **) &column_definition,
8630
22.5k
             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
22.5k
        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
22.5k
        if( column_definition_index == 0 )
8660
2.61k
        {
8661
2.61k
          if( column_definition->values_array_offset != 0 )
8662
8
          {
8663
8
            libcerror_error_set(
8664
8
             error,
8665
8
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8666
8
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8667
8
             "%s: unsupported first column definition values array offset.",
8668
8
             function );
8669
8670
8
            goto on_error;
8671
8
          }
8672
2.61k
          if( column_definition->values_array_size != 4 )
8673
9
          {
8674
9
            libcerror_error_set(
8675
9
             error,
8676
9
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8677
9
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
8678
9
             "%s: unsupported first column definition values array size.",
8679
9
             function );
8680
8681
9
            goto on_error;
8682
9
          }
8683
2.60k
          byte_stream_copy_to_uint32_little_endian(
8684
2.60k
           record_entry_values_data,
8685
2.60k
           table_values_array_identifier );
8686
8687
          /* If decryption was forced reread the entry without decryption
8688
           */
8689
2.60k
          if( ( io_handle->force_decryption != 0 )
8690
2.60k
           && ( record_entry_values_array_identifier != table_values_array_identifier ) )
8691
65
          {
8692
65
            result = libpff_table_values_array_get_value_data_by_entry_number(
8693
65
                      table,
8694
65
                      values_array_reference,
8695
65
                      io_handle,
8696
65
                      file_io_handle,
8697
65
                      offsets_index,
8698
65
                      record_entry_values_array_number,
8699
65
                      values_array_entry_size,
8700
65
                      &record_entry_values_data,
8701
65
                      &record_entry_values_data_size,
8702
65
                      LIBFDATA_READ_FLAG_IGNORE_CACHE | LIBPFF_READ_FLAG_IGNORE_FORCE_DECRYPTION,
8703
65
                      error );
8704
8705
65
            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
65
            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
65
            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
65
            byte_stream_copy_to_uint32_little_endian(
8740
65
             record_entry_values_data,
8741
65
             table_values_array_identifier );
8742
65
          }
8743
2.60k
          if( record_entry_values_array_identifier != table_values_array_identifier )
8744
167
          {
8745
167
            libcerror_error_set(
8746
167
             error,
8747
167
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
8748
167
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8749
167
             "%s: mismatch in values array identifier (0x%08" PRIx32 " != 0x%08" PRIx32 ").",
8750
167
             function,
8751
167
             record_entry_values_array_identifier,
8752
167
             table_values_array_identifier );
8753
8754
167
            goto on_error;
8755
167
          }
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
2.60k
        }
8769
22.3k
        if( column_definition->values_array_offset > values_array_entry_size )
8770
32
        {
8771
32
          libcerror_error_set(
8772
32
           error,
8773
32
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8774
32
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8775
32
           "%s: invalid column definition values array offset value exceeds values array size.",
8776
32
           function );
8777
8778
32
          goto on_error;
8779
32
        }
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
22.3k
        if( libpff_table_read_entry_value(
8797
22.3k
             table,
8798
22.3k
             record_entry_index,
8799
22.3k
             column_definition_index,
8800
22.3k
             column_definition->entry_type,
8801
22.3k
             column_definition->value_type,
8802
22.3k
             &( record_entry_values_data[ column_definition->values_array_offset ] ),
8803
22.3k
             (size_t) column_definition->values_array_size,
8804
22.3k
             io_handle,
8805
22.3k
             file_io_handle,
8806
22.3k
             offsets_index,
8807
22.3k
             NULL,
8808
22.3k
             column_definition->name_to_id_map_entry,
8809
22.3k
             column_definition->record_entry_values_table,
8810
22.3k
             LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
8811
22.3k
             error ) != 1 )
8812
210
        {
8813
210
          libcerror_error_set(
8814
210
           error,
8815
210
           LIBCERROR_ERROR_DOMAIN_IO,
8816
210
           LIBCERROR_IO_ERROR_READ_FAILED,
8817
210
           "%s: unable to read entry value: %" PRIu32 ".",
8818
210
           function,
8819
210
           record_entry_values_array_number );
8820
8821
210
          goto on_error;
8822
210
        }
8823
22.3k
      }
8824
2.19k
      record_entry_index++;
8825
2.19k
    }
8826
1.30k
    memory_free(
8827
1.30k
     record_entries_data );
8828
8829
1.30k
    record_entries_data = NULL;
8830
1.30k
  }
8831
130
  return( 1 );
8832
8833
598
on_error:
8834
598
  if( record_entries_data != NULL )
8835
522
  {
8836
522
    memory_free(
8837
522
     record_entries_data );
8838
522
  }
8839
598
  return( -1 );
8840
684
}
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
29.8k
{
8862
29.8k
  libfcache_cache_t *value_data_cache                     = NULL;
8863
29.8k
  libfdata_list_t *value_data_list                        = NULL;
8864
29.8k
  libpff_local_descriptor_value_t *local_descriptor_value = NULL;
8865
29.8k
  libpff_internal_record_entry_t *record_entry            = NULL;
8866
29.8k
  libpff_internal_record_entry_t *value_record_entry      = NULL;
8867
29.8k
  libpff_table_index_value_t *table_index_value           = NULL;
8868
29.8k
  uint8_t *record_entry_value_data                        = NULL;
8869
29.8k
  static char *function                                   = "libpff_table_read_entry_value";
8870
29.8k
  size_t record_entry_value_data_size                     = 0;
8871
29.8k
  uint64_t entry_value                                    = 0;
8872
29.8k
  uint16_t table_index_array_reference                    = 0;
8873
29.8k
  uint16_t table_index_value_reference                    = 0;
8874
29.8k
  int result                                              = 0;
8875
8876
29.8k
  LIBPFF_UNREFERENCED_PARAMETER( debug_item_type )
8877
8878
29.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
29.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
29.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
29.8k
  if( ( io_handle->file_type != LIBPFF_FILE_TYPE_32BIT )
8912
29.8k
   && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT )
8913
29.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
29.8k
  if( libpff_table_get_record_entry_by_index(
8925
29.8k
       table,
8926
29.8k
       set_index,
8927
29.8k
       entry_index,
8928
29.8k
       (libpff_record_entry_t **) &record_entry,
8929
29.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
29.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
29.8k
  if( ( record_entry_type >= 0x8000 )
8967
29.8k
   || ( record_entry_type <= 0xfffe ) )
8968
29.8k
  {
8969
    /* The corresponding name to id map entry was already determined
8970
     */
8971
29.8k
    if( name_to_id_map_entry != NULL )
8972
0
    {
8973
0
      record_entry->name_to_id_map_entry = name_to_id_map_entry;
8974
0
    }
8975
29.8k
    else if( name_to_id_map_list != NULL )
8976
0
    {
8977
0
      result = libpff_name_to_id_map_entry_get_entry_by_identifier(
8978
0
                name_to_id_map_list,
8979
0
                record_entry_type,
8980
0
                &( record_entry->name_to_id_map_entry ),
8981
0
                error );
8982
8983
0
      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
0
    }
8996
29.8k
  }
8997
29.8k
  record_entry->identifier.format     = LIBPFF_RECORD_ENTRY_IDENTIFIER_FORMAT_MAPI_PROPERTY;
8998
29.8k
  record_entry->identifier.entry_type = record_entry_type;
8999
29.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
29.8k
  if( record_entry_value_size == 1 )
9074
4.85k
  {
9075
4.85k
    entry_value = record_entry_value[ 0 ];
9076
4.85k
  }
9077
24.9k
  else if( record_entry_value_size == 2 )
9078
201
  {
9079
201
    byte_stream_copy_to_uint16_little_endian(
9080
201
     record_entry_value,
9081
201
     entry_value );
9082
201
  }
9083
24.7k
  else if( record_entry_value_size == 4 )
9084
23.8k
  {
9085
23.8k
    byte_stream_copy_to_uint32_little_endian(
9086
23.8k
     record_entry_value,
9087
23.8k
     entry_value );
9088
23.8k
  }
9089
936
  else if( record_entry_value_size == 8 )
9090
916
  {
9091
916
    byte_stream_copy_to_uint64_little_endian(
9092
916
     record_entry_value,
9093
916
     entry_value );
9094
916
  }
9095
20
  else
9096
20
  {
9097
20
    libcerror_error_set(
9098
20
     error,
9099
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9100
20
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9101
20
     "%s: unsupported record entry value size: %" PRIu8 ".",
9102
20
     function,
9103
20
     record_entry_value_size );
9104
9105
20
    goto on_error;
9106
20
  }
9107
  /* Check if there is a record entry values (a5) table
9108
   */
9109
29.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
29.8k
  else
9311
29.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
29.8k
    if( record_entry_value_type == LIBPFF_VALUE_TYPE_BOOLEAN )
9320
3.08k
    {
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
3.08k
      record_entry_value_data      = record_entry_value;
9351
3.08k
      record_entry_value_data_size = sizeof( uint8_t );
9352
3.08k
    }
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
26.7k
    else if( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_16BIT_SIGNED )
9360
133
    {
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
133
      record_entry_value_data      = record_entry_value;
9388
133
      record_entry_value_data_size = sizeof( uint16_t );
9389
133
    }
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
26.5k
    else if( ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_32BIT_SIGNED )
9397
26.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FLOAT_32BIT )
9398
26.5k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_ERROR ) )
9399
8.45k
    {
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
8.45k
      record_entry_value_data      = record_entry_value;
9426
8.45k
      record_entry_value_data_size = sizeof( uint32_t );
9427
8.45k
    }
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
18.1k
    else if( ( record_entry_value_size == 8 )
9437
18.1k
          && ( ( record_entry_value_type == LIBPFF_VALUE_TYPE_DOUBLE_64BIT )
9438
895
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_CURRENCY )
9439
895
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_APPLICATION_TIME )
9440
895
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_64BIT_SIGNED )
9441
895
           || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FILETIME ) ) )
9442
135
    {
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
135
      record_entry_value_data      = record_entry_value;
9455
135
      record_entry_value_data_size = sizeof( uint64_t );
9456
135
    }
9457
    /* These values are references in the bc table
9458
     */
9459
17.9k
    else if( ( record_entry_value_type == LIBPFF_VALUE_TYPE_DOUBLE_64BIT )
9460
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_CURRENCY )
9461
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_APPLICATION_TIME )
9462
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_OBJECT )
9463
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_INTEGER_64BIT_SIGNED )
9464
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
9465
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_STRING_UNICODE )
9466
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_FILETIME )
9467
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_GUID )
9468
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_SERVER_IDENTIFIER )
9469
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_RESTRICTION )
9470
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_RULE_ACTION )
9471
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_BINARY_DATA )
9472
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_16BIT_SIGNED )
9473
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_32BIT_SIGNED )
9474
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_FLOAT_32BIT )
9475
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_DOUBLE_64BIT )
9476
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_CURRENCY )
9477
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_APPLICATION_TIME )
9478
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_INTEGER_64BIT_SIGNED )
9479
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_STRING_ASCII )
9480
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_STRING_UNICODE )
9481
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_FILETIME )
9482
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_GUID )
9483
17.9k
          || ( record_entry_value_type == LIBPFF_VALUE_TYPE_MULTI_VALUE_BINARY_DATA ) )
9484
17.8k
    {
9485
      /* Check if the entry value is a referenced local descriptor
9486
       */
9487
/* TODO check entry value type */
9488
17.8k
      if( ( entry_value & 0x0000001fUL ) != 0 )
9489
4.23k
      {
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
4.23k
        if( entry_value > (uint64_t) UINT32_MAX )
9504
40
        {
9505
40
          libcerror_error_set(
9506
40
           error,
9507
40
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9508
40
           LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
9509
40
           "%s: entry value reference value exceeds maximum.",
9510
40
           function );
9511
9512
40
          goto on_error;
9513
40
        }
9514
4.19k
        result = libpff_local_descriptors_tree_get_value_by_identifier(
9515
4.19k
            table->local_descriptors_tree,
9516
4.19k
            file_io_handle,
9517
4.19k
            (uint32_t) entry_value,
9518
4.19k
            &local_descriptor_value,
9519
4.19k
            error );
9520
9521
4.19k
        if( result == -1 )
9522
152
        {
9523
152
          libcerror_error_set(
9524
152
           error,
9525
152
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9526
152
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9527
152
           "%s: unable to retrieve descriptor identifier: %" PRIu32 " from local descriptors.",
9528
152
           function,
9529
152
           (uint32_t) entry_value );
9530
9531
152
          goto on_error;
9532
152
        }
9533
4.04k
        else if( result == 0 )
9534
956
        {
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
956
          record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9545
956
          table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9546
956
        }
9547
3.08k
        else
9548
3.08k
        {
9549
3.08k
          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.08k
          if( libpff_table_read_descriptor_data_list(
9575
3.08k
               table,
9576
3.08k
               io_handle,
9577
3.08k
               file_io_handle,
9578
3.08k
               offsets_index,
9579
3.08k
               (uint32_t) entry_value,
9580
3.08k
               local_descriptor_value->data_identifier,
9581
3.08k
               table->recovered,
9582
3.08k
               0,
9583
3.08k
               &value_data_list,
9584
3.08k
               &value_data_cache,
9585
3.08k
               error ) != 1 )
9586
2.35k
          {
9587
2.35k
            libcerror_error_set(
9588
2.35k
             error,
9589
2.35k
             LIBCERROR_ERROR_DOMAIN_IO,
9590
2.35k
             LIBCERROR_IO_ERROR_READ_FAILED,
9591
2.35k
             "%s: unable to read record entry value data with descriptor: %" PRIu32 " - marked as missing.",
9592
2.35k
             function,
9593
2.35k
             (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.35k
            libcerror_error_free(
9605
2.35k
             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.35k
            record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9611
2.35k
            table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9612
2.35k
          }
9613
3.08k
          if( libpff_local_descriptor_value_free(
9614
3.08k
               &local_descriptor_value,
9615
3.08k
               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.08k
        }
9627
4.19k
      }
9628
      /* Check if the entry value is empty
9629
       */
9630
13.6k
      else if( entry_value == 0 )
9631
5.22k
      {
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
5.22k
      }
9643
      /* Otherwise the entry value is a referenced table value
9644
       */
9645
8.40k
      else
9646
8.40k
      {
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
8.40k
        result = libpff_table_get_index_value_by_reference(
9663
8.40k
            table,
9664
8.40k
            (uint32_t) entry_value,
9665
8.40k
            io_handle,
9666
8.40k
            &table_index_value,
9667
8.40k
            error );
9668
9669
8.40k
        if( result != 1 )
9670
2.71k
        {
9671
2.71k
          libcerror_error_set(
9672
2.71k
           error,
9673
2.71k
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
9674
2.71k
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9675
2.71k
           "%s: unable to retrieve record entry value reference: 0x%08" PRIx64 ".",
9676
2.71k
           function,
9677
2.71k
           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
2.71k
          libcerror_error_free(
9689
2.71k
           error );
9690
9691
2.71k
          record_entry->flags |= LIBPFF_RECORD_ENTRY_FLAG_MISSING_DATA_DESCRIPTOR;
9692
2.71k
          table->flags        |= LIBPFF_TABLE_FLAG_MISSING_RECORD_ENTRY_DATA;
9693
2.71k
        }
9694
5.68k
        else
9695
5.68k
        {
9696
5.68k
          if( libpff_table_get_value_data_by_index_value(
9697
5.68k
               table,
9698
5.68k
               table_index_value,
9699
5.68k
               file_io_handle,
9700
5.68k
               &record_entry_value_data,
9701
5.68k
               &record_entry_value_data_size,
9702
5.68k
               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
5.68k
        }
9714
8.40k
      }
9715
17.8k
    }
9716
146
    else
9717
146
    {
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
146
      libcerror_error_set(
9732
146
       error,
9733
146
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9734
146
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
9735
146
       "%s: unsupported value type: 0x%08" PRIx32 " with value size: %" PRIu8 ".",
9736
146
       function,
9737
146
       record_entry_value_type,
9738
146
       record_entry_value_size );
9739
9740
146
      goto on_error;
9741
146
    }
9742
29.8k
  }
9743
/* TODO is this check necessary do entry values get read more than once ? */
9744
29.4k
  if( record_entry->value_data == NULL )
9745
29.4k
  {
9746
29.4k
    if( value_data_list != NULL )
9747
725
    {
9748
725
      result = libpff_record_entry_set_value_data_from_list(
9749
725
                (libpff_record_entry_t *) record_entry,
9750
725
                file_io_handle,
9751
725
                value_data_list,
9752
725
                value_data_cache,
9753
725
                error );
9754
725
    }
9755
28.7k
    else
9756
28.7k
    {
9757
28.7k
      result = libpff_record_entry_set_value_data(
9758
28.7k
                (libpff_record_entry_t *) record_entry,
9759
28.7k
                record_entry_value_data,
9760
28.7k
                record_entry_value_data_size,
9761
28.7k
                error );
9762
28.7k
    }
9763
29.4k
    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
29.4k
  }
9775
29.4k
  if( value_data_cache != NULL )
9776
725
  {
9777
725
    if( libfcache_cache_free(
9778
725
         &value_data_cache,
9779
725
         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
725
  }
9791
29.4k
  if( value_data_list != NULL )
9792
725
  {
9793
725
    if( libfdata_list_free(
9794
725
         &value_data_list,
9795
725
         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
725
  }
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
29.4k
  return( 1 );
9829
9830
358
on_error:
9831
358
  if( value_data_cache != NULL )
9832
0
  {
9833
0
    libfcache_cache_free(
9834
0
     &value_data_cache,
9835
0
     NULL );
9836
0
  }
9837
358
  if( value_data_list != NULL )
9838
0
  {
9839
0
    libfdata_list_free(
9840
0
     &value_data_list,
9841
0
     NULL );
9842
0
  }
9843
358
  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
358
  return( -1 );
9850
29.4k
}
9851