Coverage Report

Created: 2026-02-19 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libesedb/libesedb/libesedb_catalog.c
Line
Count
Source
1
/*
2
 * Catalog 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 <types.h>
25
26
#include "libesedb_block_descriptor.h"
27
#include "libesedb_block_tree.h"
28
#include "libesedb_data_definition.h"
29
#include "libesedb_debug.h"
30
#include "libesedb_definitions.h"
31
#include "libesedb_catalog.h"
32
#include "libesedb_catalog_definition.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_libuna.h"
40
#include "libesedb_page_tree.h"
41
#include "libesedb_table_definition.h"
42
43
/* Creates a catalog
44
 * Make sure the value catalog is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libesedb_catalog_initialize(
48
     libesedb_catalog_t **catalog,
49
     libesedb_io_handle_t *io_handle,
50
     uint32_t root_page_number,
51
     libfdata_vector_t *pages_vector,
52
     libfcache_cache_t *pages_cache,
53
     libcerror_error_t **error )
54
3.43k
{
55
3.43k
  static char *function = "libesedb_catalog_initialize";
56
57
3.43k
  if( catalog == NULL )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
62
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
63
0
     "%s: invalid catalog.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
3.43k
  if( *catalog != NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
73
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
74
0
     "%s: invalid catalog value already set.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
3.43k
  if( io_handle == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
84
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
85
0
     "%s: invalid IO handle.",
86
0
     function );
87
88
0
    return( -1 );
89
0
  }
90
3.43k
  *catalog = memory_allocate_structure(
91
3.43k
              libesedb_catalog_t );
92
93
3.43k
  if( *catalog == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
98
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
99
0
     "%s: unable to create catalog.",
100
0
     function );
101
102
0
    goto on_error;
103
0
  }
104
3.43k
  if( memory_set(
105
3.43k
       *catalog,
106
3.43k
       0,
107
3.43k
       sizeof( libesedb_catalog_t ) ) == NULL )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
112
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
113
0
     "%s: unable to clear catalog.",
114
0
     function );
115
116
0
    memory_free(
117
0
     *catalog );
118
119
0
    *catalog = NULL;
120
121
0
    return( -1 );
122
0
  }
123
3.43k
  if( libesedb_page_tree_initialize(
124
3.43k
       &( ( *catalog )->page_tree ),
125
3.43k
       io_handle,
126
3.43k
       pages_vector,
127
3.43k
       pages_cache,
128
3.43k
       LIBESEDB_FDP_OBJECT_IDENTIFIER_CATALOG,
129
3.43k
       root_page_number,
130
3.43k
       NULL,
131
3.43k
       NULL,
132
3.43k
       error ) != 1 )
133
0
  {
134
0
    libcerror_error_set(
135
0
     error,
136
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
137
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
138
0
     "%s: unable to create page tree.",
139
0
     function );
140
141
0
    goto on_error;
142
0
  }
143
3.43k
  if( libesedb_block_tree_initialize(
144
3.43k
       &( ( *catalog )->page_block_tree ),
145
3.43k
       io_handle->file_size,
146
3.43k
       io_handle->page_size,
147
3.43k
       error ) != 1 )
148
0
  {
149
0
    libcerror_error_set(
150
0
     error,
151
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
152
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
153
0
     "%s: unable to create page block tree.",
154
0
     function );
155
156
0
    goto on_error;
157
0
  }
158
3.43k
  if( libcdata_array_initialize(
159
3.43k
       &( ( *catalog )->table_definition_array ),
160
3.43k
       0,
161
3.43k
       error ) != 1 )
162
0
  {
163
0
    libcerror_error_set(
164
0
     error,
165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
166
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
167
0
     "%s: unable to create table definition array.",
168
0
     function );
169
170
0
    goto on_error;
171
0
  }
172
3.43k
  return( 1 );
173
174
0
on_error:
175
0
  if( *catalog != NULL )
176
0
  {
177
0
    if( ( *catalog )->page_block_tree != NULL )
178
0
    {
179
0
      libesedb_block_tree_free(
180
0
       &( ( *catalog )->page_block_tree ),
181
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_block_descriptor_free,
182
0
       NULL );
183
0
    }
184
0
    if( ( *catalog )->page_tree != NULL )
185
0
    {
186
0
      libesedb_page_tree_free(
187
0
       &( ( *catalog )->page_tree ),
188
0
       NULL );
189
0
    }
190
0
    memory_free(
191
0
     *catalog );
192
193
0
    *catalog = NULL;
194
0
  }
195
0
  return( -1 );
196
3.43k
}
197
198
/* Frees a catalog
199
 * Returns 1 if successful or -1 on error
200
 */
201
int libesedb_catalog_free(
202
     libesedb_catalog_t **catalog,
203
     libcerror_error_t **error )
204
3.74k
{
205
3.74k
  static char *function = "libesedb_catalog_free";
206
3.74k
  int result            = 1;
207
208
3.74k
  if( catalog == NULL )
209
0
  {
210
0
    libcerror_error_set(
211
0
     error,
212
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
213
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
214
0
     "%s: invalid catalog.",
215
0
     function );
216
217
0
    return( -1 );
218
0
  }
219
3.74k
  if( *catalog != NULL )
220
3.43k
  {
221
3.43k
    if( libesedb_page_tree_free(
222
3.43k
         &( ( *catalog )->page_tree ),
223
3.43k
         error ) != 1 )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
229
0
       "%s: unable to free catalog page tree.",
230
0
       function );
231
232
0
      result = -1;
233
0
    }
