Coverage Report

Created: 2026-03-05 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libregf/libregf/libregf_key_item.c
Line
Count
Source
1
/*
2
 * Key item functions
3
 *
4
 * Copyright (C) 2009-2025, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libregf_debug.h"
27
#include "libregf_definitions.h"
28
#include "libregf_hive_bins_list.h"
29
#include "libregf_io_handle.h"
30
#include "libregf_key_descriptor.h"
31
#include "libregf_key_item.h"
32
#include "libregf_libbfio.h"
33
#include "libregf_libcdata.h"
34
#include "libregf_libcerror.h"
35
#include "libregf_libcnotify.h"
36
#include "libregf_libfcache.h"
37
#include "libregf_libfdata.h"
38
#include "libregf_libuna.h"
39
#include "libregf_named_key.h"
40
#include "libregf_security_key.h"
41
#include "libregf_sub_key_list.h"
42
#include "libregf_unused.h"
43
#include "libregf_value_item.h"
44
45
#include "regf_cell_values.h"
46
47
/* Creates key item
48
 * Make sure the key_item is referencing, is set to NULL
49
 * Returns 1 if successful or -1 on error
50
 */
51
int libregf_key_item_initialize(
52
     libregf_key_item_t **key_item,
53
     libcerror_error_t **error )
54
2.84k
{
55
2.84k
  static char *function = "libregf_key_item_initialize";
56
57
2.84k
  if( key_item == NULL )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
62
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
63
0
     "%s: invalid key item.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
2.84k
  if( *key_item != NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
73
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
74
0
     "%s: invalid key item value already set.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
2.84k
  *key_item = memory_allocate_structure(
80
2.84k
               libregf_key_item_t );
81
82
2.84k
  if( *key_item == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
88
0
     "%s: unable to create key item.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
2.84k
  if( memory_set(
94
2.84k
       *key_item,
95
2.84k
       0,
96
2.84k
       sizeof( libregf_key_item_t ) ) == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
101
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
102
0
     "%s: unable to clear key item.",
103
0
     function );
104
105
0
    goto on_error;
106
0
  }
107
2.84k
  if( libcdata_array_initialize(
108
2.84k
       &( ( *key_item )->sub_key_descriptors ),
109
2.84k
       0,
110
2.84k
       error ) != 1 )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
115
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
116
0
     "%s: unable to create sub key descriptors.",
117
0
     function );
118
119
0
    goto on_error;
120
0
  }
121
2.84k
  return( 1 );
122
123
0
on_error:
124
0
  if( *key_item != NULL )
125
0
  {
126
0
    memory_free(
127
0
     *key_item );
128
129
0
    *key_item = NULL;
130
0
  }
131
0
  return( -1 );
132
2.84k
}
133
134
/* Frees key item
135
 * Returns 1 if successful or -1 on error
136
 */
137
int libregf_key_item_free(
138
     libregf_key_item_t **key_item,
139
     libcerror_error_t **error )
140
2.84k
{
141
2.84k
  static char *function = "libregf_key_item_free";
142
2.84k
  int result            = 1;
143
144
2.84k
  if( key_item == NULL )
145
0
  {
146
0
    libcerror_error_set(
147
0
     error,
148
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
149
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
150
0
     "%s: invalid key item.",
151
0
     function );
152
153
0
    return( -1 );
154
0
  }
155
2.84k
  if( *key_item != NULL )
156
2.84k
  {
157
2.84k
    if( ( *key_item )->named_key != NULL )
158
979
    {
159
979
      if( libregf_named_key_free(
160
979
           &( ( *key_item )->named_key ),
161
979
           error ) != 1 )
162
0
      {
163
0
        libcerror_error_set(
164
0
         error,
165
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
166
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
167
0
         "%s: unable to free the named key.",
168
0
         function );
169
170
0
        result = -1;
171
0
      }
172
979
    }
173
2.84k
    if( ( *key_item )->class_name != NULL )
174
23
    {
175
23
      memory_free(
176
23
       ( *key_item )->class_name );
177
23
    }
178
2.84k
    if( ( *key_item )->security_descriptor != NULL )
179
236
    {
180
236
      memory_free(
181
236
       ( *key_item )->security_descriptor );
182
236
    }
183
2.84k
    if( ( *key_item )->values_list != NULL )
184
979
    {
185
979
      if( libfdata_list_free(
186
979
           &( ( *key_item )->values_list ),
187
979
           error ) != 1 )
188
0
      {
189
0
        libcerror_error_set(
190
0
         error,
191
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
192
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
193
0
         "%s: unable to free the values data list.",
194
0
         function );
195
196
0
        result = -1;
197
0
      }
198
979
    }
199
2.84k
    if( ( *key_item )->values_cache != NULL )
200
979
    {
201
979
      if( libfcache_cache_free(
202
979
           &( ( *key_item )->values_cache ),
203
979
           error ) != 1 )
204
0
      {
205
0
        libcerror_error_set(
206
0
         error,
207
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
208
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
209
0
         "%s: unable to free values cache.",
210
0
         function );
211
212
0
        result = -1;
213
0
      }
214
979
    }
215
2.84k
    if( libcdata_array_free(
216
2.84k
         &( ( *key_item )->sub_key_descriptors ),
217
2.84k
         (int (*)(intptr_t **, libcerror_error_t **)) &libregf_key_descriptor_free,
218
2.84k
         error ) != 1 )
219
0
    {
220
0
      libcerror_error_set(
221
0
       error,
222
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
223
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
224
0
       "%s: unable to free sub key descriptors.",
225
0
       function );
226
227
0
      result = -1;
228
0
    }
229
2.84k
    memory_free(
230
2.84k
     *key_item );
231
232
2.84k
    *key_item = NULL;
233
2.84k
  }
234
2.84k
  return( result );
235
2.84k
}
236
237
/* Reads a key item
238
 * Returns 1 if successful or -1 on error
239
 */
240
int libregf_key_item_read(
241
     libregf_key_item_t *key_item,
242
     libbfio_handle_t *file_io_handle,
243
     libregf_hive_bins_list_t *hive_bins_list,
244
     off64_t key_offset,
245
     uint32_t named_key_hash,
246
     libcerror_error_t **error )
247
2.84k
{
248
2.84k
  static char *function = "libregf_key_item_read";
249
2.84k
  int hive_bin_index    = 0;
250
2.84k
  int result            = 0;
251
252
2.84k
  if( key_item == NULL )
253
0
  {
254
0
    libcerror_error_set(
255
0
     error,
256
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
257
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
258
0
     "%s: invalid key item.",
259
0
     function );
260
261
0
    return( -1 );
262
0
  }
263
2.84k
  if( key_item->named_key != NULL )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
268
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
269
0
     "%s: invalid key item - named key value already set.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
2.84k
  if( libregf_named_key_initialize(
275
2.84k
       &( key_item->named_key ),
276
2.84k
       error ) != 1 )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
282
0
     "%s: unable to create named key.",
283
0
     function );
284
285
0
    goto on_error;
286
0
  }
287
2.84k
  if( libregf_key_item_read_named_key(
288
2.84k
       key_item->named_key,
289
2.84k
       file_io_handle,
290
2.84k
       hive_bins_list,
291
2.84k
       key_offset,
292
2.84k
       named_key_hash,
293
2.84k
       error ) != 1 )
294
871
  {
295
871
    libcerror_error_set(
296
871
     error,
297
871
     LIBCERROR_ERROR_DOMAIN_IO,
298
871
     LIBCERROR_IO_ERROR_READ_FAILED,
299
871
     "%s: unable to read named key at offset: %" PRIi64 " (0x%08" PRIx64 ").",
300
871
     function,
301
871
     key_offset,
302
871
     key_offset );
303
304
871
    goto on_error;
305
871
  }
306
1.97k
  if( libregf_key_item_read_class_name(
307
1.97k
       key_item,
308
1.97k
       file_io_handle,
309
1.97k
       hive_bins_list,
310
1.97k
       key_item->named_key->class_name_offset,
311
1.97k
       key_item->named_key->class_name_size,
312
1.97k
       error ) != 1 )
313
164
  {
314
164
    libcerror_error_set(
315
164
     error,
316
164
     LIBCERROR_ERROR_DOMAIN_IO,
317
164
     LIBCERROR_IO_ERROR_READ_FAILED,
318
164
     "%s: unable to read class name at offset: %" PRIu32 " (0x%08" PRIx32 ").",
319
164
     function,
320
164
     key_item->named_key->class_name_offset,
321
164
     key_item->named_key->class_name_offset );
322
323
164
    goto on_error;
324
164
  }
325
1.81k
  if( key_item->named_key->security_key_offset != 0xffffffffUL )
326
695
  {
327
695
    if( libregf_key_item_read_security_key(
328
695
         key_item,
329
695
         file_io_handle,
330
695
         hive_bins_list,
331
695
         key_item->named_key->security_key_offset,
332
695
         error ) != 1 )
333
316
    {
334
316
      libcerror_error_set(
335
316
       error,
336
316
       LIBCERROR_ERROR_DOMAIN_IO,
337
316
       LIBCERROR_IO_ERROR_READ_FAILED,
338
316
       "%s: unable to read security key at offset: %" PRIu32 " (0x%08" PRIx32 ").",
339
316
       function,
340
316
       key_item->named_key->security_key_offset,
341
316
       key_item->named_key->security_key_offset );
342
343
316
      goto on_error;
344
316
    }
345
695
  }
346
1.49k
  if( key_item->named_key->number_of_sub_keys > 0 )
347
1.17k
  {
348
1.17k
    result = libregf_key_item_read_sub_keys_list(
349
1.17k
              key_item->sub_key_descriptors,
350
1.17k
              file_io_handle,
351
1.17k
              hive_bins_list,
352
1.17k
              (off64_t) key_item->named_key->sub_keys_list_offset,
353
1.17k
              0,
354
1.17k
              error );
355
356
1.17k
    if( result == -1 )
357
274
    {
358
274
      libcerror_error_set(
359
274
       error,
360
274
       LIBCERROR_ERROR_DOMAIN_IO,
361
274
       LIBCERROR_IO_ERROR_READ_FAILED,
362
274
       "%s: unable to read sub keys list at offset: %" PRIu32 " (0x%08" PRIx32 ").",
363
274
       function,
364
274
       key_item->named_key->sub_keys_list_offset,
365
274
       key_item->named_key->sub_keys_list_offset );
366
367
274
      goto on_error;
368
274
    }
369
896
    else if( result == 0 )
370
717
    {
371
717
      key_item->item_flags |= LIBREGF_ITEM_FLAG_IS_CORRUPTED;
372
717
    }
373
1.17k
  }
374
/* TODO clone function */
375
1.22k
  if( libfdata_list_initialize(
376
1.22k
       &( key_item->values_list ),
377
1.22k
       (intptr_t *) hive_bins_list,
378
1.22k
       NULL,
379
1.22k
       NULL,
380
1.22k
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libregf_value_item_read_element_data,
381
1.22k
       NULL,
382
1.22k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
383
1.22k
       error ) != 1 )
