Coverage Report

Created: 2025-06-22 07:35

/src/libcreg/libcreg/libcreg_key.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Key functions
3
 *
4
 * Copyright (C) 2013-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 <types.h>
25
26
#include "libcreg_definitions.h"
27
#include "libcreg_io_handle.h"
28
#include "libcreg_key.h"
29
#include "libcreg_key_descriptor.h"
30
#include "libcreg_key_item.h"
31
#include "libcreg_key_name_entry.h"
32
#include "libcreg_key_navigation.h"
33
#include "libcreg_key_tree.h"
34
#include "libcreg_libbfio.h"
35
#include "libcreg_libcerror.h"
36
#include "libcreg_libcthreads.h"
37
#include "libcreg_libuna.h"
38
#include "libcreg_types.h"
39
#include "libcreg_value.h"
40
#include "libcreg_value_entry.h"
41
#include "libcreg_value_type.h"
42
43
/* Creates a key
44
 * Make sure the value key is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libcreg_key_initialize(
48
     libcreg_key_t **key,
49
     libcreg_io_handle_t *io_handle,
50
     libbfio_handle_t *file_io_handle,
51
     libcreg_key_navigation_t *key_navigation,
52
     uint32_t key_offset,
53
     libcerror_error_t **error )
54
2.50k
{
55
2.50k
  libcreg_internal_key_t *internal_key = NULL;
56
2.50k
  static char *function                = "libcreg_key_initialize";
57
58
2.50k
  if( key == NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
63
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
64
0
     "%s: invalid key.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
2.50k
  if( *key != NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
74
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
75
0
     "%s: invalid key value already set.",
76
0
     function );
77
78
0
    return( -1 );
79
0
  }
80
2.50k
  internal_key = memory_allocate_structure(
81
2.50k
                  libcreg_internal_key_t );
82
83
2.50k
  if( internal_key == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
88
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
89
0
     "%s: unable to create internal key.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
2.50k
  if( memory_set(
95
2.50k
       internal_key,
96
2.50k
       0,
97
2.50k
       sizeof( libcreg_internal_key_t ) ) == NULL )
98
0
  {
99
0
    libcerror_error_set(
100
0
     error,
101
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
102
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
103
0
     "%s: unable to clear internal key.",
104
0
     function );
105
106
0
    memory_free(
107
0
     internal_key );
108
109
0
    return( -1 );
110
0
  }
111
2.50k
  if( libcreg_key_item_initialize(
112
2.50k
       &( internal_key->key_item ),
113
2.50k
       error ) != 1 )
114
0
  {
115
0
    libcerror_error_set(
116
0
     error,
117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
118
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
119
0
     "%s: unable to create key item.",
120
0
     function );
121
122
0
    goto on_error;
123
0
  }
124
2.50k
  if( libcreg_key_item_read(
125
2.50k
       internal_key->key_item,
126
2.50k
       file_io_handle,
127
2.50k
       key_navigation,
128
2.50k
       (off64_t) key_offset,
129
2.50k
       error ) != 1 )
130
1.71k
  {
131
1.71k
    libcerror_error_set(
132
1.71k
     error,
133
1.71k
     LIBCERROR_ERROR_DOMAIN_IO,
134
1.71k
     LIBCERROR_IO_ERROR_READ_FAILED,
135
1.71k
     "%s: unable to read key item at offset: %" PRIi64 " (0x%08" PRIx64 ").",
136
1.71k
     function,
137
1.71k
     key_offset,
138
1.71k
     key_offset );
139
140
1.71k
    goto on_error;
141
1.71k
  }
142
791
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
143
791
  if( libcthreads_read_write_lock_initialize(
144
791
       &( internal_key->read_write_lock ),
145
791
       error ) != 1 )
146
0
  {
147
0
    libcerror_error_set(
148
0
     error,
149
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
150
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
151
0
     "%s: unable to initialize read/write lock.",
152
0
     function );
153
154
0
    goto on_error;
155
0
  }
156
791
#endif
157
791
  internal_key->file_io_handle = file_io_handle;
158
791
  internal_key->io_handle      = io_handle;
159
791
  internal_key->key_navigation = key_navigation;
160
791
  internal_key->key_offset     = key_offset;
161
162
791
  *key = (libcreg_key_t *) internal_key;
163
164
791
  return( 1 );
165
166
1.71k
on_error:
167
1.71k
  if( internal_key != NULL )
168
1.71k
  {
169
1.71k
    if( internal_key->key_item != NULL )
170
1.71k
    {
171
1.71k
      libcreg_key_item_free(
172
1.71k
       &( internal_key->key_item ),
173
1.71k
       NULL );
174
1.71k
    }
175
1.71k
    memory_free(
176
1.71k
     internal_key );
177
1.71k
  }
178
1.71k
  return( -1 );
179
791
}
180
181
/* Frees a key
182
 * Returns 1 if successful or -1 on error
183
 */
184
int libcreg_key_free(
185
     libcreg_key_t **key,
186
     libcerror_error_t **error )
187
791
{
188
791
  libcreg_internal_key_t *internal_key = NULL;
189
791
  static char *function                = "libcreg_key_free";
190
791
  int result                           = 1;
191
192
791
  if( key == NULL )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
197
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
198
0
     "%s: invalid key.",
199
0
     function );
200
201
0
    return( -1 );
202
0
  }
203
791
  if( *key != NULL )
204
791
  {
205
791
    internal_key = (libcreg_internal_key_t *) *key;
206
791
    *key         = NULL;
207
208
791
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
209
791
    if( libcthreads_read_write_lock_free(
210
791
         &( internal_key->read_write_lock ),
211
791
         error ) != 1 )
212
0
    {
213
0
      libcerror_error_set(
214
0
       error,
215
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
216
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
217
0
       "%s: unable to free read/write lock.",
218
0
       function );
219
220
0
      result = -1;
221
0
    }
222
791
#endif
223
    /* The io_handle and file_io_handle references are freed elsewhere
224
     */
225
791
    if( libcreg_key_item_free(
226
791
         &( internal_key->key_item ),
227
791
         error ) != 1 )
228
0
    {
229
0
      libcerror_error_set(
230
0
       error,
231
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
232
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
233
0
       "%s: unable to free key item.",
234
0
       function );
235
236
0
      result = -1;
237
0
    }
238
791
    memory_free(
239
791
     internal_key );
240
791
  }
241
791
  return( result );
242
791
}
243
244
/* Determine if the key corrupted
245
 * Returns 1 if corrupted, 0 if not or -1 on error
246
 */
247
int libcreg_key_is_corrupted(
248
     libcreg_key_t *key,
249
     libcerror_error_t **error )