234
3.43k
    if( libesedb_block_tree_free(
235
3.43k
         &( ( *catalog )->page_block_tree ),
236
3.43k
         (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_block_descriptor_free,
237
3.43k
         error ) != 1 )
238
0
    {
239
0
      libcerror_error_set(
240
0
       error,
241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
242
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
243
0
       "%s: unable to free page block tree.",
244
0
       function );
245
246
0
      result = -1;
247
0
    }
248
3.43k
    if( libcdata_array_free(
249
3.43k
         &( ( *catalog )->table_definition_array ),
250
3.43k
         (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_table_definition_free,
251
3.43k
         error ) != 1 )
252
0
    {
253
0
      libcerror_error_set(
254
0
       error,
255
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
256
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
257
0
       "%s: unable to free table definition array.",
258
0
       function );
259
260
0
      result = -1;
261
0
    }
262
3.43k
    memory_free(
263
3.43k
     *catalog );
264
265
3.43k
    *catalog = NULL;
266
3.43k
  }
267
3.74k
  return( result );
268
3.74k
}
269
270
/* Reads a catalog value
271
 * Returns 1 if successful or -1 on error
272
 */
273
int libesedb_catalog_read_value_data(
274
     libesedb_catalog_t *catalog,
275
     const uint8_t *data,
276
     size_t data_size,
277
     libesedb_table_definition_t **table_definition,
278
     libcerror_error_t **error )
