Coverage Report

Created: 2025-09-05 06:58

/src/libfwps/libfwps/libfwps_record.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Windows Serialized Property Record 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 <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libfwps_debug.h"
31
#include "libfwps_definitions.h"
32
#include "libfwps_libcerror.h"
33
#include "libfwps_libcnotify.h"
34
#include "libfwps_libuna.h"
35
#include "libfwps_record.h"
36
#include "libfwps_types.h"
37
38
/* Creates a record
39
 * Make sure the record value is referencing, is set to NULL
40
 * Returns 1 if successful or -1 on error
41
 */
42
int libfwps_record_initialize(
43
     libfwps_record_t **record,
44
     uint8_t record_type,
45
     libcerror_error_t **error )
46
1.08M
{
47
1.08M
  libfwps_internal_record_t *internal_record = NULL;
48
1.08M
  static char *function                      = "libfwps_record_initialize";
49
50
1.08M
  if( record == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid record.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
1.08M
  if( *record != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid record value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
1.08M
  if( ( record_type != LIBFWPS_RECORD_TYPE_NAMED )
73
1.08M
   && ( record_type != LIBFWPS_RECORD_TYPE_NUMERIC ) )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
78
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
79
0
     "%s: unsupported record type.",
80
0
     function );
81
82
0
    return( -1 );
83
0
  }
84
1.08M
  internal_record = memory_allocate_structure(
85
1.08M
                     libfwps_internal_record_t );
86
87
1.08M
  if( internal_record == NULL )
88
0
  {
89
0
    libcerror_error_set(
90
0
     error,
91
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
92
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
93
0
     "%s: unable to create record.",
94
0
     function );
95
96
0
    goto on_error;
97
0
  }
98
1.08M
  if( memory_set(
99
1.08M
       internal_record,
100
1.08M
       0,
101
1.08M
       sizeof( libfwps_internal_record_t ) ) == NULL )
102
0
  {
103
0
    libcerror_error_set(
104
0
     error,
105
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
106
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
107
0
     "%s: unable to clear record.",
108
0
     function );
109
110
0
    goto on_error;
111
0
  }
112
1.08M
  internal_record->type = record_type;
113
114
1.08M
  *record = (libfwps_record_t *) internal_record;
115
116
1.08M
  return( 1 );
117
118
0
on_error:
119
0
  if( internal_record != NULL )
120
0
  {
121
0
    memory_free(
122
0
     internal_record );
123
0
  }
124
0
  return( -1 );
125
1.08M
}
126
127
/* Frees a record
128
 * Returns 1 if successful or -1 on error
129
 */
130
int libfwps_record_free(
131
     libfwps_record_t **record,
132
     libcerror_error_t **error )
133
578
{
134
578
  static char *function = "libfwps_record_free";
135
136
578
  if( record == NULL )
137
0
  {
138
0
    libcerror_error_set(
139
0
     error,
140
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
141
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
142
0
     "%s: invalid record.",
143
0
     function );
144
145
0
    return( -1 );
146
0
  }
147
578
  if( *record != NULL )
148
578
  {
149
578
    *record = NULL;
150
578
  }
151
578
  return( 1 );
152
578
}
153
154
/* Frees a record
155
 * Returns 1 if successful or -1 on error
156
 */
157
int libfwps_internal_record_free(
158
     libfwps_internal_record_t **internal_record,
159
     libcerror_error_t **error )
160
1.08M
{
161
1.08M
  static char *function = "libfwps_internal_record_free";
162
163
1.08M
  if( internal_record == NULL )
164
0
  {
165
0
    libcerror_error_set(
166
0
     error,
167
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
168
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
169
0
     "%s: invalid internal record.",
170
0
     function );
171
172
0
    return( -1 );
173
0
  }
174
1.08M
  if( *internal_record != NULL )
175
1.08M
  {
176
1.08M
    if( ( *internal_record )->entry_name != NULL )
177
4.53k
    {
178
4.53k
      memory_free(
179
4.53k
       ( *internal_record )->entry_name );
180
4.53k
    }
181
1.08M
    if( ( *internal_record )->value_name != NULL )
182
712
    {
183
712
      memory_free(
184
712
       ( *internal_record )->value_name );
185
712
    }
186
1.08M
    if( ( *internal_record )->value_data != NULL )
187
677k
    {
188
677k
      memory_free(
189
677k
       ( *internal_record )->value_data );
190
677k
    }
191
1.08M
    memory_free(
192
1.08M
     *internal_record );
193
194
1.08M
    *internal_record = NULL;
195
1.08M
  }
196
1.08M
  return( 1 );
197
1.08M
}
198
199
/* Copies a record from a byte stream
200
 * Returns 1 if successful or -1 on error
201
 */
202
int libfwps_record_copy_from_byte_stream(
203
     libfwps_record_t *record,
204
     const uint8_t *byte_stream,
205
     size_t byte_stream_size,
206
     int ascii_codepage,
207
     libcerror_error_t **error )
