Coverage Report

Created: 2025-12-05 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libesedb/libesedb/libesedb_data_definition.c
Line
Count
Source
1
/*
2
 * Data definition functions
3
 *
4
 * Copyright (C) 2009-2025, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <system_string.h>
25
#include <types.h>
26
27
#include "libesedb_catalog_definition.h"
28
#include "libesedb_column_type.h"
29
#include "libesedb_data_definition.h"
30
#include "libesedb_debug.h"
31
#include "libesedb_definitions.h"
32
#include "libesedb_io_handle.h"
33
#include "libesedb_libbfio.h"
34
#include "libesedb_libcdata.h"
35
#include "libesedb_libcerror.h"
36
#include "libesedb_libcnotify.h"
37
#include "libesedb_libfcache.h"
38
#include "libesedb_libfdata.h"
39
#include "libesedb_libfvalue.h"
40
#include "libesedb_page.h"
41
#include "libesedb_table_definition.h"
42
#include "libesedb_value_data_handle.h"
43
44
#include "esedb_page_values.h"
45
46
/* Creates a data definition
47
 * Make sure the value data_definition is referencing, is set to NULL
48
 * Returns 1 if successful or -1 on error
49
 */
50
int libesedb_data_definition_initialize(
51
     libesedb_data_definition_t **data_definition,
52
     libcerror_error_t **error )
53
320
{
54
320
  static char *function = "libesedb_data_definition_initialize";
55
56
320
  if( data_definition == NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
61
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
62
0
     "%s: invalid data definition.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
320
  if( *data_definition != NULL )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
72
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
73
0
     "%s: invalid data definition value already set.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
320
  *data_definition = memory_allocate_structure(
79
320
                      libesedb_data_definition_t );
80
81
320
  if( *data_definition == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87
0
     "%s: unable to create data definition.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
320
  if( memory_set(
93
320
       *data_definition,
94
320
       0,
95
320
       sizeof( libesedb_data_definition_t ) ) == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
101
0
     "%s: unable to clear data definition.",
102
0
     function );
103
104
0
    goto on_error;
105
0
  }
106
320
  return( 1 );
107
108
0
on_error:
109
0
  if( *data_definition != NULL )
110
0
  {
111
0
    memory_free(
112
0
     *data_definition );
113
114
0
    *data_definition = NULL;
115
0
  }
116
0
  return( -1 );
117
320
}
118
119
/* Frees a data definition
120
 * Returns 1 if successful or -1 on error
121
 */
122
int libesedb_data_definition_free(
123
     libesedb_data_definition_t **data_definition,
124
     libcerror_error_t **error )
125
320
{
126
320
  static char *function = "libesedb_data_definition_free";
127
128
320
  if( data_definition == NULL )
129
0
  {
130
0
    libcerror_error_set(
131
0
     error,
132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
134
0
     "%s: invalid data definition.",
135
0
     function );
136
137
0
    return( -1 );
138
0
  }
139
320
  if( *data_definition != NULL )
140
320
  {
141
320
    memory_free(
142
320
     *data_definition );
143
144
320
    *data_definition = NULL;
145
320
  }
146
320
  return( 1 );
147
320
}
148
149
/* Reads the data
150
 * Returns 1 if successful or -1 on error
151
 */
152
int libesedb_data_definition_read_data(
153
     libesedb_data_definition_t *data_definition,
154
     libbfio_handle_t *file_io_handle,
155
     libesedb_io_handle_t *io_handle,
156
     libfdata_vector_t *pages_vector,
157
     libfcache_cache_t *pages_cache,
158
     uint8_t **data,
159
     size_t *data_size,
160
     libcerror_error_t **error )
161
0
{
162
0
  libesedb_page_t *page             = NULL;
163
0
  libesedb_page_value_t *page_value = NULL;
164
0
  static char *function             = "libesedb_data_definition_read_data";
165
0
  off64_t element_data_offset       = 0;
166
0
  uint16_t data_offset              = 0;
167
168
0
  if( data_definition == NULL )
169
0
  {
170
0
    libcerror_error_set(
171
0
     error,
172
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
173
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
174
0
     "%s: invalid data definition.",
175
0
     function );
176
177
0
    return( -1 );
178
0
  }
179
0
  if( io_handle == NULL )
180
0
  {
181
0
    libcerror_error_set(
182
0
     error,
183
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
184
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
185
0
     "%s: invalid IO handle.",
186
0
     function );
187
188
0
    return( -1 );
189
0
  }
190
0
  if( data == NULL )
191
0
  {
192
0
    libcerror_error_set(
193
0
     error,
194
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
195
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
196
0
     "%s: invalid data.",
197
0
     function );
198
199
0
    return( -1 );
200
0
  }
201
0
  if( data_size == NULL )
202
0
  {
203
0
    libcerror_error_set(
204
0
     error,
205
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
206
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
207
0
     "%s: invalid data size.",
208
0
     function );
209
210
0
    return( -1 );
211
0
  }
212
0
  if( libfdata_vector_get_element_value_at_offset(
213
0
       pages_vector,
214
0
       (intptr_t *) file_io_handle,
215
0
       (libfdata_cache_t *) pages_cache,
216
0
       data_definition->page_offset,
217
0
       &element_data_offset,
218
0
       (intptr_t **) &page,
219
0
       0,
220
0
       error ) != 1 )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
226
0
     "%s: unable to retrieve page: %" PRIu32 " at offset: 0x%08" PRIx64 ".",
227
0
     function,
228
0
     data_definition->page_number,
229
0
     data_definition->page_offset );
230
231
0
    return( -1 );
232
0
  }
233
0
  if( page == NULL )
234
0
  {
235
0
    libcerror_error_set(
236
0
     error,
237
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
238
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
239
0
     "%s: missing page.",
240
0
     function );
241
242
0
    return( -1 );
243
0
  }
244
0
  if( libesedb_page_get_value_by_index(
245
0
       page,
246
0
       data_definition->page_value_index,
247
0
       &page_value,
248
0
       error ) != 1 )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
253
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
254
0
     "%s: unable to retrieve page value: %" PRIu16 ".",
255
0
     function,
256
0
     data_definition->page_value_index );
257
258
0
    return( -1 );
259
0
  }
260
0
  if( page_value == NULL )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
265
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
266
0
     "%s: missing page value: %" PRIu16 ".",
267
0
     function,
268
0
     data_definition->page_value_index );
269
270
0
    return( -1 );
271
0
  }
272
0
  if( page_value->data == NULL )
273
0
  {
274
0
    libcerror_error_set(
275
0
     error,
276
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
277
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
278
0
     "%s: missing page value data.",
279
0
     function );
280
281
0
    return( -1 );
282
0
  }
283
0
  data_offset = data_definition->data_offset - page_value->offset;
284
285
0
  if( ( data_definition->data_offset < page_value->offset )
286
0
   || ( data_offset > page_value->size ) )
287
0
  {
288
0
    libcerror_error_set(
289
0
     error,
290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
291
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
292
0
     "%s: invalid data definition - data offset value out of bounds.",
293
0
     function );
294
295
0
    return( -1 );
296
0
  }
297
0
  *data      = &( page_value->data[ data_offset ] );
298
0
  *data_size = (size_t) ( page_value->size - data_offset );
299
300
0
  return( 1 );
301
0
}
302
303
/* Reads the record
304
 * Uses the definition data in the catalog definitions
305
 * Returns 1 if successful or -1 on error
306
 */
307
int libesedb_data_definition_read_record(
308
     libesedb_data_definition_t *data_definition,
309
     libbfio_handle_t *file_io_handle,
310
     libesedb_io_handle_t *io_handle,
311
     libfdata_vector_t *pages_vector,
312
     libfcache_cache_t *pages_cache,
313
     libesedb_table_definition_t *table_definition,
314
     libesedb_table_definition_t *template_table_definition,
315
     libcdata_array_t *values_array,
316
     uint8_t *record_flags,
317
     libcerror_error_t **error )