279
143k
{
280
143k
  libesedb_catalog_definition_t *catalog_definition = NULL;
281
143k
  static char *function                             = "libesedb_catalog_read_value_data";
282
143k
  int entry_index                                   = 0;
283
284
143k
  if( catalog == NULL )
285
0
  {
286
0
    libcerror_error_set(
287
0
     error,
288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
289
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
290
0
     "%s: invalid catalog.",
291
0
     function );
292
293
0
    return( -1 );
294
0
  }
295
143k
  if( catalog->page_tree == NULL )
296
0
  {
297
0
    libcerror_error_set(
298
0
     error,
299
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
300
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
301
0
     "%s: invalid catalog - missing page tree.",
302
0
     function );
303
304
0
    return( -1 );
305
0
  }
306
143k
  if( catalog->page_tree->io_handle == NULL )
307
0
  {
308
0
    libcerror_error_set(
309
0
     error,
310
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
311
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
312
0
     "%s: invalid catalog - invalid page tree - missing IO handle.",
313
0
     function );
314
315
0
    return( -1 );
316
0
  }
317
143k
  if( table_definition == NULL )
318
0
  {
319
0
    libcerror_error_set(
320
0
     error,
321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
323
0
     "%s: invalid table definition.",
324
0
     function );
325
326
0
    return( -1 );
327
0
  }
328
143k
  if( libesedb_catalog_definition_initialize(
329
143k
       &catalog_definition,
330
143k
       error ) != 1 )
331
0
  {
332
0
    libcerror_error_set(
333
0
     error,
334
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
335
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
336
0
     "%s: unable to create catalog definition.",
337
0
     function );
338
339
0
    goto on_error;
340
0
  }
341
143k
  if( libesedb_catalog_definition_read_data(
342
143k
       catalog_definition,
343
143k
       data,
344
143k
       data_size,
345
143k
       catalog->page_tree->io_handle->ascii_codepage,
346
143k
       error ) != 1 )
347
274
  {
348
274
    libcerror_error_set(
349
274
     error,
350
274
     LIBCERROR_ERROR_DOMAIN_IO,
351
274
     LIBCERROR_IO_ERROR_READ_FAILED,
352
274
     "%s: unable to read catalog definition.",
353
274
     function );
354
355
274
    goto on_error;
356
274
  }
357
143k
  if( ( catalog_definition->type != LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE )
358
111k
   && ( *table_definition == NULL ) )
359
19.7k
  {
360
/* TODO add build-in table 1 support */
361
#if defined( HAVE_DEBUG_OUTPUT )
362
    if( libcnotify_verbose != 0 )
363
    {
364
      libcnotify_printf(
365
       "%s: missing table definition for catalog definition type: %" PRIu16 ".\n",
366
       function,
367
       catalog_definition->type );
368
    }
369
#endif
370
19.7k
    if( libesedb_catalog_definition_free(
371
19.7k
         &catalog_definition,
372
19.7k
         error ) != 1 )
373
0
    {
374
0
      libcerror_error_set(
375
0
       error,
376
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
377
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
378
0
       "%s: unable to free catalog definition.",
379
0
       function );
380
381
0
      goto on_error;
382
0
    }
383
19.7k
    catalog_definition = NULL;
384
19.7k
  }
385
123k
  else switch( catalog_definition->type )
386
123k
  {
387
32.1k
    case LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE:
388
32.1k
      *table_definition = NULL;
389
390
32.1k
      if( libesedb_table_definition_initialize(
391
32.1k
           table_definition,
392
32.1k
           catalog_definition,
393
32.1k
           error ) != 1 )
394
0
      {
395
0
        libcerror_error_set(
396
0
         error,
397
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
398
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
399
0
         "%s: unable to create table definition.",
400
0
         function );
401
402
0
        libesedb_table_definition_free(
403
0
         table_definition,
404
0
         NULL );
405
406
0
        goto on_error;
407
0
      }
408
32.1k
      catalog_definition = NULL;
409
410
32.1k
      if( libcdata_array_append_entry(
411
32.1k
           catalog->table_definition_array,
412
32.1k
           &entry_index,
413
32.1k
           (intptr_t *) *table_definition,
414
32.1k
           error ) != 1 )
415
0
      {
416
0
        libcerror_error_set(
417
0
         error,
418
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
419
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
420
0
         "%s: unable to append table definition to table definition array.",
421
0
         function );
422
423
0
        libesedb_table_definition_free(
424
0
         table_definition,
425
0
         NULL );
426
427
0
        goto on_error;
428
0
      }
429
32.1k
      break;
430
431
86.1k
    case LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN:
432
86.1k
      if( libesedb_table_definition_append_column_catalog_definition(
433
86.1k
           *table_definition,
434
86.1k
           catalog_definition,
435
86.1k
           error ) != 1 )
436
0
      {
437
0
        libcerror_error_set(
438
0
         error,
439
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
440
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
441
0
         "%s: unable to append column catalog definition to table definition.",
442
0
         function );
443
444
0
        goto on_error;
445
0
      }
446
86.1k
      catalog_definition = NULL;
447
448
86.1k
      break;
449
450
2.26k
    case LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX:
451
2.26k
      if( libesedb_table_definition_append_index_catalog_definition(
452
2.26k
           *table_definition,
453
2.26k
           catalog_definition,
454
2.26k
           error ) != 1 )
455
0
      {
456
0
        libcerror_error_set(
457
0
         error,
458
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
460
0
         "%s: unable to append index catalog definition to table definition.",
461
0
         function );
462
463
0
        goto on_error;
464
0
      }
465
2.26k
      catalog_definition = NULL;
466
467
2.26k
      break;
468
469
413
    case LIBESEDB_CATALOG_DEFINITION_TYPE_LONG_VALUE:
470
413
      if( libesedb_table_definition_set_long_value_catalog_definition(
471
413
           *table_definition,
472
413
           catalog_definition,
473
413
           error ) != 1 )
474
6
      {
475
6
        libcerror_error_set(
476
6
         error,
477
6
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
478
6
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
479
6
         "%s: unable to set long value catalog definition in table definition.",
480
6
         function );
481
482
6
        goto on_error;
483
6
      }
484
407
      catalog_definition = NULL;
485
486
407
      break;
487
488
318
    case LIBESEDB_CATALOG_DEFINITION_TYPE_CALLBACK:
489
318
      if( libesedb_table_definition_set_callback_catalog_definition(
490
318
           *table_definition,
491
318
           catalog_definition,
492
318
           error ) != 1 )
493
7
      {
494
7
        libcerror_error_set(
495
7
         error,
496
7
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
7
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
498
7
         "%s: unable to set callback catalog definition in table definition.",
499
7
         function );
500
501
7
        goto on_error;
502
7
      }
503
311
      catalog_definition = NULL;
504
505
311
      break;
506
507
2.55k
    default:
508
#if defined( HAVE_DEBUG_OUTPUT )
509
      if( libcnotify_verbose != 0 )
510
      {
511
        libcnotify_printf(
512
         "%s: unsupported catalog definition type: %" PRIu16 ".\n",
513
         function,
514
         catalog_definition->type );
515
      }
516
#endif
517
2.55k
      if( libesedb_catalog_definition_free(
518
2.55k
           &catalog_definition,
519
2.55k
           error ) != 1 )
520
0
      {
521
0
        libcerror_error_set(
522
0
         error,
523
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
524
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
525
0
         "%s: unable to free catalog definition.",
526
0
         function );
527
528
0
        goto on_error;
529
0
      }
530
2.55k
      catalog_definition = NULL;
531
532
2.55k
      break;
533
123k
  }
534
143k
  return( 1 );
535
536
287
on_error:
537
287
  if( catalog_definition != NULL )
538
287
  {
539
287
    libesedb_catalog_definition_free(
540
287
     &catalog_definition,
541
287
     NULL );
542
287
  }
543
287
  return( -1 );
544
143k
}
545
546
/* Reads the catalog values from a leaf page
547
 * Returns 1 if successful or -1 on error
548
 */
549
int libesedb_catalog_read_values_from_leaf_page(
550
     libesedb_catalog_t *catalog,
551
     libesedb_page_t *page,
552
     libesedb_table_definition_t **table_definition,
553
     libcerror_error_t **error )
