Coverage Report

Created: 2025-07-04 07:01

/src/libpff/libpff/libpff_multi_value.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Multi value functions
3
 *
4
 * Copyright (C) 2008-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 <memory.h>
24
#include <types.h>
25
26
#include "libpff_definitions.h"
27
#include "libpff_libcerror.h"
28
#include "libpff_libfmapi.h"
29
#include "libpff_mapi.h"
30
#include "libpff_multi_value.h"
31
#include "libpff_value_type.h"
32
#include "libpff_types.h"
33
34
/* Creates a multi value
35
 * Make sure the value multi_value is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libpff_multi_value_initialize(
39
     libpff_multi_value_t **multi_value,
40
     libcerror_error_t **error )
41
0
{
42
0
  libpff_internal_multi_value_t *internal_multi_value = NULL;
43
0
  static char *function                               = "libpff_multi_value_initialize";
44
45
0
  if( multi_value == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid multi value.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
0
  if( *multi_value != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid multi value value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
0
  internal_multi_value = memory_allocate_structure(
68
0
                          libpff_internal_multi_value_t );
69
70
0
  if( internal_multi_value == NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
75
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
76
0
     "%s: unable to create multi value.",
77
0
     function );
78
79
0
    goto on_error;
80
0
  }
81
0
  if( memory_set(
82
0
       internal_multi_value,
83
0
       0,
84
0
       sizeof( libpff_internal_multi_value_t ) ) == NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
89
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
90
0
     "%s: unable to clear multi value.",
91
0
     function );
92
93
0
    goto on_error;
94
0
  }
95
0
  *multi_value = (libpff_multi_value_t *) internal_multi_value;
96
97
0
  return( 1 );
98
99
0
on_error:
100
0
  if( internal_multi_value != NULL )
101
0
  {
102
0
    memory_free(
103
0
     internal_multi_value );
104
0
  }
105
0
  return( -1 );
106
0
}
107
108
/* Frees a multi value
109
 * Returns 1 if successful or -1 on error
110
 */
111
int libpff_multi_value_free(
112
     libpff_multi_value_t **multi_value,
113
     libcerror_error_t **error )
114
0
{
115
0
  static char *function = "libpff_multi_value_free";
116
117
0
  if( multi_value == NULL )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123
0
     "%s: invalid multi value.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
0
  if( *multi_value != NULL )
129
0
  {
130
0
    if( ( (libpff_internal_multi_value_t *) *multi_value )->value_data != NULL )
131
0
    {
132
0
      memory_free(
133
0
       ( (libpff_internal_multi_value_t *) *multi_value )->value_data );
134
0
    }
135
0
    if( ( (libpff_internal_multi_value_t *) *multi_value )->value_offset != NULL )
136
0
    {
137
0
      memory_free(
138
0
       ( (libpff_internal_multi_value_t *) *multi_value )->value_offset );
139
0
    }
140
0
    if( ( (libpff_internal_multi_value_t *) *multi_value )->value_size != NULL )
141
0
    {
142
0
      memory_free(
143
0
       ( (libpff_internal_multi_value_t *) *multi_value )->value_size );
144
0
    }
145
0
    memory_free(
146
0
     *multi_value );
147
148
0
    *multi_value = NULL;
149
0
  }
150
0
  return( 1 );
151
0
}
152
153
/* Retrieves the number of values of the multi value
154
 * Returns 1 if successful or -1 on error
155
 */
156
int libpff_multi_value_get_number_of_values(
157
     libpff_multi_value_t *multi_value,
158
     int *number_of_values,
159
     libcerror_error_t **error )
160
0
{
161
0
  libpff_internal_multi_value_t *internal_multi_value = NULL;
162
0
  static char *function                               = "libpff_multi_value_get_number_of_entries";
163
164
0
  if( multi_value == NULL )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170
0
     "%s: invalid multi value.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
0
  internal_multi_value = (libpff_internal_multi_value_t *) multi_value;
176
177
0
  if( number_of_values == NULL )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
182
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
183
0
     "%s: invalid number of values.",
184
0
     function );
185
186
0
    return( -1 );
187
0
  }
188
0
  if( internal_multi_value->number_of_values > (uint32_t) INT_MAX )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
