Coverage Report

Created: 2025-06-13 07:21

/src/libregf/libregf/libregf_key.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Key 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 <types.h>
25
26
#if defined( HAVE_WCTYPE_H )
27
#include <wctype.h>
28
#endif
29
30
#include "libregf_definitions.h"
31
#include "libregf_io_handle.h"
32
#include "libregf_key.h"
33
#include "libregf_key_item.h"
34
#include "libregf_key_tree.h"
35
#include "libregf_libbfio.h"
36
#include "libregf_libcerror.h"
37
#include "libregf_libcthreads.h"
38
#include "libregf_libfdata.h"
39
#include "libregf_libuna.h"
40
#include "libregf_value.h"
41
#include "libregf_value_item.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 libregf_key_initialize(
48
     libregf_key_t **key,
49
     libregf_io_handle_t *io_handle,
50
     libbfio_handle_t *file_io_handle,
51
     uint32_t key_offset,
52
     libregf_hive_bins_list_t *hive_bins_list,
53
     libcerror_error_t **error )
54
1.06k
{
55
1.06k
  libregf_internal_key_t *internal_key = NULL;
56
1.06k
  static char *function                = "libregf_key_initialize";
57
58
1.06k
  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
1.06k
  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
1.06k
  if( io_handle == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
85
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
86
0
     "%s: invalid IO handle.",
87
0
     function );
88
89
0
    return( -1 );
90
0
  }
91
1.06k
  internal_key = memory_allocate_structure(
92
1.06k
                  libregf_internal_key_t );
93
94
1.06k
  if( internal_key == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
99
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
100
0
     "%s: unable to create internal key.",
101
0
     function );
102
103
0
    goto on_error;
104
0
  }
105
1.06k
  if( memory_set(
106
1.06k
       internal_key,
107
1.06k
       0,
108
1.06k
       sizeof( libregf_internal_key_t ) ) == NULL )
109
0
  {
110
0
    libcerror_error_set(
111
0
     error,
112
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
113
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
114
0
     "%s: unable to clear internal key.",
115
0
     function );
116
117
0
    memory_free(
118
0
     internal_key );
119
120
0
    return( -1 );
121
0
  }
122
1.06k
  if( libregf_key_item_initialize(
123
1.06k
       &( internal_key->key_item ),
124
1.06k
       error ) != 1 )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
129
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
130
0
     "%s: unable to create key item.",
131
0
     function );
132
133
0
    goto on_error;
134
0
  }
135
1.06k
  if( libregf_key_item_read(
136
1.06k
       internal_key->key_item,
137
1.06k
       file_io_handle,
138
1.06k
       hive_bins_list,
139
1.06k
       key_offset,
140
1.06k
       (uint32_t) 0, /* TODO pass hash or key descriptor */
141
1.06k
       error ) != 1 )
142
934
  {
143
934
    libcerror_error_set(
144
934
     error,
145
934
     LIBCERROR_ERROR_DOMAIN_IO,
146
934
     LIBCERROR_IO_ERROR_READ_FAILED,
147
934
     "%s: unable to read key item at offset: %" PRIi64 " (0x%08" PRIx64 ").",
148
934
     function,
149
934
     key_offset,
150
934
     key_offset );
151
152
934
    goto on_error;
153
934
  }
154
131
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
155
131
  if( libcthreads_read_write_lock_initialize(
156
131
       &( internal_key->read_write_lock ),
157
131
       error ) != 1 )
158
0
  {
159
0
    libcerror_error_set(
160
0
     error,
161
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
162
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
163
0
     "%s: unable to initialize read/write lock.",
164
0
     function );
165
166
0
    goto on_error;
167
0
  }
168
131
#endif
169
131
  internal_key->file_io_handle = file_io_handle;
170
131
  internal_key->io_handle      = io_handle;
171
131
  internal_key->key_offset     = key_offset;
172
131
  internal_key->hive_bins_list = hive_bins_list;
173
174
131
  *key = (libregf_key_t *) internal_key;
175
176
131
  return( 1 );
177
178
934
on_error:
179
934
  if( internal_key != NULL )
180
934
  {
181
934
    if( internal_key->key_item != NULL )
182
934
    {
183
934
      libregf_key_item_free(
184
934
       &( internal_key->key_item ),
185
934
       NULL );
186
934
    }
187
934
    memory_free(
188
934
     internal_key );
189
934
  }
190
934
  return( -1 );
191
131
}
192
193
/* Frees a key
194
 * Returns 1 if successful or -1 on error
195
 */
196
int libregf_key_free(
197
     libregf_key_t **key,
198
     libcerror_error_t **error )
199
131
{
200
131
  libregf_internal_key_t *internal_key = NULL;
201
131
  static char *function                = "libregf_key_free";
202
131
  int result                           = 1;
203
204
131
  if( key == NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
210
0
     "%s: invalid key.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
131
  if( *key != NULL )
216
131
  {
217
131
    internal_key = (libregf_internal_key_t *) *key;
218
131
    *key         = NULL;
219
220
131
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
221
131
    if( libcthreads_read_write_lock_free(
222
131
         &( internal_key->read_write_lock ),
223
131
         error ) != 1 )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
229
0
       "%s: unable to free read/write lock.",
230
0
       function );
231
232
0
      result = -1;
233
0
    }
234
131
#endif
235
    /* The io_handle, file_io_handle and hive_bins_list references are freed elsewhere
236
     */
237
131
    if( libregf_key_item_free(
238
131
         &( internal_key->key_item ),
239
131
         error ) != 1 )
240
0
    {
241
0
      libcerror_error_set(
242
0
       error,
243
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
245
0
       "%s: unable to free key item.",
246
0
       function );
247
248
0
      result = -1;
249
0
    }
250
131
    memory_free(
251
131
     internal_key );
252
131
  }
253
131
  return( result );
254
131
}
255
256
/* Determines if the key is corrupted
257
 * Returns 1 if corrupted, 0 if not or -1 on error
258
 */
259
int libregf_key_is_corrupted(
260
     libregf_key_t *key,
261
     libcerror_error_t **error )
262
0
{
263
0
  libregf_internal_key_t *internal_key = NULL;
264
0
  static char *function                = "libregf_key_is_corrupted";
265
0
  int result                           = 0;
266
267
0
  if( key == NULL )
268
0
  {
269
0
    libcerror_error_set(
270
0
     error,
271
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
272
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
273
0
     "%s: invalid key.",
274
0
     function );
275
276
0
    return( -1 );
277
0
  }
278
0
  internal_key = (libregf_internal_key_t *) key;
279
280
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
281
0
  if( libcthreads_read_write_lock_grab_for_write(
282
0
       internal_key->read_write_lock,
283
0
       error ) != 1 )
284
0
  {
285
0
    libcerror_error_set(
286
0
     error,
287
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
288
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
289
0
     "%s: unable to grab read/write lock for writing.",
290
0
     function );
291
292
0
    return( -1 );
293
0
  }
294
0
#endif
295
0
  result = libregf_key_item_is_corrupted(
296
0
            internal_key->key_item,
297
0
            error );
298
299
0
  if( result == -1 )
300
0
  {
301
0
    libcerror_error_set(
302
0
     error,
303
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
304
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
305
0
     "%s: unable to determine if key item is corruped.",
306
0
     function );
307
308
0
    result = -1;
309
0
  }
310
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
311
0
  if( libcthreads_read_write_lock_release_for_write(
312
0
       internal_key->read_write_lock,
313
0
       error ) != 1 )
314
0
  {
315
0
    libcerror_error_set(
316
0
     error,
317
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
318
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
319
0
     "%s: unable to release read/write lock for writing.",
320
0
     function );
321
322
0
    return( -1 );
323
0
  }
324
0
#endif
325
0
  return( result );
326
0
}
327
328
/* Retrieves the offset of the key
329
 * Returns 1 if successful or -1 on error
330
 */
331
int libregf_key_get_offset(
332
     libregf_key_t *key,
333
     off64_t *offset,
334
     libcerror_error_t **error )
335
0
{
336
0
  libregf_internal_key_t *internal_key = NULL;
337
0
  static char *function                = "libregf_key_get_offset";
338
0
  int result                           = 1;
339
340
0
  if( key == NULL )
341
0
  {
342
0
    libcerror_error_set(
343
0
     error,
344
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
345
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
346
0
     "%s: invalid key.",
347
0
     function );
348
349
0
    return( -1 );
350
0
  }
351
0
  internal_key = (libregf_internal_key_t *) key;
352
353
0
  if( internal_key->io_handle == NULL )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
359
0
     "%s: invalid key - missing IO handle.",
360
0
     function );
361
362
0
    return( -1 );
363
0
  }
364
0
  if( offset == NULL )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
369
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
370
0
     "%s: invalid offset.",
371
0
     function );
372
373
0
    return( -1 );
374
0
  }
375
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
376
0
  if( libcthreads_read_write_lock_grab_for_write(
377
0
       internal_key->read_write_lock,
378
0
       error ) != 1 )
379
0
  {
380
0
    libcerror_error_set(
381
0
     error,
382
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
383
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
384
0
     "%s: unable to grab read/write lock for writing.",
385
0
     function );
386
387
0
    return( -1 );
388
0
  }
389
0
#endif
390
  /* The offset is relative from the start of the hive bins list
391
   * and points to the start of the corresponding hive bin cell
392
   */
393
0
  *offset = (off64_t) internal_key->key_offset + internal_key->io_handle->hive_bins_list_offset + 4;
394
395
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
396
0
  if( libcthreads_read_write_lock_release_for_write(
397
0
       internal_key->read_write_lock,
398
0
       error ) != 1 )
399
0
  {
400
0
    libcerror_error_set(
401
0
     error,
402
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
403
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
404
0
     "%s: unable to release read/write lock for writing.",
405
0
     function );
406
407
0
    return( -1 );
408
0
  }
409
0
#endif
410
0
  return( result );
411
0
}
412
413
/* Retrieves the key name size
414
 * Returns 1 if successful or -1 on error
415
 */
416
int libregf_key_get_name_size(
417
     libregf_key_t *key,
418
     size_t *name_size,
419
     libcerror_error_t **error )
420
0
{
421
0
  libregf_internal_key_t *internal_key = NULL;
422
0
  static char *function                = "libregf_key_get_name_size";
423
0
  int result                           = 1;
424
425
0
  if( key == NULL )
426
0
  {
427
0
    libcerror_error_set(
428
0
     error,
429
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
430
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
431
0
     "%s: invalid key.",
432
0
     function );
433
434
0
    return( -1 );
435
0
  }
436
0
  internal_key = (libregf_internal_key_t *) key;
437
438
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
439
0
  if( libcthreads_read_write_lock_grab_for_write(
440
0
       internal_key->read_write_lock,
441
0
       error ) != 1 )
442
0
  {
443
0
    libcerror_error_set(
444
0
     error,
445
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
446
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
447
0
     "%s: unable to grab read/write lock for writing.",
448
0
     function );
449
450
0
    return( -1 );
451
0
  }
452
0
#endif
453
0
  if( libregf_key_item_get_name_size(
454
0
       internal_key->key_item,
455
0
       name_size,
456
0
       error ) != 1 )
457
0
  {
458
0
    libcerror_error_set(
459
0
     error,
460
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
461
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
462
0
     "%s: unable to retrieve name size.",
463
0
     function );
464
465
0
    result = -1;
466
0
  }
467
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
468
0
  if( libcthreads_read_write_lock_release_for_write(
469
0
       internal_key->read_write_lock,
470
0
       error ) != 1 )
471
0
  {
472
0
    libcerror_error_set(
473
0
     error,
474
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
475
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
476
0
     "%s: unable to release read/write lock for writing.",
477
0
     function );
478
479
0
    return( -1 );
480
0
  }
481
0
#endif
482
0
  return( result );
483
0
}
484
485
/* Retrieves the key name
486
 * Returns 1 if successful or -1 on error
487
 */
488
int libregf_key_get_name(
489
     libregf_key_t *key,
490
     uint8_t *name,
491
     size_t name_size,
492
     libcerror_error_t **error )
493
0
{
494
0
  libregf_internal_key_t *internal_key = NULL;
495
0
  static char *function                = "libregf_key_get_name";
496
0
  int result                           = 1;
497
498
0
  if( key == NULL )
499
0
  {
500
0
    libcerror_error_set(
501
0
     error,
502
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
503
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
504
0
     "%s: invalid key.",
505
0
     function );
506
507
0
    return( -1 );
508
0
  }
509
0
  internal_key = (libregf_internal_key_t *) key;
510
511
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
512
0
  if( libcthreads_read_write_lock_grab_for_write(
513
0
       internal_key->read_write_lock,
514
0
       error ) != 1 )
515
0
  {
516
0
    libcerror_error_set(
517
0
     error,
518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
519
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
520
0
     "%s: unable to grab read/write lock for writing.",
521
0
     function );
522
523
0
    return( -1 );
524
0
  }
525
0
#endif
526
0
  if( libregf_key_item_get_name(
527
0
       internal_key->key_item,
528
0
       name,
529
0
       name_size,
530
0
       error ) != 1 )
531
0
  {
532
0
    libcerror_error_set(
533
0
     error,
534
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
535
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
536
0
     "%s: unable to retrieve name.",
537
0
     function );
538
539
0
    result = -1;
540
0
  }
541
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
542
0
  if( libcthreads_read_write_lock_release_for_write(
543
0
       internal_key->read_write_lock,
544
0
       error ) != 1 )
545
0
  {
546
0
    libcerror_error_set(
547
0
     error,
548
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
549
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
550
0
     "%s: unable to release read/write lock for writing.",
551
0
     function );
552
553
0
    return( -1 );
554
0
  }
555
0
#endif
556
0
  return( result );
557
0
}
558
559
/* Retrieves the UTF-8 string size of the key name
560
 * The returned size includes the end of string character
561
 * Returns 1 if successful or -1 on error
562
 */