554
2.88k
{
555
2.88k
  libesedb_page_tree_value_t *page_tree_value = NULL;
556
2.88k
  libesedb_page_value_t *page_value           = NULL;
557
2.88k
  static char *function                       = "libesedb_catalog_read_values_from_leaf_page";
558
2.88k
  uint32_t page_flags                         = 0;
559
2.88k
  uint16_t number_of_page_values              = 0;
560
2.88k
  uint16_t page_value_index                   = 0;
561
562
2.88k
  if( catalog == NULL )
563
0
  {
564
0
    libcerror_error_set(
565
0
     error,
566
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
567
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
568
0
     "%s: invalid catalog.",
569
0
     function );
570
571
0
    return( -1 );
572
0
  }
573
2.88k
  if( libesedb_page_get_flags(
574
2.88k
       page,
575
2.88k
       &page_flags,
576
2.88k
       error ) != 1 )
577
0
  {
578
0
    libcerror_error_set(
579
0
     error,
580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
581
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
582
0
     "%s: unable to retrieve page flags.",
583
0
     function );
584
585
0
    goto on_error;
586
0
  }
587
2.88k
  if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_LEAF ) == 0 )
588
53
  {
589
53
    libcerror_error_set(
590
53
     error,
591
53
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
53
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
593
53
     "%s: unsupported page - not a leaf page.",
594
53
     function );
595
596
53
    goto on_error;
597
53
  }
598
2.82k
  if( libesedb_page_get_number_of_values(
599
2.82k
       page,
600
2.82k
       &number_of_page_values,
601
2.82k
       error ) != 1 )
602
0
  {
603
0
    libcerror_error_set(
604
0
     error,
605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
606
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
607
0
     "%s: unable to retrieve number of page values.",
608
0
     function );
609
610
0
    goto on_error;
611
0
  }
612
2.82k
  for( page_value_index = 1;
613
193k
       page_value_index < number_of_page_values;
614
190k
       page_value_index++ )
615
190k
  {
616
190k
    if( libesedb_page_get_value_by_index(
617
190k
         page,
618
190k
         page_value_index,
619
190k
         &page_value,
620
190k
         error ) != 1 )
621
0
    {
622
0
      libcerror_error_set(
623
0
       error,
624
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
625
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
626
0
       "%s: unable to retrieve page value: %" PRIu16 ".",
627
0
       function,
628
0
       page_value_index );
629
630
0
      goto on_error;
631
0
    }
632
190k
    if( page_value == NULL )
633
0
    {
634
0
      libcerror_error_set(
635
0
       error,
636
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
637
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
638
0
       "%s: missing page value: %" PRIu16 ".",
639
0
       function,
640
0
       page_value_index );
641
642
0
      goto on_error;
643
0
    }
644
#if defined( HAVE_DEBUG_OUTPUT )
645
    if( libcnotify_verbose != 0 )
646
    {
647
      libcnotify_printf(
648
       "%s: page value: %03" PRIu16 " page tag flags\t\t: 0x%02" PRIx8 "",
649
       function,
650
       page_value_index,
651
       page_value->flags );
652
      libesedb_debug_print_page_tag_flags(
653
       page_value->flags );
654
      libcnotify_printf(
655
       "\n" );
656
    }
657
#endif
658
190k
    if( ( page_value->flags & LIBESEDB_PAGE_TAG_FLAG_IS_DEFUNCT ) != 0 )
659
46.9k
    {
660
46.9k
      continue;
661
46.9k
    }
662
143k
    if( libesedb_page_tree_value_initialize(
663
143k
         &page_tree_value,
664
143k
         error ) != 1 )
665
0
    {
666
0
      libcerror_error_set(
667
0
       error,
668
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
669
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
670
0
       "%s: unable to create page tree value.",
671
0
       function );
672
673
0
      goto on_error;
674
0
    }
675
143k
    if( libesedb_page_tree_value_read_data(
676
143k
         page_tree_value,
677
143k
         page_value->data,
678
143k
         (size_t) page_value->size,
679
143k
         page_value->flags,
680
143k
         error ) != 1 )
681
90
    {
682
90
      libcerror_error_set(
683
90
       error,
684
90
       LIBCERROR_ERROR_DOMAIN_IO,
685
90
       LIBCERROR_IO_ERROR_READ_FAILED,
686
90
       "%s: unable to read page tree value: %" PRIu16 ".",
687
90
       function,
688
90
       page_value_index );
689
690
90
      goto on_error;
691
90
    }
692
143k
    if( libesedb_catalog_read_value_data(
693
143k
         catalog,
694
143k
         page_tree_value->data,
695
143k
         page_tree_value->data_size,
696
143k
         table_definition,
697
143k
         error ) != 1 )
698
287
    {
699
287
      libcerror_error_set(
700
287
       error,
701
287
       LIBCERROR_ERROR_DOMAIN_IO,
702
287
       LIBCERROR_IO_ERROR_READ_FAILED,
703
287
       "%s: unable to read catalog value.",
704
287
       function );
705
706
287
      goto on_error;
707
287
    }
708
143k
    if( libesedb_page_tree_value_free(
709
143k
         &page_tree_value,
710
143k
         error ) != 1 )
711
0
    {
712
0
      libcerror_error_set(
713
0
       error,
714
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
716
0
       "%s: unable to free page tree value.",
717
0
       function );
718
719
0
      goto on_error;
720
0
    }
721
143k
  }
722
2.45k
  return( 1 );
723
724
430
on_error:
725
430
  if( page_tree_value != NULL )