193
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
194
0
     "%s: invalid number of values value exceeds maximum.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
0
  *number_of_values = (int) internal_multi_value->number_of_values;
200
201
0
  return( 1 );
202
0
}
203
204
/* Retrieves a specific value of the multi value
205
 * Returns 1 if successful or -1 on error
206
 */
207
int libpff_multi_value_get_value(
208
     libpff_multi_value_t *multi_value,
209
     int value_index,
210
     uint32_t *value_type,
211
     uint8_t **value_data,
212
     size_t *value_data_size,
213
     libcerror_error_t **error )
214
0
{
215
0
  libpff_internal_multi_value_t *internal_multi_value = NULL;
216
0
  static char *function                               = "libpff_multi_value_get_value";
217
0
  uint32_t value_offset                               = 0;
218
219
0
  if( multi_value == NULL )
220
0
  {
221
0
    libcerror_error_set(
222
0
     error,
223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
225
0
     "%s: invalid multi value.",
226
0
     function );
227
228
0
    return( -1 );
229
0
  }
230
0
  internal_multi_value = (libpff_internal_multi_value_t *) multi_value;
231
232
0
  if( value_type == NULL )
233
0
  {
234
0
    libcerror_error_set(
235
0
     error,
236
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
237
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
238
0
     "%s: invalid value type.",
239
0
     function );
240
241
0
    return( -1 );
242
0
  }
243
0
  if( ( value_index < 0 )
244
0
   || ( value_index >= (int) internal_multi_value->number_of_values ) )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
250
0
     "%s: invalid value index.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
0
  value_offset = internal_multi_value->value_offset[ value_index ];
256
257
  /* Returns the value type without the multi value flag
258
   */
259
0
  *value_type      = internal_multi_value->value_type & 0xefff;
260
0
  *value_data_size = internal_multi_value->value_size[ value_index ];
261
262
0
  if( internal_multi_value->value_size[ value_index ] == 0 )
263
0
  {
264
0
    *value_data = NULL;
265
0
  }
266
0
  else
267
0
  {
268
0
    *value_data = &( internal_multi_value->value_data[ value_offset ] );
269
0
  }
270
0
  return( 1 );
271
0
}
272
273
/* Retrieves the 32-bit value of a specific value of the multi value
274
 * Returns 1 if successful or -1 on error
275
 */
276
int libpff_multi_value_get_value_32bit(
277
     libpff_multi_value_t *multi_value,
278
     int value_index,
279
     uint32_t *value,
280
     libcerror_error_t **error )
281
0
{
282
0
  uint8_t *value_data    = NULL;
283
0
  static char *function  = "libpff_multi_value_get_value_32bit";
284
0
  size_t value_data_size = 0;
285
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_INTEGER_32BIT_SIGNED;
286
0
  int result             = 0;
287
288
0
  result = libpff_multi_value_get_value(
289
0
            multi_value,
290
0
            value_index,
291
0
            &value_type,
292
0
            &value_data,
293
0
            &value_data_size,
294
0
            error );
295
296
0
  if( result == -1 )
297
0
  {
298
0
    libcerror_error_set(
299
0
     error,
300
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
301
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
302
0
     "%s: unable to retrieve value.",
303
0
     function );
304
0
  }
305
0
  else if( result == 1 )
306
0
  {
307
0
    if( libpff_value_type_copy_to_32bit(
308
0
         value_data,
309
0
         value_data_size,
310
0
         value,
311
0
         error ) != 1 )
312
0
    {
313
0
      libcerror_error_set(
314
0
       error,
315
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
316
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
317
0
       "%s: unable to set 32-bit value.",
318
0
       function );
319
320
0
      return( -1 );
321
0
    }
322
0
  }
323
0
  return( result );
324
0
}
325
326
/* Retrieves the 64-bit value of a specific value of the multi value
327
 * Returns 1 if successful or -1 on error
328
 */
329
int libpff_multi_value_get_value_64bit(
330
     libpff_multi_value_t *multi_value,
331
     int value_index,
332
     uint64_t *value,
333
     libcerror_error_t **error )