208
1.08M
{
209
1.08M
  libfwps_internal_record_t *internal_record = NULL;
210
1.08M
  static char *function                      = "libfwps_record_copy_from_byte_stream";
211
1.08M
  size_t byte_stream_offset                  = 0;
212
1.08M
  uint32_t name_size                         = 0;
213
1.08M
  uint32_t number_of_values                  = 0;
214
1.08M
  uint32_t value_index                       = 0;
215
1.08M
  uint32_t vector_value_data_size            = 0;
216
1.08M
  uint16_t value_16bit                       = 0;
217
1.08M
  int has_variable_data_size                 = 0;
218
219
#if defined( HAVE_DEBUG_OUTPUT )
220
  system_character_t *value_string           = NULL;
221
#endif
222
223
1.08M
  if( record == NULL )
224
0
  {
225
0
    libcerror_error_set(
226
0
     error,
227
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
228
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
229
0
     "%s: invalid record.",
230
0
     function );
231
232
0
    return( -1 );
233
0
  }
234
1.08M
  internal_record = (libfwps_internal_record_t *) record;
235
236
1.08M
  if( internal_record->entry_name != NULL )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
241
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
242
0
     "%s: invalid record - entry name already set.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
1.08M
  if( internal_record->value_name != NULL )
248
0
  {
249
0
    libcerror_error_set(
250
0
     error,
251
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
252
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
253
0
     "%s: invalid record - value name already set.",
254
0
     function );
255
256
0
    return( -1 );
257
0
  }
258
1.08M
  if( internal_record->value_data != NULL )
259
0
  {
260
0
    libcerror_error_set(
261
0
     error,
262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
264
0
     "%s: invalid record - value data already set.",
265
0
     function );
266
267
0
    return( -1 );
268
0
  }
269
1.08M
  if( byte_stream == NULL )
270
0
  {
271
0
    libcerror_error_set(
272
0
     error,
273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
275
0
     "%s: invalid byte stream.",
276
0
     function );
277
278
0
    return( -1 );
279
0
  }
280
1.08M
  if( ( byte_stream_size < 13 )
281
1.08M
   || ( byte_stream_size > (size_t) SSIZE_MAX ) )
282
87
  {
283
87
    libcerror_error_set(
284
87
     error,
285
87
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
286
87
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
287
87
     "%s: invalid byte stream size value out of bounds.",
288
87
     function );
289
290
87
    return( -1 );
291
87
  }
292
1.08M
  byte_stream_copy_to_uint32_little_endian(
293
1.08M
   byte_stream,
294
1.08M
   internal_record->size );
295
296
1.08M
  if( ( internal_record->size < 13 )
297
1.08M
   || ( (size_t) internal_record->size > byte_stream_size ) )
298
0
  {
299
0
    libcerror_error_set(
300
0
     error,
301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
302
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
303
0
     "%s: invalid record - size value out of bounds.",
304
0
     function );
305
306
0
    goto on_error;
307
0
  }
308
#if defined( HAVE_DEBUG_OUTPUT )
309
  if( libcnotify_verbose != 0 )
310
  {
311
    libcnotify_printf(
312
     "%s: record data:\n",
313
     function );
314
    libcnotify_print_data(
315
     byte_stream,
316
     internal_record->size,
317
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
318
  }
319
#endif
320
1.08M
  if( internal_record->type == LIBFWPS_RECORD_TYPE_NAMED )
321
4.87k
  {
322
4.87k
    byte_stream_copy_to_uint32_little_endian(
323
4.87k
     &( byte_stream[ byte_stream_offset + 4 ] ),
324
4.87k
     name_size );
325
4.87k
  }
326
1.08M
  else if( internal_record->type == LIBFWPS_RECORD_TYPE_NUMERIC )
327
1.08M
  {
328
1.08M
    byte_stream_copy_to_uint32_little_endian(
329
1.08M
     &( byte_stream[ byte_stream_offset + 4 ] ),
330
1.08M
     internal_record->entry_type );
331
1.08M
  }
332
#if defined( HAVE_DEBUG_OUTPUT )
333
  if( libcnotify_verbose != 0 )
334
  {
335
    libcnotify_printf(
336
     "%s: size\t\t\t\t: %" PRIu32 "\n",
337
     function,
338
     internal_record->size );
339
340
    if( internal_record->type == LIBFWPS_RECORD_TYPE_NAMED )
341
    {
342
      libcnotify_printf(
343
       "%s: name size\t\t\t\t: %" PRIu32 "\n",
344
       function,
345
       name_size );
346
    }
347
    else
348
    {
349
      libcnotify_printf(
350
       "%s: entry type\t\t\t: %" PRIu32 "\n",
351
       function,
352
       internal_record->entry_type );
353
    }
354
    libcnotify_printf(
355
     "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
356
     function,
357
     byte_stream[ byte_stream_offset + 8 ] );
358
  }
359
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
360
361
1.08M
  byte_stream_offset += 9;
362
363
1.08M
  if( internal_record->type == LIBFWPS_RECORD_TYPE_NAMED )
364
4.87k
  {
365
4.87k
    if( ( name_size > byte_stream_size )
366
4.87k
     || ( byte_stream_offset > ( byte_stream_size - name_size ) ) )
367
145
    {
368
145
      libcerror_error_set(
369
145
       error,
370
145
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
371
145
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
372
145
       "%s: invalid name size value out of bounds.",
373
145
       function );
374
375
145
      goto on_error;
376
145
    }
377
4.73k
    internal_record->entry_name = (uint8_t *) memory_allocate(
378
4.73k
                                               sizeof( uint8_t ) * name_size );
379
380
4.73k
    if( internal_record->entry_name == NULL )
381
0
    {
382
0
      libcerror_error_set(
383
0
       error,
384
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
385
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
386
0
       "%s: unable to create entry name.",
387
0
       function );
388
389
0
      goto on_error;
390
0
    }
391
4.73k
    if( memory_copy(
392
4.73k
         internal_record->entry_name,
393
4.73k
         &( byte_stream[ byte_stream_offset ] ),
394
4.73k
         name_size ) == NULL )
395
0
    {
396
0
      libcerror_error_set(
397
0
       error,
398
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
399
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
400
0
       "%s: unable to copy entry name data.",
401
0
       function );
402
403
0
      goto on_error;
404
0
    }
405
4.73k
    internal_record->entry_name_size = name_size;
406
407
#if defined( HAVE_DEBUG_OUTPUT )
408
    if( libcnotify_verbose != 0 )
409
    {
410
      if( libfwps_debug_print_utf16_string_value(
411
           function,
412
           "entry name\t\t\t",
413
           internal_record->entry_name,
414
           internal_record->entry_name_size,
415
           LIBUNA_ENDIAN_LITTLE,
416
           error ) != 1 )
417
      {
418
        libcerror_error_set(
419
         error,
420
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
421
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
422
         "%s: unable to print UTF-16 string value.",
423
         function );
424
425
        goto on_error;
426
      }
427
    }
428
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
429
430
4.73k
    byte_stream_offset += name_size;
431
4.73k
  }
432
1.08M
  if( byte_stream_offset > ( byte_stream_size - 4 ) )
433
24
  {
434
24
    libcerror_error_set(
435
24
     error,
436
24
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
437
24
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
438
24
     "%s: invalid byte stream size value too small.",
439
24
     function );
440
441
24
    goto on_error;
442
24
  }
443
1.08M
  byte_stream_copy_to_uint32_little_endian(
444
1.08M
   &( byte_stream[ byte_stream_offset ] ),
445
1.08M
   internal_record->value_type );
446
447
1.08M
  byte_stream_offset += 4;
448
449
#if defined( HAVE_DEBUG_OUTPUT )
450
  if( libcnotify_verbose != 0 )
451
  {
452
    libcnotify_printf(
453
     "%s: value type\t\t\t: 0x%04" PRIx32 "\n",
454
     function,
455
     internal_record->value_type );
456
  }
457
#endif
458
  /* TODO add support for VT_ARRAY and VT_BYREF
459
   */
460
1.08M
  switch( internal_record->value_type & 0xffffefffUL )
461
1.08M
  {
462
395k
    case LIBFWPS_VALUE_TYPE_NULL:
463
395k
      internal_record->value_data_size = 0;
464
395k
      break;
465
466
667k
    case LIBFWPS_VALUE_TYPE_BOOLEAN:
467
668k
    case LIBFWPS_VALUE_TYPE_INTEGER_8BIT_SIGNED:
468
669k
    case LIBFWPS_VALUE_TYPE_INTEGER_8BIT_UNSIGNED:
469
669k
      internal_record->value_data_size = 1;
470
669k
      break;
471
472
2.25k
    case LIBFWPS_VALUE_TYPE_INTEGER_16BIT_SIGNED:
473
3.12k
    case LIBFWPS_VALUE_TYPE_INTEGER_16BIT_UNSIGNED:
474
3.12k
      internal_record->value_data_size = 2;
475
3.12k
      break;
476
477
595
    case LIBFWPS_VALUE_TYPE_ERROR:
478
1.86k
    case LIBFWPS_VALUE_TYPE_FLOAT_32BIT:
479
3.17k
    case LIBFWPS_VALUE_TYPE_INTEGER_32BIT_SIGNED:
480
3.78k
    case LIBFWPS_VALUE_TYPE_INTEGER_32BIT_UNSIGNED:
481
4.38k
    case LIBFWPS_VALUE_TYPE_INTEGER_SIGNED:
482
4.98k
    case LIBFWPS_VALUE_TYPE_INTEGER_UNSIGNED:
483
4.98k
      internal_record->value_data_size = 4;
484
4.98k
      break;
485
486
717
    case LIBFWPS_VALUE_TYPE_APPLICATION_TIME:
487
1.95k
    case LIBFWPS_VALUE_TYPE_CURRENCY:
488
2.57k
    case LIBFWPS_VALUE_TYPE_DOUBLE_64BIT:
489
3.21k
    case LIBFWPS_VALUE_TYPE_FILETIME:
490
3.81k
    case LIBFWPS_VALUE_TYPE_INTEGER_64BIT_SIGNED:
491
4.55k
    case LIBFWPS_VALUE_TYPE_INTEGER_64BIT_UNSIGNED:
492
4.55k
      internal_record->value_data_size = 8;
493
4.55k
      break;
494
495
633
    case LIBFWPS_VALUE_TYPE_FIXED_POINT_128BIT:
496
1.30k
    case LIBFWPS_VALUE_TYPE_GUID:
497
1.30k
      internal_record->value_data_size = 16;
498
1.30k
      break;
499
500
865
    case LIBFWPS_VALUE_TYPE_BINARY_DATA:
501
4.57k
    case LIBFWPS_VALUE_TYPE_BINARY_STRING:
502
6.45k
    case LIBFWPS_VALUE_TYPE_STREAM:
503
8.06k
    case LIBFWPS_VALUE_TYPE_STRING_ASCII:
504
9.70k
    case LIBFWPS_VALUE_TYPE_STRING_UNICODE:
505
9.70k
      has_variable_data_size = 1;
506
9.70k
      break;
507
508
102
    default:
509
102
      libcerror_error_set(
510
102
       error,
511
102
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
512
102
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
513
102
       "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
514
102
       function,
515
102
       internal_record->value_type );
516
517
102
      goto on_error;
518
1.08M
  }
519
1.08M
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STREAM )
520
1.08k
  {
521
1.08k
    if( byte_stream_offset > ( byte_stream_size - 4 ) )
522
20
    {
523
20
      libcerror_error_set(
524
20
       error,
525
20
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
526
20
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
527
20
       "%s: invalid byte stream size value too small.",
528
20
       function );
529
530
20
      goto on_error;
531
20
    }
532
1.06k
    byte_stream_copy_to_uint32_little_endian(
533
1.06k
     &( byte_stream[ byte_stream_offset ] ),
534
1.06k
     name_size );
535
536
1.06k
    byte_stream_offset += 4;
537
538
1.06k
    if( ( name_size > byte_stream_size )
539
1.06k
     || ( byte_stream_offset > ( byte_stream_size - name_size ) ) )
540
209
    {
541
209
      libcerror_error_set(
542
209
       error,
543
209
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
544
209
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
545
209
       "%s: invalid name size value out of bounds.",
546
209
       function );
547
548
209
      goto on_error;
549
209
    }
550
851
    internal_record->value_name = (uint8_t *) memory_allocate(
551
851
                                               sizeof( uint8_t ) * name_size );
552
553
851
    if( internal_record->value_name == NULL )
554
0
    {
555
0
      libcerror_error_set(
556
0
       error,
557
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
558
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
559
0
       "%s: unable to create value name.",
560
0
       function );
561
562
0
      goto on_error;
563
0
    }
564
851
    if( memory_copy(
565
851
         internal_record->value_name,
566
851
         &( byte_stream[ byte_stream_offset ] ),
567
851
         name_size ) == NULL )
568
0
    {
569
0
      libcerror_error_set(
570
0
       error,
571
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
572
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
573
0
       "%s: unable to copy value name data.",
574
0
       function );
575
576
0
      goto on_error;
577
0
    }
578
851
    internal_record->value_name_size = name_size;
579
580
#if defined( HAVE_DEBUG_OUTPUT )
581
    if( libcnotify_verbose != 0 )
582
    {
583
      if( libfwps_debug_print_utf16_string_value(
584
           function,
585
           "value name\t\t\t",
586
           internal_record->value_name,
587
           internal_record->value_name_size,
588
           LIBUNA_ENDIAN_LITTLE,
589
           error ) != 1 )
590
      {
591
        libcerror_error_set(
592
         error,
593
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
594
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
595
         "%s: unable to print UTF-16 string value.",
596
         function );
597
598
        goto on_error;
599
      }
600
    }
601
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
602
603
851
    byte_stream_offset += name_size;
604
605
851
    if( byte_stream_offset > ( byte_stream_size - 2 ) )
606
23
    {
607
23
      libcerror_error_set(
608
23
       error,
609
23
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
610
23
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
611
23
       "%s: invalid byte stream size value too small.",
612
23
       function );
613
614
23
      goto on_error;
615
23
    }
616
#if defined( HAVE_DEBUG_OUTPUT )
617
    if( libcnotify_verbose != 0 )
618
    {
619
      byte_stream_copy_to_uint16_little_endian(
620
       &( byte_stream[ byte_stream_offset ] ),
621
       value_16bit );
622
      libcnotify_printf(
623
       "%s: unknown1\t\t\t\t: 0x%04" PRIx16 "\n",
624
       function,
625
       value_16bit );
626
    }
627
#endif
628
828
    byte_stream_offset += 2;
629
828
  }
630
1.08M
  if( ( internal_record->value_type & 0x0000f000UL ) == 0x00001000UL )
631
9.13k
  {
632
9.13k
    if( byte_stream_offset > ( byte_stream_size - 4 ) )
633
117
    {
634
117
      libcerror_error_set(
635
117
       error,
636
117
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
637
117
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
638
117
       "%s: invalid byte stream size value too small.",
639
117
       function );
640
641
117
      goto on_error;
642
117
    }
643
9.01k
    byte_stream_copy_to_uint32_little_endian(
644
9.01k
     &( byte_stream[ byte_stream_offset ] ),
645
9.01k
     number_of_values );
646
647
#if defined( HAVE_DEBUG_OUTPUT )
648
    if( libcnotify_verbose != 0 )
649
    {
650
      if( has_variable_data_size == 0 )
651
      {
652
        libcnotify_printf(
653
         "%s: value data size\t\t\t: %" PRIu32 "\n",
654
         function,
655
         internal_record->value_data_size );
656
      }
657
      libcnotify_printf(
658
       "%s: number of values\t\t\t: %" PRIu32 "\n",
659
       function,
660
       number_of_values );
661
    }
662
#endif
663
9.01k
    byte_stream_offset += 4;
664
665
9.01k
    if( has_variable_data_size == 0 )
666
6.33k
    {
667
6.33k
      if( ( internal_record->value_data_size > 0 )
668
6.33k
       && ( number_of_values > ( (size_t) SSIZE_MAX / internal_record->value_data_size ) ) )
669
0
      {
670
0
        libcerror_error_set(
671
0
         error,
672
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
673
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
674
0
         "%s: invalid number of values value out of bounds.",
675
0
         function );
676
677
0
        goto on_error;
678
0
      }
679
#if defined( HAVE_DEBUG_OUTPUT )
680
      if( libcnotify_verbose != 0 )
681
      {
682
        libcnotify_printf(
683
         "%s: vector values data:\n",
684
         function,
685
         value_index );
686
        libcnotify_print_data(
687
         &( byte_stream[ byte_stream_offset ] ),
688
         internal_record->value_data_size,
689
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
690
      }
691
#endif
692
6.33k
      internal_record->value_data_size *= number_of_values;
693
694
6.33k
      byte_stream_offset += internal_record->value_data_size;
695
6.33k
    }
696
2.68k
    else
697
2.68k
    {
698
2.68k
      if( ( number_of_values > ( ( byte_stream_size - byte_stream_offset ) / 4 ) )
699
2.68k
       || ( number_of_values == 0xffffffffUL ) )
700
113
      {
701
113
        libcerror_error_set(
702
113
         error,
703
113
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
704
113
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
705
113
         "%s: invalid number of values value out of bounds.",
706
113
         function );
707
708
113
        goto on_error;
709
113
      }
710
2.56k
      for( value_index = 0;
711
17.3k
           value_index < number_of_values;
712
14.7k
           value_index++ )
713
15.1k
      {
714
15.1k
        if( byte_stream_offset > ( byte_stream_size - 4 ) )
715
244
        {
716
244
          libcerror_error_set(
717
244
           error,
718
244
           LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
719
244
           LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
720
244
           "%s: invalid byte stream size value too small.",
721
244
           function );
722
723
244
          goto on_error;
724
244
        }
725
14.8k
        byte_stream_copy_to_uint32_little_endian(
726
14.8k
         &( byte_stream[ byte_stream_offset ] ),
727
14.8k
         vector_value_data_size );
728
729
#if defined( HAVE_DEBUG_OUTPUT )
730
        if( libcnotify_verbose != 0 )
731
        {
732
          libcnotify_printf(
733
           "%s: vector value: %" PRIu32 " data size\t\t: %" PRIu32 "\n",
734
           function,
735
           value_index,
736
           vector_value_data_size );
737
        }
738
#endif
739
14.8k
        byte_stream_offset += 4;
740
741
14.8k
        if( ( internal_record->value_type & 0x00000fffUL ) == LIBFWPS_VALUE_TYPE_STRING_UNICODE )
742
5.82k
        {
743
5.82k
          if( vector_value_data_size > ( (uint32_t) UINT32_MAX / 2 ) )
744
110
          {
745
110
            libcerror_error_set(
746
110
             error,
747
110
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
748
110
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
749
110
             "%s: invalid vector value: %" PRIu32 " data size value out of bounds.",
750
110
             function,
751
110
             value_index );
752
753
110
            goto on_error;
754
110
          }
755
5.71k
          vector_value_data_size *= 2;
756
5.71k
        }
757
14.7k
        if( vector_value_data_size > ( (size_t) SSIZE_MAX - internal_record->value_data_size ) )
758
0
        {
759
0
          libcerror_error_set(
760
0
           error,
761
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
762
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
763
0
           "%s: invalid vector value: %" PRIu32 " data size value out of bounds.",
764
0
           function,
765
0
           value_index );
766
767
0
          goto on_error;
768
0
        }
769
#if defined( HAVE_DEBUG_OUTPUT )
770
        if( libcnotify_verbose != 0 )
771
        {
772
          libcnotify_printf(
773
           "%s: vector value: %" PRIu32 " data:\n",
774
           function,
775
           value_index );
776
          libcnotify_print_data(
777
           &( byte_stream[ byte_stream_offset ] ),
778
           vector_value_data_size,
779
           LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
780
        }
781
#endif
782
14.7k
        byte_stream_offset += vector_value_data_size;
783
784
14.7k
        internal_record->value_data_size += 4 + vector_value_data_size;
785
786
14.7k
        if( byte_stream_offset <= ( byte_stream_size - 2 ) )
787
13.7k
        {
788
13.7k
          byte_stream_copy_to_uint16_little_endian(
789
13.7k
           &( byte_stream[ byte_stream_offset ] ),
790
13.7k
           value_16bit );
791
792
13.7k
          if( value_16bit == 0 )
793
12.9k
          {
794
#if defined( HAVE_DEBUG_OUTPUT )
795
            if( libcnotify_verbose != 0 )
796
            {
797
              libcnotify_printf(
798
               "%s: alignment padding data:\n",
799
               function );
800
              libcnotify_print_data(
801
               &( byte_stream[ byte_stream_offset ] ),
802
               2,
803
               0 );
804
            }
805
#endif
806
12.9k
            byte_stream_offset += 2;
807
808
12.9k
            internal_record->value_data_size += 2;
809
12.9k
          }
810
13.7k
        }
811
14.7k
      }
812
2.56k
    }
813
9.01k
  }
814
1.07M
  else
815
1.07M
  {
816
1.07M
    if( has_variable_data_size != 0 )
817
6.75k
    {
818
6.75k
      if( byte_stream_offset > ( byte_stream_size - 4 ) )
819
86
      {
820
86
        libcerror_error_set(
821
86
         error,
822
86
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
823
86
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
824
86
         "%s: invalid byte stream size value too small.",
825
86
         function );
826
827
86
        goto on_error;
828
86
      }
829
6.67k
      byte_stream_copy_to_uint32_little_endian(
830
6.67k
       &( byte_stream[ byte_stream_offset ] ),
831
6.67k
       internal_record->value_data_size );
832
833
6.67k
      byte_stream_offset += 4;
834
835
6.67k
      if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_UNICODE )
836
910
      {
837
910
        if( internal_record->value_data_size > ( (size_t) SSIZE_MAX / 2 ) )
838
0
        {
839
0
          libcerror_error_set(
840
0
           error,
841
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
842
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
843
0
           "%s: invalid value data size value out of bounds.",
844
0
           function );
845
846
0
          goto on_error;
847
0
        }
848
910
        internal_record->value_data_size *= 2;
849
910
      }
850
6.67k
    }
851
#if defined( HAVE_DEBUG_OUTPUT )
852
    if( libcnotify_verbose != 0 )
853
    {
854
      libcnotify_printf(
855
       "%s: value data size\t\t\t: %" PRIu32 "\n",
856
       function,
857
       internal_record->value_data_size );
858
    }
859
#endif
860
1.07M
    if( internal_record->value_data_size > 0 )
861
678k
    {
862
678k
      if( ( internal_record->value_data_size > byte_stream_size )
863
678k
       || ( byte_stream_offset > ( byte_stream_size - internal_record->value_data_size ) ) )
864
512
      {
865
512
        libcerror_error_set(
866
512
         error,
867
512
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
868
512
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
869
512
         "%s: invalid value data size value out of bounds.",
870
512
         function );
871
872
512
        goto on_error;
873
512
      }
874
#if defined( HAVE_DEBUG_OUTPUT )
875
      if( libcnotify_verbose != 0 )
876
      {
877
        libcnotify_printf(
878
         "%s: value data:\n",
879
         function );
880
        libcnotify_print_data(
881
         &( byte_stream[ byte_stream_offset ] ),
882
         internal_record->value_data_size,
883
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
884
      }
885
#endif
886
677k
      if( internal_record->value_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE )
887
0
      {
888
0
        libcerror_error_set(
889
0
         error,
890
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
891
0
         LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
892
0
         "%s: invalid value data size value exceeds maximum.",
893
0
         function );
894
895
0
        goto on_error;
896
0
      }
897
677k
      internal_record->value_data = (uint8_t *) memory_allocate(
898
677k
                                                 sizeof( uint8_t ) * internal_record->value_data_size );
899
900
677k
      if( internal_record->value_data == NULL )
901
0
      {
902
0
        libcerror_error_set(
903
0
         error,
904
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
905
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
906
0
         "%s: unable to create value data.",
907
0
         function );
908
909
0
        goto on_error;
910
0
      }
911
677k
      if( memory_copy(
912
677k
           internal_record->value_data,
913
677k
           &( byte_stream[ byte_stream_offset ] ),
914
677k
           internal_record->value_data_size ) == NULL )
915
0
      {
916
0
        libcerror_error_set(
917
0
         error,
918
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
919
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
920
0
         "%s: unable to copy value data.",
921
0
         function );
922
923
0
        goto on_error;
924
0
      }
925
677k
      byte_stream_offset += internal_record->value_data_size;
926
677k
    }
927
1.07M
  }
928
#if defined( HAVE_DEBUG_OUTPUT )
929
  if( libcnotify_verbose != 0 )
930
  {
931
    if( byte_stream_offset < internal_record->size )
932
    {
933
      libcnotify_printf(
934
       "%s: trailing data:\n",
935
       function );
936
      libcnotify_print_data(
937
       &( byte_stream[ byte_stream_offset ] ),
938
       internal_record->size - byte_stream_offset,
939
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
940
    }
941
  }
942
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
943
944
1.08M
  internal_record->ascii_codepage = ascii_codepage;
945
946
1.08M
  return( 1 );
947
948
1.70k
on_error:
949
#if defined( HAVE_DEBUG_OUTPUT )
950
  if( value_string != NULL )
951
  {
952
    memory_free(
953
     value_string );
954
  }
955
#endif
956
1.70k
  if( internal_record->value_data != NULL )
957
0
  {
958
0
    memory_free(
959
0
     internal_record->value_data );
960
961
0
    internal_record->value_data = NULL;
962
0
  }
963
1.70k
  internal_record->value_data_size = 0;
964
965
1.70k
  if( internal_record->value_name != NULL )
966
139
  {
967
139
    memory_free(
968
139
     internal_record->value_name );
969
970
139
    internal_record->value_name = NULL;
971
139
  }
972
1.70k
  internal_record->value_name_size = 0;
973
974
1.70k
  if( internal_record->entry_name != NULL )
975
201
  {
976
201
    memory_free(
977
201
     internal_record->entry_name );
978
979
201
    internal_record->entry_name = NULL;
980
201
  }
981
1.70k
  internal_record->entry_name_size = 0;
982
983
1.70k
  return( -1 );
984
1.08M
}
985
986
/* Retrieves the size of the UTF-8 encoded entry name
987
 * The returned size includes the end of string character
988
 * Returns 1 if successful or -1 on error
989
 */
990
int libfwps_record_get_utf8_entry_name_size(
991
     libfwps_record_t *record,
992
     size_t *utf8_string_size,
993
     libcerror_error_t **error )
994
0
{
995
0
  libfwps_internal_record_t *internal_record = NULL;
996
0
  static char *function                      = "libfwps_record_get_utf8_entry_name_size";
997
998
0
  if( record == NULL )
999
0
  {
1000
0
    libcerror_error_set(
1001
0
     error,
1002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1003
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1004
0
     "%s: invalid record.",
1005
0
     function );
1006
1007
0
    return( -1 );
1008
0
  }
1009
0
  internal_record = (libfwps_internal_record_t *) record;
1010
1011
0
  if( internal_record->type != LIBFWPS_RECORD_TYPE_NAMED )
1012
0
  {
1013
0
    return( 0 );
1014
0
  }
1015
0
  if( libuna_utf8_string_size_from_utf16_stream(
1016
0
       internal_record->entry_name,
1017
0
       internal_record->entry_name_size,
1018
0
       LIBUNA_ENDIAN_LITTLE,
1019
0
       utf8_string_size,
1020
0
       error ) != 1 )
1021
0
  {
1022
0
    libcerror_error_set(
1023
0
     error,
1024
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1025
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1026
0
     "%s: unable to retrieve size of entry name as UTF-8 string.",
1027
0
     function );
1028
1029
0
    return( -1 );
1030
0
  }
1031
0
  return( 1 );
1032
0
}
1033
1034
/* Retrieves the UTF-8 encoded entry name
1035
 * The size should include the end of string character
1036
 * Returns 1 if successful or -1 on error
1037
 */
1038
int libfwps_record_get_utf8_entry_name(
1039
     libfwps_record_t *record,
1040
     uint8_t *utf8_string,
1041
     size_t utf8_string_size,
1042
     libcerror_error_t **error )
1043
0
{
1044
0
  libfwps_internal_record_t *internal_record = NULL;
1045
0
  static char *function                      = "libfwps_record_get_utf8_entry_name";
1046
1047
0
  if( record == NULL )
1048
0
  {
1049
0
    libcerror_error_set(
1050
0
     error,
1051
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1052
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1053
0
     "%s: invalid record.",
1054
0
     function );
1055
1056
0
    return( -1 );
1057
0
  }
1058
0
  internal_record = (libfwps_internal_record_t *) record;
1059
1060
0
  if( internal_record->type != LIBFWPS_RECORD_TYPE_NAMED )
1061
0
  {
1062
0
    return( 0 );
1063
0
  }
1064
0
  if( libuna_utf8_string_copy_from_utf16_stream(
1065
0
       utf8_string,
1066
0
       utf8_string_size,
1067
0
       internal_record->entry_name,
1068
0
       internal_record->entry_name_size,
1069
0
       LIBUNA_ENDIAN_LITTLE,
1070
0
       error ) != 1 )
1071
0
  {
1072
0
    libcerror_error_set(
1073
0
     error,
1074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1075
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1076
0
     "%s: unable to retrieve entry name as UTF-8 string.",
1077
0
     function );
1078
1079
0
    return( -1 );
1080
0
  }
1081
0
  return( 1 );
1082
0
}
1083
1084
/* Retrieves the size of the UTF-16 encoded entry name
1085
 * The returned size includes the end of string character
1086
 * Returns 1 if successful or -1 on error
1087
 */
1088
int libfwps_record_get_utf16_entry_name_size(
1089
     libfwps_record_t *record,
1090
     size_t *utf16_string_size,
1091
     libcerror_error_t **error )
1092
0
{
1093
0
  libfwps_internal_record_t *internal_record = NULL;
1094
0
  static char *function                      = "libfwps_record_get_utf16_entry_name_size";
1095
1096
0
  if( record == NULL )
1097
0
  {
1098
0
    libcerror_error_set(
1099
0
     error,
1100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1102
0
     "%s: invalid record.",
1103
0
     function );
1104
1105
0
    return( -1 );
1106
0
  }
1107
0
  internal_record = (libfwps_internal_record_t *) record;
1108
1109
0
  if( internal_record->type != LIBFWPS_RECORD_TYPE_NAMED )
1110
0
  {
1111
0
    return( 0 );
1112
0
  }
1113
0
  if( libuna_utf16_string_size_from_utf16_stream(
1114
0
       internal_record->entry_name,
1115
0
       internal_record->entry_name_size,
1116
0
       LIBUNA_ENDIAN_LITTLE,
1117
0
       utf16_string_size,
1118
0
       error ) != 1 )
1119
0
  {
1120
0
    libcerror_error_set(
1121
0
     error,
1122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1123
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1124
0
     "%s: unable to retrieve size of entry name as UTF-16 string.",
1125
0
     function );
1126
1127
0
    return( -1 );
1128
0
  }
1129
0
  return( 1 );
1130
0
}
1131
1132
/* Retrieves the UTF-16 encoded entry name
1133
 * The size should include the end of string character
1134
 * Returns 1 if successful or -1 on error
1135
 */
1136
int libfwps_record_get_utf16_entry_name(
1137
     libfwps_record_t *record,
1138
     uint16_t *utf16_string,
1139
     size_t utf16_string_size,
1140
     libcerror_error_t **error )
1141
0
{
1142
0
  libfwps_internal_record_t *internal_record = NULL;
1143
0
  static char *function                      = "libfwps_record_get_utf16_entry_name";
1144
1145
0
  if( record == NULL )
1146
0
  {
1147
0
    libcerror_error_set(
1148
0
     error,
1149
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1150
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1151
0
     "%s: invalid record.",
1152
0
     function );
1153
1154
0
    return( -1 );
1155
0
  }
1156
0
  internal_record = (libfwps_internal_record_t *) record;
1157
1158
0
  if( internal_record->type != LIBFWPS_RECORD_TYPE_NAMED )
1159
0
  {
1160
0
    return( 0 );
1161
0
  }
1162
0
  if( libuna_utf16_string_copy_from_utf16_stream(
1163
0
       utf16_string,
1164
0
       utf16_string_size,
1165
0
       internal_record->entry_name,
1166
0
       internal_record->entry_name_size,
1167
0
       LIBUNA_ENDIAN_LITTLE,
1168
0
       error ) != 1 )
1169
0
  {
1170
0
    libcerror_error_set(
1171
0
     error,
1172
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1173
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1174
0
     "%s: unable to retrieve entry name as UTF-16 string.",
1175
0
     function );
1176
1177
0
    return( -1 );
1178
0
  }
1179
0
  return( 1 );
1180
0
}
1181
1182
/* Retrieves the entry type
1183
 * Returns 1 if successful, 0 if not available or -1 on error
1184
 */
1185
int libfwps_record_get_entry_type(
1186
     libfwps_record_t *record,
1187
     uint32_t *entry_type,
1188
     libcerror_error_t **error )
1189
0
{
1190
0
  libfwps_internal_record_t *internal_record = NULL;
1191
0
  static char *function                      = "libfwps_record_get_entry_type";
1192
1193
0
  if( record == NULL )
1194
0
  {
1195
0
    libcerror_error_set(
1196
0
     error,
1197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1199
0
     "%s: invalid record.",
1200
0
     function );
1201
1202
0
    return( -1 );
1203
0
  }
1204
0
  internal_record = (libfwps_internal_record_t *) record;
1205
1206
0
  if( entry_type == NULL )
1207
0
  {
1208
0
    libcerror_error_set(
1209
0
     error,
1210
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1211
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1212
0
     "%s: invalid entry type.",
1213
0
     function );
1214
1215
0
    return( -1 );
1216
0
  }
1217
0
  if( internal_record->type != LIBFWPS_RECORD_TYPE_NUMERIC )
1218
0
  {
1219
0
    return( 0 );
1220
0
  }
1221
0
  *entry_type = internal_record->entry_type;
1222
1223
0
  return( 1 );
1224
0
}
1225
1226
/* Retrieves the size of the UTF-8 encoded value name
1227
 * The returned size includes the end of string character
1228
 * Returns 1 if successful or -1 on error
1229
 */
1230
int libfwps_record_get_utf8_value_name_size(
1231
     libfwps_record_t *record,
1232
     size_t *utf8_string_size,
1233
     libcerror_error_t **error )
1234
0
{
1235
0
  libfwps_internal_record_t *internal_record = NULL;
1236
0
  static char *function                      = "libfwps_record_get_utf8_value_name_size";
1237
1238
0
  if( record == NULL )
1239
0
  {
1240
0
    libcerror_error_set(
1241
0
     error,
1242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1243
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1244
0
     "%s: invalid record.",
1245
0
     function );
1246
1247
0
    return( -1 );
1248
0
  }
1249
0
  internal_record = (libfwps_internal_record_t *) record;
1250
1251
0
  if( ( internal_record->value_name_size == 0 )
1252
0
   || ( internal_record->value_name == NULL ) )
1253
0
  {
1254
0
    return( 0 );
1255
0
  }
1256
0
  if( libuna_utf8_string_size_from_utf16_stream(
1257
0
       internal_record->value_name,
1258
0
       internal_record->value_name_size,
1259
0
       LIBUNA_ENDIAN_LITTLE,
1260
0
       utf8_string_size,
1261
0
       error ) != 1 )
1262
0
  {
1263
0
    libcerror_error_set(
1264
0
     error,
1265
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1266
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1267
0
     "%s: unable to retrieve size of value name as UTF-8 string.",
1268
0
     function );
1269
1270
0
    return( -1 );
1271
0
  }
1272
0
  return( 1 );
1273
0
}
1274
1275
/* Retrieves the UTF-8 encoded value name
1276
 * The size should include the end of string character
1277
 * Returns 1 if successful or -1 on error
1278
 */
1279
int libfwps_record_get_utf8_value_name(
1280
     libfwps_record_t *record,
1281
     uint8_t *utf8_string,
1282
     size_t utf8_string_size,
1283
     libcerror_error_t **error )
1284
0
{
1285
0
  libfwps_internal_record_t *internal_record = NULL;
1286
0
  static char *function                      = "libfwps_record_get_utf8_value_name";
1287
1288
0
  if( record == NULL )
1289
0
  {
1290
0
    libcerror_error_set(
1291
0
     error,
1292
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1293
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1294
0
     "%s: invalid record.",
1295
0
     function );
1296
1297
0
    return( -1 );
1298
0
  }
1299
0
  internal_record = (libfwps_internal_record_t *) record;
1300
1301
0
  if( ( internal_record->value_name_size == 0 )
1302
0
   || ( internal_record->value_name == NULL ) )
1303
0
  {
1304
0
    return( 0 );
1305
0
  }
1306
0
  if( libuna_utf8_string_copy_from_utf16_stream(
1307
0
       utf8_string,
1308
0
       utf8_string_size,
1309
0
       internal_record->value_name,
1310
0
       internal_record->value_name_size,
1311
0
       LIBUNA_ENDIAN_LITTLE,
1312
0
       error ) != 1 )
1313
0
  {
1314
0
    libcerror_error_set(
1315
0
     error,
1316
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1317
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1318
0
     "%s: unable to retrieve value name as UTF-8 string.",
1319
0
     function );
1320
1321
0
    return( -1 );
1322
0
  }
1323
0
  return( 1 );
1324
0
}
1325
1326
/* Retrieves the size of the UTF-16 encoded value name
1327
 * The returned size includes the end of string character
1328
 * Returns 1 if successful or -1 on error
1329
 */
1330
int libfwps_record_get_utf16_value_name_size(
1331
     libfwps_record_t *record,
1332
     size_t *utf16_string_size,
1333
     libcerror_error_t **error )
1334
0
{
1335
0
  libfwps_internal_record_t *internal_record = NULL;
1336
0
  static char *function                      = "libfwps_record_get_utf16_value_name_size";
1337
1338
0
  if( record == NULL )
1339
0
  {
1340
0
    libcerror_error_set(
1341
0
     error,
1342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1343
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1344
0
     "%s: invalid record.",
1345
0
     function );
1346
1347
0
    return( -1 );
1348
0
  }
1349
0
  internal_record = (libfwps_internal_record_t *) record;
1350
1351
0
  if( ( internal_record->value_name_size == 0 )
1352
0
   || ( internal_record->value_name == NULL ) )
1353
0
  {
1354
0
    return( 0 );
1355
0
  }
1356
0
  if( libuna_utf16_string_size_from_utf16_stream(
1357
0
       internal_record->value_name,
1358
0
       internal_record->value_name_size,
1359
0
       LIBUNA_ENDIAN_LITTLE,
1360
0
       utf16_string_size,
1361
0
       error ) != 1 )
1362
0
  {
1363
0
    libcerror_error_set(
1364
0
     error,
1365
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1366
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1367
0
     "%s: unable to retrieve size of value name as UTF-16 string.",
1368
0
     function );
1369
1370
0
    return( -1 );
1371
0
  }
1372
0
  return( 1 );
1373
0
}
1374
1375
/* Retrieves the UTF-16 encoded value name
1376
 * The size should include the end of string character
1377
 * Returns 1 if successful or -1 on error
1378
 */
1379
int libfwps_record_get_utf16_value_name(
1380
     libfwps_record_t *record,
1381
     uint16_t *utf16_string,
1382
     size_t utf16_string_size,
1383
     libcerror_error_t **error )
1384
0
{
1385
0
  libfwps_internal_record_t *internal_record = NULL;
1386
0
  static char *function                      = "libfwps_record_get_utf16_value_name";
1387
1388
0
  if( record == NULL )
1389
0
  {
1390
0
    libcerror_error_set(
1391
0
     error,
1392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1394
0
     "%s: invalid record.",
1395
0
     function );
1396
1397
0
    return( -1 );
1398
0
  }
1399
0
  internal_record = (libfwps_internal_record_t *) record;
1400
1401
0
  if( ( internal_record->value_name_size == 0 )
1402
0
   || ( internal_record->value_name == NULL ) )
1403
0
  {
1404
0
    return( 0 );
1405
0
  }
1406
0
  if( libuna_utf16_string_copy_from_utf16_stream(
1407
0
       utf16_string,
1408
0
       utf16_string_size,
1409
0
       internal_record->value_name,
1410
0
       internal_record->value_name_size,
1411
0
       LIBUNA_ENDIAN_LITTLE,
1412
0
       error ) != 1 )
1413
0
  {
1414
0
    libcerror_error_set(
1415
0
     error,
1416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1417
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1418
0
     "%s: unable to retrieve value name as UTF-16 string.",
1419
0
     function );
1420
1421
0
    return( -1 );
1422
0
  }
1423
0
  return( 1 );
1424
0
}
1425
1426
/* Retrieves the value type
1427
 * Returns 1 if successful or -1 on error
1428
 */
1429
int libfwps_record_get_value_type(
1430
     libfwps_record_t *record,
1431
     uint32_t *value_type,
1432
     libcerror_error_t **error )
1433
0
{
1434
0
  libfwps_internal_record_t *internal_record = NULL;
1435
0
  static char *function                      = "libfwps_record_get_value_type";
1436
1437
0
  if( record == NULL )
1438
0
  {
1439
0
    libcerror_error_set(
1440
0
     error,
1441
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1442
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1443
0
     "%s: invalid record.",
1444
0
     function );
1445
1446
0
    return( -1 );
1447
0
  }
1448
0
  internal_record = (libfwps_internal_record_t *) record;
1449
1450
0
  if( value_type == NULL )
1451
0
  {
1452
0
    libcerror_error_set(
1453
0
     error,
1454
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1455
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1456
0
     "%s: invalid value type.",
1457
0
     function );
1458
1459
0
    return( -1 );
1460
0
  }
1461
0
  *value_type = internal_record->value_type;
1462
1463
0
  return( 1 );
1464
0
}
1465
1466
/* Retrieves the data size
1467
 * Returns 1 if successful or -1 on error
1468
 */
1469
int libfwps_record_get_data_size(
1470
     libfwps_record_t *record,
1471
     size_t *data_size,
1472
     libcerror_error_t **error )
1473
0
{
1474
0
  libfwps_internal_record_t *internal_record = NULL;
1475
0
  static char *function                      = "libfwps_record_get_data_size";
1476
1477
0
  if( record == NULL )
1478
0
  {
1479
0
    libcerror_error_set(
1480
0
     error,
1481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1482
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1483
0
     "%s: invalid record.",
1484
0
     function );
1485
1486
0
    return( -1 );
1487
0
  }
1488
0
  internal_record = (libfwps_internal_record_t *) record;
1489
1490
0
  if( data_size == NULL )
1491
0
  {
1492
0
    libcerror_error_set(
1493
0
     error,
1494
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1495
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1496
0
     "%s: invalid data size.",
1497
0
     function );
1498
1499
0
    return( -1 );
1500
0
  }
1501
0
  *data_size = internal_record->value_data_size;
1502
1503
0
  return( 1 );
1504
0
}
1505
1506
/* Retrieves the data
1507
 * Returns 1 if successful or -1 on error
1508
 */
1509
int libfwps_record_get_data(
1510
     libfwps_record_t *record,
1511
     uint8_t *data,
1512
     size_t data_size,
1513
     libcerror_error_t **error )
1514
0
{
1515
0
  libfwps_internal_record_t *internal_record = NULL;
1516
0
  static char *function                      = "libfwps_record_get_data";
1517
1518
0
  if( record == NULL )
1519
0
  {
1520
0
    libcerror_error_set(
1521
0
     error,
1522
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1523
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1524
0
     "%s: invalid record.",
1525
0
     function );
1526
1527
0
    return( -1 );
1528
0
  }
1529
0
  internal_record = (libfwps_internal_record_t *) record;
1530
1531
0
  if( internal_record->value_data == NULL )
1532
0
  {
1533
0
    libcerror_error_set(
1534
0
     error,
1535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1536
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1537
0
     "%s: invalid record entry - missing value data.",
1538
0
     function );
1539
1540
0
    return( -1 );
1541
0
  }
1542
0
  if( data == NULL )
1543
0
  {
1544
0
    libcerror_error_set(
1545
0
     error,
1546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1548
0
     "%s: invalid data.",
1549
0
     function );
1550
1551
0
    return( -1 );
1552
0
  }
1553
0
  if( ( data_size < internal_record->value_data_size )
1554
0
   || ( data_size > (size_t) SSIZE_MAX ) )
1555
0
  {
1556
0
    libcerror_error_set(
1557
0
     error,
1558
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1559
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1560
0
     "%s: invalid data size value out of bounds.",
1561
0
     function );
1562
1563
0
    return( -1 );
1564
0
  }
1565
0
  if( memory_copy(
1566
0
       data,
1567
0
       internal_record->value_data,
1568
0
       internal_record->value_data_size ) == NULL )
1569
0
  {
1570
0
    libcerror_error_set(
1571
0
     error,
1572
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1573
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1574
0
     "%s: unable to copy data.",
1575
0
     function );
1576
1577
0
    return( -1 );
1578
0
  }
1579
0
  return( 1 );
1580
0
}
1581
1582
/* Retrieves the data as a boolean value
1583
 * Returns 1 if successful or -1 on error
1584
 */
1585
int libfwps_record_get_data_as_boolean(
1586
     libfwps_record_t *record,
1587
     uint8_t *value_boolean,
1588
     libcerror_error_t **error )
1589
0
{
1590
0
  libfwps_internal_record_t *internal_record = NULL;
1591
0
  static char *function                      = "libfwps_record_get_data_as_boolean";
1592
1593
0
  if( record == NULL )
1594
0
  {
1595
0
    libcerror_error_set(
1596
0
     error,
1597
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1598
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1599
0
     "%s: invalid record entry.",
1600
0
     function );
1601
1602
0
    return( -1 );
1603
0
  }
1604
0
  internal_record = (libfwps_internal_record_t *) record;
1605
1606
0
  if( internal_record->value_type != LIBFWPS_VALUE_TYPE_BOOLEAN )
1607
0
  {
1608
0
    libcerror_error_set(
1609
0
     error,
1610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1611
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1612
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1613
0
     function,
1614
0
     internal_record->value_type );
1615
1616
0
    return( -1 );
1617
0
  }
1618
0
  if( internal_record->value_data == NULL )
1619
0
  {
1620
0
    libcerror_error_set(
1621
0
     error,
1622
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1623
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1624
0
     "%s: invalid record entry - missing value data.",
1625
0
     function );
1626
1627
0
    return( -1 );
1628
0
  }
1629
0
  if( internal_record->value_data_size != 1 )
1630
0
  {
1631
0
    libcerror_error_set(
1632
0
     error,
1633
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1634
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1635
0
     "%s: unsupported value data size.",
1636
0
     function );
1637
1638
0
    return( -1 );
1639
0
  }
1640
0
  if( value_boolean == NULL )
1641
0
  {
1642
0
    libcerror_error_set(
1643
0
     error,
1644
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1645
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1646
0
     "%s: invalid value boolean.",
1647
0
     function );
1648
1649
0
    return( -1 );
1650
0
  }
1651
0
  *value_boolean = internal_record->value_data[ 0 ];
1652
1653
0
  return( 1 );
1654
0
}
1655
1656
/* Retrieves the data as a 8-bit integer value
1657
 * Returns 1 if successful or -1 on error
1658
 */
1659
int libfwps_record_get_data_as_8bit_integer(
1660
     libfwps_record_t *record,
1661
     uint8_t *value_8bit,
1662
     libcerror_error_t **error )
1663
0
{
1664
0
  libfwps_internal_record_t *internal_record = NULL;
1665
0
  static char *function                      = "libfwps_record_get_data_as_8bit_integer";
1666
1667
0
  if( record == NULL )
1668
0
  {
1669
0
    libcerror_error_set(
1670
0
     error,
1671
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1672
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1673
0
     "%s: invalid record entry.",
1674
0
     function );
1675
1676
0
    return( -1 );
1677
0
  }
1678
0
  internal_record = (libfwps_internal_record_t *) record;
1679
1680
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_8BIT_SIGNED )
1681
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_8BIT_UNSIGNED ) )
1682
0
  {
1683
0
    libcerror_error_set(
1684
0
     error,
1685
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1686
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1687
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1688
0
     function,
1689
0
     internal_record->value_type );
1690
1691
0
    return( -1 );
1692
0
  }
1693
0
  if( internal_record->value_data == NULL )
1694
0
  {
1695
0
    libcerror_error_set(
1696
0
     error,
1697
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1698
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1699
0
     "%s: invalid record entry - missing value data.",
1700
0
     function );
1701
1702
0
    return( -1 );
1703
0
  }
1704
0
  if( internal_record->value_data_size != 1 )
1705
0
  {
1706
0
    libcerror_error_set(
1707
0
     error,
1708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1709
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1710
0
     "%s: unsupported value data size.",
1711
0
     function );
1712
1713
0
    return( -1 );
1714
0
  }
1715
0
  if( value_8bit == NULL )
1716
0
  {
1717
0
    libcerror_error_set(
1718
0
     error,
1719
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1720
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1721
0
     "%s: invalid value 8-bit.",
1722
0
     function );
1723
1724
0
    return( -1 );
1725
0
  }
1726
0
  *value_8bit = internal_record->value_data[ 0 ];
1727
1728
0
  return( 1 );
1729
0
}
1730
1731
/* Retrieves the data as a 16-bit integer value
1732
 * Returns 1 if successful or -1 on error
1733
 */
