Coverage Report

Created: 2024-06-12 07:07

/src/libcreg/libcreg/libcreg_value_entry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Value entry functions
3
 *
4
 * Copyright (C) 2013-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <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 "libcreg_data_type.h"
32
#include "libcreg_debug.h"
33
#include "libcreg_libcerror.h"
34
#include "libcreg_libcnotify.h"
35
#include "libcreg_libuna.h"
36
#include "libcreg_unused.h"
37
#include "libcreg_value_entry.h"
38
39
#include "creg_data_block.h"
40
41
/* Creates a value entry
42
 * Make sure the value value_entry is referencing, is set to NULL
43
 * Returns 1 if successful or -1 on error
44
 */
45
int libcreg_value_entry_initialize(
46
     libcreg_value_entry_t **value_entry,
47
     libcerror_error_t **error )
48
21.2k
{
49
21.2k
  static char *function = "libcreg_value_entry_initialize";
50
51
21.2k
  if( value_entry == NULL )
52
0
  {
53
0
    libcerror_error_set(
54
0
     error,
55
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
56
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
57
0
     "%s: invalid value entry.",
58
0
     function );
59
60
0
    return( -1 );
61
0
  }
62
21.2k
  if( *value_entry != NULL )
63
0
  {
64
0
    libcerror_error_set(
65
0
     error,
66
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
67
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
68
0
     "%s: invalid value entry value already set.",
69
0
     function );
70
71
0
    return( -1 );
72
0
  }
73
21.2k
  *value_entry = memory_allocate_structure(
74
21.2k
                  libcreg_value_entry_t );
75
76
21.2k
  if( *value_entry == NULL )
77
0
  {
78
0
    libcerror_error_set(
79
0
     error,
80
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
81
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
82
0
     "%s: unable to create value entry.",
83
0
     function );
84
85
0
    goto on_error;
86
0
  }
87
21.2k
  if( memory_set(
88
21.2k
       *value_entry,
89
21.2k
       0,
90
21.2k
       sizeof( libcreg_value_entry_t ) ) == NULL )
91
0
  {
92
0
    libcerror_error_set(
93
0
     error,
94
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
95
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
96
0
     "%s: unable to clear value entry.",
97
0
     function );
98
99
0
    goto on_error;
100
0
  }
101
21.2k
  return( 1 );
102
103
0
on_error:
104
0
  if( *value_entry != NULL )
105
0
  {
106
0
    memory_free(
107
0
     *value_entry );
108
109
0
    *value_entry = NULL;
110
0
  }
111
0
  return( -1 );
112
21.2k
}
113
114
/* Frees a value entry
115
 * Returns 1 if successful or -1 on error
116
 */
117
int libcreg_value_entry_free(
118
     libcreg_value_entry_t **value_entry,
119
     libcerror_error_t **error )
120
21.2k
{
121
21.2k
  static char *function = "libcreg_value_entry_free";
122
123
21.2k
  if( value_entry == NULL )
124
0
  {
125
0
    libcerror_error_set(
126
0
     error,
127
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
128
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
129
0
     "%s: invalid value entry.",
130
0
     function );
131
132
0
    return( -1 );
133
0
  }
134
21.2k
  if( *value_entry != NULL )
135
21.2k
  {
136
21.2k
    if( ( *value_entry )->data != NULL )
137
4.10k
    {
138
4.10k
      memory_free(
139
4.10k
       ( *value_entry )->data );
140
4.10k
    }
141
21.2k
    if( ( *value_entry )->name != NULL )
142
3.41k
    {
143
3.41k
      memory_free(
144
3.41k
       ( *value_entry )->name );
145
3.41k
    }
146
21.2k
    memory_free(
147
21.2k
     *value_entry );
148
149
21.2k
    *value_entry = NULL;
150
21.2k
  }
151
21.2k
  return( 1 );
152
21.2k
}
153
154
/* Reads a value entry
155
 * Returns 1 if successful or -1 on error
156
 */
157
int libcreg_value_entry_read_data(
158
     libcreg_value_entry_t *value_entry,
159
     const uint8_t *data,
160
     size_t data_size,
161
     int ascii_codepage LIBCREG_ATTRIBUTE_UNUSED,
162
     libcerror_error_t **error )
