Coverage Report

Created: 2026-08-31 07:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libregf/libregf/libregf_value.c
Line
Count
Source
1
/*
2
 * Value functions
3
 *
4
 * Copyright (C) 2009-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libregf_definitions.h"
27
#include "libregf_io_handle.h"
28
#include "libregf_libbfio.h"
29
#include "libregf_libcerror.h"
30
#include "libregf_multi_string.h"
31
#include "libregf_value.h"
32
#include "libregf_value_item.h"
33
34
/* Creates a value
35
 * Make sure the value value is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libregf_value_initialize(
39
     libregf_value_t **value,
40
     libregf_io_handle_t *io_handle,
41
     libbfio_handle_t *file_io_handle,
42
     off64_t file_offset,
43
     libregf_value_item_t *value_item,
44
     libcerror_error_t **error )
45
231
{
46
231
  libregf_internal_value_t *internal_value = NULL;
47
231
  static char *function                    = "libregf_value_initialize";
48
49
231
  if( value == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid value.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
231
  if( *value != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid value value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
231
  if( value_item == NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
76
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
77
0
     "%s: invalid value item.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
231
  internal_value = memory_allocate_structure(
83
231
                    libregf_internal_value_t );
84
85
231
  if( internal_value == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
90
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
91
0
     "%s: unable to create internal value.",
92
0
     function );
93
94
0
    goto on_error;
95
0
  }
96
231
  if( memory_set(
97
231
       internal_value,
98
231
       0,
99
231
       sizeof( libregf_internal_value_t ) ) == NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
104
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
105
0
     "%s: unable to clear internal value.",
106
0
     function );
107
108
0
    memory_free(
109
0
     internal_value );
110
111
0
    return( -1 );
112
0
  }
113
231
  if( libregf_value_item_clone(
114
231
       &( internal_value->value_item ),
115
231
       value_item,
116
231
       error ) != 1 )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
121
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
122
0
     "%s: unable to clone value item.",
123
0
     function );
124
125
0
    goto on_error;
126
0
  }
127
231
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
128
231
  if( libcthreads_read_write_lock_initialize(
129
231
       &( internal_value->read_write_lock ),
130
231
       error ) != 1 )
131
0
  {
132
0
    libcerror_error_set(
133
0
     error,
134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
135
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
136
0
     "%s: unable to initialize read/write lock.",
137
0
     function );
138
139
0
    goto on_error;
140
0
  }
141
231
#endif
142
231
  internal_value->file_io_handle = file_io_handle;
143
231
  internal_value->io_handle      = io_handle;
144
231
  internal_value->file_offset    = file_offset;
145
146
231
  *value = (libregf_value_t *) internal_value;
147
148
231
  return( 1 );
149
150
0
on_error:
151
0
  if( internal_value != NULL )
152
0
  {
153
0
    if( internal_value->value_item != NULL )
154
0
    {
155
0
      libregf_value_item_free(
156
0
       &( internal_value->value_item ),
157
0
       NULL );
158
0
    }
159
0
    memory_free(
160
0
     internal_value );
161
0
  }
162
0
  return( -1 );
163
231
}
164
165
/* Frees a value
166
 * Returns 1 if successful or -1 on error
167
 */
168
int libregf_value_free(
169
     libregf_value_t **value,
170
     libcerror_error_t **error )
171
231
{
172
231
  libregf_internal_value_t *internal_value = NULL;
173
231
  static char *function                    = "libregf_value_free";
174
231
  int result                               = 1;
175
176
231
  if( value == NULL )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
182
0
     "%s: invalid value.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
231
  if( *value != NULL )
188
231
  {
189
231
    internal_value = (libregf_internal_value_t *) *value;
190
231
    *value         = NULL;
191
192
231
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
193
231
    if( libcthreads_read_write_lock_free(
194
231
         &( internal_value->read_write_lock ),
195
231
         error ) != 1 )
196
0
    {
197
0
      libcerror_error_set(
198
0
       error,
199
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
200
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
201
0
       "%s: unable to free read/write lock.",
202
0
       function );
203
204
0
      result = -1;
205
0
    }
206
231
#endif
207
231
    if( libregf_value_item_free(
208
231
         &( internal_value->value_item ),
209
231
         error ) != 1 )
210
0
    {
211
0
      libcerror_error_set(
212
0
       error,
213
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
214
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
215
0
       "%s: unable to free value item.",
216
0
       function );
217
218
0
      result = -1;
219
0
    }
220
    /* The io_handle and file_io_handle references are freed elsewhere
221
     */
222
231
    memory_free(
223
231
     internal_value );
224
231
  }
225
231
  return( result );
226
231
}
227
228
/* Determine if the value corrupted
229
 * Returns 1 if corrupted, 0 if not or -1 on error
230
 */
231
int libregf_value_is_corrupted(
232
     libregf_value_t *value,
233
     libcerror_error_t **error )
234
0
{
235
0
  libregf_internal_value_t *internal_value = NULL;
236
0
  static char *function                    = "libregf_value_is_corrupted";
237
0
  int result                               = 1;
238
239
0
  if( value == NULL )
240
0
  {
241
0
    libcerror_error_set(
242
0
     error,
243
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
244
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
245
0
     "%s: invalid value.",
246
0
     function );
247
248
0
    return( -1 );
249
0
  }
250
0
  internal_value = (libregf_internal_value_t *) value;
251
252
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
253
0
  if( libcthreads_read_write_lock_grab_for_read(
254
0
       internal_value->read_write_lock,
255
0
       error ) != 1 )
256
0
  {
257
0
    libcerror_error_set(
258
0
     error,
259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
260
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
261
0
     "%s: unable to grab read/write lock for reading.",
262
0
     function );
263
264
0
    return( -1 );
265
0
  }
266
0
#endif
267
0
  result = libregf_value_item_is_corrupted(
268
0
            internal_value->value_item,
269
0
            error );
270
271
0
  if( result == -1 )
272
0
  {
273
0
    libcerror_error_set(
274
0
     error,
275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
276
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
277
0
     "%s: unable to determine if value is corrupted.",
278
0
     function );
279
280
0
    result = -1;
281
0
  }
282
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
283
0
  if( libcthreads_read_write_lock_release_for_read(
284
0
       internal_value->read_write_lock,
285
0
       error ) != 1 )
286
0
  {
287
0
    libcerror_error_set(
288
0
     error,
289
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
290
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
291
0
     "%s: unable to release read/write lock for reading.",
292
0
     function );
293
294
0
    return( -1 );
295
0
  }
296
0
#endif
297
0
  return( result );
298
0
}
299
300
/* Retrieves the offset of the value
301
 * Returns 1 if successful or -1 on error
302
 */