384
0
  {
385
0
    libcerror_error_set(
386
0
     error,
387
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
388
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
389
0
     "%s: unable to create values data list.",
390
0
     function );
391
392
0
    goto on_error;
393
0
  }
394
1.22k
  if( libfcache_cache_initialize(
395
1.22k
       &( key_item->values_cache ),
396
1.22k
       LIBREGF_MAXIMUM_CACHE_ENTRIES_VALUES,
397
1.22k
       error ) != 1 )
398
0
  {
399
0
    libcerror_error_set(
400
0
     error,
401
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
402
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
403
0
     "%s: unable to create values cache.",
404
0
     function );
405
406
0
    goto on_error;
407
0
  }
408
1.22k
  result = libregf_hive_bins_list_get_index_at_offset(
409
1.22k
            hive_bins_list,
410
1.22k
            (off64_t) key_item->named_key->values_list_offset,
411
1.22k
            &hive_bin_index,
412
1.22k
            error );
413
414
1.22k
  if( result == -1 )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
419
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
420
0
     "%s: unable to determine if values list offset is valid.",
421
0
     function );
422
423
0
    goto on_error;
424
0
  }
425
1.22k
  else if( result == 0 )
426
372
  {
427
372
    key_item->item_flags |= LIBREGF_ITEM_FLAG_IS_CORRUPTED;
428
372
  }
429
852
  else
430
852
  {
431
852
    if( libregf_key_item_read_values_list(
432
852
         key_item,
433
852
         file_io_handle,
434
852
         hive_bins_list,
435
852
         key_item->named_key->values_list_offset,
436
852
         key_item->named_key->number_of_values,
437
852
         error ) != 1 )
438
245
    {
439
245
      libcerror_error_set(
440
245
       error,
441
245
       LIBCERROR_ERROR_DOMAIN_IO,
442
245
       LIBCERROR_IO_ERROR_READ_FAILED,
443
245
       "%s: unable to read values list at offset: %" PRIu32 " (0x%08" PRIx32 ").",
444
245
       function,
445
245
       key_item->named_key->values_list_offset,
446
245
       key_item->named_key->values_list_offset );
447
448
245
      goto on_error;
449
245
    }
450
852
  }
451
  /* The values and sub keys are read on demand
452
   */
453
979
  return( 1 );
454
455
1.87k
on_error:
456
1.87k
  if( key_item->values_cache != NULL )
457
245
  {
458
245
    libfcache_cache_free(
459
245
     &( key_item->values_cache ),
460
245
     NULL );
461
245
  }
462
1.87k
  if( key_item->values_list != NULL )
463
245
  {
464
245
    libfdata_list_free(
465
245
     &( key_item->values_list ),
466
245
     NULL );
467
245
  }
468
1.87k
  if( key_item->security_descriptor != NULL )
469
83
  {
470
83
    memory_free(
471
83
     key_item->security_descriptor );
472
473
83
    key_item->security_descriptor = NULL;
474
83
  }
475
1.87k
  key_item->security_descriptor_size = 0;
476
477
1.87k
  if( key_item->class_name != NULL )
478
68
  {
479
68
    memory_free(
480
68
     key_item->class_name );
481
482
68
    key_item->class_name = NULL;
483
68
  }
484
1.87k
  key_item->class_name_size = 0;
485
486
1.87k
  if( key_item->named_key != NULL )
487
1.87k
  {
488
1.87k
    libregf_named_key_free(
489
1.87k
     &( key_item->named_key ),
490
1.87k
     NULL );
491
1.87k
  }
492
1.87k
  libcdata_array_empty(
493
1.87k
   key_item->sub_key_descriptors,
494
1.87k
   (int (*)(intptr_t **, libcerror_error_t **)) &libregf_key_descriptor_free,
495
1.87k
   NULL );
496
497
1.87k
  return( -1 );
498
1.22k
}
499
500
/* Reads a named key
501
 * Returns the number of bytes read if successful or -1 on error
502
 */
503
int libregf_key_item_read_named_key(
504
     libregf_named_key_t *named_key,
505
     libbfio_handle_t *file_io_handle,
506
     libregf_hive_bins_list_t *hive_bins_list,
507
     off64_t named_key_offset,
508
     uint32_t named_key_hash,
509
     libcerror_error_t **error )
510
2.84k
{
511
2.84k
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
512
2.84k
  static char *function                  = "libregf_key_item_read_named_key";
513
514
2.84k
  if( hive_bins_list == NULL )
515
113
  {
516
113
    libcerror_error_set(
517
113
     error,
518
113
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
519
113
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
520
113
     "%s: invalid hive bins list.",
521
113
     function );
522
523
113
    return( -1 );
524
113
  }
525
2.73k
  if( hive_bins_list->io_handle == NULL )
526
0
  {
527
0
    libcerror_error_set(
528
0
     error,
529
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
530
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
531
0
     "%s: invalid hive bins list - missing IO handle.",
532
0
     function );
533
534
0
    return( -1 );
535
0
  }
536
2.73k
  if( ( named_key_offset == 0 )
537
2.72k
   || ( named_key_offset >= (off64_t) 0xffffffffUL ) )
538
16
  {
539
16
    libcerror_error_set(
540
16
     error,
541
16
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
542
16
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
543
16
     "%s: invalid named key offset.",
544
16
     function );
545
546
16
    return( -1 );
547
16
  }
548
#if defined( HAVE_DEBUG_OUTPUT )
549
  if( libcnotify_verbose != 0 )
550
  {
551
    libcnotify_printf(
552
     "%s: reading named key at offset: %" PRIi64 " (0x%08" PRIx64 ").\n",
553
     function,
554
     named_key_offset,
555
     named_key_offset );
556
  }
557
#endif
558
2.72k
  if( libregf_hive_bins_list_get_cell_at_offset(
559
2.72k
       hive_bins_list,
560
2.72k
       file_io_handle,
561
2.72k
       (uint32_t) named_key_offset,
562
2.72k
       &hive_bin_cell,
563
2.72k
       error ) != 1 )
564
577
  {
565
577
    libcerror_error_set(
566
577
     error,
567
577
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
568
577
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
569
577
     "%s: unable to retrieve hive bin cell at offset: %" PRIi64 " (0x%08" PRIx64 ").",
570
577
     function,
571
577
     named_key_offset,
572
577
     named_key_offset );
573
574
577
    return( -1 );
575
577
  }
576
2.14k
  if( libregf_named_key_read_data(
577
2.14k
       named_key,
578
2.14k
       hive_bins_list->io_handle,
579
2.14k
       hive_bin_cell->data,
580
2.14k
       hive_bin_cell->size,
581
2.14k
       named_key_hash,
582
2.14k
       error ) != 1 )
583
165
  {
584
165
    libcerror_error_set(
585
165
     error,
586
165
     LIBCERROR_ERROR_DOMAIN_IO,
587
165
     LIBCERROR_IO_ERROR_READ_FAILED,
588
165
     "%s: unable to read named key at offset: %" PRIi64 " (0x%08" PRIx64 ").",
589
165
     function,
590
165
     named_key_offset,
591
165
     named_key_offset );
592
593
165
    return( -1 );
594
165
  }
595
1.97k
  return( 1 );
596
2.14k
}
597
598
/* Reads a class name
599
 * Returns 1 if successful or -1 on error
600
 */
601
int libregf_key_item_read_class_name_data(
602
     libregf_key_item_t *key_item,
603
     const uint8_t *data,
604
     size_t data_size,
605
     uint16_t class_name_size,
606
     libcerror_error_t **error )
607
117
{
608
117
  static char *function = "libregf_key_item_read_class_name_data";
609
610
117
  if( key_item == NULL )
611
0
  {
612
0
    libcerror_error_set(
613
0
     error,
614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
616
0
     "%s: invalid key item.",
617
0
     function );
618
619
0
    return( -1 );
620
0
  }
621
117
  if( key_item->class_name != NULL )
622
0
  {
623
0
    libcerror_error_set(
624
0
     error,
625
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
626
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
627
0
     "%s: invalid key item - class name value already set.",
628
0
     function );
629
630
0
    return( -1 );
631
0
  }
632
117
  if( data == NULL )
633
0
  {
634
0
    libcerror_error_set(
635
0
     error,
636
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
637
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
638
0
     "%s: invalid data.",
639
0
     function );
640
641
0
    return( -1 );
642
0
  }
643
117
  if( data_size > (size_t) SSIZE_MAX )
644
0
  {
645
0
    libcerror_error_set(
646
0
     error,
647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
648
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
649
0
     "%s: invalid data size value exceeds maximum.",
650
0
     function );
651
652
0
    return( -1 );
653
0
  }
654
#if defined( HAVE_DEBUG_OUTPUT )
655
  if( libcnotify_verbose != 0 )
656
  {
657
    libcnotify_printf(
658
     "%s: data:\n",
659
     function );
660
    libcnotify_print_data(
661
     data,
662
     data_size,
663
     0 );
664
  }
665
#endif
666
117
  if( ( class_name_size == 0 )
667
115
   || ( (size_t) class_name_size > data_size ) )
668
26
  {
669
26
    libcerror_error_set(
670
26
     error,
671
26
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
672
26
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
673
26
     "%s: invalid class name size value out of bounds.",
674
26
     function );
675
676
26
    goto on_error;
677
26
  }
678
91
  key_item->class_name = (uint8_t *) memory_allocate(
679
91
                                      sizeof( uint8_t ) * (size_t) class_name_size );
680
681
91
  if( key_item->class_name == NULL )
682
0
  {
683
0
    libcerror_error_set(
684
0
     error,
685
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
686
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
687
0
     "%s: unable to create class name.",
688
0
     function );
689
690
0
    goto on_error;
691
0
  }
692
91
  if( memory_copy(
693
91
       key_item->class_name,
694
91
       data,
695
91
       (size_t) class_name_size ) == NULL )
696
0
  {
697
0
    libcerror_error_set(
698
0
     error,
699
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
700
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
701
0
     "%s: unable to class name.",
702
0
     function );
703
704
0
    goto on_error;
705
0
  }
706
91
  key_item->class_name_size = class_name_size;
707
708
#if defined( HAVE_DEBUG_OUTPUT )
709
  if( libcnotify_verbose != 0 )
710
  {
711
    if( libregf_debug_print_utf16_string_value(
712
         function,
713
         "class name\t\t\t",
714
         key_item->class_name,
715
         (size_t) key_item->class_name_size,
716
         LIBUNA_ENDIAN_LITTLE,
717
         error ) != 1 )
718
    {
719
      libcerror_error_set(
720
       error,
721
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
722
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
723
       "%s: unable to print UTF-16 string value.",
724
       function );
725
726
      goto on_error;
727
    }
728
    if( (size_t) class_name_size < data_size )
729
    {
730
      libcnotify_printf(
731
       "%s: padding:\n",
732
       function );
733
      libcnotify_print_data(
734
       &( data[ (size_t) class_name_size ] ),
735
       data_size - (size_t) class_name_size,
736
       0 );
737
    }
738
    else
739
    {
740
      libcnotify_printf(
741
       "\n" );
742
    }
743
  }
744
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
745
746
91
  return( 1 );
747
748
26
on_error:
749
26
  if( key_item->class_name != NULL )
750
0
  {
751
0
    memory_free(
752
0
     key_item->class_name );
753
754
0
    key_item->class_name = NULL;
755
0
  }
756
26
  key_item->class_name_size = 0;
757
758
26
  return( -1 );
759
91
}
760
761
/* Reads a class name
762
 * Returns 1 if successful or -1 on error
763
 */