163
21.2k
{
164
21.2k
  static char *function    = "libcreg_value_entry_read_data";
165
21.2k
  size_t value_data_offset = 0; 
166
167
#if defined( HAVE_DEBUG_OUTPUT )
168
  uint32_t value_32bit     = 0; 
169
#endif
170
171
21.2k
  LIBCREG_UNREFERENCED_PARAMETER( ascii_codepage )
172
173
21.2k
  if( value_entry == NULL )
174
0
  {
175
0
    libcerror_error_set(
176
0
     error,
177
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
178
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
179
0
     "%s: invalid value entry.",
180
0
     function );
181
182
0
    return( -1 );
183
0
  }
184
21.2k
  if( data == NULL )
185
0
  {
186
0
    libcerror_error_set(
187
0
     error,
188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
190
0
     "%s: invalid data.",
191
0
     function );
192
193
0
    return( -1 );
194
0
  }
195
21.2k
  if( data_size < sizeof( creg_value_entry_t ) )
196
103
  {
197
103
    libcerror_error_set(
198
103
     error,
199
103
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
200
103
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
201
103
     "%s: invalid data size value too small.",
202
103
     function );
203
204
103
    return( -1 );
205
103
  }
206
21.1k
  if( data_size > (size_t) SSIZE_MAX )
207
0
  {
208
0
    libcerror_error_set(
209
0
     error,
210
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
211
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
212
0
     "%s: invalid data size value exceeds maximum.",
213
0
     function );
214
215
0
    return( -1 );
216
0
  }
217
21.1k
  byte_stream_copy_to_uint32_little_endian(
218
21.1k
   ( (creg_value_entry_t *) data )->data_type,
219
21.1k
   value_entry->type );
220
221
21.1k
  byte_stream_copy_to_uint16_little_endian(
222
21.1k
   ( (creg_value_entry_t *) data )->name_size,
223
21.1k
   value_entry->name_size );
224
225
21.1k
  byte_stream_copy_to_uint16_little_endian(
226
21.1k
   ( (creg_value_entry_t *) data )->data_size,
227
21.1k
   value_entry->data_size );
228
229
21.1k
  value_entry->size = sizeof( creg_value_entry_t ) + value_entry->name_size + value_entry->data_size;
230
231
#if SIZEOF_SIZE_T <= 4
232
  if( value_entry->size > (size_t) SSIZE_MAX )
233
#else
234
21.1k
  if( (uint32_t) value_entry->size > (uint32_t) SSIZE_MAX )
235
0
#endif
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
240
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
241
0
     "%s: invalid value entry size value out of bounds.",
242
0
     function );
243
244
0
    return( -1 );
245
0
  }
246
21.1k
  if( data_size < (size_t) value_entry->size )
247
149
  {
248
149
    libcerror_error_set(
249
149
     error,
250
149
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
251
149
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
252
149
     "%s: invalid data size value too small.",
253
149
     function );
254
255
149
    return( -1 );
256
149
  }
257
#if defined( HAVE_DEBUG_OUTPUT )
258
  if( libcnotify_verbose != 0 )
259
  {
260
    libcnotify_printf(
261
     "%s: data:\n",
262
     function );
263
    libcnotify_print_data(
264
     data,
265
     value_entry->size,
266
     0 );
267
  }
268
#endif
269
#if defined( HAVE_DEBUG_OUTPUT )
270
  if( libcnotify_verbose != 0 )
271
  {
272
    libcnotify_printf(
273
     "%s: data type\t\t\t\t: 0x%08" PRIx32 " (%s) %s\n",
274
     function,
275
     value_entry->type,
276
     libcreg_data_type_get_identifier(
277
      value_entry->type ),
278
     libcreg_data_type_get_description(
279
      value_entry->type ) );
280
281
    byte_stream_copy_to_uint32_little_endian(
282
     ( (creg_value_entry_t *) data )->unknown1,
283
     value_32bit );
284
    libcnotify_printf(
285
     "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n",
286
     function,
287
     value_32bit );
288
289
    libcnotify_printf(
290
     "%s: name size\t\t\t\t: %" PRIu16 "\n",
291
     function,
292
     value_entry->name_size );
293
294
    libcnotify_printf(
295
     "%s: data size\t\t\t\t: %" PRIu16 "\n",
296
     function,
297
     value_entry->data_size );
298
  }
299
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
300
301
21.0k
  value_data_offset = sizeof( creg_value_entry_t );
302
303
21.0k
  if( value_entry->name_size > 0 )
