Coverage Report

Created: 2024-02-25 07:19

/src/libesedb/libesedb/libesedb_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File functions
3
 *
4
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "libesedb_catalog.h"
29
#include "libesedb_database.h"
30
#include "libesedb_debug.h"
31
#include "libesedb_definitions.h"
32
#include "libesedb_i18n.h"
33
#include "libesedb_io_handle.h"
34
#include "libesedb_file.h"
35
#include "libesedb_file_header.h"
36
#include "libesedb_libbfio.h"
37
#include "libesedb_libcerror.h"
38
#include "libesedb_libcnotify.h"
39
#include "libesedb_libfcache.h"
40
#include "libesedb_libfdata.h"
41
#include "libesedb_page.h"
42
#include "libesedb_table.h"
43
#include "libesedb_table_definition.h"
44
45
/* Creates a file
46
 * Make sure the value file is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libesedb_file_initialize(
50
     libesedb_file_t **file,
51
     libcerror_error_t **error )
52
1.61k
{
53
1.61k
  libesedb_internal_file_t *internal_file = NULL;
54
1.61k
  static char *function                   = "libesedb_file_initialize";
55
56
1.61k
  if( file == 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 file.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
1.61k
  if( *file != 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 file value already set.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
1.61k
  internal_file = memory_allocate_structure(
79
1.61k
                   libesedb_internal_file_t );
80
81
1.61k
  if( internal_file == 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 file.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
1.61k
  if( memory_set(
93
1.61k
       internal_file,
94
1.61k
       0,
95
1.61k
       sizeof( libesedb_internal_file_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 file.",
102
0
     function );
103
104
0
    memory_free(
105
0
     internal_file );
106
107
0
    return( -1 );
108
0
  }
109
1.61k
  if( libesedb_io_handle_initialize(
110
1.61k
       &( internal_file->io_handle ),
111
1.61k
       error ) != 1 )
112
0
  {
113
0
    libcerror_error_set(
114
0
     error,
115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
117
0
     "%s: unable to create IO handle.",
118
0
     function );
119
120
0
    goto on_error;
121
0
  }
122
1.61k
  if( libesedb_i18n_initialize(
123
1.61k
       error ) != 1 )
124
0
  {
125
0
    libcerror_error_set(
126
0
     error,
127
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
128
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
129
0
     "%s: unable to initalize internationalization (i18n).",
130
0
     function );
131
132
0
    goto on_error;
133
0
  }
134
1.61k
  *file = (libesedb_file_t *) internal_file;
135
136
1.61k
  return( 1 );
137
138
0
on_error:
139
0
  if( internal_file != NULL )
140
0
  {
141
0
    if( internal_file->io_handle != NULL )
142
0
    {
143
0
      libesedb_io_handle_free(
144
0
       &( internal_file->io_handle ),
145
0
       NULL );
146
0
    }
147
0
    memory_free(
148
0
     internal_file );
149
0
  }
150
0
  return( -1 );
151
1.61k
}
152
153
/* Frees a file
154
 * Returns 1 if successful or -1 on error
155
 */
156
int libesedb_file_free(
157
     libesedb_file_t **file,
158
     libcerror_error_t **error )
159
1.61k
{
160
1.61k
  libesedb_internal_file_t *internal_file = NULL;
161
1.61k
  static char *function                   = "libesedb_file_free";
162
1.61k
  int result                              = 1;
163
164
1.61k
  if( file == NULL )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170
0
     "%s: invalid file.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
1.61k
  if( *file != NULL )
176
1.61k
  {
177
1.61k
    internal_file = (libesedb_internal_file_t *) *file;
178
179
1.61k
    if( internal_file->file_io_handle != NULL )
180
0
    {
181
0
      if( libesedb_file_close(
182
0
           *file,
183
0
           error ) != 0 )
184
0
      {
185
0
        libcerror_error_set(
186
0
         error,
187
0
         LIBCERROR_ERROR_DOMAIN_IO,
188
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
189
0
         "%s: unable to close file.",
190
0
         function );
191
192
0
        result = -1;
193
0
      }
194
0
    }
195
1.61k
    *file = NULL;
196
197
1.61k
    if( libesedb_io_handle_free(
198
1.61k
         &( internal_file->io_handle ),
199
1.61k
         error ) != 1 )
200
0
    {
201
0
      libcerror_error_set(
202
0
       error,
203
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
205
0
       "%s: unable to free IO handle.",
206
0
       function );
207
208
0
      result = -1;
209
0
    }
210
1.61k
    memory_free(
211
1.61k
     internal_file );
212
1.61k
  }
213
1.61k
  return( result );
214
1.61k
}
215
216
/* Signals a file to abort its current activity
217
 * Returns 1 if successful or -1 on error
218
 */
219
int libesedb_file_signal_abort(
220
     libesedb_file_t *file,
221
     libcerror_error_t **error )
222
0
{
223
0
  libesedb_internal_file_t *internal_file = NULL;
224
0
  static char *function                   = "libesedb_file_signal_abort";
225
226
0
  if( file == NULL )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
232
0
     "%s: invalid file.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
0
  internal_file = (libesedb_internal_file_t *) file;
238
239
0
  if( internal_file->io_handle == NULL )
240
0
  {
241
0
    libcerror_error_set(
242
0
     error,
243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
245
0
     "%s: invalid file - missing IO handle.",
246
0
     function );
247
248
0
    return( -1 );
249
0
  }
250
0
  internal_file->io_handle->abort = 1;
251
252
0
  return( 1 );
253
0
}
254
255
/* Opens a file
256
 * Returns 1 if successful or -1 on error
257
 */
258
int libesedb_file_open(
259
     libesedb_file_t *file,
260
     const char *filename,
261
     int access_flags,
262
     libcerror_error_t **error )
263
0
{
264
0
  libbfio_handle_t *file_io_handle        = NULL;
265
0
  libesedb_internal_file_t *internal_file = NULL;
266
0
  static char *function                   = "libesedb_file_open";
267
0
  size_t filename_length                  = 0;
268
269
0
  if( file == NULL )
270
0
  {
271
0
    libcerror_error_set(
272
0
     error,
273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
275
0
     "%s: invalid file.",
276
0
     function );
277
278
0
    return( -1 );
279
0
  }
280
0
  internal_file = (libesedb_internal_file_t *) file;
281
282
0
  if( filename == NULL )
283
0
  {
284
0
    libcerror_error_set(
285
0
     error,
286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
288
0
     "%s: invalid filename.",
289
0
     function );
290
291
0
    return( -1 );
292
0
  }
293
0
  if( ( ( access_flags & LIBESEDB_ACCESS_FLAG_READ ) == 0 )
294
0
   && ( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) == 0 ) )
295
0
  {
296
0
    libcerror_error_set(
297
0
     error,
298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
299
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
300
0
     "%s: unsupported access flags.",
301
0
     function );
302
303
0
    return( -1 );
304
0
  }
305
0
  if( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) != 0 )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
310
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
311
0
     "%s: write access currently not supported.",
312
0
     function );
313
314
0
    return( -1 );
315
0
  }
316
0
  if( libbfio_file_initialize(
317
0
       &file_io_handle,
318
0
       error ) != 1 )
319
0
  {
320
0
    libcerror_error_set(
321
0
     error,
322
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
323
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
324
0
     "%s: unable to create file IO handle.",
325
0
     function );
326
327
0
    goto on_error;
328
0
  }
329
#if defined( HAVE_DEBUG_OUTPUT )
330
  if( libbfio_handle_set_track_offsets_read(
331
       file_io_handle,
332
       1,
333
       error ) != 1 )
334
  {
335
                libcerror_error_set(
336
                 error,
337
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
338
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
339
                 "%s: unable to set track offsets read in file IO handle.",
340
                 function );
341
342
    goto on_error;
343
  }
344
#endif
345
0
  filename_length = narrow_string_length(
346
0
                     filename );