303
int libregf_value_get_offset(
304
     libregf_value_t *value,
305
     off64_t *offset,
306
     libcerror_error_t **error )
307
0
{
308
0
  libregf_internal_value_t *internal_value = NULL;
309
0
  static char *function                    = "libregf_value_get_offset";
310
0
  int result                               = 1;
311
312
0
  if( value == NULL )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
317
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
318
0
     "%s: invalid value.",
319
0
     function );
320
321
0
    return( -1 );
322
0
  }
323
0
  internal_value = (libregf_internal_value_t *) value;
324
325
0
  if( internal_value->io_handle == NULL )
326
0
  {
327
0
    libcerror_error_set(
328
0
     error,
329
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
330
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
331
0
     "%s: invalid value - missing IO handle.",
332
0
     function );
333
334
0
    return( -1 );
335
0
  }
336
0
  if( offset == NULL )
337
0
  {
338
0
    libcerror_error_set(
339
0
     error,
340
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
341
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
342
0
     "%s: invalid offset.",
343
0
     function );
344
345
0
    return( -1 );
346
0
  }
347
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
348
0
  if( libcthreads_read_write_lock_grab_for_read(
349
0
       internal_value->read_write_lock,
350
0
       error ) != 1 )
351
0
  {
352
0
    libcerror_error_set(
353
0
     error,
354
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
355
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
356
0
     "%s: unable to grab read/write lock for reading.",
357
0
     function );
358
359
0
    return( -1 );
360
0
  }
361
0
#endif
362
0
  *offset = internal_value->file_offset;
363
364
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
365
0
  if( libcthreads_read_write_lock_release_for_read(
366
0
       internal_value->read_write_lock,
367
0
       error ) != 1 )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
372
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
373
0
     "%s: unable to release read/write lock for reading.",
374
0
     function );
375
376
0
    return( -1 );
377
0
  }
378
0
#endif
379
0
  return( result );
380
0
}
381
382
/* Retrieves the value name size
383
 * Returns 1 if successful or -1 on error
384
 */
385
int libregf_value_get_name_size(
386
     libregf_value_t *value,
387
     size_t *name_size,
388
     libcerror_error_t **error )
389
0
{
390
0
  libregf_internal_value_t *internal_value = NULL;
391
0
  static char *function                    = "libregf_value_get_name_size";
392
0
  int result                               = 1;
393
394
0
  if( value == NULL )
395
0
  {
396
0
    libcerror_error_set(
397
0
     error,
398
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
399
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
400
0
     "%s: invalid value.",
401
0
     function );
402
403
0
    return( -1 );
404
0
  }
405
0
  internal_value = (libregf_internal_value_t *) value;
406
407
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
408
0
  if( libcthreads_read_write_lock_grab_for_read(
409
0
       internal_value->read_write_lock,
410
0
       error ) != 1 )
411
0
  {
412
0
    libcerror_error_set(
413
0
     error,
414
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
415
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
416
0
     "%s: unable to grab read/write lock for reading.",
417
0
     function );
418
419
0
    return( -1 );
420
0
  }
421
0
#endif
422
0
  if( libregf_value_item_get_name_size(
423
0
       internal_value->value_item,
424
0
       name_size,
425
0
       error ) != 1 )
426
0
  {
427
0
    libcerror_error_set(
428
0
     error,
429
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
430
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
431
0
     "%s: unable to retrieve name size.",
432
0
     function );
433
434
0
    result = -1;
435
0
  }
436
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
437
0
  if( libcthreads_read_write_lock_release_for_read(
438
0
       internal_value->read_write_lock,
439
0
       error ) != 1 )
440
0
  {
441
0
    libcerror_error_set(
442
0
     error,
443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
445
0
     "%s: unable to release read/write lock for reading.",
446
0
     function );
447
448
0
    return( -1 );
449
0
  }
450
0
#endif
451
0
  return( result );
452
0
}
453
454
/* Retrieves the value name
455
 * Returns 1 if successful or -1 on error
456
 */
457
int libregf_value_get_name(
458
     libregf_value_t *value,
459
     uint8_t *name,
460
     size_t name_size,
461
     libcerror_error_t **error )
462
0
{
463
0
  libregf_internal_value_t *internal_value = NULL;
464
0
  static char *function                    = "libregf_value_get_name";
465
0
  int result                               = 1;
466
467
0
  if( value == NULL )
468
0
  {
469
0
    libcerror_error_set(
470
0
     error,
471
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
472
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
473
0
     "%s: invalid value.",
474
0
     function );
475
476
0
    return( -1 );
477
0
  }
478
0
  internal_value = (libregf_internal_value_t *) value;
479
480
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
481
0
  if( libcthreads_read_write_lock_grab_for_read(
482
0
       internal_value->read_write_lock,
483
0
       error ) != 1 )
484
0
  {
485
0
    libcerror_error_set(
486
0
     error,
487
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
488
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
489
0
     "%s: unable to grab read/write lock for reading.",
490
0
     function );
491
492
0
    return( -1 );
493
0
  }
494
0
#endif
495
0
  if( libregf_value_item_get_name(
496
0
       internal_value->value_item,
497
0
       name,
498
0
       name_size,
499
0
       error ) != 1 )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
504
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
505
0
     "%s: unable to retrieve name.",
506
0
     function );
507
508
0
    result = -1;
509
0
  }
510
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
511
0
  if( libcthreads_read_write_lock_release_for_read(
512
0
       internal_value->read_write_lock,
513
0
       error ) != 1 )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
518
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
519
0
     "%s: unable to release read/write lock for reading.",
520
0
     function );
521
522
0
    return( -1 );
523
0
  }
524
0
#endif
525
0
  return( result );
526
0
}
527
528
/* Retrieves the UTF-8 string size of the value name
529
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
530
 * The returned size includes the end of string character
531
 * Returns 1 if successful or -1 on error
532
 */
533
int libregf_value_get_utf8_name_size(
534
     libregf_value_t *value,
535
     size_t *utf8_name_size,
536
     libcerror_error_t **error )