726
377
  {
727
377
    libesedb_page_tree_value_free(
728
377
     &page_tree_value,
729
377
     NULL );
730
377
  }
731
430
  return( -1 );
732
2.82k
}
733
734
/* Reads the catalog
735
 * Returns 1 if successful or -1 on error
736
 */
737
int libesedb_catalog_read_file_io_handle(
738
     libesedb_catalog_t *catalog,
739
     libbfio_handle_t *file_io_handle,
740
     libcerror_error_t **error )
741
3.43k
{
742
3.43k
  libesedb_page_t *page                         = NULL;
743
3.43k
  libesedb_table_definition_t *table_definition = NULL;
744
3.43k
  static char *function                         = "libesedb_catalog_read_file_io_handle";
745
3.43k
  off64_t page_offset                           = 0;
746
3.43k
  uint32_t leaf_page_number                     = 0;
747
748
3.43k
  if( catalog == NULL )
749
0
  {
750
0
    libcerror_error_set(
751
0
     error,
752
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
753
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
754
0
     "%s: invalid catalog.",
755
0
     function );
756
757
0
    return( -1 );
758
0
  }
759
3.43k
  if( catalog->page_tree == NULL )
760
0
  {
761
0
    libcerror_error_set(
762
0
     error,
763
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
764
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
765
0
     "%s: invalid catalog - missing page tree.",
766
0
     function );
767
768
0
    return( -1 );
769
0
  }
770
3.43k
  if( catalog->page_tree->io_handle == NULL )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
776
0
     "%s: invalid catalog - invalid page tree - missing IO handle.",
777
0
     function );
778
779
0
    return( -1 );
780
0
  }
781
3.43k
  if( libesedb_page_tree_get_get_first_leaf_page_number(
782
3.43k
       catalog->page_tree,
783
3.43k
       file_io_handle,
784
3.43k
       &leaf_page_number,
785
3.43k
       error ) != 1 )
786
612
  {
787
612
    libcerror_error_set(
788
612
     error,
789
612
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
790
612
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
791
612
     "%s: unable to retrieve first leaf page number from page tree.",
792
612
     function );
793
794
612
    return( -1 );
795
612
  }
796
5.27k
  while( leaf_page_number != 0 )
797
3.14k
  {
798
3.14k
    page_offset = ( leaf_page_number + 1 ) * catalog->page_tree->io_handle->page_size;
799
800
3.14k
    if( libesedb_page_tree_check_if_page_block_first_read(
801
3.14k
         catalog->page_tree,
802
3.14k
         catalog->page_block_tree,
803
3.14k
         leaf_page_number,
804
3.14k
         page_offset,
805
3.14k
         error ) != 1 )
806
116
    {
807
116
      libcerror_error_set(
808
116
       error,
809
116
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
810
116
       LIBCERROR_RUNTIME_ERROR_GENERIC,
811
116
       "%s: unable to check if first read of page number: %" PRIu32 ".",
812
116
       function,
813
116
       leaf_page_number );
814
815
116
      return( -1 );
816
116
    }
817
3.02k
#if ( SIZEOF_INT <= 4 )
818
3.02k
    if( leaf_page_number > (uint32_t) INT_MAX )
819
#else
820
    if( leaf_page_number > (unsigned int) INT_MAX )
821
#endif
822
86
    {
823
86
      libcerror_error_set(
824
86
       error,
825
86
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
826
86
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
827
86
       "%s: invalid leaf page number value out of bounds.",
828
86
       function );
829
830
86
      return( -1 );
831
86
    }
832
2.94k
    if( libfdata_vector_get_element_value_by_index(
833
2.94k
         catalog->page_tree->pages_vector,
834
2.94k
         (intptr_t *) file_io_handle,
835
2.94k
         (libfdata_cache_t *) catalog->page_tree->pages_cache,
836
2.94k
         (int) leaf_page_number - 1,
837
2.94k
         (intptr_t **) &page,
838
2.94k
         0,
839
2.94k
         error ) != 1 )
840
58
    {
841
58
      libcerror_error_set(
842
58
       error,
843
58
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
844
58
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
845
58
       "%s: unable to retrieve page: %" PRIu32 ".",
846
58
       function,
847
58
       leaf_page_number );
848
849
58
      return( -1 );
850
58
    }
851
2.88k
    if( libesedb_catalog_read_values_from_leaf_page(
852
2.88k
         catalog,
853
2.88k
         page,
854
2.88k
         &table_definition,
855
2.88k
         error ) != 1 )
856
430
    {
857
430
      libcerror_error_set(
858
430
       error,
859
430
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
860
430
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
861
430
       "%s: unable to read values from page: %" PRIu32 ".",
862
430
       function,
863
430
       leaf_page_number );
864
865
430
      return( -1 );
866
430
    }
867
2.45k
    if( libesedb_page_get_next_page_number(
868
2.45k
         page,
869
2.45k
         &leaf_page_number,
870
2.45k
         error ) != 1 )
871
0
    {
872
0
      libcerror_error_set(
873
0
       error,
874
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
875
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
876
0
       "%s: unable to retrieve next page number from page: %" PRIu32 ".",
877
0
       function,
878
0
       leaf_page_number );
879
880
0
      return( -1 );
881
0
    }
882
2.45k
  }
