Coverage Report

Created: 2025-08-28 07:10

/src/libregf/libregf/libregf_value_key.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Value key functions
3
 *
4
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#if defined( HAVE_WCTYPE_H )
28
#include <wctype.h>
29
#endif
30
31
#include "libregf_data_type.h"
32
#include "libregf_debug.h"
33
#include "libregf_definitions.h"
34
#include "libregf_io_handle.h"
35
#include "libregf_libcerror.h"
36
#include "libregf_libcnotify.h"
37
#include "libregf_libuna.h"
38
#include "libregf_value_key.h"
39
#include "libregf_unused.h"
40
41
#include "regf_cell_values.h"
42
43
/* Creates a value key
44
 * Make sure the value value_key is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libregf_value_key_initialize(
48
     libregf_value_key_t **value_key,
49
     libcerror_error_t **error )
50
589
{
51
589
  static char *function = "libregf_value_key_initialize";
52
53
589
  if( value_key == NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
58
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
59
0
     "%s: invalid value key.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
589
  if( *value_key != NULL )
65
0
  {
66
0
    libcerror_error_set(
67
0
     error,
68
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
69
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
70
0
     "%s: invalid value key value already set.",
71
0
     function );
72
73
0
    return( -1 );
74
0
  }
75
589
  *value_key = memory_allocate_structure(
76
589
                libregf_value_key_t );
77
78
589
  if( *value_key == NULL )
79
0
  {
80
0
    libcerror_error_set(
81
0
     error,
82
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
83
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
84
0
     "%s: unable to create value key.",
85
0
     function );
86
87
0
    goto on_error;
88
0
  }
89
589
  if( memory_set(
90
589
       *value_key,
91
589
       0,
92
589
       sizeof( libregf_value_key_t ) ) == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
97
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
98
0
     "%s: unable to clear value key.",
99
0
     function );
100
101
0
    goto on_error;
102
0
  }
103
589
  return( 1 );
104
105
0
on_error:
106
0
  if( *value_key != NULL )
107
0
  {
108
0
    memory_free(
109
0
     *value_key );
110
111
0
    *value_key = NULL;
112
0
  }
113
0
  return( -1 );
114
589
}
115
116
/* Frees a value key
117
 * Returns 1 if successful or -1 on error
118
 */
119
int libregf_value_key_free(
120
     libregf_value_key_t **value_key,
121
     libcerror_error_t **error )
122
589
{
123
589
  static char *function = "libregf_value_key_free";
124
125
589
  if( value_key == NULL )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
130
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
131
0
     "%s: invalid value key.",
132
0
     function );
133
134
0
    return( -1 );
135
0
  }
136
589
  if( *value_key != NULL )
137
589
  {
138
589
    if( ( *value_key )->name != NULL )
139
246
    {
140
246
      memory_free(
141
246
       ( *value_key )->name );
142
246
    }
143
589
    if( ( *value_key )->data != NULL )
144
0
    {
145
0
      memory_free(
146
0
       ( *value_key )->data );
147
0
    }
148
589
    memory_free(
149
589
     *value_key );
150
151
589
    *value_key = NULL;
152
589
  }
153
589
  return( 1 );
154
589
}
155
156
/* Clones (duplicates) the value key
157
 * Returns 1 if successful or -1 on error
158
 */
159
int libregf_value_key_clone(
160
     libregf_value_key_t **destination_value_key,
161
     libregf_value_key_t *source_value_key,
162
     libcerror_error_t **error )
163
239
{
164
239
  static char *function = "libregf_value_key_clone";
165
166
239
  if( destination_value_key == NULL )
167
0
  {
168
0
    libcerror_error_set(
169
0
     error,
170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
172
0
     "%s: invalid destination value key.",
173
0
     function );
174
175
0
    return( -1 );
176
0
  }
177
239
  if( *destination_value_key != NULL )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
182
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
183
0
     "%s: destination value key already set.",
184
0
     function );
185
186
0
    return( -1 );
187
0
  }
188
239
  if( source_value_key == NULL )
189
2
  {
190
2
    *destination_value_key = NULL;
191
192
2
    return( 1 );
193
2
  }
194
237
  if( libregf_value_key_initialize(
195
237
       destination_value_key,
196
237
       error ) != 1 )
197
0
  {
198
0
    libcerror_error_set(
199
0
     error,
200
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
201
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
202
0
     "%s: unable to create destination value key.",
203
0
     function );
204
205
0
    goto on_error;
206
0
  }
207
237
  if( source_value_key->name != NULL )
208
114
  {
209
114
    if( source_value_key->name_size == 0 )
210
0
    {
211
0
      libcerror_error_set(
212
0
       error,
213
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
214
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
215
0
       "%s: invalid source value key - invalid name size value out of bounds.",
216
0
       function );
217
218
0
      goto on_error;
219
0
    }
220
114
    ( *destination_value_key )->name = (uint8_t *) memory_allocate(
221
114
                                                    sizeof( uint8_t ) * (size_t) source_value_key->name_size );
222
223
114
    if( ( *destination_value_key )->name == NULL )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
228
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
229
0
       "%s: unable to create value name.",
230
0
       function );
231
232
0
      goto on_error;
233
0
    }
234
114
    if( memory_copy(
235
114
         ( *destination_value_key )->name,
236
114
         source_value_key->name,
237
114
         (size_t) source_value_key->name_size ) == NULL )
238
0
    {
239
0
      libcerror_error_set(
240
0
       error,
241
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
242
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
243
0
       "%s: unable to copy value name.",
244
0
       function );
245
246
0
      goto on_error;
247
0
    }
248
114
    ( *destination_value_key )->name_size = source_value_key->name_size;
