Coverage Report

Created: 2025-06-13 07:21

/src/libmsiecf/libmsiecf/libmsiecf_item.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Item 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 "libmsiecf_definitions.h"
27
#include "libmsiecf_item.h"
28
#include "libmsiecf_io_handle.h"
29
#include "libmsiecf_leak_values.h"
30
#include "libmsiecf_libcerror.h"
31
#include "libmsiecf_libcthreads.h"
32
#include "libmsiecf_redirected_values.h"
33
#include "libmsiecf_url_values.h"
34
35
/* Creates an item
36
 * Make sure the value item is referencing, is set to NULL
37
 * Returns 1 if successful or -1 on error
38
 */
39
int libmsiecf_item_initialize(
40
     libmsiecf_item_t **item,
41
     libmsiecf_item_descriptor_t *item_descriptor,
42
     libcerror_error_t **error )
43
0
{
44
0
  libmsiecf_internal_item_t *internal_item = NULL;
45
0
  static char *function                    = "libmsiecf_item_initialize";
46
47
0
  if( item == 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 item.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
0
  if( *item != 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 item value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
0
  if( item_descriptor == 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 item descriptor.",
76
0
     function );
77
78
0
    return( -1 );
79
0
  }
80
0
  internal_item = memory_allocate_structure(
81
0
                   libmsiecf_internal_item_t );
82
83
0
  if( internal_item == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
88
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
89
0
     "%s: unable to create internal item.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
0
  if( memory_set(
95
0
       internal_item,
96
0
       0,
97
0
       sizeof( libmsiecf_internal_item_t ) ) == NULL )
98
0
  {
99
0
    libcerror_error_set(
100
0
     error,
101
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
102
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
103
0
     "%s: unable to clear internal item.",
104
0
     function );
105
106
0
    memory_free(
107
0
     internal_item );
108
109
0
    return( -1 );
110
0
  }
111
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
112
0
  if( libcthreads_read_write_lock_initialize(
113
0
       &( internal_item->read_write_lock ),
114
0
       error ) != 1 )
115
0
  {
116
0
    libcerror_error_set(
117
0
     error,
118
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
119
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
120
0
     "%s: unable to initialize read/write lock.",
121
0
     function );
122
123
0
    goto on_error;
124
0
  }
125
0
#endif
126
0
  internal_item->item_descriptor = item_descriptor;
127
128
0
  *item = (libmsiecf_item_t *) internal_item;
129
130
0
  return( 1 );
131
132
0
on_error:
133
0
  if( internal_item != NULL )
134
0
  {
135
0
    memory_free(
136
0
     internal_item );
137
0
  }
138
0
  return( -1 );
139
0
}
140
141
/* Frees an item
142
 * Returns 1 if successful or -1 on error
143
 */
144
int libmsiecf_item_free(
145
     libmsiecf_item_t **item,
146
     libcerror_error_t **error )
147
0
{
148
0
  libmsiecf_internal_item_t *internal_item = NULL;
149
0
  static char *function                    = "libmsiecf_item_free";
150
0
  int result                               = 1;
151
152
0
  if( item == NULL )
153
0
  {
154
0
    libcerror_error_set(
155
0
     error,
156
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
158
0
     "%s: invalid item.",
159
0
     function );
160
161
0
    return( -1 );
162
0
  }
163
0
  if( *item != NULL )
164
0
  {
165
0
    internal_item = (libmsiecf_internal_item_t *) *item;
166
0
    *item         = NULL;
167
168
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
169
0
    if( libcthreads_read_write_lock_free(
170
0
         &( internal_item->read_write_lock ),
171
0
         error ) != 1 )
172
0
    {
173
0
      libcerror_error_set(
174
0
       error,
175
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
176
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
177
0
       "%s: unable to free read/write lock.",
178
0
       function );
179
180
0
      result = -1;
181
0
    }
182
0
#endif
183
                /* The item_descriptor reference is freed elsewhere
184
     */
185
0
    if( internal_item->value != NULL )
186
0
    {
187
0
      if( internal_item->free_value != NULL )
188
0
      {
189
0
        if( internal_item->free_value(
190
0
             &( internal_item->value ),
191
0
             error ) != 1 )
192
0
        {
193
0
          libcerror_error_set(
194
0
           error,
195
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
196
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
197
0
           "%s: unable to free item value.",
198
0
           function );
199
200
0
          result = -1;
201
0
        }
202
0
      }
203
0
    }
204
0
    memory_free(
205
0
     internal_item );
206
0
  }
207
0
  return( result );
208
0
}
209
210
/* Retrieves the type
211
 * Determines the item type if neccessary
212
 * Returns 1 if successful or -1 on error
213
 */
214
int libmsiecf_item_get_type(
215
     libmsiecf_item_t *item,
216
     uint8_t *item_type,
217
     libcerror_error_t **error )
218
0
{
219
0
  libmsiecf_internal_item_t *internal_item = NULL;
220
0
  static char *function                    = "libmsiecf_item_get_type";
221
222
0
  if( item == NULL )
223
0
  {
224
0
    libcerror_error_set(
225
0
     error,
226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
227
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
228
0
     "%s: invalid item.",
229
0
     function );
230
231
0
    return( -1 );
232
0
  }
233
0
  internal_item = (libmsiecf_internal_item_t *) item;
234
235
0
  if( internal_item->item_descriptor == NULL )
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
240
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
241
0
     "%s: invalid item - missing item descriptor.",
242
0
     function );
243
244
0
    return( -1 );
245
0
  }
246
0
  if( item_type == NULL )
247
0
  {
248
0
    libcerror_error_set(
249
0
     error,
250
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
251
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
252
0
     "%s: invalid item type.",
253
0
     function );
254
255
0
    return( -1 );
256
0
  }
257
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
258
0
  if( libcthreads_read_write_lock_grab_for_read(
259
0
       internal_item->read_write_lock,
260
0
       error ) != 1 )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
265
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
266
0
     "%s: unable to grab read/write lock for reading.",
267
0
     function );