250
0
{
251
0
  libcreg_internal_key_t *internal_key = NULL;
252
0
  static char *function                = "libcreg_key_is_corrupted";
253
0
  int result                           = 0;
254
255
0
  if( key == NULL )
256
0
  {
257
0
    libcerror_error_set(
258
0
     error,
259
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
260
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
261
0
     "%s: invalid key.",
262
0
     function );
263
264
0
    return( -1 );
265
0
  }
266
0
  internal_key = (libcreg_internal_key_t *) key;
267
268
0
  if( internal_key->key_item == NULL )
269
0
  {
270
0
    libcerror_error_set(
271
0
     error,
272
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
273
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
274
0
     "%s: invalid key - key item.",
275
0
     function );
276
277
0
    return( -1 );
278
0
  }
279
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
280
0
  if( libcthreads_read_write_lock_grab_for_write(
281
0
       internal_key->read_write_lock,
282
0
       error ) != 1 )
283
0
  {
284
0
    libcerror_error_set(
285
0
     error,
286
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
287
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
288
0
     "%s: unable to grab read/write lock for writing.",
289
0
     function );
290
291
0
    return( -1 );
292
0
  }
293
0
#endif
294
0
  result = libcreg_key_item_is_corrupted(
295
0
            internal_key->key_item,
296
0
            error );
297
298
0
  if( result == -1 )
299
0
  {
300
0
    libcerror_error_set(
301
0
     error,
302
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
303
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
304
0
     "%s: unable to determine if key item is corruped.",
305
0
     function );
306
307
0
    result = -1;
308
0
  }
309
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
310
0
  if( libcthreads_read_write_lock_release_for_write(
311
0
       internal_key->read_write_lock,
312
0
       error ) != 1 )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
317
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
318
0
     "%s: unable to release read/write lock for writing.",
319
0
     function );
320
321
0
    return( -1 );
322
0
  }
323
0
#endif
324
0
  return( result );
325
0
}
326
327
/* Retrieves the offset
328
 * Returns 1 if successful or -1 on error
329
 */
330
int libcreg_key_get_offset(
331
     libcreg_key_t *key,
332
     off64_t *offset,
333
     libcerror_error_t **error )
334
0
{
335
0
  libcreg_internal_key_t *internal_key = NULL;
336
0
  static char *function                = "libcreg_key_get_offset";
337
338
0
  if( key == NULL )
339
0
  {
340
0
    libcerror_error_set(
341
0
     error,
342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
343
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
344
0
     "%s: invalid key.",
345
0
     function );
346
347
0
    return( -1 );
348
0
  }
349
0
  internal_key = (libcreg_internal_key_t *) key;
350
351
0
  if( internal_key->io_handle == NULL )
352
0
  {
353
0
    libcerror_error_set(
354
0
     error,
355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
356
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
357
0
     "%s: invalid key - missing IO handle.",
358
0
     function );
359
360
0
    return( -1 );
361
0
  }
362
0
  if( offset == NULL )
363
0
  {
364
0
    libcerror_error_set(
365
0
     error,
366
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
367
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
368
0
     "%s: invalid offset.",
369
0
     function );
370
371
0
    return( -1 );
372
0
  }
373
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
374
0
  if( libcthreads_read_write_lock_grab_for_write(
375
0
       internal_key->read_write_lock,
376
0
       error ) != 1 )
377
0
  {
378
0
    libcerror_error_set(
379
0
     error,
380
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
381
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
382
0
     "%s: unable to grab read/write lock for writing.",
383
0
     function );
384
385
0
    return( -1 );
386
0
  }
387
0
#endif
388
  /* The offset is relative from the start of the data blocks list
389
   * and points to the start of the corresponding key name entry
390
   */
391
0
  *offset = internal_key->key_offset + internal_key->io_handle->data_blocks_list_offset + 4;
392
393
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
394
0
  if( libcthreads_read_write_lock_release_for_write(
395
0
       internal_key->read_write_lock,
396
0
       error ) != 1 )
397
0
  {
398
0
    libcerror_error_set(
399
0
     error,
400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
401
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
402
0
     "%s: unable to release read/write lock for writing.",
403
0
     function );
404
405
0
    return( -1 );
406
0
  }
407
0
#endif
408
0
  return( 1 );
409
0
}
410
411
/* Retrieves the key name size
412
 * Returns 1 if successful or -1 on error
413
 */
414
int libcreg_key_get_name_size(
415
     libcreg_key_t *key,
416
     size_t *string_size,
417
     libcerror_error_t **error )
418
0
{
419
0
  libcreg_internal_key_t *internal_key = NULL;
420
0
  static char *function                = "libcreg_key_get_name_size";
421
0
  int result                           = 1;
422
423
0
  if( key == NULL )
424
0
  {
425
0
    libcerror_error_set(
426
0
     error,
427
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
428
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
429
0
     "%s: invalid key.",
430
0
     function );
431
432
0
    return( -1 );
433
0
  }
434
0
  internal_key = (libcreg_internal_key_t *) key;
435
436
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
437
0
  if( libcthreads_read_write_lock_grab_for_write(
438
0
       internal_key->read_write_lock,
439
0
       error ) != 1 )
440
0
  {
441
0
    libcerror_error_set(
442
0
     error,
443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
445
0
     "%s: unable to grab read/write lock for writing.",
446
0
     function );
447
448
0
    return( -1 );
449
0
  }
450
0
#endif
451
0
  if( libcreg_key_item_get_name_size(
452
0
       internal_key->key_item,
453
0
       string_size,
454
0
       error ) != 1 )
455
0
  {
456
0
    libcerror_error_set(
457
0
     error,
458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
460
0
     "%s: unable to retrieve name size.",
461
0
     function );
462
463
0
    result = -1;
464
0
  }
465
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
466
0
  if( libcthreads_read_write_lock_release_for_write(
467
0
       internal_key->read_write_lock,
468
0
       error ) != 1 )
469
0
  {
470
0
    libcerror_error_set(
471
0
     error,
472
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
473
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
474
0
     "%s: unable to release read/write lock for writing.",
475
0
     function );
476
477
0
    return( -1 );
478
0
  }
479
0
#endif
480
0
  return( result );
481
0
}
482
483
/* Retrieves the key name
484
 * Returns 1 if successful or -1 on error
485
 */
486
int libcreg_key_get_name(
487
     libcreg_key_t *key,
488
     uint8_t *string,
489
     size_t string_size,
490
     libcerror_error_t **error )
491
0
{
492
0
  libcreg_internal_key_t *internal_key = NULL;
493
0
  static char *function                = "libcreg_key_get_name";
494
0
  int result                           = 1;
495
496
0
  if( key == NULL )
497
0
  {
498
0
    libcerror_error_set(
499
0
     error,
500
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
501
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
502
0
     "%s: invalid key.",
503
0
     function );
504
505
0
    return( -1 );
506
0
  }
507
0
  internal_key = (libcreg_internal_key_t *) key;
508
509
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
510
0
  if( libcthreads_read_write_lock_grab_for_write(
511
0
       internal_key->read_write_lock,
512
0
       error ) != 1 )
513
0
  {
514
0
    libcerror_error_set(
515
0
     error,
516
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
517
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
518
0
     "%s: unable to grab read/write lock for writing.",
519
0
     function );
520
521
0
    return( -1 );
522
0
  }
523
0
#endif
524
0
  if( libcreg_key_item_get_name(
525
0
       internal_key->key_item,
526
0
       string,
527
0
       string_size,
528
0
       error ) != 1 )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
533
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
534
0
     "%s: unable to retrieve name.",
535
0
     function );
536
537
0
    result = -1;
538
0
  }
539
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
540
0
  if( libcthreads_read_write_lock_release_for_write(
541
0
       internal_key->read_write_lock,
542
0
       error ) != 1 )