347
348
0
  if( libbfio_file_set_name(
349
0
       file_io_handle,
350
0
       filename,
351
0
       filename_length + 1,
352
0
       error ) != 1 )
353
0
  {
354
0
                libcerror_error_set(
355
0
                 error,
356
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
357
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
358
0
                 "%s: unable to set filename in file IO handle.",
359
0
                 function );
360
361
0
    goto on_error;
362
0
  }
363
0
  if( libesedb_file_open_file_io_handle(
364
0
       file,
365
0
       file_io_handle,
366
0
       access_flags,
367
0
       error ) != 1 )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_IO,
372
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
373
0
     "%s: unable to open file: %s.",
374
0
     function,
375
0
     filename );
376
377
0
    goto on_error;
378
0
  }
379
0
  internal_file->file_io_handle_created_in_library = 1;
380
381
0
  return( 1 );
382
383
0
on_error:
384
0
  if( file_io_handle != NULL )
385
0
  {
386
0
    libbfio_handle_free(
387
0
     &file_io_handle,
388
0
     NULL );
389
0
  }
390
0
  return( -1 );
391
0
}
392
393
#if defined( HAVE_WIDE_CHARACTER_TYPE )
394
395
/* Opens a file
396
 * Returns 1 if successful or -1 on error
397
 */
398
int libesedb_file_open_wide(
399
     libesedb_file_t *file,
400
     const wchar_t *filename,
401
     int access_flags,
402
     libcerror_error_t **error )
403
{
404
  libbfio_handle_t *file_io_handle        = NULL;
405
  libesedb_internal_file_t *internal_file = NULL;
406
  static char *function                   = "libesedb_file_open_wide";
407
  size_t filename_length                  = 0;
408
409
  if( file == NULL )
410
  {
411
    libcerror_error_set(
412
     error,
413
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
414
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
415
     "%s: invalid file.",
416
     function );
417
418
    return( -1 );
419
  }
420
  internal_file = (libesedb_internal_file_t *) file;
421
422
  if( filename == NULL )
423
  {
424
    libcerror_error_set(
425
     error,
426
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
427
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
428
     "%s: invalid filename.",
429
     function );
430
431
    return( -1 );
432
  }
433
  if( ( ( access_flags & LIBESEDB_ACCESS_FLAG_READ ) == 0 )
434
   && ( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) == 0 ) )
435
  {
436
    libcerror_error_set(
437
     error,
438
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
439
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
440
     "%s: unsupported access flags.",
441
     function );
442
443
    return( -1 );
444
  }
445
  if( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) != 0 )
446
  {
447
    libcerror_error_set(
448
     error,
449
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
450
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
451
     "%s: write access currently not supported.",
452
     function );
453
454
    return( -1 );
455
  }
456
  if( libbfio_file_initialize(
457
       &file_io_handle,
458
       error ) != 1 )
459
  {
460
    libcerror_error_set(
461
     error,
462
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
463
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
464
     "%s: unable to create file IO handle.",
465
     function );
466
467
    goto on_error;
468
  }
469
#if defined( HAVE_DEBUG_OUTPUT )
470
  if( libbfio_handle_set_track_offsets_read(
471
       file_io_handle,
472
       1,
473
       error ) != 1 )
474
  {
475
                libcerror_error_set(
476
                 error,
477
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
478
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
479
                 "%s: unable to set track offsets read in file IO handle.",
480
                 function );
481
482
    goto on_error;
483
  }
484
#endif
485
  filename_length = wide_string_length(
486
                     filename );
487
488
  if( libbfio_file_set_name_wide(
489
       file_io_handle,
490
       filename,
491
       filename_length + 1,
492
       error ) != 1 )
493
  {
494
                libcerror_error_set(
495
                 error,
496
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
498
                 "%s: unable to set filename in file IO handle.",
499
                 function );
500
501
    goto on_error;
502
  }
503
  if( libesedb_file_open_file_io_handle(
504
       file,
505
       file_io_handle,
506
       access_flags,
507
       error ) != 1 )
508
  {
509
    libcerror_error_set(
510
     error,
511
     LIBCERROR_ERROR_DOMAIN_IO,
512
     LIBCERROR_IO_ERROR_OPEN_FAILED,
513
     "%s: unable to open file: %ls.",
514
     function,
515
     filename );
516
517
    goto on_error;
518
  }
519
  internal_file->file_io_handle_created_in_library = 1;
520
521
  return( 1 );
522
523
on_error:
524
  if( file_io_handle != NULL )
525
  {
526
    libbfio_handle_free(
527
     &file_io_handle,
528
     NULL );
529
  }
530
  return( -1 );
531
}
532
533
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
534
535
/* Opens a file using a Basic File IO (bfio) handle
536
 * Returns 1 if successful or -1 on error
537
 */
538
int libesedb_file_open_file_io_handle(
539
     libesedb_file_t *file,
540
     libbfio_handle_t *file_io_handle,
541
     int access_flags,
542
     libcerror_error_t **error )
543
1.61k
{
544
1.61k
  libesedb_internal_file_t *internal_file = NULL;
545
1.61k
  static char *function                   = "libesedb_file_open_file_io_handle";
546
1.61k
  int bfio_access_flags                   = 0;
547
1.61k
  int file_io_handle_is_open              = 0;
548
549
1.61k
  if( file == NULL )
550
0
  {
551
0
    libcerror_error_set(
552
0
     error,
553
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
554
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
555
0
     "%s: invalid file.",
556
0
     function );
557
558
0
    return( -1 );
559
0
  }
560
1.61k
  if( file_io_handle == NULL )
561
0
  {
562
0
    libcerror_error_set(
563
0
     error,
564
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
565
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
566
0
     "%s: invalid file IO handle.",
567
0
     function );
568
569
0
    return( -1 );
570
0
  }
571
1.61k
  if( ( ( access_flags & LIBESEDB_ACCESS_FLAG_READ ) == 0 )
572
1.61k
   && ( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) == 0 ) )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
577
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
578
0
     "%s: unsupported access flags.",
579
0
     function );
580
581
0
    return( -1 );
582
0
  }
583
1.61k
  if( ( access_flags & LIBESEDB_ACCESS_FLAG_WRITE ) != 0 )
584
0
  {
585
0
    libcerror_error_set(
586
0
     error,
587
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
588
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
589
0
     "%s: write access currently not supported.",
590
0
     function );
591
592
0
    return( -1 );
593
0
  }
594
1.61k
  internal_file = (libesedb_internal_file_t *) file;
595
596
1.61k
  if( ( access_flags & LIBESEDB_ACCESS_FLAG_READ ) != 0 )
597
1.61k
  {
598
1.61k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
599
1.61k
  }
600
1.61k
  file_io_handle_is_open = libbfio_handle_is_open(
601
1.61k
                            file_io_handle,
602
1.61k
                            error );
603
604
1.61k
  if( file_io_handle_is_open == -1 )
605
0
  {
606
0
    libcerror_error_set(
607
0
     error,
608
0
     LIBCERROR_ERROR_DOMAIN_IO,
609
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
610
0
     "%s: unable to open file.",
611
0
     function );
612
613
0
    goto on_error;
614
0
  }
615
1.61k
  else if( file_io_handle_is_open == 0 )
616
1.61k
  {
617
1.61k
    if( libbfio_handle_open(
618
1.61k
         file_io_handle,
619
1.61k
         bfio_access_flags,
620
1.61k
         error ) != 1 )
621
0
    {
622
0
      libcerror_error_set(
623
0
       error,
624
0
       LIBCERROR_ERROR_DOMAIN_IO,
625
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
626
0
       "%s: unable to open file IO handle.",
627
0
       function );
628
629
0
      goto on_error;
630
0
    }
631
1.61k
    internal_file->file_io_handle_opened_in_library = 1;
632
1.61k
  }
633
1.61k
  if( libesedb_file_open_read(
634
1.61k
       internal_file,
635
1.61k
       file_io_handle,
636
1.61k
       error ) != 1 )
