Coverage Report

Created: 2025-06-13 07:21

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