537
0
{
538
0
  libregf_internal_value_t *internal_value = NULL;
539
0
  static char *function                    = "libregf_value_get_utf8_name_size";
540
0
  int result                               = 1;
541
542
0
  if( value == NULL )
543
0
  {
544
0
    libcerror_error_set(
545
0
     error,
546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
548
0
     "%s: invalid value.",
549
0
     function );
550
551
0
    return( -1 );
552
0
  }
553
0
  internal_value = (libregf_internal_value_t *) value;
554
555
0
  if( internal_value->io_handle == NULL )
556
0
  {
557
0
    libcerror_error_set(
558
0
     error,
559
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
560
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
561
0
     "%s: invalid value - missing IO handle.",
562
0
     function );
563
564
0
    return( -1 );
565
0
  }
566
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
567
0
  if( libcthreads_read_write_lock_grab_for_read(
568
0
       internal_value->read_write_lock,
569
0
       error ) != 1 )
570
0
  {
571
0
    libcerror_error_set(
572
0
     error,
573
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
574
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
575
0
     "%s: unable to grab read/write lock for reading.",
576
0
     function );
577
578
0
    return( -1 );
579
0
  }
580
0
#endif
581
0
  if( libregf_value_item_get_utf8_name_size(
582
0
       internal_value->value_item,
583
0
       utf8_name_size,
584
0
       internal_value->io_handle->ascii_codepage,
585
0
       error ) != 1 )
586
0
  {
587
0
    libcerror_error_set(
588
0
     error,
589
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
590
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
591
0
     "%s: unable to retrieve UTF-8 name size.",
592
0
     function );
593
594
0
    result = -1;
595
0
  }
596
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
597
0
  if( libcthreads_read_write_lock_release_for_read(
598
0
       internal_value->read_write_lock,
599
0
       error ) != 1 )
600
0
  {
601
0
    libcerror_error_set(
602
0
     error,
603
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
604
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
605
0
     "%s: unable to release read/write lock for reading.",
606
0
     function );
607
608
0
    return( -1 );
609
0
  }
610
0
#endif
611
0
  return( result );
612
0
}
613
614
/* Retrieves the UTF-8 string value of the value name
615
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
616
 * The function uses a codepage if necessary, it uses the codepage set for the library
617
 * The size should include the end of string character
618
 * Returns 1 if successful or -1 on error
619
 */
620
int libregf_value_get_utf8_name(
621
     libregf_value_t *value,
622
     uint8_t *utf8_name,
623
     size_t utf8_name_size,
624
     libcerror_error_t **error )
625
0
{
626
0
  libregf_internal_value_t *internal_value = NULL;
627
0
  static char *function                    = "libregf_value_get_utf8_name";
628
0
  int result                               = 1;
629
630
0
  if( value == NULL )
631
0
  {
632
0
    libcerror_error_set(
633
0
     error,
634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
635
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
636
0
     "%s: invalid value.",
637
0
     function );
638
639
0
    return( -1 );
640
0
  }
641
0
  internal_value = (libregf_internal_value_t *) value;
642
643
0
  if( internal_value->io_handle == NULL )
644
0
  {
645
0
    libcerror_error_set(
646
0
     error,
647
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
648
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
649
0
     "%s: invalid value - missing IO handle.",
650
0
     function );
651
652
0
    return( -1 );
653
0
  }
654
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
655
0
  if( libcthreads_read_write_lock_grab_for_read(
656
0
       internal_value->read_write_lock,
657
0
       error ) != 1 )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
662
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
663
0
     "%s: unable to grab read/write lock for reading.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
0
#endif
669
0
  if( libregf_value_item_get_utf8_name(
670
0
       internal_value->value_item,
671
0
       utf8_name,
672
0
       utf8_name_size,
673
0
       internal_value->io_handle->ascii_codepage,
674
0
       error ) != 1 )
675
0
  {
676
0
    libcerror_error_set(
677
0
     error,
678
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
679
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
680
0
     "%s: unable to retrieve UTF-8 name size.",
681
0
     function );
682
683
0
    result = -1;
684
0
  }
685
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
686
0
  if( libcthreads_read_write_lock_release_for_read(
687
0
       internal_value->read_write_lock,
688
0
       error ) != 1 )
689
0
  {
690
0
    libcerror_error_set(
691
0
     error,
692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
693
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
694
0
     "%s: unable to release read/write lock for reading.",
695
0
     function );
696
697
0
    return( -1 );
698
0
  }
699
0
#endif
700
0
  return( result );
701
0
}
702
703
/* Retrieves the UTF-16 string size of the value name
704
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
705
 * The returned size includes the end of string character
706
 * Returns 1 if successful or -1 on error
707
 */
708
int libregf_value_get_utf16_name_size(
709
     libregf_value_t *value,
710
     size_t *utf16_name_size,
711
     libcerror_error_t **error )
712
0
{
713
0
  libregf_internal_value_t *internal_value = NULL;
714
0
  static char *function                    = "libregf_value_get_utf16_name_size";
715
0
  int result                               = 1;
716
717
0
  if( value == NULL )
718
0
  {
719
0
    libcerror_error_set(
720
0
     error,
721
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
722
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
723
0
     "%s: invalid value.",
724
0
     function );
725
726
0
    return( -1 );
727
0
  }
728
0
  internal_value = (libregf_internal_value_t *) value;
729
730
0
  if( internal_value->io_handle == NULL )
731
0
  {
732
0
    libcerror_error_set(
733
0
     error,
734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
735
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
736
0
     "%s: invalid value - missing IO handle.",
737
0
     function );
738
739
0
    return( -1 );
740
0
  }
741
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
742
0
  if( libcthreads_read_write_lock_grab_for_read(
743
0
       internal_value->read_write_lock,
744
0
       error ) != 1 )
745
0
  {
746
0
    libcerror_error_set(
747
0
     error,
748
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
749
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
750
0
     "%s: unable to grab read/write lock for reading.",
751
0
     function );
752
753
0
    return( -1 );
754
0
  }
755
0
#endif
756
0
  if( libregf_value_item_get_utf16_name_size(
757
0
       internal_value->value_item,
758
0
       utf16_name_size,
759
0
       internal_value->io_handle->ascii_codepage,
760
0
       error ) != 1 )
761
0
  {
762
0
    libcerror_error_set(
763
0
     error,
764
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
765
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
766
0
     "%s: unable to retrieve UTF-16 name size.",
767
0
     function );
768
769
0
    result = -1;
770
0
  }
771
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
772
0
  if( libcthreads_read_write_lock_release_for_read(
773
0
       internal_value->read_write_lock,
774
0
       error ) != 1 )
775
0
  {
776
0
    libcerror_error_set(
777
0
     error,
778
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
779
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
780
0
     "%s: unable to release read/write lock for reading.",
781
0
     function );
782
783
0
    return( -1 );
784
0
  }
785
0
#endif
786
0
  return( result );
787
0
}
788
789
/* Retrieves the UTF-16 string value of the value name
790
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
791
 * The function uses a codepage if necessary, it uses the codepage set for the library
792
 * The size should include the end of string character
793
 * Returns 1 if successful or -1 on error
794
 */
