Coverage Report

Created: 2026-10-22 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libpff/libpff/libpff_item.c
Line
Count
Source
1
/*
2
 * Item functions
3
 *
4
 * Copyright (C) 2008-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <narrow_string.h>
26
#include <types.h>
27
28
#include "libpff_debug.h"
29
#include "libpff_definitions.h"
30
#include "libpff_descriptor_data_stream.h"
31
#include "libpff_descriptors_index.h"
32
#include "libpff_item_descriptor.h"
33
#include "libpff_item.h"
34
#include "libpff_item_tree.h"
35
#include "libpff_item_values.h"
36
#include "libpff_libbfio.h"
37
#include "libpff_libcdata.h"
38
#include "libpff_libcerror.h"
39
#include "libpff_libcnotify.h"
40
#include "libpff_libfcache.h"
41
#include "libpff_libfdata.h"
42
#include "libpff_libfmapi.h"
43
#include "libpff_mapi.h"
44
#include "libpff_offsets_index.h"
45
#include "libpff_record_entry.h"
46
#include "libpff_table.h"
47
#include "libpff_types.h"
48
#include "libpff_value_type.h"
49
50
/* Creates an item
51
 * Make sure the value item is referencing, is set to NULL
52
 * Returns 1 if successful or -1 on error
53
 */
54
int libpff_item_initialize(
55
     libpff_item_t **item,
56
     libpff_io_handle_t *io_handle,
57
     libbfio_handle_t *file_io_handle,
58
     libcdata_list_t *name_to_id_map_list,
59
     libpff_descriptors_index_t *descriptors_index,
60
     libpff_offsets_index_t *offsets_index,
61
     libpff_item_tree_t *item_tree,
62
     libcdata_tree_node_t *item_tree_node,
63
     uint8_t flags,
64
     libcerror_error_t **error )
65
1.79k
{
66
1.79k
  libpff_internal_item_t *internal_item     = NULL;
67
1.79k
  libpff_item_descriptor_t *item_descriptor = NULL;
68
1.79k
  static char *function                     = "libpff_item_initialize";
69
70
1.79k
  if( item == NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
75
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
76
0
     "%s: invalid item.",
77
0
     function );
78
79
0
    return( -1 );
80
0
  }
81
1.79k
  if( *item != NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
86
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
87
0
     "%s: invalid item value already set.",
88
0
     function );
89
90
0
    return( -1 );
91
0
  }
92
1.79k
  if( io_handle == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
97
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
98
0
     "%s: invalid IO handle.",
99
0
     function );
100
101
0
    return( -1 );
102
0
  }
103
1.79k
  if( ( flags & ~( LIBPFF_ITEM_FLAG_MANAGED_ITEM_TREE_NODE ) ) != 0 )
104
0
  {
105
0
    libcerror_error_set(
106
0
     error,
107
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
108
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
109
0
     "%s: unsupported flags: 0x%02" PRIx8 ".",
110
0
     function,
111
0
     flags );
112
113
0
    return( -1 );
114
0
  }
115
1.79k
  if( libcdata_tree_node_get_value(
116
1.79k
       item_tree_node,
117
1.79k
       (intptr_t **) &item_descriptor,
118
1.79k
       error ) != 1 )
119
0
  {
120
0
    libcerror_error_set(
121
0
     error,
122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
123
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
124
0
     "%s: unable to retrieve item descriptor from item tree node.",
125
0
     function );
126
127
0
    return( -1 );
128
0
  }
129
1.79k
  if( item_descriptor == NULL )
130
0
  {
131
0
    libcerror_error_set(
132
0
     error,
133
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
134
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
135
0
     "%s: invalid item descriptor.",
136
0
     function );
137
138
0
    return( -1 );
139
0
  }
140
1.79k
  internal_item = memory_allocate_structure(
141
1.79k
                   libpff_internal_item_t );
142
143
1.79k
  if( internal_item == NULL )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
148
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
149
0
     "%s: unable to create item.",
150
0
     function );
151
152
0
    goto on_error;
153
0
  }
154
1.79k
  if( memory_set(
155
1.79k
       internal_item,
156
1.79k
       0,
157
1.79k
       sizeof( libpff_internal_item_t ) ) == NULL )
158
0
  {
159
0
    libcerror_error_set(
160
0
     error,
161
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
162
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
163
0
     "%s: unable to clear item.",
164
0
     function );
165
166
0
    memory_free(
167
0
     internal_item );
168
169
0
    return( -1 );
170
0
  }
171
1.79k
  if( libpff_item_values_initialize(
172
1.79k
       &( internal_item->item_values ),
173
1.79k
       item_descriptor->descriptor_identifier,
174
1.79k
       item_descriptor->data_identifier,
175
1.79k
       item_descriptor->local_descriptors_identifier,
176
1.79k
       item_descriptor->recovered,
177
1.79k
       error ) != 1 )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
182
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
183
0
     "%s: unable to create item values.",
184
0
     function );
185
186
0
    goto on_error;
187
0
  }
188
1.79k
  if( ( flags & LIBPFF_ITEM_FLAG_MANAGED_ITEM_TREE_NODE ) == 0 )
189
1.79k
  {
190
1.79k
    internal_item->item_tree_node = item_tree_node;
191
1.79k
  }
192
0
  else
193
0
  {
194
0
    if( libcdata_tree_node_clone(
195
0
         &( internal_item->item_tree_node ),
196
0
         item_tree_node,
197
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free,
198
0
         (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_item_descriptor_clone,
199
0
         error ) != 1 )
200
0
    {
201
0
      libcerror_error_set(
202
0
       error,
203
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
205
0
       "%s: unable to copy item tree node.",
206
0
       function );
207
208
0
      goto on_error;
209
0
    }
210
0
  }
211
1.79k
  internal_item->type                = LIBPFF_ITEM_TYPE_UNDEFINED;
212
1.79k
  internal_item->io_handle           = io_handle;
213
1.79k
  internal_item->file_io_handle      = file_io_handle;
214
1.79k
  internal_item->name_to_id_map_list = name_to_id_map_list;
215
1.79k
  internal_item->descriptors_index   = descriptors_index;
216
1.79k
  internal_item->offsets_index       = offsets_index;
217
1.79k
  internal_item->item_tree           = item_tree;
218
1.79k
  internal_item->item_descriptor     = item_descriptor;
219
1.79k
  internal_item->ascii_codepage      = io_handle->ascii_codepage;
220
1.79k
  internal_item->flags               = flags;
221
222
1.79k
  *item = (libpff_item_t *) internal_item;
223
224
1.79k
  return( 1 );
225
226
0
on_error:
227
0
  if( internal_item != NULL )
228
0
  {
229
0
    if( internal_item->item_values != NULL )
230
0
    {
231
0
      libpff_item_values_free(
232
0
       &( internal_item->item_values ),
233
0
       NULL );
234
0
    }
235
0
    memory_free(
236
0
     internal_item );
237
0
  }
238
0
  return( -1 );
239
1.79k
}
240
241
/* Frees an item
242
 * Returns 1 if successful or -1 on error
243
 */
244
int libpff_item_free(
245
     libpff_item_t **item,
246
     libcerror_error_t **error )