268
269
0
    return( -1 );
270
0
  }
271
0
#endif
272
0
  *item_type = internal_item->item_descriptor->type;
273
274
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
275
0
  if( libcthreads_read_write_lock_release_for_read(
276
0
       internal_item->read_write_lock,
277
0
       error ) != 1 )
278
0
  {
279
0
    libcerror_error_set(
280
0
     error,
281
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
282
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
283
0
     "%s: unable to release read/write lock for reading.",
284
0
     function );
285
286
0
    return( -1 );
287
0
  }
288
0
#endif
289
0
  return( 1 );
290
0
}
291
292
/* Retrieves the flags
293
 * Returns 1 if successful or -1 on error
294
 */
295
int libmsiecf_item_get_flags(
296
     libmsiecf_item_t *item,
297
     uint8_t *item_flags,
298
     libcerror_error_t **error )
299
0
{
300
0
  libmsiecf_internal_item_t *internal_item = NULL;
301
0
  static char *function                    = "libmsiecf_item_get_flags";
302
303
0
  if( item == NULL )
304
0
  {
305
0
    libcerror_error_set(
306
0
     error,
307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
309
0
     "%s: invalid item.",
310
0
     function );
311
312
0
    return( -1 );
313
0
  }
314
0
  internal_item = (libmsiecf_internal_item_t *) item;
315
316
0
  if( internal_item->item_descriptor == NULL )
317
0
  {
318
0
    libcerror_error_set(
319
0
     error,
320
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
321
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
322
0
     "%s: invalid item - missing item descriptor.",
323
0
     function );
324
325
0
    return( -1 );
326
0
  }
327
0
  if( item_flags == NULL )
328
0
  {
329
0
    libcerror_error_set(
330
0
     error,
331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
333
0
     "%s: invalid item flags.",
334
0
     function );
335
336
0
    return( -1 );
337
0
  }
338
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
339
0
  if( libcthreads_read_write_lock_grab_for_read(
340
0
       internal_item->read_write_lock,
341
0
       error ) != 1 )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
346
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
347
0
     "%s: unable to grab read/write lock for reading.",
348
0
     function );
349
350
0
    return( -1 );
351
0
  }
352
0
#endif
353
0
  *item_flags = internal_item->item_descriptor->flags;
354
355
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
356
0
  if( libcthreads_read_write_lock_release_for_read(
357
0
       internal_item->read_write_lock,
358
0
       error ) != 1 )
359
0
  {
360
0
    libcerror_error_set(
361
0
     error,
362
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
363
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
364
0
     "%s: unable to release read/write lock for reading.",
365
0
     function );
366
367
0
    return( -1 );
368
0
  }
369
0
#endif
370
0
  return( 1 );
371
0
}
372
373
/* Retrieves the offset
374
 * Returns 1 if successful or -1 on error
375
 */
376
int libmsiecf_item_get_offset(
377
     libmsiecf_item_t *item,
378
     off64_t *offset,
379
     libcerror_error_t **error )