1734
int libfwps_record_get_data_as_16bit_integer(
1735
     libfwps_record_t *record,
1736
     uint16_t *value_16bit,
1737
     libcerror_error_t **error )
1738
0
{
1739
0
  libfwps_internal_record_t *internal_record = NULL;
1740
0
  static char *function                      = "libfwps_record_get_data_as_16bit_integer";
1741
1742
0
  if( record == NULL )
1743
0
  {
1744
0
    libcerror_error_set(
1745
0
     error,
1746
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1747
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1748
0
     "%s: invalid record entry.",
1749
0
     function );
1750
1751
0
    return( -1 );
1752
0
  }
1753
0
  internal_record = (libfwps_internal_record_t *) record;
1754
1755
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_16BIT_SIGNED )
1756
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_16BIT_UNSIGNED ) )
1757
0
  {
1758
0
    libcerror_error_set(
1759
0
     error,
1760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1761
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1762
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1763
0
     function,
1764
0
     internal_record->value_type );
1765
1766
0
    return( -1 );
1767
0
  }
1768
0
  if( internal_record->value_data == NULL )
1769
0
  {
1770
0
    libcerror_error_set(
1771
0
     error,
1772
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1773
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1774
0
     "%s: invalid record entry - missing value data.",
1775
0
     function );
1776
1777
0
    return( -1 );
1778
0
  }