304
3.41k
  {
305
3.41k
    if( value_entry->name_size > ( value_entry->size - value_data_offset ) )
306
0
    {
307
0
      libcerror_error_set(
308
0
       error,
309
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
310
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
311
0
       "%s: invalid name size value out of bounds.",
312
0
       function );
313
314
0
      goto on_error;
315
0
    }
316
3.41k
    value_entry->name = (uint8_t *) memory_allocate(
317
3.41k
                                     sizeof( uint8_t ) * (size_t) value_entry->name_size );
318
319
3.41k
    if( value_entry->name == NULL )
320
0
    {
321
0
      libcerror_error_set(
322
0
       error,
323
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
324
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
325
0
       "%s: unable to create name.",
326
0
       function );
327
328
0
      goto on_error;
329
0
    }
330
3.41k
    if( memory_copy(
331
3.41k
         value_entry->name,
332
3.41k
         &( data[ value_data_offset ] ),
333
3.41k
         (size_t) value_entry->name_size ) == NULL )
334
0
    {
335
0
      libcerror_error_set(
336
0
       error,
337
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
338
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
339
0
       "%s: unable to copy name.",
340
0
       function );
341
342
0
      goto on_error;
343
0
    }
344
3.41k
    value_entry->name_hash = 0;
345
346
#if defined( HAVE_DEBUG_OUTPUT )
347
    if( libcnotify_verbose != 0 )
348
    {
349
      if( libcreg_debug_print_string_value(
350
           function,
351
           "name\t\t\t\t\t",
352
           &( data[ value_data_offset ] ),
353
           (size_t) value_entry->name_size,
354
           ascii_codepage,
355
           error ) != 1 )
356
      {
357
        libcerror_error_set(
358
         error,
359
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
360
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
361
         "%s: unable to print string value.",
362
         function );
363
364
        goto on_error;
365
      }
366
    }
367
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
368
369
3.41k
    value_data_offset += value_entry->name_size;
370
3.41k
  }
371
21.0k
  if( value_entry->data_size > 0 )
372
4.10k
  {
373
4.10k
    if( value_entry->data_size > ( value_entry->size - value_data_offset ) )
374
0
    {
375
0
      libcerror_error_set(
376
0
       error,
377
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
378
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
379
0
       "%s: invalid data size value out of bounds.",
380
0
       function );
381
382
0
      goto on_error;
383
0
    }
384
4.10k
    value_entry->data = (uint8_t *) memory_allocate(
385
4.10k
                                     sizeof( uint8_t ) * (size_t) value_entry->data_size );
386
387
4.10k
    if( value_entry->data == NULL )
388
0
    {
389
0
      libcerror_error_set(
390
0
       error,
391
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
392
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
393
0
       "%s: unable to create data.",
394
0
       function );
395
396
0
      goto on_error;
397
0
    }
398
4.10k
    if( memory_copy(
399
4.10k
         value_entry->data,
400
4.10k
         &( data[ value_data_offset ] ),
401
4.10k
         (size_t) value_entry->data_size ) == NULL )
402
0
    {
403
0
      libcerror_error_set(
404
0
       error,
405
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
406
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
407
0
       "%s: unable to copy data.",
408
0
       function );
409
410
0
      goto on_error;
411
0
    }
412
#if defined( HAVE_DEBUG_OUTPUT )
413
    if( libcnotify_verbose != 0 )
414
    {
415
      libcnotify_printf(
416
       "%s: data:\n",
417
       function );
418
      libcnotify_print_data(
419
       &( data[ value_data_offset ] ),
420
       (size_t) value_entry->data_size,
421
       0 );
422
    }
423
#endif
424
4.10k
  }
425
/* TODO trailing data */
426
21.0k
  return( 1 );
427
428
0
on_error:
429
0
  if( value_entry->data != NULL )
430
0
  {
431
0
    memory_free(
432
0
     value_entry->data );
433
434
0
    value_entry->data = NULL;
435
0
  }
436
0
  value_entry->data_size = 0;
437
438
0
  if( value_entry->name != NULL )
439
0
  {
440
0
    memory_free(
441
0
     value_entry->name );
442
443
0
    value_entry->name = NULL;
444
0
  }
445
0
  value_entry->name_size = 0;
446
447
0
  return( -1 );
448
21.0k
}
449
450
/* Retrieves the data size
451
 * Returns 1 if successful or -1 on error
452
 */
453
int libcreg_value_entry_get_data_size(
454
     libcreg_value_entry_t *value_entry,
455
     size_t *data_size,
456
     libcerror_error_t **error )