795
int libregf_value_get_utf16_name(
796
     libregf_value_t *value,
797
     uint16_t *utf16_name,
798
     size_t utf16_name_size,
799
     libcerror_error_t **error )
800
0
{
801
0
  libregf_internal_value_t *internal_value = NULL;
802
0
  static char *function                    = "libregf_value_get_utf16_name";
803
0
  int result                               = 1;
804
805
0
  if( value == NULL )
806
0
  {
807
0
    libcerror_error_set(
808
0
     error,
809
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
810
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
811
0
     "%s: invalid value.",
812
0
     function );
813
814
0
    return( -1 );
815
0
  }
816
0
  internal_value = (libregf_internal_value_t *) value;
817
818
0
  if( internal_value->io_handle == NULL )
819
0
  {
820
0
    libcerror_error_set(
821
0
     error,
822
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
823
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
824
0
     "%s: invalid value - missing IO handle.",
825
0
     function );
826
827
0
    return( -1 );
828
0
  }
829
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
830
0
  if( libcthreads_read_write_lock_grab_for_read(
831
0
       internal_value->read_write_lock,
832
0
       error ) != 1 )
833
0
  {
834
0
    libcerror_error_set(
835
0
     error,
836
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
837
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
838
0
     "%s: unable to grab read/write lock for reading.",
839
0
     function );
840
841
0
    return( -1 );
842
0
  }
843
0
#endif
844
0
  if( libregf_value_item_get_utf16_name(
845
0
       internal_value->value_item,
846
0
       utf16_name,
847
0
       utf16_name_size,
848
0
       internal_value->io_handle->ascii_codepage,
849
0
       error ) != 1 )
850
0
  {
851
0
    libcerror_error_set(
852
0
     error,
853
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
854
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
855
0
     "%s: unable to retrieve UTF-16 name size.",
856
0
     function );
857
858
0
    result = -1;
859
0
  }
860
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
861
0
  if( libcthreads_read_write_lock_release_for_read(
862
0
       internal_value->read_write_lock,
863
0
       error ) != 1 )
864
0
  {
865
0
    libcerror_error_set(
866
0
     error,
867
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
868
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
869
0
     "%s: unable to release read/write lock for reading.",
870
0
     function );
871
872
0
    return( -1 );
873
0
  }
874
0
#endif
875
0
  return( result );
876
0
}
877
878
/* Retrieves the value type
879
 * Returns 1 if successful or -1 on error
880
 */
881
int libregf_value_get_value_type(
882
     libregf_value_t *value,
883
     uint32_t *value_type,
884
     libcerror_error_t **error )
885
231
{
886
231
  libregf_internal_value_t *internal_value = NULL;
887
231
  static char *function                    = "libregf_value_get_value_type";
888
231
  int result                               = 1;
889
890
231
  if( value == 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 value.",
897
0
     function );
898
899
0
    return( -1 );
900
0
  }
901
231
  internal_value = (libregf_internal_value_t *) value;
902
903
231
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
904
231
  if( libcthreads_read_write_lock_grab_for_read(
905
231
       internal_value->read_write_lock,
906
231
       error ) != 1 )
907
0
  {
908
0
    libcerror_error_set(
909
0
     error,
910
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
911
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
912
0
     "%s: unable to grab read/write lock for reading.",
913
0
     function );
914
915
0
    return( -1 );
916
0
  }
917
231
#endif
918
231
  if( libregf_value_item_get_value_type(
919
231
       internal_value->value_item,
920
231
       value_type,
921
231
       error ) != 1 )
922
2
  {
923
2
    libcerror_error_set(
924
2
     error,
925
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
926
2
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
927
2
     "%s: unable to retrieve value type.",
928
2
     function );
929
930
2
    result = -1;
931
2
  }
932
231
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
933
231
  if( libcthreads_read_write_lock_release_for_read(
934
231
       internal_value->read_write_lock,
935
231
       error ) != 1 )
936
0
  {
937
0
    libcerror_error_set(
938
0
     error,
939
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
940
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
941
0
     "%s: unable to release read/write lock for reading.",
942
0
     function );
943
944
0
    return( -1 );
945
0
  }
946
231
#endif
947
231
  return( result );
948
231
}
949
950
/* Retrieves the value data size
951
 * Returns 1 if successful or -1 on error
952
 */
953
int libregf_value_get_value_data_size(
954
     libregf_value_t *value,
955
     size_t *value_data_size,
956
     libcerror_error_t **error )
957
0
{
958
0
  libregf_internal_value_t *internal_value = NULL;
959
0
  static char *function                    = "libregf_value_get_value_data_size";
960
0
  int result                               = 1;
961
962
0
  if( value == NULL )
963
0
  {
964
0
    libcerror_error_set(
965
0
     error,
966
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
967
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
968
0
     "%s: invalid value.",
969
0
     function );
970
971
0
    return( -1 );
972
0
  }
973
0
  internal_value = (libregf_internal_value_t *) value;
974
975
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
976
0
  if( libcthreads_read_write_lock_grab_for_read(
977
0
       internal_value->read_write_lock,
978
0
       error ) != 1 )
979
0
  {
980
0
    libcerror_error_set(
981
0
     error,
982
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
983
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
984
0
     "%s: unable to grab read/write lock for reading.",
985
0
     function );
986
987
0
    return( -1 );
988
0
  }
989
0
#endif
990
0
  if( libregf_value_item_get_data_size(
991
0
       internal_value->value_item,
992
0
       value_data_size,
993
0
       error ) != 1 )
994
0
  {
995
0
    libcerror_error_set(
996
0
     error,
997
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
998
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
999
0
     "%s: unable to retrieve value data size.",
1000
0
     function );
1001
1002
0
    result = -1;
1003
0
  }
1004
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1005
0
  if( libcthreads_read_write_lock_release_for_read(
1006
0
       internal_value->read_write_lock,
1007
0
       error ) != 1 )
1008
0
  {
1009
0
    libcerror_error_set(
1010
0
     error,
1011
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1012
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1013
0
     "%s: unable to release read/write lock for reading.",
1014
0
     function );
1015
1016
0
    return( -1 );
1017
0
  }
1018
0
#endif
1019
0
  return( result );
1020
0
}
1021
1022
/* Retrieves the value data
1023
 * Returns 1 if successful or -1 on error
1024
 */