247
1.79k
{
248
1.79k
  libpff_internal_item_t *internal_item = NULL;
249
1.79k
  static char *function                 = "libpff_item_free";
250
1.79k
  int result                            = 1;
251
1.79k
  int sub_item_iterator                 = 0;
252
253
1.79k
  if( item == NULL )
254
0
  {
255
0
    libcerror_error_set(
256
0
     error,
257
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
258
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
259
0
     "%s: invalid item.",
260
0
     function );
261
262
0
    return( -1 );
263
0
  }
264
1.79k
  if( *item != NULL )
265
1.79k
  {
266
1.79k
    internal_item = (libpff_internal_item_t *) *item;
267
1.79k
    *item         = NULL;
268
269
    /* The io_handle, file_io_handle, name_to_id_map_list, descriptors_index, offsets_index and item_tree reference is freed elsewhere
270
     */
271
    /* If not managed the item_tree_node reference is freed elsewhere
272
     */
273
1.79k
    if( ( internal_item->flags & LIBPFF_ITEM_FLAG_MANAGED_ITEM_TREE_NODE ) != 0 )
274
0
    {
275
0
      if( internal_item->item_tree_node != NULL )
276
0
      {
277
0
        if( libcdata_tree_node_free(
278
0
             &( internal_item->item_tree_node ),
279
0
             (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free,
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_FINALIZE_FAILED,
286
0
           "%s: unable to free item tree node.",
287
0
           function );
288
289
0
          return( -1 );
290
0
        }
291
0
      }
292
0
    }
293
1.79k
    if( internal_item->item_values != NULL )
294
1.79k
    {
295
1.79k
      if( libpff_item_values_free(
296
1.79k
           &( internal_item->item_values ),
297
1.79k
           error ) != 1 )
298
0
      {
299
0
        libcerror_error_set(
300
0
         error,
301
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
302
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
303
0
         "%s: unable to free item values.",
304
0
         function );
305
306
0
        result = -1;
307
0
      }
308
1.79k
    }
309
1.79k
    for( sub_item_iterator = 0;
310
8.95k
         sub_item_iterator < LIBPFF_ITEM_NUMBER_OF_SUB_ITEMS;
311
7.16k
         sub_item_iterator++ )
312
7.16k
    {
313
7.16k
      if( internal_item->sub_item_tree_node[ sub_item_iterator ] != NULL )
314
0
      {
315
0
        if( libcdata_tree_node_free(
316
0
             &( internal_item->sub_item_tree_node[ sub_item_iterator ] ),
317
0
             (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free,
318
0
             error ) != 1 )
319
0
        {
320
0
          libcerror_error_set(
321
0
           error,
322
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
323
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
324
0
           "%s: unable to free sub item tree node: %d.",
325
0
           function,
326
0
           sub_item_iterator );
327
328
0
          result = -1;
329
0
        }
330
0
      }
331
7.16k
    }
332
1.79k
    for( sub_item_iterator = 0;
333
8.95k
         sub_item_iterator < LIBPFF_ITEM_NUMBER_OF_SUB_ITEMS;
334
7.16k
         sub_item_iterator++ )
335
7.16k
    {
336
7.16k
      if( internal_item->sub_item_values[ sub_item_iterator ] != NULL )
337
0
      {
338
0
        if( libpff_item_values_free(
339
0
             &( internal_item->sub_item_values[ sub_item_iterator ] ),
340
0
             error ) != 1 )
341
0
        {
342
0
          libcerror_error_set(
343
0
           error,
344
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
345
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
346
0
           "%s: unable to free sub item values: %d.",
347
0
           function,
348
0
           sub_item_iterator );
349
350
0
          result = -1;
351
0
        }
352
0
      }
353
7.16k
    }
354
1.79k
    if( internal_item->embedded_object_data_stream != NULL )
355
0
    {
356
0
      if( libfdata_stream_free(
357
0
           &( internal_item->embedded_object_data_stream ),
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_FINALIZE_FAILED,
364
0
         "%s: unable to free embedded object data stream.",
365
0
         function );
366
367
0
        result = -1;
368
0
      }
369
0
    }
370
1.79k
    memory_free(
371
1.79k
     internal_item );
372
1.79k
  }
373
1.79k
  return( result );
374
1.79k
}
375
376
/* Determines the item type
377
 * Returns 1 if successful or -1 on error
378
 */
379
int libpff_internal_item_determine_type(
380
     libpff_internal_item_t *internal_item,
381
     libcerror_error_t **error )
382
0
{
383
0
  libpff_record_entry_t *record_entry = NULL;
384
0
  char *item_type_string              = NULL;
385
0
  static char *function               = "libpff_internal_item_determine_type";
386
0
  size_t item_type_string_size        = 0;
387
0
  uint32_t value_type                 = 0;
388
0
  int result                          = 0;
389
390
0
  if( internal_item == NULL )
391
0
  {
392
0
    libcerror_error_set(
393
0
     error,
394
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396
0
     "%s: invalid item.",
397
0
     function );
398
399
0
    return( -1 );
400
0
  }
401
0
  if( internal_item->type != LIBPFF_ITEM_TYPE_UNDEFINED )
402
0
  {
403
0
    return( 1 );
404
0
  }
405
0
  result = libpff_item_values_get_record_entry_by_type(
406
0
            internal_item->item_values,
407
0
            internal_item->name_to_id_map_list,
408
0
            internal_item->io_handle,
409
0
            internal_item->file_io_handle,
410
0
            internal_item->offsets_index,
411
0
            0,
412
0
            LIBPFF_ENTRY_TYPE_MESSAGE_CLASS,
413
0
            0,
414
0
            &record_entry,
415
0
            LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE,
416
0
            error );
417
418
0
  if( result == -1 )
419
0
  {
420
0
    libcerror_error_set(
421
0
     error,
422
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
423
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
424
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 ".",
425
0
     function,
426
0
     LIBPFF_ENTRY_TYPE_MESSAGE_CLASS );
427
428
0
    goto on_error;
429
0
  }
430
0
  else if( result == 0 )
431
0
  {
432
    /* The item does not contain a message class and therefore is a folder
433
     */
434
0
    internal_item->type = LIBPFF_ITEM_TYPE_FOLDER;
435
0
  }
436
0
  else
437
0
  {
438
0
    if( libpff_record_entry_get_value_type(
439
0
         record_entry,
440
0
         &value_type,
441
0
         error ) != 1 )
442
0
    {
443
0
      libcerror_error_set(
444
0
       error,
445
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
446
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
447
0
       "%s: unable to retrieve value type.",
448
0
       function );
449
450
0
      goto on_error;
451
0
    }
452
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
453
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
454
0
    {
455
0
      libcerror_error_set(
456
0
       error,
457
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
458
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
459
0
       "%s: unsupported value type: 0x%04" PRIx32 ".",
460
0
       function,
461
0
       value_type );
462
463
0
      goto on_error;
464
0
    }
465
0
    if( libpff_record_entry_get_data_as_utf8_string_size_with_codepage(
466
0
         record_entry,
467
0
         internal_item->ascii_codepage,
468
0
         &item_type_string_size,
469
0
         error ) != 1 )
470
0
    {
471
0
      libcerror_error_set(
472
0
       error,
473
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
474
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
475
0
       "%s: unable to retrieve UTF-8 string size.",
476
0
       function );
477
478
0
      goto on_error;
479
0
    }
480
0
    if( item_type_string_size > 0 )
481
0
    {
482
0
      item_type_string = narrow_string_allocate(
483
0
                          item_type_string_size );
484
485
0
      if( item_type_string == NULL )
486
0
      {
487
0
        libcerror_error_set(
488
0
         error,
489
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
490
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
491
0
         "%s: unable to create item type string.",
492
0
         function );
493
494
0
        goto on_error;
495
0
      }
496
0
      if( libpff_record_entry_get_data_as_utf8_string_with_codepage(
497
0
           record_entry,
498
0
           internal_item->ascii_codepage,
499
0
           (uint8_t *) item_type_string,
500
0
           item_type_string_size,
501
0
           error ) != 1 )
502
0
      {
503
0
        libcerror_error_set(
504
0
         error,
505
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
507
0
         "%s: unable to retrieve UTF-8 string of record entry.",
508
0
         function );
509
510
0
        goto on_error;
511
0
      }
512
0
      if( item_type_string_size == 4 )
513
0
      {
514
0
        if( narrow_string_compare_no_case(
515
0
             item_type_string,
516
0
             "IPM",
517
0
             3 ) == 0 )
518
0
        {
519
0
          internal_item->type = LIBPFF_ITEM_TYPE_COMMON;
520
0
        }
521
0
      }
522
0
      else if( item_type_string_size == 8 )
523
0
      {
524
0
        if( narrow_string_compare_no_case(
525
0
             item_type_string,
526
0
             "IPM.FAX",
527
0
             7 ) == 0 )
528
0
        {
529
0
          internal_item->type = LIBPFF_ITEM_TYPE_FAX;
530
0
        }
531
0
      }
532
0
      else if( item_type_string_size == 9 )
533
0
      {
534
0
        if( narrow_string_compare_no_case(
535
0
             item_type_string,
536
0
             "IPM.Note",
537
0
             8 ) == 0 )
538
0
        {
539
0
          internal_item->type = LIBPFF_ITEM_TYPE_EMAIL;
540
0
        }
541
0
        else if( narrow_string_compare_no_case(
542
0
            item_type_string,
543
0
            "IPM.Post",
544
0
            8 ) == 0 )
545
0
        {
546
0
          internal_item->type = LIBPFF_ITEM_TYPE_POSTING_NOTE;
547
0
        }
548
0
        else if( narrow_string_compare_no_case(
549
0
            item_type_string,
550
0
            "IPM.Task",
551
0
            8 ) == 0 )
552
0
        {
553
0
          internal_item->type = LIBPFF_ITEM_TYPE_TASK;
554
0
        }
555
0
      }
556
0
      else if( item_type_string_size == 12 )
557
0
      {
558
0
        if( narrow_string_compare_no_case(
559
0
             item_type_string,
560
0
             "IPM.Contact",
561
0
             11 ) == 0 )
562
0
        {
563
0
          internal_item->type = LIBPFF_ITEM_TYPE_CONTACT;
564
0
        }
565
0
      }
566
0
      else if( item_type_string_size == 13 )
567
0
      {
568
0
        if( narrow_string_compare_no_case(
569
0
             item_type_string,
570
0
             "IPM.Activity",
571
0
             12 ) == 0 )
572
0
        {
573
0
          internal_item->type = LIBPFF_ITEM_TYPE_ACTIVITY;
574
0
        }
575
0
        else if( narrow_string_compare_no_case(
576
0
            item_type_string,
577
0
            "IPM.DistList",
578
0
            12 ) == 0 )
579
0
        {
580
0
          internal_item->type = LIBPFF_ITEM_TYPE_DISTRIBUTION_LIST;
581
0
        }
582
0
        else if( narrow_string_compare_no_case(
583
0
            item_type_string,
584
0
            "IPM.Note.Fax",
585
0
            12 ) == 0 )
586
0
        {
587
0
          internal_item->type = LIBPFF_ITEM_TYPE_FAX;
588
0
        }
589
0
        else if( narrow_string_compare_no_case(
590
0
            item_type_string,
591
0
            "IPM.Post.RSS",
592
0
            12 ) == 0 )
593
0
        {
594
0
          internal_item->type = LIBPFF_ITEM_TYPE_RSS_FEED;
595
0
        }
596
0
      }
597
0
      else if( item_type_string_size == 15 )
598
0
      {
599
0
        if( narrow_string_compare_no_case(
600
0
             item_type_string,
601
0
             "IPM.StickyNote",
602
0
             15 ) == 0 )
603
0
        {
604
0
          internal_item->type = LIBPFF_ITEM_TYPE_NOTE;
605
0
        }
606
0
      }
607
0
      else if( item_type_string_size == 16 )
608
0
      {
609
0
        if( narrow_string_compare_no_case(
610
0
             item_type_string,
611
0
             "IPM.Appointment",
612
0
             15 ) == 0 )
613
0
        {
614
0
          internal_item->type = LIBPFF_ITEM_TYPE_APPOINTMENT;
615
0
        }
616
0
      }
617
0
      else if( item_type_string_size == 19 )
618
0
      {
619
0
        if( narrow_string_compare_no_case(
620
0
             item_type_string,
621
0
             "IPM.Note.Voicemail",
622
0
             18 ) == 0 )
623
0
        {
624
0
          internal_item->type = LIBPFF_ITEM_TYPE_VOICEMAIL;
625
0
        }
626
0
      }
627
0
      else if( item_type_string_size == 20 )
628
0
      {
629
0
        if( narrow_string_compare_no_case(
630
0
             item_type_string,
631
0
             "IPM.Note.Mobile.SMS",
632
0
             19 ) == 0 )
633
0
        {
634
0
          internal_item->type = LIBPFF_ITEM_TYPE_SMS;
635
0
        }
636
0
        else if( narrow_string_compare_no_case(
637
0
            item_type_string,
638
0
            "IPM.Note.Mobile.MMS",
639
0
            19 ) == 0 )
640
0
        {
641
0
          internal_item->type = LIBPFF_ITEM_TYPE_MMS;
642
0
        }
643
0
      }
644
0
      else if( item_type_string_size == 21 )
645
0
      {
646
0
        if( narrow_string_compare_no_case(
647
0
             item_type_string,
648
0
             "IPM.Conflict.Message",
649
0
             20 ) == 0 )
650
0
        {
651
0
          internal_item->type = LIBPFF_ITEM_TYPE_CONFLICT_MESSAGE;
652
0
        }
653
0
      }
654
0
      else if( item_type_string_size == 53 )
655
0
      {
656
0
        if( narrow_string_compare_no_case(
657
0
             item_type_string,
658
0
             "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}",
659
0
             52 ) == 0 )
660
0
        {
661
0
          internal_item->type = LIBPFF_ITEM_TYPE_APPOINTMENT;
662
0
        }
663
0
      }
664
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
665
0
      {
666
0
        if( item_type_string_size >= 12 )
667
0
        {
668
0
          if( narrow_string_compare_no_case(
669
0
               item_type_string,
670
0
               "IPM.Sharing",
671
0
               11 ) == 0 )
672
0
          {
673
0
            internal_item->type = LIBPFF_ITEM_TYPE_SHARING;
674
0
          }
675
0
        }
676
0
      }
677
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
678
0
      {
679
0
        if( item_type_string_size >= 13 )
680
0
        {
681
0
          if( narrow_string_compare_no_case(
682
0
               item_type_string,
683
0
               "IPM.Document",
684
0
               12 ) == 0 )
685
0
          {
686
0
            internal_item->type = LIBPFF_ITEM_TYPE_DOCUMENT;
687
0
          }
688
0
        }
689
0
      }
690
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
691
0
      {
692
0
        if( item_type_string_size >= 15 )
693
0
        {
694
0
          if( narrow_string_compare_no_case(
695
0
               item_type_string,
696
0
               "IPM.Note.SMIME",
697
0
               14 ) == 0 )
698
0
          {
699
0
            internal_item->type = LIBPFF_ITEM_TYPE_EMAIL_SMIME;
700
0
          }
701
0
        }
702
0
      }
703
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
704
0
      {
705
0
        if( item_type_string_size >= 16 )
706
0
        {
707
0
          if( narrow_string_compare_no_case(
708
0
               item_type_string,
709
0
               "IPM.TaskRequest",
710
0
               15 ) == 0 )
711
0
          {
712
0
            internal_item->type = LIBPFF_ITEM_TYPE_TASK_REQUEST;
713
0
          }
714
0
          else if( narrow_string_compare_no_case(
715
0
              item_type_string,
716
0
              "REPORT.IPM.Note",
717
0
              15 ) == 0 )
718
0
          {
719
0
            internal_item->type = LIBPFF_ITEM_TYPE_EMAIL;
720
0
          }
721
0
        }
722
0
      }
723
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
724
0
      {
725
0
        if( item_type_string_size >= 18 )
726
0
        {
727
0
          if( narrow_string_compare_no_case(
728
0
               item_type_string,
729
0
               "IPM.Configuration",
730
0
               17 ) == 0 )
731
0
          {
732
0
            internal_item->type = LIBPFF_ITEM_TYPE_CONFIGURATION;
733
0
          }
734
0
        }
735
0
      }
736
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
737
0
      {
738
0
        if( item_type_string_size >= 21 )
739
0
        {
740
0
          if( narrow_string_compare_no_case(
741
0
               item_type_string,
742
0
               "IPM.Schedule.Meeting",
743
0
               20 ) == 0 )
744
0
          {
745
0
            internal_item->type = LIBPFF_ITEM_TYPE_MEETING;
746
0
          }
747
0
        }
748
0
      }
749
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
750
0
      {
751
0
        if( item_type_string_size >= 28 )
752
0
        {
753
0
          if( narrow_string_compare_no_case(
754
0
               item_type_string,
755
0
               "REPORT.IPM.Schedule.Meeting",
756
0
               27 ) == 0 )
757
0
          {
758
0
            internal_item->type = LIBPFF_ITEM_TYPE_MEETING;
759
0
          }
760
0
        }
761
0
      }
762
0
      if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
763
0
      {
764
        /* Consider any remaining IPM.Note as an e-mail
765
         * should catch IPM.Note.StorageQuotaWarning
766
         */
767
0
        if( item_type_string_size >= 10 )
768
0
        {
769
0
          if( narrow_string_compare_no_case(
770
0
               item_type_string,
771
0
               "IPM.Note.",
772
0
               9 ) == 0 )
773
0
          {
774
0
            internal_item->type = LIBPFF_ITEM_TYPE_EMAIL;
775
0
          }
776
0
        }
777
0
      }
778
#if defined( HAVE_DEBUG_OUTPUT )
779
      if( ( libcnotify_verbose != 0 )
780
       && ( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED ) )
781
      {
782
        libcnotify_printf(
783
         "%s: unsupported item type: %s\n",
784
         function,
785
         item_type_string );
786
      }
787
#endif
788
0
      memory_free(
789
0
       item_type_string );
790
0
    }
791
0
  }
792
0
  return( 1 );
793
794
0
on_error:
795
0
  if( item_type_string != NULL )
796
0
  {
797
0
    memory_free(
798
0
     item_type_string );
799
0
  }
800
0
  return( -1 );
801
0
}
802
803
/* Retrieves the identifier
804
 * Returns 1 if successful or -1 on error
805
 */
806
int libpff_item_get_identifier(
807
     libpff_item_t *item,
808
     uint32_t *identifier,
809
     libcerror_error_t **error )
810
0
{
811
0
  libpff_internal_item_t *internal_item = NULL;
812
0
  static char *function                 = "libpff_item_get_identifier";
813
814
0
  if( item == NULL )
815
0
  {
816
0
    libcerror_error_set(
817
0
     error,
818
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
819
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
820
0
     "%s: invalid item.",
821
0
     function );
822
823
0
    return( -1 );
824
0
  }
825
0
  internal_item = (libpff_internal_item_t *) item;
826
827
0
  if( libpff_item_descriptor_get_descriptor_identifier(
828
0
       internal_item->item_descriptor,
829
0
       identifier,
830
0
       error ) != 1 )
831
0
  {
832
0
    libcerror_error_set(
833
0
     error,
834
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
835
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
836
0
     "%s: unable to retrieve descriptor identifier.",
837
0
     function );
838
839
0
    return( -1 );
840
0
  }
841
0
  return( 1 );
842
0
}
843
844
/* Retrieves the number of record sets
845
 * Returns 1 if successful or -1 on error
846
 */
847
int libpff_item_get_number_of_record_sets(
848
     libpff_item_t *item,
849
     int *number_of_record_sets,
850
     libcerror_error_t **error )
851
1.71k
{
852
1.71k
  libpff_internal_item_t *internal_item = NULL;
853
1.71k
  static char *function                 = "libpff_item_get_number_of_record_sets";
854
855
1.71k
  if( item == NULL )
856
0
  {
857
0
    libcerror_error_set(
858
0
     error,
859
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
860
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
861
0
     "%s: invalid item.",
862
0
     function );
863
864
0
    return( -1 );
865
0
  }
866
1.71k
  internal_item = (libpff_internal_item_t *) item;
867
868
1.71k
  if( internal_item->item_values == NULL )
869
0
  {
870
0
    libcerror_error_set(
871
0
     error,
872
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
873
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
874
0
     "%s: invalid item - missing item values.",
875
0
     function );
876
877
0
    return( -1 );
878
0
  }
879
1.71k
  if( internal_item->item_values->table == NULL )
880
1.71k
  {
881
1.71k
    if( libpff_item_values_read(
882
1.71k
         internal_item->item_values,
883
1.71k
         internal_item->name_to_id_map_list,
884
1.71k
         internal_item->io_handle,
885
1.71k
         internal_item->file_io_handle,
886
1.71k
         internal_item->offsets_index,
887
1.71k
         LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
888
1.71k
         error ) != 1 )
889
1.56k
    {
890
1.56k
      libcerror_error_set(
891
1.56k
       error,
892
1.56k
       LIBCERROR_ERROR_DOMAIN_IO,
893
1.56k
       LIBCERROR_IO_ERROR_READ_FAILED,
894
1.56k
       "%s: unable to read item values.",
895
1.56k
       function );
896
897
1.56k
      return( -1 );
898
1.56k
    }
899
144
    if( internal_item->item_values->table == NULL )
900
0
    {
901
0
      libcerror_error_set(
902
0
       error,
903
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
904
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
905
0
       "%s: invalid item - invalid item values - missing table.",
906
0
       function );
907
908
0
      return( -1 );
909
0
    }
910
144
  }
911
144
  if( libpff_table_get_number_of_record_sets(
912
144
       internal_item->item_values->table,
913
144
       number_of_record_sets,
914
144
       error ) != 1 )
915
0
  {
916
0
    libcerror_error_set(
917
0
     error,
918
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
919
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
920
0
     "%s: unable to retrieve number of record sets.",
921
0
     function );
922
923
0
    return( -1 );
924
0
  }
925
144
  return( 1 );
926
144
}
927
928
/* Retrieves a specific record set
929
 * Returns 1 if successful or -1 on error
930
 */
931
int libpff_item_get_record_set_by_index(
932
     libpff_item_t *item,
933
     int record_set_index,
934
     libpff_record_set_t **record_set,
935
     libcerror_error_t **error )
936
138
{
937
138
  libpff_internal_item_t *internal_item = NULL;
938
138
  static char *function                 = "libpff_item_get_record_set_by_index";
939
940
138
  if( item == NULL )
941
0
  {
942
0
    libcerror_error_set(
943
0
     error,
944
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
945
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
946
0
     "%s: invalid item.",
947
0
     function );
948
949
0
    return( -1 );
950
0
  }
951
138
  internal_item = (libpff_internal_item_t *) item;
952
953
138
  if( internal_item->item_values == NULL )
954
0
  {
955
0
    libcerror_error_set(
956
0
     error,
957
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
958
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
959
0
     "%s: invalid item - missing item values.",
960
0
     function );
961
962
0
    return( -1 );
963
0
  }
964
138
  if( record_set == NULL )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
969
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
970
0
     "%s: invalid record set.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
138
  if( *record_set != NULL )
976
0
  {
977
0
    libcerror_error_set(
978
0
     error,
979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
980
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
981
0
     "%s: record set already set.",
982
0
     function );
983
984
0
    return( -1 );
985
0
  }
986
138
  if( internal_item->item_values->table == NULL )
987
0
  {
988
0
    if( libpff_item_values_read(
989
0
         internal_item->item_values,
990
0
         internal_item->name_to_id_map_list,
991
0
         internal_item->io_handle,
992
0
         internal_item->file_io_handle,
993
0
         internal_item->offsets_index,
994
0
         LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
995
0
         error ) != 1 )
996
0
    {
997
0
      libcerror_error_set(
998
0
       error,
999
0
       LIBCERROR_ERROR_DOMAIN_IO,
1000
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1001
0
       "%s: unable to read item values.",
1002
0
       function );
1003
1004
0
      return( -1 );
1005
0
    }
1006
0
    if( internal_item->item_values->table == NULL )
1007
0
    {
1008
0
      libcerror_error_set(
1009
0
       error,
1010
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1011
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1012
0
       "%s: invalid item - invalid item values - missing table.",
1013
0
       function );
1014
1015
0
      return( -1 );
1016
0
    }
1017
0
  }
1018
138
  if( libpff_table_get_record_set_by_index(
1019
138
       internal_item->item_values->table,
1020
138
       record_set_index,
1021
138
       record_set,
1022
138
       error ) != 1 )
1023
0
  {
1024
0
    libcerror_error_set(
1025
0
     error,
1026
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1027
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1028
0
     "%s: unable to retrieve record set: %d.",
1029
0
     function,
1030
0
     record_set_index );
1031
1032
0
    return( -1 );
1033
0
  }
1034
138
  return( 1 );
1035
138
}
1036
1037
/* Retrieves the number of entries (of a set)
1038
 * All sets in an item contain the same number of entries
1039
 * Returns 1 if successful or -1 on error
1040
 */
1041
int libpff_item_get_number_of_entries(
1042
     libpff_item_t *item,
1043
     uint32_t *number_of_entries,
1044
     libcerror_error_t **error )
1045
0
{
1046
0
  libpff_internal_item_t *internal_item = NULL;
1047
0
  static char *function                 = "libpff_item_get_number_of_entries";
1048
0
  int table_number_of_entries           = 0;
1049
1050
0
  if( item == NULL )
1051
0
  {
1052
0
    libcerror_error_set(
1053
0
     error,
1054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1055
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1056
0
     "%s: invalid item.",
1057
0
     function );
1058
1059
0
    return( -1 );
1060
0
  }
1061
0
  internal_item = (libpff_internal_item_t *) item;
1062
1063
0
  if( internal_item->item_values == NULL )
1064
0
  {
1065
0
    libcerror_error_set(
1066
0
     error,
1067
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1068
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1069
0
     "%s: invalid item - missing item values.",
1070
0
     function );
1071
1072
0
    return( -1 );
1073
0
  }
1074
0
  if( number_of_entries == NULL )
1075
0
  {
1076
0
    libcerror_error_set(
1077
0
     error,
1078
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1079
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1080
0
     "%s: invalid number of entries.",
1081
0
     function );
1082
1083
0
    return( -1 );
1084
0
  }
1085
0
  if( internal_item->item_values->table == NULL )
1086
0
  {
1087
0
    if( libpff_item_values_read(
1088
0
         internal_item->item_values,
1089
0
         internal_item->name_to_id_map_list,
1090
0
         internal_item->io_handle,
1091
0
         internal_item->file_io_handle,
1092
0
         internal_item->offsets_index,
1093
0
         LIBPFF_DEBUG_ITEM_TYPE_DEFAULT,
1094
0
         error ) != 1 )
1095
0
    {
1096
0
      libcerror_error_set(
1097
0
       error,
1098
0
       LIBCERROR_ERROR_DOMAIN_IO,
1099
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1100
0
       "%s: unable to read item values.",
1101
0
       function );
1102
1103
0
      return( -1 );
1104
0
    }
1105
0
    if( internal_item->item_values->table == NULL )
1106
0
    {
1107
0
      libcerror_error_set(
1108
0
       error,
1109
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1110
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1111
0
       "%s: invalid item - invalid item values - missing table.",
1112
0
       function );
1113
1114
0
      return( -1 );
1115
0
    }
1116
0
  }
1117
0
  if( libpff_table_get_number_of_entries(
1118
0
       internal_item->item_values->table,
1119
0
       &table_number_of_entries,
1120
0
       error ) != 1 )
1121
0
  {
1122
0
    libcerror_error_set(
1123
0
     error,
1124
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1125
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1126
0
     "%s: unable to retrieve number of entries.",
1127
0
     function );
1128
1129
0
    return( -1 );
1130
0
  }
1131
0
  *number_of_entries = (uint32_t) table_number_of_entries;
1132
1133
0
  return( 1 );
1134
0
}
1135
1136
/* Retrieves a 32-bit integer value
1137
 * Returns 1 if successful, 0 if not available or -1 on error
1138
 */
1139
int libpff_internal_item_get_entry_value_32bit_integer(
1140
     libpff_internal_item_t *internal_item,
1141
     uint32_t entry_type,
1142
     uint32_t *value_32bit,
1143
     libcerror_error_t **error )
1144
0
{
1145
0
  libpff_record_entry_t *record_entry = NULL;
1146
0
  static char *function               = "libpff_internal_item_get_entry_value_32bit_integer";
1147
0
  int result                          = 0;
1148
1149
0
  if( internal_item == NULL )
1150
0
  {
1151
0
    libcerror_error_set(
1152
0
     error,
1153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1155
0
     "%s: invalid item.",
1156
0
     function );
1157
1158
0
    return( -1 );
1159
0
  }
1160
0
  result = libpff_item_values_get_record_entry_by_type(
1161
0
            internal_item->item_values,
1162
0
            internal_item->name_to_id_map_list,
1163
0
            internal_item->io_handle,
1164
0
            internal_item->file_io_handle,
1165
0
            internal_item->offsets_index,
1166
0
            0,
1167
0
            entry_type,
1168
0
            LIBPFF_VALUE_TYPE_INTEGER_32BIT_SIGNED,
1169
0
            &record_entry,
1170
0
            0,
1171
0
            error );
1172
1173
0
  if( result == -1 )
1174
0
  {
1175
0
    libcerror_error_set(
1176
0
     error,
1177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1178
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1179
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 " 0x%04" PRIx32 ".",
1180
0
     function,
1181
0
     entry_type,
1182
0
     LIBPFF_VALUE_TYPE_INTEGER_32BIT_SIGNED );
1183
1184
0
    goto on_error;
1185
0
  }
1186
0
  else if( result != 0 )
1187
0
  {
1188
0
    if( libpff_record_entry_get_data_as_32bit_integer(
1189
0
         record_entry,
1190
0
         value_32bit,
1191
0
         error ) != 1 )
1192
0
    {
1193
0
      libcerror_error_set(
1194
0
       error,
1195
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1196
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1197
0
       "%s: unable to retrieve 32-bit integer value.",
1198
0
       function );
1199
1200
0
      goto on_error;
1201
0
    }
1202
0
    if( libpff_record_entry_free(
1203
0
         &record_entry,
1204
0
         error ) != 1 )
1205
0
    {
1206
0
      libcerror_error_set(
1207
0
       error,
1208
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1209
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1210
0
       "%s: unable to free record entry.",
1211
0
       function );
1212
1213
0
      goto on_error;
1214
0
    }
1215
0
  }
1216
0
  return( result );
1217
1218
0
on_error:
1219
0
  if( record_entry != NULL )
1220
0
  {
1221
0
    libpff_record_entry_free(
1222
0
     &record_entry,
1223
0
     NULL );
1224
0
  }
1225
0
  return( -1 );
1226
0
}
1227
1228
/* Retrieves a 64-bit FILETIME entry value
1229
 * Returns 1 if successful, 0 if not available or -1 on error
1230
 */
1231
int libpff_internal_item_get_entry_value_filetime(
1232
     libpff_internal_item_t *internal_item,
1233
     uint32_t entry_type,
1234
     uint64_t *filetime,
1235
     libcerror_error_t **error )
1236
0
{
1237
0
  libpff_record_entry_t *record_entry = NULL;
1238
0
  static char *function               = "libpff_internal_item_get_entry_value_filetime";
1239
0
  int result                          = 0;
1240
1241
0
  if( internal_item == NULL )
1242
0
  {
1243
0
    libcerror_error_set(
1244
0
     error,
1245
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1246
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1247
0
     "%s: invalid item.",
1248
0
     function );
1249
1250
0
    return( -1 );
1251
0
  }
1252
0
  result = libpff_item_values_get_record_entry_by_type(
1253
0
            internal_item->item_values,
1254
0
            internal_item->name_to_id_map_list,
1255
0
            internal_item->io_handle,
1256
0
            internal_item->file_io_handle,
1257
0
            internal_item->offsets_index,
1258
0
            0,
1259
0
            entry_type,
1260
0
            LIBPFF_VALUE_TYPE_FILETIME,
1261
0
            &record_entry,
1262
0
            0,
1263
0
            error );
1264
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 to retrieve record entry: 0x%04" PRIx32 " 0x%04" PRIx32 ".",
1272
0
     function,
1273
0
     entry_type,
1274
0
     LIBPFF_VALUE_TYPE_FILETIME );
1275
1276
0
    goto on_error;
1277
0
  }
1278
0
  else if( result != 0 )
1279
0
  {
1280
0
    if( libpff_record_entry_get_data_as_filetime(
1281
0
         record_entry,
1282
0
         filetime,
1283
0
         error ) != 1 )
1284
0
    {
1285
0
      libcerror_error_set(
1286
0
       error,
1287
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1288
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1289
0
       "%s: unable to retrieve filetime value.",
1290
0
       function );
1291
1292
0
      goto on_error;
1293
0
    }
1294
0
    if( libpff_record_entry_free(
1295
0
         &record_entry,
1296
0
         error ) != 1 )
1297
0
    {
1298
0
      libcerror_error_set(
1299
0
       error,
1300
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1301
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1302
0
       "%s: unable to free record entry.",
1303
0
       function );
1304
1305
0
      goto on_error;
1306
0
    }
1307
0
  }
1308
0
  return( result );
1309
1310
0
on_error:
1311
0
  if( record_entry != NULL )
1312
0
  {
1313
0
    libpff_record_entry_free(
1314
0
     &record_entry,
1315
0
     NULL );
1316
0
  }
1317
0
  return( -1 );
1318
0
}
1319
1320
/* Retrieves the UTF-8 string size of a specific entry
1321
 * The size includes the end of string character
1322
 * Returns 1 if successful, 0 if not available or -1 on error
1323
 */