543
0
  {
544
0
    libcerror_error_set(
545
0
     error,
546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
547
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
548
0
     "%s: unable to release read/write lock for writing.",
549
0
     function );
550
551
0
    return( -1 );
552
0
  }
553
0
#endif
554
0
  return( result );
555
0
}
556
557
/* Retrieves the UTF-8 string size of the key name
558
 * The returned size includes the end of string character
559
 * Returns 1 if successful or -1 on error
560
 */
561
int libcreg_key_get_utf8_name_size(
562
     libcreg_key_t *key,
563
     size_t *utf8_string_size,
564
     libcerror_error_t **error )
565
0
{
566
0
  libcreg_internal_key_t *internal_key = NULL;
567
0
  static char *function                = "libcreg_key_get_utf8_name_size";
568
0
  int result                           = 1;
569
570
0
  if( key == NULL )
571
0
  {
572
0
    libcerror_error_set(
573
0
     error,
574
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
575
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
576
0
     "%s: invalid key.",
577
0
     function );
578
579
0
    return( -1 );
580
0
  }
581
0
  internal_key = (libcreg_internal_key_t *) key;
582
583
0
  if( internal_key->io_handle == NULL )
584
0
  {
585
0
    libcerror_error_set(
586
0
     error,
587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
588
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
589
0
     "%s: invalid key - missing IO handle.",
590
0
     function );
591
592
0
    return( -1 );
593
0
  }
594
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
595
0
  if( libcthreads_read_write_lock_grab_for_write(
596
0
       internal_key->read_write_lock,
597
0
       error ) != 1 )
598
0
  {
599
0
    libcerror_error_set(
600
0
     error,
601
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
602
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
603
0
     "%s: unable to grab read/write lock for writing.",
604
0
     function );
605
606
0
    return( -1 );
607
0
  }
608
0
#endif
609
0
  if( libcreg_key_item_get_utf8_name_size(
610
0
       internal_key->key_item,
611
0
       utf8_string_size,
612
0
       internal_key->io_handle->ascii_codepage,
613
0
       error ) != 1 )
614
0
  {
615
0
    libcerror_error_set(
616
0
     error,
617
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
618
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
619
0
     "%s: unable to retrieve UTF-8 name size.",
620
0
     function );
621
622
0
    result = -1;
623
0
  }
624
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
625
0
  if( libcthreads_read_write_lock_release_for_write(
626
0
       internal_key->read_write_lock,
627
0
       error ) != 1 )
628
0
  {
629
0
    libcerror_error_set(
630
0
     error,
631
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
632
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
633
0
     "%s: unable to release read/write lock for writing.",
634
0
     function );
635
636
0
    return( -1 );
637
0
  }
638
0
#endif
639
0
  return( result );
640
0
}
641
642
/* Retrieves the UTF-8 string value of the key name
643
 * The function uses a codepage if necessary, it uses the codepage set for the library
644
 * The size should include the end of string character
645
 * Returns 1 if successful or -1 on error
646
 */
647
int libcreg_key_get_utf8_name(
648
     libcreg_key_t *key,
649
     uint8_t *utf8_string,
650
     size_t utf8_string_size,
651
     libcerror_error_t **error )
652
0
{
653
0
  libcreg_internal_key_t *internal_key = NULL;
654
0
  static char *function                = "libcreg_key_get_utf8_name";
655
0
  int result                           = 1;
656
657
0
  if( key == NULL )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
662
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
663
0
     "%s: invalid key.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
0
  internal_key = (libcreg_internal_key_t *) key;
669
670
0
  if( internal_key->io_handle == NULL )
671
0
  {
672
0
    libcerror_error_set(
673
0
     error,
674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
675
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
676
0
     "%s: invalid key - missing IO handle.",
677
0
     function );
678
679
0
    return( -1 );
680
0
  }
681
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
682
0
  if( libcthreads_read_write_lock_grab_for_write(
683
0
       internal_key->read_write_lock,
684
0
       error ) != 1 )
685
0
  {
686
0
    libcerror_error_set(
687
0
     error,
688
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
689
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
690
0
     "%s: unable to grab read/write lock for writing.",
691
0
     function );
692
693
0
    return( -1 );
694
0
  }
695
0
#endif
696
0
  if( libcreg_key_item_get_utf8_name(
697
0
       internal_key->key_item,
698
0
       utf8_string,
699
0
       utf8_string_size,
700
0
       internal_key->io_handle->ascii_codepage,
701
0
       error ) != 1 )
702
0
  {
703
0
    libcerror_error_set(
704
0
     error,
705
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
706
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
707
0
     "%s: unable to retrieve UTF-8 name size.",
708
0
     function );
709
710
0
    result = -1;
711
0
  }
712
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
713
0
  if( libcthreads_read_write_lock_release_for_write(
714
0
       internal_key->read_write_lock,
715
0
       error ) != 1 )
716
0
  {
717
0
    libcerror_error_set(
718
0
     error,
719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
720
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
721
0
     "%s: unable to release read/write lock for writing.",
722
0
     function );
723
724
0
    return( -1 );
725
0
  }
726
0
#endif
727
0
  return( result );
728
0
}
729
730
/* Retrieves the UTF-16 string size of the key name
731
 * The returned size includes the end of string character
732
 * Returns 1 if successful or -1 on error
733
 */
734
int libcreg_key_get_utf16_name_size(
735
     libcreg_key_t *key,
736
     size_t *utf16_string_size,
737
     libcerror_error_t **error )
738
0
{
739
0
  libcreg_internal_key_t *internal_key = NULL;
740
0
  static char *function                = "libcreg_key_get_utf16_name_size";
741
0
  int result                           = 1;
742
743
0
  if( key == NULL )
744
0
  {
745
0
    libcerror_error_set(
746
0
     error,
747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
749
0
     "%s: invalid key.",
750
0
     function );
751
752
0
    return( -1 );
753
0
  }
754
0
  internal_key = (libcreg_internal_key_t *) key;
755
756
0
  if( internal_key->io_handle == NULL )
757
0
  {
758
0
    libcerror_error_set(
759
0
     error,
760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
761
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
762
0
     "%s: invalid key - missing IO handle.",
763
0
     function );
764
765
0
    return( -1 );
766
0
  }
767
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
768
0
  if( libcthreads_read_write_lock_grab_for_write(
769
0
       internal_key->read_write_lock,
770
0
       error ) != 1 )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
776
0
     "%s: unable to grab read/write lock for writing.",
777
0
     function );
778
779
0
    return( -1 );
780
0
  }
781
0
#endif
782
0
  if( libcreg_key_item_get_utf16_name_size(
783
0
       internal_key->key_item,
784
0
       utf16_string_size,
785
0
       internal_key->io_handle->ascii_codepage,
786
0
       error ) != 1 )
787
0
  {
788
0
    libcerror_error_set(
789
0
     error,
790
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
791
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
792
0
     "%s: unable to retrieve UTF-16 name size.",
793
0
     function );
794
795
0
    result = -1;
796
0
  }
797
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
798
0
  if( libcthreads_read_write_lock_release_for_write(
799
0
       internal_key->read_write_lock,
800
0
       error ) != 1 )