563
int libregf_key_get_utf8_name_size(
564
     libregf_key_t *key,
565
     size_t *utf8_string_size,
566
     libcerror_error_t **error )
567
0
{
568
0
  libregf_internal_key_t *internal_key = NULL;
569
0
  static char *function                = "libregf_key_get_utf8_name_size";
570
0
  int result                           = 1;
571
572
0
  if( key == NULL )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
577
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
578
0
     "%s: invalid key.",
579
0
     function );
580
581
0
    return( -1 );
582
0
  }
583
0
  internal_key = (libregf_internal_key_t *) key;
584
585
0
  if( internal_key->io_handle == NULL )
586
0
  {
587
0
    libcerror_error_set(
588
0
     error,
589
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
590
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
591
0
     "%s: invalid key - missing IO handle.",
592
0
     function );
593
594
0
    return( -1 );
595
0
  }
596
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
597
0
  if( libcthreads_read_write_lock_grab_for_write(
598
0
       internal_key->read_write_lock,
599
0
       error ) != 1 )
600
0
  {
601
0
    libcerror_error_set(
602
0
     error,
603
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
604
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
605
0
     "%s: unable to grab read/write lock for writing.",
606
0
     function );
607
608
0
    return( -1 );
609
0
  }
610
0
#endif
611
0
  if( libregf_key_item_get_utf8_name_size(
612
0
       internal_key->key_item,
613
0
       utf8_string_size,
614
0
       internal_key->io_handle->ascii_codepage,
615
0
       error ) != 1 )
616
0
  {
617
0
    libcerror_error_set(
618
0
     error,
619
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
620
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
621
0
     "%s: unable to retrieve UTF-8 name size.",
622
0
     function );
623
624
0
    result = -1;
625
0
  }
626
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
627
0
  if( libcthreads_read_write_lock_release_for_write(
628
0
       internal_key->read_write_lock,
629
0
       error ) != 1 )
630
0
  {
631
0
    libcerror_error_set(
632
0
     error,
633
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
634
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
635
0
     "%s: unable to release read/write lock for writing.",
636
0
     function );
637
638
0
    return( -1 );
639
0
  }
640
0
#endif
641
0
  return( result );
642
0
}
643
644
/* Retrieves the UTF-8 string value of the key name
645
 * The function uses a codepage if necessary, it uses the codepage set for the library
646
 * The size should include the end of string character
647
 * Returns 1 if successful or -1 on error
648
 */
649
int libregf_key_get_utf8_name(
650
     libregf_key_t *key,
651
     uint8_t *utf8_string,
652
     size_t utf8_string_size,
653
     libcerror_error_t **error )
654
0
{
655
0
  libregf_internal_key_t *internal_key = NULL;
656
0
  static char *function                = "libregf_key_get_utf8_name";
657
0
  int result                           = 1;
658
659
0
  if( key == NULL )
660
0
  {
661
0
    libcerror_error_set(
662
0
     error,
663
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
664
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
665
0
     "%s: invalid key.",
666
0
     function );
667
668
0
    return( -1 );
669
0
  }
670
0
  internal_key = (libregf_internal_key_t *) key;
671
672
0
  if( internal_key->io_handle == NULL )
673
0
  {
674
0
    libcerror_error_set(
675
0
     error,
676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
677
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
678
0
     "%s: invalid key - missing IO handle.",
679
0
     function );
680
681
0
    return( -1 );
682
0
  }
683
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
684
0
  if( libcthreads_read_write_lock_grab_for_write(
685
0
       internal_key->read_write_lock,
686
0
       error ) != 1 )
687
0
  {
688
0
    libcerror_error_set(
689
0
     error,
690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
691
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
692
0
     "%s: unable to grab read/write lock for writing.",
693
0
     function );
694
695
0
    return( -1 );
696
0
  }
697
0
#endif
698
0
  if( libregf_key_item_get_utf8_name(
699
0
       internal_key->key_item,
700
0
       utf8_string,
701
0
       utf8_string_size,
702
0
       internal_key->io_handle->ascii_codepage,
703
0
       error ) != 1 )
704
0
  {
705
0
    libcerror_error_set(
706
0
     error,
707
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
708
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
709
0
     "%s: unable to retrieve UTF-8 name.",
710
0
     function );
711
712
0
    result = -1;
713
0
  }
714
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
715
0
  if( libcthreads_read_write_lock_release_for_write(
716
0
       internal_key->read_write_lock,
717
0
       error ) != 1 )
718
0
  {
719
0
    libcerror_error_set(
720
0
     error,
721
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
722
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
723
0
     "%s: unable to release read/write lock for writing.",
724
0
     function );
725
726
0
    return( -1 );
727
0
  }
728
0
#endif
729
0
  return( result );
730
0
}
731
732
/* Retrieves the UTF-16 string size of the key name
733
 * The returned size includes the end of string character
734
 * Returns 1 if successful or -1 on error
735
 */
736
int libregf_key_get_utf16_name_size(
737
     libregf_key_t *key,
738
     size_t *utf16_string_size,
739
     libcerror_error_t **error )
740
0
{
741
0
  libregf_internal_key_t *internal_key = NULL;
742
0
  static char *function                = "libregf_key_get_utf16_name_size";
743
0
  int result                           = 1;
744
745
0
  if( key == NULL )
746
0
  {
747
0
    libcerror_error_set(
748
0
     error,
749
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
750
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
751
0
     "%s: invalid key.",
752
0
     function );
753
754
0
    return( -1 );
755
0
  }
756
0
  internal_key = (libregf_internal_key_t *) key;
757
758
0
  if( internal_key->io_handle == NULL )
759
0
  {
760
0
    libcerror_error_set(
761
0
     error,
762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
763
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
764
0
     "%s: invalid key - missing IO handle.",
765
0
     function );
766
767
0
    return( -1 );
768
0
  }
769
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
770
0
  if( libcthreads_read_write_lock_grab_for_write(
771
0
       internal_key->read_write_lock,
772
0
       error ) != 1 )
773
0
  {
774
0
    libcerror_error_set(
775
0
     error,
776
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
777
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
778
0
     "%s: unable to grab read/write lock for writing.",
779
0
     function );
780
781
0
    return( -1 );
782
0
  }
783
0
#endif
784
0
  if( libregf_key_item_get_utf16_name_size(
785
0
       internal_key->key_item,
786
0
       utf16_string_size,
787
0
       internal_key->io_handle->ascii_codepage,
788
0
       error ) != 1 )
789
0
  {
790
0
    libcerror_error_set(
791
0
     error,
792
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
793
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
794
0
     "%s: unable to retrieve UTF-16 name size.",
795
0
     function );
796
797
0
    result = -1;
798
0
  }
799
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
800
0
  if( libcthreads_read_write_lock_release_for_write(
801
0
       internal_key->read_write_lock,
802
0
       error ) != 1 )
803
0
  {
804
0
    libcerror_error_set(
805
0
     error,
806
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
807
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
808
0
     "%s: unable to release read/write lock for writing.",
809
0
     function );
810
811
0
    return( -1 );
812
0
  }
813
0
#endif
814
0
  return( result );
815
0
}
816
817
/* Retrieves the UTF-16 string value of the key name
818
 * The function uses a codepage if necessary, it uses the codepage set for the library
819
 * The size should include the end of string character
820
 * Returns 1 if successful or -1 on error
821
 */
822
int libregf_key_get_utf16_name(
823
     libregf_key_t *key,
824
     uint16_t *utf16_string,
825
     size_t utf16_string_size,
826
     libcerror_error_t **error )
827
0
{
828
0
  libregf_internal_key_t *internal_key = NULL;
829
0
  static char *function                = "libregf_value_get_utf16_name";
830
0
  int result                           = 1;
831
832
0
  if( key == NULL )
833
0
  {
834
0
    libcerror_error_set(
835
0
     error,
836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
838
0
     "%s: invalid key.",
839
0
     function );
840
841
0
    return( -1 );
842
0
  }
843
0
  internal_key = (libregf_internal_key_t *) key;
844
845
0
  if( internal_key->io_handle == NULL )
846
0
  {
847
0
    libcerror_error_set(
848
0
     error,
849
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
850
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
851
0
     "%s: invalid key - missing IO handle.",
852
0
     function );
853
854
0
    return( -1 );
855
0
  }
856
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
857
0
  if( libcthreads_read_write_lock_grab_for_write(
858
0
       internal_key->read_write_lock,
859
0
       error ) != 1 )
860
0
  {
861
0
    libcerror_error_set(
862
0
     error,
863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
864
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
865
0
     "%s: unable to grab read/write lock for writing.",
866
0
     function );
867
868
0
    return( -1 );
869
0
  }
870
0
#endif
871
0
  if( libregf_key_item_get_utf16_name(
872
0
       internal_key->key_item,
873
0
       utf16_string,
874
0
       utf16_string_size,
875
0
       internal_key->io_handle->ascii_codepage,
876
0
       error ) != 1 )
877
0
  {
878
0
    libcerror_error_set(
879
0
     error,
880
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
881
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
882
0
     "%s: unable to retrieve UTF-16 name.",
883
0
     function );
884
885
0
    result = -1;
886
0
  }
887
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
888
0
  if( libcthreads_read_write_lock_release_for_write(
889
0
       internal_key->read_write_lock,
890
0
       error ) != 1 )
891
0
  {
892
0
    libcerror_error_set(
893
0
     error,
894
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
895
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
896
0
     "%s: unable to release read/write lock for writing.",
897
0
     function );
898
899
0
    return( -1 );
900
0
  }
901
0
#endif
902
0
  return( result );
903
0
}
904
905
/* Retrieves the class name size
906
 * Returns 1 if successful, 0 if no such value or -1 on error
907
 */
908
int libregf_key_get_class_name_size(
909
     libregf_key_t *key,
910
     size_t *class_name_size,
911
     libcerror_error_t **error )
912
0
{
913
0
  libregf_internal_key_t *internal_key = NULL;
914
0
  static char *function                = "libregf_key_get_class_name_size";
915
0
  int result                           = 0;
916
917
0
  if( key == NULL )
918
0
  {
919
0
    libcerror_error_set(
920
0
     error,
921
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
922
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
923
0
     "%s: invalid key.",
924
0
     function );
925
926
0
    return( -1 );
927
0
  }
928
0
  internal_key = (libregf_internal_key_t *) key;
929
930
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
931
0
  if( libcthreads_read_write_lock_grab_for_write(
932
0
       internal_key->read_write_lock,
933
0
       error ) != 1 )
934
0
  {
935
0
    libcerror_error_set(
936
0
     error,
937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
938
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
939
0
     "%s: unable to grab read/write lock for writing.",
940
0
     function );
941
942
0
    return( -1 );
943
0
  }
944
0
#endif
945
0
  result = libregf_key_item_get_class_name_size(
946
0
            internal_key->key_item,
947
0
            class_name_size,
948
0
            error );
949
950
0
  if( result == -1 )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
955
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
956
0
     "%s: unable to retrieve class name size.",
957
0
     function );
958
959
0
    result = -1;
960
0
  }
961
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
962
0
  if( libcthreads_read_write_lock_release_for_write(
963
0
       internal_key->read_write_lock,
964
0
       error ) != 1 )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
969
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
970
0
     "%s: unable to release read/write lock for writing.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
0
#endif
976
0
  return( result );
977
0
}
978
979
/* Retrieves the class name
980
 * Returns 1 if successful, 0 if no such value or -1 on error
981
 */
982
int libregf_key_get_class_name(
983
     libregf_key_t *key,
984
     uint8_t *class_name,
985
     size_t class_name_size,
986
     libcerror_error_t **error )
987
0
{
988
0
  libregf_internal_key_t *internal_key = NULL;
989
0
  static char *function                = "libregf_key_get_class_name";
990
0
  int result                           = 0;
991
992
0
  if( key == NULL )
993
0
  {
994
0
    libcerror_error_set(
995
0
     error,
996
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
997
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
998
0
     "%s: invalid key.",
999
0
     function );
1000
1001
0
    return( -1 );
1002
0
  }
1003
0
  internal_key = (libregf_internal_key_t *) key;
1004
1005
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1006
0
  if( libcthreads_read_write_lock_grab_for_write(
1007
0
       internal_key->read_write_lock,
1008
0
       error ) != 1 )
1009
0
  {
1010
0
    libcerror_error_set(
1011
0
     error,
1012
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1013
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1014
0
     "%s: unable to grab read/write lock for writing.",
1015
0
     function );
1016
1017
0
    return( -1 );
1018
0
  }
1019
0
#endif
1020
0
  result = libregf_key_item_get_class_name(
1021
0
            internal_key->key_item,
1022
0
            class_name,
1023
0
            class_name_size,
1024
0
            error );
1025
1026
0
  if( result == -1 )
1027
0
  {
1028
0
    libcerror_error_set(
1029
0
     error,
1030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1031
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1032
0
     "%s: unable to retrieve class name.",
1033
0
     function );
1034
1035
0
    result = -1;
1036
0
  }
1037
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1038
0
  if( libcthreads_read_write_lock_release_for_write(
1039
0
       internal_key->read_write_lock,
1040
0
       error ) != 1 )
1041
0
  {
1042
0
    libcerror_error_set(
1043
0
     error,
1044
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1045
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1046
0
     "%s: unable to release read/write lock for writing.",
1047
0
     function );
1048
1049
0
    return( -1 );
1050
0
  }
1051
0
#endif
1052
0
  return( result );
1053
0
}
1054
1055
/* Retrieves the UTF-8 string size of the class name
1056
 * The returned size includes the end of string character
1057
 * Returns 1 if successful, 0 if no such value or -1 on error
1058
 */