334
0
{
335
0
  uint8_t *value_data    = NULL;
336
0
  static char *function  = "libpff_multi_value_get_value_64bit";
337
0
  size_t value_data_size = 0;
338
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_INTEGER_64BIT_SIGNED;
339
0
  int result             = 0;
340
341
0
  result = libpff_multi_value_get_value(
342
0
            multi_value,
343
0
            value_index,
344
0
            &value_type,
345
0
            &value_data,
346
0
            &value_data_size,
347
0
            error );
348
349
0
  if( result == -1 )
350
0
  {
351
0
    libcerror_error_set(
352
0
     error,
353
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
354
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
355
0
     "%s: unable to retrieve value.",
356
0
     function );
357
0
  }
358
0
  else if( result == 1 )
359
0
  {
360
0
    if( libpff_value_type_copy_to_64bit(
361
0
         value_data,
362
0
         value_data_size,
363
0
         value,
364
0
         error ) != 1 )
365
0
    {
366
0
      libcerror_error_set(
367
0
       error,
368
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
369
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
370
0
       "%s: unable to set 64-bit value.",
371
0
       function );
372
373
0
      return( -1 );
374
0
    }
375
0
  }
376
0
  return( result );
377
0
}
378
379
/* Retrieves the 64-bit filetime value of a specific value of the multi value
380
 * Returns 1 if successful or -1 on error
381
 */
382
int libpff_multi_value_get_value_filetime(
383
     libpff_multi_value_t *multi_value,
384
     int value_index,
385
     uint64_t *filetime,
386
     libcerror_error_t **error )
387
0
{
388
0
  uint8_t *value_data    = NULL;
389
0
  static char *function  = "libpff_multi_value_get_value_filetime";
390
0
  size_t value_data_size = 0;
391
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_FILETIME;
392
0
  int result             = 0;
393
394
0
  result = libpff_multi_value_get_value(
395
0
            multi_value,
396
0
            value_index,
397
0
            &value_type,
398
0
            &value_data,
399
0
            &value_data_size,
400
0
            error );
401
402
0
  if( result == -1 )
403
0
  {
404
0
    libcerror_error_set(
405
0
     error,
406
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
407
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
408
0
     "%s: unable to retrieve value.",
409
0
     function );
410
0
  }
411
0
  else if( result == 1 )
412
0
  {
413
0
    if( libpff_value_type_copy_to_64bit(
414
0
         value_data,
415
0
         value_data_size,
416
0
         filetime,
417
0
         error ) != 1 )
418
0
    {
419
0
      libcerror_error_set(
420
0
       error,
421
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
422
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
423
0
       "%s: unable to set filetime value.",
424
0
       function );
425
426
0
      return( -1 );
427
0
    }
428
0
  }
429
0
  return( result );
430
0
}
431
432
/* Retrieves the UTF-8 string size of a specific value of the multi value
433
 * The returned size includes the end of string character
434
 * Returns 1 if successful or -1 on error
435
 */
436
int libpff_multi_value_get_value_utf8_string_size(
437
     libpff_multi_value_t *multi_value,
438
     int value_index,
439
     size_t *utf8_string_size,
440
     libcerror_error_t **error )