764
int libregf_key_item_read_class_name(
765
     libregf_key_item_t *key_item,
766
     libbfio_handle_t *file_io_handle,
767
     libregf_hive_bins_list_t *hive_bins_list,
768
     uint32_t class_name_offset,
769
     uint16_t class_name_size,
770
     libcerror_error_t **error )
771
1.97k
{
772
1.97k
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
773
1.97k
  static char *function                  = "libregf_key_item_read_class_name";
774
775
1.97k
  if( key_item == NULL )
776
0
  {
777
0
    libcerror_error_set(
778
0
     error,
779
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
780
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
781
0
     "%s: invalid key item.",
782
0
     function );
783
784
0
    return( -1 );
785
0
  }
786
1.97k
  if( key_item->class_name != NULL )
787
0
  {
788
0
    libcerror_error_set(
789
0
     error,
790
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
791
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
792
0
     "%s: invalid key item - class name value already set.",
793
0
     function );
794
795
0
    return( -1 );
796
0
  }
797
1.97k
  if( hive_bins_list == NULL )
798
0
  {
799
0
    libcerror_error_set(
800
0
     error,
801
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
802
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
803
0
     "%s: invalid hive bins list.",
804
0
     function );
805
806
0
    return( -1 );
807
0
  }
808
1.97k
  if( class_name_offset == 0xffffffffUL )
809
1.37k
  {
810
1.37k
    return( 1 );
811
1.37k
  }
812
602
  if( ( class_name_offset == 0 )
813
379
   && ( class_name_size == 0 ) )
814
347
  {
815
347
    return( 1 );
816
347
  }
817
255
  if( class_name_offset == 0 )
818
32
  {
819
32
    libcerror_error_set(
820
32
     error,
821
32
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
822
32
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
823
32
     "%s: invalid class name offset.",
824
32
     function );
825
826
32
    return( -1 );
827
32
  }
828
#if defined( HAVE_DEBUG_OUTPUT )
829
  if( libcnotify_verbose != 0 )
830
  {
831
    libcnotify_printf(
832
     "%s: reading class name at offset: %" PRIi64 " (0x%08" PRIx64 ").\n",
833
     function,
834
     class_name_offset,
835
     class_name_offset );
836
  }
837
#endif
838
223
  if( libregf_hive_bins_list_get_cell_at_offset(
839
223
       hive_bins_list,
840
223
       file_io_handle,
841
223
       class_name_offset,
842
223
       &hive_bin_cell,
843
223
       error ) != 1 )
844
106
  {
845
106
    libcerror_error_set(
846
106
     error,
847
106
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
848
106
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
849
106
     "%s: unable to retrieve hive bin at offset: %" PRIu32 " (0x%08" PRIx32 ").",
850
106
     function,
851
106
     class_name_offset,
852
106
     class_name_offset );
853
854
106
    return( -1 );
855
106
  }
856
117
  if( libregf_key_item_read_class_name_data(
857
117
       key_item,
858
117
       hive_bin_cell->data,
859
117
       hive_bin_cell->size,
860
117
       class_name_size,
861
117
       error ) != 1 )
862
26
  {
863
26
    libcerror_error_set(
864
26
     error,
865
26
     LIBCERROR_ERROR_DOMAIN_IO,
866
26
     LIBCERROR_IO_ERROR_READ_FAILED,
867
26
     "%s: unable to read class name at offset: %" PRIu32 " (0x%08" PRIx32 ").",
868
26
     function,
869
26
     class_name_offset,
870
26
     class_name_offset );
871
872
26
    return( -1 );
873
26
  }
874
91
  return( 1 );
875
117
}
876
877
/* Reads a security key
878
 * Returns 1 if successful or -1 on error
879
 */
880
int libregf_key_item_read_security_key(
881
     libregf_key_item_t *key_item,
882
     libbfio_handle_t *file_io_handle,
883
     libregf_hive_bins_list_t *hive_bins_list,
884
     uint32_t security_key_offset,
885
     libcerror_error_t **error )
886
695
{
887
695
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
888
695
  libregf_security_key_t *security_key   = NULL;
889
695
  static char *function                  = "libregf_key_item_read_security_key";
890
891
695
  if( key_item == NULL )
892
0
  {
893
0
    libcerror_error_set(
894
0
     error,
895
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
896
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
897
0
     "%s: invalid key item.",
898
0
     function );
899
900
0
    return( -1 );
901
0
  }
902
695
  if( key_item->security_descriptor != NULL )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
907
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
908
0
     "%s: invalid key item - security descriptor value already set.",
909
0
     function );
910
911
0
    return( -1 );
912
0
  }
913
695
  if( ( security_key_offset == 0 )
914
692
   || ( security_key_offset == 0xffffffffUL ) )
915
3
  {
916
3
    libcerror_error_set(
917
3
     error,
918
3
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
919
3
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
920
3
     "%s: invalid security key offset.",
921
3
     function );
922
923
3
    return( -1 );
924
3
  }
925
692
  if( libregf_hive_bins_list_get_cell_at_offset(
926
692
       hive_bins_list,
927
692
       file_io_handle,
928
692
       security_key_offset,
929
692
       &hive_bin_cell,
930
692
       error ) != 1 )
931
149
  {
932
149
    libcerror_error_set(
933
149
     error,
934
149
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
935
149
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
936
149
     "%s: unable to retrieve hive bin at offset: %" PRIu32 " (0x%08" PRIx32 ").",
937
149
     function,
938
149
     security_key_offset,
939
149
     security_key_offset );
940
941
149
    goto on_error;
942
149
  }
943
543
  if( libregf_security_key_initialize(
944
543
       &security_key,
945
543
       error ) != 1 )
946
0
  {
947
0
    libcerror_error_set(
948
0
     error,
949
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
950
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
951
0
     "%s: unable to create security key.",
952
0
     function );
953
954
0
    goto on_error;
955
0
  }
956
543
  if( libregf_security_key_read_data(
957
543
       security_key,
958
543
       hive_bins_list->io_handle,
959
543
       hive_bin_cell->data,
960
543
       hive_bin_cell->size,
961
543
       error ) != 1 )
962
164
  {
963
164
    libcerror_error_set(
964
164
     error,
965
164
     LIBCERROR_ERROR_DOMAIN_IO,
966
164
     LIBCERROR_IO_ERROR_READ_FAILED,
967
164
     "%s: unable to read security key at offset: %" PRIu32 " (0x%08" PRIx32 ").",
968
164
     function,
969
164
     security_key_offset,
970
164
     security_key_offset );
971
972
164
    goto on_error;
973
164
  }
974
379
  key_item->security_descriptor      = security_key->security_descriptor;
975
379
  key_item->security_descriptor_size = security_key->security_descriptor_size;
976
977
379
  security_key->security_descriptor      = NULL;
978
379
  security_key->security_descriptor_size = 0;
979
980
379
  if( libregf_security_key_free(
981
379
       &security_key,
982
379
       error ) != 1 )
983
0
  {
984
0
    libcerror_error_set(
985
0
     error,
986
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
987
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
988
0
     "%s: unable to free security key.",
989
0
     function );
990
991
0
    goto on_error;
992
0
  }
993
379
  return( 1 );
994
995
313
on_error:
996
313
  if( security_key != NULL )
997
164
  {
998
164
    libregf_security_key_free(
999
164
     &security_key,
1000
164
     NULL );
1001
164
  }
1002
313
  return( -1 );
1003
379
}
1004
1005
/* Reads a values list
1006
 * Returns 1 if successful or -1 on error
1007
 */
1008
int libregf_key_item_read_values_list(
1009
     libregf_key_item_t *key_item,
1010
     libbfio_handle_t *file_io_handle,
1011
     libregf_hive_bins_list_t *hive_bins_list,
1012
     uint32_t values_list_offset,
1013
     uint32_t number_of_values_list_elements,
1014
     libcerror_error_t **error )