1059
int libregf_key_get_utf8_class_name_size(
1060
     libregf_key_t *key,
1061
     size_t *utf8_string_size,
1062
     libcerror_error_t **error )
1063
0
{
1064
0
  libregf_internal_key_t *internal_key = NULL;
1065
0
  static char *function                = "libregf_key_get_utf8_class_name_size";
1066
0
  int result                           = 0;
1067
1068
0
  if( key == NULL )
1069
0
  {
1070
0
    libcerror_error_set(
1071
0
     error,
1072
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1073
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1074
0
     "%s: invalid key.",
1075
0
     function );
1076
1077
0
    return( -1 );
1078
0
  }
1079
0
  internal_key = (libregf_internal_key_t *) key;
1080
1081
0
  if( internal_key->io_handle == NULL )
1082
0
  {
1083
0
    libcerror_error_set(
1084
0
     error,
1085
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1086
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1087
0
     "%s: invalid key - missing IO handle.",
1088
0
     function );
1089
1090
0
    return( -1 );
1091
0
  }
1092
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1093
0
  if( libcthreads_read_write_lock_grab_for_write(
1094
0
       internal_key->read_write_lock,
1095
0
       error ) != 1 )
1096
0
  {
1097
0
    libcerror_error_set(
1098
0
     error,
1099
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1100
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1101
0
     "%s: unable to grab read/write lock for writing.",
1102
0
     function );
1103
1104
0
    return( -1 );
1105
0
  }
1106
0
#endif
1107
0
  result = libregf_key_item_get_utf8_class_name_size(
1108
0
            internal_key->key_item,
1109
0
            utf8_string_size,
1110
0
            internal_key->io_handle->ascii_codepage,
1111
0
            error );
1112
1113
0
  if( result == -1 )
1114
0
  {
1115
0
    libcerror_error_set(
1116
0
     error,
1117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1118
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1119
0
     "%s: unable to retrieve UTF-8 string size.",
1120
0
     function );
1121
1122
0
    result = -1;
1123
0
  }
1124
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1125
0
  if( libcthreads_read_write_lock_release_for_write(
1126
0
       internal_key->read_write_lock,
1127
0
       error ) != 1 )
1128
0
  {
1129
0
    libcerror_error_set(
1130
0
     error,
1131
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1132
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1133
0
     "%s: unable to release read/write lock for writing.",
1134
0
     function );
1135
1136
0
    return( -1 );
1137
0
  }
1138
0
#endif
1139
0
  return( result );
1140
0
}
1141
1142
/* Retrieves the UTF-8 string value of the class name
1143
 * The function uses a codepage if necessary, it uses the codepage set for the library
1144
 * The size should include the end of string character
1145
 * Returns 1 if successful, 0 if no such value or -1 on error
1146
 */
1147
int libregf_key_get_utf8_class_name(
1148
     libregf_key_t *key,
1149
     uint8_t *utf8_string,
1150
     size_t utf8_string_size,
1151
     libcerror_error_t **error )
1152
0
{
1153
0
  libregf_internal_key_t *internal_key = NULL;
1154
0
  static char *function                = "libregf_key_get_utf8_class_name";
1155
0
  int result                           = 0;
1156
1157
0
  if( key == NULL )
1158
0
  {
1159
0
    libcerror_error_set(
1160
0
     error,
1161
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1162
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1163
0
     "%s: invalid key.",
1164
0
     function );
1165
1166
0
    return( -1 );
1167
0
  }
1168
0
  internal_key = (libregf_internal_key_t *) key;
1169
1170
0
  if( internal_key->io_handle == NULL )
1171
0
  {
1172
0
    libcerror_error_set(
1173
0
     error,
1174
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1175
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1176
0
     "%s: invalid key - missing IO handle.",
1177
0
     function );
1178
1179
0
    return( -1 );
1180
0
  }
1181
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1182
0
  if( libcthreads_read_write_lock_grab_for_write(
1183
0
       internal_key->read_write_lock,
1184
0
       error ) != 1 )
1185
0
  {
1186
0
    libcerror_error_set(
1187
0
     error,
1188
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1189
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1190
0
     "%s: unable to grab read/write lock for writing.",
1191
0
     function );
1192
1193
0
    return( -1 );
1194
0
  }
1195
0
#endif
1196
0
  result = libregf_key_item_get_utf8_class_name(
1197
0
            internal_key->key_item,
1198
0
            utf8_string,
1199
0
            utf8_string_size,
1200
0
            internal_key->io_handle->ascii_codepage,
1201
0
            error );
1202
1203
0
  if( result == -1 )
1204
0
  {
1205
0
    libcerror_error_set(
1206
0
     error,
1207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1208
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1209
0
     "%s: unable to retrieve UTF-8 string.",
1210
0
     function );
1211
1212
0
    result = -1;
1213
0
  }
1214
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1215
0
  if( libcthreads_read_write_lock_release_for_write(
1216
0
       internal_key->read_write_lock,
1217
0
       error ) != 1 )
1218
0
  {
1219
0
    libcerror_error_set(
1220
0
     error,
1221
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1222
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1223
0
     "%s: unable to release read/write lock for writing.",
1224
0
     function );
1225
1226
0
    return( -1 );
1227
0
  }
1228
0
#endif
1229
0
  return( result );
1230
0
}
1231
1232
/* Retrieves the UTF-16 string size of the class name
1233
 * The returned size includes the end of string character
1234
 * Returns 1 if successful, 0 if no such value or -1 on error
1235
 */
1236
int libregf_key_get_utf16_class_name_size(
1237
     libregf_key_t *key,
1238
     size_t *utf16_string_size,
1239
     libcerror_error_t **error )
1240
0
{
1241
0
  libregf_internal_key_t *internal_key = NULL;
1242
0
  static char *function                = "libregf_key_get_utf16_class_name_size";
1243
0
  int result                           = 0;
1244
1245
0
  if( key == NULL )
1246
0
  {
1247
0
    libcerror_error_set(
1248
0
     error,
1249
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1250
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1251
0
     "%s: invalid key.",
1252
0
     function );
1253
1254
0
    return( -1 );
1255
0
  }
1256
0
  internal_key = (libregf_internal_key_t *) key;
1257
1258
0
  if( internal_key->io_handle == NULL )
1259
0
  {
1260
0
    libcerror_error_set(
1261
0
     error,
1262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1263
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1264
0
     "%s: invalid key - missing IO handle.",
1265
0
     function );
1266
1267
0
    return( -1 );
1268
0
  }
1269
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1270
0
  if( libcthreads_read_write_lock_grab_for_write(
1271
0
       internal_key->read_write_lock,
1272
0
       error ) != 1 )
1273
0
  {
1274
0
    libcerror_error_set(
1275
0
     error,
1276
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1277
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1278
0
     "%s: unable to grab read/write lock for writing.",
1279
0
     function );
1280
1281
0
    return( -1 );
1282
0
  }
1283
0
#endif
1284
0
  result = libregf_key_item_get_utf16_class_name_size(
1285
0
            internal_key->key_item,
1286
0
            utf16_string_size,
1287
0
            internal_key->io_handle->ascii_codepage,
1288
0
            error );
1289
1290
0
  if( result == -1 )
1291
0
  {
1292
0
    libcerror_error_set(
1293
0
     error,
1294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1295
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1296
0
     "%s: unable to retrieve UTF-16 string size.",
1297
0
     function );
1298
1299
0
    result = -1;
1300
0
  }
1301
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1302
0
  if( libcthreads_read_write_lock_release_for_write(
1303
0
       internal_key->read_write_lock,
1304
0
       error ) != 1 )
1305
0
  {
1306
0
    libcerror_error_set(
1307
0
     error,
1308
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1309
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1310
0
     "%s: unable to release read/write lock for writing.",
1311
0
     function );
1312
1313
0
    return( -1 );
1314
0
  }
1315
0
#endif
1316
0
  return( result );
1317
0
}
1318
1319
/* Retrieves the UTF-16 string value of the class name
1320
 * The function uses a codepage if necessary, it uses the codepage set for the library
1321
 * The size should include the end of string character
1322
 * Returns 1 if successful, 0 if no such value or -1 on error
1323
 */
1324
int libregf_key_get_utf16_class_name(
1325
     libregf_key_t *key,
1326
     uint16_t *utf16_string,
1327
     size_t utf16_string_size,
1328
     libcerror_error_t **error )
1329
0
{
1330
0
  libregf_internal_key_t *internal_key = NULL;
1331
0
  static char *function                = "libregf_value_get_utf16_class_name";
1332
0
  int result                           = 0;
1333
1334
0
  if( key == NULL )
1335
0
  {
1336
0
    libcerror_error_set(
1337
0
     error,
1338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1340
0
     "%s: invalid key.",
1341
0
     function );
1342
1343
0
    return( -1 );
1344
0
  }
1345
0
  internal_key = (libregf_internal_key_t *) key;
1346
1347
0
  if( internal_key->io_handle == NULL )
1348
0
  {
1349
0
    libcerror_error_set(
1350
0
     error,
1351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1352
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1353
0
     "%s: invalid key - missing IO handle.",
1354
0
     function );
1355
1356
0
    return( -1 );
1357
0
  }
1358
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1359
0
  if( libcthreads_read_write_lock_grab_for_write(
1360
0
       internal_key->read_write_lock,
1361
0
       error ) != 1 )
1362
0
  {
1363
0
    libcerror_error_set(
1364
0
     error,
1365
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1366
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1367
0
     "%s: unable to grab read/write lock for writing.",
1368
0
     function );
1369
1370
0
    return( -1 );
1371
0
  }
1372
0
#endif
1373
0
  result = libregf_key_item_get_utf16_class_name(
1374
0
            internal_key->key_item,
1375
0
            utf16_string,
1376
0
            utf16_string_size,
1377
0
            internal_key->io_handle->ascii_codepage,
1378
0
            error );
1379
1380
0
  if( result == -1 )
1381
0
  {
1382
0
    libcerror_error_set(
1383
0
     error,
1384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1385
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1386
0
     "%s: unable to retrieve UTF-16 string.",
1387
0
     function );
1388
1389
0
    result = -1;
1390
0
  }
1391
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1392
0
  if( libcthreads_read_write_lock_release_for_write(
1393
0
       internal_key->read_write_lock,
1394
0
       error ) != 1 )
1395
0
  {
1396
0
    libcerror_error_set(
1397
0
     error,
1398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1399
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1400
0
     "%s: unable to release read/write lock for writing.",
1401
0
     function );
1402
1403
0
    return( -1 );
1404
0
  }
1405
0
#endif
1406
0
  return( result );
1407
0
}
1408
1409
/* Retrieves the 64-bit FILETIME value of the last written date and time
1410
 * Returns 1 if successful or -1 on error
1411
 */
1412
int libregf_key_get_last_written_time(
1413
     libregf_key_t *key,
1414
     uint64_t *filetime,
1415
     libcerror_error_t **error )
1416
0
{
1417
0
  libregf_internal_key_t *internal_key = NULL;
1418
0
  static char *function                = "libregf_key_get_last_written_time";
1419
0
  int result                           = 1;
1420
1421
0
  if( key == NULL )
1422
0
  {
1423
0
    libcerror_error_set(
1424
0
     error,
1425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1427
0
     "%s: invalid key.",
1428
0
     function );
1429
1430
0
    return( -1 );
1431
0
  }
1432
0
  internal_key = (libregf_internal_key_t *) key;
1433
1434
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1435
0
  if( libcthreads_read_write_lock_grab_for_write(
1436
0
       internal_key->read_write_lock,
1437
0
       error ) != 1 )
1438
0
  {
1439
0
    libcerror_error_set(
1440
0
     error,
1441
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1442
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1443
0
     "%s: unable to grab read/write lock for writing.",
1444
0
     function );
1445
1446
0
    return( -1 );
1447
0
  }
1448
0
#endif
1449
0
  if( libregf_key_item_get_last_written_time(
1450
0
       internal_key->key_item,
1451
0
       filetime,
1452
0
       error ) != 1 )
1453
0
  {
1454
0
    libcerror_error_set(
1455
0
     error,
1456
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1457
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1458
0
     "%s: unable to retrieve last written time.",
1459
0
     function );
1460
1461
0
    result = -1;
1462
0
  }
1463
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1464
0
  if( libcthreads_read_write_lock_release_for_write(
1465
0
       internal_key->read_write_lock,
1466
0
       error ) != 1 )
1467
0
  {
1468
0
    libcerror_error_set(
1469
0
     error,
1470
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1471
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1472
0
     "%s: unable to release read/write lock for writing.",
1473
0
     function );
1474
1475
0
    return( -1 );
1476
0
  }
1477
0
#endif
1478
0
  return( result );
1479
0
}
1480
1481
/* Retrieves the security descriptor size
1482
 * Returns 1 if successful, 0 if no such value or -1 on error
1483
 */