637
1.36k
  {
638
1.36k
    libcerror_error_set(
639
1.36k
     error,
640
1.36k
     LIBCERROR_ERROR_DOMAIN_IO,
641
1.36k
     LIBCERROR_IO_ERROR_READ_FAILED,
642
1.36k
     "%s: unable to read from file handle.",
643
1.36k
     function );
644
645
1.36k
    goto on_error;
646
1.36k
  }
647
254
  internal_file->file_io_handle = file_io_handle;
648
649
254
  return( 1 );
650
651
1.36k
on_error:
652
1.36k
  if( ( file_io_handle_is_open == 0 )
653
1.36k
   && ( internal_file->file_io_handle_opened_in_library != 0 ) )
654
1.36k
  {
655
1.36k
    libbfio_handle_close(
656
1.36k
     file_io_handle,
657
1.36k
     error );
658
659
1.36k
    internal_file->file_io_handle_opened_in_library = 0;
660
1.36k
  }
661
1.36k
  return( -1 );
662
1.61k
}
663
664
/* Closes a file
665
 * Returns 0 if successful or -1 on error
666
 */
667
int libesedb_file_close(
668
     libesedb_file_t *file,
669
     libcerror_error_t **error )
670
254
{
671
254
  libesedb_internal_file_t *internal_file = NULL;
672
254
  static char *function                   = "libesedb_file_close";
673
254
  int result                              = 0;
674
675
254
  if( file == NULL )
676
0
  {
677
0
    libcerror_error_set(
678
0
     error,
679
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
680
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
681
0
     "%s: invalid file.",
682
0
     function );
683
684
0
    return( -1 );
685
0
  }
686
254
  internal_file = (libesedb_internal_file_t *) file;
687
688
254
  if( internal_file->file_io_handle == NULL )
689
0
  {
690
0
    libcerror_error_set(
691
0
     error,
692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
693
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
694
0
     "%s: invalid file - missing file IO handle.",
695
0
     function );
696
697
0
    return( -1 );
698
0
  }
699
#if defined( HAVE_DEBUG_OUTPUT )
700
  if( libcnotify_verbose != 0 )
701
  {
702
    if( internal_file->file_io_handle_created_in_library != 0 )
703
    {
704
      if( libesedb_debug_print_read_offsets(
705
           internal_file->file_io_handle,
706
           error ) != 1 )
707
      {
708
        libcerror_error_set(
709
         error,
710
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
711
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
712
         "%s: unable to print the read offsets.",
713
         function );
714
715
        result = -1;
716
      }
717
    }
718
  }
719
#endif
720
254
  if( internal_file->file_io_handle_opened_in_library != 0 )
721
254
  {
722
254
    if( libbfio_handle_close(
723
254
         internal_file->file_io_handle,
724
254
         error ) != 0 )
725
0
    {
726
0
      libcerror_error_set(
727
0
       error,
728
0
       LIBCERROR_ERROR_DOMAIN_IO,
729
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
730
0
       "%s: unable to close file IO handle.",
731
0
       function );
732
733
0
      result = -1;
734
0
    }
735
254
    internal_file->file_io_handle_opened_in_library = 0;
736
254
  }
737
254
  if( internal_file->file_io_handle_created_in_library != 0 )
738
0
  {
739
0
    if( libbfio_handle_free(
740
0
         &( internal_file->file_io_handle ),
741
0
         error ) != 1 )
742
0
    {
743
0
      libcerror_error_set(
744
0
       error,
745
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
746
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
747
0
       "%s: unable to free file IO handle.",
748
0
       function );
749
750
0
      result = -1;
751
0
    }
752
0
    internal_file->file_io_handle_created_in_library = 0;
753
0
  }
754
254
  internal_file->file_io_handle = NULL;
755
756
254
  if( libesedb_io_handle_clear(
757
254
       internal_file->io_handle,
758
254
       error ) != 1 )
759
0
  {
760
0
    libcerror_error_set(
761
0
     error,
762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
763
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
764
0
     "%s: unable to clear IO handle.",
765
0
     function );
766
767
0
    result = -1;
768
0
  }
769
254
  if( libfdata_vector_free(
770
254
       &( internal_file->pages_vector ),
771
254
       error ) != 1 )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
776
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
777
0
     "%s: unable to free pages vector.",
778
0
     function );
779
780
0
    result = -1;
781
0
  }
782
254
  if( libfcache_cache_free(
783
254
       &( internal_file->pages_cache ),
784
254
       error ) != 1 )
785
0
  {
786
0
    libcerror_error_set(
787
0
     error,
788
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
789
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
790
0
     "%s: unable to free pages cache.",
791
0
     function );
792
793
0
    result = -1;
794
0
  }
795
254
  if( libesedb_database_free(
796
254
       &( internal_file->database ),
797
254
       error ) != 1 )
798
0
  {
799
0
    libcerror_error_set(
800
0
     error,
801
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
802
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
803
0
     "%s: unable to free database.",
804
0
     function );
805
806
0
    result = -1;
807
0
  }
808
254
  if( libesedb_catalog_free(
809
254
       &( internal_file->catalog ),
810
254
       error ) != 1 )
811
0
  {
812
0
    libcerror_error_set(
813
0
     error,
814
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
815
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
816
0
     "%s: unable to free catalog.",
817
0
     function );
818
819
0
    result = -1;
820
0
  }
821
254
  if( libesedb_catalog_free(
822
254
       &( internal_file->backup_catalog ),
823
254
       error ) != 1 )
824
0
  {
825
0
    libcerror_error_set(
826
0
     error,
827
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
828
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
829
0
     "%s: unable to free backup catalog.",
830
0
     function );
831
832
0
    result = -1;
833
0
  }
834
254
  return( result );
835
254
}
836
837
/* Opens a file for reading
838
 * Returns 1 if successful or -1 on error
839
 */
840
int libesedb_file_open_read(
841
     libesedb_internal_file_t *internal_file,
842
     libbfio_handle_t *file_io_handle,
843
     libcerror_error_t **error )