1015
852
{
1016
852
  libregf_hive_bin_cell_t *hive_bin_cell = NULL;
1017
852
  static char *function                  = "libregf_key_item_read_values_list";
1018
852
  size_t data_offset                     = 0;
1019
852
  size_t hive_bin_cell_size              = 0;
1020
852
  uint32_t values_list_element_index     = 0;
1021
852
  uint32_t values_list_element_offset    = 0;
1022
852
  int element_index                      = 0;
1023
852
  int hive_bin_index                     = 0;
1024
852
  int result                             = 0;
1025
1026
852
  if( key_item == NULL )
1027
0
  {
1028
0
    libcerror_error_set(
1029
0
     error,
1030
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1031
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1032
0
     "%s: invalid key item.",
1033
0
     function );
1034
1035
0
    return( -1 );
1036
0
  }
1037
852
  if( hive_bins_list == NULL )
1038
0
  {
1039
0
    libcerror_error_set(
1040
0
     error,
1041
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1042
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1043
0
     "%s: invalid hive bins list.",
1044
0
     function );
1045
1046
0
    return( -1 );
1047
0
  }
1048
852
  if( hive_bins_list->io_handle == NULL )
1049
0
  {
1050
0
    libcerror_error_set(
1051
0
     error,
1052
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1053
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1054
0
     "%s: invalid hive bins list - missing IO handle.",
1055
0
     function );
1056
1057
0
    return( -1 );
1058
0
  }
1059
852
  if( number_of_values_list_elements == 0 )
1060
26
  {
1061
26
    return( 1 );
1062
26
  }
1063
826
  if( ( values_list_offset == 0 )
1064
820
   || ( values_list_offset == 0xffffffffUL ) )
1065
8
  {
1066
8
    libcerror_error_set(
1067
8
     error,
1068
8
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1069
8
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1070
8
     "%s: invalid values list offset.",
1071
8
     function );
1072
1073
8
    return( -1 );
1074
8
  }
1075
818
  if( libregf_hive_bins_list_get_cell_at_offset(
1076
818
       hive_bins_list,
1077
818
       file_io_handle,
1078
818
       values_list_offset,
1079
818
       &hive_bin_cell,
1080
818
       error ) != 1 )
1081
137
  {
1082
137
    libcerror_error_set(
1083
137
     error,
1084
137
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1085
137
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1086
137
     "%s: unable to retrieve hive bin at offset: %" PRIu32 " (0x%08" PRIx32 ").",
1087
137
     function,
1088
137
     values_list_offset ,
1089
137
     values_list_offset );
1090
1091
137
    return( -1 );
1092
137
  }
1093
681
  hive_bin_cell_size = hive_bin_cell->size;
1094
1095
#if defined( HAVE_DEBUG_OUTPUT )
1096
  if( libcnotify_verbose != 0 )
1097
  {
1098
    libcnotify_printf(
1099
     "%s: data:\n",
1100
     function );
1101
    libcnotify_print_data(
1102
     hive_bin_cell->data,
1103
     hive_bin_cell_size,
1104
     0 );
1105
  }
1106
#endif
1107
681
  if( ( hive_bins_list->io_handle->major_version == 1 )
1108
412
   && ( hive_bins_list->io_handle->minor_version <= 1 ) )
1109
0
  {
1110
0
    data_offset += 4;
1111
0
  }
1112
681
  if( ( data_offset > hive_bin_cell_size )
1113
681
   || ( number_of_values_list_elements > ( ( hive_bin_cell_size - data_offset ) / 4 ) ) )
1114
100
  {
1115
100
    libcerror_error_set(
1116
100
     error,
1117
100
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1118
100
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1119
100
     "%s: invalid cell size value too small to contain number of values.",
1120
100
     function );
1121
1122
100
    return( -1 );
1123
100
  }
1124
581
  for( values_list_element_index = 0;
1125
13.0k
       values_list_element_index < number_of_values_list_elements;
1126
12.4k
       values_list_element_index++ )
1127
12.4k
  {
1128
12.4k
    byte_stream_copy_to_uint32_little_endian(
1129
12.4k
     &( hive_bin_cell->data[ data_offset ] ),
1130
12.4k
     values_list_element_offset );
1131
1132
12.4k
    data_offset += 4;
1133
1134
#if defined( HAVE_DEBUG_OUTPUT )
1135
    if( libcnotify_verbose != 0 )
1136
    {
1137
      libcnotify_printf(
1138
       "%s: element: %03" PRIu32 " offset\t\t\t: 0x%08" PRIx32 "\n",
1139
       function,
1140
       values_list_element_index,
1141
       values_list_element_offset );
1142
    }
1143
#endif
1144
12.4k
    result = libregf_hive_bins_list_get_index_at_offset(
1145
12.4k
              hive_bins_list,
1146
12.4k
              (off64_t) values_list_element_offset,
1147
12.4k
              &hive_bin_index,
1148
12.4k
              error );
1149
1150
12.4k
    if( result == -1 )
1151
0
    {
1152
0
      libcerror_error_set(
1153
0
       error,
1154
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1155
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1156
0
       "%s: unable to determine if values list element offset is valid.",
1157
0
       function );
1158
1159
0
      return( -1 );
1160
0
    }
1161
12.4k
    else if( result == 0 )
1162
6.93k
    {
1163
6.93k
      key_item->item_flags |= LIBREGF_ITEM_FLAG_IS_CORRUPTED;
1164
6.93k
    }
1165
5.50k
    else
1166
5.50k
    {
1167
5.50k
      if( libfdata_list_append_element(
1168
5.50k
           key_item->values_list,
1169
5.50k
           &element_index,
1170
5.50k
           0,
1171
5.50k
           (off64_t) values_list_element_offset,
1172
5.50k
           0,
1173
5.50k
           0,
1174
5.50k
           error ) != 1 )
1175
0
      {
1176
0
        libcerror_error_set(
1177
0
         error,
1178
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179
0
         LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
1180
0
         "%s: unable to set value list element: %" PRIu32 " in list.",
1181
0
         function,
1182
0
         values_list_element_index );
1183
1184
0
        return( -1 );
1185
0
      }
1186
5.50k
    }
1187
12.4k
  }
1188
#if defined( HAVE_DEBUG_OUTPUT )
1189
  if( libcnotify_verbose != 0 )
1190
  {
1191
    if( data_offset < hive_bin_cell_size )
1192
    {
1193
      libcnotify_printf(
1194
       "%s: padding:\n",
1195
       function );
1196
      libcnotify_print_data(
1197
       &( hive_bin_cell->data[ data_offset ] ),
1198
       hive_bin_cell_size - data_offset,
1199
       0 );
1200
    }
1201
    else
1202
    {
1203
      libcnotify_printf(
1204
       "\n" );
1205
    }
1206
  }
1207
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1208
1209
581
  return( 1 );
1210
581
}
1211
1212
/* Reads a sub keys list
1213
 * Returns 1 if successful, 0 if not or -1 on error
1214
 */
1215
int libregf_key_item_read_sub_keys_list(
1216
     libcdata_array_t *sub_key_descriptors,
1217
     libbfio_handle_t *file_io_handle,
1218
     libregf_hive_bins_list_t *hive_bins_list,
1219
     off64_t sub_keys_list_offset,
1220
     int recursion_depth,
1221
     libcerror_error_t **error )
1222
21.4k
{
1223
21.4k
  libregf_hive_bin_cell_t *hive_bin_cell       = NULL;
1224
21.4k
  libregf_key_descriptor_t *sub_key_descriptor = NULL;
1225
21.4k
  libregf_sub_key_list_t *sub_key_list         = NULL;
1226
21.4k
  static char *function                        = "libregf_key_item_read_sub_keys_list";
1227
21.4k
  int corruption_detected                      = 0;
1228
21.4k
  int entry_index                              = 0;
1229
21.4k
  int hive_bin_index                           = 0;
1230
21.4k
  int number_of_sub_key_descriptors            = 0;
1231
21.4k
  int result                                   = 0;
1232
21.4k
  int sub_key_descriptor_index                 = 0;
1233
1234
21.4k
  if( hive_bins_list == NULL )
1235
0
  {
1236
0
    libcerror_error_set(
1237
0
     error,
1238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1240
0
     "%s: invalid hive bins list.",
1241
0
     function );
1242
1243
0
    return( -1 );
1244
0
  }
1245
21.4k
  if( ( sub_keys_list_offset == 0 )
1246
21.4k
   || ( sub_keys_list_offset == (off64_t) 0xffffffffUL ) )
1247
10
  {
1248
10
    libcerror_error_set(
1249
10
     error,
1250
10
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1251
10
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1252
10
     "%s: invalid sub keys list offset.",
1253
10
     function );
1254
1255
10
    return( -1 );
1256
10
  }
1257
21.4k
  if( ( recursion_depth < 0 )
1258
21.4k
   || ( recursion_depth > LIBREGF_MAXIMUM_SUB_KEY_RECURSION_DEPTH ) )
1259
17
  {
1260
17
    libcerror_error_set(
1261
17
     error,
1262
17
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1263
17
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1264
17
     "%s: invalid recursion depth value out of bounds.",
1265
17
     function );
1266
1267
17
    return( -1 );
1268
17
  }
1269
21.3k
  if( libregf_hive_bins_list_get_cell_at_offset(
1270
21.3k
       hive_bins_list,
1271
21.3k
       file_io_handle,
1272
21.3k
       (uint32_t) sub_keys_list_offset,
1273
21.3k
       &hive_bin_cell,
1274
21.3k
       error ) != 1 )
1275
130
  {
1276
130
    libcerror_error_set(
1277
130
     error,
1278
130
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1279
130
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1280
130
     "%s: unable to retrieve hive bin at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1281
130
     function,
1282
130
     sub_keys_list_offset,
1283
130
     sub_keys_list_offset );
1284
1285
130
    goto on_error;
1286
130
  }
1287
21.2k
  if( libregf_sub_key_list_initialize(
1288
21.2k
       &sub_key_list,
1289
21.2k
       error ) != 1 )
1290
0
  {
1291
0
    libcerror_error_set(
1292
0
     error,
1293
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1294
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1295
0
     "%s: unable to create sub key list.",
1296
0
     function );
1297
1298
0
    goto on_error;
1299
0
  }
1300
21.2k
  if( libregf_sub_key_list_read_data(
1301
21.2k
       sub_key_list,
1302
21.2k
       hive_bins_list->io_handle,
1303
21.2k
       hive_bin_cell->data,
1304
21.2k
       hive_bin_cell->size,
1305
21.2k
       error ) != 1 )
1306
117
  {
1307
117
    libcerror_error_set(
1308
117
     error,
1309
117
     LIBCERROR_ERROR_DOMAIN_IO,
1310
117
     LIBCERROR_IO_ERROR_READ_FAILED,
1311
117
     "%s: unable to read sub key list at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1312
117
     function,
1313
117
     sub_keys_list_offset,
1314
117
     sub_keys_list_offset );
1315
1316
117
    goto on_error;
1317
117
  }
1318
21.1k
  if( libcdata_array_get_number_of_entries(
1319
21.1k
       sub_key_list->sub_key_descriptors,
1320
21.1k
       &number_of_sub_key_descriptors,
1321
21.1k
       error ) != 1 )
1322
0
  {
1323
0
    libcerror_error_set(
1324
0
     error,
1325
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1326
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1327
0
     "%s: unable to retrieve number of entries from sub key descriptors array.",
1328
0
     function );
1329
1330
0
    goto on_error;
1331
0
  }
1332
21.1k
  for( sub_key_descriptor_index = 0;
1333
92.6k
       sub_key_descriptor_index < number_of_sub_key_descriptors;
1334
71.5k
       sub_key_descriptor_index++ )
1335
75.9k
  {
1336
75.9k
    if( libcdata_array_get_entry_by_index(
1337
75.9k
         sub_key_list->sub_key_descriptors,
1338
75.9k
         sub_key_descriptor_index,
1339
75.9k
         (intptr_t **) &sub_key_descriptor,
1340
75.9k
         error ) != 1 )
1341
0
    {
1342
0
      libcerror_error_set(
1343
0
       error,
1344
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1345
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1346
0
       "%s: unable to retrieve sub key descriptor: %d from array.",
1347
0
       function,
1348
0
       sub_key_descriptor_index );
1349
1350
0
      goto on_error;
1351
0
    }
1352
75.9k
    if( sub_key_descriptor == NULL )
1353
0
    {
1354
0
      libcerror_error_set(
1355
0
       error,
1356
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1357
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1358
0
       "%s: missing sub key descriptor: %d.",
1359
0
       function,
1360
0
       sub_key_descriptor_index );
1361
1362
0
      goto on_error;
1363
0
    }
1364
75.9k
    result = libregf_hive_bins_list_get_index_at_offset(
1365
75.9k
              hive_bins_list,
1366
75.9k
              (off64_t) sub_key_descriptor->key_offset,
1367
75.9k
              &hive_bin_index,
1368
75.9k
              error );
1369
1370
75.9k
    if( result == -1 )
1371
0
    {
1372
0
      libcerror_error_set(
1373
0
       error,
1374
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1375
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1376
0
       "%s: unable to determine if sub keys list element: %d offset is valid.",
1377
0
       function,
1378
0
       sub_key_descriptor_index );
1379
1380
0
      goto on_error;
1381
0
    }
1382
75.9k
    else if( result != 0 )
1383
41.0k
    {
1384
41.0k
      if( sub_key_list->at_leaf_level != 0 )
1385
20.8k
      {
1386
20.8k
        if( libcdata_array_set_entry_by_index(
1387
20.8k
             sub_key_list->sub_key_descriptors,
1388
20.8k
             sub_key_descriptor_index,
1389
20.8k
             NULL,
1390
20.8k
             error ) != 1 )
1391
0
        {
1392
0
          libcerror_error_set(
1393
0
           error,
1394
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1395
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1396
0
           "%s: unable to set sub key descriptor: %d in array.",
1397
0
           function,
1398
0
           sub_key_descriptor_index );
1399
1400
0
          goto on_error;
1401
0
        }
1402
20.8k
        if( libcdata_array_append_entry(
1403
20.8k
             sub_key_descriptors,
1404
20.8k
             &entry_index,
1405
20.8k
             (intptr_t *) sub_key_descriptor,
1406
20.8k
             error ) != 1 )
1407
0
        {
1408
0
          libcerror_error_set(
1409
0
           error,
1410
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1411
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1412
0
           "%s: unable to append sub key descriptor to array.",
1413
0
           function );
1414
1415
0
          libregf_key_descriptor_free(
1416
0
           &sub_key_descriptor,
1417
0
           NULL );
1418
1419
0
          goto on_error;
1420
0
        }
1421
20.8k
        sub_key_descriptor = NULL;
1422
20.8k
      }
1423
20.2k
      else
1424
20.2k
      {
1425
20.2k
        result = libregf_key_item_read_sub_keys_list(
1426
20.2k
            sub_key_descriptors,
1427
20.2k
            file_io_handle,
1428
20.2k
            hive_bins_list,
1429
20.2k
                  (off64_t) sub_key_descriptor->key_offset,
1430
20.2k
                  recursion_depth + 1,
1431
20.2k
            error );
1432
1433
20.2k
        if( result == -1 )
1434
4.40k
        {
1435
4.40k
          libcerror_error_set(
1436
4.40k
           error,
1437
4.40k
           LIBCERROR_ERROR_DOMAIN_IO,
1438
4.40k
           LIBCERROR_IO_ERROR_READ_FAILED,
1439
4.40k
           "%s: unable to read sub keys list at offset: %" PRIu32 " (0x%08" PRIx32 ").",
1440
4.40k
           function,
1441
4.40k
           sub_key_descriptor->key_offset,
1442
4.40k
           sub_key_descriptor->key_offset );
1443
1444
4.40k
          goto on_error;
1445
4.40k
        }
1446
20.2k
      }
1447
41.0k
    }
1448
71.5k
    if( result == 0 )
1449
40.3k
    {
1450
40.3k
      corruption_detected = 1;
1451
40.3k
    }
1452
71.5k
  }
1453
16.7k
  if( libregf_sub_key_list_free(
1454
16.7k
       &sub_key_list,
1455
16.7k
       error ) != 1 )
1456
0
  {
1457
0
    libcerror_error_set(
1458
0
     error,
1459
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1460
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1461
0
     "%s: unable to free sub key list.",
1462
0
     function );
1463
1464
0
    goto on_error;
1465
0
  }
1466
16.7k
  if( corruption_detected != 0 )
1467
6.22k
  {
1468
6.22k
    return( 0 );
1469
6.22k
  }
1470
10.5k
  return( 1 );
1471
1472
4.64k
on_error:
1473
4.64k
  if( sub_key_list != NULL )
1474
4.51k
  {
1475
4.51k
    libregf_sub_key_list_free(
1476
4.51k
     &sub_key_list,
1477
4.51k
     NULL );
1478
4.51k
  }
1479
4.64k
  libcdata_array_empty(
1480
4.64k
   sub_key_descriptors,
1481
4.64k
   (int (*)(intptr_t **, libcerror_error_t **)) &libregf_key_descriptor_free,
1482
4.64k
   NULL );
1483
1484
4.64k
  return( -1 );
1485
16.7k
}
1486
1487
/* Determines if the key item is corrupted
1488
 * Returns 1 if corrupted, 0 if not or -1 on error
1489
 */