1484
int libregf_key_get_security_descriptor_size(
1485
     libregf_key_t *key,
1486
     size_t *security_descriptor_size,
1487
     libcerror_error_t **error )
1488
0
{
1489
0
  libregf_internal_key_t *internal_key = NULL;
1490
0
  static char *function                = "libregf_key_get_security_descriptor_size";
1491
0
  int result                           = 0;
1492
1493
0
  if( key == NULL )
1494
0
  {
1495
0
    libcerror_error_set(
1496
0
     error,
1497
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1498
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1499
0
     "%s: invalid key.",
1500
0
     function );
1501
1502
0
    return( -1 );
1503
0
  }
1504
0
  internal_key = (libregf_internal_key_t *) key;
1505
1506
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1507
0
  if( libcthreads_read_write_lock_grab_for_write(
1508
0
       internal_key->read_write_lock,
1509
0
       error ) != 1 )
1510
0
  {
1511
0
    libcerror_error_set(
1512
0
     error,
1513
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1514
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1515
0
     "%s: unable to grab read/write lock for writing.",
1516
0
     function );
1517
1518
0
    return( -1 );
1519
0
  }
1520
0
#endif
1521
0
  result = libregf_key_item_get_security_descriptor_size(
1522
0
            internal_key->key_item,
1523
0
            security_descriptor_size,
1524
0
            error );
1525
1526
0
  if( result == -1 )
1527
0
  {
1528
0
    libcerror_error_set(
1529
0
     error,
1530
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1531
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1532
0
     "%s: unable to retrieve security descriptor size.",
1533
0
     function );
1534
1535
0
    result = -1;
1536
0
  }
1537
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1538
0
  if( libcthreads_read_write_lock_release_for_write(
1539
0
       internal_key->read_write_lock,
1540
0
       error ) != 1 )
1541
0
  {
1542
0
    libcerror_error_set(
1543
0
     error,
1544
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1545
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1546
0
     "%s: unable to release read/write lock for writing.",
1547
0
     function );
1548
1549
0
    return( -1 );
1550
0
  }
1551
0
#endif
1552
0
  return( result );
1553
0
}
1554
1555
/* Retrieves the security descriptor
1556
 * Returns 1 if successful, 0 if no such value or -1 on error
1557
 */
1558
int libregf_key_get_security_descriptor(
1559
     libregf_key_t *key,
1560
     uint8_t *security_descriptor,
1561
     size_t security_descriptor_size,
1562
     libcerror_error_t **error )
1563
0
{
1564
0
  libregf_internal_key_t *internal_key = NULL;
1565
0
  static char *function                = "libregf_key_get_security_descriptor";
1566
0
  int result                           = 0;
1567
1568
0
  if( key == NULL )
1569
0
  {
1570
0
    libcerror_error_set(
1571
0
     error,
1572
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1573
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1574
0
     "%s: invalid key.",
1575
0
     function );
1576
1577
0
    return( -1 );
1578
0
  }
1579
0
  internal_key = (libregf_internal_key_t *) key;
1580
1581
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1582
0
  if( libcthreads_read_write_lock_grab_for_write(
1583
0
       internal_key->read_write_lock,
1584
0
       error ) != 1 )
1585
0
  {
1586
0
    libcerror_error_set(
1587
0
     error,
1588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1589
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1590
0
     "%s: unable to grab read/write lock for writing.",
1591
0
     function );
1592
1593
0
    return( -1 );
1594
0
  }
1595
0
#endif
1596
0
  result = libregf_key_item_get_security_descriptor(
1597
0
            internal_key->key_item,
1598
0
            security_descriptor,
1599
0
            security_descriptor_size,
1600
0
            error );
1601
1602
0
  if( result == -1 )
1603
0
  {
1604
0
    libcerror_error_set(
1605
0
     error,
1606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1607
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1608
0
     "%s: unable to retrieve security descriptor.",
1609
0
     function );
1610
1611
0
    result = -1;
1612
0
  }
1613
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1614
0
  if( libcthreads_read_write_lock_release_for_write(
1615
0
       internal_key->read_write_lock,
1616
0
       error ) != 1 )
1617
0
  {
1618
0
    libcerror_error_set(
1619
0
     error,
1620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1621
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1622
0
     "%s: unable to release read/write lock for writing.",
1623
0
     function );
1624
1625
0
    return( -1 );
1626
0
  }
1627
0
#endif
1628
0
  return( result );
1629
0
}
1630
1631
/* Retrieves the number of values
1632
 * Returns 1 if successful or -1 on error
1633
 */
1634
int libregf_key_get_number_of_values(
1635
     libregf_key_t *key,
1636
     int *number_of_values,
1637
     libcerror_error_t **error )
1638
0
{
1639
0
  libregf_internal_key_t *internal_key = NULL;
1640
0
  static char *function                = "libregf_key_get_number_of_values";
1641
0
  int result                           = 1;
1642
1643
0
  if( key == NULL )
1644
0
  {
1645
0
    libcerror_error_set(
1646
0
     error,
1647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1648
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1649
0
     "%s: invalid key.",
1650
0
     function );
1651
1652
0
    return( -1 );
1653
0
  }
1654
0
  internal_key = (libregf_internal_key_t *) key;
1655
1656
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1657
0
  if( libcthreads_read_write_lock_grab_for_write(
1658
0
       internal_key->read_write_lock,
1659
0
       error ) != 1 )
1660
0
  {
1661
0
    libcerror_error_set(
1662
0
     error,
1663
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1664
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1665
0
     "%s: unable to grab read/write lock for writing.",
1666
0
     function );
1667
1668
0
    return( -1 );
1669
0
  }
1670
0
#endif
1671
0
  if( libregf_key_item_get_number_of_values(
1672
0
       internal_key->key_item,
1673
0
       number_of_values,
1674
0
       error ) != 1 )
1675
0
  {
1676
0
    libcerror_error_set(
1677
0
     error,
1678
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1679
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1680
0
     "%s: unable to retrieve number of values.",
1681
0
     function );
1682
1683
0
    result = -1;
1684
0
  }
1685
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1686
0
  if( libcthreads_read_write_lock_release_for_write(
1687
0
       internal_key->read_write_lock,
1688
0
       error ) != 1 )
1689
0
  {
1690
0
    libcerror_error_set(
1691
0
     error,
1692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1693
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1694
0
     "%s: unable to release read/write lock for writing.",
1695
0
     function );
1696
1697
0
    return( -1 );
1698
0
  }
1699
0
#endif
1700
0
  return( result );
1701
0
}
1702
1703
/* Retrieves the value
1704
 * Creates a new value
1705
 * Returns 1 if successful or -1 on error
1706
 */
1707
int libregf_internal_key_get_value(
1708
     libregf_internal_key_t *internal_key,
1709
     int value_index,
1710
     libregf_value_t **value,
1711
     libcerror_error_t **error )
1712
0
{
1713
0
  libfdata_list_element_t *values_list_element = NULL;
1714
0
  libregf_value_item_t *value_item             = NULL;
1715
0
  static char *function                        = "libregf_internal_key_get_value";
1716
0
  size64_t size                                = 0;
1717
0
  off64_t offset                               = 0;
1718
0
  uint32_t flags                               = 0;
1719
0
  int file_index                               = 0;
1720
1721
0
  if( internal_key == NULL )
1722
0
  {
1723
0
    libcerror_error_set(
1724
0
     error,
1725
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1726
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1727
0
     "%s: invalid key.",
1728
0
     function );
1729
1730
0
    return( -1 );
1731
0
  }
1732
0
  if( internal_key->key_item == NULL )
1733
0
  {
1734
0
    libcerror_error_set(
1735
0
     error,
1736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1737
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1738
0
     "%s: invalid key - missing key item.",
1739
0
     function );
1740
1741
0
    return( -1 );
1742
0
  }
1743
0
  if( value == NULL )
1744
0
  {
1745
0
    libcerror_error_set(
1746
0
     error,
1747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1749
0
     "%s: invalid value.",
1750
0
     function );
1751
1752
0
    return( -1 );
1753
0
  }
1754
0
  if( *value != NULL )
1755
0
  {
1756
0
    libcerror_error_set(
1757
0
     error,
1758
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1759
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1760
0
     "%s: value already set.",
1761
0
     function );
1762
1763
0
    return( -1 );
1764
0
  }
1765
0
  if( libfdata_list_get_list_element_by_index(
1766
0
       internal_key->key_item->values_list,
1767
0
       value_index,
1768
0
       &values_list_element,
1769
0
       error ) != 1 )
1770
0
  {
1771
0
    libcerror_error_set(
1772
0
     error,
1773
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1774
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1775
0
     "%s: unable to retrieve value: %d.",
1776
0
     function,
1777
0
     value_index );
1778
1779
0
    return( -1 );
1780
0
  }
1781
0
  if( libfdata_list_element_get_data_range(
1782
0
       values_list_element,
1783
0
       &file_index,
1784
0
       &offset,
1785
0
       &size,
1786
0
       &flags,
1787
0
       error ) != 1 )
1788
0
  {
1789
0
    libcerror_error_set(
1790
0
     error,
1791
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1792
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1793
0
     "%s: unable to retrieve value data range.",
1794
0
     function );
1795
1796
0
    return( -1 );
1797
0
  }
1798
  /* The offset is relative from the start of the hive bins list
1799
   * and points to the start of the corresponding hive bin cell
1800
   */
1801
0
  offset += internal_key->io_handle->hive_bins_list_offset + 4;
1802
1803
0
  if( libfdata_list_element_get_element_value(
1804
0
       values_list_element,
1805
0
       (intptr_t *) internal_key->file_io_handle,
1806
0
       (libfdata_cache_t *) internal_key->key_item->values_cache,
1807
0
       (intptr_t **) &value_item,
1808
0
       0,
1809
0
       error ) != 1 )
1810
0
  {
1811
0
    libcerror_error_set(
1812
0
     error,
1813
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1814
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1815
0
     "%s: unable to retrieve value item.",
1816
0
     function );
1817
1818
0
    return( -1 );
1819
0
  }
1820
0
  if( libregf_value_initialize(
1821
0
       value,
1822
0
       internal_key->io_handle,
1823
0
       internal_key->file_io_handle,
1824
0
       offset,
1825
0
       value_item,
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_INITIALIZE_FAILED,
1832
0
     "%s: unable to initialize value.",
1833
0
     function );
1834
1835
0
    return( -1 );
1836
0
  }
1837
0
  return( 1 );
1838
0
}
1839
1840
/* Retrieves the value
1841
 * Creates a new value
1842
 * Returns 1 if successful or -1 on error
1843
 */
1844
int libregf_key_get_value(
1845
     libregf_key_t *key,
1846
     int value_index,
1847
     libregf_value_t **value,
1848
     libcerror_error_t **error )
1849
0
{
1850
0
  libregf_internal_key_t *internal_key = NULL;
1851
0
  static char *function                = "libregf_key_get_value";
1852
0
  int result                           = 1;
1853
1854
0
  if( key == NULL )
1855
0
  {
1856
0
    libcerror_error_set(
1857
0
     error,
1858
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1859
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1860
0
     "%s: invalid key.",
1861
0
     function );
1862
1863
0
    return( -1 );
1864
0
  }
1865
0
  internal_key = (libregf_internal_key_t *) key;
1866
1867
0
  if( value == NULL )
1868
0
  {
1869
0
    libcerror_error_set(
1870
0
     error,
1871
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1872
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1873
0
     "%s: invalid value.",
1874
0
     function );
1875
1876
0
    return( -1 );
1877
0
  }
1878
0
  if( *value != NULL )
1879
0
  {
1880
0
    libcerror_error_set(
1881
0
     error,
1882
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1883
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1884
0
     "%s: value already set.",
1885
0
     function );
1886
1887
0
    return( -1 );
1888
0
  }
1889
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1890
0
  if( libcthreads_read_write_lock_grab_for_write(
1891
0
       internal_key->read_write_lock,
1892
0
       error ) != 1 )
1893
0
  {
1894
0
    libcerror_error_set(
1895
0
     error,
1896
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1897
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1898
0
     "%s: unable to grab read/write lock for writing.",
1899
0
     function );
1900
1901
0
    return( -1 );
1902
0
  }
1903
0
#endif
1904
0
  if( libregf_internal_key_get_value(
1905
0
       internal_key,
1906
0
       value_index,
1907
0
       value,
1908
0
       error ) != 1 )
1909
0
  {
1910
0
    libcerror_error_set(
1911
0
     error,
1912
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1913
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1914
0
     "%s: unable to retrieve value: %d.",
1915
0
     function,
1916
0
     value_index );
1917
1918
0
    result = -1;
1919
0
  }
1920
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1921
0
  if( libcthreads_read_write_lock_release_for_write(
1922
0
       internal_key->read_write_lock,
1923
0
       error ) != 1 )
1924
0
  {
1925
0
    libcerror_error_set(
1926
0
     error,
1927
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1928
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1929
0
     "%s: unable to release read/write lock for writing.",
1930
0
     function );
1931
1932
0
    return( -1 );
1933
0
  }
1934
0
#endif
1935
0
  return( result );
1936
0
}
1937
1938
/* Retrieves the value
1939
 * Creates a new value
1940
 * Returns 1 if successful or -1 on error
1941
 */