844
1.61k
{
845
1.61k
  libesedb_file_header_t *file_header = NULL;
846
1.61k
  static char *function               = "libesedb_file_open_read";
847
1.61k
  size64_t file_size                  = 0;
848
1.61k
  off64_t file_offset                 = 0;
849
1.61k
  int result                          = 0;
850
1.61k
  int segment_index                   = 0;
851
852
1.61k
  if( internal_file == NULL )
853
0
  {
854
0
    libcerror_error_set(
855
0
     error,
856
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
857
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
858
0
     "%s: invalid file.",
859
0
     function );
860
861
0
    return( -1 );
862
0
  }
863
1.61k
  if( internal_file->io_handle == NULL )
864
0
  {
865
0
    libcerror_error_set(
866
0
     error,
867
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
868
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
869
0
     "%s: invalid file - missing IO handle.",
870
0
     function );
871
872
0
    return( -1 );
873
0
  }
874
1.61k
  if( internal_file->pages_vector != NULL )
875
0
  {
876
0
    libcerror_error_set(
877
0
     error,
878
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
879
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
880
0
     "%s: invalid file - pages vector already set.",
881
0
     function );
882
883
0
    return( -1 );
884
0
  }
885
1.61k
  if( internal_file->pages_cache != NULL )
886
0
  {
887
0
    libcerror_error_set(
888
0
     error,
889
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
890
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
891
0
     "%s: invalid file - pages cache already set.",
892
0
     function );
893
894
0
    return( -1 );
895
0
  }
896
1.61k
  if( internal_file->database != NULL )
897
0
  {
898
0
    libcerror_error_set(
899
0
     error,
900
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
901
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
902
0
     "%s: invalid file - database already set.",
903
0
     function );
904
905
0
    return( -1 );
906
0
  }
907
1.61k
  if( internal_file->catalog != NULL )
908
0
  {
909
0
    libcerror_error_set(
910
0
     error,
911
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
912
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
913
0
     "%s: invalid file - catalog already set.",
914
0
     function );
915
916
0
    return( -1 );
917
0
  }
918
1.61k
  if( internal_file->backup_catalog != NULL )
919
0
  {
920
0
    libcerror_error_set(
921
0
     error,
922
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
923
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
924
0
     "%s: invalid file - backup catalog already set.",
925
0
     function );
926
927
0
    return( -1 );
928
0
  }
929
1.61k
  internal_file->io_handle->abort = 0;
930
931
1.61k
  if( libbfio_handle_get_size(
932
1.61k
       file_io_handle,
933
1.61k
       &file_size,
934
1.61k
       error ) != 1 )
935
0
  {
936
0
    libcerror_error_set(
937
0
     error,
938
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
939
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
940
0
     "%s: unable to retrieve file size.",
941
0
     function );
942
943
0
    goto on_error;
944
0
  }
945
#if defined( HAVE_DEBUG_OUTPUT )
946
  if( libcnotify_verbose != 0 )
947
  {
948
    libcnotify_printf(
949
     "Reading file header:\n" );
950
  }
951
#endif
952
1.61k
  if( libesedb_file_header_initialize(
953
1.61k
       &file_header,
954
1.61k
       error ) != 1 )
955
0
  {
956
0
    libcerror_error_set(
957
0
     error,
958
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
959
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
960
0
     "%s: unable to create file header.",
961
0
     function );
962
963
0
    goto on_error;
964
0
  }
965
1.61k
  if( libesedb_file_header_read_file_io_handle(
966
1.61k
       file_header,
967
1.61k
       file_io_handle,
968
1.61k
       file_offset,
969
1.61k
       error ) != 1 )
970
129
  {
971
129
    libcerror_error_set(
972
129
     error,
973
129
     LIBCERROR_ERROR_DOMAIN_IO,
974
129
     LIBCERROR_IO_ERROR_READ_FAILED,
975
129
     "%s: unable to read file header.",
976
129
     function );
977
978
129
    goto on_error;
979
129
  }
980
1.48k
  internal_file->io_handle->file_type                = file_header->file_type;
981
1.48k
  internal_file->io_handle->format_version           = file_header->format_version;
982
1.48k
  internal_file->io_handle->format_revision          = file_header->format_revision;
983
1.48k
  internal_file->io_handle->page_size                = file_header->page_size;
984
1.48k
  internal_file->io_handle->creation_format_version  = file_header->creation_format_version;
985
1.48k
  internal_file->io_handle->creation_format_revision = file_header->creation_format_revision;
986
987
1.48k
  if( libesedb_file_header_free(
988
1.48k
       &file_header,
989
1.48k
       error ) != 1 )
990
0
  {
991
0
    libcerror_error_set(
992
0
     error,
993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
994
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
995
0
     "%s: unable to free file header.",
996
0
     function );
997
998
0
    goto on_error;
999
0
  }
1000
#if defined( HAVE_DEBUG_OUTPUT )
1001
  if( libcnotify_verbose != 0 )
1002
  {
1003
    libcnotify_printf(
1004
     "Reading backup file header:\n" );
1005
  }
1006
#endif
1007
1.48k
  if( internal_file->io_handle->page_size != 0 )
1008
1.44k
  {
1009
1.44k
    if( libesedb_file_header_initialize(
1010
1.44k
         &file_header,
1011
1.44k
         error ) != 1 )
1012
0
    {
1013
0
      libcerror_error_set(
1014
0
       error,
1015
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1016
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1017
0
       "%s: unable to create backup file header.",
1018
0
       function );
1019
1020
0
      goto on_error;
1021
0
    }
1022
1.44k
    result = libesedb_file_header_read_file_io_handle(
1023
1.44k
              file_header,
1024
1.44k
              file_io_handle,
1025
1.44k
              (off64_t) internal_file->io_handle->page_size,
1026
1.44k
              error );
1027
1028
1.44k
    if( result != 1 )
1029
65
    {
1030
65
      file_offset = 0x0800;
1031
1032
390
      while( file_offset <= 0x8000 )
1033
325
      {
1034
#if defined( HAVE_DEBUG_OUTPUT )
1035
        if( ( libcnotify_verbose != 0 )
1036
         && ( error != NULL )
1037
         && ( *error != NULL ) )
1038
        {
1039
          libcnotify_print_error_backtrace(
1040
           *error );
1041
        }
1042
#endif
1043
325
        libcerror_error_free(
1044
325
         error );
1045
1046
325
        result = libesedb_file_header_read_file_io_handle(
1047
325
                  file_header,
1048
325
                  file_io_handle,
1049
325
                  (off64_t) internal_file->io_handle->page_size,
1050
325
                  error );
1051
1052
325
        if( result == 1 )
1053
0
        {
1054
0
          break;
1055
0
        }
1056
325
        file_offset <<= 1;
1057
325
      }
1058
65
    }
1059
1.44k
    if( result != 1 )
1060
65
    {
1061
65
      libcerror_error_set(
1062
65
       error,
1063
65
       LIBCERROR_ERROR_DOMAIN_IO,
1064
65
       LIBCERROR_IO_ERROR_READ_FAILED,
1065
65
       "%s: unable to read backup file header.",
1066
65
       function );
1067
1068
65
      goto on_error;
1069
65
    }
1070
1.38k
    if( internal_file->io_handle->format_version == 0 )
1071
10
    {
1072
10
      internal_file->io_handle->format_version = file_header->format_version;
1073
10
    }
1074
1.37k
    else if( internal_file->io_handle->format_version != file_header->format_version )
1075
186
    {
1076
#if defined( HAVE_VERBOSE_OUTPUT )
1077
      if( libcnotify_verbose != 0 )
1078
      {
1079
        libcnotify_printf(
1080
         "%s: mismatch in format version: 0x%" PRIx32 " and backup: 0x%" PRIx32 "\n",
1081
         function,
1082
         internal_file->io_handle->format_version,
1083
         file_header->format_version );
1084
      }
1085
#endif
1086
186
    }
1087
1.38k
    if( internal_file->io_handle->format_revision == 0 )
1088
24
    {
1089
24
      internal_file->io_handle->format_revision = file_header->format_revision;
1090
24
    }
1091
1.35k
    else if( internal_file->io_handle->format_revision != file_header->format_revision )
1092
926
    {
1093
#if defined( HAVE_VERBOSE_OUTPUT )
1094
      if( libcnotify_verbose != 0 )
1095
      {
1096
        libcnotify_printf(
1097
         "%s: mismatch in format revision: 0x%" PRIx32 " and backup: 0x%" PRIx32 "\n",
1098
         function,
1099
         internal_file->io_handle->format_revision,
1100
         file_header->format_revision );
1101
      }
1102
#endif
1103
926
    }
1104
1.38k
    if( internal_file->io_handle->page_size == 0 )
1105
0
    {
1106
0
      internal_file->io_handle->page_size = file_header->page_size;
1107
0
    }
1108
1.38k
    else if( internal_file->io_handle->page_size != file_header->page_size )
1109
110
    {
1110
#if defined( HAVE_VERBOSE_OUTPUT )
1111
      if( libcnotify_verbose != 0 )
1112
      {
1113
        libcnotify_printf(
1114
         "%s: mismatch in page size: 0x%04" PRIx32 " and backup: 0x%04" PRIx32 "\n",
1115
         function,
1116
         internal_file->io_handle->page_size,
1117
         file_header->page_size );
1118
      }
1119
#endif
1120
      /* The offset of the backup (database) file header
1121
       * is a good indication of the actual page size
1122
       */
1123
110
      internal_file->io_handle->page_size = (uint32_t) file_offset;
1124
110
    }
1125
1.38k
    if( libesedb_file_header_free(
1126
1.38k
         &file_header,
1127
1.38k
         error ) != 1 )
1128
0
    {
1129
0
      libcerror_error_set(
1130
0
       error,
1131
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1132
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1133
0
       "%s: unable to free backup file header.",
1134
0
       function );
1135
1136
0
      goto on_error;
1137
0
    }
1138
1.38k
  }
1139
1.42k
  if( internal_file->io_handle->format_version != 0x620 )
1140
149
  {
1141
149
    libcerror_error_set(
1142
149
     error,
1143
149
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1144
149
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1145
149
     "%s: unsupported format version: 0x%04" PRIx32 ".",
1146
149
     function,
1147
149
     internal_file->io_handle->format_version );
1148
1149
149
    goto on_error;
1150
149
  }
1151
1.27k
  if( internal_file->io_handle->page_size == 0 )
1152
4
  {
1153
4
    libcerror_error_set(
1154
4
     error,
1155
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1156
4
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1157
4
     "%s: invalid page size.",
1158
4
     function );
1159
1160
4
    goto on_error;
1161
4
  }
1162
1.26k
  if( internal_file->io_handle->format_version == 0x620 )
1163
1.26k
  {
1164
1.26k
    if( internal_file->io_handle->format_revision < 0x11 )
1165
59
    {
1166
59
      if( ( internal_file->io_handle->page_size != 0x1000 )
1167
59
       && ( internal_file->io_handle->page_size != 0x2000 ) )
1168
27
      {
1169
27
        libcerror_error_set(
1170
27
         error,
1171
27
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1172
27
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1173
27
         "%s: unsupported page size: %" PRIu32 " (0x%04" PRIx32 ") for format version: 0x%" PRIx32 " revision: 0x%" PRIx32 ".",
1174
27
         function,
1175
27
         internal_file->io_handle->page_size,
1176
27
         internal_file->io_handle->page_size,
1177
27
         internal_file->io_handle->format_version,
1178
27
         internal_file->io_handle->format_revision );
1179
1180
27
        goto on_error;
1181
27
      }
1182
59
    }
1183
1.20k
    else
1184
1.20k
    {
1185
1.20k
      if( ( internal_file->io_handle->page_size != 0x0800 )
1186
1.20k
       && ( internal_file->io_handle->page_size != 0x1000 )
1187
1.20k
       && ( internal_file->io_handle->page_size != 0x2000 )
1188
1.20k
       && ( internal_file->io_handle->page_size != 0x4000 )
1189
1.20k
       && ( internal_file->io_handle->page_size != 0x8000 ) )
1190
64
      {
1191
64
        libcerror_error_set(
1192
64
         error,
1193
64
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1194
64
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1195
64
         "%s: unsupported page size: %" PRIu32 " (0x%04" PRIx32 ") for format version: 0x%" PRIx32 " revision: 0x%" PRIx32 ".",
1196
64
         function,
1197
64
         internal_file->io_handle->page_size,
1198
64
         internal_file->io_handle->page_size,
1199
64
         internal_file->io_handle->format_version,
1200
64
         internal_file->io_handle->format_revision );
1201
1202
64
        goto on_error;
1203
64
      }
1204
1.20k
    }
1205
1.26k
  }
1206
1.17k
  if( libesedb_io_handle_set_pages_data_range(
1207
1.17k
       internal_file->io_handle,
1208
1.17k
       file_size,
1209
1.17k
       error ) != 1 )
1210
0
  {
1211
0
                libcerror_error_set(
1212
0
                 error,
1213
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1214
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1215
0
                 "%s: unable to set pages data range in IO handle.",
1216
0
                 function );
1217
1218
0
    goto on_error;
1219
0
  }
1220
/* TODO add clone function ? */
1221
1.17k
  if( libfdata_vector_initialize(
1222
1.17k
       &( internal_file->pages_vector ),
1223
1.17k
       (size64_t) internal_file->io_handle->page_size,
1224
1.17k
       (intptr_t *) internal_file->io_handle,
1225
1.17k
       NULL,
1226
1.17k
       NULL,
1227
1.17k
       (int (*)(intptr_t *, intptr_t *, libfdata_vector_t *, libfdata_cache_t *, int, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libesedb_io_handle_read_page,
1228
1.17k
       NULL,
1229
1.17k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1230
1.17k
       error ) != 1 )
1231
0
  {
1232
0
    libcerror_error_set(
1233
0
     error,
1234
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1235
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1236
0
     "%s: unable to create pages vector.",
1237
0
     function );
1238
1239
0
    goto on_error;
1240
0
  }
1241
1.17k
  if( libfdata_vector_append_segment(
1242
1.17k
       internal_file->pages_vector,
1243
1.17k
       &segment_index,
1244
1.17k
       0,
1245
1.17k
       internal_file->io_handle->pages_data_offset,
1246
1.17k
       internal_file->io_handle->pages_data_size,
1247
1.17k
       0,
1248
1.17k
       error ) != 1 )
1249
29
  {
1250
29
    libcerror_error_set(
1251
29
     error,
1252
29
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1253
29
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1254
29
     "%s: unable to append segment to pages vector.",
1255
29
     function );
1256
1257
29
    goto on_error;
1258
29
  }
1259
1.14k
  if( libfcache_cache_initialize(
1260
1.14k
       &( internal_file->pages_cache ),
1261
1.14k
       LIBESEDB_MAXIMUM_CACHE_ENTRIES_PAGES,
1262
1.14k
       error ) != 1 )
1263
0
  {
1264
0
    libcerror_error_set(
1265
0
     error,
1266
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1267
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1268
0
     "%s: unable to create pages cache.",
1269
0
     function );
1270
1271
0
    goto on_error;
1272
0
  }
1273
1.14k
  if( internal_file->io_handle->file_type == LIBESEDB_FILE_TYPE_DATABASE )
1274
1.10k
  {
1275
#if defined( HAVE_DEBUG_OUTPUT )
1276
    if( libcnotify_verbose != 0 )
1277
    {
1278
      libcnotify_printf(
1279
       "Reading the database:\n" );
1280
    }
1281
#endif
1282
1.10k
    if( libesedb_database_initialize(
1283
1.10k
         &( internal_file->database ),
1284
1.10k
         internal_file->io_handle,
1285
1.10k
         internal_file->pages_vector,
1286
1.10k
         internal_file->pages_cache,
1287
1.10k
         error ) != 1 )
1288
0
    {
1289
0
      libcerror_error_set(
1290
0
       error,
1291
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1292
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1293
0
       "%s: unable to create database.",
1294
0
       function );
1295
1296
0
      goto on_error;
1297
0
    }
1298
1.10k
    if( libesedb_database_read_file_io_handle(
1299
1.10k
         internal_file->database,
1300
1.10k
         file_io_handle,
1301
1.10k
         error ) != 1 )
1302
571
    {
1303
571
      libcerror_error_set(
1304
571
       error,
1305
571
       LIBCERROR_ERROR_DOMAIN_IO,
1306
571
       LIBCERROR_IO_ERROR_READ_FAILED,
1307
571
       "%s: unable to read database.",
1308
571
       function );
1309
1310
571
      goto on_error;
1311
571
    }
1312
#if defined( HAVE_DEBUG_OUTPUT )
1313
    if( libcnotify_verbose != 0 )
1314
    {
1315
      libcnotify_printf(
1316
       "Reading the catalog:\n" );
1317
    }
1318
#endif
1319
534
    if( libesedb_catalog_initialize(
1320
534
         &( internal_file->catalog ),
1321
534
         internal_file->io_handle,
1322
534
         LIBESEDB_PAGE_NUMBER_CATALOG,
1323
534
         internal_file->pages_vector,
1324
534
         internal_file->pages_cache,
1325
534
         error ) != 1 )
1326
0
    {
1327
0
      libcerror_error_set(
1328
0
       error,
1329
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1330
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1331
0
       "%s: unable to create catalog.",
1332
0
       function );
1333
1334
0
      goto on_error;
1335
0
    }
1336
534
    if( libesedb_catalog_read_file_io_handle(
1337
534
         internal_file->catalog,
1338
534
         file_io_handle,
1339
534
         error ) != 1 )
1340
270
    {
1341
270
      libcerror_error_set(
1342
270
       error,
1343
270
       LIBCERROR_ERROR_DOMAIN_IO,
1344
270
       LIBCERROR_IO_ERROR_READ_FAILED,
1345
270
       "%s: unable to read catalog.",
1346
270
       function );
1347
1348
270
      goto on_error;
1349
270
    }
1350
#if defined( HAVE_DEBUG_OUTPUT )
1351
    if( libcnotify_verbose != 0 )
1352
    {
1353
      libcnotify_printf(
1354
       "Reading the backup catalog:\n" );
1355
    }
1356
#endif
1357
264
    if( libesedb_catalog_initialize(
1358
264
         &( internal_file->backup_catalog ),
1359
264
         internal_file->io_handle,
1360
264
         LIBESEDB_PAGE_NUMBER_CATALOG_BACKUP,
1361
264
         internal_file->pages_vector,
1362
264
         internal_file->pages_cache,
1363
264
         error ) != 1 )
1364
0
    {
1365
0
      libcerror_error_set(
1366
0
       error,
1367
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1368
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1369
0
       "%s: unable to create backup catalog.",
1370
0
       function );
1371
1372
0
      goto on_error;
1373
0
    }
1374
264
    if( libesedb_catalog_read_file_io_handle(
1375
264
         internal_file->backup_catalog,
1376
264
         file_io_handle,
1377
264
         error ) != 1 )
1378
52
    {
1379
52
      libcerror_error_set(
1380
52
       error,
1381
52
       LIBCERROR_ERROR_DOMAIN_IO,
1382
52
       LIBCERROR_IO_ERROR_READ_FAILED,
1383
52
       "%s: unable to read backup catalog.",
1384
52
       function );
1385
1386
52
      goto on_error;
1387
52
    }
1388
/* TODO compare contents of catalogs ? */
1389
264
  }
1390
254
  internal_file->io_handle->abort = 0;
1391
1392
254
  return( 1 );
1393
1394
1.36k
on_error:
1395
1.36k
  if( internal_file->backup_catalog != NULL )
1396
52
  {
1397
52
    libesedb_catalog_free(
1398
52
     &( internal_file->backup_catalog ),
1399
52
     NULL );
1400
52
  }
1401
1.36k
  if( internal_file->catalog != NULL )
1402
322
  {
1403
322
    libesedb_catalog_free(
1404
322
     &( internal_file->catalog ),
1405
322
     NULL );
1406
322
  }
1407
1.36k
  if( internal_file->database != NULL )
1408
893
  {
1409
893
    libesedb_database_free(
1410
893
     &( internal_file->database ),
1411
893
     NULL );
1412
893
  }
1413
1.36k
  if( internal_file->pages_cache != NULL )
1414
893
  {
1415
893
    libfcache_cache_free(
1416
893
     &( internal_file->pages_cache ),
1417
893
     NULL );
1418
893
  }
1419
1.36k
  if( internal_file->pages_vector != NULL )
1420
922
  {
1421
922
    libfdata_vector_free(
1422
922
     &( internal_file->pages_vector ),
1423
922
     NULL );
1424
922
  }
1425
1.36k
  if( file_header != NULL )
1426
194
  {
1427
194
    libesedb_file_header_free(
1428
194
     &file_header,
1429
194
     NULL );
1430
194
  }
1431
1.36k
  internal_file->io_handle->abort = 0;
1432
1433
1.36k
  return( -1 );
1434
1.14k
}
1435
1436
/* Retrieves the file type
1437
 * Returns 1 if successful or -1 on error
1438
 */
1439
int libesedb_file_get_type(
1440
     libesedb_file_t *file,
1441
     uint32_t *type,
1442
     libcerror_error_t **error )
1443
0
{
1444
0
  libesedb_internal_file_t *internal_file = NULL;
1445
0
  static char *function                   = "libesedb_file_get_type";
1446
1447
0
  if( file == NULL )
1448
0
  {
1449
0
    libcerror_error_set(
1450
0
     error,
1451
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1452
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1453
0
     "%s: invalid file.",
1454
0
     function );
1455
1456
0
    return( -1 );
1457
0
  }
1458
0
  internal_file = (libesedb_internal_file_t *) file;
1459
1460
0
  if( internal_file->io_handle == NULL )
1461
0
  {
1462
0
    libcerror_error_set(
1463
0
     error,
1464
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1465
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1466
0
     "%s: invalid file - missing IO handle.",
1467
0
     function );
1468
1469
0
    return( -1 );
1470
0
  }
1471
0
  if( type == NULL )
1472
0
  {
1473
0
    libcerror_error_set(
1474
0
     error,
1475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1477
0
     "%s: invalid type.",
1478
0
     function );
1479
1480
0
    return( -1 );
1481
0
  }
1482
0
  *type = internal_file->io_handle->file_type;
1483
1484
0
  return( 1 );
1485
0
}
1486
1487
/* Retrieves the file (current) version
1488
 * Returns 1 if successful or -1 on error
1489
 */
1490
int libesedb_file_get_format_version(
1491
     libesedb_file_t *file,
1492
     uint32_t *format_version,
1493
     uint32_t *format_revision,
1494
     libcerror_error_t **error )
1495
0
{
1496
0
  libesedb_internal_file_t *internal_file = NULL;
1497
0
  static char *function                   = "libesedb_file_get_format_version";
1498
1499
0
  if( file == NULL )
1500
0
  {
1501
0
    libcerror_error_set(
1502
0
     error,
1503
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1504
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1505
0
     "%s: invalid file.",
1506
0
     function );
1507
1508
0
    return( -1 );
1509
0
  }
1510
0
  internal_file = (libesedb_internal_file_t *) file;
1511
1512
0
  if( internal_file->io_handle == NULL )
1513
0
  {
1514
0
    libcerror_error_set(
1515
0
     error,
1516
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1517
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1518
0
     "%s: invalid file - missing IO handle.",
1519
0
     function );
1520
1521
0
    return( -1 );
1522
0
  }
1523
0
  if( format_version == NULL )
1524
0
  {
1525
0
    libcerror_error_set(
1526
0
     error,
1527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1528
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1529
0
     "%s: invalid format version.",
1530
0
     function );
1531
1532
0
    return( -1 );
1533
0
  }
1534
0
  if( format_revision == NULL )
1535
0
  {
1536
0
    libcerror_error_set(
1537
0
     error,
1538
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1539
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1540
0
     "%s: invalid format revision.",
1541
0
     function );
1542
1543
0
    return( -1 );
1544
0
  }
1545
0
  *format_version  = internal_file->io_handle->format_version;
1546
0
  *format_revision = internal_file->io_handle->format_revision;
1547
1548
0
  return( 1 );
1549
0
}
1550
1551
/* Retrieves the file creation format version
1552
 * Returns 1 if successful or -1 on error
1553
 */
1554
int libesedb_file_get_creation_format_version(
1555
     libesedb_file_t *file,
1556
     uint32_t *format_version,
1557
     uint32_t *format_revision,
1558
     libcerror_error_t **error )
1559
0
{
1560
0
  libesedb_internal_file_t *internal_file = NULL;
1561
0
  static char *function                   = "libesedb_file_get_creation_format_version";
1562
1563
0
  if( file == NULL )
1564
0
  {
1565
0
    libcerror_error_set(
1566
0
     error,
1567
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1568
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1569
0
     "%s: invalid file.",
1570
0
     function );
1571
1572
0
    return( -1 );
1573
0
  }
1574
0
  internal_file = (libesedb_internal_file_t *) file;
1575
1576
0
  if( internal_file->io_handle == NULL )
1577
0
  {
1578
0
    libcerror_error_set(
1579
0
     error,
1580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1581
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1582
0
     "%s: invalid file - missing IO handle.",
1583
0
     function );
1584
1585
0
    return( -1 );
1586
0
  }
1587
0
  if( format_version == NULL )
1588
0
  {
1589
0
    libcerror_error_set(
1590
0
     error,
1591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1593
0
     "%s: invalid format version.",
1594
0
     function );
1595
1596
0
    return( -1 );
1597
0
  }
1598
0
  if( format_revision == NULL )
1599
0
  {
1600
0
    libcerror_error_set(
1601
0
     error,
1602
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1603
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1604
0
     "%s: invalid format revision.",
1605
0
     function );
1606
1607
0
    return( -1 );
1608
0
  }
1609
0
  *format_version  = internal_file->io_handle->creation_format_version;
1610
0
  *format_revision = internal_file->io_handle->creation_format_revision;
1611
1612
0
  return( 1 );
1613
0
}
1614
1615
/* Retrieves the file page size
1616
 * Returns 1 if successful or -1 on error
1617
 */
1618
int libesedb_file_get_page_size(
1619
     libesedb_file_t *file,
1620
     uint32_t *page_size,
1621
     libcerror_error_t **error )
1622
0
{
1623
0
  libesedb_internal_file_t *internal_file = NULL;
1624
0
  static char *function                   = "libesedb_file_get_page_size";
1625
1626
0
  if( file == NULL )
1627
0
  {
1628
0
    libcerror_error_set(
1629
0
     error,
1630
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1631
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1632
0
     "%s: invalid file.",
1633
0
     function );
1634
1635
0
    return( -1 );
1636
0
  }
1637
0
  internal_file = (libesedb_internal_file_t *) file;
1638
1639
0
  if( internal_file->io_handle == NULL )
1640
0
  {
1641
0
    libcerror_error_set(
1642
0
     error,
1643
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1644
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1645
0
     "%s: invalid file - missing IO handle.",
1646
0
     function );
1647
1648
0
    return( -1 );
1649
0
  }
1650
0
  if( page_size == NULL )
1651
0
  {
1652
0
    libcerror_error_set(
1653
0
     error,
1654
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1655
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1656
0
     "%s: invalid page size.",
1657
0
     function );
1658
1659
0
    return( -1 );
1660
0
  }
1661
0
  *page_size = internal_file->io_handle->page_size;
1662
1663
0
  return( 1 );
1664
0
}
1665
1666
/* Retrieves the number of tables
1667
 * Returns 1 if successful or -1 on error
1668
 */
1669
int libesedb_file_get_number_of_tables(
1670
     libesedb_file_t *file,
1671
     int *number_of_tables,
1672
     libcerror_error_t **error )
1673
254
{
1674
254
  libesedb_internal_file_t *internal_file = NULL;
1675
254
  static char *function                   = "libesedb_file_get_number_of_tables";
1676
1677
254
  if( file == NULL )
1678
0
  {
1679
0
    libcerror_error_set(
1680
0
     error,
1681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1682
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1683
0
     "%s: invalid file.",
1684
0
     function );
1685
1686
0
    return( -1 );
1687
0
  }
1688
254
  internal_file = (libesedb_internal_file_t *) file;
1689
1690
254
  if( internal_file->catalog == NULL )
1691
42
  {
1692
42
    if( number_of_tables == NULL )
1693
0
    {
1694
0
      libcerror_error_set(
1695
0
       error,
1696
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1697
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1698
0
       "%s: invalid number of tables.",
1699
0
       function );
1700
1701
0
      return( -1 );
1702
0
    }
1703
42
    *number_of_tables = 0;
1704
42
  }
1705
212
  else
1706
212
  {
1707
212
    if( libesedb_catalog_get_number_of_table_definitions(
1708
212
         internal_file->catalog,
1709
212
         number_of_tables,
1710
212
         error ) != 1 )
1711
0
    {
1712
0
      libcerror_error_set(
1713
0
       error,
1714
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1715
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1716
0
       "%s: unable to retrieve number of tables.",
1717
0
       function );
1718
1719
0
      return( -1 );
1720
0
    }
1721
212
  }
1722
254
  return( 1 );
1723
254
}
1724
1725
/* Retrieves a specific table
1726
 * Returns 1 if successful or -1 on error
1727
 */
1728
int libesedb_file_get_table(
1729
     libesedb_file_t *file,
1730
     int table_entry,
1731
     libesedb_table_t **table,
1732
     libcerror_error_t **error )
1733
179
{
1734
179
  libesedb_internal_file_t *internal_file                = NULL;
1735
179
  libesedb_table_definition_t *table_definition          = NULL;
1736
179
  libesedb_table_definition_t *template_table_definition = NULL;
1737
179
  static char *function                                  = "libesedb_file_get_table";
1738
1739
179
  if( file == NULL )
1740
0
  {
1741
0
    libcerror_error_set(
1742
0
     error,
1743
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1744
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1745
0
     "%s: invalid file.",
1746
0
     function );
1747
1748
0
    return( -1 );
1749
0
  }
1750
179
  internal_file = (libesedb_internal_file_t *) file;
1751
1752
179
  if( table == NULL )
1753
0
  {
1754
0
    libcerror_error_set(
1755
0
     error,
1756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1757
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1758
0
     "%s: invalid table.",
1759
0
     function );
1760
1761
0
    return( -1 );
1762
0
  }
1763
179
  if( *table != NULL )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1769
0
     "%s: invalid table value already set.",
1770
0
     function );
1771
1772
0
    return( -1 );
1773
0
  }
1774
179
  if( libesedb_catalog_get_table_definition_by_index(
1775
179
       internal_file->catalog,
1776
179
       table_entry,
1777
179
       &table_definition,
1778
179
       error ) != 1 )
1779
0
  {
1780
0
    libcerror_error_set(
1781
0
     error,
1782
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1783
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1784
0
     "%s: unable to retrieve table definition: %d.",
1785
0
     function,
1786
0
     table_entry );
1787
1788
0
    return( -1 );
1789
0
  }
1790
179
  if( table_definition == NULL )
1791
0
  {
1792
0
    libcerror_error_set(
1793
0
     error,
1794
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1795
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1796
0
     "%s: missing table definition.",
1797
0
     function );
1798
1799
0
    return( -1 );
1800
0
  }
1801
179
  if( table_definition->table_catalog_definition == NULL )
1802
0
  {
1803
0
    libcerror_error_set(
1804
0
     error,
1805
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1806
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1807
0
     "%s: invalid table definition - missing table catalog definition.",
1808
0
     function );
1809
1810
0
    return( -1 );
1811
0
  }
1812
179
  if( table_definition->table_catalog_definition->template_name != NULL )
1813
134
  {
1814
134
    if( libesedb_catalog_get_table_definition_by_utf8_name(
1815
134
         internal_file->catalog,
1816
134
         table_definition->table_catalog_definition->template_name,
1817
134
         table_definition->table_catalog_definition->template_name_size,
1818
134
         &template_table_definition,
1819
134
         error ) != 1 )
1820
133
    {
1821
133
      libcerror_error_set(
1822
133
       error,
1823
133
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824
133
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1825
133
       "%s: unable to retrieve template table definition.",
1826
133
       function );
1827
1828
133
      return( -1 );
1829
133
    }
1830
134
  }
1831
46
  if( libesedb_table_initialize(
1832
46
       table,
1833
46
       internal_file->file_io_handle,
1834
46
       internal_file->io_handle,
1835
46
       table_definition,
1836
46
       template_table_definition,
1837
46
       error ) != 1 )
1838
37
  {
1839
37
    libcerror_error_set(
1840
37
     error,
1841
37
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1842
37
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1843
37
     "%s: unable to create table.",
1844
37
     function );
1845
1846
37
    return( -1 );
1847
37
  }
1848
9
  return( 1 );
1849
46
}
1850
1851
/* Retrieves the table for the UTF-8 encoded name
1852
 * Returns 1 if successful, 0 if no table could be found or -1 on error
1853
 */