1490
int libregf_key_item_is_corrupted(
1491
     libregf_key_item_t *key_item,
1492
     libcerror_error_t **error )
1493
0
{
1494
0
  static char *function = "libregf_key_item_is_corrupted";
1495
1496
0
  if( key_item == NULL )
1497
0
  {
1498
0
    libcerror_error_set(
1499
0
     error,
1500
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1501
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1502
0
     "%s: invalid key item.",
1503
0
     function );
1504
1505
0
    return( -1 );
1506
0
  }
1507
0
  if( ( key_item->item_flags & LIBREGF_ITEM_FLAG_IS_CORRUPTED ) != 0 )
1508
0
  {
1509
0
    return( 1 );
1510
0
  }
1511
0
  return( 0 );
1512
0
}
1513
1514
/* Retrieves the key name size
1515
 * Returns 1 if successful or -1 on error
1516
 */
1517
int libregf_key_item_get_name_size(
1518
     libregf_key_item_t *key_item,
1519
     size_t *name_size,
1520
     libcerror_error_t **error )
1521
0
{
1522
0
  static char *function = "libregf_key_item_get_name_size";
1523
1524
0
  if( key_item == NULL )
1525
0
  {
1526
0
    libcerror_error_set(
1527
0
     error,
1528
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1529
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1530
0
     "%s: invalid key item.",
1531
0
     function );
1532
1533
0
    return( -1 );
1534
0
  }
1535
0
  if( libregf_named_key_get_name_size(
1536
0
       key_item->named_key,
1537
0
       name_size,
1538
0
       error ) != 1 )
1539
0
  {
1540
0
    libcerror_error_set(
1541
0
     error,
1542
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1543
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1544
0
     "%s: unable to retrieve name size.",
1545
0
     function );
1546
1547
0
    return( -1 );
1548
0
  }
1549
0
  return( 1 );
1550
0
}
1551
1552
/* Retrieves the key name
1553
 * Returns 1 if successful or -1 on error
1554
 */
1555
int libregf_key_item_get_name(
1556
     libregf_key_item_t *key_item,
1557
     uint8_t *name,
1558
     size_t name_size,
1559
     libcerror_error_t **error )
1560
0
{
1561
0
  static char *function = "libregf_key_item_get_name";
1562
1563
0
  if( key_item == NULL )
1564
0
  {
1565
0
    libcerror_error_set(
1566
0
     error,
1567
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1568
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1569
0
     "%s: invalid key item.",
1570
0
     function );
1571
1572
0
    return( -1 );
1573
0
  }
1574
0
  if( libregf_named_key_get_name(
1575
0
       key_item->named_key,
1576
0
       name,
1577
0
       name_size,
1578
0
       error ) != 1 )
1579
0
  {
1580
0
    libcerror_error_set(
1581
0
     error,
1582
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1583
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1584
0
     "%s: unable to retrieve name.",
1585
0
     function );
1586
1587
0
    return( -1 );
1588
0
  }
1589
0
  return( 1 );
1590
0
}
1591
1592
/* Retrieves the UTF-8 string size of the key name
1593
 * The returned size includes the end of string character
1594
 * Returns 1 if successful or -1 on error
1595
 */
1596
int libregf_key_item_get_utf8_name_size(
1597
     libregf_key_item_t *key_item,
1598
     size_t *utf8_string_size,
1599
     int ascii_codepage,
1600
     libcerror_error_t **error )
1601
0
{
1602
0
  static char *function = "libregf_key_item_get_utf8_name_size";
1603
1604
0
  if( key_item == NULL )
1605
0
  {
1606
0
    libcerror_error_set(
1607
0
     error,
1608
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1609
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1610
0
     "%s: invalid key item.",
1611
0
     function );
1612
1613
0
    return( -1 );
1614
0
  }
1615
0
  if( libregf_named_key_get_utf8_name_size(
1616
0
       key_item->named_key,
1617
0
       utf8_string_size,
1618
0
       ascii_codepage,
1619
0
       error ) != 1 )
1620
0
  {
1621
0
    libcerror_error_set(
1622
0
     error,
1623
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1624
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1625
0
     "%s: unable to retrieve UTF-8 name size.",
1626
0
     function );
1627
1628
0
    return( -1 );
1629
0
  }
1630
0
  return( 1 );
1631
0
}
1632
1633
/* Retrieves the UTF-8 string value of the key name
1634
 * The function uses a codepage if necessary, it uses the codepage set for the library
1635
 * The size should include the end of string character
1636
 * Returns 1 if successful or -1 on error
1637
 */
1638
int libregf_key_item_get_utf8_name(
1639
     libregf_key_item_t *key_item,
1640
     uint8_t *utf8_string,
1641
     size_t utf8_string_size,
1642
     int ascii_codepage,
1643
     libcerror_error_t **error )
1644
0
{
1645
0
  static char *function = "libregf_key_item_get_utf8_name";
1646
1647
0
  if( key_item == NULL )
1648
0
  {
1649
0
    libcerror_error_set(
1650
0
     error,
1651
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1652
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1653
0
     "%s: invalid key item.",
1654
0
     function );
1655
1656
0
    return( -1 );
1657
0
  }
1658
0
  if( libregf_named_key_get_utf8_name(
1659
0
       key_item->named_key,
1660
0
       utf8_string,
1661
0
       utf8_string_size,
1662
0
       ascii_codepage,
1663
0
       error ) != 1 )
1664
0
  {
1665
0
    libcerror_error_set(
1666
0
     error,
1667
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1668
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1669
0
     "%s: unable to retrieve UTF-8 name.",
1670
0
     function );
1671
1672
0
    return( -1 );
1673
0
  }
1674
0
  return( 1 );
1675
0
}
1676
1677
/* Retrieves the UTF-16 string size of the key name
1678
 * The returned size includes the end of string character
1679
 * Returns 1 if successful or -1 on error
1680
 */
1681
int libregf_key_item_get_utf16_name_size(
1682
     libregf_key_item_t *key_item,
1683
     size_t *utf16_string_size,
1684
     int ascii_codepage,
1685
     libcerror_error_t **error )
1686
0
{
1687
0
  static char *function = "libregf_key_item_get_utf16_name_size";
1688
1689
0
  if( key_item == NULL )
1690
0
  {
1691
0
    libcerror_error_set(
1692
0
     error,
1693
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1694
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1695
0
     "%s: invalid key item.",
1696
0
     function );
1697
1698
0
    return( -1 );
1699
0
  }
1700
0
  if( libregf_named_key_get_utf16_name_size(
1701
0
       key_item->named_key,
1702
0
       utf16_string_size,
1703
0
       ascii_codepage,
1704
0
       error ) != 1 )
1705
0
  {
1706
0
    libcerror_error_set(
1707
0
     error,
1708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1709
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1710
0
     "%s: unable to retrieve UTF-16 name size.",
1711
0
     function );
1712
1713
0
    return( -1 );
1714
0
  }
1715
0
  return( 1 );
1716
0
}
1717
1718
/* Retrieves the UTF-16 string value of the key name
1719
 * The function uses a codepage if necessary, it uses the codepage set for the library
1720
 * The size should include the end of string character
1721
 * Returns 1 if successful or -1 on error
1722
 */