249
114
    ( *destination_value_key )->name_hash = source_value_key->name_hash;
250
114
  }
251
237
  if( source_value_key->data != NULL )
252
0
  {
253
0
    if( ( source_value_key->data_size == 0 )
254
0
     || ( source_value_key->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
255
0
    {
256
0
      libcerror_error_set(
257
0
       error,
258
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
259
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
260
0
       "%s: invalid source value key - invalid data size value out of bounds.",
261
0
       function );
262
263
0
      goto on_error;
264
0
    }
265
0
    ( *destination_value_key )->data = (uint8_t *) memory_allocate(
266
0
                                                    sizeof( uint8_t ) * (size_t) source_value_key->data_size );
267
268
0
    if( ( *destination_value_key )->data == NULL )
269
0
    {
270
0
      libcerror_error_set(
271
0
       error,
272
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
273
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
274
0
       "%s: unable to create value data.",
275
0
       function );
276
277
0
      goto on_error;
278
0
    }
279
0
    if( memory_copy(
280
0
         ( *destination_value_key )->data,
281
0
         source_value_key->data,
282
0
         (size_t) source_value_key->data_size ) == NULL )
283
0
    {
284
0
      libcerror_error_set(
285
0
       error,
286
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
287
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
288
0
       "%s: unable to copy value data.",
289
0
       function );
290
291
0
      goto on_error;
292
0
    }
293
0
    ( *destination_value_key )->data_size = source_value_key->data_size;
294
0
  }
295
237
  ( *destination_value_key )->value_type  = source_value_key->value_type;
296
237
  ( *destination_value_key )->flags       = source_value_key->flags;
297
237
  ( *destination_value_key )->data_offset = source_value_key->data_offset;
298
237
  ( *destination_value_key )->data_in_key = source_value_key->data_in_key;
299
300
237
  return( 1 );
301
302
0
on_error:
303
0
  libregf_value_key_free(
304
0
   destination_value_key,
305
0
   NULL );
306
307
0
  return( -1 );
308
237
}
309
310
/* Reads a value key
311
 * Returns 1 if successful, 0 if the signature does not match or -1 on error
312
 */
313
int libregf_value_key_read_data(
314
     libregf_value_key_t *value_key,
315
     libregf_io_handle_t *io_handle,
316
     const uint8_t *data,
317
     size_t data_size,
318
     uint32_t value_key_hash LIBREGF_ATTRIBUTE_UNUSED,
319
     libcerror_error_t **error )
320
352
{
321
352
  static char *function                        = "libregf_value_key_read_data";
322
352
  libuna_unicode_character_t unicode_character = 0;
323
352
  size_t data_offset                           = 0;
324
352
  size_t name_index                            = 0;
325
352
  size_t value_key_data_size                   = 0;
326
352
  uint32_t value_data_offset                   = 0;
327
352
  uint8_t correct_string_size                  = 0;
328
352
  int result                                   = 0;
329
330
#if defined( HAVE_DEBUG_OUTPUT )
331
  uint32_t value_32bit                         = 0;
332
  uint16_t value_16bit                         = 0;
333
#endif
334
335
352
  LIBREGF_UNREFERENCED_PARAMETER( value_key_hash )
336
337
352
  if( value_key == NULL )
338
0
  {
339
0
    libcerror_error_set(
340
0
     error,
341
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
342
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
343
0
     "%s: invalid value key.",
344
0
     function );
345
346
0
    return( -1 );
347
0
  }
348
352
  if( value_key->name != NULL )
349
0
  {
350
0
    libcerror_error_set(
351
0
     error,
352
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
353
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
354
0
     "%s: invalid value key - name value already set.",
355
0
     function );
356
357
0
    return( -1 );
358
0
  }
359
352
  if( value_key->data != NULL )
360
0
  {
361
0
    libcerror_error_set(
362
0
     error,
363
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
364
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
365
0
     "%s: invalid value key - data value already set.",
366
0
     function );
367
368
0
    return( -1 );
369
0
  }
370
352
  if( io_handle == NULL )
371
0
  {
372
0
    libcerror_error_set(
373
0
     error,
374
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
375
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
376
0
     "%s: invalid IO handle.",
377
0
     function );
378
379
0
    return( -1 );
380
0
  }
381
352
  value_key_data_size = sizeof( regf_value_key_t );
382
383
352
  if( ( io_handle->major_version == 1 )
384
352
   && ( io_handle->minor_version <= 1 ) )
385
0
  {
386
0
    value_key_data_size += 4;
387
0
  }
388
352
  if( data == NULL )
389
0
  {
390
0
    libcerror_error_set(
391
0
     error,
392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
394
0
     "%s: invalid data.",
395
0
     function );
396
397
0
    return( -1 );
398
0
  }
399
352
  if( ( data_size < value_key_data_size )
400
352
   || ( data_size > (size_t) SSIZE_MAX ) )
401
0
  {
402
0
    libcerror_error_set(
403
0
     error,
404
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
405
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
406
0
     "%s: invalid data size value out of bounds.",
407
0
     function );
408
409
0
    return( -1 );
410
0
  }
411
#if defined( HAVE_DEBUG_OUTPUT )
412
  if( libcnotify_verbose != 0 )
413
  {
414
    libcnotify_printf(
415
     "%s: value key data:\n",
416
     function );
417
    libcnotify_print_data(
418
     data,
419
     data_size,
420
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
421
  }
422
#endif
423
352
  if( ( io_handle->major_version == 1 )
424
352
   && ( io_handle->minor_version <= 1 ) )
425
0
  {
426
0
    data_offset += 4;
427
0
  }
428
  /* Check if the signature matches that of a value key: "vk"
429
   */
430
352
  if( ( data[ data_offset ] != (uint8_t) 'v' )
431
352
   || ( data[ data_offset + 1 ] != (uint8_t) 'k' ) )
432
54
  {
433
54
    return( 0 );
434
54
  }
435
298
  byte_stream_copy_to_uint16_little_endian(
436
298
   ( (regf_value_key_t *) &( data[ data_offset ] ) )->value_name_size,
437
298
   value_key->name_size );
438
439
298
  byte_stream_copy_to_uint32_little_endian(
440
298
   ( (regf_value_key_t *) &( data[ data_offset ] ) )->data_size,
441
298
   value_key->data_size );
442
443
298
  byte_stream_copy_to_uint32_little_endian(
444
298
   ( (regf_value_key_t *) &( data[ data_offset ] ) )->data_offset,
445
298
   value_data_offset );
446
447
298
  byte_stream_copy_to_uint32_little_endian(
448
298
   ( (regf_value_key_t *) &( data[ data_offset ] ) )->value_type,
449
298
   value_key->value_type );
450
451
298
  byte_stream_copy_to_uint16_little_endian(
452
298
   ( (regf_value_key_t *) &( data[ data_offset ] ) )->flags,
453
298
   value_key->flags );
454
455
#if defined( HAVE_DEBUG_OUTPUT )
456
  if( libcnotify_verbose != 0 )
457
  {
458
    if( ( io_handle->major_version == 1 )
459
     && ( io_handle->minor_version <= 1 ) )
460
    {
461
      byte_stream_copy_to_uint32_little_endian(
462
       data,
463
       value_32bit );
464
      libcnotify_printf(
465
       "%s: unknown0\t\t\t\t\t: 0x%08" PRIx32 " (%" PRIi32 ")\n",
466
       function,
467
       value_32bit,
468
       (int32_t) value_32bit );
469
    }
470
    libcnotify_printf(
471
     "%s: signature\t\t\t\t\t: %c%c\n",
472
     function,
473
     ( (regf_value_key_t *) &( data[ data_offset ] ) )->signature[ 0 ],
474
     ( (regf_value_key_t *) &( data[ data_offset ] ) )->signature[ 1 ] );
475
476
    libcnotify_printf(
477
     "%s: value name size\t\t\t\t: %" PRIu16 "\n",
478
     function,
479
     value_key->name_size );
480
481
    libcnotify_printf(
482
     "%s: value data size\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
483
     function,
484
     value_key->data_size,
485
     value_key->data_size & 0x5fffffffUL );
486
487
    if( ( value_key->data_size & 0x80000000UL ) == 0 )
488
    {
489
      libcnotify_printf(
490
       "%s: value data offset\t\t\t\t: 0x%08" PRIx32 "\n",
491
       function,
492
       value_data_offset );
493
    }
494
    else
495
    {
496
      libcnotify_printf(
497
       "%s: value data:\n",
498
       function );
499
      libcnotify_print_data(
500
       ( (regf_value_key_t *) &( data[ data_offset ] ) )->data_offset,
501
       4,
502
       0 );
503
    }
504
    libcnotify_printf(
505
     "%s: value type\t\t\t\t\t: 0x%08" PRIx32 " (%s) %s\n",
506
     function,
507
     value_key->value_type,
508
     libregf_data_type_get_identifier(
509
      value_key->value_type ),
510
     libregf_data_type_get_description(
511
      value_key->value_type ) );
512
513
    libcnotify_printf(
514
     "%s: flags\t\t\t\t\t: 0x%04" PRIx16 "\n",
515
     function,
516
     value_key->flags );
517
    libregf_debug_print_value_key_flags(
518
     value_key->flags );
519
520
    byte_stream_copy_to_uint16_little_endian(
521
     ( (regf_value_key_t *) &( data[ data_offset ] ) )->unknown1,
522
     value_16bit );
523
    libcnotify_printf(
524
     "%s: unknown1\t\t\t\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n",
525
     function,
526
     value_16bit,
527
     value_16bit );
528
  }
529
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
530
531
298
  if( ( value_key->data_size & 0x80000000UL ) != 0 )
532
95
  {
533
95
    value_key->data_in_key = 1;
534
95
  }
535
/* TODO should this bitmask be 0x5fffffffUL ? */
536
298
  value_key->data_size &= 0x7fffffffUL;
537
538
298
  if( value_key->data_in_key == 0 )
539
203
  {
540
203
    value_key->data_offset = value_data_offset;
541
203
  }
542
95
  else
543
95
  {
544
/* TODO mark value as corrupted and handle issue */
545
95
    if( value_key->data_size > 4 )
546
47
    {
547
47
      libcerror_error_set(
548
47
       error,
549
47
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
550
47
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
551
47
       "%s: invalid value data size value out of bounds.",
552
47
       function );
553
554
47
      goto on_error;
555
47
    }
556
48
    if( value_key->data_size > 0 )
557
46
    {
558
46
      if( ( value_key->value_type == LIBREGF_VALUE_TYPE_STRING )
559
46
       || ( value_key->value_type == LIBREGF_VALUE_TYPE_EXPANDABLE_STRING ) )
560
5
      {
561
5
        if( ( value_key->data_size == 1 )
562
5
         || ( value_key->data_size == 3 ) )
563
2
        {
564
2
          correct_string_size = 1;
565
566
2
          value_key->data_size += 1;
567
2
        }
568
5
      }
569
46
      if( value_key->data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
570
0
      {
571
0
        libcerror_error_set(
572
0
         error,
573
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
574
0
         LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
575
0
         "%s: invalid value key - invalid data size value exceeds maximum allocation size.",
576
0
         function );
577
578
0
        goto on_error;
579
0
      }
580
46
      value_key->data = (uint8_t *) memory_allocate(
581
46
                                     sizeof( uint8_t ) * value_key->data_size );
582
583
46
      if( value_key->data == NULL )
584
0
      {
585
0
        libcerror_error_set(
586
0
         error,
587
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
588
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
589
0
         "%s: unable to create data.",
590
0
         function );
591
592
0
        goto on_error;
593
0
      }
594
46
      value_key->data_size = (size_t) value_key->data_size;
595
596
46
      if( memory_copy(
597
46
           value_key->data,
598
46
           &( ( ( (regf_value_key_t *) &( data[ data_offset ] ) )->data_offset )[ 4 - value_key->data_size ] ),
599
46
           value_key->data_size ) == NULL )
600
0
      {
601
0
        libcerror_error_set(
602
0
         error,
603
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
604
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
605
0
         "%s: unable to copy data.",
606
0
         function );
607
608
0
        goto on_error;
609
0
      }
610
46
      if( correct_string_size != 0 )
611
2
      {
612
        /* Make sure remnant data in the string is zero-ed out
613
         */
614
2
        value_key->data[ value_key->data_size - 1 ] = 0;
615
2
      }
616
46
    }
617
48
  }
618
251
  data_offset += sizeof( regf_value_key_t );
619
620
251
  if( value_key->name_size > 0 )
621
176
  {
622
/* TODO mark value as corrupted and handle issue */
623
176
    if( value_key->name_size > ( data_size - data_offset ) )
624
33
    {
625
33
      libcerror_error_set(
626
33
       error,
627
33
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
628
33
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
629
33
       "%s: invalid value name size value out of bounds.",
630
33
       function );
631
632
33
      goto on_error;
633
33
    }
634
143
    value_key->name = (uint8_t *) memory_allocate(
635
143
                                   sizeof( uint8_t ) * (size_t) value_key->name_size );
636
637
143
    if( value_key->name == NULL )
638
0
    {
639
0
      libcerror_error_set(
640
0
       error,
641
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
642
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
643
0
       "%s: unable to create value name.",
644
0
       function );
645
646
0
      goto on_error;
647
0
    }
648
143
    if( memory_copy(
649
143
         value_key->name,
650
143
         &( data[ data_offset ] ),
651
143
         (size_t) value_key->name_size ) == NULL )
652
0
    {
653
0
      libcerror_error_set(
654
0
       error,
655
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
656
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
657
0
       "%s: unable to copy value name.",
658
0
       function );
659
660
0
      goto on_error;
661
0
    }
662
143
    value_key->name_hash = 0;
663
664
2.77k
    while( name_index < (size_t) value_key->name_size )
665
2.64k
    {
666
2.64k
      if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
667
2.15k
      {
668
2.15k
        result = libuna_unicode_character_copy_from_byte_stream(
669
2.15k
            &unicode_character,
670
2.15k
            value_key->name,
671
2.15k
            (size_t) value_key->name_size,
672
2.15k
            &name_index,
673
2.15k
            io_handle->ascii_codepage,
674
2.15k
            error );
675
2.15k
      }
676
492
      else
677
492
      {
678
492
        result = libuna_unicode_character_copy_from_utf16_stream(
679
492
            &unicode_character,
680
492
            value_key->name,
681
492
            (size_t) value_key->name_size,
682
492
            &name_index,
683
492
            LIBUNA_ENDIAN_LITTLE,
684
492
            error );
685
492
      }
686
2.64k
      if( result != 1 )
687
11
      {
688
11
        libcerror_error_set(
689
11
         error,
690
11
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
691
11
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
692
11
         "%s: unable to copy value name to Unicode character.",
693
11
         function );
694
695
11
        goto on_error;
696
11
      }
697
2.63k
      value_key->name_hash *= 37;
698
2.63k
      value_key->name_hash += (uint32_t) towupper( (wint_t) unicode_character );
699
2.63k
    }
700
#if defined( HAVE_DEBUG_OUTPUT )
701
    if( libcnotify_verbose != 0 )
702
    {
703
      if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
704
      {
705
        if( libregf_debug_print_string_value(
706
             function,
707
             "value name\t\t\t\t\t",
708
             value_key->name,
709
             (size_t) value_key->name_size,
710
             io_handle->ascii_codepage,
711
             error ) != 1 )
712
        {
713
          libcerror_error_set(
714
           error,
715
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
716
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
717
           "%s: unable to print string value.",
718
           function );
719
720
          goto on_error;
721
        }
722
      }
723
      else
724
      {
725
        if( libregf_debug_print_utf16_string_value(
726
             function,
727
             "value name\t\t\t\t\t",
728
             value_key->name,
729
             (size_t) value_key->name_size,
730
             LIBUNA_ENDIAN_LITTLE,
731
             error ) != 1 )
732
        {
733
          libcerror_error_set(
734
           error,
735
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
736
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
737
           "%s: unable to print UTF-16 string value.",
738
           function );
739
740
          goto on_error;
741
        }
742
      }
743
      if( result != 1 )
744
      {
745
        libcerror_error_set(
746
         error,
747
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
748
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
749
         "%s: unable to retrieve value name string size.",
750
         function );
751
752
        goto on_error;
753
      }
754
      libcnotify_printf(
755
       "%s: value name hash\t\t\t\t: 0x%08" PRIx32 "\n",
756
       function,
757
       value_key->name_hash );
758
    }
759
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
760
143
  }
761
#if defined( HAVE_DEBUG_OUTPUT )
762
  else if( libcnotify_verbose != 0 )
763
  {
764
    libcnotify_printf(
765
     "%s: value name\t\t\t\t\t: (default)\n",
766
     function );
767
768
    libcnotify_printf(
769
     "%s: value name hash\t\t\t\t: 0x%08" PRIx32 "\n",
770
     function,
771
     value_key->name_hash );
772
  }
773
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
774
775
207
  data_offset += value_key->name_size;
776
777
#if defined( HAVE_DEBUG_OUTPUT )
778
  if( libcnotify_verbose != 0 )
779
  {
780
    if( ( value_key_hash != 0 )
781
     && ( value_key_hash != value_key->name_hash ) )
782
    {
783
      libcnotify_printf(
784
       "%s: mismatch in name hash ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n",
785
       function,
786
       value_key_hash,
787
       value_key->name_hash );
788
    }
789
    if( data_offset < data_size )
790
    {
791
      libcnotify_printf(
792
       "%s: padding:\n",
793
       function );
794
      libcnotify_print_data(
795
       &( data[ data_offset ] ),
796
       data_size - data_offset,
797
       0 );
798
    }
799
    else
800
    {
801
      libcnotify_printf(
802
       "\n" );
803
    }
804
  }
805
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
806
807
207
  return( 1 );
808
809
91
on_error:
810
91
  if( value_key->data != NULL )
811
27
  {
812
27
    memory_free(
813
27
     value_key->data );
814
815
27
    value_key->data = NULL;
816
27
  }
817
91
  value_key->data_size = 0;
818
819
91
  if( value_key->name != NULL )
820
11
  {
821
11
    memory_free(
822
11
     value_key->name );
823
824
11
    value_key->name = NULL;
825
11
  }
826
91
  value_key->name_size = 0;
827
828
91
  return( -1 );
829
251
}
830
831
/* Retrieves the value name size
832
 * Returns 1 if successful or -1 on error
833
 */
834
int libregf_value_key_get_name_size(
835
     libregf_value_key_t *value_key,
836
     size_t *name_size,
837
     libcerror_error_t **error )
838
0
{
839
0
  static char *function = "libregf_value_key_get_name_size";
840
841
0
  if( value_key == NULL )
842
0
  {
843
0
    libcerror_error_set(
844
0
     error,
845
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
846
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
847
0
     "%s: invalid value key.",
848
0
     function );
849
850
0
    return( -1 );
851
0
  }
852
0
  if( name_size == NULL )
853
0
  {
854
0
    libcerror_error_set(
855
0
     error,
856
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
857
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
858
0
     "%s: invalid name size.",
859
0
     function );
860
861
0
    return( -1 );
862
0
  }
863
0
  *name_size = value_key->name_size;
864
865
0
  return( 1 );
866
0
}
867
868
/* Retrieves the value name
869
 * Returns 1 if successful or -1 on error
870
 */
871
int libregf_value_key_get_name(
872
     libregf_value_key_t *value_key,
873
     uint8_t *name,
874
     size_t name_size,
875
     libcerror_error_t **error )
876
0
{
877
0
  static char *function = "libregf_value_key_get_name";
878
879
0
  if( value_key == NULL )
880
0
  {
881
0
    libcerror_error_set(
882
0
     error,
883
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
884
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
885
0
     "%s: invalid value key.",
886
0
     function );
887
888
0
    return( -1 );
889
0
  }
890
0
  if( name == NULL )
891
0
  {
892
0
    libcerror_error_set(
893
0
     error,
894
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
895
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
896
0
     "%s: invalid name.",
897
0
     function );
898
899
0
    return( -1 );
900
0
  }
901
0
  if( name_size > (size_t) SSIZE_MAX )
902
0
  {
903
0
    libcerror_error_set(
904
0
     error,
905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
906
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
907
0
     "%s: invalid name size value exceeds maximum.",
908
0
     function );
909
910
0
    return( -1 );
911
0
  }
912
0
  if( name_size < value_key->name_size )
913
0
  {
914
0
    libcerror_error_set(
915
0
     error,
916
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
917
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
918
0
     "%s: invalid name size value out of bounds.",
919
0
     function );
920
921
0
    return( -1 );
922
0
  }
923
0
  if( memory_copy(
924
0
       name,
925
0
       value_key->name,
926
0
       value_key->name_size ) == NULL )
927
0
  {
928
0
    libcerror_error_set(
929
0
     error,
930
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
931
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
932
0
     "%s: unable to copy name.",
933
0
     function );
934
935
0
    return( -1 );
936
0
  }
937
0
  return( 1 );
938
0
}
939
940
/* Retrieves the UTF-8 string size of the value name
941
 * The returned size includes the end of string character
942
 * Returns 1 if successful or -1 on error
943
 */
944
int libregf_value_key_get_utf8_name_size(
945
     libregf_value_key_t *value_key,
946
     size_t *utf8_name_size,
947
     int ascii_codepage,
948
     libcerror_error_t **error )
949
0
{
950
0
  static char *function = "libregf_value_key_get_utf8_name_size";
951
0
  int result            = 0;
952
953
0
  if( value_key == NULL )
954
0
  {
955
0
    libcerror_error_set(
956
0
     error,
957
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
958
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
959
0
     "%s: invalid value key.",
960
0
     function );
961
962
0
    return( -1 );
963
0
  }
964
0
  if( value_key->name == NULL )
965
0
  {
966
0
    if( utf8_name_size == NULL )
967
0
    {
968
0
      libcerror_error_set(
969
0
       error,
970
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
971
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
972
0
       "%s: invalid UTF-8 name size.",
973
0
       function );
974
975
0
      return( -1 );
976
0
    }
977
0
    *utf8_name_size = 0;
978
0
  }
979
0
  else
980
0
  {
981
0
    if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
982
0
    {
983
0
      result = libuna_utf8_string_size_from_byte_stream(
984
0
          value_key->name,
985
0
          (size_t) value_key->name_size,
986
0
          ascii_codepage,
987
0
          utf8_name_size,
988
0
          error );
989
0
    }
990
0
    else
991
0
    {
992
0
      result = libuna_utf8_string_size_from_utf16_stream(
993
0
          value_key->name,
994
0
          (size_t) value_key->name_size,
995
0
          LIBUNA_ENDIAN_LITTLE,
996
0
          utf8_name_size,
997
0
          error );
998
0
    }
999
0
    if( result != 1 )
1000
0
    {
1001
0
      libcerror_error_set(
1002
0
       error,
1003
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1004
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1005
0
       "%s: unable to retrieve UTF-8 string size.",
1006
0
       function );
1007
1008
0
      return( -1 );
1009
0
    }
1010
0
  }
1011
0
  return( 1 );
1012
0
}
1013
1014
/* Retrieves the UTF-8 string value of the value name
1015
 * The function uses a codepage if necessary, it uses the codepage set for the library
1016
 * The size should include the end of string character
1017
 * Returns 1 if successful or -1 on error
1018
 */
1019
int libregf_value_key_get_utf8_name(
1020
     libregf_value_key_t *value_key,
1021
     uint8_t *utf8_name,
1022
     size_t utf8_name_size,
1023
     int ascii_codepage,
1024
     libcerror_error_t **error )
1025
0
{
1026
0
  static char *function = "libregf_value_key_get_utf8_name";
1027
0
  int result            = 0;
1028
1029
0
  if( value_key == NULL )
1030
0
  {
1031
0
    libcerror_error_set(
1032
0
     error,
1033
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1034
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1035
0
     "%s: invalid value key.",
1036
0
     function );
1037
1038
0
    return( -1 );
1039
0
  }
1040
0
  if( value_key->name == NULL )
1041
0
  {
1042
0
    libcerror_error_set(
1043
0
     error,
1044
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1045
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1046
0
     "%s: invalid value key - missing name.",
1047
0
     function );
1048
1049
0
    return( -1 );
1050
0
  }
1051
0
  if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
1052
0
  {
1053
0
    result = libuna_utf8_string_copy_from_byte_stream(
1054
0
        utf8_name,
1055
0
        utf8_name_size,
1056
0
        value_key->name,
1057
0
        (size_t) value_key->name_size,
1058
0
        ascii_codepage,
1059
0
        error );
1060
0
  }
1061
0
  else
1062
0
  {
1063
0
    result = libuna_utf8_string_copy_from_utf16_stream(
1064
0
        utf8_name,
1065
0
        utf8_name_size,
1066
0
        value_key->name,
1067
0
        (size_t) value_key->name_size,
1068
0
        LIBUNA_ENDIAN_LITTLE,
1069
0
        error );
1070
0
  }
1071
0
  if( result != 1 )
1072
0
  {
1073
0
    libcerror_error_set(
1074
0
     error,
1075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1076
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1077
0
     "%s: unable to retrieve UTF-8 string.",
1078
0
     function );
1079
1080
0
    return( -1 );
1081
0
  }
1082
0
  return( 1 );
1083
0
}
1084
1085
/* Retrieves the UTF-16 string size of the value name
1086
 * The returned size includes the end of string character
1087
 * Returns 1 if successful or -1 on error
1088
 */
1089
int libregf_value_key_get_utf16_name_size(
1090
     libregf_value_key_t *value_key,
1091
     size_t *utf16_name_size,
1092
     int ascii_codepage,
1093
     libcerror_error_t **error )
1094
0
{
1095
0
  static char *function = "libregf_value_key_get_utf16_name_size";
1096
0
  int result            = 0;
1097
1098
0
  if( value_key == NULL )
1099
0
  {
1100
0
    libcerror_error_set(
1101
0
     error,
1102
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1103
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1104
0
     "%s: invalid value key.",
1105
0
     function );
1106
1107
0
    return( -1 );
1108
0
  }
1109
0
  if( value_key->name == NULL )
1110
0
  {
1111
0
    if( utf16_name_size == NULL )
1112
0
    {
1113
0
      libcerror_error_set(
1114
0
       error,
1115
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1116
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1117
0
       "%s: invalid UTF-16 name size.",
1118
0
       function );
1119
1120
0
      return( -1 );
1121
0
    }
1122
0
    *utf16_name_size = 0;
1123
0
  }
1124
0
  else
1125
0
  {
1126
0
    if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
1127
0
    {
1128
0
      result = libuna_utf16_string_size_from_byte_stream(
1129
0
          value_key->name,
1130
0
          (size_t) value_key->name_size,
1131
0
          ascii_codepage,
1132
0
          utf16_name_size,
1133
0
          error );
1134
0
    }
1135
0
    else
1136
0
    {
1137
0
      result = libuna_utf16_string_size_from_utf16_stream(
1138
0
          value_key->name,
1139
0
          (size_t) value_key->name_size,
1140
0
          LIBUNA_ENDIAN_LITTLE,
1141
0
          utf16_name_size,
1142
0
          error );
1143
0
    }
1144
0
    if( result != 1 )
1145
0
    {
1146
0
      libcerror_error_set(
1147
0
       error,
1148
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1149
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1150
0
       "%s: unable to retrieve UTF-16 string size.",
1151
0
       function );
1152
1153
0
      return( -1 );
1154
0
    }
1155
0
  }
1156
0
  return( 1 );
1157
0
}
1158
1159
/* Retrieves the UTF-16 string value of the value name
1160
 * The function uses a codepage if necessary, it uses the codepage set for the library
1161
 * The size should include the end of string character
1162
 * Returns 1 if successful or -1 on error
1163
 */
1164
int libregf_value_key_get_utf16_name(
1165
     libregf_value_key_t *value_key,
1166
     uint16_t *utf16_name,
1167
     size_t utf16_name_size,
1168
     int ascii_codepage,
1169
     libcerror_error_t **error )
1170
0
{
1171
0
  static char *function = "libregf_value_key_get_utf16_name";
1172
0
  int result            = 0;
1173
1174
0
  if( value_key == NULL )
1175
0
  {
1176
0
    libcerror_error_set(
1177
0
     error,
1178
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1179
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1180
0
     "%s: invalid value key.",
1181
0
     function );
1182
1183
0
    return( -1 );
1184
0
  }
1185
0
  if( value_key->name == NULL )
1186
0
  {
1187
0
    libcerror_error_set(
1188
0
     error,
1189
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1190
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1191
0
     "%s: invalid value key - missing name.",
1192
0
     function );
1193
1194
0
    return( -1 );
1195
0
  }
1196
0
  if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
1197
0
  {
1198
0
    result = libuna_utf16_string_copy_from_byte_stream(
1199
0
        utf16_name,
1200
0
        utf16_name_size,
1201
0
        value_key->name,
1202
0
        (size_t) value_key->name_size,
1203
0
        ascii_codepage,
1204
0
        error );
1205
0
  }
1206
0
  else
1207
0
  {
1208
0
    result = libuna_utf16_string_copy_from_utf16_stream(
1209
0
        utf16_name,
1210
0
        utf16_name_size,
1211
0
        value_key->name,
1212
0
        (size_t) value_key->name_size,
1213
0
        LIBUNA_ENDIAN_LITTLE,
1214
0
        error );
1215
0
  }
1216
0
  if( result != 1 )
1217
0
  {
1218
0
    libcerror_error_set(
1219
0
     error,
1220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1221
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1222
0
     "%s: unable to retrieve UTF-16 string.",
1223
0
     function );
1224
1225
0
    return( -1 );
1226
0
  }
1227
0
  return( 1 );
1228
0
}
1229
1230
/* Retrieves the value type
1231
 * Returns 1 if successful or -1 on error
1232
 */
1233
int libregf_value_key_get_value_type(
1234
     libregf_value_key_t *value_key,
1235
     uint32_t *value_type,
1236
     libcerror_error_t **error )
1237
397
{
1238
397
  static char *function = "libregf_value_key_get_value_type";
1239
1240
397
  if( value_key == NULL )
1241
2
  {
1242
2
    libcerror_error_set(
1243
2
     error,
1244
2
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1245
2
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1246
2
     "%s: invalid value key.",
1247
2
     function );
1248
1249
2
    return( -1 );
1250
2
  }
1251
395
  if( value_type == NULL )
1252
0
  {
1253
0
    libcerror_error_set(
1254
0
     error,
1255
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1256
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1257
0
     "%s: invalid data type.",
1258
0
     function );
1259
1260
0
    return( -1 );
1261
0
  }
1262
395
  *value_type = value_key->value_type;
1263
1264
395
  return( 1 );
1265
395
}
1266
1267
/* Compares the value name with UTF-8 string
1268
 * Returns 1 if the names match, 0 if not or -1 on error
1269
 */
1270
int libregf_value_key_compare_name_with_utf8_string(
1271
     libregf_value_key_t *value_key,
1272
     uint32_t name_hash,
1273
     const uint8_t *utf8_string,
1274
     size_t utf8_string_length,
1275
     int ascii_codepage,
1276
     libcerror_error_t **error )
1277
0
{
1278
0
  static char *function                       = "libregf_value_key_compare_name_with_utf8_string";
1279
0
  libuna_unicode_character_t name_character   = 0;
1280
0
  libuna_unicode_character_t string_character = 0;
1281
0
  size_t name_index                           = 0;
1282
0
  size_t utf8_string_index                    = 0;
1283
0
  int result                                  = 0;
1284
1285
0
  if( value_key == NULL )
1286
0
  {
1287
0
    libcerror_error_set(
1288
0
     error,
1289
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1290
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1291
0
     "%s: invalid value key.",
1292
0
     function );
1293
1294
0
    return( -1 );
1295
0
  }
1296
0
  if( utf8_string_length > (size_t) SSIZE_MAX )
1297
0
  {
1298
0
    libcerror_error_set(
1299
0
     error,
1300
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1301
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1302
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
1303
0
     function );
1304
1305
0
    return( -1 );
1306
0
  }
1307
  /* Check if we are looking for the nameless default value
1308
   */
1309
0
  if( value_key->name == NULL )
1310
0
  {
1311
0
    if( ( utf8_string == NULL )
1312
0
     && ( utf8_string_length == 0 ) )
1313
0
    {
1314
0
      return( 1 );
1315
0
    }
1316
0
  }
1317
0
  else if( ( name_hash == 0 )
1318
0
        || ( value_key->name_hash == 0 )
1319
0
        || ( value_key->name_hash == name_hash ) )
1320
0
  {
1321
    /* Do a full compare if there no name hash was provided or the name hash matches
1322
     */
1323
0
    while( name_index < (size_t) value_key->name_size )
1324
0
    {
1325
0
      if( utf8_string_index >= utf8_string_length )
1326
0
      {
1327
0
        break;
1328
0
      }
1329
0
      if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
1330
0
      {
1331
0
        result = libuna_unicode_character_copy_from_byte_stream(
1332
0
            &name_character,
1333
0
            value_key->name,
1334
0
            (size_t) value_key->name_size,
1335
0
            &name_index,
1336
0
            ascii_codepage,
1337
0
            error );
1338
0
      }
1339
0
      else
1340
0
      {
1341
0
        result = libuna_unicode_character_copy_from_utf16_stream(
1342
0
            &name_character,
1343
0
            value_key->name,
1344
0
            (size_t) value_key->name_size,
1345
0
            &name_index,
1346
0
            LIBUNA_ENDIAN_LITTLE,
1347
0
            error );
1348
0
      }
1349
0
      if( result != 1 )
1350
0
      {
1351
0
        libcerror_error_set(
1352
0
         error,
1353
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1354
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1355
0
         "%s: unable to copy value name to Unicode character.",
1356
0
         function );
1357
1358
0
        return( -1 );
1359
0
      }
1360
0
      if( libuna_unicode_character_copy_from_utf8(
1361
0
           &string_character,
1362
0
           utf8_string,
1363
0
           utf8_string_length,
1364
0
           &utf8_string_index,
1365
0
           error ) != 1 )
1366
0
      {
1367
0
        libcerror_error_set(
1368
0
         error,
1369
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1370
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1371
0
         "%s: unable to copy UTF-8 string to Unicode character.",
1372
0
         function );
1373
1374
0
        return( -1 );
1375
0
      }
1376
0
      if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) )
1377
0
      {
1378
0
        break;
1379
0
      }
1380
0
    }
1381
0
    if( ( name_index == (size_t) value_key->name_size )
1382
0
     && ( utf8_string_index == utf8_string_length ) )
1383
0
    {
1384
0
      return( 1 );
1385
0
    }
1386
0
  }
1387
0
  return( 0 );
1388
0
}
1389
1390
/* Compares the value name with UTF-16 string
1391
 * Returns 1 if the names match, 0 if not or -1 on error
1392
 */
1393
int libregf_value_key_compare_name_with_utf16_string(
1394
     libregf_value_key_t *value_key,
1395
     uint32_t name_hash,
1396
     const uint16_t *utf16_string,
1397
     size_t utf16_string_length,
1398
     int ascii_codepage,
1399
     libcerror_error_t **error )
1400
0
{
1401
0
  static char *function                       = "libregf_value_key_compare_name_with_utf16_string";
1402
0
  libuna_unicode_character_t name_character   = 0;
1403
0
  libuna_unicode_character_t string_character = 0;
1404
0
  size_t name_index                           = 0;
1405
0
  size_t utf16_string_index                   = 0;
1406
0
  int result                                  = 0;
1407
1408
0
  if( value_key == NULL )
1409
0
  {
1410
0
    libcerror_error_set(
1411
0
     error,
1412
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1413
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1414
0
     "%s: invalid value key.",
1415
0
     function );
1416
1417
0
    return( -1 );
1418
0
  }
1419
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
1420
0
  {
1421
0
    libcerror_error_set(
1422
0
     error,
1423
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1424
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1425
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
1426
0
     function );
1427
1428
0
    return( -1 );
1429
0
  }
1430
  /* Check if we are looking for the nameless default value
1431
   */
1432
0
  if( value_key->name == NULL )
1433
0
  {
1434
0
    if( ( utf16_string == NULL )
1435
0
     && ( utf16_string_length == 0 ) )
1436
0
    {
1437
0
      return( 1 );
1438
0
    }
1439
0
  }
1440
0
  else if( ( name_hash == 0 )
1441
0
        || ( value_key->name_hash == 0 )
1442
0
        || ( value_key->name_hash == name_hash ) )
1443
0
  {
1444
    /* Do a full compare if there no name hash was provided or the name hash matches
1445
     */
1446
0
    while( name_index < (size_t) value_key->name_size )
1447
0
    {
1448
0
      if( utf16_string_index >= utf16_string_length )
1449
0
      {
1450
0
        break;
1451
0
      }
1452
0
      if( ( value_key->flags & LIBREGF_VALUE_KEY_FLAG_NAME_IS_ASCII ) != 0 )
1453
0
      {
1454
0
        result = libuna_unicode_character_copy_from_byte_stream(
1455
0
                  &name_character,
1456
0
                  value_key->name,
1457
0
                  (size_t) value_key->name_size,
1458
0
                  &name_index,
1459
0
                  ascii_codepage,
1460
0
                  error );
1461
0
      }
1462
0
      else
1463
0
      {
1464
0
        result = libuna_unicode_character_copy_from_utf16_stream(
1465
0
                  &name_character,
1466
0
                  value_key->name,
1467
0
                  (size_t) value_key->name_size,
1468
0
                  &name_index,
1469
0
                  LIBUNA_ENDIAN_LITTLE,
1470
0
                  error );
1471
0
      }
1472
0
      if( result != 1 )
1473
0
      {
1474
0
        libcerror_error_set(
1475
0
         error,
1476
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1477
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1478
0
         "%s: unable to copy value name to Unicode character.",
1479
0
         function );
1480
1481
0
        return( -1 );
1482
0
      }
1483
0
      if( libuna_unicode_character_copy_from_utf16(
1484
0
           &string_character,
1485
0
           utf16_string,
1486
0
           utf16_string_length,
1487
0
           &utf16_string_index,
1488
0
           error ) != 1 )
1489
0
      {
1490
0
        libcerror_error_set(
1491
0
         error,
1492
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1493
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1494
0
         "%s: unable to copy UTF-16 string to Unicode character.",
1495
0
         function );
1496
1497
0
        return( -1 );
1498
0
      }
1499
0
      if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) )
1500
0
      {
1501
0
        break;
1502
0
      }
1503
0
    }
1504
0
    if( ( name_index == (size_t) value_key->name_size )
1505
0
     && ( utf16_string_index == utf16_string_length ) )
1506
0
    {
1507
0
      return( 1 );
1508
0
    }
1509
0
  }
1510
0
  return( 0 );
1511
0
}
1512