883
2.13k
  return( 1 );
884
2.82k
}
885
886
/* Retrieves the number of table definitions
887
 * Returns 1 if successful or -1 on error
888
 */
889
int libesedb_catalog_get_number_of_table_definitions(
890
     libesedb_catalog_t *catalog,
891
     int *number_of_table_definitions,
892
     libcerror_error_t **error )
893
945
{
894
945
  static char *function = "libesedb_catalog_get_number_of_table_definitions";
895
896
945
  if( catalog == NULL )
897
0
  {
898
0
    libcerror_error_set(
899
0
     error,
900
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
901
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
902
0
     "%s: invalid catalog.",
903
0
     function );
904
905
0
    return( -1 );
906
0
  }
907
945
  if( libcdata_array_get_number_of_entries(
908
945
       catalog->table_definition_array,
909
945
       number_of_table_definitions,
910
945
       error ) != 1 )
911
0
  {
912
0
    libcerror_error_set(
913
0
     error,
914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
915
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
916
0
     "%s: unable to retrieve number of entries from table definition array.",
917
0
     function );
918
919
0
    return( -1 );
920
0
  }
921
945
  return( 1 );
922
945
}
923
924
/* Retrieves the table definition for the specific index
925
 * Returns 1 if successful or -1 on error
926
 */
927
int libesedb_catalog_get_table_definition_by_index(
928
     libesedb_catalog_t *catalog,
929
     int table_definition_index,
930
     libesedb_table_definition_t **table_definition,
931
     libcerror_error_t **error )
932
892
{
933
892
  static char *function = "libesedb_catalog_get_table_definition_by_index";
934
935
892
  if( catalog == NULL )
936
0
  {
937
0
    libcerror_error_set(
938
0
     error,
939
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
940
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
941
0
     "%s: invalid catalog.",
942
0
     function );
943
944
0
    return( -1 );
945
0
  }
946
892
  if( libcdata_array_get_entry_by_index(
947
892
       catalog->table_definition_array,
948
892
       table_definition_index,
949
892
       (intptr_t **) table_definition,
950
892
       error ) != 1 )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
955
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
956
0
     "%s: unable to retrieve entry: %d from table definition array.",
957
0
     function,
958
0
     table_definition_index );
959
960
0
    return( -1 );
961
0
  }
962
892
  return( 1 );
963
892
}
964
965
/* Retrieves the table definition for the specific name
966
 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
967
 */
968
int libesedb_catalog_get_table_definition_by_name(
969
     libesedb_catalog_t *catalog,
970
     const uint8_t *table_name,
971
     size_t table_name_size,
972
     libesedb_table_definition_t **table_definition,
973
     libcerror_error_t **error )
974
0
{
975
0
  libesedb_table_definition_t *safe_table_definition = NULL;
976
0
  static char *function                              = "libesedb_catalog_get_table_definition_by_name";
977
0
  int entry_index                                    = 0;
978
0
  int number_of_entries                              = 0;
979
0
  int result                                         = 0;
980
981
0
  if( catalog == NULL )
982
0
  {
983
0
    libcerror_error_set(
984
0
     error,
985
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
986
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
987
0
     "%s: invalid catalog.",
988
0
     function );
989
990
0
    return( -1 );
991
0
  }
992
0
  if( table_name == NULL )
993
0
  {
994
0
    libcerror_error_set(
995
0
     error,
996
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
997
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
998
0
     "%s: invalid table name.",
999
0
     function );
1000
1001
0
    return( -1 );
1002
0
  }
1003
0
  if( ( table_name_size == 0 )
1004
0
   || ( table_name_size > (size_t) SSIZE_MAX ) )
1005
0
  {
1006
0
    libcerror_error_set(
1007
0
     error,
1008
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1009
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1010
0
     "%s: invalid table name size value exceeds maximum.",
1011
0
     function );
1012
1013
0
    return( -1 );
1014
0
  }
1015
0
  if( table_definition == NULL )
1016
0
  {
1017
0
    libcerror_error_set(
1018
0
     error,
1019
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1020
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1021
0
     "%s: invalid table definition.",
1022
0
     function );
1023
1024
0
    return( -1 );
1025
0
  }
1026
0
  *table_definition = NULL;
1027
1028
0
  if( libcdata_array_get_number_of_entries(
1029
0
       catalog->table_definition_array,
1030
0
       &number_of_entries,
1031
0
       error ) != 1 )
1032
0
  {
1033
0
    libcerror_error_set(
1034
0
     error,
1035
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1036
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1037
0
     "%s: unable to retrieve number of entries in table definition array.",
1038
0
     function );
1039
1040
0
    return( -1 );
1041
0
  }
1042
0
  for( entry_index = 0;
1043
0
       entry_index < number_of_entries;
1044
0
       entry_index++ )
1045
0
  {
1046
0
    if( libcdata_array_get_entry_by_index(
1047
0
         catalog->table_definition_array,
1048
0
         entry_index,
1049
0
         (intptr_t **) &safe_table_definition,
1050
0
         error ) != 1 )
1051
0
    {
1052
0
      libcerror_error_set(
1053
0
       error,
1054
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1055
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1056
0
       "%s: unable to retrieve entry: %d from table definition array.",
1057
0
       function,
1058
0
       entry_index );
1059
1060
0
      return( -1 );
1061
0
    }
1062
0
    if( safe_table_definition == NULL )
1063
0
    {
1064
0
      libcerror_error_set(
1065
0
       error,
1066
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1067
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1068
0
       "%s: missing table definition: %d.",
1069
0
       function,
1070
0
       entry_index );
1071
1072
0
      return( -1 );
1073
0
    }
1074
0
    result = libesedb_catalog_definition_compare_name(
1075
0
        safe_table_definition->table_catalog_definition,
1076
0
        table_name,
1077
0
        table_name_size,
1078
0
        error );
1079
1080
0
    if( result == -1 )
1081
0
    {
1082
0
      libcerror_error_set(
1083
0
       error,
1084
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1085
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1086
0
       "%s: unable to compare table name with table catalog definition: %d name.",
1087
0
       function,
1088
0
       entry_index );
1089
1090
0
      return( -1 );
1091
0
    }
1092
0
    else if( result == 1 )
1093
0
    {
1094
0
      break;
1095
0
    }
1096
0
  }
1097
0
  if( result != 0 )
1098
0
  {
1099
0
    *table_definition = safe_table_definition;
1100
0
  }
1101
0
  return( result );
1102
0
}
1103
1104
/* Retrieves the table definition for the specific UTF-8 encoded name
1105
 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
1106
 */