318
320
{
319
320
  libesedb_catalog_definition_t *column_catalog_definition = NULL;
320
320
  libesedb_page_t *page                                    = NULL;
321
320
  libesedb_page_value_t *page_value                        = NULL;
322
320
  libfvalue_data_handle_t *value_data_handle               = NULL;
323
320
  libfvalue_value_t *record_value                          = NULL;
324
320
  uint8_t *record_data                                     = NULL;
325
320
  uint8_t *tagged_data_type_offset_data                    = NULL;
326
320
  static char *function                                    = "libesedb_data_definition_read_record";
327
320
  size_t record_data_size                                  = 0;
328
320
  size_t remaining_definition_data_size                    = 0;
329
320
  off64_t element_data_offset                              = 0;
330
320
  uint16_t data_offset                                     = 0;
331
320
  uint16_t fixed_size_data_type_value_offset               = 0;
332
320
  uint16_t masked_previous_tagged_data_type_offset         = 0;
333
320
  uint16_t masked_tagged_data_type_offset                  = 0;
334
320
  uint16_t previous_tagged_data_type_offset                = 0;
335
320
  uint16_t previous_variable_size_data_type_size           = 0;
336
320
  uint16_t tagged_data_type_identifier                     = 0;
337
320
  uint16_t tagged_data_type_offset                         = 0;
338
320
  uint16_t tagged_data_type_offset_bitmask                 = 0x3fff;
339
320
  uint16_t tagged_data_type_offset_data_size               = 0;
340
320
  uint16_t tagged_data_type_size                           = 0;
341
320
  uint16_t tagged_data_type_value_offset                   = 0;
342
320
  uint16_t tagged_data_types_offset                        = 0;
343
320
  uint16_t variable_size_data_type_offset                  = 0;
344
320
  uint16_t variable_size_data_type_size                    = 0;
345
320
  uint16_t variable_size_data_type_value_offset            = 0;
346
320
  uint16_t variable_size_data_type_value_size              = 0;
347
320
  uint16_t variable_size_data_types_offset                 = 0;
348
320
  uint8_t current_variable_size_data_type                  = 0;
349
320
  uint8_t last_fixed_size_data_type                        = 0;
350
320
  uint8_t last_variable_size_data_type                     = 0;
351
320
  uint8_t number_of_variable_size_data_types               = 0;
352
320
  uint8_t record_value_type                                = 0;
353
320
  uint8_t tagged_data_types_format                         = LIBESEDB_TAGGED_DATA_TYPES_FORMAT_INDEX;
354
320
  int column_catalog_definition_index                      = 0;
355
320
  int encoding                                             = 0;
356
320
  int number_of_column_catalog_definitions                 = 0;
357
320
  int number_of_table_column_catalog_definitions           = 0;
358
320
  int number_of_template_table_column_catalog_definitions  = 0;
359
320
  int record_value_codepage                                = 0;
360
361
320
  if( data_definition == NULL )
362
0
  {
363
0
    libcerror_error_set(
364
0
     error,
365
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
366
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
367
0
     "%s: invalid data definition.",
368
0
     function );
369
370
0
    return( -1 );
371
0
  }
372
320
  if( io_handle == NULL )
373
0
  {
374
0
    libcerror_error_set(
375
0
     error,
376
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
377
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
378
0
     "%s: invalid IO handle.",
379
0
     function );
380
381
0
    return( -1 );
382
0
  }
383
320
  if( table_definition == NULL )
384
0
  {
385
0
    libcerror_error_set(
386
0
     error,
387
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
388
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
389
0
     "%s: invalid table definition.",
390
0
     function );
391
392
0
    return( -1 );
393
0
  }
394
320
  if( values_array == NULL )
395
0
  {
396
0
    libcerror_error_set(
397
0
     error,
398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
399
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
400
0
     "%s: invalid values array.",
401
0
     function );
402
403
0
    return( -1 );
404
0
  }
405
320
  if( record_flags == NULL )
406
0
  {
407
0
    libcerror_error_set(
408
0
     error,
409
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
410
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
411
0
     "%s: invalid record flags.",
412
0
     function );
413
414
0
    return( -1 );
415
0
  }
416
320
  if( libfdata_vector_get_element_value_at_offset(
417
320
       pages_vector,
418
320
       (intptr_t *) file_io_handle,
419
320
       (libfdata_cache_t *) pages_cache,
420
320
       data_definition->page_offset,
421
320
       &element_data_offset,
422
320
       (intptr_t **) &page,
423
320
       0,
424
320
       error ) != 1 )
425
0
  {
426
0
    libcerror_error_set(
427
0
     error,
428
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
429
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
430
0
     "%s: unable to retrieve page: %" PRIu32 " at offset: 0x%08" PRIx64 ".",
431
0
     function,
432
0
     data_definition->page_number,
433
0
     data_definition->page_offset );
434
435
0
    goto on_error;
436
0
  }
437
320
  if( page == NULL )
438
0
  {
439
0
    libcerror_error_set(
440
0
     error,
441
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
442
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
443
0
     "%s: missing page.",
444
0
     function );
445
446
0
    goto on_error;
447
0
  }
448
320
  if( libesedb_page_get_value_by_index(
449
320
       page,
450
320
       data_definition->page_value_index,
451
320
       &page_value,
452
320
       error ) != 1 )
453
0
  {
454
0
    libcerror_error_set(
455
0
     error,
456
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
457
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
458
0
     "%s: unable to retrieve page value: %" PRIu16 ".",
459
0
     function,
460
0
     data_definition->page_value_index );
461
462
0
    goto on_error;
463
0
  }
464
320
  if( page_value == NULL )
465
0
  {
466
0
    libcerror_error_set(
467
0
     error,
468
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
469
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
470
0
     "%s: missing page value: %" PRIu16 ".",
471
0
     function,
472
0
     data_definition->page_value_index );
473
474
0
    goto on_error;
475
0
  }
476
320
  if( page_value->data == NULL )
477
0
  {
478
0
    libcerror_error_set(
479
0
     error,
480
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
481
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
482
0
     "%s: missing page value data.",
483
0
     function );
484
485
0
    goto on_error;
486
0
  }
487
320
  data_offset = data_definition->data_offset - page_value->offset;
488
489
320
  if( ( data_definition->data_offset < page_value->offset )
490
320
   || ( data_offset > page_value->size ) )
491
2
  {
492
2
    libcerror_error_set(
493
2
     error,
494
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
495
2
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
496
2
     "%s: invalid data definition - data offset value out of bounds.",
497
2
     function );
498
499
2
    goto on_error;
500
2
  }
501
318
  record_data      = &( page_value->data[ data_offset ] );
502
318
  record_data_size = page_value->size - data_offset;
503
504
318
  if( record_data_size < sizeof( esedb_data_definition_header_t ) )
505
9
  {
506
9
    libcerror_error_set(
507
9
     error,
508
9
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
509
9
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
510
9
     "%s: invalid record data size value out of bounds.",
511
9
     function );
512
513
9
    goto on_error;
514
9
  }
515
309
  if( ( io_handle->format_version == 0x620 )
516
309
   && ( io_handle->format_revision <= 2 ) )
517
0
  {
518
0
    tagged_data_types_format = LIBESEDB_TAGGED_DATA_TYPES_FORMAT_LINEAR;
519
0
  }
520
309
  if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
521
309
   && ( io_handle->page_size >= 16384 ) )
522
222
  {
523
222
    tagged_data_type_offset_bitmask = 0x7fff;
524
222
  }
525
309
  last_fixed_size_data_type    = ( (esedb_data_definition_header_t *) record_data )->last_fixed_size_data_type;
526
309
  last_variable_size_data_type = ( (esedb_data_definition_header_t *) record_data )->last_variable_size_data_type;
527
528
309
  byte_stream_copy_to_uint16_little_endian(
529
309
   ( (esedb_data_definition_header_t *) record_data )->variable_size_data_types_offset,
530
309
   variable_size_data_types_offset );
531
532
#if defined( HAVE_DEBUG_OUTPUT )
533
  if( libcnotify_verbose != 0 )
534
  {
535
    libcnotify_printf(
536
     "%s: last fixed size data type\t\t\t: %" PRIu8 "\n",
537
     function,
538
     last_fixed_size_data_type );
539
540
    libcnotify_printf(
541
     "%s: last variable size data type\t\t: %" PRIu8 "\n",
542
     function,
543
     last_variable_size_data_type );
544
545
    libcnotify_printf(
546
     "%s: variable size data types offset\t\t: %" PRIu16 "\n",
547
     function,
548
     variable_size_data_types_offset );
549
  }
550
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
551
552
309
  if( template_table_definition != NULL )
553
0
  {
554
0
    if( libesedb_table_definition_get_number_of_column_catalog_definitions(
555
0
         template_table_definition,
556
0
         &number_of_template_table_column_catalog_definitions,
557
0
         error ) != 1 )
558
0
    {
559
0
      libcerror_error_set(
560
0
       error,
561
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
562
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
563
0
       "%s: unable to retrieve number of template table column catalog definitions.",
564
0
       function );
565
566
0
      goto on_error;
567
0
    }
568
0
  }