1025
int libregf_value_get_value_data(
1026
     libregf_value_t *value,
1027
     uint8_t *value_data,
1028
     size_t value_data_size,
1029
     libcerror_error_t **error )
1030
0
{
1031
0
  libregf_internal_value_t *internal_value = NULL;
1032
0
  uint8_t *data                            = NULL;
1033
0
  static char *function                    = "libregf_value_get_value_data";
1034
0
  size_t data_size                         = 0;
1035
0
  int result                               = 1;
1036
1037
0
  if( value == 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 value.",
1044
0
     function );
1045
1046
0
    return( -1 );
1047
0
  }
1048
0
  internal_value = (libregf_internal_value_t *) value;
1049
1050
0
  if( value_data == NULL )
1051
0
  {
1052
0
    libcerror_error_set(
1053
0
     error,
1054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1055
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1056
0
     "%s: invalid value data.",
1057
0
     function );
1058
1059
0
    return( -1 );
1060
0
  }
1061
0
  if( value_data_size > (size_t) SSIZE_MAX )
1062
0
  {
1063
0
    libcerror_error_set(
1064
0
     error,
1065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1066
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1067
0
     "%s: invalid value data size value exceeds maximum.",
1068
0
     function );
1069
1070
0
    return( -1 );
1071
0
  }
1072
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1073
0
  if( libcthreads_read_write_lock_grab_for_write(
1074
0
       internal_value->read_write_lock,
1075
0
       error ) != 1 )
1076
0
  {
1077
0
    libcerror_error_set(
1078
0
     error,
1079
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1080
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1081
0
     "%s: unable to grab read/write lock for writing.",
1082
0
     function );
1083
1084
0
    return( -1 );
1085
0
  }
1086
0
#endif
1087
0
  if( libregf_value_item_get_data(
1088
0
       internal_value->value_item,
1089
0
       internal_value->file_io_handle,
1090
0
       &data,
1091
0
       &data_size,
1092
0
       error ) != 1 )
1093
0
  {
1094
0
    libcerror_error_set(
1095
0
     error,
1096
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1097
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1098
0
     "%s: unable to retrieve value data.",
1099
0
     function );
1100
1101
0
    result = -1;
1102
0
  }
1103
0
  else if( value_data_size < data_size )
1104
0
  {
1105
0
    libcerror_error_set(
1106
0
     error,
1107
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1108
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1109
0
     "%s: invalid value data size value out of bounds.",
1110
0
     function );
1111
1112
0
    result = -1;
1113
0
  }
1114
0
  else if( memory_copy(
1115
0
            value_data,
1116
0
            data,
1117
0
            data_size ) == NULL )
1118
0
  {
1119
0
    libcerror_error_set(
1120
0
     error,
1121
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1122
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1123
0
     "%s: unable to copy value data.",
1124
0
     function );
1125
1126
0
    result = -1;
1127
0
  }
1128
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1129
0
  if( libcthreads_read_write_lock_release_for_write(
1130
0
       internal_value->read_write_lock,
1131
0
       error ) != 1 )
1132
0
  {
1133
0
    libcerror_error_set(
1134
0
     error,
1135
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1136
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1137
0
     "%s: unable to release read/write lock for writing.",
1138
0
     function );
1139
1140
0
    return( -1 );
1141
0
  }
1142
0
#endif
1143
0
  return( result );
1144
0
}
1145
1146
/* Retrieves the 32-bit value
1147
 * Returns 1 if successful or -1 on error
1148
 */
1149
int libregf_value_get_value_32bit(
1150
     libregf_value_t *value,
1151
     uint32_t *value_32bit,
1152
     libcerror_error_t **error )
1153
0
{
1154
0
  libregf_internal_value_t *internal_value = NULL;
1155
0
  static char *function                    = "libregf_value_get_value_32bit";
1156
0
  int result                               = 1;
1157
1158
0
  if( value == NULL )
1159
0
  {
1160
0
    libcerror_error_set(
1161
0
     error,
1162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1164
0
     "%s: invalid value.",
1165
0
     function );
1166
1167
0
    return( -1 );
1168
0
  }
1169
0
  internal_value = (libregf_internal_value_t *) value;
1170
1171
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1172
0
  if( libcthreads_read_write_lock_grab_for_write(
1173
0
       internal_value->read_write_lock,
1174
0
       error ) != 1 )
1175
0
  {
1176
0
    libcerror_error_set(
1177
0
     error,
1178
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1180
0
     "%s: unable to grab read/write lock for writing.",
1181
0
     function );
1182
1183
0
    return( -1 );
1184
0
  }
1185
0
#endif
1186
0
  if( libregf_value_item_get_value_32bit(
1187
0
       internal_value->value_item,
1188
0
       internal_value->file_io_handle,
1189
0
       value_32bit,
1190
0
       error ) != 1 )
1191
0
  {
1192
0
    libcerror_error_set(
1193
0
     error,
1194
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1195
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1196
0
     "%s: unable to retrieve 32-bit value.",
1197
0
     function );
1198
1199
0
    result = -1;
1200
0
  }
1201
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1202
0
  if( libcthreads_read_write_lock_release_for_write(
1203
0
       internal_value->read_write_lock,
1204
0
       error ) != 1 )
1205
0
  {
1206
0
    libcerror_error_set(
1207
0
     error,
1208
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1209
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1210
0
     "%s: unable to release read/write lock for writing.",
1211
0
     function );
1212
1213
0
    return( -1 );
1214
0
  }
1215
0
#endif
1216
0
  return( result );
1217
0
}
1218
1219
/* Retrieves the 64-bit value
1220
 * Returns 1 if successful or -1 on error
1221
 */