1723
int libregf_key_item_get_utf16_name(
1724
     libregf_key_item_t *key_item,
1725
     uint16_t *utf16_string,
1726
     size_t utf16_string_size,
1727
     int ascii_codepage,
1728
     libcerror_error_t **error )
1729
0
{
1730
0
  static char *function = "libregf_key_item_get_utf16_name";
1731
1732
0
  if( key_item == NULL )
1733
0
  {
1734
0
    libcerror_error_set(
1735
0
     error,
1736
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1737
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1738
0
     "%s: invalid key item.",
1739
0
     function );
1740
1741
0
    return( -1 );
1742
0
  }
1743
0
  if( libregf_named_key_get_utf16_name(
1744
0
       key_item->named_key,
1745
0
       utf16_string,
1746
0
       utf16_string_size,
1747
0
       ascii_codepage,
1748
0
       error ) != 1 )
1749
0
  {
1750
0
    libcerror_error_set(
1751
0
     error,
1752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1753
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1754
0
     "%s: unable to retrieve UTF-16 name.",
1755
0
     function );
1756
1757
0
    return( -1 );
1758
0
  }
1759
0
  return( 1 );
1760
0
}
1761
1762
/* Retrieves the class name size
1763
 * Returns 1 if successful, 0 if no such value or -1 on error
1764
 */
1765
int libregf_key_item_get_class_name_size(
1766
     libregf_key_item_t *key_item,
1767
     size_t *class_name_size,
1768
     libcerror_error_t **error )
1769
0
{
1770
0
  static char *function = "libregf_key_item_get_class_name_size";
1771
1772
0
  if( key_item == NULL )
1773
0
  {
1774
0
    libcerror_error_set(
1775
0
     error,
1776
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1777
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1778
0
     "%s: invalid key item.",
1779
0
     function );
1780
1781
0
    return( -1 );
1782
0
  }
1783
0
  if( class_name_size == NULL )
1784
0
  {
1785
0
    libcerror_error_set(
1786
0
     error,
1787
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1788
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1789
0
     "%s: invalid class name size.",
1790
0
     function );
1791
1792
0
    return( -1 );
1793
0
  }
1794
0
  if( ( key_item->class_name == NULL )
1795
0
   || ( key_item->class_name_size == 0 ) )
1796
0
  {
1797
0
    return( 0 );
1798
0
  }
1799
0
  *class_name_size = key_item->class_name_size;
1800
1801
0
  return( 1 );
1802
0
}
1803
1804
/* Retrieves the class name
1805
 * Returns 1 if successful, 0 if no such value or -1 on error
1806
 */
1807
int libregf_key_item_get_class_name(
1808
     libregf_key_item_t *key_item,
1809
     uint8_t *class_name,
1810
     size_t class_name_size,
1811
     libcerror_error_t **error )
1812
0
{
1813
0
  static char *function = "libregf_key_item_get_class_name";
1814
1815
0
  if( key_item == NULL )
1816
0
  {
1817
0
    libcerror_error_set(
1818
0
     error,
1819
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1820
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1821
0
     "%s: invalid key item.",
1822
0
     function );
1823
1824
0
    return( -1 );
1825
0
  }
1826
0
  if( class_name == NULL )
1827
0
  {
1828
0
    libcerror_error_set(
1829
0
     error,
1830
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1831
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1832
0
     "%s: invalid class name.",
1833
0
     function );
1834
1835
0
    return( -1 );
1836
0
  }
1837
0
  if( class_name_size > (size_t) SSIZE_MAX )
1838
0
  {
1839
0
    libcerror_error_set(
1840
0
     error,
1841
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1842
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1843
0
     "%s: invalid class name size value exceeds maximum.",
1844
0
     function );
1845
1846
0
    return( -1 );
1847
0
  }
1848
0
  if( ( key_item->class_name == NULL )
1849
0
   || ( key_item->class_name_size == 0 ) )
1850
0
  {
1851
0
    return( 0 );
1852
0
  }
1853
0
  if( class_name_size < key_item->class_name_size )
1854
0
  {
1855
0
    libcerror_error_set(
1856
0
     error,
1857
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1858
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1859
0
     "%s: invalid class name size value out of bounds.",
1860
0
     function );
1861
1862
0
    return( -1 );
1863
0
  }
1864
0
  if( memory_copy(
1865
0
       class_name,
1866
0
       key_item->class_name,
1867
0
       key_item->class_name_size ) == NULL )
1868
0
  {
1869
0
    libcerror_error_set(
1870
0
     error,
1871
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1872
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1873
0
     "%s: unable to copy class name.",
1874
0
     function );
1875
1876
0
    return( -1 );
1877
0
  }
1878
0
  return( 1 );
1879
0
}
1880
1881
/* Retrieves the UTF-8 string size of the class name
1882
 * The returned size includes the end of string character
1883
 * Returns 1 if successful, 0 if no such value or -1 on error
1884
 */
1885
int libregf_key_item_get_utf8_class_name_size(
1886
     libregf_key_item_t *key_item,
1887
     size_t *utf8_string_size,
1888
     int ascii_codepage,
1889
     libcerror_error_t **error )
1890
0
{
1891
0
  static char *function = "libregf_key_item_get_utf8_class_name_size";
1892
1893
0
  if( key_item == NULL )
1894
0
  {
1895
0
    libcerror_error_set(
1896
0
     error,
1897
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1898
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1899
0
     "%s: invalid key item.",
1900
0
     function );
1901
1902
0
    return( -1 );
1903
0
  }
1904
0
  if( ( key_item->class_name == NULL )
1905
0
   || ( key_item->class_name_size == 0 ) )
1906
0
  {
1907
0
    return( 0 );
1908
0
  }
1909
0
  if( libuna_utf8_string_size_from_utf16_stream(
1910
0
       key_item->class_name,
1911
0
       (size_t) key_item->class_name_size,
1912
0
       LIBUNA_ENDIAN_LITTLE,
1913
0
       utf8_string_size,
1914
0
       error ) != 1 )
1915
0
  {
1916
0
    libcerror_error_set(
1917
0
     error,
1918
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1919
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1920
0
     "%s: unable to retrieve UTF-8 string size.",
1921
0
     function );
1922
1923
0
    return( -1 );
1924
0
  }
1925
0
  return( 1 );
1926
0
}
1927
1928
/* Retrieves the UTF-8 string value of the class name
1929
 * The function uses a codepage if necessary, it uses the codepage set for the library
1930
 * The size should include the end of string character
1931
 * Returns 1 if successful, 0 if no such value or -1 on error
1932
 */
1933
int libregf_key_item_get_utf8_class_name(
1934
     libregf_key_item_t *key_item,
1935
     uint8_t *utf8_string,
1936
     size_t utf8_string_size,
1937
     int ascii_codepage,
1938
     libcerror_error_t **error )
1939
0
{
1940
0
  static char *function = "libregf_key_item_get_utf8_class_name";
1941
1942
0
  if( key_item == NULL )
1943
0
  {
1944
0
    libcerror_error_set(
1945
0
     error,
1946
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1947
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1948
0
     "%s: invalid key item.",
1949
0
     function );
1950
1951
0
    return( -1 );
1952
0
  }
1953
0
  if( ( key_item->class_name == NULL )
1954
0
   || ( key_item->class_name_size == 0 ) )
1955
0
  {
1956
0
    return( 0 );
1957
0
  }
1958
0
  if( libuna_utf8_string_copy_from_utf16_stream(
1959
0
       utf8_string,
1960
0
       utf8_string_size,
1961
0
       key_item->class_name,
1962
0
       (size_t) key_item->class_name_size,
1963
0
       LIBUNA_ENDIAN_LITTLE,
1964
0
       error ) != 1 )
1965
0
  {
1966
0
    libcerror_error_set(
1967
0
     error,
1968
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1969
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1970
0
     "%s: unable to retrieve UTF-8 string.",
1971
0
     function );
1972
1973
0
    return( 1 );
1974
0
  }
1975
0
  return( 1 );
1976
0
}
1977
1978
/* Retrieves the UTF-16 string size of the class name
1979
 * The returned size includes the end of string character
1980
 * Returns 1 if successful, 0 if no such value or -1 on error
1981
 */
1982
int libregf_key_item_get_utf16_class_name_size(
1983
     libregf_key_item_t *key_item,
1984
     size_t *utf16_string_size,
1985
     int ascii_codepage,
1986
     libcerror_error_t **error )
1987
0
{
1988
0
  static char *function = "libregf_key_item_get_utf16_class_name_size";
1989
1990
0
  if( key_item == NULL )
1991
0
  {
1992
0
    libcerror_error_set(
1993
0
     error,
1994
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1995
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1996
0
     "%s: invalid key item.",
1997
0
     function );
1998
1999
0
    return( -1 );
2000
0
  }
2001
0
  if( ( key_item->class_name == NULL )
2002
0
   || ( key_item->class_name_size == 0 ) )
2003
0
  {
2004
0
    return( 0 );
2005
0
  }
2006
0
  if( libuna_utf16_string_size_from_utf16_stream(
2007
0
       key_item->class_name,
2008
0
       (size_t) key_item->class_name_size,
2009
0
       LIBUNA_ENDIAN_LITTLE,
2010
0
       utf16_string_size,
2011
0
       error ) != 1 )
2012
0
  {
2013
0
    libcerror_error_set(
2014
0
     error,
2015
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2016
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2017
0
     "%s: unable to retrieve UTF-16 string size.",
2018
0
     function );
2019
2020
0
    return( -1 );
2021
0
  }
2022
0
  return( 1 );
2023
0
}
2024
2025
/* Retrieves the UTF-16 string value of the class name
2026
 * The function uses a codepage if necessary, it uses the codepage set for the library
2027
 * The size should include the end of string character
2028
 * Returns 1 if successful, 0 if no such value or -1 on error
2029
 */
2030
int libregf_key_item_get_utf16_class_name(
2031
     libregf_key_item_t *key_item,
2032
     uint16_t *utf16_string,
2033
     size_t utf16_string_size,
2034
     int ascii_codepage,
2035
     libcerror_error_t **error )
2036
0
{
2037
0
  static char *function = "libregf_key_item_get_utf16_class_name";
2038
2039
0
  if( key_item == NULL )
2040
0
  {
2041
0
    libcerror_error_set(
2042
0
     error,
2043
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2044
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2045
0
     "%s: invalid key item.",
2046
0
     function );
2047
2048
0
    return( -1 );
2049
0
  }
2050
0
  if( ( key_item->class_name == NULL )
2051
0
   || ( key_item->class_name_size == 0 ) )
2052
0
  {
2053
0
    return( 0 );
2054
0
  }
2055
0
  if( libuna_utf16_string_copy_from_utf16_stream(
2056
0
       utf16_string,
2057
0
       utf16_string_size,
2058
0
       key_item->class_name,
2059
0
       (size_t) key_item->class_name_size,
2060
0
       LIBUNA_ENDIAN_LITTLE,
2061
0
       error ) != 1 )
2062
0
  {
2063
0
    libcerror_error_set(
2064
0
     error,
2065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2066
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2067
0
     "%s: unable to retrieve UTF-16 string.",
2068
0
     function );
2069
2070
0
    return( 1 );
2071
0
  }
2072
0
  return( 1 );
2073
0
}
2074
2075
/* Retrieves the 64-bit FILETIME value of the last written date and time
2076
 * Returns 1 if successful or -1 on error
2077
 */