1942
int libregf_key_get_value_by_index(
1943
     libregf_key_t *key,
1944
     int value_index,
1945
     libregf_value_t **value,
1946
     libcerror_error_t **error )
1947
0
{
1948
0
  libregf_internal_key_t *internal_key = NULL;
1949
0
  static char *function                = "libregf_key_get_value_by_index";
1950
0
  int result                           = 1;
1951
1952
0
  if( key == NULL )
1953
0
  {
1954
0
    libcerror_error_set(
1955
0
     error,
1956
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1957
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1958
0
     "%s: invalid key.",
1959
0
     function );
1960
1961
0
    return( -1 );
1962
0
  }
1963
0
  internal_key = (libregf_internal_key_t *) key;
1964
1965
0
  if( value == NULL )
1966
0
  {
1967
0
    libcerror_error_set(
1968
0
     error,
1969
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1970
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1971
0
     "%s: invalid value.",
1972
0
     function );
1973
1974
0
    return( -1 );
1975
0
  }
1976
0
  if( *value != NULL )
1977
0
  {
1978
0
    libcerror_error_set(
1979
0
     error,
1980
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1981
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1982
0
     "%s: value already set.",
1983
0
     function );
1984
1985
0
    return( -1 );
1986
0
  }
1987
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1988
0
  if( libcthreads_read_write_lock_grab_for_write(
1989
0
       internal_key->read_write_lock,
1990
0
       error ) != 1 )
1991
0
  {
1992
0
    libcerror_error_set(
1993
0
     error,
1994
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1995
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1996
0
     "%s: unable to grab read/write lock for writing.",
1997
0
     function );
1998
1999
0
    return( -1 );
2000
0
  }
2001
0
#endif
2002
0
  if( libregf_internal_key_get_value(
2003
0
       internal_key,
2004
0
       value_index,
2005
0
       value,
2006
0
       error ) != 1 )
2007
0
  {
2008
0
    libcerror_error_set(
2009
0
     error,
2010
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2011
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2012
0
     "%s: unable to retrieve value: %d.",
2013
0
     function,
2014
0
     value_index );
2015
2016
0
    result = -1;
2017
0
  }
2018
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2019
0
  if( libcthreads_read_write_lock_release_for_write(
2020
0
       internal_key->read_write_lock,
2021
0
       error ) != 1 )
2022
0
  {
2023
0
    libcerror_error_set(
2024
0
     error,
2025
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2026
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2027
0
     "%s: unable to release read/write lock for writing.",
2028
0
     function );
2029
2030
0
    return( -1 );
2031
0
  }
2032
0
#endif
2033
0
  return( result );
2034
0
}
2035
2036
/* Retrieves the value for the specific UTF-8 encoded name
2037
 * To retrieve the default value specify value name as NULL and its length as 0
2038
 * Creates a new value
2039
 * Returns 1 if successful, 0 if no such value or -1 on error
2040
 */
2041
int libregf_internal_key_get_value_by_utf8_name(
2042
     libregf_internal_key_t *internal_key,
2043
     const uint8_t *utf8_string,
2044
     size_t utf8_string_length,
2045
     libregf_value_t **value,
2046
     libcerror_error_t **error )
2047
0
{
2048
0
  libfdata_list_element_t *values_list_element = NULL;
2049
0
  libregf_value_item_t *value_item             = NULL;
2050
0
  static char *function                        = "libregf_internal_key_get_value_by_utf8_name";
2051
0
  libuna_unicode_character_t unicode_character = 0;
2052
0
  size64_t size                                = 0;
2053
0
  size_t utf8_string_index                     = 0;
2054
0
  off64_t offset                               = 0;
2055
0
  uint32_t flags                               = 0;
2056
0
  uint32_t name_hash                           = 0;
2057
0
  int file_index                               = 0;
2058
0
  int number_of_values                         = 0;
2059
0
  int result                                   = 0;
2060
0
  int value_index                              = 0;
2061
2062
0
  if( internal_key == NULL )
2063
0
  {
2064
0
    libcerror_error_set(
2065
0
     error,
2066
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2067
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2068
0
     "%s: invalid key.",
2069
0
     function );
2070
2071
0
    return( -1 );
2072
0
  }
2073
0
  if( internal_key->io_handle == NULL )
2074
0
  {
2075
0
    libcerror_error_set(
2076
0
     error,
2077
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2078
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2079
0
     "%s: invalid key - missing IO handle.",
2080
0
     function );
2081
2082
0
    return( -1 );
2083
0
  }
2084
0
  if( internal_key->key_item == NULL )
2085
0
  {
2086
0
    libcerror_error_set(
2087
0
     error,
2088
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2089
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2090
0
     "%s: invalid key - missing key item.",
2091
0
     function );
2092
2093
0
    return( -1 );
2094
0
  }
2095
0
  if( ( utf8_string == NULL )
2096
0
   && ( utf8_string_length != 0 ) )
2097
0
  {
2098
0
    libcerror_error_set(
2099
0
     error,
2100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2102
0
     "%s: invalid UTF-8 string.",
2103
0
     function );
2104
2105
0
    return( -1 );
2106
0
  }
2107
0
  if( utf8_string_length > (size_t) SSIZE_MAX )
2108
0
  {
2109
0
    libcerror_error_set(
2110
0
     error,
2111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2112
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2113
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
2114
0
     function );
2115
2116
0
    return( -1 );
2117
0
  }
2118
0
  if( value == NULL )
2119
0
  {
2120
0
    libcerror_error_set(
2121
0
     error,
2122
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2123
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2124
0
     "%s: invalid value.",
2125
0
     function );
2126
2127
0
    return( -1 );
2128
0
  }
2129
0
  if( *value != NULL )
2130
0
  {
2131
0
    libcerror_error_set(
2132
0
     error,
2133
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2134
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2135
0
     "%s: value already set.",
2136
0
     function );
2137
2138
0
    return( -1 );
2139
0
  }
2140
0
  if( libregf_key_item_get_number_of_values(
2141
0
       internal_key->key_item,
2142
0
       &number_of_values,
2143
0
       error ) != 1 )
2144
0
  {
2145
0
    libcerror_error_set(
2146
0
     error,
2147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2148
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2149
0
     "%s: unable to retrieve number of values.",
2150
0
     function );
2151
2152
0
    return( -1 );
2153
0
  }
2154
0
  if( number_of_values == 0 )
2155
0
  {
2156
0
    return( 0 );
2157
0
  }
2158
0
  while( utf8_string_index < utf8_string_length )
2159
0
  {
2160
0
    if( libuna_unicode_character_copy_from_utf8(
2161
0
         &unicode_character,
2162
0
         utf8_string,
2163
0
         utf8_string_length,
2164
0
         &utf8_string_index,
2165
0
         error ) != 1 )
2166
0
    {
2167
0
      libcerror_error_set(
2168
0
       error,
2169
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2170
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2171
0
       "%s: unable to copy UTF-8 string to Unicode character.",
2172
0
       function );
2173
2174
0
      return( -1 );
2175
0
    }
2176
0
    name_hash *= 37;
2177
0
    name_hash += (uint32_t) towupper( (wint_t) unicode_character );
2178
0
  }
2179
0
  for( value_index = 0;
2180
0
       value_index < number_of_values;
2181
0
       value_index++ )
2182
0
  {
2183
0
    if( libfdata_list_get_list_element_by_index(
2184
0
         internal_key->key_item->values_list,
2185
0
         value_index,
2186
0
         &values_list_element,
2187
0
         error ) != 1 )
2188
0
    {
2189
0
      libcerror_error_set(
2190
0
       error,
2191
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2192
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2193
0
       "%s: unable to retrieve value item: %d.",
2194
0
       function,
2195
0
       value_index );
2196
2197
0
      return( -1 );
2198
0
    }
2199
0
    if( libfdata_list_element_get_element_value(
2200
0
         values_list_element,
2201
0
         (intptr_t *) internal_key->file_io_handle,
2202
0
         (libfdata_cache_t *) internal_key->key_item->values_cache,
2203
0
         (intptr_t **) &value_item,
2204
0
         0,
2205
0
         error ) != 1 )
2206
0
    {
2207
0
      libcerror_error_set(
2208
0
       error,
2209
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2210
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2211
0
       "%s: unable to retrieve value item: %d values.",
2212
0
       function,
2213
0
       value_index );
2214
2215
0
      return( -1 );
2216
0
    }
2217
0
    result = libregf_value_item_compare_name_with_utf8_string(
2218
0
        value_item,
2219
0
        name_hash,
2220
0
        utf8_string,
2221
0
        utf8_string_length,
2222
0
        internal_key->io_handle->ascii_codepage,
2223
0
        error );
2224
2225
0
    if( result == -1 )
2226
0
    {
2227
0
      libcerror_error_set(
2228
0
       error,
2229
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2230
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2231
0
       "%s: unable to compare value name with UTF-8 string.",
2232
0
       function );
2233
2234
0
      return( -1 );
2235
0
    }
2236
0
    else if( result != 0 )
2237
0
    {
2238
0
      break;
2239
0
    }
2240
0
  }
2241
0
  if( value_index >= number_of_values )
2242
0
  {
2243
0
    return( 0 );
2244
0
  }
2245
0
  if( libfdata_list_element_get_data_range(
2246
0
       values_list_element,
2247
0
       &file_index,
2248
0
       &offset,
2249
0
       &size,
2250
0
       &flags,
2251
0
       error ) != 1 )
2252
0
  {
2253
0
    libcerror_error_set(
2254
0
     error,
2255
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2256
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2257
0
     "%s: unable to retrieve value data range.",
2258
0
     function );
2259
2260
0
    return( -1 );
2261
0
  }
2262
  /* The offset is relative from the start of the hive bins list
2263
   * and points to the start of the corresponding hive bin cell
2264
   */
2265
0
  offset += internal_key->io_handle->hive_bins_list_offset + 4;
2266
2267
0
  if( libregf_value_initialize(
2268
0
       value,
2269
0
       internal_key->io_handle,
2270
0
       internal_key->file_io_handle,
2271
0
       offset,
2272
0
       value_item,
2273
0
       error ) != 1 )
2274
0
  {
2275
0
    libcerror_error_set(
2276
0
     error,
2277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2278
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2279
0
     "%s: unable to initialize value.",
2280
0
     function );
2281
2282
0
    return( -1 );
2283
0
  }
2284
0
  return( 1 );
2285
0
}
2286
2287
/* Retrieves the value for the specific UTF-8 encoded name
2288
 * To retrieve the default value specify value name as NULL and its length as 0
2289
 * Creates a new value
2290
 * Returns 1 if successful, 0 if no such value or -1 on error
2291
 */
2292
int libregf_key_get_value_by_utf8_name(
2293
     libregf_key_t *key,
2294
     const uint8_t *utf8_string,
2295
     size_t utf8_string_length,
2296
     libregf_value_t **value,
2297
     libcerror_error_t **error )
2298
0
{
2299
0
  libregf_internal_key_t *internal_key = NULL;
2300
0
  static char *function                = "libregf_key_get_value_by_utf8_name";
2301
0
  int result                           = 0;
2302
2303
0
  if( key == NULL )
2304
0
  {
2305
0
    libcerror_error_set(
2306
0
     error,
2307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2309
0
     "%s: invalid key.",
2310
0
     function );
2311
2312
0
    return( -1 );
2313
0
  }
2314
0
  internal_key = (libregf_internal_key_t *) key;
2315
2316
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2317
0
  if( libcthreads_read_write_lock_grab_for_write(
2318
0
       internal_key->read_write_lock,
2319
0
       error ) != 1 )
2320
0
  {
2321
0
    libcerror_error_set(
2322
0
     error,
2323
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2324
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2325
0
     "%s: unable to grab read/write lock for writing.",
2326
0
     function );
2327
2328
0
    return( -1 );
2329
0
  }
2330
0
#endif
2331
0
  result = libregf_internal_key_get_value_by_utf8_name(
2332
0
            internal_key,
2333
0
            utf8_string,
2334
0
            utf8_string_length,
2335
0
            value,
2336
0
            error );
2337
2338
0
  if( result == -1 )
2339
0
  {
2340
0
    libcerror_error_set(
2341
0
     error,
2342
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2343
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2344
0
     "%s: unable to retrieve key by UTF-8 name.",
2345
0
     function );
2346
2347
0
    result = -1;
2348
0
  }
2349
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2350
0
  if( libcthreads_read_write_lock_release_for_write(
2351
0
       internal_key->read_write_lock,
2352
0
       error ) != 1 )
2353
0
  {
2354
0
    libcerror_error_set(
2355
0
     error,
2356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2357
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2358
0
     "%s: unable to release read/write lock for writing.",
2359
0
     function );
2360
2361
0
    return( -1 );
2362
0
  }
2363
0
#endif
2364
0
  return( result );
2365
0
}
2366
2367
/* Retrieves the value for the specific UTF-16 encoded name
2368
 * To retrieve the default value specify string as NULL and its length as 0
2369
 * Creates a new value
2370
 * Returns 1 if successful, 0 if no such value or -1 on error
2371
 */