1222
int libregf_value_get_value_64bit(
1223
     libregf_value_t *value,
1224
     uint64_t *value_64bit,
1225
     libcerror_error_t **error )
1226
0
{
1227
0
  libregf_internal_value_t *internal_value = NULL;
1228
0
  static char *function                    = "libregf_value_get_value_64bit";
1229
0
  int result                               = 1;
1230
1231
0
  if( value == NULL )
1232
0
  {
1233
0
    libcerror_error_set(
1234
0
     error,
1235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1237
0
     "%s: invalid value.",
1238
0
     function );
1239
1240
0
    return( -1 );
1241
0
  }
1242
0
  internal_value = (libregf_internal_value_t *) value;
1243
1244
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1245
0
  if( libcthreads_read_write_lock_grab_for_write(
1246
0
       internal_value->read_write_lock,
1247
0
       error ) != 1 )
1248
0
  {
1249
0
    libcerror_error_set(
1250
0
     error,
1251
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1252
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1253
0
     "%s: unable to grab read/write lock for writing.",
1254
0
     function );
1255
1256
0
    return( -1 );
1257
0
  }
1258
0
#endif
1259
0
  if( libregf_value_item_get_value_64bit(
1260
0
       internal_value->value_item,
1261
0
       internal_value->file_io_handle,
1262
0
       value_64bit,
1263
0
       error ) != 1 )
1264
0
  {
1265
0
    libcerror_error_set(
1266
0
     error,
1267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1268
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1269
0
     "%s: unable to retrieve 64-bit value.",
1270
0
     function );
1271
1272
0
    result = -1;
1273
0
  }
1274
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1275
0
  if( libcthreads_read_write_lock_release_for_write(
1276
0
       internal_value->read_write_lock,
1277
0
       error ) != 1 )
1278
0
  {
1279
0
    libcerror_error_set(
1280
0
     error,
1281
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1282
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1283
0
     "%s: unable to release read/write lock for writing.",
1284
0
     function );
1285
1286
0
    return( -1 );
1287
0
  }
1288
0
#endif
1289
0
  return( result );
1290
0
}
1291
1292
/* Retrieves the UTF-8 string size
1293
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1294
 * The returned size includes the end of string character
1295
 * Returns 1 if successful or -1 on error
1296
 */
1297
int libregf_value_get_value_utf8_string_size(
1298
     libregf_value_t *value,
1299
     size_t *utf8_string_size,
1300
     libcerror_error_t **error )
1301
0
{
1302
0
  libregf_internal_value_t *internal_value = NULL;
1303
0
  static char *function                    = "libregf_value_get_value_utf8_string_size";
1304
0
  int result                               = 1;
1305
1306
0
  if( value == NULL )
1307
0
  {
1308
0
    libcerror_error_set(
1309
0
     error,
1310
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1311
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1312
0
     "%s: invalid value.",
1313
0
     function );
1314
1315
0
    return( -1 );
1316
0
  }
1317
0
  internal_value = (libregf_internal_value_t *) value;
1318
1319
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1320
0
  if( libcthreads_read_write_lock_grab_for_write(
1321
0
       internal_value->read_write_lock,
1322
0
       error ) != 1 )
1323
0
  {
1324
0
    libcerror_error_set(
1325
0
     error,
1326
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1327
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1328
0
     "%s: unable to grab read/write lock for writing.",
1329
0
     function );
1330
1331
0
    return( -1 );
1332
0
  }
1333
0
#endif
1334
0
  if( libregf_value_item_get_value_utf8_string_size(
1335
0
       internal_value->value_item,
1336
0
       internal_value->file_io_handle,
1337
0
       utf8_string_size,
1338
0
       error ) != 1 )
1339
0
  {
1340
0
    libcerror_error_set(
1341
0
     error,
1342
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1343
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1344
0
     "%s: unable to retrieve UTF-8 string size.",
1345
0
     function );
1346
1347
0
    result = -1;
1348
0
  }
1349
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1350
0
  if( libcthreads_read_write_lock_release_for_write(
1351
0
       internal_value->read_write_lock,
1352
0
       error ) != 1 )
1353
0
  {
1354
0
    libcerror_error_set(
1355
0
     error,
1356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1357
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1358
0
     "%s: unable to release read/write lock for writing.",
1359
0
     function );
1360
1361
0
    return( -1 );
1362
0
  }
1363
0
#endif
1364
0
  return( result );
1365
0
}
1366
1367
/* Retrieves the UTF-8 string value
1368
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1369
 * The function uses a codepage if necessary, it uses the codepage set for the library
1370
 * The size should include the end of string character
1371
 * Returns 1 if successful or -1 on error
1372
 */
1373
int libregf_value_get_value_utf8_string(
1374
     libregf_value_t *value,
1375
     uint8_t *utf8_string,
1376
     size_t utf8_string_size,
1377
     libcerror_error_t **error )
1378
0
{
1379
0
  libregf_internal_value_t *internal_value = NULL;
1380
0
  static char *function                    = "libregf_value_get_value_utf8_string";
1381
0
  int result                               = 1;
1382
1383
0
  if( value == NULL )
1384
0
  {
1385
0
    libcerror_error_set(
1386
0
     error,
1387
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1388
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1389
0
     "%s: invalid value.",
1390
0
     function );
1391
1392
0
    return( -1 );
1393
0
  }
1394
0
  internal_value = (libregf_internal_value_t *) value;
1395
1396
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1397
0
  if( libcthreads_read_write_lock_grab_for_write(
1398
0
       internal_value->read_write_lock,
1399
0
       error ) != 1 )
1400
0
  {
1401
0
    libcerror_error_set(
1402
0
     error,
1403
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1404
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1405
0
     "%s: unable to grab read/write lock for writing.",
1406
0
     function );
1407
1408
0
    return( -1 );
1409
0
  }
1410
0
#endif
1411
0
  if( libregf_value_item_get_value_utf8_string(
1412
0
       internal_value->value_item,
1413
0
       internal_value->file_io_handle,
1414
0
       utf8_string,
1415
0
       utf8_string_size,
1416
0
       error ) != 1 )
1417
0
  {
1418
0
    libcerror_error_set(
1419
0
     error,
1420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1421
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1422
0
     "%s: unable to retrieve UTF-8 string.",
1423
0
     function );
1424
1425
0
    result = -1;
1426
0
  }
1427
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1428
0
  if( libcthreads_read_write_lock_release_for_write(
1429
0
       internal_value->read_write_lock,
1430
0
       error ) != 1 )
1431
0
  {
1432
0
    libcerror_error_set(
1433
0
     error,
1434
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1435
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1436
0
     "%s: unable to release read/write lock for writing.",
1437
0
     function );
1438
1439
0
    return( -1 );
1440
0
  }
1441
0
#endif
1442
0
  return( result );
1443
0
}
1444
1445
/* Retrieves the UTF-16 string size at a specific value from the referenced value
1446
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1447
 * The returned size includes the end of string character
1448
 * Returns 1 if successful or -1 on error
1449
 */