1779
0
  if( internal_record->value_data_size != 2 )
1780
0
  {
1781
0
    libcerror_error_set(
1782
0
     error,
1783
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1784
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1785
0
     "%s: unsupported value data size.",
1786
0
     function );
1787
1788
0
    return( -1 );
1789
0
  }
1790
0
  if( value_16bit == NULL )
1791
0
  {
1792
0
    libcerror_error_set(
1793
0
     error,
1794
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1795
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1796
0
     "%s: invalid value 16-bit.",
1797
0
     function );
1798
1799
0
    return( -1 );
1800
0
  }
1801
0
  byte_stream_copy_to_uint16_little_endian(
1802
0
   internal_record->value_data,
1803
0
   *value_16bit );
1804
1805
0
  return( 1 );
1806
0
}
1807
1808
/* Retrieves the data as a 32-bit integer value
1809
 * Returns 1 if successful or -1 on error
1810
 */
1811
int libfwps_record_get_data_as_32bit_integer(
1812
     libfwps_record_t *record,
1813
     uint32_t *value_32bit,
1814
     libcerror_error_t **error )
1815
0
{
1816
0
  libfwps_internal_record_t *internal_record = NULL;
1817
0
  static char *function                      = "libfwps_record_get_data_as_32bit_integer";
1818
1819
0
  if( record == NULL )
1820
0
  {
1821
0
    libcerror_error_set(
1822
0
     error,
1823
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1824
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1825
0
     "%s: invalid record entry.",
1826
0
     function );
1827
1828
0
    return( -1 );
1829
0
  }
1830
0
  internal_record = (libfwps_internal_record_t *) record;
1831
1832
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_ERROR )
1833
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_32BIT_SIGNED )
1834
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_32BIT_UNSIGNED )
1835
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_SIGNED )
1836
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_UNSIGNED ) )
1837
0
  {
1838
0
    libcerror_error_set(
1839
0
     error,
1840
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1841
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1842
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1843
0
     function,
1844
0
     internal_record->value_type );
1845
1846
0
    return( -1 );
1847
0
  }