457
0
{
458
0
  static char *function = "libcreg_value_entry_get_data_size";
459
460
0
  if( value_entry == NULL )
461
0
  {
462
0
    libcerror_error_set(
463
0
     error,
464
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
465
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
466
0
     "%s: invalid value entry.",
467
0
     function );
468
469
0
    return( -1 );
470
0
  }
471
0
  if( data_size == NULL )
472
0
  {
473
0
    libcerror_error_set(
474
0
     error,
475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
477
0
     "%s: invalid data size.",
478
0
     function );
479
480
0
    return( -1 );
481
0
  }
482
0
  *data_size = (size_t) value_entry->data_size;
483
484
0
  return( 1 );
485
0
}
486
487
/* Retrieves the data
488
 * Returns 1 if successful or -1 on error
489
 */
490
int libcreg_value_entry_get_data(
491
     libcreg_value_entry_t *value_entry,
492
     uint8_t **data,
493
     size_t *data_size,
494
     libcerror_error_t **error )
495
0
{
496
0
  static char *function = "libcreg_value_entry_get_data";
497
498
0
  if( value_entry == NULL )
499
0
  {
500
0
    libcerror_error_set(
501
0
     error,
502
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
503
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
504
0
     "%s: invalid value entry.",
505
0
     function );
506
507
0
    return( -1 );
508
0
  }
509
0
  if( data == NULL )
510
0
  {
511
0
    libcerror_error_set(
512
0
     error,
513
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
514
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
515
0
     "%s: invalid data.",
516
0
     function );
517
518
0
    return( -1 );
519
0
  }
520
0
  if( data_size == NULL )
521
0
  {
522
0
    libcerror_error_set(
523
0
     error,
524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
525
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
526
0
     "%s: invalid data size.",
527
0
     function );
528
529
0
    return( -1 );
530
0
  }
531
0
  *data      = value_entry->data;
532
0
  *data_size = (size_t) value_entry->data_size;
533
534
0
  return( 1 );
535
0
}
536
537
/* Compares the value name with UTF-8 string
538
 * Returns 1 if the names match, 0 if not or -1 on error
539
 */
540
int libcreg_value_entry_compare_name_with_utf8_string(
541
     libcreg_value_entry_t *value_entry,
542
     uint32_t name_hash,
543
     const uint8_t *utf8_string,
544
     size_t utf8_string_length,
545
     int ascii_codepage,
546
     libcerror_error_t **error )
547
0
{
548
0
  static char *function                       = "libcreg_value_entry_compare_name_with_utf8_string";
549
0
  libuna_unicode_character_t name_character   = 0;
550
0
  libuna_unicode_character_t string_character = 0;
551
0
  size_t name_index                           = 0;
552
0
  size_t utf8_string_index                    = 0;
553
554
0
  if( value_entry == NULL )
555
0
  {
556
0
    libcerror_error_set(
557
0
     error,
558
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
560
0
     "%s: invalid value entry.",
561
0
     function );
562
563
0
    return( -1 );
564
0
  }
565
0
  if( value_entry->name == NULL )
566
0
  {
567
0
    libcerror_error_set(
568
0
     error,
569
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
570
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
571
0
     "%s: invalid value entry - missing name.",
572
0
     function );
573
574
0
    return( -1 );
575
0
  }
576
0
  if( utf8_string == NULL )
577
0
  {
578
0
    libcerror_error_set(
579
0
     error,
580
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
581
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
582
0
     "%s: invalid UTF-8 string.",
583
0
     function );
584
585
0
    return( -1 );
586
0
  }
587
0
  if( utf8_string_length > (size_t) SSIZE_MAX )
588
0
  {
589
0
    libcerror_error_set(
590
0
     error,
591
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
593
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
594
0
     function );
595
596
0
    return( -1 );
597
0
  }
598
  /* Do a full compare if there no name hash was provided or the name hash matches
599
   */
600
0
  if( ( name_hash == 0 )
601
0
   || ( value_entry->name_hash == 0 )
602
0
   || ( value_entry->name_hash == name_hash ) )
603
0
  {
604
0
    while( name_index < (size_t) value_entry->name_size )
605
0
    {
606
0
      if( utf8_string_index >= utf8_string_length )
607
0
      {
608
0
        break;
609
0
      }
610
0
      if( libuna_unicode_character_copy_from_byte_stream(
611
0
           &name_character,
612
0
           value_entry->name,
613
0
           (size_t) value_entry->name_size,
614
0
           &name_index,
615
0
           ascii_codepage,
616
0
           error ) != 1 )
617
0
      {
618
0
        libcerror_error_set(
619
0
         error,
620
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
621
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
622
0
         "%s: unable to copy value name to Unicode character.",
623
0
         function );
624
625
0
        return( -1 );
626
0
      }
627
0
      if( libuna_unicode_character_copy_from_utf8(
628
0
           &string_character,
629
0
           utf8_string,
630
0
           utf8_string_length,
631
0
           &utf8_string_index,
632
0
           error ) != 1 )
633
0
      {
634
0
        libcerror_error_set(
635
0
         error,
636
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
637
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
638
0
         "%s: unable to copy UTF-8 string to Unicode character.",
639
0
         function );
640
641
0
        return( -1 );
642
0
      }
643
0
      if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) )
644
0
      {
645
0
        break;
646
0
      }
647
0
    }