1450
int libregf_value_get_value_utf16_string_size(
1451
     libregf_value_t *value,
1452
     size_t *utf16_string_size,
1453
     libcerror_error_t **error )
1454
0
{
1455
0
  libregf_internal_value_t *internal_value = NULL;
1456
0
  static char *function                    = "libregf_value_get_value_utf16_string_size";
1457
0
  int result                               = 1;
1458
1459
0
  if( value == NULL )
1460
0
  {
1461
0
    libcerror_error_set(
1462
0
     error,
1463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1465
0
     "%s: invalid value.",
1466
0
     function );
1467
1468
0
    return( -1 );
1469
0
  }
1470
0
  internal_value = (libregf_internal_value_t *) value;
1471
1472
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1473
0
  if( libcthreads_read_write_lock_grab_for_write(
1474
0
       internal_value->read_write_lock,
1475
0
       error ) != 1 )
1476
0
  {
1477
0
    libcerror_error_set(
1478
0
     error,
1479
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1480
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1481
0
     "%s: unable to grab read/write lock for writing.",
1482
0
     function );
1483
1484
0
    return( -1 );
1485
0
  }
1486
0
#endif
1487
0
  if( libregf_value_item_get_value_utf16_string_size(
1488
0
       internal_value->value_item,
1489
0
       internal_value->file_io_handle,
1490
0
       utf16_string_size,
1491
0
       error ) != 1 )
1492
0
  {
1493
0
    libcerror_error_set(
1494
0
     error,
1495
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1496
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1497
0
     "%s: unable to retrieve UTF-16 string size.",
1498
0
     function );
1499
1500
0
    result = -1;
1501
0
  }
1502
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1503
0
  if( libcthreads_read_write_lock_release_for_write(
1504
0
       internal_value->read_write_lock,
1505
0
       error ) != 1 )
1506
0
  {
1507
0
    libcerror_error_set(
1508
0
     error,
1509
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1510
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1511
0
     "%s: unable to release read/write lock for writing.",
1512
0
     function );
1513
1514
0
    return( -1 );
1515
0
  }
1516
0
#endif
1517
0
  return( result );
1518
0
}
1519
1520
/* Retrieves the UTF-16 string value
1521
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1522
 * The function uses a codepage if necessary, it uses the codepage set for the library
1523
 * The size should include the end of string character
1524
 * Returns 1 if successful or -1 on error
1525
 */
1526
int libregf_value_get_value_utf16_string(
1527
     libregf_value_t *value,
1528
     uint16_t *utf16_string,
1529
     size_t utf16_string_size,
1530
     libcerror_error_t **error )
1531
0
{
1532
0
  libregf_internal_value_t *internal_value = NULL;
1533
0
  static char *function                    = "libregf_value_get_value_utf16_string";
1534
0
  int result                               = 1;
1535
1536
0
  if( value == NULL )
1537
0
  {
1538
0
    libcerror_error_set(
1539
0
     error,
1540
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1541
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1542
0
     "%s: invalid value.",
1543
0
     function );
1544
1545
0
    return( -1 );
1546
0
  }
1547
0
  internal_value = (libregf_internal_value_t *) value;
1548
1549
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1550
0
  if( libcthreads_read_write_lock_grab_for_write(
1551
0
       internal_value->read_write_lock,
1552
0
       error ) != 1 )
1553
0
  {
1554
0
    libcerror_error_set(
1555
0
     error,
1556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1557
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1558
0
     "%s: unable to grab read/write lock for writing.",
1559
0
     function );
1560
1561
0
    return( -1 );
1562
0
  }
1563
0
#endif
1564
0
  if( libregf_value_item_get_value_utf16_string(
1565
0
       internal_value->value_item,
1566
0
       internal_value->file_io_handle,
1567
0
       utf16_string,
1568
0
       utf16_string_size,
1569
0
       error ) != 1 )
1570
0
  {
1571
0
    libcerror_error_set(
1572
0
     error,
1573
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1574
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1575
0
     "%s: unable to retrieve UTF-16 string.",
1576
0
     function );
1577
1578
0
    result = -1;
1579
0
  }
1580
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1581
0
  if( libcthreads_read_write_lock_release_for_write(
1582
0
       internal_value->read_write_lock,
1583
0
       error ) != 1 )
1584
0
  {
1585
0
    libcerror_error_set(
1586
0
     error,
1587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1588
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1589
0
     "%s: unable to release read/write lock for writing.",
1590
0
     function );
1591
1592
0
    return( -1 );
1593
0
  }
1594
0
#endif
1595
0
  return( result );
1596
0
}
1597
1598
/* Retrieves the binary data size
1599
 * Returns 1 if successful or -1 on error
1600
 */
1601
int libregf_value_get_value_binary_data_size(
1602
     libregf_value_t *value,
1603
     size_t *size,
1604
     libcerror_error_t **error )