1848
0
  if( internal_record->value_data == NULL )
1849
0
  {
1850
0
    libcerror_error_set(
1851
0
     error,
1852
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1853
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1854
0
     "%s: invalid record entry - missing value data.",
1855
0
     function );
1856
1857
0
    return( -1 );
1858
0
  }
1859
0
  if( internal_record->value_data_size != 4 )
1860
0
  {
1861
0
    libcerror_error_set(
1862
0
     error,
1863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1864
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1865
0
     "%s: unsupported value data size.",
1866
0
     function );
1867
1868
0
    return( -1 );
1869
0
  }
1870
0
  if( value_32bit == NULL )
1871
0
  {
1872
0
    libcerror_error_set(
1873
0
     error,
1874
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1875
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1876
0
     "%s: invalid value 32-bit.",
1877
0
     function );
1878
1879
0
    return( -1 );
1880
0
  }
1881
0
  byte_stream_copy_to_uint32_little_endian(
1882
0
   internal_record->value_data,
1883
0
   *value_32bit );
1884
1885
0
  return( 1 );
1886
0
}
1887
1888
/* Retrieves the data as a 64-bit integer value
1889
 * Returns 1 if successful or -1 on error
1890
 */
1891
int libfwps_record_get_data_as_64bit_integer(
1892
     libfwps_record_t *record,
1893
     uint64_t *value_64bit,
1894
     libcerror_error_t **error )
1895
0
{
1896
0
  libfwps_internal_record_t *internal_record = NULL;
1897
0
  static char *function                      = "libfwps_record_get_data_as_64bit_integer";
1898
1899
0
  if( record == NULL )
1900
0
  {
1901
0
    libcerror_error_set(
1902
0
     error,
1903
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1904
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1905
0
     "%s: invalid record entry.",
1906
0
     function );
1907
1908
0
    return( -1 );
1909
0
  }
1910
0
  internal_record = (libfwps_internal_record_t *) record;
1911
1912
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_APPLICATION_TIME )
1913
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_CURRENCY )
1914
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_FILETIME )
1915
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_64BIT_SIGNED )
1916
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_INTEGER_64BIT_UNSIGNED ) )
1917
0
  {
1918
0
    libcerror_error_set(
1919
0
     error,
1920
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1921
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1922
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1923
0
     function,
1924
0
     internal_record->value_type );
1925
1926
0
    return( -1 );
1927
0
  }
1928
0
  if( internal_record->value_data == NULL )
1929
0
  {
1930
0
    libcerror_error_set(
1931
0
     error,
1932
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1933
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1934
0
     "%s: invalid record entry - missing value data.",
1935
0
     function );
1936
1937
0
    return( -1 );
1938
0
  }
1939
0
  if( internal_record->value_data_size != 8 )
1940
0
  {
1941
0
    libcerror_error_set(
1942
0
     error,
1943
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1944
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1945
0
     "%s: unsupported value data size.",
1946
0
     function );
1947
1948
0
    return( -1 );
1949
0
  }
1950
0
  if( value_64bit == NULL )
1951
0
  {
1952
0
    libcerror_error_set(
1953
0
     error,
1954
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1955
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1956
0
     "%s: invalid value 64-bit.",
1957
0
     function );
1958
1959
0
    return( -1 );
1960
0
  }
1961
0
  byte_stream_copy_to_uint64_little_endian(
1962
0
   internal_record->value_data,
1963
0
   *value_64bit );
1964
1965
0
  return( 1 );
1966
0
}
1967
1968
/* Retrieves the data as a 64-bit floatingtime value
1969
 * Returns 1 if successful or -1 on error
1970
 */
1971
int libfwps_record_get_data_as_floatingtime(
1972
     libfwps_record_t *record,
1973
     uint64_t *floatingtime,
1974
     libcerror_error_t **error )
1975
0
{
1976
0
  libfwps_internal_record_t *internal_record = NULL;
1977
0
  static char *function                      = "libfwps_record_get_data_as_floatingtime";
1978
1979
0
  if( record == NULL )
1980
0
  {
1981
0
    libcerror_error_set(
1982
0
     error,
1983
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1984
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1985
0
     "%s: invalid record entry.",
1986
0
     function );
1987
1988
0
    return( -1 );
1989
0
  }
1990
0
  internal_record = (libfwps_internal_record_t *) record;
1991
1992
0
  if( internal_record->value_type != LIBFWPS_VALUE_TYPE_APPLICATION_TIME )
1993
0
  {
1994
0
    libcerror_error_set(
1995
0
     error,
1996
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1997
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1998
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
1999
0
     function,
2000
0
     internal_record->value_type );
2001
2002
0
    return( -1 );
2003
0
  }
2004
0
  if( internal_record->value_data == NULL )
2005
0
  {
2006
0
    libcerror_error_set(
2007
0
     error,
2008
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2009
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2010
0
     "%s: invalid record entry - missing value data.",
2011
0
     function );
2012
2013
0
    return( -1 );
2014
0
  }
2015
0
  if( internal_record->value_data_size != 8 )
2016
0
  {
2017
0
    libcerror_error_set(
2018
0
     error,
2019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2020
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2021
0
     "%s: unsupported value data size.",
2022
0
     function );
2023
2024
0
    return( -1 );
2025
0
  }
2026
0
  if( floatingtime == NULL )
2027
0
  {
2028
0
    libcerror_error_set(
2029
0
     error,
2030
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2031
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2032
0
     "%s: invalid floatingtime.",
2033
0
     function );
2034
2035
0
    return( -1 );
2036
0
  }
2037
0
  byte_stream_copy_to_uint64_little_endian(
2038
0
   internal_record->value_data,
2039
0
   *floatingtime );
2040
2041
0
  return( 1 );
2042
0
}
2043
2044
/* Retrieves the data as a 64-bit FILETIME value
2045
 * Returns 1 if successful or -1 on error
2046
 */
2047
int libfwps_record_get_data_as_filetime(
2048
     libfwps_record_t *record,
2049
     uint64_t *filetime,
2050
     libcerror_error_t **error )
2051
0
{
2052
0
  libfwps_internal_record_t *internal_record = NULL;
2053
0
  static char *function                      = "libfwps_record_get_data_as_filetime";
2054
2055
0
  if( record == NULL )
2056
0
  {
2057
0
    libcerror_error_set(
2058
0
     error,
2059
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2060
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2061
0
     "%s: invalid record entry.",
2062
0
     function );
2063
2064
0
    return( -1 );
2065
0
  }
2066
0
  internal_record = (libfwps_internal_record_t *) record;
2067
2068
0
  if( internal_record->value_type != LIBFWPS_VALUE_TYPE_FILETIME )
2069
0
  {
2070
0
    libcerror_error_set(
2071
0
     error,
2072
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2073
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2074
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2075
0
     function,
2076
0
     internal_record->value_type );
2077
2078
0
    return( -1 );
2079
0
  }
2080
0
  if( internal_record->value_data == NULL )
2081
0
  {
2082
0
    libcerror_error_set(
2083
0
     error,
2084
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2085
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2086
0
     "%s: invalid record entry - missing value data.",
2087
0
     function );
2088
2089
0
    return( -1 );
2090
0
  }
2091
0
  if( internal_record->value_data_size != 8 )
2092
0
  {
2093
0
    libcerror_error_set(
2094
0
     error,
2095
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2096
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2097
0
     "%s: unsupported value data size.",
2098
0
     function );
2099
2100
0
    return( -1 );
2101
0
  }
2102
0
  if( filetime == NULL )
2103
0
  {
2104
0
    libcerror_error_set(
2105
0
     error,
2106
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2107
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2108
0
     "%s: invalid filetime.",
2109
0
     function );
2110
2111
0
    return( -1 );
2112
0
  }
2113
0
  byte_stream_copy_to_uint64_little_endian(
2114
0
   internal_record->value_data,
2115
0
   *filetime );
2116
2117
0
  return( 1 );
2118
0
}
2119
2120
/* Retrieves the floating point value
2121
 * Returns 1 if successful or -1 on error
2122
 */