801
0
  {
802
0
    libcerror_error_set(
803
0
     error,
804
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
805
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
806
0
     "%s: unable to release read/write lock for writing.",
807
0
     function );
808
809
0
    return( -1 );
810
0
  }
811
0
#endif
812
0
  return( result );
813
0
}
814
815
/* Retrieves the UTF-16 string value of the key name
816
 * The function uses a codepage if necessary, it uses the codepage set for the library
817
 * The size should include the end of string character
818
 * Returns 1 if successful or -1 on error
819
 */
820
int libcreg_key_get_utf16_name(
821
     libcreg_key_t *key,
822
     uint16_t *utf16_string,
823
     size_t utf16_string_size,
824
     libcerror_error_t **error )
825
0
{
826
0
  libcreg_internal_key_t *internal_key = NULL;
827
0
  static char *function                = "libcreg_value_get_utf16_name";
828
0
  int result                           = 1;
829
830
0
  if( key == NULL )
831
0
  {
832
0
    libcerror_error_set(
833
0
     error,
834
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
835
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
836
0
     "%s: invalid key.",
837
0
     function );
838
839
0
    return( -1 );
840
0
  }
841
0
  internal_key = (libcreg_internal_key_t *) key;
842
843
0
  if( internal_key->io_handle == NULL )
844
0
  {
845
0
    libcerror_error_set(
846
0
     error,
847
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
848
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
849
0
     "%s: invalid key - missing IO handle.",
850
0
     function );
851
852
0
    return( -1 );
853
0
  }
854
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
855
0
  if( libcthreads_read_write_lock_grab_for_write(
856
0
       internal_key->read_write_lock,
857
0
       error ) != 1 )
858
0
  {
859
0
    libcerror_error_set(
860
0
     error,
861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
862
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
863
0
     "%s: unable to grab read/write lock for writing.",
864
0
     function );
865
866
0
    return( -1 );
867
0
  }
868
0
#endif
869
0
  if( libcreg_key_item_get_utf16_name(
870
0
       internal_key->key_item,
871
0
       utf16_string,
872
0
       utf16_string_size,
873
0
       internal_key->io_handle->ascii_codepage,
874
0
       error ) != 1 )
875
0
  {
876
0
    libcerror_error_set(
877
0
     error,
878
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
879
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
880
0
     "%s: unable to retrieve UTF-16 name.",
881
0
     function );
882
883
0
    result = -1;
884
0
  }
885
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
886
0
  if( libcthreads_read_write_lock_release_for_write(
887
0
       internal_key->read_write_lock,
888
0
       error ) != 1 )
889
0
  {
890
0
    libcerror_error_set(
891
0
     error,
892
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
893
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
894
0
     "%s: unable to release read/write lock for writing.",
895
0
     function );
896
897
0
    return( -1 );
898
0
  }
899
0
#endif
900
0
  return( result );
901
0
}
902
903
/* Retrieves the number of values
904
 * Returns 1 if successful or -1 on error
905
 */
906
int libcreg_key_get_number_of_values(
907
     libcreg_key_t *key,
908
     int *number_of_values,
909
     libcerror_error_t **error )
910
147
{
911
147
  libcreg_internal_key_t *internal_key = NULL;
912
147
  static char *function                = "libcreg_key_get_number_of_values";
913
147
  int result                           = 1;
914
915
147
  if( key == NULL )
916
0
  {
917
0
    libcerror_error_set(
918
0
     error,
919
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
920
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
921
0
     "%s: invalid key.",
922
0
     function );
923
924
0
    return( -1 );
925
0
  }
926
147
  internal_key = (libcreg_internal_key_t *) key;
927
928
147
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
929
147
  if( libcthreads_read_write_lock_grab_for_write(
930
147
       internal_key->read_write_lock,
931
147
       error ) != 1 )
932
0
  {
933
0
    libcerror_error_set(
934
0
     error,
935
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
936
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
937
0
     "%s: unable to grab read/write lock for writing.",
938
0
     function );
939
940
0
    return( -1 );
941
0
  }
942
147
#endif
943
147
  if( libcreg_key_item_get_number_of_value_entries(
944
147
       internal_key->key_item,
945
147
       number_of_values,
946
147
       error ) != 1 )
947
0
  {
948
0
    libcerror_error_set(
949
0
     error,
950
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
951
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
952
0
     "%s: unable to retrieve number of value entries.",
953
0
     function );
954
955
0
    result = -1;
956
0
  }
957
147
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
958
147
  if( libcthreads_read_write_lock_release_for_write(
959
147
       internal_key->read_write_lock,
960
147
       error ) != 1 )
961
0
  {
962
0
    libcerror_error_set(
963
0
     error,
964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
966
0
     "%s: unable to release read/write lock for writing.",
967
0
     function );
968
969
0
    return( -1 );
970
0
  }
971
147
#endif
972
147
  return( result );
973
147
}
974
975
/* Retrieves a specific value
976
 * Returns 1 if successful or -1 on error
977
 */
978
int libcreg_key_get_value_by_index(
979
     libcreg_key_t *key,
980
     int value_index,
981
     libcreg_value_t **value,
982
     libcerror_error_t **error )
983
147
{
984
147
  libcreg_internal_key_t *internal_key = NULL;
985
147
  libcreg_value_entry_t *value_entry   = NULL;
986
147
  static char *function                = "libcreg_key_get_value_by_index";
987
147
  int result                           = 1;
988
989
147
  if( key == NULL )
990
0
  {
991
0
    libcerror_error_set(
992
0
     error,
993
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
994
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
995
0
     "%s: invalid key.",
996
0
     function );
997
998
0
    return( -1 );
999
0
  }
1000
147
  internal_key = (libcreg_internal_key_t *) key;
1001
1002
147
  if( value == NULL )
1003
0
  {
1004
0
    libcerror_error_set(
1005
0
     error,
1006
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1007
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1008
0
     "%s: invalid value.",
1009
0
     function );
1010
1011
0
    return( -1 );
1012
0
  }
1013
147
  if( *value != NULL )
1014
0
  {
1015
0
    libcerror_error_set(
1016
0
     error,
1017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1018
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1019
0
     "%s: value already set.",
1020
0
     function );
1021
1022
0
    return( -1 );
1023
0
  }
1024
147
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1025
147
  if( libcthreads_read_write_lock_grab_for_write(
1026
147
       internal_key->read_write_lock,
1027
147
       error ) != 1 )
1028
0
  {
1029
0
    libcerror_error_set(
1030
0
     error,
1031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1032
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1033
0
     "%s: unable to grab read/write lock for writing.",
1034
0
     function );
1035
1036
0
    return( -1 );
1037
0
  }
1038
147
#endif
1039
147
  if( libcreg_key_item_get_value_entry_by_index(
1040
147
       internal_key->key_item,
1041
147
       value_index,
1042
147
       &value_entry,
1043
147
       error ) != 1 )
1044
143
  {
1045
143
    libcerror_error_set(
1046
143
     error,
1047
143
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1048
143
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1049
143
     "%s: unable to retrieve value entry: %d.",
1050
143
     function,
1051
143
     value_index );
1052
1053
143
    result = -1;
1054
143
  }
1055
4
  else if( libcreg_value_initialize(
1056
4
            value,
1057
4
            internal_key->io_handle,
1058
4
            value_entry,
1059
4
            error ) != 1 )
1060
0
  {
1061
0
    libcerror_error_set(
1062
0
     error,
1063
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1064
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1065
0
     "%s: unable to initialize value.",
1066
0
     function );
1067
1068
0
    result = -1;
1069
0
  }
1070
147
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1071
147
  if( libcthreads_read_write_lock_release_for_write(
1072
147
       internal_key->read_write_lock,
1073
147
       error ) != 1 )
1074
0
  {
1075
0
    libcerror_error_set(
1076
0
     error,
1077
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1078
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1079
0
     "%s: unable to release read/write lock for writing.",
1080
0
     function );
1081
1082
0
    return( -1 );
1083
0
  }
1084
147
#endif
1085
147
  return( result );
1086
147
}
1087
1088
/* Retrieves the value for the specific UTF-8 encoded name
1089
 * To retrieve the default value specify value name as NULL and its length as 0
1090
 * Returns 1 if successful, 0 if no such value or -1 on error
1091
 */