380
0
{
381
0
  libmsiecf_internal_item_t *internal_item = NULL;
382
0
  static char *function                    = "libmsiecf_item_get_offset";
383
384
0
  if( item == NULL )
385
0
  {
386
0
    libcerror_error_set(
387
0
     error,
388
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
389
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
390
0
     "%s: invalid item.",
391
0
     function );
392
393
0
    return( -1 );
394
0
  }
395
0
  internal_item = (libmsiecf_internal_item_t *) item;
396
397
0
  if( internal_item->item_descriptor == NULL )
398
0
  {
399
0
    libcerror_error_set(
400
0
     error,
401
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
402
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
403
0
     "%s: invalid item - missing item descriptor.",
404
0
     function );
405
406
0
    return( -1 );
407
0
  }
408
0
  if( offset == NULL )
409
0
  {
410
0
    libcerror_error_set(
411
0
     error,
412
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
413
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
414
0
     "%s: invalid offset.",
415
0
     function );
416
417
0
    return( -1 );
418
0
  }
419
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
420
0
  if( libcthreads_read_write_lock_grab_for_read(
421
0
       internal_item->read_write_lock,
422
0
       error ) != 1 )
423
0
  {
424
0
    libcerror_error_set(
425
0
     error,
426
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
427
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
428
0
     "%s: unable to grab read/write lock for reading.",
429
0
     function );
430
431
0
    return( -1 );
432
0
  }
433
0
#endif
434
0
  *offset = internal_item->item_descriptor->file_offset;
435
436
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
437
0
  if( libcthreads_read_write_lock_release_for_read(
438
0
       internal_item->read_write_lock,
439
0
       error ) != 1 )
440
0
  {
441
0
    libcerror_error_set(
442
0
     error,
443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
445
0
     "%s: unable to release read/write lock for reading.",
446
0
     function );
447
448
0
    return( -1 );
449
0
  }
450
0
#endif
451
0
  return( 1 );
452
0
}
453
454
/* Retrieves the offset range
455
 * Returns 1 if successful or -1 on error
456
 */
457
int libmsiecf_item_get_offset_range(
458
     libmsiecf_item_t *item,
459
     off64_t *offset,
460
     size64_t *size,
461
     libcerror_error_t **error )
462
0
{
463
0
  libmsiecf_internal_item_t *internal_item = NULL;
464
0
  static char *function                    = "libmsiecf_item_get_offset_range";
465
466
0
  if( item == NULL )
467
0
  {
468
0
    libcerror_error_set(
469
0
     error,
470
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
471
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
472
0
     "%s: invalid item.",
473
0
     function );
474
475
0
    return( -1 );
476
0
  }
477
0
  internal_item = (libmsiecf_internal_item_t *) item;
478
479
0
  if( internal_item->item_descriptor == NULL )
480
0
  {
481
0
    libcerror_error_set(
482
0
     error,
483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
484
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
485
0
     "%s: invalid item - missing item descriptor.",
486
0
     function );
487
488
0
    return( -1 );
489
0
  }
490
0
  if( offset == 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 offset.",
497
0
     function );
498
499
0
    return( -1 );
500
0
  }
501
0
  if( size == NULL )
502
0
  {
503
0
    libcerror_error_set(
504
0
     error,
505
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
506
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
507
0
     "%s: invalid size.",
508
0
     function );
509
510
0
    return( -1 );
511
0
  }
512
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
513
0
  if( libcthreads_read_write_lock_grab_for_read(
514
0
       internal_item->read_write_lock,
515
0
       error ) != 1 )
516
0
  {
517
0
    libcerror_error_set(
518
0
     error,
519
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
520
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
521
0
     "%s: unable to grab read/write lock for reading.",
522
0
     function );
523
524
0
    return( -1 );
525
0
  }
526
0
#endif
527
0
  *offset = internal_item->item_descriptor->file_offset;
528
0
  *size   = (size64_t) internal_item->item_descriptor->record_size;
529
530
0
#if defined( HAVE_LIBMSIECF_MULTI_THREAD_SUPPORT )
531
0
  if( libcthreads_read_write_lock_release_for_read(
532
0
       internal_item->read_write_lock,
533
0
       error ) != 1 )
534
0
  {
535
0
    libcerror_error_set(
536
0
     error,
537
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
538
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
539
0
     "%s: unable to release read/write lock for reading.",
540
0
     function );
541
542
0
    return( -1 );
543
0
  }
544
0
#endif
545
0
  return( 1 );
546
0
}
547
548
/* Reads the item values
549
 * Returns 1 if successful or -1 on error
550
 */
551
int libmsiecf_internal_item_read_values(
552
     libmsiecf_internal_item_t *internal_item,
553
     libmsiecf_io_handle_t *io_handle,
554
     libbfio_handle_t *file_io_handle,
555
     libcerror_error_t **error )
556
0
{
557
0
  const char *item_type_string = NULL;
558
0
  static char *function        = "libmsiecf_internal_item_read_values";
559
0
  int result                   = 0;
560
561
0
  if( internal_item == NULL )
562
0
  {
563
0
    libcerror_error_set(
564
0
     error,
565
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
566
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
567
0
     "%s: invalid item.",
568
0
     function );
569
570
0
    return( -1 );
571
0
  }
572
0
  if( io_handle == NULL )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
577
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
578
0
     "%s: invalid IO handle.",
579
0
     function );