2123
int libfwps_record_get_data_as_floating_point(
2124
     libfwps_record_t *record,
2125
     double *value_floating_point,
2126
     libcerror_error_t **error )
2127
0
{
2128
0
  byte_stream_float32_t value_float;
2129
0
  byte_stream_float64_t value_double;
2130
2131
0
  libfwps_internal_record_t *internal_record = NULL;
2132
0
  static char *function                      = "libfwps_record_get_data_as_floating_point";
2133
2134
0
  if( record == NULL )
2135
0
  {
2136
0
    libcerror_error_set(
2137
0
     error,
2138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2139
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2140
0
     "%s: invalid record entry.",
2141
0
     function );
2142
2143
0
    return( -1 );
2144
0
  }
2145
0
  internal_record = (libfwps_internal_record_t *) record;
2146
2147
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_APPLICATION_TIME )
2148
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_FLOAT_32BIT )
2149
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_DOUBLE_64BIT ) )
2150
0
  {
2151
0
    libcerror_error_set(
2152
0
     error,
2153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2154
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2155
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2156
0
     function,
2157
0
     internal_record->value_type );
2158
2159
0
    return( -1 );
2160
0
  }
2161
0
  if( internal_record->value_data == NULL )
2162
0
  {
2163
0
    libcerror_error_set(
2164
0
     error,
2165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2166
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2167
0
     "%s: invalid record entry - missing value data.",
2168
0
     function );
2169
2170
0
    return( -1 );
2171
0
  }
2172
0
  if( value_floating_point == NULL )
2173
0
  {
2174
0
    libcerror_error_set(
2175
0
     error,
2176
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2177
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2178
0
     "%s: invalid value floating point.",
2179
0
     function );
2180
2181
0
    return( -1 );
2182
0
  }
2183
  /* The value data size of a floating point value is 4 or 8
2184
   */
2185
0
  if( ( internal_record->value_data_size != 4 )
2186
0
   && ( internal_record->value_data_size != 8 ) )
2187
0
  {
2188
0
    libcerror_error_set(
2189
0
     error,
2190
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2191
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2192
0
     "%s: unsupported value data size.",
2193
0
     function );
2194
2195
0
    return( -1 );
2196
0
  }
2197
0
  if( internal_record->value_data_size == 4 )
2198
0
  {
2199
0
    byte_stream_copy_to_uint32_little_endian(
2200
0
     internal_record->value_data,
2201
0
     value_float.integer );
2202
2203
0
    *value_floating_point = (double) value_float.floating_point;
2204
0
  }
2205
0
  else if( internal_record->value_data_size == 8 )
2206
0
  {
2207
0
    byte_stream_copy_to_uint64_little_endian(
2208
0
     internal_record->value_data,
2209
0
     value_double.integer );
2210
2211
0
    *value_floating_point = value_double.floating_point;
2212
0
  }
2213
0
  return( 1 );
2214
0
}
2215
2216
/* Retrieves the size of the data formatted as an UTF-8 string
2217
 * The function uses a codepage if necessary, it uses the codepage set for the library
2218
 * The returned size includes the end of string character
2219
 * Returns 1 if successful or -1 on error
2220
 */
2221
int libfwps_record_get_data_as_utf8_string_size(
2222
     libfwps_record_t *record,
2223
     size_t *utf8_string_size,
2224
     libcerror_error_t **error )
2225
0
{
2226
0
  libfwps_internal_record_t *internal_record = NULL;
2227
0
  static char *function                      = "libfwps_record_get_data_as_utf8_string_size";
2228
0
  uint8_t is_ascii_string                    = 0;
2229
0
  int result                                 = 0;
2230
2231
0
  if( record == NULL )
2232
0
  {
2233
0
    libcerror_error_set(
2234
0
     error,
2235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2237
0
     "%s: invalid record entry.",
2238
0
     function );
2239
2240
0
    return( -1 );
2241
0
  }
2242
0
  internal_record = (libfwps_internal_record_t *) record;
2243
2244
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2245
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2246
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2247
0
  {
2248
0
    libcerror_error_set(
2249
0
     error,
2250
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2251
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2252
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2253
0
     function,
2254
0
     internal_record->value_type );
2255
2256
0
    return( -1 );
2257
0
  }
2258
0
  if( utf8_string_size == NULL )
2259
0
  {
2260
0
    libcerror_error_set(
2261
0
     error,
2262
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2263
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2264
0
     "%s: invalid UTF-8 string size.",
2265
0
     function );
2266
2267
0
    return( -1 );
2268
0
  }
2269
0
  if( ( internal_record->value_data == NULL )
2270
0
   || ( internal_record->value_data_size == 0 ) )
2271
0
  {
2272
0
    *utf8_string_size = 0;
2273
2274
0
    return( 1 );
2275
0
  }
2276
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2277
0
  {
2278
0
    is_ascii_string = 1;
2279
0
  }
2280
  /* String is in UTF-16 little-endian
2281
   */
2282
0
  if( is_ascii_string == 0 )
2283
0
  {
2284
0
    result = libuna_utf8_string_size_from_utf16_stream(
2285
0
              internal_record->value_data,
2286
0
              internal_record->value_data_size,
2287
0
              LIBUNA_ENDIAN_LITTLE,
2288
0
              utf8_string_size,
2289
0
              error );
2290
0
  }
2291
  /* Codepage 65000 represents UTF-7
2292
   */
2293
0
  else if( internal_record->ascii_codepage == 65000 )
2294
0
  {
2295
0
    result = libuna_utf8_string_size_from_utf7_stream(
2296
0
        internal_record->value_data,
2297
0
        internal_record->value_data_size,
2298
0
        utf8_string_size,
2299
0
        error );
2300
0
  }
2301
  /* Codepage 65001 represents UTF-8
2302
   */
2303
0
  else if( internal_record->ascii_codepage == 65001 )
2304
0
  {
2305
0
    result = libuna_utf8_string_size_from_utf8_stream(
2306
0
        internal_record->value_data,
2307
0
        internal_record->value_data_size,
2308
0
        utf8_string_size,
2309
0
        error );
2310
0
  }
2311
0
  else
2312
0
  {
2313
0
    result = libuna_utf8_string_size_from_byte_stream(
2314
0
        internal_record->value_data,
2315
0
        internal_record->value_data_size,
2316
0
        internal_record->ascii_codepage,
2317
0
        utf8_string_size,
2318
0
        error );
2319
0
  }
2320
0
  if( result != 1 )
2321
0
  {
2322
0
    libcerror_error_set(
2323
0
     error,
2324
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2325
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2326
0
     "%s: unable to determine size of value data as UTF-8 string.",
2327
0
     function );
2328
2329
0
    return( -1 );
2330
0
  }
2331
0
  return( 1 );
2332
0
}
2333
2334
/* Retrieves the data formatted as an UTF-8 string
2335
 * The function uses a codepage if necessary, it uses the codepage set for the library
2336
 * The size should include the end of string character
2337
 * Returns 1 if successful or -1 on error
2338
 */
2339
int libfwps_record_get_data_as_utf8_string(
2340
     libfwps_record_t *record,
2341
     uint8_t *utf8_string,
2342
     size_t utf8_string_size,
2343
     libcerror_error_t **error )
2344
0
{
2345
0
  libfwps_internal_record_t *internal_record = NULL;
2346
0
  static char *function                      = "libfwps_record_get_data_as_utf8_string";
2347
0
  uint8_t is_ascii_string                    = 0;
2348
0
  int result                                 = 0;
2349
2350
0
  if( record == NULL )
2351
0
  {
2352
0
    libcerror_error_set(
2353
0
     error,
2354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2355
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2356
0
     "%s: invalid record entry.",
2357
0
     function );
2358
2359
0
    return( -1 );
2360
0
  }
2361
0
  internal_record = (libfwps_internal_record_t *) record;
2362
2363
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2364
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2365
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2366
0
  {
2367
0
    libcerror_error_set(
2368
0
     error,
2369
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2370
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2371
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2372
0
     function,
2373
0
     internal_record->value_type );
2374
2375
0
    return( -1 );
2376
0
  }
2377
0
  if( utf8_string == NULL )
2378
0
  {
2379
0
    libcerror_error_set(
2380
0
     error,
2381
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2382
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2383
0
     "%s: invalid UTF-8 string.",
2384
0
     function );
2385
2386
0
    return( -1 );
2387
0
  }
2388
0
  if( ( utf8_string_size == 0 )
2389
0
   || ( utf8_string_size > (size_t) SSIZE_MAX ) )
2390
0
  {
2391
0
    libcerror_error_set(
2392
0
     error,
2393
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2394
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2395
0
     "%s: invalid UTF-8 string size value out of bounds.",
2396
0
     function );
2397
2398
0
    return( -1 );
2399
0
  }
2400
0
  if( ( internal_record->value_data == NULL )
2401
0
   || ( internal_record->value_data_size == 0 ) )
2402
0
  {
2403
0
    utf8_string[ 0 ] = 0;
2404
2405
0
    return( 1 );
2406
0
  }
2407
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2408
0
  {
2409
0
    is_ascii_string = 1;
2410
0
  }
2411
  /* String is in UTF-16 little-endian
2412
   */
2413
0
  if( is_ascii_string == 0 )
2414
0
  {
2415
0
    result = libuna_utf8_string_copy_from_utf16_stream(
2416
0
              utf8_string,
2417
0
              utf8_string_size,
2418
0
              internal_record->value_data,
2419
0
              internal_record->value_data_size,
2420
0
              LIBUNA_ENDIAN_LITTLE,
2421
0
              error );
2422
0
  }
2423
  /* Codepage 65000 represents UTF-7
2424
   */
2425
0
  else if( internal_record->ascii_codepage == 65000 )
2426
0
  {
2427
0
    result = libuna_utf8_string_copy_from_utf7_stream(
2428
0
              utf8_string,
2429
0
              utf8_string_size,
2430
0
              internal_record->value_data,
2431
0
              internal_record->value_data_size,
2432
0
              error );
2433
0
  }
2434
  /* Codepage 65001 represents UTF-8
2435
   */
2436
0
  else if( internal_record->ascii_codepage == 65001 )
2437
0
  {
2438
0
    result = libuna_utf8_string_copy_from_utf8_stream(
2439
0
              utf8_string,
2440
0
              utf8_string_size,
2441
0
              internal_record->value_data,
2442
0
              internal_record->value_data_size,
2443
0
              error );
2444
0
  }
2445
0
  else
2446
0
  {
2447
0
    result = libuna_utf8_string_copy_from_byte_stream(
2448
0
              utf8_string,
2449
0
              utf8_string_size,
2450
0
              internal_record->value_data,
2451
0
              internal_record->value_data_size,
2452
0
              internal_record->ascii_codepage,
2453
0
              error );
2454
0
  }
2455
0
  if( result != 1 )
2456
0
  {
2457
0
    libcerror_error_set(
2458
0
     error,
2459
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2460
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2461
0
     "%s: unable to copy value data to UTF-8 string.",
2462
0
     function );
2463
2464
0
    return( -1 );
2465
0
  }
2466
0
  return( 1 );
2467
0
}
2468
2469
/* Retrieves the size of the data formatted as an UTF-16 string
2470
 * The function uses a codepage if necessary, it uses the codepage set for the library
2471
 * The returned size includes the end of string character
2472
 * Returns 1 if successful or -1 on error
2473
 */
2474
int libfwps_record_get_data_as_utf16_string_size(
2475
     libfwps_record_t *record,
2476
     size_t *utf16_string_size,
2477
     libcerror_error_t **error )