2372
int libregf_internal_key_get_value_by_utf16_name(
2373
     libregf_internal_key_t *internal_key,
2374
     const uint16_t *utf16_string,
2375
     size_t utf16_string_length,
2376
     libregf_value_t **value,
2377
     libcerror_error_t **error )
2378
0
{
2379
0
  libfdata_list_element_t *values_list_element = NULL;
2380
0
  libregf_value_item_t *value_item             = NULL;
2381
0
  static char *function                        = "libregf_internal_key_get_value_by_utf16_name";
2382
0
  libuna_unicode_character_t unicode_character = 0;
2383
0
  size64_t size                                = 0;
2384
0
  size_t utf16_string_index                    = 0;
2385
0
  off64_t offset                               = 0;
2386
0
  uint32_t flags                               = 0;
2387
0
  uint32_t name_hash                           = 0;
2388
0
  int file_index                               = 0;
2389
0
  int number_of_values                         = 0;
2390
0
  int result                                   = 0;
2391
0
  int value_index                              = 0;
2392
2393
0
  if( internal_key == NULL )
2394
0
  {
2395
0
    libcerror_error_set(
2396
0
     error,
2397
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2398
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2399
0
     "%s: invalid key.",
2400
0
     function );
2401
2402
0
    return( -1 );
2403
0
  }
2404
0
  if( internal_key->io_handle == NULL )
2405
0
  {
2406
0
    libcerror_error_set(
2407
0
     error,
2408
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2409
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2410
0
     "%s: invalid key - missing IO handle.",
2411
0
     function );
2412
2413
0
    return( -1 );
2414
0
  }
2415
0
  if( internal_key->key_item == NULL )
2416
0
  {
2417
0
    libcerror_error_set(
2418
0
     error,
2419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2420
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2421
0
     "%s: invalid key - missing key item.",
2422
0
     function );
2423
2424
0
    return( -1 );
2425
0
  }
2426
0
  if( ( utf16_string == NULL )
2427
0
   && ( utf16_string_length != 0 ) )
2428
0
  {
2429
0
    libcerror_error_set(
2430
0
     error,
2431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2433
0
     "%s: invalid UTF-16 string.",
2434
0
     function );
2435
2436
0
    return( -1 );
2437
0
  }
2438
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
2439
0
  {
2440
0
    libcerror_error_set(
2441
0
     error,
2442
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2443
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2444
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
2445
0
     function );
2446
2447
0
    return( -1 );
2448
0
  }
2449
0
  if( value == NULL )
2450
0
  {
2451
0
    libcerror_error_set(
2452
0
     error,
2453
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2454
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2455
0
     "%s: invalid value.",
2456
0
     function );
2457
2458
0
    return( -1 );
2459
0
  }
2460
0
  if( *value != NULL )
2461
0
  {
2462
0
    libcerror_error_set(
2463
0
     error,
2464
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2465
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2466
0
     "%s: value already set.",
2467
0
     function );
2468
2469
0
    return( -1 );
2470
0
  }
2471
0
  if( libregf_key_item_get_number_of_values(
2472
0
       internal_key->key_item,
2473
0
       &number_of_values,
2474
0
       error ) != 1 )
2475
0
  {
2476
0
    libcerror_error_set(
2477
0
     error,
2478
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2479
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2480
0
     "%s: unable to retrieve number of values.",
2481
0
     function );
2482
2483
0
    return( -1 );
2484
0
  }
2485
0
  if( number_of_values == 0 )
2486
0
  {
2487
0
    return( 0 );
2488
0
  }
2489
0
  while( utf16_string_index < utf16_string_length )
2490
0
  {
2491
0
    if( libuna_unicode_character_copy_from_utf16(
2492
0
         &unicode_character,
2493
0
         utf16_string,
2494
0
         utf16_string_length,
2495
0
         &utf16_string_index,
2496
0
         error ) != 1 )
2497
0
    {
2498
0
      libcerror_error_set(
2499
0
       error,
2500
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2501
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2502
0
       "%s: unable to copy UTF-16 string to Unicode character.",
2503
0
       function );
2504
2505
0
      return( -1 );
2506
0
    }
2507
0
    name_hash *= 37;
2508
0
    name_hash += (uint32_t) towupper( (wint_t) unicode_character );
2509
0
  }
2510
0
  for( value_index = 0;
2511
0
       value_index < number_of_values;
2512
0
       value_index++ )
2513
0
  {
2514
0
    if( libfdata_list_get_list_element_by_index(
2515
0
         internal_key->key_item->values_list,
2516
0
         value_index,
2517
0
         &values_list_element,
2518
0
         error ) != 1 )
2519
0
    {
2520
0
      libcerror_error_set(
2521
0
       error,
2522
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2523
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2524
0
       "%s: unable to retrieve value item: %d.",
2525
0
       function,
2526
0
       value_index );
2527
2528
0
      return( -1 );
2529
0
    }
2530
0
    if( libfdata_list_element_get_element_value(
2531
0
         values_list_element,
2532
0
         (intptr_t *) internal_key->file_io_handle,
2533
0
         (libfdata_cache_t *) internal_key->key_item->values_cache,
2534
0
         (intptr_t **) &value_item,
2535
0
         0,
2536
0
         error ) != 1 )
2537
0
    {
2538
0
      libcerror_error_set(
2539
0
       error,
2540
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2541
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2542
0
       "%s: unable to retrieve value item: %d values.",
2543
0
       function,
2544
0
       value_index );
2545
2546
0
      return( -1 );
2547
0
    }
2548
0
    result = libregf_value_item_compare_name_with_utf16_string(
2549
0
        value_item,
2550
0
        name_hash,
2551
0
        utf16_string,
2552
0
        utf16_string_length,
2553
0
        internal_key->io_handle->ascii_codepage,
2554
0
        error );
2555
2556
0
    if( result == -1 )
2557
0
    {
2558
0
      libcerror_error_set(
2559
0
       error,
2560
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2561
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2562
0
       "%s: unable to compare value name with UTF-16 string.",
2563
0
       function );
2564
2565
0
      return( -1 );
2566
0
    }
2567
0
    else if( result != 0 )
2568
0
    {
2569
0
      break;
2570
0
    }
2571
0
  }
2572
0
  if( value_index >= number_of_values )
2573
0
  {
2574
0
    return( 0 );
2575
0
  }
2576
0
  if( libfdata_list_element_get_data_range(
2577
0
       values_list_element,
2578
0
       &file_index,
2579
0
       &offset,
2580
0
       &size,
2581
0
       &flags,
2582
0
       error ) != 1 )
2583
0
  {
2584
0
    libcerror_error_set(
2585
0
     error,
2586
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2587
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2588
0
     "%s: unable to retrieve value data range.",
2589
0
     function );
2590
2591
0
    return( -1 );
2592
0
  }
2593
  /* The offset is relative from the start of the hive bins list
2594
   * and points to the start of the corresponding hive bin cell
2595
   */
2596
0
  offset += internal_key->io_handle->hive_bins_list_offset + 4;
2597
2598
0
  if( libregf_value_initialize(
2599
0
       value,
2600
0
       internal_key->io_handle,
2601
0
       internal_key->file_io_handle,
2602
0
       offset,
2603
0
       value_item,
2604
0
       error ) != 1 )
2605
0
  {
2606
0
    libcerror_error_set(
2607
0
     error,
2608
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2609
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2610
0
     "%s: unable to initialize value.",
2611
0
     function );
2612
2613
0
    return( -1 );
2614
0
  }
2615
0
  return( 1 );
2616
0
}
2617
2618
/* Retrieves the value for the specific UTF-16 encoded name
2619
 * To retrieve the default value specify value name as NULL and its length as 0
2620
 * Creates a new value
2621
 * Returns 1 if successful, 0 if no such value or -1 on error
2622
 */
2623
int libregf_key_get_value_by_utf16_name(
2624
     libregf_key_t *key,
2625
     const uint16_t *utf16_string,
2626
     size_t utf16_string_length,
2627
     libregf_value_t **value,
2628
     libcerror_error_t **error )
2629
0
{
2630
0
  libregf_internal_key_t *internal_key = NULL;
2631
0
  static char *function                = "libregf_key_get_value_by_utf16_name";
2632
0
  int result                           = 0;
2633
2634
0
  if( key == NULL )
2635
0
  {
2636
0
    libcerror_error_set(
2637
0
     error,
2638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2639
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2640
0
     "%s: invalid key.",
2641
0
     function );
2642
2643
0
    return( -1 );
2644
0
  }
2645
0
  internal_key = (libregf_internal_key_t *) key;
2646
2647
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2648
0
  if( libcthreads_read_write_lock_grab_for_write(
2649
0
       internal_key->read_write_lock,
2650
0
       error ) != 1 )
2651
0
  {
2652
0
    libcerror_error_set(
2653
0
     error,
2654
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2655
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2656
0
     "%s: unable to grab read/write lock for writing.",
2657
0
     function );
2658
2659
0
    return( -1 );
2660
0
  }
2661
0
#endif
2662
0
  result = libregf_internal_key_get_value_by_utf16_name(
2663
0
            internal_key,
2664
0
            utf16_string,
2665
0
            utf16_string_length,
2666
0
            value,
2667
0
            error );
2668
2669
0
  if( result == -1 )
2670
0
  {
2671
0
    libcerror_error_set(
2672
0
     error,
2673
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2674
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2675
0
     "%s: unable to retrieve key by UTF-16 name.",
2676
0
     function );
2677
2678
0
    result = -1;
2679
0
  }
2680
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2681
0
  if( libcthreads_read_write_lock_release_for_write(
2682
0
       internal_key->read_write_lock,
2683
0
       error ) != 1 )
2684
0
  {
2685
0
    libcerror_error_set(
2686
0
     error,
2687
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2688
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2689
0
     "%s: unable to release read/write lock for writing.",
2690
0
     function );
2691
2692
0
    return( -1 );
2693
0
  }
2694
0
#endif
2695
0
  return( result );
2696
0
}
2697
2698
/* Retrieves the number of sub keys
2699
 * Returns 1 if successful or -1 on error
2700
 */
2701
int libregf_key_get_number_of_sub_keys(
2702
     libregf_key_t *key,
2703
     int *number_of_sub_keys,
2704
     libcerror_error_t **error )
2705
104
{
2706
104
  libregf_internal_key_t *internal_key = NULL;
2707
104
  static char *function                = "libregf_key_get_number_of_sub_keys";
2708
104
  int result                           = 1;
2709
2710
104
  if( key == NULL )
2711
0
  {
2712
0
    libcerror_error_set(
2713
0
     error,
2714
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2715
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2716
0
     "%s: invalid key.",
2717
0
     function );
2718
2719
0
    return( -1 );
2720
0
  }
2721
104
  internal_key = (libregf_internal_key_t *) key;
2722
2723
104
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2724
104
  if( libcthreads_read_write_lock_grab_for_write(
2725
104
       internal_key->read_write_lock,
2726
104
       error ) != 1 )
2727
0
  {
2728
0
    libcerror_error_set(
2729
0
     error,
2730
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2731
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2732
0
     "%s: unable to grab read/write lock for writing.",
2733
0
     function );
2734
2735
0
    return( -1 );
2736
0
  }
2737
104
#endif
2738
104
  if( libregf_key_item_get_number_of_sub_key_descriptors(
2739
104
       internal_key->key_item,
2740
104
       number_of_sub_keys,
2741
104
       error ) != 1 )
2742
0
  {
2743
0
    libcerror_error_set(
2744
0
     error,
2745
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2746
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2747
0
     "%s: unable to retrieve number of sub key descriptors.",
2748
0
     function );
2749
2750
0
    result = -1;
2751
0
  }
2752
104
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2753
104
  if( libcthreads_read_write_lock_release_for_write(
2754
104
       internal_key->read_write_lock,
2755
104
       error ) != 1 )
2756
0
  {
2757
0
    libcerror_error_set(
2758
0
     error,
2759
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2760
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2761
0
     "%s: unable to release read/write lock for writing.",
2762
0
     function );
2763
2764
0
    return( -1 );
2765
0
  }
2766
104
#endif
2767
104
  return( result );
2768
104
}
2769
2770
/* Retrieves a specific sub key
2771
 * Creates a new key
2772
 * Returns 1 if successful or -1 on error
2773
 */
2774
int libregf_key_get_sub_key(
2775
     libregf_key_t *key,
2776
     int sub_key_index,
2777
     libregf_key_t **sub_key,
2778
     libcerror_error_t **error )