1107
int libesedb_catalog_get_table_definition_by_utf8_name(
1108
     libesedb_catalog_t *catalog,
1109
     const uint8_t *utf8_string,
1110
     size_t utf8_string_length,
1111
     libesedb_table_definition_t **table_definition,
1112
     libcerror_error_t **error )
1113
339
{
1114
339
  libesedb_table_definition_t *safe_table_definition = NULL;
1115
339
  static char *function                              = "libesedb_catalog_get_table_definition_by_utf8_name";
1116
339
  int entry_index                                    = 0;
1117
339
  int number_of_entries                              = 0;
1118
339
  int result                                         = LIBUNA_COMPARE_GREATER;
1119
1120
339
  if( catalog == NULL )
1121
0
  {
1122
0
    libcerror_error_set(
1123
0
     error,
1124
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1125
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1126
0
     "%s: invalid catalog.",
1127
0
     function );
1128
1129
0
    return( -1 );
1130
0
  }
1131
339
  if( utf8_string == NULL )
1132
0
  {
1133
0
    libcerror_error_set(
1134
0
     error,
1135
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1136
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1137
0
     "%s: invalid UTF-8 string.",
1138
0
     function );
1139
1140
0
    return( -1 );
1141
0
  }
1142
339
  if( ( utf8_string_length == 0 )
1143
339
   || ( utf8_string_length > (size_t) SSIZE_MAX ) )
1144
0
  {
1145
0
    libcerror_error_set(
1146
0
     error,
1147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1148
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1149
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
1150
0
     function );
1151
1152
0
    return( -1 );
1153
0
  }
1154
339
  if( table_definition == NULL )
1155
0
  {
1156
0
    libcerror_error_set(
1157
0
     error,
1158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1160
0
     "%s: invalid table definition.",
1161
0
     function );
1162
1163
0
    return( -1 );
1164
0
  }
1165
339
  *table_definition = NULL;
1166
1167
339
  if( libcdata_array_get_number_of_entries(
1168
339
       catalog->table_definition_array,
1169
339
       &number_of_entries,
1170
339
       error ) != 1 )
1171
0
  {
1172
0
    libcerror_error_set(
1173
0
     error,
1174
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1175
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1176
0
     "%s: unable to retrieve number of entries in table definition array.",
1177
0
     function );
1178
1179
0
    return( -1 );
1180
0
  }
1181
339
  for( entry_index = 0;
1182
5.44k
       entry_index < number_of_entries;
1183
5.10k
       entry_index++ )
1184
5.22k
  {
1185
5.22k
    if( libcdata_array_get_entry_by_index(
1186
5.22k
         catalog->table_definition_array,
1187
5.22k
         entry_index,
1188
5.22k
         (intptr_t **) &safe_table_definition,
1189
5.22k
         error ) != 1 )
1190
0
    {
1191
0
      libcerror_error_set(
1192
0
       error,
1193
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1194
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1195
0
       "%s: unable to retrieve entry: %d from table definition array.",
1196
0
       function,
1197
0
       entry_index );
1198
1199
0
      return( -1 );
1200
0
    }
1201
5.22k
    if( safe_table_definition == NULL )
1202
0
    {
1203
0
      libcerror_error_set(
1204
0
       error,
1205
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1206
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1207
0
       "%s: missing table definition: %d.",
1208
0
       function,
1209
0
       entry_index );
1210
1211
0
      return( -1 );
1212
0
    }
1213
5.22k
    result = libesedb_catalog_definition_compare_name_with_utf8_string(
1214
5.22k
        safe_table_definition->table_catalog_definition,
1215
5.22k
        utf8_string,
1216
5.22k
        utf8_string_length,
1217
5.22k
        error );
1218
1219
5.22k
    if( result == -1 )
1220
121
    {
1221
121
      libcerror_error_set(
1222
121
       error,
1223
121
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1224
121
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1225
121
       "%s: unable to compare UTF-8 string with table catalog definition: %d name.",
1226
121
       function,
1227
121
       entry_index );
1228
1229
121
      return( -1 );
1230
121
    }
1231
5.10k
    else if( result == LIBUNA_COMPARE_EQUAL )
1232
2
    {
1233
2
      break;
1234
2
    }
1235
5.22k
  }
1236
218
  if( result == LIBUNA_COMPARE_EQUAL )
1237
2
  {
1238
2
    *table_definition = safe_table_definition;
1239
1240
2
    return( 1 );
1241
2
  }
1242
216
  return( 0 );
1243
218
}
1244
1245
/* Retrieves the table definition for the specific UTF-16 encoded name
1246
 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
1247
 */