1324
int libpff_internal_item_get_entry_value_utf8_string_size(
1325
     libpff_internal_item_t *internal_item,
1326
     uint32_t entry_type,
1327
     int ascii_codepage,
1328
     size_t *utf8_string_size,
1329
     libcerror_error_t **error )
1330
0
{
1331
0
  libpff_record_entry_t *record_entry = NULL;
1332
0
  static char *function               = "libpff_internal_item_get_entry_value_utf8_string_size";
1333
0
  uint32_t value_type                 = 0;
1334
0
  int result                          = 0;
1335
1336
0
  if( internal_item == NULL )
1337
0
  {
1338
0
    libcerror_error_set(
1339
0
     error,
1340
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1341
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1342
0
     "%s: invalid item.",
1343
0
     function );
1344
1345
0
    return( -1 );
1346
0
  }
1347
0
  result = libpff_item_values_get_record_entry_by_type(
1348
0
            internal_item->item_values,
1349
0
            internal_item->name_to_id_map_list,
1350
0
            internal_item->io_handle,
1351
0
            internal_item->file_io_handle,
1352
0
            internal_item->offsets_index,
1353
0
            0,
1354
0
            entry_type,
1355
0
            0,
1356
0
            &record_entry,
1357
0
            LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE,
1358
0
            error );
1359
1360
0
  if( result == -1 )
1361
0
  {
1362
0
    libcerror_error_set(
1363
0
     error,
1364
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1365
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1366
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 ".",
1367
0
     function,
1368
0
     entry_type );
1369
1370
0
    goto on_error;
1371
0
  }
1372
0
  else if( result != 0 )
1373
0
  {
1374
0
    if( libpff_record_entry_get_value_type(
1375
0
         record_entry,
1376
0
         &value_type,
1377
0
         error ) != 1 )
1378
0
    {
1379
0
      libcerror_error_set(
1380
0
       error,
1381
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1382
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1383
0
       "%s: unable to retrieve value type.",
1384
0
       function );
1385
1386
0
      goto on_error;
1387
0
    }
1388
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
1389
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
1390
0
    {
1391
0
      libcerror_error_set(
1392
0
       error,
1393
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1394
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1395
0
       "%s: unsupported value type: 0x%04" PRIx32 ".",
1396
0
       function,
1397
0
       value_type );
1398
1399
0
      goto on_error;
1400
0
    }
1401
0
    if( libpff_record_entry_get_data_as_utf8_string_size_with_codepage(
1402
0
         record_entry,
1403
0
         ascii_codepage,
1404
0
         utf8_string_size,
1405
0
         error ) != 1 )
1406
0
    {
1407
0
      libcerror_error_set(
1408
0
       error,
1409
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1410
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1411
0
       "%s: unable to retrieve UTF-8 string size.",
1412
0
       function );
1413
1414
0
      goto on_error;
1415
0
    }
1416
0
    if( libpff_record_entry_free(
1417
0
         &record_entry,
1418
0
         error ) != 1 )
1419
0
    {
1420
0
      libcerror_error_set(
1421
0
       error,
1422
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1423
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1424
0
       "%s: unable to free record entry.",
1425
0
       function );
1426
1427
0
      goto on_error;
1428
0
    }
1429
0
  }
1430
0
  return( result );
1431
1432
0
on_error:
1433
0
  if( record_entry != NULL )
1434
0
  {
1435
0
    libpff_record_entry_free(
1436
0
     &record_entry,
1437
0
     NULL );
1438
0
  }
1439
0
  return( -1 );
1440
0
}
1441
1442
/* Retrieves the UTF-8 string value of a specific entry
1443
 * The function uses a codepage if necessary, it uses the codepage set for the library
1444
 * Returns 1 if successful, 0 if not available or -1 on error
1445
 */