580
581
0
    return( -1 );
582
0
  }
583
0
  if( internal_item->item_descriptor == NULL )
584
0
  {
585
0
    libcerror_error_set(
586
0
     error,
587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
588
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
589
0
     "%s: invalid item - missing item descriptor.",
590
0
     function );
591
592
0
    return( -1 );
593
0
  }
594
0
  switch( internal_item->item_descriptor->type )
595
0
  {
596
0
    case LIBMSIECF_ITEM_TYPE_LEAK:
597
0
      item_type_string = "leak";
598
599
0
      result = libmsiecf_leak_values_initialize(
600
0
                (libmsiecf_leak_values_t **) &( internal_item->value ),
601
0
                error );
602
603
0
      internal_item->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libmsiecf_leak_values_free;
604
605
0
      break;
606
607
0
    case LIBMSIECF_ITEM_TYPE_REDIRECTED:
608
0
      item_type_string = "redirected";
609
610
0
      result = libmsiecf_redirected_values_initialize(
611
0
                (libmsiecf_redirected_values_t **) &( internal_item->value ),
612
0
                error );
613
614
0
      internal_item->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libmsiecf_redirected_values_free;
615
616
0
      break;
617
618
0
    case LIBMSIECF_ITEM_TYPE_URL:
619
0
      item_type_string = "url";
620
621
0
      result = libmsiecf_url_values_initialize(
622
0
                (libmsiecf_url_values_t **) &( internal_item->value ),
623
0
                error );
624
625
0
      internal_item->free_value = (int (*)(intptr_t **, libcerror_error_t **)) &libmsiecf_url_values_free;
626
627
0
      break;
628
629
0
    default:
630
0
      libcerror_error_set(
631
0
       error,
632
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
633
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
634
0
       "%s: unsupported item type: %" PRIu8 ".",
635
0
       function,
636
0
       internal_item->item_descriptor->type );
637
638
0
      goto on_error;
639
0
  }
640
0
  if( result != 1 )
641
0
  {
642
0
    libcerror_error_set(
643
0
     error,
644
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
645
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
646
0
     "%s: unable to create %s values.",
647
0
     function,
648
0
     item_type_string );
649
650
0
    goto on_error;
651
0
  }
652
0
  switch( internal_item->item_descriptor->type )
653
0
  {
654
0
    case LIBMSIECF_ITEM_TYPE_LEAK:
655
0
      result = libmsiecf_leak_values_read_file_io_handle(
656
0
                (libmsiecf_leak_values_t *) internal_item->value,
657
0
                file_io_handle,
658
0
                internal_item->item_descriptor->file_offset,
659
0
                internal_item->item_descriptor->record_size,
660
0
                io_handle->ascii_codepage,
661
0
                internal_item->item_descriptor->flags,
662
0
                error );
663
0
      break;
664
665
0
    case LIBMSIECF_ITEM_TYPE_REDIRECTED:
666
0
      result = libmsiecf_redirected_values_read_file_io_handle(
667
0
                (libmsiecf_redirected_values_t *) internal_item->value,
668
0
                file_io_handle,
669
0
                internal_item->item_descriptor->file_offset,
670
0
                internal_item->item_descriptor->record_size,
671
0
                io_handle->ascii_codepage,
672
0
                internal_item->item_descriptor->flags,
673
0
                error );
674
0
      break;
675
676
0
    case LIBMSIECF_ITEM_TYPE_URL:
677
0
      result = libmsiecf_url_values_read_file_io_handle(
678
0
                (libmsiecf_url_values_t *) internal_item->value,
679
0
                io_handle,
680
0
                file_io_handle,
681
0
                internal_item->item_descriptor->file_offset,
682
0
                internal_item->item_descriptor->record_size,
683
0
                internal_item->item_descriptor->flags,
684
0
                error );
685
0
      break;
686
0
  }
687
0
  if( result != 1 )
688
0
  {
689
0
    libcerror_error_set(
690
0
     error,
691
0
     LIBCERROR_ERROR_DOMAIN_IO,
692
0
     LIBCERROR_IO_ERROR_READ_FAILED,
693
0
     "%s: unable to read %s values at offset: %" PRIi64 ".",
694
0
     function,
695
0
     item_type_string,
696
0
     internal_item->item_descriptor->file_offset );
697
698
0
    goto on_error;
699
0
  }
700
0
  return( 1 );
701
702
0
on_error:
703
0
  if( internal_item->value != NULL )
704
0
  {
705
0
    if( internal_item->free_value != NULL )
706
0
    {
707
0
      internal_item->free_value(
708
0
       &( internal_item->value ),
709
0
       NULL );
710
0
    }
711
0
    internal_item->free_value = NULL;
712
0
  }
713
0
  return( -1 );
714
0
}
715