2478
0
{
2479
0
  libfwps_internal_record_t *internal_record = NULL;
2480
0
  static char *function                      = "libfwps_record_get_data_as_utf16_string_size";
2481
0
  uint8_t is_ascii_string                    = 0;
2482
0
  int result                                 = 0;
2483
2484
0
  if( record == NULL )
2485
0
  {
2486
0
    libcerror_error_set(
2487
0
     error,
2488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2490
0
     "%s: invalid record entry.",
2491
0
     function );
2492
2493
0
    return( -1 );
2494
0
  }
2495
0
  internal_record = (libfwps_internal_record_t *) record;
2496
2497
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2498
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2499
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2500
0
  {
2501
0
    libcerror_error_set(
2502
0
     error,
2503
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2504
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2505
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2506
0
     function,
2507
0
     internal_record->value_type );
2508
2509
0
    return( -1 );
2510
0
  }
2511
0
  if( utf16_string_size == NULL )
2512
0
  {
2513
0
    libcerror_error_set(
2514
0
     error,
2515
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2516
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2517
0
     "%s: invalid UTF-16 string size.",
2518
0
     function );
2519
2520
0
    return( -1 );
2521
0
  }
2522
0
  if( ( internal_record->value_data == NULL )
2523
0
   || ( internal_record->value_data_size == 0 ) )
2524
0
  {
2525
0
    *utf16_string_size = 0;
2526
2527
0
    return( 1 );
2528
0
  }
2529
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2530
0
  {
2531
0
    is_ascii_string = 1;
2532
0
  }
2533
  /* String is in UTF-16 little-endian
2534
   */
2535
0
  if( is_ascii_string == 0 )
2536
0
  {
2537
0
    result = libuna_utf16_string_size_from_utf16_stream(
2538
0
              internal_record->value_data,
2539
0
              internal_record->value_data_size,
2540
0
              LIBUNA_ENDIAN_LITTLE,
2541
0
              utf16_string_size,
2542
0
              error );
2543
0
  }
2544
  /* Codepage 65000 represents UTF-7
2545
   */
2546
0
  else if( internal_record->ascii_codepage == 65000 )
2547
0
  {
2548
0
    result = libuna_utf16_string_size_from_utf7_stream(
2549
0
        internal_record->value_data,
2550
0
        internal_record->value_data_size,
2551
0
        utf16_string_size,
2552
0
        error );
2553
0
  }
2554
  /* Codepage 65001 represents UTF-8
2555
   */
2556
0
  else if( internal_record->ascii_codepage == 65001 )
2557
0
  {
2558
0
    result = libuna_utf16_string_size_from_utf8_stream(
2559
0
        internal_record->value_data,
2560
0
        internal_record->value_data_size,
2561
0
        utf16_string_size,
2562
0
        error );
2563
0
  }
2564
0
  else
2565
0
  {
2566
0
    result = libuna_utf16_string_size_from_byte_stream(
2567
0
        internal_record->value_data,
2568
0
        internal_record->value_data_size,
2569
0
        internal_record->ascii_codepage,
2570
0
        utf16_string_size,
2571
0
        error );
2572
0
  }
2573
0
  if( result != 1 )
2574
0
  {
2575
0
    libcerror_error_set(
2576
0
     error,
2577
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2578
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2579
0
     "%s: unable to determine size of value data as UTF-16 string.",
2580
0
     function );
2581
2582
0
    return( -1 );
2583
0
  }
2584
0
  return( 1 );
2585
0
}
2586
2587
/* Retrieves the data formatted as an UTF-16 string
2588
 * The function uses a codepage if necessary, it uses the codepage set for the library
2589
 * The size should include the end of string character
2590
 * Returns 1 if successful or -1 on error
2591
 */
2592
int libfwps_record_get_data_as_utf16_string(
2593
     libfwps_record_t *record,
2594
     uint16_t *utf16_string,
2595
     size_t utf16_string_size,
2596
     libcerror_error_t **error )
2597
0
{
2598
0
  libfwps_internal_record_t *internal_record = NULL;
2599
0
  static char *function                      = "libfwps_record_get_data_as_utf16_string";
2600
0
  uint8_t is_ascii_string                    = 0;
2601
0
  int result                                 = 0;
2602
2603
0
  if( record == NULL )
2604
0
  {
2605
0
    libcerror_error_set(
2606
0
     error,
2607
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2608
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2609
0
     "%s: invalid record entry.",
2610
0
     function );
2611
2612
0
    return( -1 );
2613
0
  }
2614
0
  internal_record = (libfwps_internal_record_t *) record;
2615
2616
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2617
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2618
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2619
0
  {
2620
0
    libcerror_error_set(
2621
0
     error,
2622
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2623
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2624
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2625
0
     function,
2626
0
     internal_record->value_type );
2627
2628
0
    return( -1 );
2629
0
  }
2630
0
  if( utf16_string == NULL )
2631
0
  {
2632
0
    libcerror_error_set(
2633
0
     error,
2634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2635
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2636
0
     "%s: invalid UTF-16 string.",
2637
0
     function );
2638
2639
0
    return( -1 );
2640
0
  }
2641
0
  if( ( utf16_string_size == 0 )
2642
0
   || ( utf16_string_size > (size_t) SSIZE_MAX ) )
2643
0
  {
2644
0
    libcerror_error_set(
2645
0
     error,
2646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2647
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2648
0
     "%s: invalid UTF-16 string size value out of bounds.",
2649
0
     function );
2650
2651
0
    return( -1 );
2652
0
  }
2653
0
  if( ( internal_record->value_data == NULL )
2654
0
   || ( internal_record->value_data_size == 0 ) )
2655
0
  {
2656
0
    utf16_string[ 0 ] = 0;
2657
2658
0
    return( 1 );
2659
0
  }
2660
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2661
0
  {
2662
0
    is_ascii_string = 1;
2663
0
  }
2664
  /* String is in UTF-16 little-endian
2665
   */
2666
0
  if( is_ascii_string == 0 )
2667
0
  {
2668
0
    result = libuna_utf16_string_copy_from_utf16_stream(
2669
0
              utf16_string,
2670
0
              utf16_string_size,
2671
0
              internal_record->value_data,
2672
0
              internal_record->value_data_size,
2673
0
              LIBUNA_ENDIAN_LITTLE,
2674
0
              error );
2675
0
  }
2676
  /* Codepage 65000 represents UTF-7
2677
   */
2678
0
  else if( internal_record->ascii_codepage == 65000 )
2679
0
  {
2680
0
    result = libuna_utf16_string_copy_from_utf7_stream(
2681
0
              utf16_string,
2682
0
              utf16_string_size,
2683
0
              internal_record->value_data,
2684
0
              internal_record->value_data_size,
2685
0
              error );
2686
0
  }
2687
  /* Codepage 65001 represents UTF-8
2688
   */
2689
0
  else if( internal_record->ascii_codepage == 65001 )
2690
0
  {
2691
0
    result = libuna_utf16_string_copy_from_utf8_stream(
2692
0
              utf16_string,
2693
0
              utf16_string_size,
2694
0
              internal_record->value_data,
2695
0
              internal_record->value_data_size,
2696
0
              error );
2697
0
  }
2698
0
  else
2699
0
  {
2700
0
    result = libuna_utf16_string_copy_from_byte_stream(
2701
0
              utf16_string,
2702
0
              utf16_string_size,
2703
0
              internal_record->value_data,
2704
0
              internal_record->value_data_size,
2705
0
              internal_record->ascii_codepage,
2706
0
              error );
2707
0
  }
2708
0
  if( result != 1 )
2709
0
  {
2710
0
    libcerror_error_set(
2711
0
     error,
2712
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2713
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2714
0
     "%s: unable to copy value data to UTF-16 string.",
2715
0
     function );
2716
2717
0
    return( -1 );
2718
0
  }
2719
0
  return( 1 );
2720
0
}
2721
2722
/* Retrieves the size of the data formatted as an UTF-8 path string
2723
 * The function uses a codepage if necessary, it uses the codepage set for the library
2724
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2725
 * The returned size includes the end of string character
2726
 * Returns 1 if successful or -1 on error
2727
 */
2728
int libfwps_record_get_data_as_utf8_path_string_size(
2729
     libfwps_record_t *record,
2730
     size_t *utf8_string_size,
2731
     libcerror_error_t **error )
2732
0
{
2733
0
  libfwps_internal_record_t *internal_record = NULL;
2734
0
  static char *function                      = "libfwps_record_get_data_as_utf8_path_string_size";
2735
0
  uint8_t is_ascii_string                    = 0;
2736
0
  int result                                 = 0;
2737
2738
0
  if( record == NULL )
2739
0
  {
2740
0
    libcerror_error_set(
2741
0
     error,
2742
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2743
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2744
0
     "%s: invalid record entry.",
2745
0
     function );
2746
2747
0
    return( -1 );
2748
0
  }
2749
0
  internal_record = (libfwps_internal_record_t *) record;
2750
2751
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2752
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2753
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2754
0
  {
2755
0
    libcerror_error_set(
2756
0
     error,
2757
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2758
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2759
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2760
0
     function,
2761
0
     internal_record->value_type );
2762
2763
0
    return( -1 );
2764
0
  }
2765
0
  if( utf8_string_size == NULL )
2766
0
  {
2767
0
    libcerror_error_set(
2768
0
     error,
2769
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2770
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2771
0
     "%s: invalid UTF-8 string size.",
2772
0
     function );
2773
2774
0
    return( -1 );
2775
0
  }
2776
0
  if( ( internal_record->value_data == NULL )
2777
0
   || ( internal_record->value_data_size == 0 ) )
2778
0
  {
2779
0
    *utf8_string_size = 0;
2780
2781
0
    return( 1 );
2782
0
  }
2783
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2784
0
  {
2785
0
    is_ascii_string = 1;
2786
0
  }
2787
  /* String is in UTF-16 little-endian
2788
   */
2789
0
  if( is_ascii_string == 0 )
2790
0
  {
2791
0
    result = libuna_utf8_string_size_from_utf16_stream(
2792
0
              internal_record->value_data,
2793
0
              internal_record->value_data_size,
2794
0
              LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2795
0
              utf8_string_size,
2796
0
              error );
2797
0
  }
2798
  /* Codepage 65000 represents UTF-7
2799
   */
2800
0
  else if( internal_record->ascii_codepage == 65000 )
2801
0
  {
2802
0
    result = libuna_utf8_string_size_from_utf7_stream(
2803
0
        internal_record->value_data,
2804
0
        internal_record->value_data_size,
2805
0
        utf8_string_size,
2806
0
        error );
2807
0
  }
2808
  /* Codepage 65001 represents UTF-8
2809
   */
2810
0
  else if( internal_record->ascii_codepage == 65001 )
2811
0
  {
2812
0
    result = libuna_utf8_string_size_from_utf8_stream(
2813
0
        internal_record->value_data,
2814
0
        internal_record->value_data_size,
2815
0
        utf8_string_size,
2816
0
        error );
2817
0
  }
2818
0
  else
2819
0
  {
2820
0
    result = libuna_utf8_string_size_from_byte_stream(
2821
0
        internal_record->value_data,
2822
0
        internal_record->value_data_size,
2823
0
        internal_record->ascii_codepage,
2824
0
        utf8_string_size,
2825
0
        error );
2826
0
  }
2827
0
  if( result != 1 )
2828
0
  {
2829
0
    libcerror_error_set(
2830
0
     error,
2831
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2832
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2833
0
     "%s: unable to determine size of value data as UTF-8 string.",
2834
0
     function );
2835
2836
0
    return( -1 );
2837
0
  }
2838
0
  return( 1 );
2839
0
}
2840
2841
/* Retrieves the data formatted as an UTF-8 path string
2842
 * The function uses a codepage if necessary, it uses the codepage set for the library
2843
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2844
 * The size should include the end of string character
2845
 * Returns 1 if successful or -1 on error
2846
 */
2847
int libfwps_record_get_data_as_utf8_path_string(
2848
     libfwps_record_t *record,
2849
     uint8_t *utf8_string,
2850
     size_t utf8_string_size,
2851
     libcerror_error_t **error )
2852
0
{
2853
0
  libfwps_internal_record_t *internal_record = NULL;
2854
0
  static char *function                      = "libfwps_record_get_data_as_utf8_path_string";
2855
0
  uint8_t is_ascii_string                    = 0;
2856
0
  int result                                 = 0;
2857
2858
0
  if( record == NULL )
2859
0
  {
2860
0
    libcerror_error_set(
2861
0
     error,
2862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2863
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2864
0
     "%s: invalid record entry.",
2865
0
     function );
2866
2867
0
    return( -1 );
2868
0
  }
2869
0
  internal_record = (libfwps_internal_record_t *) record;
2870
2871
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
2872
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
2873
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
2874
0
  {
2875
0
    libcerror_error_set(
2876
0
     error,
2877
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2878
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2879
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
2880
0
     function,
2881
0
     internal_record->value_type );
2882
2883
0
    return( -1 );
2884
0
  }
2885
0
  if( utf8_string == NULL )
2886
0
  {
2887
0
    libcerror_error_set(
2888
0
     error,
2889
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2890
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2891
0
     "%s: invalid UTF-8 string.",
2892
0
     function );
2893
2894
0
    return( -1 );
2895
0
  }
2896
0
  if( ( utf8_string_size == 0 )
2897
0
   || ( utf8_string_size > (size_t) SSIZE_MAX ) )
2898
0
  {
2899
0
    libcerror_error_set(
2900
0
     error,
2901
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2902
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2903
0
     "%s: invalid UTF-8 string size value out of bounds.",
2904
0
     function );
2905
2906
0
    return( -1 );
2907
0
  }
2908
0
  if( ( internal_record->value_data == NULL )
2909
0
   || ( internal_record->value_data_size == 0 ) )
2910
0
  {
2911
0
    utf8_string[ 0 ] = 0;
2912
2913
0
    return( 1 );
2914
0
  }
2915
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
2916
0
  {
2917
0
    is_ascii_string = 1;
2918
0
  }
2919
  /* String is in UTF-16 little-endian
2920
   */
2921
0
  if( is_ascii_string == 0 )
2922
0
  {
2923
0
    result = libuna_utf8_string_copy_from_utf16_stream(
2924
0
              utf8_string,
2925
0
              utf8_string_size,
2926
0
              internal_record->value_data,
2927
0
              internal_record->value_data_size,
2928
0
              LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2929
0
              error );
2930
0
  }
2931
  /* Codepage 65000 represents UTF-7
2932
   */
2933
0
  else if( internal_record->ascii_codepage == 65000 )
2934
0
  {
2935
0
    result = libuna_utf8_string_copy_from_utf7_stream(
2936
0
              utf8_string,
2937
0
              utf8_string_size,
2938
0
              internal_record->value_data,
2939
0
              internal_record->value_data_size,
2940
0
              error );
2941
0
  }
2942
  /* Codepage 65001 represents UTF-8
2943
   */
2944
0
  else if( internal_record->ascii_codepage == 65001 )
2945
0
  {
2946
0
    result = libuna_utf8_string_copy_from_utf8_stream(
2947
0
              utf8_string,
2948
0
              utf8_string_size,
2949
0
              internal_record->value_data,
2950
0
              internal_record->value_data_size,
2951
0
              error );
2952
0
  }
2953
0
  else
2954
0
  {
2955
0
    result = libuna_utf8_string_copy_from_byte_stream(
2956
0
              utf8_string,
2957
0
              utf8_string_size,
2958
0
              internal_record->value_data,
2959
0
              internal_record->value_data_size,
2960
0
              internal_record->ascii_codepage,
2961
0
              error );
2962
0
  }
2963
0
  if( result != 1 )
2964
0
  {
2965
0
    libcerror_error_set(
2966
0
     error,
2967
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2968
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2969
0
     "%s: unable to copy value data to UTF-8 string.",
2970
0
     function );
2971
2972
0
    return( -1 );
2973
0
  }
2974
0
  return( 1 );
2975
0
}
2976
2977
/* Retrieves the size of the data formatted as an UTF-16 path string
2978
 * The function uses a codepage if necessary, it uses the codepage set for the library
2979
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2980
 * The returned size includes the end of string character
2981
 * Returns 1 if successful or -1 on error
2982
 */