1446
int libpff_internal_item_get_entry_value_utf8_string(
1447
     libpff_internal_item_t *internal_item,
1448
     uint32_t entry_type,
1449
     int ascii_codepage,
1450
     uint8_t *utf8_string,
1451
     size_t utf8_string_size,
1452
     libcerror_error_t **error )
1453
0
{
1454
0
  libpff_record_entry_t *record_entry = NULL;
1455
0
  static char *function               = "libpff_internal_item_get_entry_value_utf8_string";
1456
0
  uint32_t value_type                 = 0;
1457
0
  int result                          = 0;
1458
1459
0
  if( internal_item == NULL )
1460
0
  {
1461
0
    libcerror_error_set(
1462
0
     error,
1463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1465
0
     "%s: invalid item.",
1466
0
     function );
1467
1468
0
    return( -1 );
1469
0
  }
1470
0
  result = libpff_item_values_get_record_entry_by_type(
1471
0
            internal_item->item_values,
1472
0
            internal_item->name_to_id_map_list,
1473
0
            internal_item->io_handle,
1474
0
            internal_item->file_io_handle,
1475
0
            internal_item->offsets_index,
1476
0
            0,
1477
0
            entry_type,
1478
0
            0,
1479
0
            &record_entry,
1480
0
            LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE,
1481
0
            error );
1482
1483
0
  if( result == -1 )
1484
0
  {
1485
0
    libcerror_error_set(
1486
0
     error,
1487
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1488
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1489
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 ".",
1490
0
     function,
1491
0
     entry_type );
1492
1493
0
    goto on_error;
1494
0
  }
1495
0
  else if( result != 0 )
1496
0
  {
1497
0
    if( libpff_record_entry_get_value_type(
1498
0
         record_entry,
1499
0
         &value_type,
1500
0
         error ) != 1 )
1501
0
    {
1502
0
      libcerror_error_set(
1503
0
       error,
1504
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1505
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1506
0
       "%s: unable to retrieve value type.",
1507
0
       function );
1508
1509
0
      goto on_error;
1510
0
    }
1511
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
1512
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
1513
0
    {
1514
0
      libcerror_error_set(
1515
0
       error,
1516
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1517
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1518
0
       "%s: unsupported value type: 0x%04" PRIx32 ".",
1519
0
       function,
1520
0
       value_type );
1521
1522
0
      goto on_error;
1523
0
    }
1524
0
    if( libpff_record_entry_get_data_as_utf8_string_with_codepage(
1525
0
         record_entry,
1526
0
         ascii_codepage,
1527
0
         utf8_string,
1528
0
         utf8_string_size,
1529
0
         error ) != 1 )
1530
0
    {
1531
0
      libcerror_error_set(
1532
0
       error,
1533
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1534
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1535
0
       "%s: unable to copy record entry to UTF-8 string.",
1536
0
       function );
1537
1538
0
      goto on_error;
1539
0
    }
1540
0
    if( libpff_record_entry_free(
1541
0
         &record_entry,
1542
0
         error ) != 1 )
1543
0
    {
1544
0
      libcerror_error_set(
1545
0
       error,
1546
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1547
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1548
0
       "%s: unable to free record entry.",
1549
0
       function );
1550
1551
0
      goto on_error;
1552
0
    }
1553
0
  }
1554
0
  return( result );
1555
1556
0
on_error:
1557
0
  if( record_entry != NULL )
1558
0
  {
1559
0
    libpff_record_entry_free(
1560
0
     &record_entry,
1561
0
     NULL );
1562
0
  }
1563
0
  return( -1 );
1564
0
}
1565
1566
/* Retrieves the UTF-16 string size of a specific entry
1567
 * The size includes the end of string character
1568
 * Returns 1 if successful, 0 if not available or -1 on error
1569
 */