1854
int libesedb_file_get_table_by_utf8_name(
1855
     libesedb_file_t *file,
1856
     const uint8_t *utf8_string,
1857
     size_t utf8_string_length,
1858
     libesedb_table_t **table,
1859
     libcerror_error_t **error )
1860
0
{
1861
0
  libesedb_internal_file_t *internal_file                = NULL;
1862
0
  libesedb_table_definition_t *table_definition          = NULL;
1863
0
  libesedb_table_definition_t *template_table_definition = NULL;
1864
0
  static char *function                                  = "libesedb_file_get_table_by_utf8_name";
1865
0
  int result                                             = 0;
1866
1867
0
  if( file == NULL )
1868
0
  {
1869
0
    libcerror_error_set(
1870
0
     error,
1871
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1872
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1873
0
     "%s: invalid file.",
1874
0
     function );
1875
1876
0
    return( -1 );
1877
0
  }
1878
0
  internal_file = (libesedb_internal_file_t *) file;
1879
1880
0
  if( table == NULL )
1881
0
  {
1882
0
    libcerror_error_set(
1883
0
     error,
1884
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1885
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1886
0
     "%s: invalid table.",
1887
0
     function );
1888
1889
0
    return( -1 );
1890
0
  }
1891
0
  if( *table != NULL )
1892
0
  {
1893
0
    libcerror_error_set(
1894
0
     error,
1895
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1896
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1897
0
     "%s: invalid table value already set.",
1898
0
     function );
1899
1900
0
    return( -1 );
1901
0
  }
1902
0
  result = libesedb_catalog_get_table_definition_by_utf8_name(
1903
0
            internal_file->catalog,
1904
0
            utf8_string,
1905
0
            utf8_string_length,
1906
0
            &table_definition,
1907
0
            error );
1908
1909
0
  if( result == -1 )
1910
0
  {
1911
0
    libcerror_error_set(
1912
0
     error,
1913
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1914
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1915
0
     "%s: unable to retrieve table definition.",
1916
0
     function );
1917
1918
0
    return( -1 );
1919
0
  }
1920
0
  else if( result != 0 )
1921
0
  {
1922
0
    if( table_definition == NULL )
1923
0
    {
1924
0
      libcerror_error_set(
1925
0
       error,
1926
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1927
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1928
0
       "%s: missing table definition.",
1929
0
       function );
1930
1931
0
      return( -1 );
1932
0
    }
1933
0
    if( table_definition->table_catalog_definition == NULL )
1934
0
    {
1935
0
      libcerror_error_set(
1936
0
       error,
1937
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1938
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1939
0
       "%s: invalid table definition - missing table catalog definition.",
1940
0
       function );
1941
1942
0
      return( -1 );
1943
0
    }
1944
0
    if( table_definition->table_catalog_definition->template_name != NULL )
1945
0
    {
1946
0
      if( libesedb_catalog_get_table_definition_by_name(
1947
0
           internal_file->catalog,
1948
0
           table_definition->table_catalog_definition->template_name,
1949
0
           table_definition->table_catalog_definition->template_name_size,
1950
0
           &template_table_definition,
1951
0
           error ) != 1 )
1952
0
      {
1953
0
        libcerror_error_set(
1954
0
         error,
1955
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1956
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1957
0
         "%s: unable to retrieve template table definition.",
1958
0
         function );
1959
1960
0
        return( -1 );
1961
0
      }
1962
0
    }
1963
0
    if( libesedb_table_initialize(
1964
0
         table,
1965
0
         internal_file->file_io_handle,
1966
0
         internal_file->io_handle,
1967
0
         table_definition,
1968
0
         template_table_definition,
1969
0
         error ) != 1 )
1970
0
    {
1971
0
      libcerror_error_set(
1972
0
       error,
1973
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1974
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1975
0
       "%s: unable to create table.",
1976
0
       function );
1977
1978
0
      return( -1 );
1979
0
    }
1980
0
  }
1981
0
  return( result );
1982
0
}
1983
1984
/* Retrieves the table for the UTF-16 encoded name
1985
 * Returns 1 if successful, 0 if no table could be found or -1 on error
1986
 */