1605
0
{
1606
0
  libregf_internal_value_t *internal_value = NULL;
1607
0
  static char *function                    = "libregf_value_get_value_binary_data_size";
1608
0
  int result                               = 1;
1609
1610
0
  if( value == NULL )
1611
0
  {
1612
0
    libcerror_error_set(
1613
0
     error,
1614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1616
0
     "%s: invalid value.",
1617
0
     function );
1618
1619
0
    return( -1 );
1620
0
  }
1621
0
  internal_value = (libregf_internal_value_t *) value;
1622
1623
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1624
0
  if( libcthreads_read_write_lock_grab_for_write(
1625
0
       internal_value->read_write_lock,
1626
0
       error ) != 1 )
1627
0
  {
1628
0
    libcerror_error_set(
1629
0
     error,
1630
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1631
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1632
0
     "%s: unable to grab read/write lock for writing.",
1633
0
     function );
1634
1635
0
    return( -1 );
1636
0
  }
1637
0
#endif
1638
0
  if( libregf_value_item_get_value_binary_data_size(
1639
0
       internal_value->value_item,
1640
0
       size,
1641
0
       error ) != 1 )
1642
0
  {
1643
0
    libcerror_error_set(
1644
0
     error,
1645
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1646
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1647
0
     "%s: unable to retrieve binary data size.",
1648
0
     function );
1649
1650
0
    result = -1;
1651
0
  }
1652
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1653
0
  if( libcthreads_read_write_lock_release_for_write(
1654
0
       internal_value->read_write_lock,
1655
0
       error ) != 1 )
1656
0
  {
1657
0
    libcerror_error_set(
1658
0
     error,
1659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1660
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1661
0
     "%s: unable to release read/write lock for writing.",
1662
0
     function );
1663
1664
0
    return( -1 );
1665
0
  }
1666
0
#endif
1667
0
  return( result );
1668
0
}
1669
1670
/* Retrieves the binary data value
1671
 * Returns 1 if successful or -1 on error
1672
 */
1673
int libregf_value_get_value_binary_data(
1674
     libregf_value_t *value,
1675
     uint8_t *binary_data,
1676
     size_t size,
1677
     libcerror_error_t **error )
1678
0
{
1679
0
  libregf_internal_value_t *internal_value = NULL;
1680
0
  static char *function                    = "libregf_value_get_value_binary_data";
1681
0
  int result                               = 1;
1682
1683
0
  if( value == NULL )
1684
0
  {
1685
0
    libcerror_error_set(
1686
0
     error,
1687
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1688
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1689
0
     "%s: invalid value.",
1690
0
     function );
1691
1692
0
    return( -1 );
1693
0
  }
1694
0
  internal_value = (libregf_internal_value_t *) value;
1695
1696
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1697
0
  if( libcthreads_read_write_lock_grab_for_write(
1698
0
       internal_value->read_write_lock,
1699
0
       error ) != 1 )
1700
0
  {
1701
0
    libcerror_error_set(
1702
0
     error,
1703
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1704
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1705
0
     "%s: unable to grab read/write lock for writing.",
1706
0
     function );
1707
1708
0
    return( -1 );
1709
0
  }
1710
0
#endif
1711
0
  if( libregf_value_item_get_value_binary_data(
1712
0
       internal_value->value_item,
1713
0
       internal_value->file_io_handle,
1714
0
       binary_data,
1715
0
       size,
1716
0
       error ) != 1 )
1717
0
  {
1718
0
    libcerror_error_set(
1719
0
     error,
1720
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1721
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1722
0
     "%s: unable to retrieve binary data.",
1723
0
     function );
1724
1725
0
    result = -1;
1726
0
  }
1727
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1728
0
  if( libcthreads_read_write_lock_release_for_write(
1729
0
       internal_value->read_write_lock,
1730
0
       error ) != 1 )
1731
0
  {
1732
0
    libcerror_error_set(
1733
0
     error,
1734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1735
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1736
0
     "%s: unable to release read/write lock for writing.",
1737
0
     function );
1738
1739
0
    return( -1 );
1740
0
  }
1741
0
#endif
1742
0
  return( result );
1743
0
}
1744
1745
/* Retrieves the multi string value
1746
 * Creates a new multi string
1747
 * Returns 1 if successful or -1 on error
1748
 */
1749
int libregf_value_get_value_multi_string(
1750
     libregf_value_t *value,
1751
     libregf_multi_string_t **multi_string,
1752
     libcerror_error_t **error )
1753
0
{
1754
0
  libregf_internal_value_t *internal_value = NULL;
1755
0
  static char *function                    = "libregf_value_get_value_multi_string";
1756
0
  int result                               = 1;
1757
1758
0
  if( value == NULL )
1759
0
  {
1760
0
    libcerror_error_set(
1761
0
     error,
1762
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1763
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1764
0
     "%s: invalid value.",
1765
0
     function );
1766
1767
0
    return( -1 );
1768
0
  }
1769
0
  internal_value = (libregf_internal_value_t *) value;
1770
1771
0
  if( multi_string == NULL )
1772
0
  {
1773
0
    libcerror_error_set(
1774
0
     error,
1775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1776
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1777
0
     "%s: invalid multi string.",
1778
0
     function );
1779
1780
0
    return( -1 );
1781
0
  }
1782
0
  if( *multi_string != NULL )
1783
0
  {
1784
0
    libcerror_error_set(
1785
0
     error,
1786
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1787
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1788
0
     "%s: invalid multi string value already set.",
1789
0
     function );
1790
1791
0
    return( -1 );
1792
0
  }
1793
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1794
0
  if( libcthreads_read_write_lock_grab_for_write(
1795
0
       internal_value->read_write_lock,
1796
0
       error ) != 1 )
1797
0
  {
1798
0
    libcerror_error_set(
1799
0
     error,
1800
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1801
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1802
0
     "%s: unable to grab read/write lock for writing.",
1803
0
     function );
1804
1805
0
    return( -1 );
1806
0
  }
1807
0
#endif
1808
0
  if( libregf_value_item_get_value_multi_string(
1809
0
       internal_value->value_item,
1810
0
       internal_value->file_io_handle,
1811
0
       multi_string,
1812
0
       error ) != 1 )
1813
0
  {
1814
0
    libcerror_error_set(
1815
0
     error,
1816
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1817
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1818
0
     "%s: unable to retrieve multi string.",
1819
0
     function );
1820
1821
0
    result = -1;
1822
0
  }
1823
0
#if defined( HAVE_LIBREGF_MULTI_THREAD_SUPPORT )
1824
0
  if( libcthreads_read_write_lock_release_for_write(
1825
0
       internal_value->read_write_lock,
1826
0
       error ) != 1 )
1827
0
  {
1828
0
    libcerror_error_set(
1829
0
     error,
1830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1831
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1832
0
     "%s: unable to release read/write lock for writing.",
1833
0
     function );
1834
1835
0
    libregf_multi_string_free(
1836
0
     multi_string,
1837
0
     NULL );
1838
1839
0
    return( -1 );
1840
0
  }
1841
0
#endif
1842
0
  return( result );
1843
0
}
1844