1570
int libpff_internal_item_get_entry_value_utf16_string_size(
1571
     libpff_internal_item_t *internal_item,
1572
     uint32_t entry_type,
1573
     int ascii_codepage,
1574
     size_t *utf16_string_size,
1575
     libcerror_error_t **error )
1576
0
{
1577
0
  libpff_record_entry_t *record_entry = NULL;
1578
0
  static char *function               = "libpff_internal_item_get_entry_value_utf16_string_size";
1579
0
  uint32_t value_type                 = 0;
1580
0
  int result                          = 0;
1581
1582
0
  if( internal_item == NULL )
1583
0
  {
1584
0
    libcerror_error_set(
1585
0
     error,
1586
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1587
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1588
0
     "%s: invalid item.",
1589
0
     function );
1590
1591
0
    return( -1 );
1592
0
  }
1593
0
  result = libpff_item_values_get_record_entry_by_type(
1594
0
            internal_item->item_values,
1595
0
            internal_item->name_to_id_map_list,
1596
0
            internal_item->io_handle,
1597
0
            internal_item->file_io_handle,
1598
0
            internal_item->offsets_index,
1599
0
            0,
1600
0
            entry_type,
1601
0
            0,
1602
0
            &record_entry,
1603
0
            LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE,
1604
0
            error );
1605
1606
0
  if( result == -1 )
1607
0
  {
1608
0
    libcerror_error_set(
1609
0
     error,
1610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1611
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1612
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 ".",
1613
0
     function,
1614
0
     entry_type );
1615
1616
0
    goto on_error;
1617
0
  }
1618
0
  else if( result != 0 )
1619
0
  {
1620
0
    if( libpff_record_entry_get_value_type(
1621
0
         record_entry,
1622
0
         &value_type,
1623
0
         error ) != 1 )
1624
0
    {
1625
0
      libcerror_error_set(
1626
0
       error,
1627
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1628
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1629
0
       "%s: unable to retrieve value type.",
1630
0
       function );
1631
1632
0
      goto on_error;
1633
0
    }
1634
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
1635
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
1636
0
    {
1637
0
      libcerror_error_set(
1638
0
       error,
1639
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1640
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1641
0
       "%s: unsupported value type: 0x%04" PRIx32 ".",
1642
0
       function,
1643
0
       value_type );
1644
1645
0
      goto on_error;
1646
0
    }
1647
0
    if( libpff_record_entry_get_data_as_utf16_string_size_with_codepage(
1648
0
         record_entry,
1649
0
         ascii_codepage,
1650
0
         utf16_string_size,
1651
0
         error ) != 1 )
1652
0
    {
1653
0
      libcerror_error_set(
1654
0
       error,
1655
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1656
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1657
0
       "%s: unable to retrieve UTF-16 string size.",
1658
0
       function );
1659
1660
0
      goto on_error;
1661
0
    }
1662
0
    if( libpff_record_entry_free(
1663
0
         &record_entry,
1664
0
         error ) != 1 )
1665
0
    {
1666
0
      libcerror_error_set(
1667
0
       error,
1668
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1669
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1670
0
       "%s: unable to free record entry.",
1671
0
       function );
1672
1673
0
      goto on_error;
1674
0
    }
1675
0
  }
1676
0
  return( result );
1677
1678
0
on_error:
1679
0
  if( record_entry != NULL )
1680
0
  {
1681
0
    libpff_record_entry_free(
1682
0
     &record_entry,
1683
0
     NULL );
1684
0
  }
1685
0
  return( -1 );
1686
0
}
1687
1688
/* Retrieves the UTF-16 string value of a specific entry
1689
 * The function uses a codepage if necessary, it uses the codepage set for the library
1690
 * Returns 1 if successful, 0 if not available or -1 on error
1691
 */