2779
88
{
2780
88
  libregf_internal_key_t *internal_key         = NULL;
2781
88
  libregf_key_descriptor_t *sub_key_descriptor = NULL;
2782
88
  static char *function                        = "libregf_key_get_sub_key";
2783
88
  int result                                   = 1;
2784
2785
88
  if( key == NULL )
2786
0
  {
2787
0
    libcerror_error_set(
2788
0
     error,
2789
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2790
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2791
0
     "%s: invalid key.",
2792
0
     function );
2793
2794
0
    return( -1 );
2795
0
  }
2796
88
  internal_key = (libregf_internal_key_t *) key;
2797
2798
88
  if( sub_key == NULL )
2799
0
  {
2800
0
    libcerror_error_set(
2801
0
     error,
2802
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2803
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2804
0
     "%s: invalid sub key.",
2805
0
     function );
2806
2807
0
    return( -1 );
2808
0
  }
2809
88
  if( *sub_key != NULL )
2810
0
  {
2811
0
    libcerror_error_set(
2812
0
     error,
2813
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2814
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2815
0
     "%s: sub key already set.",
2816
0
     function );
2817
2818
0
    return( -1 );
2819
0
  }
2820
88
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2821
88
  if( libcthreads_read_write_lock_grab_for_write(
2822
88
       internal_key->read_write_lock,
2823
88
       error ) != 1 )
2824
0
  {
2825
0
    libcerror_error_set(
2826
0
     error,
2827
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2828
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2829
0
     "%s: unable to grab read/write lock for writing.",
2830
0
     function );
2831
2832
0
    return( -1 );
2833
0
  }
2834
88
#endif
2835
88
  if( libregf_key_item_get_sub_key_descriptor_by_index(
2836
88
       internal_key->key_item,
2837
88
             sub_key_index,
2838
88
       &sub_key_descriptor,
2839
88
       error ) != 1 )
2840
0
  {
2841
0
    libcerror_error_set(
2842
0
     error,
2843
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2844
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2845
0
     "%s: unable to retrieve sub key: %d descriptor.",
2846
0
     function,
2847
0
     sub_key_index );
2848
2849
0
    result = -1;
2850
0
  }
2851
88
  else if( sub_key_descriptor == NULL )
2852
0
  {
2853
0
    libcerror_error_set(
2854
0
     error,
2855
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2856
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2857
0
     "%s: invalid sub key: %d descriptor.",
2858
0
     function,
2859
0
     sub_key_index );
2860
2861
0
    result = -1;
2862
0
  }
2863
88
  else if( libregf_key_initialize(
2864
88
            sub_key,
2865
88
            internal_key->io_handle,
2866
88
            internal_key->file_io_handle,
2867
88
            sub_key_descriptor->key_offset,
2868
88
            internal_key->hive_bins_list,
2869
88
            error ) != 1 )
2870
61
  {
2871
61
    libcerror_error_set(
2872
61
     error,
2873
61
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2874
61
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2875
61
     "%s: unable to initialize sub key: %d.",
2876
61
     function,
2877
61
     sub_key_index );
2878
2879
61
    result = -1;
2880
61
  }
2881
88
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2882
88
  if( libcthreads_read_write_lock_release_for_write(
2883
88
       internal_key->read_write_lock,
2884
88
       error ) != 1 )
2885
0
  {
2886
0
    libcerror_error_set(
2887
0
     error,
2888
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2889
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2890
0
     "%s: unable to release read/write lock for writing.",
2891
0
     function );
2892
2893
0
    return( -1 );
2894
0
  }
2895
88
#endif
2896
88
  return( result );
2897
88
}
2898
2899
/* Retrieves a specific sub key
2900
 * Creates a new key
2901
 * Returns 1 if successful or -1 on error
2902
 */
2903
int libregf_key_get_sub_key_by_index(
2904
     libregf_key_t *key,
2905
     int sub_key_index,
2906
     libregf_key_t **sub_key,
2907
     libcerror_error_t **error )
2908
0
{
2909
0
  libregf_internal_key_t *internal_key         = NULL;
2910
0
  libregf_key_descriptor_t *sub_key_descriptor = NULL;
2911
0
  static char *function                        = "libregf_key_get_sub_key_by_index";
2912
0
  int result                                   = 1;
2913
2914
0
  if( key == NULL )
2915
0
  {
2916
0
    libcerror_error_set(
2917
0
     error,
2918
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2919
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2920
0
     "%s: invalid key.",
2921
0
     function );
2922
2923
0
    return( -1 );
2924
0
  }
2925
0
  internal_key = (libregf_internal_key_t *) key;
2926
2927
0
  if( sub_key == NULL )
2928
0
  {
2929
0
    libcerror_error_set(
2930
0
     error,
2931
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2932
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2933
0
     "%s: invalid sub key.",
2934
0
     function );
2935
2936
0
    return( -1 );
2937
0
  }
2938
0
  if( *sub_key != NULL )
2939
0
  {
2940
0
    libcerror_error_set(
2941
0
     error,
2942
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2943
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2944
0
     "%s: sub key already set.",
2945
0
     function );
2946
2947
0
    return( -1 );
2948
0
  }
2949
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
2950
0
  if( libcthreads_read_write_lock_grab_for_write(
2951
0
       internal_key->read_write_lock,
2952
0
       error ) != 1 )
2953
0
  {
2954
0
    libcerror_error_set(
2955
0
     error,
2956
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2957
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2958
0
     "%s: unable to grab read/write lock for writing.",
2959
0
     function );
2960
2961
0
    return( -1 );
2962
0
  }
2963
0
#endif
2964
0
  if( libregf_key_item_get_sub_key_descriptor_by_index(
2965
0
       internal_key->key_item,
2966
0
             sub_key_index,
2967
0
       &sub_key_descriptor,
2968
0
       error ) != 1 )
2969
0
  {
2970
0
    libcerror_error_set(
2971
0
     error,
2972
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2973
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2974
0
     "%s: unable to retrieve sub key: %d descriptor.",
2975
0
     function,
2976
0
     sub_key_index );
2977
2978
0
    result = -1;
2979
0
  }
2980
0
  else if( sub_key_descriptor == NULL )
2981
0
  {
2982
0
    libcerror_error_set(
2983
0
     error,
2984
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2985
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2986
0
     "%s: invalid sub key: %d descriptor.",
2987
0
     function,
2988
0
     sub_key_index );
2989
2990
0
    result = -1;
2991
0
  }
2992
0
  else if( libregf_key_initialize(
2993
0
            sub_key,
2994
0
            internal_key->io_handle,
2995
0
            internal_key->file_io_handle,
2996
0
            sub_key_descriptor->key_offset,
2997
0
            internal_key->hive_bins_list,
2998
0
            error ) != 1 )
2999
0
  {
3000
0
    libcerror_error_set(
3001
0
     error,
3002
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3003
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3004
0
     "%s: unable to initialize sub key: %d.",
3005
0
     function,
3006
0
     sub_key_index );
3007
3008
0
    result = -1;
3009
0
  }
3010
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3011
0
  if( libcthreads_read_write_lock_release_for_write(
3012
0
       internal_key->read_write_lock,
3013
0
       error ) != 1 )
3014
0
  {
3015
0
    libcerror_error_set(
3016
0
     error,
3017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3018
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3019
0
     "%s: unable to release read/write lock for writing.",
3020
0
     function );
3021
3022
0
    return( -1 );
3023
0
  }
3024
0
#endif
3025
0
  return( result );
3026
0
}
3027
3028
/* Retrieves the sub key for the specific UTF-8 encoded name
3029
 * Creates a new key
3030
 * Returns 1 if successful, 0 if no such sub key or -1 on error
3031
 */
3032
int libregf_internal_key_get_sub_key_by_utf8_name(
3033
     libregf_internal_key_t *internal_key,
3034
     const uint8_t *utf8_string,
3035
     size_t utf8_string_length,
3036
     libregf_key_t **sub_key,
3037
     libcerror_error_t **error )
3038
0
{
3039
0
  libregf_key_descriptor_t *sub_key_descriptor = NULL;
3040
0
  static char *function                        = "libregf_internal_key_get_sub_key_by_utf8_name";
3041
0
  libuna_unicode_character_t unicode_character = 0;
3042
0
  size_t utf8_string_index                     = 0;
3043
0
  uint32_t name_hash                           = 0;
3044
0
  int result                                   = 0;
3045
3046
0
  if( internal_key == NULL )
3047
0
  {
3048
0
    libcerror_error_set(
3049
0
     error,
3050
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3051
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3052
0
     "%s: invalid key.",
3053
0
     function );
3054
3055
0
    return( -1 );
3056
0
  }
3057
0
  if( utf8_string == NULL )
3058
0
  {
3059
0
    libcerror_error_set(
3060
0
     error,
3061
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3062
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3063
0
     "%s: invalid UTF-8 string.",
3064
0
     function );
3065
3066
0
    return( -1 );
3067
0
  }
3068
0
  if( utf8_string_length > (size_t) SSIZE_MAX )
3069
0
  {
3070
0
    libcerror_error_set(
3071
0
     error,
3072
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3073
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3074
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
3075
0
     function );
3076
3077
0
    return( -1 );
3078
0
  }
3079
0
  if( sub_key == NULL )
3080
0
  {
3081
0
    libcerror_error_set(
3082
0
     error,
3083
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3084
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3085
0
     "%s: invalid sub key.",
3086
0
     function );
3087
3088
0
    return( -1 );
3089
0
  }
3090
0
  if( *sub_key != NULL )
3091
0
  {
3092
0
    libcerror_error_set(
3093
0
     error,
3094
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3095
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3096
0
     "%s: sub key already set.",
3097
0
     function );
3098
3099
0
    return( -1 );
3100
0
  }
3101
0
  while( utf8_string_index < utf8_string_length )
3102
0
  {
3103
0
    if( libuna_unicode_character_copy_from_utf8(
3104
0
         &unicode_character,
3105
0
         utf8_string,
3106
0
         utf8_string_length,
3107
0
         &utf8_string_index,
3108
0
         error ) != 1 )
3109
0
    {
3110
0
      libcerror_error_set(
3111
0
       error,
3112
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3113
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3114
0
       "%s: unable to copy UTF-8 string to Unicode character.",
3115
0
       function );
3116
3117
0
      return( -1 );
3118
0
    }
3119
0
    name_hash *= 37;
3120
0
    name_hash += (uint32_t) towupper( (wint_t) unicode_character );
3121
0
  }
3122
0
  result = libregf_key_item_get_sub_key_descriptor_by_utf8_name(
3123
0
            internal_key->key_item,
3124
0
            internal_key->file_io_handle,
3125
0
            internal_key->hive_bins_list,
3126
0
            name_hash,
3127
0
            utf8_string,
3128
0
            utf8_string_length,
3129
0
            &sub_key_descriptor,
3130
0
            error );
3131
3132
0
  if( result == -1 )
3133
0
  {
3134
0
    libcerror_error_set(
3135
0
     error,
3136
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3137
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3138
0
     "%s: unable to retrieve sub key descriptor by UTF-8 name.",
3139
0
     function );
3140
3141
0
    return( -1 );
3142
0
  }
3143
0
  else if( result != 0 )
3144
0
  {
3145
0
    if( sub_key_descriptor == NULL )
3146
0
    {
3147
0
      libcerror_error_set(
3148
0
       error,
3149
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3150
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3151
0
       "%s: missing sub key descriptor.",
3152
0
       function );
3153
3154
0
      return( -1 );
3155
0
    }
3156
0
    if( libregf_key_initialize(
3157
0
         sub_key,
3158
0
         internal_key->io_handle,
3159
0
         internal_key->file_io_handle,
3160
0
         sub_key_descriptor->key_offset,
3161
0
         internal_key->hive_bins_list,
3162
0
         error ) != 1 )
3163
0
    {
3164
0
      libcerror_error_set(
3165
0
       error,
3166
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3167
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3168
0
       "%s: unable to initialize sub key.",
3169
0
       function );
3170
3171
0
      return( -1 );
3172
0
    }
3173
0
  }
3174
0
  return( result );
3175
0
}
3176
3177
/* Retrieves the sub key for the specific UTF-8 encoded name
3178
 * Creates a new key
3179
 * Returns 1 if successful, 0 if no such sub key or -1 on error
3180
 */
3181
int libregf_key_get_sub_key_by_utf8_name(
3182
     libregf_key_t *key,
3183
     const uint8_t *utf8_string,
3184
     size_t utf8_string_length,
3185
     libregf_key_t **sub_key,
3186
     libcerror_error_t **error )
3187
0
{
3188
0
  libregf_internal_key_t *internal_key = NULL;
3189
0
  static char *function                = "libregf_key_get_sub_key_by_utf8_name";
3190
0
  int result                           = 0;
3191
3192
0
  if( key == NULL )
3193
0
  {
3194
0
    libcerror_error_set(
3195
0
     error,
3196
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3197
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3198
0
     "%s: invalid key.",
3199
0
     function );
3200
3201
0
    return( -1 );
3202
0
  }
3203
0
  internal_key = (libregf_internal_key_t *) key;
3204
3205
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3206
0
  if( libcthreads_read_write_lock_grab_for_write(
3207
0
       internal_key->read_write_lock,
3208
0
       error ) != 1 )
3209
0
  {
3210
0
    libcerror_error_set(
3211
0
     error,
3212
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3213
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3214
0
     "%s: unable to grab read/write lock for writing.",
3215
0
     function );
3216
3217
0
    return( -1 );
3218
0
  }
3219
0
#endif
3220
0
  result = libregf_internal_key_get_sub_key_by_utf8_name(
3221
0
            internal_key,
3222
0
            utf8_string,
3223
0
            utf8_string_length,
3224
0
            sub_key,
3225
0
            error );
3226
3227
0
  if( result == -1 )
3228
0
  {
3229
0
    libcerror_error_set(
3230
0
     error,
3231
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3232
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3233
0
     "%s: unable to retrieve key by UTF-8 name.",
3234
0
     function );
3235
3236
0
    result = -1;
3237
0
  }
3238
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3239
0
  if( libcthreads_read_write_lock_release_for_write(
3240
0
       internal_key->read_write_lock,
3241
0
       error ) != 1 )
3242
0
  {
3243
0
    libcerror_error_set(
3244
0
     error,
3245
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3246
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3247
0
     "%s: unable to release read/write lock for writing.",
3248
0
     function );
3249
3250
0
    return( -1 );
3251
0
  }
3252
0
#endif
3253
0
  return( result );
3254
0
}
3255
3256
/* Retrieves the sub key for the specific UTF-8 encoded path
3257
 * The path separator is the \ character
3258
 * Creates a new key
3259
 * Returns 1 if successful, 0 if no such key or -1 on error
3260
 */