2078
int libregf_key_item_get_last_written_time(
2079
     libregf_key_item_t *key_item,
2080
     uint64_t *filetime,
2081
     libcerror_error_t **error )
2082
0
{
2083
0
  static char *function = "libregf_key_item_get_last_written_time";
2084
2085
0
  if( key_item == NULL )
2086
0
  {
2087
0
    libcerror_error_set(
2088
0
     error,
2089
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2090
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2091
0
     "%s: invalid key item.",
2092
0
     function );
2093
2094
0
    return( -1 );
2095
0
  }
2096
0
  if( libregf_named_key_get_last_written_time(
2097
0
       key_item->named_key,
2098
0
       filetime,
2099
0
       error ) != 1 )
2100
0
  {
2101
0
    libcerror_error_set(
2102
0
     error,
2103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2104
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2105
0
     "%s: unable to retrieve last written time.",
2106
0
     function );
2107
2108
0
    return( -1 );
2109
0
  }
2110
0
  return( 1 );
2111
0
}
2112
2113
/* Retrieves the security descriptor size
2114
 * Returns 1 if successful, 0 if no such value or -1 on error
2115
 */
2116
int libregf_key_item_get_security_descriptor_size(
2117
     libregf_key_item_t *key_item,
2118
     size_t *security_descriptor_size,
2119
     libcerror_error_t **error )
2120
0
{
2121
0
  static char *function = "libregf_key_item_get_security_descriptor_size";
2122
2123
0
  if( key_item == NULL )
2124
0
  {
2125
0
    libcerror_error_set(
2126
0
     error,
2127
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2128
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2129
0
     "%s: invalid key item.",
2130
0
     function );
2131
2132
0
    return( -1 );
2133
0
  }
2134
0
  if( security_descriptor_size == NULL )
2135
0
  {
2136
0
    libcerror_error_set(
2137
0
     error,
2138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2139
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2140
0
     "%s: invalid security descriptor size.",
2141
0
     function );
2142
2143
0
    return( -1 );
2144
0
  }
2145
0
  if( ( key_item->security_descriptor == NULL )
2146
0
   || ( key_item->security_descriptor_size == 0 ) )
2147
0
  {
2148
0
    return( 0 );
2149
0
  }
2150
0
  *security_descriptor_size = key_item->security_descriptor_size;
2151
2152
0
  return( 1 );
2153
0
}
2154
2155
/* Retrieves the security descriptor
2156
 * Returns 1 if successful, 0 if no such value or -1 on error
2157
 */
2158
int libregf_key_item_get_security_descriptor(
2159
     libregf_key_item_t *key_item,
2160
     uint8_t *security_descriptor,
2161
     size_t security_descriptor_size,
2162
     libcerror_error_t **error )
2163
0
{
2164
0
  static char *function = "libregf_key_item_get_security_descriptor";
2165
2166
0
  if( key_item == NULL )
2167
0
  {
2168
0
    libcerror_error_set(
2169
0
     error,
2170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2172
0
     "%s: invalid key item.",
2173
0
     function );
2174
2175
0
    return( -1 );
2176
0
  }
2177
0
  if( security_descriptor == NULL )
2178
0
  {
2179
0
    libcerror_error_set(
2180
0
     error,
2181
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2182
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2183
0
     "%s: invalid security descriptor.",
2184
0
     function );
2185
2186
0
    return( -1 );
2187
0
  }
2188
0
  if( security_descriptor_size > (size_t) SSIZE_MAX )
2189
0
  {
2190
0
    libcerror_error_set(
2191
0
     error,
2192
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2193
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2194
0
     "%s: invalid security descriptor size value exceeds maximum.",
2195
0
     function );
2196
2197
0
    return( -1 );
2198
0
  }
2199
0
  if( ( key_item->security_descriptor == NULL )
2200
0
   || ( key_item->security_descriptor_size == 0 ) )
2201
0
  {
2202
0
    return( 0 );
2203
0
  }
2204
0
  if( security_descriptor_size < key_item->security_descriptor_size )
2205
0
  {
2206
0
    libcerror_error_set(
2207
0
     error,
2208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2209
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2210
0
     "%s: invalid security descriptor size value out of bounds.",
2211
0
     function );
2212
2213
0
    return( -1 );
2214
0
  }
2215
0
  if( memory_copy(
2216
0
       security_descriptor,
2217
0
       key_item->security_descriptor,
2218
0
       key_item->security_descriptor_size ) == NULL )
2219
0
  {
2220
0
    libcerror_error_set(
2221
0
     error,
2222
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2223
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2224
0
     "%s: unable to copy security descriptor.",
2225
0
     function );
2226
2227
0
    return( -1 );
2228
0
  }
2229
0
  return( 1 );
2230
0
}
2231
2232
/* Retrieves the number of values
2233
 * Returns 1 if successful or -1 on error
2234
 */
2235
int libregf_key_item_get_number_of_values(
2236
     libregf_key_item_t *key_item,
2237
     int *number_of_values,
2238
     libcerror_error_t **error )
2239
400
{
2240
400
  static char *function = "libregf_key_item_get_number_of_values";
2241
2242
400
  if( key_item == NULL )
2243
0
  {
2244
0
    libcerror_error_set(
2245
0
     error,
2246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2248
0
     "%s: invalid key item.",
2249
0
     function );
2250
2251
0
    return( -1 );
2252
0
  }
2253
400
  if( libfdata_list_get_number_of_elements(
2254
400
       key_item->values_list,
2255
400
       number_of_values,
2256
400
       error ) != 1 )
2257
0
  {
2258
0
    libcerror_error_set(
2259
0
     error,
2260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2261
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2262
0
     "%s: unable to retrieve number of elements from values data list.",
2263
0
     function );
2264
2265
0
    return( -1 );
2266
0
  }
2267
400
  return( 1 );
2268
400
}
2269
2270
/* Retrieves the number of sub key descriptors
2271
 * Returns 1 if successful or -1 on error
2272
 */
2273
int libregf_key_item_get_number_of_sub_key_descriptors(
2274
     libregf_key_item_t *key_item,
2275
     int *number_of_sub_key_descriptors,
2276
     libcerror_error_t **error )
2277
551
{
2278
551
  static char *function = "libregf_key_item_get_number_of_sub_key_descriptors";
2279
2280
551
  if( key_item == NULL )
2281
0
  {
2282
0
    libcerror_error_set(
2283
0
     error,
2284
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2285
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2286
0
     "%s: invalid key item.",
2287
0
     function );
2288
2289
0
    return( -1 );
2290
0
  }
2291
551
  if( libcdata_array_get_number_of_entries(
2292
551
       key_item->sub_key_descriptors,
2293
551
       number_of_sub_key_descriptors,
2294
551
       error ) != 1 )
2295
0
  {
2296
0
    libcerror_error_set(
2297
0
     error,
2298
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2299
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2300
0
     "%s: unable to retrieve number of sub key descriptors.",
2301
0
     function );
2302
2303
0
    return( -1 );
2304
0
  }
2305
551
  return( 1 );
2306
551
}
2307
2308
/* Retrieves a specific sub key descriptor
2309
 * Returns 1 if successful or -1 on error
2310
 */
2311
int libregf_key_item_get_sub_key_descriptor_by_index(
2312
     libregf_key_item_t *key_item,
2313
     int sub_key_descriptor_index,
2314
     libregf_key_descriptor_t **sub_key_descriptor,
2315
     libcerror_error_t **error )
2316
514
{
2317
514
  static char *function = "libregf_key_item_get_sub_key_descriptor_by_index";
2318
2319
514
  if( key_item == NULL )
2320
0
  {
2321
0
    libcerror_error_set(
2322
0
     error,
2323
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2324
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2325
0
     "%s: invalid key item.",
2326
0
     function );
2327
2328
0
    return( -1 );
2329
0
  }
2330
514
  if( libcdata_array_get_entry_by_index(
2331
514
       key_item->sub_key_descriptors,
2332
514
             sub_key_descriptor_index,
2333
514
       (intptr_t **) sub_key_descriptor,
2334
514
       error ) != 1 )
2335
0
  {
2336
0
    libcerror_error_set(
2337
0
     error,
2338
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2339
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2340
0
     "%s: unable to retrieve sub key descriptor: %d.",
2341
0
     function,
2342
0
     sub_key_descriptor_index );
2343
2344
0
    return( -1 );
2345
0
  }
2346
514
  return( 1 );
2347
514
}
2348
2349
/* Retrieves the sub key descriptor for the specific UTF-8 encoded name
2350
 * Returns 1 if successful, 0 if no such value or -1 on error
2351
 */
2352
int libregf_key_item_get_sub_key_descriptor_by_utf8_name(
2353
     libregf_key_item_t *key_item,
2354
     libbfio_handle_t *file_io_handle,
2355
     libregf_hive_bins_list_t *hive_bins_list,
2356
     uint32_t name_hash,
2357
     const uint8_t *utf8_string,
2358
     size_t utf8_string_length,
2359
     libregf_key_descriptor_t **sub_key_descriptor,
2360
     libcerror_error_t **error )