1692
int libpff_internal_item_get_entry_value_utf16_string(
1693
     libpff_internal_item_t *internal_item,
1694
     uint32_t entry_type,
1695
     int ascii_codepage,
1696
     uint16_t *utf16_string,
1697
     size_t utf16_string_size,
1698
     libcerror_error_t **error )
1699
0
{
1700
0
  libpff_record_entry_t *record_entry = NULL;
1701
0
  static char *function               = "libpff_internal_item_get_entry_value_utf16_string";
1702
0
  uint32_t value_type                 = 0;
1703
0
  int result                          = 0;
1704
1705
0
  if( internal_item == NULL )
1706
0
  {
1707
0
    libcerror_error_set(
1708
0
     error,
1709
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1710
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1711
0
     "%s: invalid item.",
1712
0
     function );
1713
1714
0
    return( -1 );
1715
0
  }
1716
0
  result = libpff_item_values_get_record_entry_by_type(
1717
0
            internal_item->item_values,
1718
0
            internal_item->name_to_id_map_list,
1719
0
            internal_item->io_handle,
1720
0
            internal_item->file_io_handle,
1721
0
            internal_item->offsets_index,
1722
0
            0,
1723
0
            entry_type,
1724
0
            0,
1725
0
            &record_entry,
1726
0
            LIBPFF_ENTRY_VALUE_FLAG_MATCH_ANY_VALUE_TYPE,
1727
0
            error );
1728
1729
0
  if( result == -1 )
1730
0
  {
1731
0
    libcerror_error_set(
1732
0
     error,
1733
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1734
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1735
0
     "%s: unable to retrieve record entry: 0x%04" PRIx32 ".",
1736
0
     function,
1737
0
     entry_type );
1738
1739
0
    goto on_error;
1740
0
  }
1741
0
  else if( result != 0 )
1742
0
  {
1743
0
    if( libpff_record_entry_get_value_type(
1744
0
         record_entry,
1745
0
         &value_type,
1746
0
         error ) != 1 )
1747
0
    {
1748
0
      libcerror_error_set(
1749
0
       error,
1750
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1751
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1752
0
       "%s: unable to retrieve value type.",
1753
0
       function );
1754
1755
0
      goto on_error;
1756
0
    }
1757
0
    if( ( value_type != LIBPFF_VALUE_TYPE_STRING_ASCII )
1758
0
     && ( value_type != LIBPFF_VALUE_TYPE_STRING_UNICODE ) )
1759
0
    {
1760
0
      libcerror_error_set(
1761
0
       error,
1762
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1763
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1764
0
       "%s: unsupported value type: 0x%04" PRIx32 ".",
1765
0
       function,
1766
0
       value_type );
1767
1768
0
      goto on_error;
1769
0
    }
1770
0
    if( libpff_record_entry_get_data_as_utf16_string_with_codepage(
1771
0
         record_entry,
1772
0
         ascii_codepage,
1773
0
         utf16_string,
1774
0
         utf16_string_size,
1775
0
         error ) != 1 )
1776
0
    {
1777
0
      libcerror_error_set(
1778
0
       error,
1779
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1780
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1781
0
       "%s: unable to copy record entry to UTF-16 string.",
1782
0
       function );
1783
1784
0
      goto on_error;
1785
0
    }
1786
0
    if( libpff_record_entry_free(
1787
0
         &record_entry,
1788
0
         error ) != 1 )
1789
0
    {
1790
0
      libcerror_error_set(
1791
0
       error,
1792
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1793
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1794
0
       "%s: unable to free record entry.",
1795
0
       function );
1796
1797
0
      goto on_error;
1798
0
    }
1799
0
  }
1800
0
  return( result );
1801
1802
0
on_error:
1803
0
  if( record_entry != NULL )
1804
0
  {
1805
0
    libpff_record_entry_free(
1806
0
     &record_entry,
1807
0
     NULL );
1808
0
  }
1809
0
  return( -1 );
1810
0
}
1811
1812
/* Retrieves the embedded object data
1813
 * Returns 1 if successful or -1 on error
1814
 */