2983
int libfwps_record_get_data_as_utf16_path_string_size(
2984
     libfwps_record_t *record,
2985
     size_t *utf16_string_size,
2986
     libcerror_error_t **error )
2987
0
{
2988
0
  libfwps_internal_record_t *internal_record = NULL;
2989
0
  static char *function                      = "libfwps_record_get_data_as_utf16_path_string_size";
2990
0
  uint8_t is_ascii_string                    = 0;
2991
0
  int result                                 = 0;
2992
2993
0
  if( record == NULL )
2994
0
  {
2995
0
    libcerror_error_set(
2996
0
     error,
2997
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2998
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2999
0
     "%s: invalid record entry.",
3000
0
     function );
3001
3002
0
    return( -1 );
3003
0
  }
3004
0
  internal_record = (libfwps_internal_record_t *) record;
3005
3006
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
3007
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
3008
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
3009
0
  {
3010
0
    libcerror_error_set(
3011
0
     error,
3012
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3013
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3014
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
3015
0
     function,
3016
0
     internal_record->value_type );
3017
3018
0
    return( -1 );
3019
0
  }
3020
0
  if( utf16_string_size == NULL )
3021
0
  {
3022
0
    libcerror_error_set(
3023
0
     error,
3024
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3025
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3026
0
     "%s: invalid UTF-16 string size.",
3027
0
     function );
3028
3029
0
    return( -1 );
3030
0
  }
3031
0
  if( ( internal_record->value_data == NULL )
3032
0
   || ( internal_record->value_data_size == 0 ) )
3033
0
  {
3034
0
    *utf16_string_size = 0;
3035
3036
0
    return( 1 );
3037
0
  }
3038
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
3039
0
  {
3040
0
    is_ascii_string = 1;
3041
0
  }
3042
  /* String is in UTF-16 little-endian
3043
   */
3044
0
  if( is_ascii_string == 0 )
3045
0
  {
3046
0
    result = libuna_utf16_string_size_from_utf16_stream(
3047
0
              internal_record->value_data,
3048
0
              internal_record->value_data_size,
3049
0
              LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3050
0
              utf16_string_size,
3051
0
              error );
3052
0
  }
3053
  /* Codepage 65000 represents UTF-7
3054
   */
3055
0
  else if( internal_record->ascii_codepage == 65000 )
3056
0
  {
3057
0
    result = libuna_utf16_string_size_from_utf7_stream(
3058
0
        internal_record->value_data,
3059
0
        internal_record->value_data_size,
3060
0
        utf16_string_size,
3061
0
        error );
3062
0
  }
3063
  /* Codepage 65001 represents UTF-8
3064
   */
3065
0
  else if( internal_record->ascii_codepage == 65001 )
3066
0
  {
3067
0
    result = libuna_utf16_string_size_from_utf8_stream(
3068
0
        internal_record->value_data,
3069
0
        internal_record->value_data_size,
3070
0
        utf16_string_size,
3071
0
        error );
3072
0
  }
3073
0
  else
3074
0
  {
3075
0
    result = libuna_utf16_string_size_from_byte_stream(
3076
0
        internal_record->value_data,
3077
0
        internal_record->value_data_size,
3078
0
        internal_record->ascii_codepage,
3079
0
        utf16_string_size,
3080
0
        error );
3081
0
  }
3082
0
  if( result != 1 )
3083
0
  {
3084
0
    libcerror_error_set(
3085
0
     error,
3086
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3087
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3088
0
     "%s: unable to determine size of value data as UTF-16 string.",
3089
0
     function );
3090
3091
0
    return( -1 );
3092
0
  }
3093
0
  return( 1 );
3094
0
}
3095
3096
/* Retrieves the data formatted as an UTF-16 path string
3097
 * The function uses a codepage if necessary, it uses the codepage set for the library
3098
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
3099
 * The size should include the end of string character
3100
 * Returns 1 if successful or -1 on error
3101
 */
3102
int libfwps_record_get_data_as_utf16_path_string(
3103
     libfwps_record_t *record,
3104
     uint16_t *utf16_string,
3105
     size_t utf16_string_size,
3106
     libcerror_error_t **error )
3107
0
{
3108
0
  libfwps_internal_record_t *internal_record = NULL;
3109
0
  static char *function                      = "libfwps_record_get_data_as_utf16_path_string";
3110
0
  uint8_t is_ascii_string                    = 0;
3111
0
  int result                                 = 0;
3112
3113
0
  if( record == NULL )
3114
0
  {
3115
0
    libcerror_error_set(
3116
0
     error,
3117
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3118
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3119
0
     "%s: invalid record entry.",
3120
0
     function );
3121
3122
0
    return( -1 );
3123
0
  }
3124
0
  internal_record = (libfwps_internal_record_t *) record;
3125
3126
0
  if( ( internal_record->value_type != LIBFWPS_VALUE_TYPE_BINARY_STRING )
3127
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_ASCII )
3128
0
   && ( internal_record->value_type != LIBFWPS_VALUE_TYPE_STRING_UNICODE ) )
3129
0
  {
3130
0
    libcerror_error_set(
3131
0
     error,
3132
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3133
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3134
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
3135
0
     function,
3136
0
     internal_record->value_type );
3137
3138
0
    return( -1 );
3139
0
  }
3140
0
  if( utf16_string == NULL )
3141
0
  {
3142
0
    libcerror_error_set(
3143
0
     error,
3144
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3145
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3146
0
     "%s: invalid UTF-16 string.",
3147
0
     function );
3148
3149
0
    return( -1 );
3150
0
  }
3151
0
  if( ( utf16_string_size == 0 )
3152
0
   || ( utf16_string_size > (size_t) SSIZE_MAX ) )
3153
0
  {
3154
0
    libcerror_error_set(
3155
0
     error,
3156
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3157
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3158
0
     "%s: invalid UTF-16 string size value out of bounds.",
3159
0
     function );
3160
3161
0
    return( -1 );
3162
0
  }
3163
0
  if( ( internal_record->value_data == NULL )
3164
0
   || ( internal_record->value_data_size == 0 ) )
3165
0
  {
3166
0
    utf16_string[ 0 ] = 0;
3167
3168
0
    return( 1 );
3169
0
  }
3170
0
  if( internal_record->value_type == LIBFWPS_VALUE_TYPE_STRING_ASCII )
3171
0
  {
3172
0
    is_ascii_string = 1;
3173
0
  }
3174
  /* String is in UTF-16 little-endian
3175
   */
3176
0
  if( is_ascii_string == 0 )
3177
0
  {
3178
0
    result = libuna_utf16_string_copy_from_utf16_stream(
3179
0
              utf16_string,
3180
0
              utf16_string_size,
3181
0
              internal_record->value_data,
3182
0
              internal_record->value_data_size,
3183
0
              LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3184
0
              error );
3185
0
  }
3186
  /* Codepage 65000 represents UTF-7
3187
   */
3188
0
  else if( internal_record->ascii_codepage == 65000 )
3189
0
  {
3190
0
    result = libuna_utf16_string_copy_from_utf7_stream(
3191
0
              utf16_string,
3192
0
              utf16_string_size,
3193
0
              internal_record->value_data,
3194
0
              internal_record->value_data_size,
3195
0
              error );
3196
0
  }
3197
  /* Codepage 65001 represents UTF-8
3198
   */
3199
0
  else if( internal_record->ascii_codepage == 65001 )
3200
0
  {
3201
0
    result = libuna_utf16_string_copy_from_utf8_stream(
3202
0
              utf16_string,
3203
0
              utf16_string_size,
3204
0
              internal_record->value_data,
3205
0
              internal_record->value_data_size,
3206
0
              error );
3207
0
  }
3208
0
  else
3209
0
  {
3210
0
    result = libuna_utf16_string_copy_from_byte_stream(
3211
0
              utf16_string,
3212
0
              utf16_string_size,
3213
0
              internal_record->value_data,
3214
0
              internal_record->value_data_size,
3215
0
              internal_record->ascii_codepage,
3216
0
              error );
3217
0
  }
3218
0
  if( result != 1 )
3219
0
  {
3220
0
    libcerror_error_set(
3221
0
     error,
3222
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3223
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3224
0
     "%s: unable to copy value data to UTF-16 string.",
3225
0
     function );
3226
3227
0
    return( -1 );
3228
0
  }
3229
0
  return( 1 );
3230
0
}
3231
3232
/* Retrieves the data as a GUID value
3233
 * Returns 1 if successful or -1 on error
3234
 */
3235
int libfwps_record_get_data_as_guid(
3236
     libfwps_record_t *record,
3237
     uint8_t *guid_data,
3238
     size_t guid_data_size,
3239
     libcerror_error_t **error )
3240
0
{
3241
0
  libfwps_internal_record_t *internal_record = NULL;
3242
0
  static char *function                      = "libfwps_record_get_data_as_guid";
3243
3244
0
  if( record == NULL )
3245
0
  {
3246
0
    libcerror_error_set(
3247
0
     error,
3248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3250
0
     "%s: invalid record entry.",
3251
0
     function );
3252
3253
0
    return( -1 );
3254
0
  }
3255
0
  internal_record = (libfwps_internal_record_t *) record;
3256
3257
0
  if( internal_record->value_type != LIBFWPS_VALUE_TYPE_GUID )
3258
0
  {
3259
0
    libcerror_error_set(
3260
0
     error,
3261
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3262
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3263
0
     "%s: invalid record entry - unsupported value type: 0x%04" PRIx32 ".",
3264
0
     function,
3265
0
     internal_record->value_type );
3266
3267
0
    return( -1 );
3268
0
  }
3269
0
  if( internal_record->value_data == NULL )
3270
0
  {
3271
0
    libcerror_error_set(
3272
0
     error,
3273
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3274
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3275
0
     "%s: invalid record entry - missing value data.",
3276
0
     function );
3277
3278
0
    return( -1 );
3279
0
  }
3280
0
  if( internal_record->value_data_size != 16 )
3281
0
  {
3282
0
    libcerror_error_set(
3283
0
     error,
3284
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3285
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3286
0
     "%s: unsupported value data size.",
3287
0
     function );
3288
3289
0
    return( -1 );
3290
0
  }
3291
0
  if( guid_data == NULL )
3292
0
  {
3293
0
    libcerror_error_set(
3294
0
     error,
3295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3297
0
     "%s: invalid GUID data.",
3298
0
     function );
3299
3300
0
    return( -1 );
3301
0
  }
3302
0
  if( guid_data_size > (size_t) SSIZE_MAX )
3303
0
  {
3304
0
    libcerror_error_set(
3305
0
     error,
3306
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3307
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3308
0
     "%s: GUID data size value exceeds maximum.",
3309
0
     function );
3310
3311
0
    return( -1 );
3312
0
  }
3313
0
  if( guid_data_size < 16 )
3314
0
  {
3315
0
    libcerror_error_set(
3316
0
     error,
3317
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3318
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3319
0
     "%s: GUID data size value too small.",
3320
0
     function );
3321
3322
0
    return( -1 );
3323
0
  }
3324
0
  if( memory_copy(
3325
0
       guid_data,
3326
0
       internal_record->value_data,
3327
0
       16 ) == NULL )
3328
0
  {
3329
0
    libcerror_error_set(
3330
0
     error,
3331
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
3332
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3333
0
     "%s: unable to copy value data.",
3334
0
     function );
3335
3336
0
    return( -1 );
3337
0
  }
3338
0
  return( 1 );
3339
0
}
3340