Coverage Report

Created: 2025-07-04 07:01

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