1815
int libpff_internal_item_get_embedded_object_data(
1816
     libpff_internal_item_t *internal_item,
1817
     libpff_record_entry_t *record_entry,
1818
     libcerror_error_t **error )
1819
0
{
1820
0
  libfcache_cache_t *embedded_object_data_cache           = NULL;
1821
0
  libfdata_list_t *embedded_object_data_list              = NULL;
1822
0
  libpff_local_descriptor_value_t *local_descriptor_value = NULL;
1823
0
  static char *function                                   = "libpff_internal_item_get_embedded_object_data";
1824
0
  uint32_t embedded_object_data_identifier                = 0;
1825
1826
0
  if( internal_item == NULL )
1827
0
  {
1828
0
    libcerror_error_set(
1829
0
     error,
1830
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1831
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1832
0
     "%s: invalid item.",
1833
0
     function );
1834
1835
0
    return( -1 );
1836
0
  }
1837
0
  if( internal_item->item_values == NULL )
1838
0
  {
1839
0
    libcerror_error_set(
1840
0
     error,
1841
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1842
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1843
0
     "%s: invalid item - missing item values.",
1844
0
     function );
1845
1846
0
    return( -1 );
1847
0
  }
1848
0
  if( internal_item->item_values->table == 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 item - invalid item values - missing table.",
1855
0
     function );
1856
1857
0
    return( -1 );
1858
0
  }
1859
0
  if( internal_item->embedded_object_data_stream != NULL )
1860
0
  {
1861
0
    libcerror_error_set(
1862
0
     error,
1863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1864
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1865
0
     "%s: invalid item - embedded object data stream already set.",
1866
0
     function );
1867
1868
0
    return( -1 );
1869
0
  }
1870
0
  if( libpff_record_entry_copy_object_identifier(
1871
0
       record_entry,
1872
0
       &embedded_object_data_identifier,
1873
0
       error ) != 1 )
1874
0
  {
1875
0
    libcerror_error_set(
1876
0
     error,
1877
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1878
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1879
0
     "%s: unable to copy record entry object identifier.",
1880
0
     function );
1881
1882
0
    goto on_error;
1883
0
  }
1884
  /* The descriptor identifier is located in the local descriptors tree
1885
   */
1886
0
  if( libpff_table_get_local_descriptors_value_by_identifier(
1887
0
       internal_item->item_values->table,
1888
0
       internal_item->file_io_handle,
1889
0
       (uint64_t) embedded_object_data_identifier,
1890
0
       &local_descriptor_value,
1891
0
       error ) != 1 )
1892
0
  {
1893
0
    libcerror_error_set(
1894
0
     error,
1895
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1896
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1897
0
     "%s: unable to retrieve local descriptor identifier: %" PRIu32 ".",
1898
0
     function,
1899
0
     embedded_object_data_identifier );
1900
1901
0
    goto on_error;
1902
0
  }
1903
0
  if( local_descriptor_value == NULL )
1904
0
  {
1905
0
    libcerror_error_set(
1906
0
     error,
1907
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1908
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1909
0
     "%s: invalid local descriptor values.",
1910
0
     function );
1911
1912
0
    goto on_error;
1913
0
  }
1914
#if defined( HAVE_DEBUG_OUTPUT )
1915
  if( libcnotify_verbose != 0 )
1916
  {
1917
    libcnotify_printf(
1918
     "%s: identifier: %" PRIu64 " (%s), data: %" PRIu64 ", local descriptors: %" PRIu64 "\n",
1919
     function,
1920
     local_descriptor_value->identifier,
1921
     libpff_debug_get_node_identifier_type(
1922
      (uint8_t) ( local_descriptor_value->identifier & 0x0000001fUL ) ),
1923
     local_descriptor_value->data_identifier,
1924
     local_descriptor_value->local_descriptors_identifier );
1925
  }
1926
#endif
1927
0
  if( local_descriptor_value->data_identifier == 0 )
1928
0
  {
1929
0
    libcerror_error_set(
1930
0
     error,
1931
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1932
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1933
0
     "%s: invalid local descriptor values - missing data identifier.",
1934
0
     function );
1935
1936
0
    goto on_error;
1937
0
  }
1938
/* TODO handle multiple recovered offset index values */
1939
0
  if( libpff_table_read_descriptor_data_list(
1940
0
       internal_item->item_values->table,
1941
0
       internal_item->io_handle,
1942
0
       internal_item->file_io_handle,
1943
0
       internal_item->offsets_index,
1944
0
       embedded_object_data_identifier,
1945
0
       local_descriptor_value->data_identifier,
1946
0
       internal_item->item_values->recovered,
1947
0
       0,
1948
0
       &embedded_object_data_list,
1949
0
       &embedded_object_data_cache,
1950
0
       error ) != 1 )
1951
0
  {
1952
0
    libcerror_error_set(
1953
0
     error,
1954
0
     LIBCERROR_ERROR_DOMAIN_IO,
1955
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1956
0
     "%s: unable to read descriptor: %" PRIu32 " data: %" PRIu64 " list.",
1957
0
     function,
1958
0
     embedded_object_data_identifier,
1959
0
     local_descriptor_value->data_identifier );
1960
1961
0
    goto on_error;
1962
0
  }
1963
0
  if( libpff_descriptor_data_stream_initialize(
1964
0
       &( internal_item->embedded_object_data_stream ),
1965
0
       embedded_object_data_list,
1966
0
       embedded_object_data_cache,
1967
0
       LIBPFF_DESCRIPTOR_DATA_STREAM_DATA_HANDLE_FLAG_MANAGED,
1968
0
       error ) != 1 )
1969
0
  {
1970
0
    libcerror_error_set(
1971
0
     error,
1972
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1973
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1974
0
     "%s: unable to create descriptor data stream.",
1975
0
     function );
1976
1977
0
    goto on_error;
1978
0
  }
1979
0
  if( libpff_local_descriptor_value_free(
1980
0
       &local_descriptor_value,
1981
0
       error ) != 1 )
1982
0
  {
1983
0
    libcerror_error_set(
1984
0
     error,
1985
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1986
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1987
0
     "%s: unable to free local descriptor values.",
1988
0
     function );
1989
1990
0
    goto on_error;
1991
0
  }
1992
0
  return( 1 );
1993
1994
0
on_error:
1995
0
  if( embedded_object_data_cache != NULL )
1996
0
  {
1997
0
    libfcache_cache_free(
1998
0
     &embedded_object_data_cache,
1999
0
     NULL );
2000
0
  }
2001
0
  if( embedded_object_data_list != NULL )
2002
0
  {
2003
0
    libfdata_list_free(
2004
0
     &embedded_object_data_list,
2005
0
     NULL );
2006
0
  }
2007
0
  if( local_descriptor_value != NULL )
2008
0
  {
2009
0
    libpff_local_descriptor_value_free(
2010
0
     &local_descriptor_value,
2011
0
     NULL );
2012
0
  }
2013
0
  return( -1 );
2014
0
}
2015
2016
/* Retrieves the type
2017
 * Determines the item type if neccessary
2018
 * Returns 1 if successful or -1 on error
2019
 */
2020
int libpff_item_get_type(
2021
     libpff_item_t *item,
2022
     uint8_t *item_type,
2023
     libcerror_error_t **error )
2024
0
{
2025
0
  libpff_internal_item_t *internal_item = NULL;
2026
0
  static char *function                 = "libpff_item_get_type";
2027
2028
0
  if( item == NULL )
2029
0
  {
2030
0
    libcerror_error_set(
2031
0
     error,
2032
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2033
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2034
0
     "%s: invalid item.",
2035
0
     function );
2036
2037
0
    return( -1 );
2038
0
  }
2039
0
  internal_item = (libpff_internal_item_t *) item;
2040
2041
0
  if( item_type == NULL )
2042
0
  {
2043
0
    libcerror_error_set(
2044
0
     error,
2045
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2046
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2047
0
     "%s: invalid item type.",
2048
0
     function );
2049
2050
0
    return( -1 );
2051
0
  }
2052
0
  if( internal_item->type == LIBPFF_ITEM_TYPE_UNDEFINED )
2053
0
  {
2054
0
    if( libpff_internal_item_determine_type(
2055
0
         internal_item,
2056
0
         error ) != 1 )
2057
0
    {
2058
0
      libcerror_error_set(
2059
0
       error,
2060
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2061
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2062
0
       "%s: unable to determine item type.",
2063
0
       function );
2064
2065
0
      return( -1 );
2066
0
    }
2067
0
  }
2068
0
  *item_type = internal_item->type;
2069
2070
0
  return( 1 );
2071
0
}
2072
2073
/* Retrieves the number of sub items from a item
2074
 * Returns 1 if successful or -1 on error
2075
 */
2076
int libpff_item_get_number_of_sub_items(
2077
     libpff_item_t *item,
2078
     int *number_of_sub_items,
2079
     libcerror_error_t **error )
