Coverage Report

Created: 2026-07-10 07:32

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