1092
int libcreg_key_get_value_by_utf8_name(
1093
     libcreg_key_t *key,
1094
     const uint8_t *utf8_string,
1095
     size_t utf8_string_length,
1096
     libcreg_value_t **value,
1097
     libcerror_error_t **error )
1098
0
{
1099
0
  libcreg_internal_key_t *internal_key = NULL;
1100
0
  libcreg_value_entry_t *value_entry   = NULL;
1101
0
  static char *function                = "libcreg_key_get_value_by_utf8_name";
1102
0
  int result                           = 1;
1103
1104
0
  if( key == NULL )
1105
0
  {
1106
0
    libcerror_error_set(
1107
0
     error,
1108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1110
0
     "%s: invalid key.",
1111
0
     function );
1112
1113
0
    return( -1 );
1114
0
  }
1115
0
  internal_key = (libcreg_internal_key_t *) key;
1116
1117
0
  if( internal_key->io_handle == NULL )
1118
0
  {
1119
0
    libcerror_error_set(
1120
0
     error,
1121
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1122
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1123
0
     "%s: invalid key - missing IO handle.",
1124
0
     function );
1125
1126
0
    return( -1 );
1127
0
  }
1128
0
  if( value == NULL )
1129
0
  {
1130
0
    libcerror_error_set(
1131
0
     error,
1132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1134
0
     "%s: invalid value.",
1135
0
     function );
1136
1137
0
    return( -1 );
1138
0
  }
1139
0
  if( *value != NULL )
1140
0
  {
1141
0
    libcerror_error_set(
1142
0
     error,
1143
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1144
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1145
0
     "%s: value already set.",
1146
0
     function );
1147
1148
0
    return( -1 );
1149
0
  }
1150
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1151
0
  if( libcthreads_read_write_lock_grab_for_write(
1152
0
       internal_key->read_write_lock,
1153
0
       error ) != 1 )
1154
0
  {
1155
0
    libcerror_error_set(
1156
0
     error,
1157
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1158
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1159
0
     "%s: unable to grab read/write lock for writing.",
1160
0
     function );
1161
1162
0
    return( -1 );
1163
0
  }
1164
0
#endif
1165
0
  result = libcreg_key_item_get_value_by_utf8_name(
1166
0
            internal_key->key_item,
1167
0
            utf8_string,
1168
0
            utf8_string_length,
1169
0
            internal_key->io_handle->ascii_codepage,
1170
0
            &value_entry,
1171
0
            error );
1172
1173
0
  if( result == -1 )
1174
0
  {
1175
0
    libcerror_error_set(
1176
0
     error,
1177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1178
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1179
0
     "%s: unable to retrieve value entry by UTF-8 name.",
1180
0
     function );
1181
1182
0
    result = -1;
1183
0
  }
1184
0
  else if( result != 0 )
1185
0
  {
1186
0
    if( libcreg_value_initialize(
1187
0
         value,
1188
0
         internal_key->io_handle,
1189
0
         value_entry,
1190
0
         error ) != 1 )
1191
0
    {
1192
0
      libcerror_error_set(
1193
0
       error,
1194
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1195
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1196
0
       "%s: unable to initialize value.",
1197
0
       function );
1198
1199
0
      result = -1;
1200
0
    }
1201
0
  }
1202
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1203
0
  if( libcthreads_read_write_lock_release_for_write(
1204
0
       internal_key->read_write_lock,
1205
0
       error ) != 1 )
1206
0
  {
1207
0
    libcerror_error_set(
1208
0
     error,
1209
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1210
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1211
0
     "%s: unable to release read/write lock for writing.",
1212
0
     function );
1213
1214
0
    return( -1 );
1215
0
  }
1216
0
#endif
1217
0
  return( result );
1218
0
}
1219
1220
/* Retrieves the value for the specific UTF-16 encoded name
1221
 * To retrieve the default value specify string as NULL
1222
 * and its length as 0
1223
 * Returns 1 if successful, 0 if no such value or -1 on error
1224
 */
1225
int libcreg_key_get_value_by_utf16_name(
1226
     libcreg_key_t *key,
1227
     const uint16_t *utf16_string,
1228
     size_t utf16_string_length,
1229
     libcreg_value_t **value,
1230
     libcerror_error_t **error )
1231
0
{
1232
0
  libcreg_internal_key_t *internal_key = NULL;
1233
0
  libcreg_value_entry_t *value_entry   = NULL;
1234
0
  static char *function                = "libcreg_key_get_value_by_utf16_name";
1235
0
  int result                           = 1;
1236
1237
0
  if( key == NULL )
1238
0
  {
1239
0
    libcerror_error_set(
1240
0
     error,
1241
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1242
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1243
0
     "%s: invalid key.",
1244
0
     function );
1245
1246
0
    return( -1 );
1247
0
  }
1248
0
  internal_key = (libcreg_internal_key_t *) key;
1249
1250
0
  if( internal_key->io_handle == NULL )
1251
0
  {
1252
0
    libcerror_error_set(
1253
0
     error,
1254
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1255
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1256
0
     "%s: invalid key - missing IO handle.",
1257
0
     function );
1258
1259
0
    return( -1 );
1260
0
  }
1261
0
  if( value == NULL )
1262
0
  {
1263
0
    libcerror_error_set(
1264
0
     error,
1265
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1266
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1267
0
     "%s: invalid value.",
1268
0
     function );
1269
1270
0
    return( -1 );
1271
0
  }
1272
0
  if( *value != NULL )
1273
0
  {
1274
0
    libcerror_error_set(
1275
0
     error,
1276
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1277
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1278
0
     "%s: value already set.",
1279
0
     function );
1280
1281
0
    return( -1 );
1282
0
  }
1283
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1284
0
  if( libcthreads_read_write_lock_grab_for_write(
1285
0
       internal_key->read_write_lock,
1286
0
       error ) != 1 )
1287
0
  {
1288
0
    libcerror_error_set(
1289
0
     error,
1290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1291
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1292
0
     "%s: unable to grab read/write lock for writing.",
1293
0
     function );
1294
1295
0
    return( -1 );
1296
0
  }
1297
0
#endif
1298
0
  result = libcreg_key_item_get_value_by_utf16_name(
1299
0
            internal_key->key_item,
1300
0
            utf16_string,
1301
0
            utf16_string_length,
1302
0
            internal_key->io_handle->ascii_codepage,
1303
0
            &value_entry,
1304
0
            error );
1305
1306
0
  if( result == -1 )
1307
0
  {
1308
0
    libcerror_error_set(
1309
0
     error,
1310
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1311
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1312
0
     "%s: unable to retrieve value entry by UTF-16 name.",
1313
0
     function );
1314
1315
0
    result = -1;
1316
0
  }
1317
0
  else if( result != 0 )
1318
0
  {
1319
0
    if( libcreg_value_initialize(
1320
0
         value,
1321
0
         internal_key->io_handle,
1322
0
         value_entry,
1323
0
         error ) != 1 )
1324
0
    {
1325
0
      libcerror_error_set(
1326
0
       error,
1327
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1328
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1329
0
       "%s: unable to initialize value.",
1330
0
       function );
1331
1332
0
      result = -1;
1333
0
    }
1334
0
  }
1335
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1336
0
  if( libcthreads_read_write_lock_release_for_write(
1337
0
       internal_key->read_write_lock,
1338
0
       error ) != 1 )
1339
0
  {
1340
0
    libcerror_error_set(
1341
0
     error,
1342
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1343
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1344
0
     "%s: unable to release read/write lock for writing.",
1345
0
     function );
1346
1347
0
    return( -1 );
1348
0
  }
1349
0
#endif
1350
0
  return( result );
1351
0
}
1352
1353
/* Retrieves the number of sub keys
1354
 * Returns 1 if successful or -1 on error
1355
 */