2080
63
{
2081
63
  libpff_internal_item_t *internal_item = NULL;
2082
63
  static char *function                 = "libpff_item_get_number_of_sub_items";
2083
2084
63
  if( item == NULL )
2085
0
  {
2086
0
    libcerror_error_set(
2087
0
     error,
2088
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2089
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2090
0
     "%s: invalid item.",
2091
0
     function );
2092
2093
0
    return( -1 );
2094
0
  }
2095
63
  internal_item = (libpff_internal_item_t *) item;
2096
2097
63
  if( libcdata_tree_node_get_number_of_sub_nodes(
2098
63
       internal_item->item_tree_node,
2099
63
       number_of_sub_items,
2100
63
       error ) != 1 )
2101
0
  {
2102
0
    libcerror_error_set(
2103
0
     error,
2104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2105
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2106
0
     "%s: unable to retrieve number of sub items.",
2107
0
     function );
2108
2109
0
    return( -1 );
2110
0
  }
2111
63
  return( 1 );
2112
63
}
2113
2114
/* Retrieves the sub item for the specific index from a item
2115
 * Returns 1 if successful or -1 on error
2116
 */
2117
int libpff_item_get_sub_item(
2118
     libpff_item_t *item,
2119
     int sub_item_index,
2120
     libpff_item_t **sub_item,
2121
     libcerror_error_t **error )
2122
16
{
2123
16
  libcdata_tree_node_t *sub_item_tree_node      = NULL;
2124
16
  libpff_internal_item_t *internal_item         = NULL;
2125
16
  libpff_item_descriptor_t *sub_item_descriptor = NULL;
2126
16
  static char *function                         = "libpff_item_get_sub_item";
2127
2128
16
  if( item == NULL )
2129
0
  {
2130
0
    libcerror_error_set(
2131
0
     error,
2132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2134
0
     "%s: invalid item.",
2135
0
     function );
2136
2137
0
    return( -1 );
2138
0
  }
2139
16
  internal_item = (libpff_internal_item_t *) item;
2140
2141
16
  if( sub_item == NULL )
2142
0
  {
2143
0
    libcerror_error_set(
2144
0
     error,
2145
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2146
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2147
0
     "%s: invalid sub item.",
2148
0
     function );
2149
2150
0
    return( -1 );
2151
0
  }
2152
16
  if( *sub_item != NULL )
2153
0
  {
2154
0
    libcerror_error_set(
2155
0
     error,
2156
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2157
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2158
0
     "%s: sub item already set.",
2159
0
     function );
2160
2161
0
    return( -1 );
2162
0
  }
2163
16
  if( libcdata_tree_node_get_sub_node_by_index(
2164
16
       internal_item->item_tree_node,
2165
16
             sub_item_index,
2166
16
             &sub_item_tree_node,
2167
16
       error ) != 1 )
2168
0
  {
2169
0
    libcerror_error_set(
2170
0
     error,
2171
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2172
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2173
0
     "%s: unable to retrieve sub item tree node.",
2174
0
     function );
2175
2176
0
    return( -1 );
2177
0
  }
2178
16
  if( libcdata_tree_node_get_value(
2179
16
       sub_item_tree_node,
2180
16
       (intptr_t **) &sub_item_descriptor,
2181
16
       error ) != 1 )
2182
0
  {
2183
0
    libcerror_error_set(
2184
0
     error,
2185
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2186
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2187
0
     "%s: unable to retrieve sub item descriptor.",
2188
0
     function );
2189
2190
0
    return( -1 );
2191
0
  }
2192
16
  if( libpff_item_initialize(
2193
16
       sub_item,
2194
16
       internal_item->io_handle,
2195
16
       internal_item->file_io_handle,
2196
16
       internal_item->name_to_id_map_list,
2197
16
       internal_item->descriptors_index,
2198
16
       internal_item->offsets_index,
2199
16
       internal_item->item_tree,
2200
16
       sub_item_tree_node,
2201
16
       LIBPFF_ITEM_FLAGS_DEFAULT,
2202
16
       error ) != 1 )
2203
0
  {
2204
0
    libcerror_error_set(
2205
0
     error,
2206
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2207
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2208
0
     "%s: unable to initialize sub item.",
2209
0
     function );
2210
2211
0
    return( -1 );
2212
0
  }
2213
16
  return( 1 );
2214
16
}
2215
2216
/* Retrieves the sub item for the specific identifier from a item
2217
 * Returns 1 if successful, 0 if no such item or -1 on error
2218
 */
2219
int libpff_item_get_sub_item_by_identifier(
2220
     libpff_item_t *item,
2221
     uint32_t sub_item_identifier,
2222
     libpff_item_t **sub_item,
2223
     libcerror_error_t **error )
2224
0
{
2225
0
  libcdata_tree_node_t *sub_item_tree_node      = NULL;
2226
0
  libpff_internal_item_t *internal_item         = NULL;
2227
0
  libpff_item_descriptor_t *sub_item_descriptor = NULL;
2228
0
  static char *function                         = "libpff_item_get_sub_item_by_identifier";
2229
0
  uint8_t flags                                 = 0;
2230
0
  int result                                    = 0;
2231
2232
0
  if( item == NULL )
2233
0
  {
2234
0
    libcerror_error_set(
2235
0
     error,
2236
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2237
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2238
0
     "%s: invalid item.",
2239
0
     function );
2240
2241
0
    return( -1 );
2242
0
  }
2243
0
  internal_item = (libpff_internal_item_t *) item;
2244
2245
0
  if( sub_item == NULL )
2246
0
  {
2247
0
    libcerror_error_set(
2248
0
     error,
2249
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2250
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2251
0
     "%s: invalid sub item.",
2252
0
     function );
2253
2254
0
    return( -1 );
2255
0
  }
2256
0
  if( *sub_item != NULL )
2257
0
  {
2258
0
    libcerror_error_set(
2259
0
     error,
2260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2261
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2262
0
     "%s: sub item already set.",
2263
0
     function );
2264
2265
0
    return( -1 );
2266
0
  }
2267
0
  result = libpff_item_tree_get_sub_node_by_identifier(
2268
0
            internal_item->item_tree_node,
2269
0
                  sub_item_identifier,
2270
0
                  &sub_item_tree_node,
2271
0
            error );
2272
2273
0
  if( result == -1 )
2274
0
  {
2275
0
    libcerror_error_set(
2276
0
     error,
2277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2278
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2279
0
     "%s: unable to retrieve sub item tree node: %" PRIu32 ".",
2280
0
     function,
2281
0
     sub_item_identifier );
2282
2283
0
    return( -1 );
2284
0
  }
2285
0
  else if( result == 0 )
2286
0
  {
2287
0
    return( 0 );
2288
0
  }
2289
0
  if( libcdata_tree_node_get_value(
2290
0
       sub_item_tree_node,
2291
0
       (intptr_t **) &sub_item_descriptor,
2292
0
       error ) != 1 )
2293
0
  {
2294
0
    libcerror_error_set(
2295
0
     error,
2296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2297
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2298
0
     "%s: unable to retrieve sub item descriptor.",
2299
0
     function );
2300
2301
0
    return( -1 );
2302
0
  }
2303
0
  if( libpff_item_initialize(
2304
0
       sub_item,
2305
0
       internal_item->io_handle,
2306
0
       internal_item->file_io_handle,
2307
0
       internal_item->name_to_id_map_list,
2308
0
       internal_item->descriptors_index,
2309
0
       internal_item->offsets_index,
2310
0
       internal_item->item_tree,
2311
0
       sub_item_tree_node,
2312
0
       LIBPFF_ITEM_FLAGS_DEFAULT | flags,
2313
0
       error ) != 1 )
2314
0
  {
2315
0
    libcerror_error_set(
2316
0
     error,
2317
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2318
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2319
0
     "%s: unable to initialize sub item.",
2320
0
     function );
2321
2322
0
    return( -1 );
2323
0
  }
2324
0
  if( *sub_item == NULL )
2325
0
  {
2326
0
    libcerror_error_set(
2327
0
     error,
2328
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2329
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2330
0
     "%s: missing sub item.",
2331
0
     function );
2332
2333
0
    return( -1 );
2334
0
  }
2335
0
  if( ( flags & LIBPFF_ITEM_FLAG_MANAGED_ITEM_TREE_NODE ) != 0 )
2336
0
  {
2337
0
    if( internal_item->type != LIBPFF_ITEM_TYPE_FOLDER )
2338
0
    {
2339
0
      if( sub_item_identifier == LIBPFF_LOCAL_DESCRIPTOR_IDENTIFIER_ATTACHMENTS )
2340
0
      {
2341
0
        ( (libpff_internal_item_t *) *sub_item )->type = LIBPFF_ITEM_TYPE_ATTACHMENTS;
2342
0
      }
2343
0
      else if( sub_item_identifier == LIBPFF_LOCAL_DESCRIPTOR_IDENTIFIER_RECIPIENTS )
2344
0
      {
2345
0
        ( (libpff_internal_item_t *) *sub_item )->type = LIBPFF_ITEM_TYPE_RECIPIENTS;
2346
0
      }
2347
0
      else
2348
0
      {
2349
0
        ( (libpff_internal_item_t *) *sub_item )->type = LIBPFF_ITEM_TYPE_ATTACHMENT;
2350
0
      }
2351
0
    }
2352
0
  }
2353
0
  return( 1 );
2354
0
}
2355