569
309
  if( libesedb_table_definition_get_number_of_column_catalog_definitions(
570
309
       table_definition,
571
309
       &number_of_table_column_catalog_definitions,
572
309
       error ) != 1 )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
577
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
578
0
     "%s: unable to retrieve number of table column catalog definitions.",
579
0
     function );
580
581
0
    goto on_error;
582
0
  }
583
309
  number_of_column_catalog_definitions = number_of_table_column_catalog_definitions;
584
585
309
  if( template_table_definition != NULL )
586
0
  {
587
0
    if( number_of_table_column_catalog_definitions > number_of_template_table_column_catalog_definitions )
588
0
    {
589
0
      libcerror_error_set(
590
0
       error,
591
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
592
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
593
0
       "%s: invalid number of table column catalog definitions value exceeds number in template table.",
594
0
       function );
595
596
0
      goto on_error;
597
0
    }
598
0
    number_of_column_catalog_definitions += number_of_template_table_column_catalog_definitions;
599
0
  }
600
309
  if( libcdata_array_resize(
601
309
       values_array,
602
309
       number_of_column_catalog_definitions,
603
309
       (int (*)(intptr_t **, libcerror_error_t **)) &libfvalue_value_free,
604
309
       error ) != 1 )
605
0
  {
606
0
    libcerror_error_set(
607
0
     error,
608
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
609
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
610
0
     "%s: unable to resize values array.",
611
0
     function );
612
613
0
    goto on_error;
614
0
  }
615
309
  if( last_variable_size_data_type > 127 )
616
210
  {
617
210
    number_of_variable_size_data_types = last_variable_size_data_type - 127;
618
210
  }
619
309
  fixed_size_data_type_value_offset    = (uint16_t) sizeof( esedb_data_definition_header_t );
620
309
  current_variable_size_data_type      = 127;
621
309
  variable_size_data_type_offset       = variable_size_data_types_offset;
622
309
  variable_size_data_type_value_offset = variable_size_data_types_offset + ( number_of_variable_size_data_types * 2 );
623
624
309
  for( column_catalog_definition_index = 0;
625
19.7k
       column_catalog_definition_index < number_of_column_catalog_definitions;
626
19.4k
       column_catalog_definition_index++ )