441
0
{
442
0
  uint8_t *value_data     = NULL;
443
0
  static char *function   = "libpff_multi_value_get_value_utf8_string_size";
444
0
  size_t value_data_size  = 0;
445
0
  uint32_t value_type     = 0;
446
0
  uint8_t is_ascii_string = 0;
447
0
  int result              = 0;
448
449
0
  result = libpff_multi_value_get_value(
450
0
            multi_value,
451
0
            value_index,
452
0
            &value_type,
453
0
            &value_data,
454
0
            &value_data_size,
455
0
            error );
456
457
0
  if( result == -1 )
458
0
  {
459
0
    libcerror_error_set(
460
0
     error,
461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
462
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
463
0
     "%s: unable to retrieve value.",
464
0
     function );
465
0
  }
466
0
  else if( result == 1 )
467
0
  {
468
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
469
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
470
0
    {
471
0
      libcerror_error_set(
472
0
       error,
473
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
474
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
475
0
       "%s: unsupported string value type: 0x%04" PRIx32 ".",
476
0
       function,
477
0
       value_type );
478
479
0
      return( -1 );
480
0
    }
481
0
    if( value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
482
0
    {
483
0
      is_ascii_string = 1;
484
0
    }
485
0
    if( libpff_value_type_get_utf8_string_size(
486
0
         value_data,
487
0
         value_data_size,
488
0
         is_ascii_string,
489
0
         ( (libpff_internal_multi_value_t *) multi_value )->ascii_codepage,
490
0
         utf8_string_size,
491
0
         error ) != 1 )
492
0
    {
493
0
      libcerror_error_set(
494
0
       error,
495
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
496
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
497
0
       "%s: unable to set UTF-8 string size.",
498
0
       function );
499
500
0
      return( -1 );
501
0
    }
502
0
  }
503
0
  return( result );
504
0
}
505
506
/* Retrieves the UTF-8 string value of a specific value of the multi value
507
 * The size should include the end of string character
508
 * Returns 1 if successful or -1 on error
509
 */
510
int libpff_multi_value_get_value_utf8_string(
511
     libpff_multi_value_t *multi_value,
512
     int value_index,
513
     uint8_t *utf8_string,
514
     size_t utf8_string_size,
515
     libcerror_error_t **error )
516
0
{
517
0
  uint8_t *value_data     = NULL;
518
0
  static char *function   = "libpff_multi_value_get_value_utf8_string";
519
0
  size_t value_data_size  = 0;
520
0
  uint32_t value_type     = 0;
521
0
  uint8_t is_ascii_string = 0;
522
0
  int result              = 0;
523
524
0
  result = libpff_multi_value_get_value(
525
0
            multi_value,
526
0
            value_index,
527
0
            &value_type,
528
0
            &value_data,
529
0
            &value_data_size,
530
0
            error );
531
532
0
  if( result == -1 )
533
0
  {
534
0
    libcerror_error_set(
535
0
     error,
536
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
537
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
538
0
     "%s: unable to retrieve value.",
539
0
     function );
540
0
  }
541
0
  else if( result == 1 )
542
0
  {
543
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
544
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
545
0
    {
546
0
      libcerror_error_set(
547
0
       error,
548
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
549
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
550
0
       "%s: unsupported string value type: 0x%04" PRIx32 ".",
551
0
       function,
552
0
       value_type );
553
554
0
      return( -1 );
555
0
    }
556
0
    if( value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
557
0
    {
558
0
      is_ascii_string = 1;
559
0
    }
560
0
    if( libpff_value_type_copy_to_utf8_string(
561
0
         value_data,
562
0
         value_data_size,
563
0
         is_ascii_string,
564
0
         ( (libpff_internal_multi_value_t *) multi_value )->ascii_codepage,
565
0
         utf8_string,
566
0
         utf8_string_size,
567
0
         error ) != 1 )
568
0
    {
569
0
      libcerror_error_set(
570
0
       error,
571
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
572
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
573
0
       "%s: unable to set UTF-8 string.",
574
0
       function );
575
576
0
      return( -1 );
577
0
    }
578
0
  }
579
0
  return( result );
580
0
}
581
582
/* Retrieves the UTF-16 string size of a specific value of the multi value
583
 * The returned size includes the end of string character
584
 * Returns 1 if successful or -1 on error
585
 */
586
int libpff_multi_value_get_value_utf16_string_size(
587
     libpff_multi_value_t *multi_value,
588
     int value_index,
589
     size_t *utf16_string_size,
590
     libcerror_error_t **error )
591
0
{
592
0
  uint8_t *value_data     = NULL;
593
0
  static char *function   = "libpff_multi_value_get_value_utf16_string_size";
594
0
  size_t value_data_size  = 0;
595
0
  uint32_t value_type     = 0;
596
0
  uint8_t is_ascii_string = 0;
597
0
  int result              = 0;
598
599
0
  result = libpff_multi_value_get_value(
600
0
            multi_value,
601
0
            value_index,
602
0
            &value_type,
603
0
            &value_data,
604
0
            &value_data_size,
605
0
            error );
606
607
0
  if( result == -1 )
608
0
  {
609
0
    libcerror_error_set(
610
0
     error,
611
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
612
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
613
0
     "%s: unable to retrieve value.",
614
0
     function );
615
0
  }
616
0
  else if( result == 1 )
617
0
  {
618
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
619
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
620
0
    {
621
0
      libcerror_error_set(
622
0
       error,
623
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
624
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
625
0
       "%s: unsupported string value type: 0x%04" PRIx32 ".",
626
0
       function,
627
0
       value_type );
628
629
0
      return( -1 );
630
0
    }
631
0
    if( value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
632
0
    {
633
0
      is_ascii_string = 1;
634
0
    }
635
0
    if( libpff_value_type_get_utf16_string_size(
636
0
         value_data,
637
0
         value_data_size,
638
0
         is_ascii_string,
639
0
         ( (libpff_internal_multi_value_t *) multi_value )->ascii_codepage,
640
0
         utf16_string_size,
641
0
         error ) != 1 )
642
0
    {
643
0
      libcerror_error_set(
644
0
       error,
645
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
646
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
647
0
       "%s: unable to set UTF-16 string size.",
648
0
       function );
649
650
0
      return( -1 );
651
0
    }
652
0
  }
653
0
  return( result );
654
0
}
655
656
/* Retrieves the UTF-16 string value of a specific value of the multi value
657
 * The size should include the end of string character
658
 * Returns 1 if successful or -1 on error
659
 */
660
int libpff_multi_value_get_value_utf16_string(
661
     libpff_multi_value_t *multi_value,
662
     int value_index,
663
     uint16_t *utf16_string,
664
     size_t utf16_string_size,
665
     libcerror_error_t **error )
666
0
{
667
0
  uint8_t *value_data     = NULL;
668
0
  static char *function   = "libpff_multi_value_get_value_utf16_string";
669
0
  size_t value_data_size  = 0;
670
0
  uint32_t value_type     = 0;
671
0
  uint8_t is_ascii_string = 0;
672
0
  int result              = 0;
673
674
0
  result = libpff_multi_value_get_value(
675
0
            multi_value,
676
0
            value_index,
677
0
            &value_type,
678
0
            &value_data,
679
0
            &value_data_size,
680
0
            error );
681
682
0
  if( result == -1 )
683
0
  {
684
0
    libcerror_error_set(
685
0
     error,
686
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
687
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
688
0
     "%s: unable to retrieve value.",
689
0
     function );
690
0
  }
691
0
  else if( result == 1 )
692
0
  {
693
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
694
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
695
0
    {
696
0
      libcerror_error_set(
697
0
       error,
698
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
699
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
700
0
       "%s: unsupported string value type: 0x%04" PRIx32 ".",
701
0
       function,
702
0
       value_type );
703
704
0
      return( -1 );
705
0
    }
706
0
    if( value_type == LIBPFF_VALUE_TYPE_STRING_ASCII )
707
0
    {
708
0
      is_ascii_string = 1;
709
0
    }
710
0
    if( libpff_value_type_copy_to_utf16_string(
711
0
         value_data,
712
0
         value_data_size,
713
0
         is_ascii_string,
714
0
         ( (libpff_internal_multi_value_t *) multi_value )->ascii_codepage,
715
0
         utf16_string,
716
0
         utf16_string_size,
717
0
         error ) != 1 )
718
0
    {
719
0
      libcerror_error_set(
720
0
       error,
721
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
722
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
723
0
       "%s: unable to set UTF-16 string.",
724
0
       function );
725
726
0
      return( -1 );
727
0
    }
728
0
  }
729
0
  return( result );
730
0
}
731
732
/* Retrieves the size of a binary data value of a specific value of the multi value
733
 * Returns 1 if successful or -1 on error
734
 */
735
int libpff_multi_value_get_value_binary_data_size(
736
     libpff_multi_value_t *multi_value,
737
     int value_index,
738
     size_t *size,
739
     libcerror_error_t **error )
740
0
{
741
0
  uint8_t *value_data    = NULL;
742
0
  static char *function  = "libpff_multi_value_get_value_binary_data_size";
743
0
  size_t value_data_size = 0;
744
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_BINARY_DATA;
745
0
  int result             = 0;
746
747
0
  result = libpff_multi_value_get_value(
748
0
            multi_value,
749
0
            value_index,
750
0
            &value_type,
751
0
            &value_data,
752
0
            &value_data_size,
753
0
            error );
754
755
0
  if( result == -1 )
756
0
  {
757
0
    libcerror_error_set(
758
0
     error,
759
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
760
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
761
0
     "%s: unable to retrieve value.",
762
0
     function );
763
0
  }
764
0
  else if( result == 1 )
765
0
  {
766
0
    if( libpff_value_type_get_binary_data_size(
767
0
         value_data,
768
0
         value_data_size,
769
0
         size,
770
0
         error ) != 1 )
771
0
    {
772
0
      libcerror_error_set(
773
0
       error,
774
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
775
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
776
0
       "%s: unable to set binary data size.",
777
0
       function );
778
779
0
      return( -1 );
780
0
    }
781
0
  }
782
0
  return( result );
783
0
}
784
785
/* Retrieves the binary data value of a specific value of the multi value
786
 * Returns 1 if successful or -1 on error
787
 */
788
int libpff_multi_value_get_value_binary_data(
789
     libpff_multi_value_t *multi_value,
790
     int value_index,
791
     uint8_t *binary_data,
792
     size_t size,
793
     libcerror_error_t **error )
794
0
{
795
0
  uint8_t *value_data    = NULL;
796
0
  static char *function  = "libpff_multi_value_get_value_binary_data";
797
0
  size_t value_data_size = 0;
798
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_BINARY_DATA;
799
0
  int result             = 0;
800
801
0
  result = libpff_multi_value_get_value(
802
0
            multi_value,
803
0
            value_index,
804
0
            &value_type,
805
0
            &value_data,
806
0
            &value_data_size,
807
0
            error );
808
809
0
  if( result == -1 )
810
0
  {
811
0
    libcerror_error_set(
812
0
     error,
813
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
814
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
815
0
     "%s: unable to retrieve value.",
816
0
     function );
817
0
  }
818
0
  else if( result == 1 )
819
0
  {
820
0
    if( libpff_value_type_copy_to_binary_data(
821
0
         value_data,
822
0
         value_data_size,
823
0
         binary_data,
824
0
         size,
825
0
         error ) != 1 )
826
0
    {
827
0
      libcerror_error_set(
828
0
       error,
829
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
830
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
831
0
       "%s: unable to set binary data.",
832
0
       function );
833
834
0
      return( -1 );
835
0
    }
836
0
  }
837
0
  return( result );
838
0
}
839
840
/* Retrieves the GUID value of a specific value of the multi value
841
 * Returns 1 if successful or -1 on error
842
 */
843
int libpff_multi_value_get_value_guid(
844
     libpff_multi_value_t *multi_value,
845
     int value_index,
846
     uint8_t *guid,
847
     size_t size,
848
     libcerror_error_t **error )
849
0
{
850
0
  uint8_t *value_data    = NULL;
851
0
  static char *function  = "libpff_multi_value_get_value_guid";
852
0
  size_t value_data_size = 0;
853
0
  uint32_t value_type    = LIBPFF_VALUE_TYPE_GUID;
854
0
  int result             = 0;
855
856
0
  result = libpff_multi_value_get_value(
857
0
            multi_value,
858
0
            value_index,
859
0
            &value_type,
860
0
            &value_data,
861
0
            &value_data_size,
862
0
            error );
863
864
0
  if( result == -1 )
865
0
  {
866
0
    libcerror_error_set(
867
0
     error,
868
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
869
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
870
0
     "%s: unable to retrieve value.",
871
0
     function );
872
0
  }
873
0
  else if( result == 1 )
874
0
  {
875
0
    if( libpff_value_type_copy_to_binary_data(
876
0
         value_data,
877
0
         value_data_size,
878
0
         guid,
879
0
         size,
880
0
         error ) != 1 )
881
0
    {
882
0
      libcerror_error_set(
883
0
       error,
884
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
885
0
       LIBCERROR_CONVERSION_ERROR_GENERIC,
886
0
       "%s: unable to set GUID.",
887
0
       function );
888
889
0
      return( -1 );
890
0
    }
891
0
  }
892
0
  return( result );
893
0
}
894