1248
int libesedb_catalog_get_table_definition_by_utf16_name(
1249
     libesedb_catalog_t *catalog,
1250
     const uint16_t *utf16_string,
1251
     size_t utf16_string_length,
1252
     libesedb_table_definition_t **table_definition,
1253
     libcerror_error_t **error )
1254
0
{
1255
0
  libesedb_table_definition_t *safe_table_definition = NULL;
1256
0
  static char *function                              = "libesedb_catalog_get_table_definition_by_utf16_name";
1257
0
  int entry_index                                    = 0;
1258
0
  int number_of_entries                              = 0;
1259
0
  int result                                         = LIBUNA_COMPARE_GREATER;
1260
1261
0
  if( catalog == NULL )
1262
0
  {
1263
0
    libcerror_error_set(
1264
0
     error,
1265
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1266
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1267
0
     "%s: invalid catalog.",
1268
0
     function );
1269
1270
0
    return( -1 );
1271
0
  }
1272
0
  if( utf16_string == NULL )
1273
0
  {
1274
0
    libcerror_error_set(
1275
0
     error,
1276
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1277
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1278
0
     "%s: invalid UTF-16 string.",
1279
0
     function );
1280
1281
0
    return( -1 );
1282
0
  }
1283
0
  if( ( utf16_string_length == 0 )
1284
0
   || ( utf16_string_length > (size_t) SSIZE_MAX ) )
1285
0
  {
1286
0
    libcerror_error_set(
1287
0
     error,
1288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1289
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1290
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
1291
0
     function );
1292
1293
0
    return( -1 );
1294
0
  }
1295
0
  if( table_definition == NULL )
1296
0
  {
1297
0
    libcerror_error_set(
1298
0
     error,
1299
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1300
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1301
0
     "%s: invalid table definition.",
1302
0
     function );
1303
1304
0
    return( -1 );
1305
0
  }
1306
0
  *table_definition = NULL;
1307
1308
0
  if( libcdata_array_get_number_of_entries(
1309
0
       catalog->table_definition_array,
1310
0
       &number_of_entries,
1311
0
       error ) != 1 )
1312
0
  {
1313
0
    libcerror_error_set(
1314
0
     error,
1315
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1316
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1317
0
     "%s: unable to retrieve number of entries in table definition array.",
1318
0
     function );
1319
1320
0
    return( -1 );
1321
0
  }
1322
0
  for( entry_index = 0;
1323
0
       entry_index < number_of_entries;
1324
0
       entry_index++ )
1325
0
  {
1326
0
    if( libcdata_array_get_entry_by_index(
1327
0
         catalog->table_definition_array,
1328
0
         entry_index,
1329
0
         (intptr_t **) &safe_table_definition,
1330
0
         error ) != 1 )
1331
0
    {
1332
0
      libcerror_error_set(
1333
0
       error,
1334
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1335
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1336
0
       "%s: unable to retrieve entry: %d from table definition array.",
1337
0
       function,
1338
0
       entry_index );
1339
1340
0
      return( -1 );
1341
0
    }
1342
0
    if( safe_table_definition == NULL )
1343
0
    {
1344
0
      libcerror_error_set(
1345
0
       error,
1346
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1347
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1348
0
       "%s: missing table definition: %d.",
1349
0
       function,
1350
0
       entry_index );
1351
1352
0
      return( -1 );
1353
0
    }
1354
0
    result = libesedb_catalog_definition_compare_name_with_utf16_string(
1355
0
        safe_table_definition->table_catalog_definition,
1356
0
        utf16_string,
1357
0
        utf16_string_length,
1358
0
        error );
1359
1360
0
    if( result == -1 )
1361
0
    {
1362
0
      libcerror_error_set(
1363
0
       error,
1364
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1365
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1366
0
       "%s: unable to compare UTF-16 string with table catalog definition: %d name.",
1367
0
       function,
1368
0
       entry_index );
1369
1370
0
      return( -1 );
1371
0
    }
1372
0
    else if( result == LIBUNA_COMPARE_EQUAL )
1373
0
    {
1374
0
      break;
1375
0
    }
1376
0
  }
1377
0
  if( result == LIBUNA_COMPARE_EQUAL )
1378
0
  {
1379
0
    *table_definition = safe_table_definition;
1380
1381
0
    return( 1 );
1382
0
  }
1383
0
  return( 0 );
1384
0
}
1385