627
19.6k
  {
628
19.6k
    if( ( template_table_definition != NULL )
629
0
     && ( column_catalog_definition_index < number_of_template_table_column_catalog_definitions ) )
630
0
    {
631
0
      if( libesedb_table_definition_get_column_catalog_definition_by_index(
632
0
           template_table_definition,
633
0
           column_catalog_definition_index,
634
0
           &column_catalog_definition,
635
0
           error ) != 1 )
636
0
      {
637
0
        libcerror_error_set(
638
0
         error,
639
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
640
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
641
0
         "%s: unable to retrieve column catalog definition: %d from template table.",
642
0
         function,
643
0
         column_catalog_definition_index );
644
645
0
        goto on_error;
646
0
      }
647
0
    }
648
19.6k
    else
649
19.6k
    {
650
19.6k
      if( libesedb_table_definition_get_column_catalog_definition_by_index(
651
19.6k
           table_definition,
652
19.6k
           column_catalog_definition_index,
653
19.6k
           &column_catalog_definition,
654
19.6k
           error ) != 1 )
655
0
      {
656
0
        libcerror_error_set(
657
0
         error,
658
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
659
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
660
0
         "%s: unable to retrieve column catalog definition: %d from table.",
661
0
         function,
662
0
         column_catalog_definition_index );
663
664
0
        goto on_error;
665
0
      }
666
19.6k
    }
667
19.6k
    if( column_catalog_definition == NULL )
668
0
    {
669
0
      libcerror_error_set(
670
0
       error,
671
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
672
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
673
0
       "%s: missing column catalog definition: %d.",
674
0
       function,
675
0
       column_catalog_definition_index );
676
677
0
      goto on_error;
678
0
    }
679
19.6k
    if( column_catalog_definition->type != LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
680
0
    {
681
0
      libcerror_error_set(
682
0
       error,
683
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
684
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
685
0
       "%s: unsupported column catalog definition type: %" PRIu16 " for list element: %d.",
686
0
       function,
687
0
       column_catalog_definition->type,
688
0
       column_catalog_definition_index );
689
690
0
      goto on_error;
691
0
    }
692
19.6k
    if( ( template_table_definition != NULL )
693
0
     && ( column_catalog_definition_index == number_of_template_table_column_catalog_definitions ) )
694
0
    {
695
0
      if( column_catalog_definition->identifier != 256 )
696
0
      {
697
0
        libcerror_error_set(
698
0
         error,
699
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
700
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
701
0
         "%s: only tagged data types supported in tables using a template table.",
702
0
         function );
703
704
0
        goto on_error;
705
0
      }
706
0
    }
707
#if defined( HAVE_DEBUG_OUTPUT )
708
    if( libcnotify_verbose != 0 )
709
    {
710
      libcnotify_printf(
711
       "%s: column definition identifier\t\t: %03" PRIu32 "\n",
712
       function,
713
       column_catalog_definition->identifier );
714
      libcnotify_printf(
715
       "%s: column definition name\t\t\t: %" PRIs_SYSTEM "\n",
716
       function,
717
       column_catalog_definition->name_string );
718
      libcnotify_printf(
719
       "%s: column definition type\t\t\t: %s (%s)\n",
720
       function,
721
       libesedb_column_type_get_description(
722
        column_catalog_definition->column_type ),
723
       libesedb_column_type_get_identifier(
724
        column_catalog_definition->column_type ) );
725
    }
726
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
727
728
/* TODO refactor to value type */
729
730
19.6k
    switch( column_catalog_definition->column_type )
731
19.6k
    {
732
591
      case LIBESEDB_COLUMN_TYPE_NULL:
733
        /* JET_coltypNil seems to be able to contain data */
734
591
        record_value_type = LIBFVALUE_VALUE_TYPE_BINARY_DATA;
735
591
        break;
736
737
1.13k
      case LIBESEDB_COLUMN_TYPE_BOOLEAN:
738
1.13k
        record_value_type = LIBFVALUE_VALUE_TYPE_BOOLEAN;
739
1.13k
        break;
740
741
916
      case LIBESEDB_COLUMN_TYPE_INTEGER_8BIT_UNSIGNED:
742
916
        record_value_type = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_8BIT;
743
916
        break;
744
745
757
      case LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_SIGNED:
746
757
        record_value_type = LIBFVALUE_VALUE_TYPE_INTEGER_16BIT;
747
757
        break;
748
749
596
      case LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_UNSIGNED:
750
596
        record_value_type = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_16BIT;
751
596
        break;
752
753
1.62k
      case LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_SIGNED:
754
1.62k
        record_value_type = LIBFVALUE_VALUE_TYPE_INTEGER_32BIT;
755
1.62k
        break;
756
757
1.88k
      case LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_UNSIGNED:
758
1.88k
        record_value_type = LIBFVALUE_VALUE_TYPE_UNSIGNED_INTEGER_32BIT;
759
1.88k
        break;
760
761
547
      case LIBESEDB_COLUMN_TYPE_CURRENCY:
762
580
      case LIBESEDB_COLUMN_TYPE_INTEGER_64BIT_SIGNED:
763
580
        record_value_type = LIBFVALUE_VALUE_TYPE_INTEGER_64BIT;
764
580
        break;
765
766
1.03k
      case LIBESEDB_COLUMN_TYPE_FLOAT_32BIT:
767
1.03k
        record_value_type = LIBFVALUE_VALUE_TYPE_FLOATING_POINT_32BIT;
768
1.03k
        break;
769
770
1.32k
      case LIBESEDB_COLUMN_TYPE_DOUBLE_64BIT:
771
1.32k
        record_value_type = LIBFVALUE_VALUE_TYPE_FLOATING_POINT_64BIT;
772
1.32k
        break;
773
774
807
      case LIBESEDB_COLUMN_TYPE_DATE_TIME:
775
807
        record_value_type = LIBFVALUE_VALUE_TYPE_FILETIME;
776
807
        break;
777
778
763
      case LIBESEDB_COLUMN_TYPE_GUID:
779
763
        record_value_type = LIBFVALUE_VALUE_TYPE_GUID;
780
763
        break;
781
782
1.71k
      case LIBESEDB_COLUMN_TYPE_BINARY_DATA:
783
1.83k
      case LIBESEDB_COLUMN_TYPE_LARGE_BINARY_DATA:
784
1.83k
        record_value_type = LIBFVALUE_VALUE_TYPE_BINARY_DATA;
785
1.83k
        break;
786
787
962
      case LIBESEDB_COLUMN_TYPE_TEXT:
788
5.74k
      case LIBESEDB_COLUMN_TYPE_LARGE_TEXT:
789
5.74k
        record_value_type = LIBFVALUE_VALUE_TYPE_STRING_BYTE_STREAM;
790
5.74k
        break;
791
792
2
      case LIBESEDB_COLUMN_TYPE_SUPER_LARGE_VALUE:
793
/* TODO handle this value type */
794
2
        record_value_type = LIBFVALUE_VALUE_TYPE_UNDEFINED;
795
2
        break;
796
797
75
      default:
798
75
        libcerror_error_set(
799
75
         error,
800
75
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
801
75
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
802
75
         "%s: unsupported column type: %" PRIu32 ".",
803
75
         function,
804
75
         column_catalog_definition->column_type );
805
806
75
        goto on_error;
807
19.6k
    }
808
19.5k
    if( libfvalue_data_handle_initialize(
809
19.5k
         &value_data_handle,
810
19.5k
         (int (*)(libfvalue_data_handle_t *, const uint8_t *, size_t, int, uint32_t, libcerror_error_t **)) &libesedb_value_data_handle_read_value_entries,
811
19.5k
         error ) != 1 )
812
0
    {
813
0
      libcerror_error_set(
814
0
       error,
815
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
816
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
817
0
       "%s: unable to create value data handle.",
818
0
       function );
819
820
0
      goto on_error;
821
0
    }
822
19.5k
    if( ( column_catalog_definition->column_type == LIBESEDB_COLUMN_TYPE_TEXT )
823
18.6k
     || ( column_catalog_definition->column_type == LIBESEDB_COLUMN_TYPE_LARGE_TEXT ) )
824
5.74k
    {
825
5.74k
      record_value_codepage = (int) column_catalog_definition->codepage;
826
827
      /* If the codepage is not set use the default codepage
828
       */
829
5.74k
      if( record_value_codepage == 0 )
830
988
      {
831
988
        record_value_codepage = io_handle->ascii_codepage;
832
988
      }
833
      /* Codepage 1200 in the ESE database format is not strict UTF-16 little-endian
834
       * it can be used for ASCII strings as well.
835
       */
836
5.74k
      if( record_value_codepage == 1200 )
837
4.32k
      {
838
4.32k
        record_value_codepage = LIBFVALUE_CODEPAGE_1200_MIXED;
839
4.32k
      }
840
5.74k
      encoding = record_value_codepage;
841
5.74k
    }
842
13.8k
    else
843
13.8k
    {
844
13.8k
      encoding = LIBFVALUE_ENDIAN_LITTLE;
845
13.8k
    }
846
19.5k
    if( column_catalog_definition->identifier <= 127 )
847
5.61k
    {
848
5.61k
      if( column_catalog_definition->identifier <= last_fixed_size_data_type )
849
3.35k
      {
850
3.35k
        if( column_catalog_definition->size > ( record_data_size - fixed_size_data_type_value_offset ) )
851
15
        {
852
15
          libcerror_error_set(
853
15
           error,
854
15
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
855
15
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
856
15
           "%s: invalid data definition - size value out of bounds.",
857
15
           function );
858
859
15
          goto on_error;
860
15
        }
861
#if defined( HAVE_DEBUG_OUTPUT )
862
        if( libcnotify_verbose != 0 )
863
        {
864
          libcnotify_printf(
865
           "%s: (%03" PRIu32 ") fixed size data type size\t\t: %" PRIu32 "\n",
866
           function,
867
           column_catalog_definition->identifier,
868
           column_catalog_definition->size );
869
          libcnotify_print_data(
870
           &( record_data[ fixed_size_data_type_value_offset ] ),
871
           column_catalog_definition->size,
872
           0 );
873
        }
874
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
875
876
3.34k
        if( libfvalue_data_handle_set_data(
877
3.34k
             value_data_handle,
878
3.34k
             &( record_data[ fixed_size_data_type_value_offset ] ),
879
3.34k
             column_catalog_definition->size,
880
3.34k
             encoding,
881
3.34k
             LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
882
3.34k
             error ) != 1 )
883
0
        {
884
0
          libcerror_error_set(
885
0
           error,
886
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
887
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
888
0
           "%s: unable to set data in fixed size data type definition.",
889
0
           function );
890
891
0
          goto on_error;
892
0
        }
893
3.34k
        if( column_catalog_definition->size > (uint32_t) UINT16_MAX )
894
0
        {
895
0
          libcerror_error_set(
896
0
           error,
897
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
898
0
           LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
899
0
           "%s: invalid common catalog definition size value exceeds maximum.",
900
0
           function );
901
902
0
          goto on_error;
903
0
        }
904
3.34k
        fixed_size_data_type_value_offset += (uint16_t) column_catalog_definition->size;
905
3.34k
      }
906
5.61k
    }
907
13.9k
    else if( current_variable_size_data_type < last_variable_size_data_type )
908
497
    {
909
3.85k
      while( current_variable_size_data_type < column_catalog_definition->identifier )
910
3.49k
      {
911
3.49k
        if( variable_size_data_type_offset > ( record_data_size - 2 ) )
912
2
        {
913
2
          libcerror_error_set(
914
2
           error,
915
2
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
916
2
           LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
917
2
           "%s: invalid variable size data type offset value out of bounds.",
918
2
           function );
919
920
2
          goto on_error;
921
2
        }
922
3.48k
        byte_stream_copy_to_uint16_little_endian(
923
3.48k
         &( record_data[ variable_size_data_type_offset ] ),
924
3.48k
         variable_size_data_type_size );
925
926
3.48k
        variable_size_data_type_offset += 2;
927
928
3.48k
        current_variable_size_data_type++;
929
930
#if defined( HAVE_DEBUG_OUTPUT )
931
        if( libcnotify_verbose != 0 )
932
        {
933
          libcnotify_printf(
934
           "%s: (%03" PRIu16 ") variable size data type size\t: 0x%04" PRIx16 " (%" PRIu16 ")\n",
935
           function,
936
           current_variable_size_data_type,
937
           variable_size_data_type_size,
938
           ( ( variable_size_data_type_size & 0x8000 ) != 0 ) ? 0 : ( variable_size_data_type_size & 0x7fff ) - previous_variable_size_data_type_size );
939
        }
940
#endif
941
3.48k
        if( current_variable_size_data_type == column_catalog_definition->identifier )
942
107
        {
943
          /* The MSB signifies that the variable size data type is empty
944
           */
945
107
          if( ( variable_size_data_type_size & 0x8000 ) == 0 )
946
77
          {
947
77
            if( variable_size_data_type_size < previous_variable_size_data_type_size )
948
2
            {
949
2
              libcerror_error_set(
950
2
               error,
951
2
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
952
2
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
953
2
               "%s: invalid variable size data type size value out of bounds.",
954
2
               function );
955
956
2
              goto on_error;
957
2
            }
958
75
            variable_size_data_type_value_size = variable_size_data_type_size - previous_variable_size_data_type_size;
959
960
75
            if( ( variable_size_data_type_value_size > record_data_size )
961
64
             || ( variable_size_data_type_value_offset > ( record_data_size - variable_size_data_type_value_size ) ) )
962
14
            {
963
14
              libcerror_error_set(
964
14
               error,
965
14
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
966
14
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
967
14
               "%s: invalid variable size data type value size value out of bounds.",
968
14
               function );
969
970
14
              goto on_error;
971
14
            }
972
#if defined( HAVE_DEBUG_OUTPUT )
973
            if( libcnotify_verbose != 0 )
974
            {
975
              libcnotify_printf(
976
               "%s: (%03" PRIu32 ") variable size data type:\n",
977
               function,
978
               column_catalog_definition->identifier );
979
              libcnotify_print_data(
980
               &( record_data[ variable_size_data_type_value_offset ] ),
981
               variable_size_data_type_value_size,
982
               0 );
983
            }
984
#endif
985
61
            if( libfvalue_data_handle_set_data(
986
61
                 value_data_handle,
987
61
                 &( record_data[ variable_size_data_type_value_offset ] ),
988
61
                 variable_size_data_type_value_size,
989
61
                 encoding,
990
61
                 LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
991
61
                 error ) != 1 )
992
0
            {
993
0
              libcerror_error_set(
994
0
               error,
995
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
996
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
997
0
               "%s: unable to set data in variable size data type definition.",
998
0
               function );
999
1000
0
              goto on_error;
1001
0
            }
1002
61
            variable_size_data_type_value_offset += variable_size_data_type_value_size;
1003
61
            previous_variable_size_data_type_size = variable_size_data_type_size;
1004
61
          }
1005
#if defined( HAVE_DEBUG_OUTPUT )
1006
          else if( libcnotify_verbose != 0 )
1007
          {
1008
            libcnotify_printf(
1009
             "%s: (%03" PRIu32 ") variable size data type\t\t: <NULL>\n",
1010
             function,
1011
             column_catalog_definition->identifier );
1012
          }
1013
#endif
1014
107
        }
1015
3.47k
        if( current_variable_size_data_type >= last_variable_size_data_type )
1016
111
        {
1017
111
          break;
1018
111
        }
1019
3.47k
      }
1020
497
    }
1021
13.4k
    else
1022
13.4k
    {
1023
13.4k
      if( tagged_data_types_format == LIBESEDB_TAGGED_DATA_TYPES_FORMAT_LINEAR )
1024
0
      {
1025
0
        if( tagged_data_types_offset == 0 )
1026
0
        {
1027
0
          tagged_data_types_offset       = variable_size_data_type_value_offset;
1028
0
          tagged_data_type_value_offset  = variable_size_data_type_value_offset;
1029
0
          remaining_definition_data_size = record_data_size - (size_t) tagged_data_types_offset;
1030
1031
0
          byte_stream_copy_to_uint16_little_endian(
1032
0
           &( record_data[ tagged_data_type_value_offset ] ),
1033
0
           tagged_data_type_identifier );
1034
1035
0
          tagged_data_type_value_offset += 2;
1036
1037
0
          byte_stream_copy_to_uint16_little_endian(
1038
0
           &( record_data[ tagged_data_type_value_offset ] ),
1039
0
           tagged_data_type_size );
1040
1041
0
          tagged_data_type_value_offset += 2;
1042
1043
0
          remaining_definition_data_size -= 4;
1044
0
        }
1045
0
        if( ( remaining_definition_data_size > 0 )
1046
0
         && ( column_catalog_definition->identifier == tagged_data_type_identifier ) )
1047
0
        {
1048
#if defined( HAVE_DEBUG_OUTPUT )
1049
          if( libcnotify_verbose != 0 )
1050
          {
1051
            libcnotify_printf(
1052
             "%s: (%03" PRIu16 ") tagged data type identifier\t\t: %" PRIu16 "\n",
1053
             function,
1054
             column_catalog_definition->identifier,
1055
             tagged_data_type_identifier );
1056
            libcnotify_printf(
1057
             "%s: (%03" PRIu16 ") tagged data type size\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n",
1058
             function,
1059
             column_catalog_definition->identifier,
1060
             tagged_data_type_size,
1061
             tagged_data_type_size & 0x5fff );
1062
          }
1063
#endif
1064
0
          if( ( tagged_data_type_size & 0x8000 ) != 0 )
1065
0
          {
1066
0
            if( tagged_data_type_value_offset >= record_data_size )
1067
0
            {
1068
0
              libcerror_error_set(
1069
0
               error,
1070
0
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1071
0
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1072
0
               "%s: invalid tagged data type offset value out of bounds.",
1073
0
               function );
1074
1075
0
              goto on_error;
1076
0
            }
1077
#if defined( HAVE_DEBUG_OUTPUT )
1078
            if( libcnotify_verbose != 0 )
1079
            {
1080
              libcnotify_printf(
1081
               "%s: (%03" PRIu16 ") tagged data type flags\t\t: 0x%02" PRIx8 "\n",
1082
               function,
1083
               column_catalog_definition->identifier,
1084
               record_data[ tagged_data_type_value_offset ] );
1085
              libesedb_debug_print_tagged_data_type_flags(
1086
               record_data[ tagged_data_type_value_offset ] );
1087
              libcnotify_printf(
1088
               "\n" );
1089
            }
1090
#endif
1091
0
            if( libfvalue_data_handle_set_data_flags(
1092
0
                 value_data_handle,
1093
0
                 (uint32_t) record_data[ tagged_data_type_value_offset ],
1094
0
                 error ) != 1 )
1095
0
            {
1096
0
              libcerror_error_set(
1097
0
               error,
1098
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
1099
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1100
0
               "%s: unable to set tagged data type flags in tagged data type definition.",
1101
0
               function );
1102
1103
0
              goto on_error;
1104
0
            }
1105
0
            tagged_data_type_value_offset  += 1;
1106
0
            tagged_data_type_size           = ( tagged_data_type_size & 0x5fff ) - 1;
1107
0
            remaining_definition_data_size -= 1;
1108
0
          }
1109
#if defined( HAVE_DEBUG_OUTPUT )
1110
          if( libcnotify_verbose != 0 )
1111
          {
1112
            if( tagged_data_type_size > 0 )
1113
            {
1114
              libcnotify_printf(
1115
               "%s: (%03" PRIu16 ") tagged data type:\n",
1116
               function,
1117
               column_catalog_definition->identifier );
1118
1119
              if( tagged_data_type_value_offset < record_data_size )
1120
              {
1121
                libcnotify_print_data(
1122
                 &( record_data[ tagged_data_type_value_offset ] ),
1123
                 tagged_data_type_size,
1124
                 0 );
1125
              }
1126
              else
1127
              {
1128
                libcnotify_printf(
1129
                 "<NULL>\n\n" );
1130
              }
1131
            }
1132
            else
1133
            {
1134
              libcnotify_printf(
1135
               "%s: (%03" PRIu32 ") tagged data type\t\t\t: <NULL>\n",
1136
               function,
1137
               column_catalog_definition->identifier );
1138
            }
1139
          }
1140
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1141
0
          if( tagged_data_type_size > 0 )
1142
0
          {
1143
0
            if( tagged_data_type_value_offset >= record_data_size )
1144
0
            {
1145
0
              libcerror_error_set(
1146
0
               error,
1147
0
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1148
0
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1149
0
               "%s: invalid tagged data type offset value out of bounds.",
1150
0
               function );
1151
1152
0
              goto on_error;
1153
0
            }
1154
0
            if( tagged_data_type_size > remaining_definition_data_size )
1155
0
            {
1156
0
              libcerror_error_set(
1157
0
               error,
1158
0
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1159
0
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1160
0
               "%s: invalid tagged data type size value exceeds remaining data size.",
1161
0
               function );
1162
1163
0
              goto on_error;
1164
0
            }
1165
0
            if( libfvalue_data_handle_set_data(
1166
0
                 value_data_handle,
1167
0
                 &( record_data[ tagged_data_type_value_offset ] ),
1168
0
                 tagged_data_type_size,
1169
0
                 encoding,
1170
0
                 LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
1171
0
                 error ) != 1 )
1172
0
            {
1173
0
              libcerror_error_set(
1174
0
               error,
1175
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
1176
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1177
0
               "%s: unable to set data in tagged data type definition.",
1178
0
               function );
1179
1180
0
              goto on_error;
1181
0
            }
1182
0
            remaining_definition_data_size -= tagged_data_type_size;
1183
0
          }
1184
0
          if( remaining_definition_data_size > 0 )
1185
0
          {
1186
0
            if( tagged_data_type_value_offset >= record_data_size )
1187
0
            {
1188
0
              libcerror_error_set(
1189
0
               error,
1190
0
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1191
0
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1192
0
               "%s: invalid tagged data type offset value out of bounds.",
1193
0
               function );
1194
1195
0
              goto on_error;
1196
0
            }
1197
0
            byte_stream_copy_to_uint16_little_endian(
1198
0
             &( record_data[ tagged_data_type_value_offset ] ),
1199
0
             tagged_data_type_identifier );
1200
1201
0
            tagged_data_type_value_offset += 2;
1202
1203
0
            byte_stream_copy_to_uint16_little_endian(
1204
0
             &( record_data[ tagged_data_type_value_offset ] ),
1205
0
             tagged_data_type_size );
1206
1207
0
            tagged_data_type_value_offset += 2;
1208
1209
0
            remaining_definition_data_size -= 4;
1210
0
          }
1211
0
        }
1212
0
      }
1213
13.4k
      else if( tagged_data_types_format == LIBESEDB_TAGGED_DATA_TYPES_FORMAT_INDEX )
1214
13.4k
      {
1215
13.4k
        if( tagged_data_types_offset == 0 )
1216
179
        {
1217
179
          tagged_data_types_offset = variable_size_data_type_value_offset;
1218
1219
          /* Note that offset is allowed to be equal to the record data size here
1220
           */
1221
179
          if( tagged_data_types_offset > record_data_size )
1222
10
          {
1223
10
            libcerror_error_set(
1224
10
             error,
1225
10
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1226
10
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1227
10
             "%s: invalid tagged data types offset value out of bounds.",
1228
10
             function );
1229
1230
10
            goto on_error;
1231
10
          }
1232
169
          tagged_data_type_offset_data   = &( record_data[ tagged_data_types_offset ] );
1233
169
          remaining_definition_data_size = record_data_size - (size_t) tagged_data_types_offset;
1234
1235
169
          if( remaining_definition_data_size > 0 )
1236
166
          {
1237
166
            if( record_data_size < 4 )
1238
0
            {
1239
0
              libcerror_error_set(
1240
0
               error,
1241
0
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1242
0
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1243
0
               "%s: invalid tagged data types offset data size value out of bounds.",
1244
0
               function );
1245
1246
0
              goto on_error;
1247
0
            }
1248
166
            byte_stream_copy_to_uint16_little_endian(
1249
166
             tagged_data_type_offset_data,
1250
166
             tagged_data_type_identifier );
1251
1252
166
            tagged_data_type_offset_data += 2;
1253
1254
166
            byte_stream_copy_to_uint16_little_endian(
1255
166
             tagged_data_type_offset_data,
1256
166
             tagged_data_type_offset );
1257
1258
166
            tagged_data_type_offset_data += 2;
1259
1260
166
            if( tagged_data_type_offset == 0 )
1261
6
            {
1262
6
              libcerror_error_set(
1263
6
               error,
1264
6
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1265
6
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1266
6
               "%s: invalid tagged data type offset value out of bounds.",
1267
6
               function );
1268
1269
6
              goto on_error;
1270
6
            }
1271
160
            tagged_data_type_offset_data_size = ( tagged_data_type_offset & 0x3fff ) - 4;
1272
1273
160
            remaining_definition_data_size -= 4;
1274
1275
#if defined( HAVE_DEBUG_OUTPUT )
1276
            if( libcnotify_verbose != 0 )
1277
            {
1278
              libcnotify_printf(
1279
               "%s: tagged data type offset data size\t\t: %" PRIu16 "\n",
1280
               function,
1281
               tagged_data_type_offset_data_size );
1282
              libcnotify_printf(
1283
               "%s: tagged data type offset data:\n",
1284
               function );
1285
              libcnotify_print_data(
1286
               tagged_data_type_offset_data,
1287
               tagged_data_type_offset_data_size + 4,
1288
               0 );
1289
            }
1290
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1291
160
          }
1292
169
        }
1293
13.4k
        if( ( remaining_definition_data_size > 0 )
1294
12.7k
         && ( column_catalog_definition->identifier == tagged_data_type_identifier ) )
1295
100
        {
1296
#if defined( HAVE_DEBUG_OUTPUT )
1297
          if( libcnotify_verbose != 0 )
1298
          {
1299
            libcnotify_printf(
1300
             "%s: (%03" PRIu16 ") tagged data type identifier\t\t: %" PRIu16 "\n",
1301
             function,
1302
             column_catalog_definition->identifier,
1303
             tagged_data_type_identifier );
1304
1305
            libcnotify_printf(
1306
             "%s: (%03" PRIu16 ") tagged data type offset\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n",
1307
             function,
1308
             column_catalog_definition->identifier,
1309
             tagged_data_type_offset,
1310
             tagged_data_type_offset & tagged_data_type_offset_bitmask );
1311
          }
1312
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1313
1314
100
          previous_tagged_data_type_offset = tagged_data_type_offset;
1315
1316
100
          if( tagged_data_type_offset_data_size > 0 )
1317
98
          {
1318
98
            if( tagged_data_type_offset_data_size < 4 )
1319
2
            {
1320
2
              libcerror_error_set(
1321
2
               error,
1322
2
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1323
2
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1324
2
               "%s: invalid tagged data types offset data size value out of bounds.",
1325
2
               function );
1326
1327
2
              goto on_error;
1328
2
            }
1329
96
            byte_stream_copy_to_uint16_little_endian(
1330
96
             tagged_data_type_offset_data,
1331
96
             tagged_data_type_identifier );
1332
1333
96
            tagged_data_type_offset_data += 2;
1334
1335
96
            byte_stream_copy_to_uint16_little_endian(
1336
96
             tagged_data_type_offset_data,
1337
96
             tagged_data_type_offset );
1338
1339
96
            tagged_data_type_offset_data += 2;
1340
1341
96
            tagged_data_type_offset_data_size -= 4;
1342
96
            remaining_definition_data_size    -= 4;
1343
96
          }
1344
98
          masked_previous_tagged_data_type_offset = previous_tagged_data_type_offset & tagged_data_type_offset_bitmask;
1345
98
          masked_tagged_data_type_offset          = tagged_data_type_offset & tagged_data_type_offset_bitmask;
1346
1347
98
          if( masked_previous_tagged_data_type_offset > masked_tagged_data_type_offset )
1348
18
          {
1349
18
            libcerror_error_set(
1350
18
             error,
1351
18
             LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1352
18
             LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1353
18
             "%s: invalid tagged data type offset value exceeds next tagged data type offset.",
1354
18
             function );
1355
1356
18
            goto on_error;
1357
18
          }
1358
80
          if( masked_tagged_data_type_offset > masked_previous_tagged_data_type_offset )
1359
66
          {
1360
66
            tagged_data_type_size = masked_tagged_data_type_offset - masked_previous_tagged_data_type_offset;
1361
66
          }
1362
14
          else
1363
14
          {
1364
14
            tagged_data_type_size = (uint16_t) remaining_definition_data_size;
1365
14
          }
1366
#if defined( HAVE_DEBUG_OUTPUT )
1367
          if( libcnotify_verbose != 0 )
1368
          {
1369
            libcnotify_printf(
1370
             "%s: (%03" PRIu16 ") tagged data type size\t\t: %" PRIu16 "\n",
1371
             function,
1372
             column_catalog_definition->identifier,
1373
             tagged_data_type_size );
1374
          }
1375
#endif
1376
80
          tagged_data_type_value_offset = tagged_data_types_offset + masked_previous_tagged_data_type_offset;
1377
1378
80
          if( tagged_data_type_size > 0 )
1379
79
          {
1380
79
            if( tagged_data_type_size > remaining_definition_data_size )
1381
5
            {
1382
5
              libcerror_error_set(
1383
5
               error,
1384
5
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1385
5
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1386
5
               "%s: invalid tagged data type size value exceeds remaining data size.",
1387
5
               function );
1388
1389
5
              goto on_error;
1390
5
            }
1391
74
            remaining_definition_data_size -= tagged_data_type_size;
1392
1393
74
            if( ( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
1394
74
              &&  ( io_handle->page_size >= 16384 ) )
1395
0
             || ( ( previous_tagged_data_type_offset & 0x4000 ) != 0 ) )
1396
74
            {
1397
74
              if( tagged_data_type_value_offset >= record_data_size )
1398
8
              {
1399
8
                libcerror_error_set(
1400
8
                 error,
1401
8
                 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1402
8
                 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1403
8
                 "%s: invalid tagged data type offset value out of bounds.",
1404
8
                 function );
1405
1406
8
                goto on_error;
1407
8
              }
1408
66
              if( libfvalue_data_handle_set_data_flags(
1409
66
                   value_data_handle,
1410
66
                   (uint32_t) record_data[ tagged_data_type_value_offset ],
1411
66
                   error ) != 1 )
1412
0
              {
1413
0
                libcerror_error_set(
1414
0
                 error,
1415
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1416
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1417
0
                 "%s: unable to set tagged data type flags in tagged data type definition.",
1418
0
                 function );
1419
1420
0
                goto on_error;
1421
0
              }
1422
66
              tagged_data_type_value_offset += 1;
1423
66
              tagged_data_type_size         -= 1;
1424
66
            }
1425
#if defined( HAVE_DEBUG_OUTPUT )
1426
            if( libcnotify_verbose != 0 )
1427
            {
1428
              libcnotify_printf(
1429
               "%s: (%03" PRIu16 ") tagged data type:\n",
1430
               function,
1431
               column_catalog_definition->identifier );
1432
1433
              if( tagged_data_type_value_offset < record_data_size )
1434
              {
1435
                libcnotify_print_data(
1436
                 &( record_data[ tagged_data_type_value_offset ] ),
1437
                 tagged_data_type_size,
1438
                 0 );
1439
              }
1440
              else
1441
              {
1442
                libcnotify_printf(
1443
                 "<NULL>\n\n" );
1444
              }
1445
            }
1446
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1447
74
          }
1448
#if defined( HAVE_DEBUG_OUTPUT )
1449
          /* TODO are zero size tagged data type values handled correctly?
1450
           */
1451
          else if( libcnotify_verbose != 0 )
1452
          {
1453
            libcnotify_printf(
1454
             "%s: (%03" PRIu32 ") tagged data type\t\t\t: <NULL>\n",
1455
             function,
1456
             column_catalog_definition->identifier );
1457
          }
1458
#endif
1459
67
          if( tagged_data_type_size > 0 )
1460
65
          {
1461
65
            if( tagged_data_type_value_offset >= record_data_size )
1462
7
            {
1463
7
              libcerror_error_set(
1464
7
               error,
1465
7
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1466
7
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1467
7
               "%s: invalid tagged data type offset value out of bounds.",
1468
7
               function );
1469
1470
7
              goto on_error;
1471
7
            }
1472
58
            if( tagged_data_type_size > ( record_data_size - tagged_data_type_value_offset ) )
1473
7
            {
1474
7
              libcerror_error_set(
1475
7
               error,
1476
7
               LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1477
7
               LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1478
7
               "%s: invalid tagged data type size value out of bounds.",
1479
7
               function );
1480
1481
7
              goto on_error;
1482
7
            }
1483
51
            if( libfvalue_data_handle_set_data(
1484
51
                 value_data_handle,
1485
51
                 &( record_data[ tagged_data_type_value_offset ] ),
1486
51
                 tagged_data_type_size,
1487
51
                 encoding,
1488
51
                 LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
1489
51
                 error ) != 1 )
1490
0
            {
1491
0
              libcerror_error_set(
1492
0
               error,
1493
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
1494
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1495
0
               "%s: unable to set data in tagged data type definition.",
1496
0
               function );
1497
1498
0
              goto on_error;
1499
0
            }
1500
51
          }
1501
67
        }
1502
13.4k
      }
1503
13.4k
    }
1504
19.4k
    if( libfvalue_value_type_initialize_with_data_handle(
1505
19.4k
         &record_value,
1506
19.4k
         record_value_type,
1507
19.4k
         value_data_handle,
1508
19.4k
         LIBFVALUE_VALUE_FLAG_DATA_HANDLE_MANAGED,
1509
19.4k
         error ) != 1 )
1510
2
    {
1511
2
      libcerror_error_set(
1512
2
       error,
1513
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1514
2
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1515
2
       "%s: unable to create record value.",
1516
2
       function );
1517
1518
2
      goto on_error;
1519
2
    }
1520
19.4k
    value_data_handle = NULL;
1521
1522
19.4k
    if( libcdata_array_set_entry_by_index(
1523
19.4k
         values_array,
1524
19.4k
         column_catalog_definition_index,
1525
19.4k
         (intptr_t *) record_value,
1526
19.4k
         error ) != 1 )
1527
0
    {
1528
0
      libcerror_error_set(
1529
0
       error,
1530
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1531
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
1532
0
       "%s: unable to set data type definition: %d.",
1533
0
       function,
1534
0
       column_catalog_definition_index );
1535
1536
0
      goto on_error;
1537
0
    }
1538
19.4k
    record_value = NULL;
1539
19.4k
  }
1540
#if defined( HAVE_DEBUG_OUTPUT )
1541
  if( libcnotify_verbose != 0 )
1542
  {
1543
    if( fixed_size_data_type_value_offset < variable_size_data_types_offset )
1544
    {
1545
      libcnotify_printf(
1546
       "%s: fixed size data types trailing data:\n",
1547
       function );
1548
      libcnotify_print_data(
1549
       &( record_data[ fixed_size_data_type_value_offset ] ),
1550
       variable_size_data_types_offset - fixed_size_data_type_value_offset,
1551
       0 );
1552
    }
1553
    libcnotify_printf(
1554
     "\n" );
1555
  }
1556
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1557
1558
136
  return( 1 );
1559
1560
184
on_error:
1561
184
  if( record_value != NULL )
1562
0
  {
1563
0
    libfvalue_value_free(
1564
0
     &record_value,
1565
0
     NULL );
1566
0
  }
1567
184
  if( value_data_handle != NULL )
1568
98
  {
1569
98
    libfvalue_data_handle_free(
1570
98
     &value_data_handle,
1571
98
     NULL );
1572
98
  }
1573
184
  return( -1 );
1574
309
}
1575
1576
/* Reads the long value
1577
 * Returns 1 if successful or -1 on error
1578
 */