3261
int libregf_key_get_sub_key_by_utf8_path(
3262
     libregf_key_t *key,
3263
     const uint8_t *utf8_string,
3264
     size_t utf8_string_length,
3265
     libregf_key_t **sub_key,
3266
     libcerror_error_t **error )
3267
0
{
3268
0
  libregf_internal_key_t *internal_key = NULL;
3269
0
  static char *function                = "libregf_key_get_sub_key_by_utf8_path";
3270
0
  int result                           = 0;
3271
3272
0
  if( key == NULL )
3273
0
  {
3274
0
    libcerror_error_set(
3275
0
     error,
3276
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3277
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3278
0
     "%s: invalid key.",
3279
0
     function );
3280
3281
0
    return( -1 );
3282
0
  }
3283
0
  internal_key = (libregf_internal_key_t *) key;
3284
3285
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3286
0
  if( libcthreads_read_write_lock_grab_for_write(
3287
0
       internal_key->read_write_lock,
3288
0
       error ) != 1 )
3289
0
  {
3290
0
    libcerror_error_set(
3291
0
     error,
3292
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3293
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3294
0
     "%s: unable to grab read/write lock for writing.",
3295
0
     function );
3296
3297
0
    return( -1 );
3298
0
  }
3299
0
#endif
3300
0
  result = libregf_key_tree_get_sub_key_by_utf8_path(
3301
0
            internal_key->io_handle,
3302
0
            internal_key->file_io_handle,
3303
0
            internal_key->hive_bins_list,
3304
0
            internal_key->key_offset,
3305
0
            utf8_string,
3306
0
            utf8_string_length,
3307
0
            sub_key,
3308
0
      error );
3309
3310
0
  if( result == -1 )
3311
0
  {
3312
0
    libcerror_error_set(
3313
0
     error,
3314
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3315
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3316
0
     "%s: unable to retrieve key by UTF-8 path.",
3317
0
     function );
3318
3319
0
    result = -1;
3320
0
  }
3321
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3322
0
  if( libcthreads_read_write_lock_release_for_write(
3323
0
       internal_key->read_write_lock,
3324
0
       error ) != 1 )
3325
0
  {
3326
0
    libcerror_error_set(
3327
0
     error,
3328
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3329
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3330
0
     "%s: unable to release read/write lock for writing.",
3331
0
     function );
3332
3333
0
    return( -1 );
3334
0
  }
3335
0
#endif
3336
0
  return( result );
3337
0
}
3338
3339
/* Retrieves the sub key for the specific UTF-16 encoded name
3340
 * Creates a new key
3341
 * Returns 1 if successful, 0 if no such sub key or -1 on error
3342
 */
3343
int libregf_internal_key_get_sub_key_by_utf16_name(
3344
     libregf_internal_key_t *internal_key,
3345
     const uint16_t *utf16_string,
3346
     size_t utf16_string_length,
3347
     libregf_key_t **sub_key,
3348
     libcerror_error_t **error )
3349
0
{
3350
0
  libregf_key_descriptor_t *sub_key_descriptor = NULL;
3351
0
  static char *function                        = "libregf_internal_key_get_value_by_utf16_name";
3352
0
  libuna_unicode_character_t unicode_character = 0;
3353
0
  size_t utf16_string_index                    = 0;
3354
0
  uint32_t name_hash                           = 0;
3355
0
  int result                                   = 0;
3356
3357
0
  if( internal_key == NULL )
3358
0
  {
3359
0
    libcerror_error_set(
3360
0
     error,
3361
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3362
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3363
0
     "%s: invalid key.",
3364
0
     function );
3365
3366
0
    return( -1 );
3367
0
  }
3368
0
  if( internal_key->io_handle == NULL )
3369
0
  {
3370
0
    libcerror_error_set(
3371
0
     error,
3372
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3373
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3374
0
     "%s: invalid key - missing IO handle.",
3375
0
     function );
3376
3377
0
    return( -1 );
3378
0
  }
3379
0
  if( utf16_string == NULL )
3380
0
  {
3381
0
    libcerror_error_set(
3382
0
     error,
3383
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3384
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3385
0
     "%s: invalid UTF-16 string.",
3386
0
     function );
3387
3388
0
    return( -1 );
3389
0
  }
3390
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
3391
0
  {
3392
0
    libcerror_error_set(
3393
0
     error,
3394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3395
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3396
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
3397
0
     function );
3398
3399
0
    return( -1 );
3400
0
  }
3401
0
  if( sub_key == NULL )
3402
0
  {
3403
0
    libcerror_error_set(
3404
0
     error,
3405
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3406
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3407
0
     "%s: invalid sub key.",
3408
0
     function );
3409
3410
0
    return( -1 );
3411
0
  }
3412
0
  if( *sub_key != NULL )
3413
0
  {
3414
0
    libcerror_error_set(
3415
0
     error,
3416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3417
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3418
0
     "%s: sub key already set.",
3419
0
     function );
3420
3421
0
    return( -1 );
3422
0
  }
3423
0
  while( utf16_string_index < utf16_string_length )
3424
0
  {
3425
0
    if( libuna_unicode_character_copy_from_utf16(
3426
0
         &unicode_character,
3427
0
         utf16_string,
3428
0
         utf16_string_length,
3429
0
         &utf16_string_index,
3430
0
         error ) != 1 )
3431
0
    {
3432
0
      libcerror_error_set(
3433
0
       error,
3434
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3435
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3436
0
       "%s: unable to copy UTF-16 string to Unicode character.",
3437
0
       function );
3438
3439
0
      return( -1 );
3440
0
    }
3441
0
    name_hash *= 37;
3442
0
    name_hash += (uint32_t) towupper( (wint_t) unicode_character );
3443
0
  }
3444
0
  result = libregf_key_item_get_sub_key_descriptor_by_utf16_name(
3445
0
            internal_key->key_item,
3446
0
            internal_key->file_io_handle,
3447
0
            internal_key->hive_bins_list,
3448
0
            name_hash,
3449
0
            utf16_string,
3450
0
            utf16_string_length,
3451
0
            &sub_key_descriptor,
3452
0
            error );
3453
3454
0
  if( result == -1 )
3455
0
  {
3456
0
    libcerror_error_set(
3457
0
     error,
3458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3459
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3460
0
     "%s: unable to retrieve sub key values by UTF-16 name.",
3461
0
     function );
3462
3463
0
    return( -1 );
3464
0
  }
3465
0
  else if( result != 0 )
3466
0
  {
3467
0
    if( sub_key_descriptor == NULL )
3468
0
    {
3469
0
      libcerror_error_set(
3470
0
       error,
3471
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3472
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3473
0
       "%s: missing sub key descriptor.",
3474
0
       function );
3475
3476
0
      return( -1 );
3477
0
    }
3478
0
    if( libregf_key_initialize(
3479
0
         sub_key,
3480
0
         internal_key->io_handle,
3481
0
         internal_key->file_io_handle,
3482
0
         sub_key_descriptor->key_offset,
3483
0
         internal_key->hive_bins_list,
3484
0
         error ) != 1 )
3485
0
    {
3486
0
      libcerror_error_set(
3487
0
       error,
3488
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3489
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3490
0
       "%s: unable to initialize sub key.",
3491
0
       function );
3492
3493
0
      return( -1 );
3494
0
    }
3495
0
  }
3496
0
  return( result );
3497
0
}
3498
3499
/* Retrieves the sub key for the specific UTF-16 encoded name
3500
 * Creates a new key
3501
 * Returns 1 if successful, 0 if no such sub key or -1 on error
3502
 */
3503
int libregf_key_get_sub_key_by_utf16_name(
3504
     libregf_key_t *key,
3505
     const uint16_t *utf16_string,
3506
     size_t utf16_string_length,
3507
     libregf_key_t **sub_key,
3508
     libcerror_error_t **error )
3509
0
{
3510
0
  libregf_internal_key_t *internal_key = NULL;
3511
0
  static char *function                = "libregf_key_get_sub_key_by_utf16_name";
3512
0
  int result                           = 0;
3513
3514
0
  if( key == NULL )
3515
0
  {
3516
0
    libcerror_error_set(
3517
0
     error,
3518
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3519
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3520
0
     "%s: invalid key.",
3521
0
     function );
3522
3523
0
    return( -1 );
3524
0
  }
3525
0
  internal_key = (libregf_internal_key_t *) key;
3526
3527
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3528
0
  if( libcthreads_read_write_lock_grab_for_write(
3529
0
       internal_key->read_write_lock,
3530
0
       error ) != 1 )
3531
0
  {
3532
0
    libcerror_error_set(
3533
0
     error,
3534
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3535
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3536
0
     "%s: unable to grab read/write lock for writing.",
3537
0
     function );
3538
3539
0
    return( -1 );
3540
0
  }
3541
0
#endif
3542
0
  result = libregf_internal_key_get_sub_key_by_utf16_name(
3543
0
            internal_key,
3544
0
            utf16_string,
3545
0
            utf16_string_length,
3546
0
            sub_key,
3547
0
            error );
3548
3549
0
  if( result == -1 )
3550
0
  {
3551
0
    libcerror_error_set(
3552
0
     error,
3553
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3554
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3555
0
     "%s: unable to retrieve key by UTF-16 name.",
3556
0
     function );
3557
3558
0
    result = -1;
3559
0
  }
3560
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3561
0
  if( libcthreads_read_write_lock_release_for_write(
3562
0
       internal_key->read_write_lock,
3563
0
       error ) != 1 )
3564
0
  {
3565
0
    libcerror_error_set(
3566
0
     error,
3567
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3568
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3569
0
     "%s: unable to release read/write lock for writing.",
3570
0
     function );
3571
3572
0
    return( -1 );
3573
0
  }
3574
0
#endif
3575
0
  return( result );
3576
0
}
3577
3578
/* Retrieves the sub key for the specific UTF-16 encoded path
3579
 * The path separator is the \ character
3580
 * Creates a new key
3581
 * Returns 1 if successful, 0 if no such key or -1 on error
3582
 */
3583
int libregf_key_get_sub_key_by_utf16_path(
3584
     libregf_key_t *key,
3585
     const uint16_t *utf16_string,
3586
     size_t utf16_string_length,
3587
     libregf_key_t **sub_key,
3588
     libcerror_error_t **error )
3589
0
{
3590
0
  libregf_internal_key_t *internal_key = NULL;
3591
0
  static char *function                = "libregf_key_get_sub_key_by_utf16_path";
3592
0
  int result                           = 0;
3593
3594
0
  if( key == NULL )
3595
0
  {
3596
0
    libcerror_error_set(
3597
0
     error,
3598
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3599
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3600
0
     "%s: invalid key.",
3601
0
     function );
3602
3603
0
    return( -1 );
3604
0
  }
3605
0
  internal_key = (libregf_internal_key_t *) key;
3606
3607
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3608
0
  if( libcthreads_read_write_lock_grab_for_write(
3609
0
       internal_key->read_write_lock,
3610
0
       error ) != 1 )
3611
0
  {
3612
0
    libcerror_error_set(
3613
0
     error,
3614
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3615
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3616
0
     "%s: unable to grab read/write lock for writing.",
3617
0
     function );
3618
3619
0
    return( -1 );
3620
0
  }
3621
0
#endif
3622
0
  result = libregf_key_tree_get_sub_key_by_utf16_path(
3623
0
            internal_key->io_handle,
3624
0
            internal_key->file_io_handle,
3625
0
            internal_key->hive_bins_list,
3626
0
            internal_key->key_offset,
3627
0
            utf16_string,
3628
0
            utf16_string_length,
3629
0
            sub_key,
3630
0
      error );
3631
3632
0
  if( result == -1 )
3633
0
  {
3634
0
    libcerror_error_set(
3635
0
     error,
3636
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3637
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3638
0
     "%s: unable to retrieve key by UTF-16 path.",
3639
0
     function );
3640
3641
0
    result = -1;
3642
0
  }
3643
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
3644
0
  if( libcthreads_read_write_lock_release_for_write(
3645
0
       internal_key->read_write_lock,
3646
0
       error ) != 1 )
3647
0
  {
3648
0
    libcerror_error_set(
3649
0
     error,
3650
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3651
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3652
0
     "%s: unable to release read/write lock for writing.",
3653
0
     function );
3654
3655
0
    return( -1 );
3656
0
  }
3657
0
#endif
3658
0
  return( result );
3659
0
}
3660