1356
int libcreg_key_get_number_of_sub_keys(
1357
     libcreg_key_t *key,
1358
     int *number_of_sub_keys,
1359
     libcerror_error_t **error )
1360
504
{
1361
504
  libcreg_internal_key_t *internal_key = NULL;
1362
504
  static char *function                = "libcreg_key_get_number_of_sub_keys";
1363
504
  int result                           = 1;
1364
1365
504
  if( key == NULL )
1366
0
  {
1367
0
    libcerror_error_set(
1368
0
     error,
1369
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1370
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1371
0
     "%s: invalid key.",
1372
0
     function );
1373
1374
0
    return( -1 );
1375
0
  }
1376
504
  internal_key = (libcreg_internal_key_t *) key;
1377
1378
504
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1379
504
  if( libcthreads_read_write_lock_grab_for_write(
1380
504
       internal_key->read_write_lock,
1381
504
       error ) != 1 )
1382
0
  {
1383
0
    libcerror_error_set(
1384
0
     error,
1385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1386
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1387
0
     "%s: unable to grab read/write lock for writing.",
1388
0
     function );
1389
1390
0
    return( -1 );
1391
0
  }
1392
504
#endif
1393
504
  if( libcreg_key_item_get_number_of_sub_key_descriptors(
1394
504
       internal_key->key_item,
1395
504
       number_of_sub_keys,
1396
504
       error ) != 1 )
1397
0
  {
1398
0
    libcerror_error_set(
1399
0
     error,
1400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1402
0
     "%s: unable to retrieve number of sub key descriptors.",
1403
0
     function );
1404
1405
0
    result = -1;
1406
0
  }
1407
504
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1408
504
  if( libcthreads_read_write_lock_release_for_write(
1409
504
       internal_key->read_write_lock,
1410
504
       error ) != 1 )
1411
0
  {
1412
0
    libcerror_error_set(
1413
0
     error,
1414
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1415
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1416
0
     "%s: unable to release read/write lock for writing.",
1417
0
     function );
1418
1419
0
    return( -1 );
1420
0
  }
1421
504
#endif
1422
504
  return( result );
1423
504
}
1424
1425
/* Retrieves the sub key for the specific index
1426
 * Returns 1 if successful or -1 on error
1427
 */
1428
int libcreg_key_get_sub_key_by_index(
1429
     libcreg_key_t *key,
1430
     int sub_key_index,
1431
     libcreg_key_t **sub_key,
1432
     libcerror_error_t **error )
1433
499
{
1434
499
  libcreg_internal_key_t *internal_key         = NULL;
1435
499
  libcreg_key_descriptor_t *sub_key_descriptor = NULL;
1436
499
  static char *function                        = "libcreg_key_get_sub_key_by_index";
1437
499
  int result                                   = 1;
1438
1439
499
  if( key == NULL )
1440
0
  {
1441
0
    libcerror_error_set(
1442
0
     error,
1443
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1444
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1445
0
     "%s: invalid key.",
1446
0
     function );
1447
1448
0
    return( -1 );
1449
0
  }
1450
499
  internal_key = (libcreg_internal_key_t *) key;
1451
1452
499
  if( sub_key == NULL )
1453
0
  {
1454
0
    libcerror_error_set(
1455
0
     error,
1456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1458
0
     "%s: invalid sub key.",
1459
0
     function );
1460
1461
0
    return( -1 );
1462
0
  }
1463
499
  if( *sub_key != NULL )
1464
0
  {
1465
0
    libcerror_error_set(
1466
0
     error,
1467
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1468
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1469
0
     "%s: sub key already set.",
1470
0
     function );
1471
1472
0
    return( -1 );
1473
0
  }
1474
499
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1475
499
  if( libcthreads_read_write_lock_grab_for_write(
1476
499
       internal_key->read_write_lock,
1477
499
       error ) != 1 )
1478
0
  {
1479
0
    libcerror_error_set(
1480
0
     error,
1481
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1482
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1483
0
     "%s: unable to grab read/write lock for writing.",
1484
0
     function );
1485
1486
0
    return( -1 );
1487
0
  }
1488
499
#endif
1489
499
  if( libcreg_key_item_get_sub_key_descriptor_by_index(
1490
499
       internal_key->key_item,
1491
499
             sub_key_index,
1492
499
       &sub_key_descriptor,
1493
499
       error ) != 1 )
1494
0
  {
1495
0
    libcerror_error_set(
1496
0
     error,
1497
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1498
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1499
0
     "%s: unable to retrieve sub key descriptor: %d.",
1500
0
     function,
1501
0
     sub_key_index );
1502
1503
0
    result = -1;
1504
0
  }
1505
499
  else if( sub_key_descriptor == NULL )
1506
0
  {
1507
0
    libcerror_error_set(
1508
0
     error,
1509
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1510
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1511
0
     "%s: invalid sub key descriptor: %d.",
1512
0
     function,
1513
0
     sub_key_index );
1514
1515
0
    result = -1;
1516
0
  }
1517
499
  else if( libcreg_key_initialize(
1518
499
            sub_key,
1519
499
            internal_key->io_handle,
1520
499
            internal_key->file_io_handle,
1521
499
            internal_key->key_navigation,
1522
499
            sub_key_descriptor->key_offset,
1523
499
            error ) != 1 )
1524
212
  {
1525
212
    libcerror_error_set(
1526
212
     error,
1527
212
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1528
212
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1529
212
     "%s: unable to initialize sub key.",
1530
212
     function );
1531
1532
212
    result = -1;
1533
212
  }
1534
499
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1535
499
  if( libcthreads_read_write_lock_release_for_write(
1536
499
       internal_key->read_write_lock,
1537
499
       error ) != 1 )
1538
0
  {
1539
0
    libcerror_error_set(
1540
0
     error,
1541
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1542
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1543
0
     "%s: unable to release read/write lock for writing.",
1544
0
     function );
1545
1546
0
    return( -1 );
1547
0
  }
1548
499
#endif
1549
499
  return( result );
1550
499
}
1551
1552
/* Retrieves the sub key for the specific UTF-8 encoded name
1553
 * Returns 1 if successful, 0 if no such sub key or -1 on error
1554
 */