1579
int libesedb_data_definition_read_long_value(
1580
     libesedb_data_definition_t *data_definition,
1581
     libbfio_handle_t *file_io_handle,
1582
     libfdata_vector_t *pages_vector,
1583
     libfcache_cache_t *pages_cache,
1584
     libcerror_error_t **error )
1585
0
{
1586
0
  libesedb_page_t *page             = NULL;
1587
0
  libesedb_page_value_t *page_value = NULL;
1588
0
  uint8_t *long_value_data          = NULL;
1589
0
  static char *function             = "libesedb_data_definition_read_long_value";
1590
0
  size_t long_value_data_size       = 0;
1591
0
  off64_t element_data_offset       = 0;
1592
0
  uint32_t value_32bit              = 0;
1593
0
  uint16_t data_offset              = 0;
1594
1595
0
  if( data_definition == NULL )
1596
0
  {
1597
0
    libcerror_error_set(
1598
0
     error,
1599
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1600
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1601
0
     "%s: invalid data definition.",
1602
0
     function );
1603
1604
0
    return( -1 );
1605
0
  }
1606
0
  if( libfdata_vector_get_element_value_at_offset(
1607
0
       pages_vector,
1608
0
       (intptr_t *) file_io_handle,
1609
0
       (libfdata_cache_t *) pages_cache,
1610
0
       data_definition->page_offset,
1611
0
       &element_data_offset,
1612
0
       (intptr_t **) &page,
1613
0
       0,
1614
0
       error ) != 1 )
1615
0
  {
1616
0
    libcerror_error_set(
1617
0
     error,
1618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1619
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1620
0
     "%s: unable to retrieve page: %" PRIu32 " at offset: 0x%08" PRIx64 ".",
1621
0
     function,
1622
0
     data_definition->page_number,
1623
0
     data_definition->page_offset );
1624
1625
0
    return( -1 );
1626
0
  }
1627
0
  if( page == NULL )
1628
0
  {
1629
0
    libcerror_error_set(
1630
0
     error,
1631
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1632
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1633
0
     "%s: missing page.",
1634
0
     function );
1635
1636
0
    return( -1 );
1637
0
  }
1638
0
  if( libesedb_page_get_value_by_index(
1639
0
       page,
1640
0
       data_definition->page_value_index,
1641
0
       &page_value,
1642
0
       error ) != 1 )
1643
0
  {
1644
0
    libcerror_error_set(
1645
0
     error,
1646
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1647
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1648
0
     "%s: unable to retrieve page value: %" PRIu16 ".",
1649
0
     function,
1650
0
     data_definition->page_value_index );
1651
1652
0
    return( -1 );
1653
0
  }
1654
0
  if( page_value == NULL )
1655
0
  {
1656
0
    libcerror_error_set(
1657
0
     error,
1658
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1659
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1660
0
     "%s: missing page value: %" PRIu16 ".",
1661
0
     function,
1662
0
     data_definition->page_value_index );
1663
1664
0
    return( -1 );
1665
0
  }
1666
0
  if( page_value->data == NULL )
1667
0
  {
1668
0
    libcerror_error_set(
1669
0
     error,
1670
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1671
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1672
0
     "%s: missing page value data.",
1673
0
     function );
1674
1675
0
    return( -1 );
1676
0
  }
1677
0
  data_offset = data_definition->data_offset - page_value->offset;
1678
1679
0
  if( ( data_definition->data_offset < page_value->offset )
1680
0
   || ( data_offset > page_value->size ) )
1681
0
  {
1682
0
    libcerror_error_set(
1683
0
     error,
1684
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1685
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1686
0
     "%s: invalid data definition - data offset value out of bounds.",
1687
0
     function );
1688
1689
0
    return( -1 );
1690
0
  }
1691
0
  long_value_data      = &( page_value->data[ data_offset ] );
1692
0
  long_value_data_size = page_value->size - data_offset;
1693
1694
0
  if( long_value_data_size != 8 )
1695
0
  {
1696
0
    libcerror_error_set(
1697
0
     error,
1698
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1699
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1700
0
     "%s: unsupported long values data size: %" PRIzd ".",
1701
0
     function,
1702
0
     long_value_data_size );
1703
1704
0
    return( -1 );
1705
0
  }
1706
#if defined( HAVE_DEBUG_OUTPUT )
1707
  if( libcnotify_verbose != 0 )
1708
  {
1709
    libcnotify_printf(
1710
     "%s: long value data:\n",
1711
     function );
1712
    libcnotify_print_data(
1713
     long_value_data,
1714
     long_value_data_size,
1715
     0 );
1716
  }
1717
#endif
1718
0
  byte_stream_copy_to_uint16_little_endian(
1719
0
   long_value_data,
1720
0
   value_32bit );
1721
1722
0
  long_value_data += 4;
1723
1724
#if defined( HAVE_DEBUG_OUTPUT )
1725
  if( libcnotify_verbose != 0 )
1726
  {
1727
    libcnotify_printf(
1728
     "%s: unknown1\t\t\t\t: %" PRIu32 "\n",
1729
     function,
1730
     value_32bit );
1731
  }
1732
#endif
1733
1734
0
  byte_stream_copy_to_uint16_little_endian(
1735
0
   long_value_data,
1736
0
   value_32bit );
1737
1738
0
  long_value_data += 4;
1739
1740
#if defined( HAVE_DEBUG_OUTPUT )
1741
  if( libcnotify_verbose != 0 )
1742
  {
1743
    libcnotify_printf(
1744
     "%s: last segment offset\t\t\t: %" PRIu32 "\n",
1745
     function,
1746
     value_32bit );
1747
    libcnotify_printf(
1748
     "\n" );
1749
  }
1750
#endif
1751
0
  return( 1 );
1752
0
}
1753
1754
/* Reads the long value segment
1755
 * Returns 1 if successful or -1 on error
1756
 */