1987
int libesedb_file_get_table_by_utf16_name(
1988
     libesedb_file_t *file,
1989
     const uint16_t *utf16_string,
1990
     size_t utf16_string_length,
1991
     libesedb_table_t **table,
1992
     libcerror_error_t **error )
1993
0
{
1994
0
  libesedb_internal_file_t *internal_file                = NULL;
1995
0
  libesedb_table_definition_t *table_definition          = NULL;
1996
0
  libesedb_table_definition_t *template_table_definition = NULL;
1997
0
  static char *function                                  = "libesedb_file_get_table_by_utf16_name";
1998
0
  int result                                             = 0;
1999
2000
0
  if( file == NULL )
2001
0
  {
2002
0
    libcerror_error_set(
2003
0
     error,
2004
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2005
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2006
0
     "%s: invalid file.",
2007
0
     function );
2008
2009
0
    return( -1 );
2010
0
  }
2011
0
  internal_file = (libesedb_internal_file_t *) file;
2012
2013
0
  if( table == NULL )
2014
0
  {
2015
0
    libcerror_error_set(
2016
0
     error,
2017
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2018
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2019
0
     "%s: invalid table.",
2020
0
     function );
2021
2022
0
    return( -1 );
2023
0
  }
2024
0
  if( *table != NULL )
2025
0
  {
2026
0
    libcerror_error_set(
2027
0
     error,
2028
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2029
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2030
0
     "%s: invalid table value already set.",
2031
0
     function );
2032
2033
0
    return( -1 );
2034
0
  }
2035
0
  result = libesedb_catalog_get_table_definition_by_utf16_name(
2036
0
            internal_file->catalog,
2037
0
            utf16_string,
2038
0
            utf16_string_length,
2039
0
            &table_definition,
2040
0
            error );
2041
2042
0
  if( result == -1 )
2043
0
  {
2044
0
    libcerror_error_set(
2045
0
     error,
2046
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2047
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2048
0
     "%s: unable to retrieve table definition.",
2049
0
     function );
2050
2051
0
    return( -1 );
2052
0
  }
2053
0
  else if( result != 0 )
2054
0
  {
2055
0
    if( table_definition == NULL )
2056
0
    {
2057
0
      libcerror_error_set(
2058
0
       error,
2059
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2060
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2061
0
       "%s: missing table definition.",
2062
0
       function );
2063
2064
0
      return( -1 );
2065
0
    }
2066
0
    if( table_definition->table_catalog_definition == NULL )
2067
0
    {
2068
0
      libcerror_error_set(
2069
0
       error,
2070
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2071
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2072
0
       "%s: invalid table definition - missing table catalog definition.",
2073
0
       function );
2074
2075
0
      return( -1 );
2076
0
    }
2077
0
    if( table_definition->table_catalog_definition->template_name != NULL )
2078
0
    {
2079
0
      if( libesedb_catalog_get_table_definition_by_name(
2080
0
           internal_file->catalog,
2081
0
           table_definition->table_catalog_definition->template_name,
2082
0
           table_definition->table_catalog_definition->template_name_size,
2083
0
           &template_table_definition,
2084
0
           error ) != 1 )
2085
0
      {
2086
0
        libcerror_error_set(
2087
0
         error,
2088
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2089
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2090
0
         "%s: unable to retrieve template table definition.",
2091
0
         function );
2092
2093
0
        return( -1 );
2094
0
      }
2095
0
    }
2096
0
    if( libesedb_table_initialize(
2097
0
         table,
2098
0
         internal_file->file_io_handle,
2099
0
         internal_file->io_handle,
2100
0
         table_definition,
2101
0
         template_table_definition,
2102
0
         error ) != 1 )
2103
0
    {
2104
0
      libcerror_error_set(
2105
0
       error,
2106
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2107
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2108
0
       "%s: unable to create table.",
2109
0
       function );
2110
2111
0
      return( -1 );
2112
0
    }
2113
0
  }
2114
0
  return( result );
2115
0
}
2116