1555
int libcreg_key_get_sub_key_by_utf8_name(
1556
     libcreg_key_t *key,
1557
     const uint8_t *utf8_string,
1558
     size_t utf8_string_length,
1559
     libcreg_key_t **sub_key,
1560
     libcerror_error_t **error )
1561
0
{
1562
0
  libcreg_key_descriptor_t *sub_key_descriptor = NULL;
1563
0
  libcreg_internal_key_t *internal_key         = NULL;
1564
0
  static char *function                        = "libcreg_key_get_sub_key_by_utf8_name";
1565
0
  int result                                   = 0;
1566
1567
0
  if( key == NULL )
1568
0
  {
1569
0
    libcerror_error_set(
1570
0
     error,
1571
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1572
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1573
0
     "%s: invalid key.",
1574
0
     function );
1575
1576
0
    return( -1 );
1577
0
  }
1578
0
  internal_key = (libcreg_internal_key_t *) key;
1579
1580
0
  if( internal_key->io_handle == NULL )
1581
0
  {
1582
0
    libcerror_error_set(
1583
0
     error,
1584
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1585
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1586
0
     "%s: invalid key - missing IO handle.",
1587
0
     function );
1588
1589
0
    return( -1 );
1590
0
  }
1591
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1592
0
  if( libcthreads_read_write_lock_grab_for_write(
1593
0
       internal_key->read_write_lock,
1594
0
       error ) != 1 )
1595
0
  {
1596
0
    libcerror_error_set(
1597
0
     error,
1598
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1599
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1600
0
     "%s: unable to grab read/write lock for writing.",
1601
0
     function );
1602
1603
0
    return( -1 );
1604
0
  }
1605
0
#endif
1606
0
  result = libcreg_key_item_get_sub_key_descriptor_by_utf8_name(
1607
0
            internal_key->key_item,
1608
0
            internal_key->file_io_handle,
1609
0
            internal_key->key_navigation,
1610
0
            utf8_string,
1611
0
            utf8_string_length,
1612
0
            internal_key->io_handle->ascii_codepage,
1613
0
            &sub_key_descriptor,
1614
0
            error );
1615
1616
0
  if( result == -1 )
1617
0
  {
1618
0
    libcerror_error_set(
1619
0
     error,
1620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1621
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1622
0
     "%s: unable to retrieve sub key descriptor by UTF-8 name.",
1623
0
     function );
1624
1625
0
    result = -1;
1626
0
  }
1627
0
  else if( result != 0 )
1628
0
  {
1629
0
    if( sub_key_descriptor == NULL )
1630
0
    {
1631
0
      libcerror_error_set(
1632
0
       error,
1633
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1634
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1635
0
       "%s: invalid sub key descriptor.",
1636
0
       function );
1637
1638
0
      result = -1;
1639
0
    }
1640
0
    else if( libcreg_key_initialize(
1641
0
        sub_key,
1642
0
        internal_key->io_handle,
1643
0
        internal_key->file_io_handle,
1644
0
        internal_key->key_navigation,
1645
0
        sub_key_descriptor->key_offset,
1646
0
        error ) != 1 )
1647
0
    {
1648
0
      libcerror_error_set(
1649
0
       error,
1650
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1651
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1652
0
       "%s: unable to initialize sub key.",
1653
0
       function );
1654
1655
0
      result = -1;
1656
0
    }
1657
0
  }
1658
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1659
0
  if( libcthreads_read_write_lock_release_for_write(
1660
0
       internal_key->read_write_lock,
1661
0
       error ) != 1 )
1662
0
  {
1663
0
    libcerror_error_set(
1664
0
     error,
1665
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1666
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1667
0
     "%s: unable to release read/write lock for writing.",
1668
0
     function );
1669
1670
0
    return( -1 );
1671
0
  }
1672
0
#endif
1673
0
  return( result );
1674
0
}
1675
1676
/* Retrieves the sub key for the specific UTF-8 encoded path
1677
 * The path separator is the \ character
1678
 * Returns 1 if successful, 0 if no such key or -1 on error
1679
 */
1680
int libcreg_key_get_sub_key_by_utf8_path(
1681
     libcreg_key_t *key,
1682
     const uint8_t *utf8_string,
1683
     size_t utf8_string_length,
1684
     libcreg_key_t **sub_key,
1685
     libcerror_error_t **error )
1686
0
{
1687
0
  libcreg_internal_key_t *internal_key = NULL;
1688
0
  static char *function                = "libcreg_key_get_sub_key_by_utf8_path";
1689
0
  int result                           = 0;
1690
1691
0
  if( key == NULL )
1692
0
  {
1693
0
    libcerror_error_set(
1694
0
     error,
1695
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1696
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1697
0
     "%s: invalid key.",
1698
0
     function );
1699
1700
0
    return( -1 );
1701
0
  }
1702
0
  internal_key = (libcreg_internal_key_t *) key;
1703
1704
0
  if( internal_key->io_handle == NULL )
1705
0
  {
1706
0
    libcerror_error_set(
1707
0
     error,
1708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1709
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1710
0
     "%s: invalid key - missing IO handle.",
1711
0
     function );
1712
1713
0
    return( -1 );
1714
0
  }
1715
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1716
0
  if( libcthreads_read_write_lock_grab_for_write(
1717
0
       internal_key->read_write_lock,
1718
0
       error ) != 1 )
1719
0
  {
1720
0
    libcerror_error_set(
1721
0
     error,
1722
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1723
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1724
0
     "%s: unable to grab read/write lock for writing.",
1725
0
     function );
1726
1727
0
    return( -1 );
1728
0
  }
1729
0
#endif
1730
0
  result = libcreg_key_tree_get_sub_key_by_utf8_path(
1731
0
            internal_key->io_handle,
1732
0
            internal_key->file_io_handle,
1733
0
            internal_key->key_navigation,
1734
0
            internal_key->key_offset,
1735
0
            utf8_string,
1736
0
            utf8_string_length,
1737
0
            internal_key->io_handle->ascii_codepage,
1738
0
            sub_key,
1739
0
      error );
1740
1741
0
  if( result == -1 )
1742
0
  {
1743
0
    libcerror_error_set(
1744
0
     error,
1745
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1746
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1747
0
     "%s: unable to retrieve key by UTF-8 path.",
1748
0
     function );
1749
1750
0
    result = -1;
1751
0
  }
1752
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1753
0
  if( libcthreads_read_write_lock_release_for_write(
1754
0
       internal_key->read_write_lock,
1755
0
       error ) != 1 )
1756
0
  {
1757
0
    libcerror_error_set(
1758
0
     error,
1759
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1760
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1761
0
     "%s: unable to release read/write lock for writing.",
1762
0
     function );
1763
1764
0
    return( -1 );
1765
0
  }
1766
0
#endif
1767
0
  return( result );
1768
0
}
1769
1770
/* Retrieves the sub key for the specific UTF-16 encoded name
1771
 * Returns 1 if successful, 0 if no such sub key or -1 on error
1772
 */