1757
int libesedb_data_definition_read_long_value_segment(
1758
     libesedb_data_definition_t *data_definition,
1759
     libbfio_handle_t *file_io_handle,
1760
     libesedb_io_handle_t *io_handle,
1761
     libfdata_vector_t *pages_vector,
1762
     libfcache_cache_t *pages_cache,
1763
     uint32_t long_value_segment_offset,
1764
     libfdata_list_t *data_segments_list,
1765
     libcerror_error_t **error )
1766
0
{
1767
0
  libesedb_page_t *page                  = NULL;
1768
0
  libesedb_page_value_t *page_value      = NULL;
1769
0
  static char *function                  = "libesedb_data_definition_read_long_value_segment";
1770
0
  off64_t element_data_offset            = 0;
1771
0
  off64_t long_value_segment_data_offset = 0;
1772
0
  size64_t data_size                     = 0;
1773
0
  size_t long_value_segment_data_size    = 0;
1774
0
  uint16_t data_offset                   = 0;
1775
0
  int element_index                      = 0;
1776
1777
0
  if( data_definition == NULL )
1778
0
  {
1779
0
    libcerror_error_set(
1780
0
     error,
1781
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1782
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1783
0
     "%s: invalid data definition.",
1784
0
     function );
1785
1786
0
    return( -1 );
1787
0
  }
1788
0
  if( io_handle == NULL )
1789
0
  {
1790
0
    libcerror_error_set(
1791
0
     error,
1792
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1793
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1794
0
     "%s: invalid IO handle.",
1795
0
     function );
1796
1797
0
    return( -1 );
1798
0
  }
1799
0
  if( libfdata_vector_get_element_value_at_offset(
1800
0
       pages_vector,
1801
0
       (intptr_t *) file_io_handle,
1802
0
       (libfdata_cache_t *) pages_cache,
1803
0
       data_definition->page_offset,
1804
0
       &element_data_offset,
1805
0
       (intptr_t **) &page,
1806
0
       0,
1807
0
       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 page: %" PRIu32 " at offset: 0x%08" PRIx64 ".",
1814
0
     function,
1815
0
     data_definition->page_number,
1816
0
     data_definition->page_offset );
1817
1818
0
    return( -1 );
1819
0
  }
1820
0
  if( page == NULL )
1821
0
  {
1822
0
    libcerror_error_set(
1823
0
     error,
1824
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1825
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1826
0
     "%s: missing page.",
1827
0
     function );
1828
1829
0
    return( -1 );
1830
0
  }
1831
0
  if( libesedb_page_get_value_by_index(
1832
0
       page,
1833
0
       data_definition->page_value_index,
1834
0
       &page_value,
1835
0
       error ) != 1 )
1836
0
  {
1837
0
    libcerror_error_set(
1838
0
     error,
1839
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1840
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1841
0
     "%s: unable to retrieve page value: %" PRIu16 ".",
1842
0
     function,
1843
0
     data_definition->page_value_index );
1844
1845
0
    return( -1 );
1846
0
  }
1847
0
  if( page_value == NULL )
1848
0
  {
1849
0
    libcerror_error_set(
1850
0
     error,
1851
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1852
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1853
0
     "%s: missing page value: %" PRIu16 ".",
1854
0
     function,
1855
0
     data_definition->page_value_index );
1856
1857
0
    return( -1 );
1858
0
  }
1859
0
  if( page_value->data == NULL )
1860
0
  {
1861
0
    libcerror_error_set(
1862
0
     error,
1863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1864
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1865
0
     "%s: missing page value data.",
1866
0
     function );
1867
1868
0
    return( -1 );
1869
0
  }
1870
0
  data_offset = data_definition->data_offset - page_value->offset;
1871
1872
0
  if( ( data_definition->data_offset < page_value->offset )
1873
0
   || ( data_offset > page_value->size ) )
1874
0
  {
1875
0
    libcerror_error_set(
1876
0
     error,
1877
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1878
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1879
0
     "%s: invalid data definition - data offset value out of bounds.",
1880
0
     function );
1881
1882
0
    return( -1 );
1883
0
  }
1884
0
  long_value_segment_data_size = page_value->size - data_offset;
1885
1886
  /* Note that the data stream will point to the file offset
1887
   * io_handle->pages_data_offset contains the offset relative from the start of the file to the page data
1888
   * data_definition->page_offset contains the offset relative from the start of the page data
1889
   * data_definition->data_offset contains the offset relative from the start of the page
1890
   */
1891
0
  long_value_segment_data_offset = io_handle->pages_data_offset
1892
0
                                 + data_definition->page_offset
1893
0
                                 + data_definition->data_offset;
1894
1895
#if defined( HAVE_DEBUG_OUTPUT )
1896
  if( libcnotify_verbose != 0 )
1897
  {
1898
    libcnotify_printf(
1899
     "%s: long value segment with offset: %" PRIu32 " has data at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIzd "\n",
1900
     function,
1901
     long_value_segment_offset,
1902
     long_value_segment_data_offset,
1903
     long_value_segment_data_offset,
1904
     long_value_segment_data_size );
1905
    libcnotify_printf(
1906
     "\n" );
1907
  }
1908
#endif
1909
0
  if( libfdata_list_get_size(
1910
0
       data_segments_list,
1911
0
       &data_size,
1912
0
       error ) != 1 )
1913
0
  {
1914
0
    libcerror_error_set(
1915
0
     error,
1916
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1917
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1918
0
     "%s: unable to retrieve size of data segments list.",
1919
0
     function );
1920
1921
0
    return( -1 );
1922
0
  }
1923
0
  if( long_value_segment_offset != (off64_t) data_size )
1924
0
  {
1925
0
    libcerror_error_set(
1926
0
     error,
1927
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1928
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1929
0
     "%s: unsupported long value segment offset: %" PRIi64 " value must match end of previous segment: %" PRIzd ".",
1930
0
     function,
1931
0
     long_value_segment_offset,
1932
0
     data_size );
1933
1934
0
    return( -1 );
1935
0
  }
1936
0
  if( libfdata_list_append_element(
1937
0
       data_segments_list,
1938
0
       &element_index,
1939
0
       0,
1940
0
       long_value_segment_data_offset,
1941
0
       (size64_t) long_value_segment_data_size,
1942
0
       0,
1943
0
       error ) != 1 )
1944
0
  {
1945
0
    libcerror_error_set(
1946
0
     error,
1947
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1948
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1949
0
     "%s: unable to append long value segment at offset: 0x%08" PRIx64 " to data segments list.",
1950
0
     function,
1951
0
     long_value_segment_offset );
1952
1953
0
    return( -1 );
1954
0
  }
1955
0
  return( 1 );
1956
0
}
1957