2361
0
{
2362
0
  libregf_key_descriptor_t *safe_sub_key_descriptor = NULL;
2363
0
  libregf_named_key_t *named_key                    = NULL;
2364
0
  static char *function                             = "libregf_key_item_get_sub_key_descriptor_by_utf8_name";
2365
0
  int number_of_sub_key_descriptors                 = 0;
2366
0
  int result                                        = 0;
2367
0
  int sub_key_descriptor_index                      = 0;
2368
2369
0
  if( key_item == NULL )
2370
0
  {
2371
0
    libcerror_error_set(
2372
0
     error,
2373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2375
0
     "%s: invalid key item.",
2376
0
     function );
2377
2378
0
    return( -1 );
2379
0
  }
2380
0
  if( hive_bins_list == NULL )
2381
0
  {
2382
0
    libcerror_error_set(
2383
0
     error,
2384
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2385
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2386
0
     "%s: invalid hive bins list.",
2387
0
     function );
2388
2389
0
    return( -1 );
2390
0
  }
2391
0
  if( hive_bins_list->io_handle == NULL )
2392
0
  {
2393
0
    libcerror_error_set(
2394
0
     error,
2395
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2396
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2397
0
     "%s: invalid hive bins list - missing IO handle.",
2398
0
     function );
2399
2400
0
    return( -1 );
2401
0
  }
2402
0
  *sub_key_descriptor = NULL;
2403
2404
/* TODO think of caching and/or optimization
2405
 * e.g. mapping sub key descriptors to name search tree?
2406
 */
2407
0
  if( libcdata_array_get_number_of_entries(
2408
0
       key_item->sub_key_descriptors,
2409
0
       &number_of_sub_key_descriptors,
2410
0
       error ) != 1 )
2411
0
  {
2412
0
    libcerror_error_set(
2413
0
     error,
2414
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2415
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2416
0
     "%s: unable to retrieve number of entries from sub key descriptors array.",
2417
0
     function );
2418
2419
0
    goto on_error;
2420
0
  }
2421
0
  for( sub_key_descriptor_index = 0;
2422
0
       sub_key_descriptor_index < number_of_sub_key_descriptors;
2423
0
       sub_key_descriptor_index++ )
2424
0
  {
2425
0
    if( libcdata_array_get_entry_by_index(
2426
0
         key_item->sub_key_descriptors,
2427
0
         sub_key_descriptor_index,
2428
0
         (intptr_t **) &safe_sub_key_descriptor,
2429
0
         error ) != 1 )
2430
0
    {
2431
0
      libcerror_error_set(
2432
0
       error,
2433
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2434
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2435
0
       "%s: unable to retrieve sub key descriptor: %d from array.",
2436
0
       function,
2437
0
       sub_key_descriptor_index );
2438
2439
0
      goto on_error;
2440
0
    }
2441
0
    if( safe_sub_key_descriptor == NULL )
2442
0
    {
2443
0
      libcerror_error_set(
2444
0
       error,
2445
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2446
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2447
0
       "%s: missing sub key descriptor: %d.",
2448
0
       function,
2449
0
       sub_key_descriptor_index );
2450
2451
0
      goto on_error;
2452
0
    }
2453
0
    if( libregf_named_key_initialize(
2454
0
         &named_key,
2455
0
         error ) != 1 )
2456
0
    {
2457
0
      libcerror_error_set(
2458
0
       error,
2459
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2460
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2461
0
       "%s: unable to create named key.",
2462
0
       function );
2463
2464
0
      goto on_error;
2465
0
    }
2466
0
    if( libregf_key_item_read_named_key(
2467
0
         named_key,
2468
0
         file_io_handle,
2469
0
         hive_bins_list,
2470
0
         safe_sub_key_descriptor->key_offset,
2471
0
         safe_sub_key_descriptor->hash_value,
2472
0
         error ) != 1 )
2473
0
    {
2474
0
      libcerror_error_set(
2475
0
       error,
2476
0
       LIBCERROR_ERROR_DOMAIN_IO,
2477
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2478
0
       "%s: unable to read named key at offset: %" PRIu32 " (0x%08" PRIx32 ").",
2479
0
       function,
2480
0
       safe_sub_key_descriptor->key_offset,
2481
0
       safe_sub_key_descriptor->key_offset );
2482
2483
0
      goto on_error;
2484
0
    }
2485
0
    result = libregf_named_key_compare_name_with_utf8_string(
2486
0
              named_key,
2487
0
              name_hash,
2488
0
              utf8_string,
2489
0
              utf8_string_length,
2490
0
              hive_bins_list->io_handle->ascii_codepage,
2491
0
              error );
2492
2493
0
    if( result == -1 )
2494
0
    {
2495
0
      libcerror_error_set(
2496
0
       error,
2497
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2498
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2499
0
       "%s: unable to compare named key with UTF-8 string.",
2500
0
       function );
2501
2502
0
      goto on_error;
2503
0
    }
2504
0
    if( libregf_named_key_free(
2505
0
         &named_key,
2506
0
         error ) != 1 )
2507
0
    {
2508
0
      libcerror_error_set(
2509
0
       error,
2510
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2511
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2512
0
       "%s: unable to free named key.",
2513
0
       function );
2514
2515
0
      goto on_error;
2516
0
    }
2517
0
    if( result != 0 )
2518
0
    {
2519
0
      break;
2520
0
    }
2521
0
  }
2522
0
  if( sub_key_descriptor_index >= number_of_sub_key_descriptors )
2523
0
  {
2524
0
    return( 0 );
2525
0
  }
2526
0
  *sub_key_descriptor = safe_sub_key_descriptor;
2527
2528
0
  return( 1 );
2529
2530
0
on_error:
2531
0
  if( named_key != NULL )
2532
0
  {
2533
0
    libregf_named_key_free(
2534
0
     &named_key,
2535
0
     NULL );
2536
0
  }
2537
0
  return( -1 );
2538
0
}
2539
2540
/* Retrieves the sub key descriptor for the specific UTF-16 encoded name
2541
 * Returns 1 if successful, 0 if no such value or -1 on error
2542
 */
2543
int libregf_key_item_get_sub_key_descriptor_by_utf16_name(
2544
     libregf_key_item_t *key_item,
2545
     libbfio_handle_t *file_io_handle,
2546
     libregf_hive_bins_list_t *hive_bins_list,
2547
     uint32_t name_hash,
2548
     const uint16_t *utf16_string,
2549
     size_t utf16_string_length,
2550
     libregf_key_descriptor_t **sub_key_descriptor,
2551
     libcerror_error_t **error )
2552
0
{
2553
0
  libregf_key_descriptor_t *safe_sub_key_descriptor = NULL;
2554
0
  libregf_named_key_t *named_key                    = NULL;
2555
0
  static char *function                             = "libregf_key_item_get_sub_key_descriptor_by_utf16_name";
2556
0
  int number_of_sub_key_descriptors                 = 0;
2557
0
  int result                                        = 0;
2558
0
  int sub_key_descriptor_index                      = 0;
2559
2560
0
  if( key_item == NULL )
2561
0
  {
2562
0
    libcerror_error_set(
2563
0
     error,
2564
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2565
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2566
0
     "%s: invalid key item.",
2567
0
     function );
2568
2569
0
    return( -1 );
2570
0
  }
2571
0
  if( hive_bins_list == NULL )
2572
0
  {
2573
0
    libcerror_error_set(
2574
0
     error,
2575
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2576
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2577
0
     "%s: invalid hive bins list.",
2578
0
     function );
2579
2580
0
    return( -1 );
2581
0
  }
2582
0
  if( hive_bins_list->io_handle == NULL )
2583
0
  {
2584
0
    libcerror_error_set(
2585
0
     error,
2586
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2587
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2588
0
     "%s: invalid hive bins list - missing IO handle.",
2589
0
     function );
2590
2591
0
    return( -1 );
2592
0
  }
2593
0
  *sub_key_descriptor = NULL;
2594
2595
/* TODO think of caching and/or optimization
2596
 * e.g. mapping sub key descriptors to name search tree?
2597
 */
2598
0
  if( libcdata_array_get_number_of_entries(
2599
0
       key_item->sub_key_descriptors,
2600
0
       &number_of_sub_key_descriptors,
2601
0
       error ) != 1 )
2602
0
  {
2603
0
    libcerror_error_set(
2604
0
     error,
2605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2606
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2607
0
     "%s: unable to retrieve number of entries from sub key descriptors array.",
2608
0
     function );
2609
2610
0
    goto on_error;
2611
0
  }
2612
0
  for( sub_key_descriptor_index = 0;
2613
0
       sub_key_descriptor_index < number_of_sub_key_descriptors;
2614
0
       sub_key_descriptor_index++ )
2615
0
  {
2616
0
    if( libcdata_array_get_entry_by_index(
2617
0
         key_item->sub_key_descriptors,
2618
0
         sub_key_descriptor_index,
2619
0
         (intptr_t **) &safe_sub_key_descriptor,
2620
0
         error ) != 1 )
2621
0
    {
2622
0
      libcerror_error_set(
2623
0
       error,
2624
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2626
0
       "%s: unable to retrieve sub key descriptor: %d from array.",
2627
0
       function,
2628
0
       sub_key_descriptor_index );
2629
2630
0
      goto on_error;
2631
0
    }
2632
0
    if( safe_sub_key_descriptor == NULL )
2633
0
    {
2634
0
      libcerror_error_set(
2635
0
       error,
2636
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2637
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2638
0
       "%s: missing sub key descriptor: %d.",
2639
0
       function,
2640
0
       sub_key_descriptor_index );
2641
2642
0
      goto on_error;
2643
0
    }
2644
0
    if( libregf_named_key_initialize(
2645
0
         &named_key,
2646
0
         error ) != 1 )
2647
0
    {
2648
0
      libcerror_error_set(
2649
0
       error,
2650
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2651
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2652
0
       "%s: unable to create named key.",
2653
0
       function );
2654
2655
0
      goto on_error;
2656
0
    }
2657
0
    if( libregf_key_item_read_named_key(
2658
0
         named_key,
2659
0
         file_io_handle,
2660
0
         hive_bins_list,
2661
0
         safe_sub_key_descriptor->key_offset,
2662
0
         safe_sub_key_descriptor->hash_value,
2663
0
         error ) != 1 )
2664
0
    {
2665
0
      libcerror_error_set(
2666
0
       error,
2667
0
       LIBCERROR_ERROR_DOMAIN_IO,
2668
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2669
0
       "%s: unable to read named key at offset: %" PRIu32 " (0x%08" PRIx32 ").",
2670
0
       function,
2671
0
       safe_sub_key_descriptor->key_offset,
2672
0
       safe_sub_key_descriptor->key_offset );
2673
2674
0
      goto on_error;
2675
0
    }
2676
0
    result = libregf_named_key_compare_name_with_utf16_string(
2677
0
              named_key,
2678
0
              name_hash,
2679
0
              utf16_string,
2680
0
              utf16_string_length,
2681
0
              hive_bins_list->io_handle->ascii_codepage,
2682
0
              error );
2683
2684
0
    if( result == -1 )
2685
0
    {
2686
0
      libcerror_error_set(
2687
0
       error,
2688
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2689
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2690
0
       "%s: unable to compare named key with UTF-16 string.",
2691
0
       function );
2692
2693
0
      goto on_error;
2694
0
    }
2695
0
    if( libregf_named_key_free(
2696
0
         &named_key,
2697
0
         error ) != 1 )
2698
0
    {
2699
0
      libcerror_error_set(
2700
0
       error,
2701
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2702
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2703
0
       "%s: unable to free named key.",
2704
0
       function );
2705
2706
0
      goto on_error;
2707
0
    }
2708
0
    if( result != 0 )
2709
0
    {
2710
0
      break;
2711
0
    }
2712
0
  }
2713
0
  if( sub_key_descriptor_index >= number_of_sub_key_descriptors )
2714
0
  {
2715
0
    return( 0 );
2716
0
  }
2717
0
  *sub_key_descriptor = safe_sub_key_descriptor;
2718
2719
0
  return( 1 );
2720
2721
0
on_error:
2722
0
  if( named_key != NULL )
2723
0
  {
2724
0
    libregf_named_key_free(
2725
0
     &named_key,
2726
     NULL );
2727
0
  }
2728
0
  return( -1 );
2729
0
}
2730