1773
int libcreg_key_get_sub_key_by_utf16_name(
1774
     libcreg_key_t *key,
1775
     const uint16_t *utf16_string,
1776
     size_t utf16_string_length,
1777
     libcreg_key_t **sub_key,
1778
     libcerror_error_t **error )
1779
0
{
1780
0
  libcreg_key_descriptor_t *sub_key_descriptor = NULL;
1781
0
  libcreg_internal_key_t *internal_key         = NULL;
1782
0
  static char *function                        = "libcreg_key_get_sub_key_by_utf16_name";
1783
0
  int result                                   = 0;
1784
1785
0
  if( key == NULL )
1786
0
  {
1787
0
    libcerror_error_set(
1788
0
     error,
1789
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1790
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1791
0
     "%s: invalid key.",
1792
0
     function );
1793
1794
0
    return( -1 );
1795
0
  }
1796
0
  internal_key = (libcreg_internal_key_t *) key;
1797
1798
0
  if( internal_key->io_handle == NULL )
1799
0
  {
1800
0
    libcerror_error_set(
1801
0
     error,
1802
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1803
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1804
0
     "%s: invalid key - missing IO handle.",
1805
0
     function );
1806
1807
0
    return( -1 );
1808
0
  }
1809
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1810
0
  if( libcthreads_read_write_lock_grab_for_write(
1811
0
       internal_key->read_write_lock,
1812
0
       error ) != 1 )
1813
0
  {
1814
0
    libcerror_error_set(
1815
0
     error,
1816
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1817
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1818
0
     "%s: unable to grab read/write lock for writing.",
1819
0
     function );
1820
1821
0
    return( -1 );
1822
0
  }
1823
0
#endif
1824
0
  result = libcreg_key_item_get_sub_key_descriptor_by_utf16_name(
1825
0
            internal_key->key_item,
1826
0
            internal_key->file_io_handle,
1827
0
            internal_key->key_navigation,
1828
0
            utf16_string,
1829
0
            utf16_string_length,
1830
0
            internal_key->io_handle->ascii_codepage,
1831
0
            &sub_key_descriptor,
1832
0
            error );
1833
1834
0
  if( result == -1 )
1835
0
  {
1836
0
    libcerror_error_set(
1837
0
     error,
1838
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1839
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1840
0
     "%s: unable to retrieve sub key descriptor by UTF-16 name.",
1841
0
     function );
1842
1843
0
    result = -1;
1844
0
  }
1845
0
  else if( result != 0 )
1846
0
  {
1847
0
    if( sub_key_descriptor == NULL )
1848
0
    {
1849
0
      libcerror_error_set(
1850
0
       error,
1851
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1852
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1853
0
       "%s: invalid sub key descriptor.",
1854
0
       function );
1855
1856
0
      result = -1;
1857
0
    }
1858
0
    else if( libcreg_key_initialize(
1859
0
        sub_key,
1860
0
        internal_key->io_handle,
1861
0
        internal_key->file_io_handle,
1862
0
        internal_key->key_navigation,
1863
0
        sub_key_descriptor->key_offset,
1864
0
        error ) != 1 )
1865
0
    {
1866
0
      libcerror_error_set(
1867
0
       error,
1868
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1869
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1870
0
       "%s: unable to initialize sub key.",
1871
0
       function );
1872
1873
0
      result = -1;
1874
0
    }
1875
0
  }
1876
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1877
0
  if( libcthreads_read_write_lock_release_for_write(
1878
0
       internal_key->read_write_lock,
1879
0
       error ) != 1 )
1880
0
  {
1881
0
    libcerror_error_set(
1882
0
     error,
1883
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1884
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1885
0
     "%s: unable to release read/write lock for writing.",
1886
0
     function );
1887
1888
0
    return( -1 );
1889
0
  }
1890
0
#endif
1891
0
  return( result );
1892
0
}
1893
1894
/* Retrieves the sub key for the specific UTF-16 encoded path
1895
 * The path separator is the \ character
1896
 * Returns 1 if successful, 0 if no such key or -1 on error
1897
 */
1898
int libcreg_key_get_sub_key_by_utf16_path(
1899
     libcreg_key_t *key,
1900
     const uint16_t *utf16_string,
1901
     size_t utf16_string_length,
1902
     libcreg_key_t **sub_key,
1903
     libcerror_error_t **error )
1904
0
{
1905
0
  libcreg_internal_key_t *internal_key = NULL;
1906
0
  static char *function                = "libcreg_key_get_sub_key_by_utf16_path";
1907
0
  int result                           = 0;
1908
1909
0
  if( key == NULL )
1910
0
  {
1911
0
    libcerror_error_set(
1912
0
     error,
1913
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1914
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1915
0
     "%s: invalid key.",
1916
0
     function );
1917
1918
0
    return( -1 );
1919
0
  }
1920
0
  internal_key = (libcreg_internal_key_t *) key;
1921
1922
0
  if( internal_key->io_handle == 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: invalid key - missing IO handle.",
1929
0
     function );
1930
1931
0
    return( -1 );
1932
0
  }
1933
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1934
0
  if( libcthreads_read_write_lock_grab_for_write(
1935
0
       internal_key->read_write_lock,
1936
0
       error ) != 1 )
1937
0
  {
1938
0
    libcerror_error_set(
1939
0
     error,
1940
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1941
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1942
0
     "%s: unable to grab read/write lock for writing.",
1943
0
     function );
1944
1945
0
    return( -1 );
1946
0
  }
1947
0
#endif
1948
0
  result = libcreg_key_tree_get_sub_key_by_utf16_path(
1949
0
            internal_key->io_handle,
1950
0
            internal_key->file_io_handle,
1951
0
            internal_key->key_navigation,
1952
0
            internal_key->key_offset,
1953
0
            utf16_string,
1954
0
            utf16_string_length,
1955
0
            internal_key->io_handle->ascii_codepage,
1956
0
            sub_key,
1957
0
      error );
1958
1959
0
  if( result == -1 )
1960
0
  {
1961
0
    libcerror_error_set(
1962
0
     error,
1963
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1964
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1965
0
     "%s: unable to retrieve key by UTF-16 path.",
1966
0
     function );
1967
1968
0
    result = -1;
1969
0
  }
1970
0
#if defined( HAVE_LIBCREG_MULTI_THREAD_SUPPORT )
1971
0
  if( libcthreads_read_write_lock_release_for_write(
1972
0
       internal_key->read_write_lock,
1973
0
       error ) != 1 )
1974
0
  {
1975
0
    libcerror_error_set(
1976
0
     error,
1977
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1978
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1979
0
     "%s: unable to release read/write lock for writing.",
1980
0
     function );
1981
1982
0
    return( -1 );
1983
0
  }
1984
0
#endif
1985
0
  return( result );
1986
0
}
1987