648
0
    if( ( name_index == (size_t) value_entry->name_size )
649
0
     && ( utf8_string_index == utf8_string_length ) )
650
0
    {
651
0
      return( 1 );
652
0
    }
653
0
  }
654
0
  return( 0 );
655
0
}
656
657
/* Compares the value name with UTF-16 string
658
 * Returns 1 if the names match, 0 if not or -1 on error
659
 */
660
int libcreg_value_entry_compare_name_with_utf16_string(
661
     libcreg_value_entry_t *value_entry,
662
     uint32_t name_hash,
663
     const uint16_t *utf16_string,
664
     size_t utf16_string_length,
665
     int ascii_codepage,
666
     libcerror_error_t **error )
667
0
{
668
0
  static char *function                       = "libcreg_value_entry_compare_name_with_utf16_string";
669
0
  libuna_unicode_character_t name_character   = 0;
670
0
  libuna_unicode_character_t string_character = 0;
671
0
  size_t name_index                           = 0;
672
0
  size_t utf16_string_index                   = 0;
673
674
0
  if( value_entry == NULL )
675
0
  {
676
0
    libcerror_error_set(
677
0
     error,
678
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
679
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
680
0
     "%s: invalid value entry.",
681
0
     function );
682
683
0
    return( -1 );
684
0
  }
685
0
  if( value_entry->name == NULL )
686
0
  {
687
0
    libcerror_error_set(
688
0
     error,
689
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
690
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
691
0
     "%s: invalid value entry - missing name.",
692
0
     function );
693
694
0
    return( -1 );
695
0
  }
696
0
  if( utf16_string == NULL )
697
0
  {
698
0
    libcerror_error_set(
699
0
     error,
700
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
701
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
702
0
     "%s: invalid UTF-16 string.",
703
0
     function );
704
705
0
    return( -1 );
706
0
  }
707
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
708
0
  {
709
0
    libcerror_error_set(
710
0
     error,
711
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
712
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
713
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
714
0
     function );
715
716
0
    return( -1 );
717
0
  }
718
  /* Do a full compare if there no name hash was provided or the name hash matches
719
   */
720
0
  if( ( name_hash == 0 )
721
0
   || ( value_entry->name_hash == 0 )
722
0
   || ( value_entry->name_hash == name_hash ) )
723
0
  {
724
0
    while( name_index < (size_t) value_entry->name_size )
725
0
    {
726
0
      if( utf16_string_index >= utf16_string_length )
727
0
      {
728
0
        break;
729
0
      }
730
0
      if( libuna_unicode_character_copy_from_byte_stream(
731
0
           &name_character,
732
0
           value_entry->name,
733
0
           (size_t) value_entry->name_size,
734
0
           &name_index,
735
0
           ascii_codepage,
736
0
           error ) != 1 )
737
0
      {
738
0
        libcerror_error_set(
739
0
         error,
740
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
741
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
742
0
         "%s: unable to copy value name to Unicode character.",
743
0
         function );
744
745
0
        return( -1 );
746
0
      }
747
0
      if( libuna_unicode_character_copy_from_utf16(
748
0
           &string_character,
749
0
           utf16_string,
750
0
           utf16_string_length,
751
0
           &utf16_string_index,
752
0
           error ) != 1 )
753
0
      {
754
0
        libcerror_error_set(
755
0
         error,
756
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
757
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
758
0
         "%s: unable to copy UTF-16 string to Unicode character.",
759
0
         function );
760
761
0
        return( -1 );
762
0
      }
763
0
      if( towupper( (wint_t) name_character ) != towupper( (wint_t) string_character ) )
764
0
      {
765
0
        break;
766
0
      }
767
0
    }
768
0
    if( ( name_index == (size_t) value_entry->name_size )
769
0
     && ( utf16_string_index == utf16_string_length ) )
770
0
    {
771
0
      return( 1 );
772
0
    }
773
0
  }
774
0
  return( 0 );
775
0
}
776