Coverage Report

Created: 2024-02-25 07:19

/src/libolecf/libolecf/libolecf_item.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Item functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libolecf_definitions.h"
27
#include "libolecf_directory_entry.h"
28
#include "libolecf_directory_tree.h"
29
#include "libolecf_io_handle.h"
30
#include "libolecf_file.h"
31
#include "libolecf_item.h"
32
#include "libolecf_libcdata.h"
33
#include "libolecf_libcerror.h"
34
#include "libolecf_libuna.h"
35
#include "libolecf_types.h"
36
37
/* Creates an item
38
 * Make sure the value item is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libolecf_item_initialize(
42
     libolecf_item_t **item,
43
     libolecf_io_handle_t *io_handle,
44
     libbfio_handle_t *file_io_handle,
45
     libolecf_internal_file_t *file,
46
     libcdata_tree_node_t *directory_tree_node,
47
     libcerror_error_t **error )
48
0
{
49
0
  libolecf_internal_item_t *internal_item = NULL;
50
0
  static char *function                   = "libolecf_item_initialize";
51
52
0
  if( item == NULL )
53
0
  {
54
0
    libcerror_error_set(
55
0
     error,
56
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
57
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
58
0
     "%s: invalid item.",
59
0
     function );
60
61
0
    return( -1 );
62
0
  }
63
0
  if( *item != NULL )
64
0
  {
65
0
    libcerror_error_set(
66
0
     error,
67
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
68
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
69
0
     "%s: invalid item value already set.",
70
0
     function );
71
72
0
    return( -1 );
73
0
  }
74
0
  if( io_handle == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
79
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
80
0
     "%s: invalid IO handle.",
81
0
     function );
82
83
0
    return( -1 );
84
0
  }
85
0
  if( file_io_handle == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
90
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
91
0
     "%s: invalid file IO handle.",
92
0
     function );
93
94
0
    return( -1 );
95
0
  }
96
0
  if( directory_tree_node == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
102
0
     "%s: invalid directory tree node.",
103
0
     function );
104
105
0
    return( -1 );
106
0
  }
107
0
  internal_item = memory_allocate_structure(
108
0
                   libolecf_internal_item_t );
109
110
0
  if( internal_item == NULL )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
115
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
116
0
     "%s: unable to create internal item.",
117
0
     function );
118
119
0
    goto on_error;
120
0
  }
121
0
  if( memory_set(
122
0
       internal_item,
123
0
       0,
124
0
       sizeof( libolecf_internal_item_t ) ) == NULL )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
129
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
130
0
     "%s: unable to clear internal item.",
131
0
     function );
132
133
0
    goto on_error;
134
0
  }
135
0
  internal_item->file_io_handle      = file_io_handle;
136
0
  internal_item->io_handle           = io_handle;
137
0
  internal_item->file                = file;
138
0
  internal_item->directory_tree_node = directory_tree_node;
139
140
0
  if( libcdata_tree_node_get_value(
141
0
       directory_tree_node,
142
0
       (intptr_t **) &( internal_item->directory_entry ),
143
0
       error ) != 1 )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
148
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
149
0
     "%s: unable to retrieve value from directory tree node.",
150
0
     function );
151
152
0
    goto on_error;
153
0
  }
154
0
  *item = (libolecf_item_t *) internal_item;
155
156
0
  return( 1 );
157
158
0
on_error:
159
0
  if( internal_item != NULL )
160
0
  {
161
0
    memory_free(
162
0
     internal_item );
163
0
  }
164
0
  return( -1 );
165
0
}
166
167
/* Frees an item
168
 * Return 1 if successful or -1 on error
169
 */
170
int libolecf_item_free(
171
     libolecf_item_t **item,
172
     libcerror_error_t **error )
173
0
{
174
0
  libolecf_internal_item_t *internal_item = NULL;
175
0
  static char *function                   = "libolecf_item_free";
176
177
0
  if( item == NULL )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
182
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
183
0
     "%s: invalid item.",
184
0
     function );
185
186
0
    return( -1 );
187
0
  }
188
0
  if( *item != NULL )
189
0
  {
190
0
    internal_item = (libolecf_internal_item_t *) *item;
191
0
    *item         = NULL;
192
193
0
    memory_free(
194
0
     internal_item );
195
0
  }
196
0
  return( 1 );
197
0
}
198
199
/* Retrieves the type
200
 * Returns 1 if successful or -1 on error
201
 */
202
int libolecf_item_get_type(
203
     libolecf_item_t *item,
204
     uint8_t *type,
205
     libcerror_error_t **error )
206
0
{
207
0
  libolecf_internal_item_t *internal_item = NULL;
208
0
  static char *function                   = "libolecf_item_get_type";
209
210
0
  if( item == NULL )
211
0
  {
212
0
    libcerror_error_set(
213
0
     error,
214
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
215
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
216
0
     "%s: invalid item.",
217
0
     function );
218
219
0
    return( -1 );
220
0
  }
221
0
  internal_item = (libolecf_internal_item_t *) item;
222
223
0
  if( internal_item->directory_entry == NULL )
224
0
  {
225
0
    libcerror_error_set(
226
0
     error,
227
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
229
0
     "%s: invalid item - missing directory entry.",
230
0
     function );
231
232
0
    return( -1 );
233
0
  }
234
0
  if( type == NULL )
235
0
  {
236
0
    libcerror_error_set(
237
0
     error,
238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
240
0
     "%s: invalid type.",
241
0
     function );
242
243
0
    return( -1 );
244
0
  }
245
0
  *type = internal_item->directory_entry->type;
246
247
0
  return( 1 );
248
0
}
249
250
/* Retrieves the size of the UTF-8 encoded name of the referenced item
251
 * The returned size includes the end of string character
252
 * Returns 1 if successful or -1 on error
253
 */
254
int libolecf_item_get_utf8_name_size(
255
     libolecf_item_t *item,
256
     size_t *utf8_string_size,
257
     libcerror_error_t **error )
258
0
{
259
0
  libolecf_internal_item_t *internal_item = NULL;
260
0
  static char *function                   = "libolecf_item_get_utf8_name_size";
261
262
0
  if( item == NULL )
263
0
  {
264
0
    libcerror_error_set(
265
0
     error,
266
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
267
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
268
0
     "%s: invalid item.",
269
0
     function );
270
271
0
    return( -1 );
272
0
  }
273
0
  internal_item = (libolecf_internal_item_t *) item;
274
275
0
  if( internal_item->io_handle == NULL )
276
0
  {
277
0
    libcerror_error_set(
278
0
     error,
279
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
280
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
281
0
     "%s: invalid item - missing IO handle.",
282
0
     function );
283
284
0
    return( -1 );
285
0
  }
286
0
  if( internal_item->directory_entry == NULL )
287
0
  {
288
0
    libcerror_error_set(
289
0
     error,
290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
291
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
292
0
     "%s: invalid item - missing directory entry.",
293
0
     function );
294
295
0
    return( -1 );
296
0
  }
297
0
  if( libuna_utf8_string_size_from_utf16_stream(
298
0
       internal_item->directory_entry->name,
299
0
       internal_item->directory_entry->name_size,
300
0
       internal_item->io_handle->byte_order,
301
0
       utf8_string_size,
302
0
       error ) != 1 )
303
0
  {
304
0
    libcerror_error_set(
305
0
     error,
306
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
307
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
308
0
     "%s: unable to determine size of name as UTF-8 string.",
309
0
     function );
310
311
0
    return( -1 );
312
0
  }
313
0
  return( 1 );
314
0
}
315
316
/* Retrieves the UTF-8 encoded name of the referenced item
317
 * The size should include the end of string character
318
 * Returns 1 if successful or -1 on error
319
 */
320
int libolecf_item_get_utf8_name(
321
     libolecf_item_t *item,
322
     uint8_t *utf8_string,
323
     size_t utf8_string_size,
324
     libcerror_error_t **error )
325
0
{
326
0
  libolecf_internal_item_t *internal_item = NULL;
327
0
  static char *function                   = "libolecf_item_get_utf8_name";
328
329
0
  if( item == NULL )
330
0
  {
331
0
    libcerror_error_set(
332
0
     error,
333
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
334
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
335
0
     "%s: invalid item.",
336
0
     function );
337
338
0
    return( -1 );
339
0
  }
340
0
  internal_item = (libolecf_internal_item_t *) item;
341
342
0
  if( internal_item->io_handle == NULL )
343
0
  {
344
0
    libcerror_error_set(
345
0
     error,
346
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
347
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
348
0
     "%s: invalid item - missing IO handle.",
349
0
     function );
350
351
0
    return( -1 );
352
0
  }
353
0
  if( internal_item->directory_entry == NULL )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
359
0
     "%s: invalid item - missing directory entry.",
360
0
     function );
361
362
0
    return( -1 );
363
0
  }
364
0
  if( utf8_string == NULL )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
369
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
370
0
     "%s: invalid UTF-8 string.",
371
0
     function );
372
373
0
    return( -1 );
374
0
  }
375
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
376
0
  {
377
0
    libcerror_error_set(
378
0
     error,
379
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
380
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
381
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
382
0
     function );
383
384
0
    return( -1 );
385
0
  }
386
0
  if( libuna_utf8_string_copy_from_utf16_stream(
387
0
       utf8_string,
388
0
       utf8_string_size,
389
0
       internal_item->directory_entry->name,
390
0
       internal_item->directory_entry->name_size,
391
0
       internal_item->io_handle->byte_order,
392
0
       error ) != 1 )
393
0
  {
394
0
    libcerror_error_set(
395
0
     error,
396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
397
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
398
0
     "%s: unable to opy name to UTF-8 string.",
399
0
     function );
400
401
0
    return( -1 );
402
0
  }
403
0
  return( 1 );
404
0
}
405
406
/* Retrieves the size of the UTF-16 encoded name of the referenced item
407
 * The returned size includes the end of string character
408
 * Returns 1 if successful or -1 on error
409
 */
410
int libolecf_item_get_utf16_name_size(
411
     libolecf_item_t *item,
412
     size_t *utf16_string_size,
413
     libcerror_error_t **error )
414
0
{
415
0
  libolecf_internal_item_t *internal_item = NULL;
416
0
  static char *function                   = "libolecf_item_get_utf16_name_size";
417
418
0
  if( item == NULL )
419
0
  {
420
0
    libcerror_error_set(
421
0
     error,
422
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
423
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
424
0
     "%s: invalid item.",
425
0
     function );
426
427
0
    return( -1 );
428
0
  }
429
0
  internal_item = (libolecf_internal_item_t *) item;
430
431
0
  if( internal_item->io_handle == NULL )
432
0
  {
433
0
    libcerror_error_set(
434
0
     error,
435
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
436
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
437
0
     "%s: invalid item - missing IO handle.",
438
0
     function );
439
440
0
    return( -1 );
441
0
  }
442
0
  if( internal_item->directory_entry == NULL )
443
0
  {
444
0
    libcerror_error_set(
445
0
     error,
446
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
447
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
448
0
     "%s: invalid item - missing directory entry.",
449
0
     function );
450
451
0
    return( -1 );
452
0
  }
453
0
  if( libuna_utf16_string_size_from_utf16_stream(
454
0
       internal_item->directory_entry->name,
455
0
       internal_item->directory_entry->name_size,
456
0
       internal_item->io_handle->byte_order,
457
0
       utf16_string_size,
458
0
       error ) != 1 )
459
0
  {
460
0
    libcerror_error_set(
461
0
     error,
462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
463
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
464
0
     "%s: unable to determine size of name as UTF-16 string.",
465
0
     function );
466
467
0
    return( -1 );
468
0
  }
469
0
  return( 1 );
470
0
}
471
472
/* Retrieves the UTF-16 encoded name of the referenced item
473
 * The size should include the end of string character
474
 * Returns 1 if successful or -1 on error
475
 */
476
int libolecf_item_get_utf16_name(
477
     libolecf_item_t *item,
478
     uint16_t *utf16_string,
479
     size_t utf16_string_size,
480
     libcerror_error_t **error )
481
0
{
482
0
  libolecf_internal_item_t *internal_item = NULL;
483
0
  static char *function                   = "libolecf_item_get_utf16_name";
484
485
0
  if( item == NULL )
486
0
  {
487
0
    libcerror_error_set(
488
0
     error,
489
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
491
0
     "%s: invalid item.",
492
0
     function );
493
494
0
    return( -1 );
495
0
  }
496
0
  internal_item = (libolecf_internal_item_t *) item;
497
498
0
  if( internal_item->io_handle == NULL )
499
0
  {
500
0
    libcerror_error_set(
501
0
     error,
502
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
503
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
504
0
     "%s: invalid item - missing IO handle.",
505
0
     function );
506
507
0
    return( -1 );
508
0
  }
509
0
  if( internal_item->directory_entry == NULL )
510
0
  {
511
0
    libcerror_error_set(
512
0
     error,
513
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
514
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
515
0
     "%s: invalid item - missing directory entry.",
516
0
     function );
517
518
0
    return( -1 );
519
0
  }
520
0
  if( libuna_utf16_string_copy_from_utf16_stream(
521
0
       utf16_string,
522
0
       utf16_string_size,
523
0
       internal_item->directory_entry->name,
524
0
       internal_item->directory_entry->name_size,
525
0
       internal_item->io_handle->byte_order,
526
0
       error ) != 1 )
527
0
  {
528
0
    libcerror_error_set(
529
0
     error,
530
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
531
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
532
0
     "%s: unable to opy name to UTF-16 string.",
533
0
     function );
534
535
0
    return( -1 );
536
0
  }
537
0
  return( 1 );
538
0
}
539
540
/* Retrieves the size of the referenced item
541
 * Returns 1 if successful or -1 on error
542
 */
543
int libolecf_item_get_size(
544
     libolecf_item_t *item,
545
     uint32_t *size,
546
     libcerror_error_t **error )
547
0
{
548
0
  libolecf_internal_item_t *internal_item = NULL;
549
0
  static char *function                   = "libolecf_item_get_size";
550
551
0
  if( item == NULL )
552
0
  {
553
0
    libcerror_error_set(
554
0
     error,
555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
557
0
     "%s: invalid item.",
558
0
     function );
559
560
0
    return( -1 );
561
0
  }
562
0
  internal_item = (libolecf_internal_item_t *) item;
563
564
0
  if( internal_item->directory_entry == NULL )
565
0
  {
566
0
    libcerror_error_set(
567
0
     error,
568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
569
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
570
0
     "%s: invalid item - missing directory entry.",
571
0
     function );
572
573
0
    return( -1 );
574
0
  }
575
0
  if( size == NULL )
576
0
  {
577
0
    libcerror_error_set(
578
0
     error,
579
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
580
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
581
0
     "%s: invalid size.",
582
0
     function );
583
584
0
    return( -1 );
585
0
  }
586
0
  *size = internal_item->directory_entry->size;
587
588
0
  return( 1 );
589
0
}
590
591
/* Retrieves the creation date and time
592
 * The returned time is a 64-bit version of a FILETIME value
593
 * Returns 1 if successful or -1 on error
594
 */
595
int libolecf_item_get_creation_time(
596
     libolecf_item_t *item,
597
     uint64_t *filetime,
598
     libcerror_error_t **error )
599
0
{
600
0
  libolecf_internal_item_t *internal_item = NULL;
601
0
  static char *function                   = "libolecf_item_get_creation_time";
602
603
0
  if( item == NULL )
604
0
  {
605
0
    libcerror_error_set(
606
0
     error,
607
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
608
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
609
0
     "%s: invalid item.",
610
0
     function );
611
612
0
    return( -1 );
613
0
  }
614
0
  internal_item = (libolecf_internal_item_t *) item;
615
616
0
  if( internal_item->directory_entry == NULL )
617
0
  {
618
0
    libcerror_error_set(
619
0
     error,
620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
621
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
622
0
     "%s: invalid item - missing directory entry.",
623
0
     function );
624
625
0
    return( -1 );
626
0
  }
627
0
  if( filetime == NULL )
628
0
  {
629
0
    libcerror_error_set(
630
0
     error,
631
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
632
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
633
0
     "%s: invalid filetime.",
634
0
     function );
635
636
0
    return( -1 );
637
0
  }
638
0
  *filetime = internal_item->directory_entry->creation_time;
639
640
0
  return( 1 );
641
0
}
642
643
/* Retrieves the modification date and time
644
 * The returned time is a 64-bit version of a FILETIME value
645
 * Returns 1 if successful or -1 on error
646
 */
647
int libolecf_item_get_modification_time(
648
     libolecf_item_t *item,
649
     uint64_t *filetime,
650
     libcerror_error_t **error )
651
0
{
652
0
  libolecf_internal_item_t *internal_item = NULL;
653
0
  static char *function                   = "libolecf_item_get_modification_time";
654
655
0
  if( item == NULL )
656
0
  {
657
0
    libcerror_error_set(
658
0
     error,
659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
660
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
661
0
     "%s: invalid item.",
662
0
     function );
663
664
0
    return( -1 );
665
0
  }
666
0
  internal_item = (libolecf_internal_item_t *) item;
667
668
0
  if( internal_item->directory_entry == NULL )
669
0
  {
670
0
    libcerror_error_set(
671
0
     error,
672
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
673
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
674
0
     "%s: invalid item - missing directory entry.",
675
0
     function );
676
677
0
    return( -1 );
678
0
  }
679
0
  if( filetime == NULL )
680
0
  {
681
0
    libcerror_error_set(
682
0
     error,
683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
685
0
     "%s: invalid filetime.",
686
0
     function );
687
688
0
    return( -1 );
689
0
  }
690
0
  *filetime = internal_item->directory_entry->modification_time;
691
692
0
  return( 1 );
693
0
}
694
695
/* Retrieves the number of sub items from a item
696
 * Returns 1 if successful or -1 on error
697
 */
698
int libolecf_item_get_number_of_sub_items(
699
     libolecf_item_t *item,
700
     int *number_of_sub_items,
701
     libcerror_error_t **error )
702
0
{
703
0
  libolecf_internal_item_t *internal_item = NULL;
704
0
  static char *function                   = "libolecf_item_get_number_of_sub_items";
705
706
0
  if( item == NULL )
707
0
  {
708
0
    libcerror_error_set(
709
0
     error,
710
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
711
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
712
0
     "%s: invalid item.",
713
0
     function );
714
715
0
    return( -1 );
716
0
  }
717
0
  internal_item = (libolecf_internal_item_t *) item;
718
719
0
  if( libcdata_tree_node_get_number_of_sub_nodes(
720
0
       internal_item->directory_tree_node,
721
0
       number_of_sub_items,
722
0
       error ) != 1 )
723
0
  {
724
0
    libcerror_error_set(
725
0
     error,
726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
727
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
728
0
     "%s: unable to retrieve number of sub items.",
729
0
     function );
730
731
0
    return( -1 );
732
0
  }
733
0
  return( 1 );
734
0
}
735
736
/* Retrieves the sub item for the specific index from a item
737
 * Returns 1 if successful or -1 on error
738
 */
739
int libolecf_item_get_sub_item(
740
     libolecf_item_t *item,
741
     int sub_item_index,
742
     libolecf_item_t **sub_item,
743
     libcerror_error_t **error )
744
0
{
745
0
  libolecf_internal_item_t *internal_item       = NULL;
746
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
747
0
  static char *function                         = "libolecf_item_get_sub_item";
748
749
0
  if( item == NULL )
750
0
  {
751
0
    libcerror_error_set(
752
0
     error,
753
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
754
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
755
0
     "%s: invalid item.",
756
0
     function );
757
758
0
    return( -1 );
759
0
  }
760
0
  internal_item = (libolecf_internal_item_t *) item;
761
762
0
  if( internal_item->directory_tree_node == NULL )
763
0
  {
764
0
    libcerror_error_set(
765
0
     error,
766
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
767
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
768
0
     "%s: invalid item - missing directory tree node.",
769
0
     function );
770
771
0
    return( -1 );
772
0
  }
773
0
  if( sub_item == NULL )
774
0
  {
775
0
    libcerror_error_set(
776
0
     error,
777
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
778
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
779
0
     "%s: invalid sub item.",
780
0
     function );
781
782
0
    return( -1 );
783
0
  }
784
0
  if( *sub_item != NULL )
785
0
  {
786
0
    libcerror_error_set(
787
0
     error,
788
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
789
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
790
0
     "%s: sub item already set.",
791
0
     function );
792
793
0
    return( -1 );
794
0
  }
795
0
  if( libcdata_tree_node_get_sub_node_by_index(
796
0
       internal_item->directory_tree_node,
797
0
             sub_item_index,
798
0
             &sub_directory_tree_node,
799
0
       error ) != 1 )
800
0
  {
801
0
    libcerror_error_set(
802
0
     error,
803
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
804
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
805
0
     "%s: unable to retrieve sub directory tree node: %d.",
806
0
     function,
807
0
     sub_item_index );
808
809
0
    return( -1 );
810
0
  }
811
0
  if( sub_directory_tree_node == NULL )
812
0
  {
813
0
    libcerror_error_set(
814
0
     error,
815
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
816
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
817
0
     "%s: invalid sub directory tree node: %d.",
818
0
     function,
819
0
     sub_item_index );
820
821
0
    return( -1 );
822
0
  }
823
0
  if( libolecf_item_initialize(
824
0
       sub_item,
825
0
       internal_item->io_handle,
826
0
       internal_item->file_io_handle,
827
0
       internal_item->file,
828
0
       sub_directory_tree_node,
829
0
       error ) != 1 )
830
0
  {
831
0
    libcerror_error_set(
832
0
     error,
833
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
834
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
835
0
     "%s: unable to create sub item.",
836
0
     function );
837
838
0
    return( -1 );
839
0
  }
840
0
  return( 1 );
841
0
}
842
843
/* Retrieves the sub item for the specific UTF-8 encoded name
844
 * Returns 1 if successful, 0 if no such sub item or -1 on error
845
 */
846
int libolecf_item_get_sub_item_by_utf8_name(
847
     libolecf_item_t *item,
848
     const uint8_t *utf8_string,
849
     size_t utf8_string_length,
850
     libolecf_item_t **sub_item,
851
     libcerror_error_t **error )
852
0
{
853
0
  libolecf_internal_item_t *internal_item       = NULL;
854
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
855
0
  static char *function                         = "libolecf_item_get_sub_item_by_utf8_name";
856
0
  int result                                    = 0;
857
858
0
  if( item == NULL )
859
0
  {
860
0
    libcerror_error_set(
861
0
     error,
862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
863
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
864
0
     "%s: invalid item.",
865
0
     function );
866
867
0
    return( -1 );
868
0
  }
869
0
  internal_item = (libolecf_internal_item_t *) item;
870
871
0
  if( internal_item->io_handle == NULL )
872
0
  {
873
0
    libcerror_error_set(
874
0
     error,
875
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
876
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
877
0
     "%s: invalid item - missing IO handle.",
878
0
     function );
879
880
0
    return( -1 );
881
0
  }
882
0
  if( sub_item == NULL )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
887
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
888
0
     "%s: invalid sub item.",
889
0
     function );
890
891
0
    return( -1 );
892
0
  }
893
0
  if( *sub_item != NULL )
894
0
  {
895
0
    libcerror_error_set(
896
0
     error,
897
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
898
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
899
0
     "%s: sub item already set.",
900
0
     function );
901
902
0
    return( -1 );
903
0
  }
904
0
  result = libolecf_directory_tree_get_sub_node_by_utf8_name(
905
0
            internal_item->directory_tree_node,
906
0
            utf8_string,
907
0
            utf8_string_length,
908
0
            internal_item->io_handle->byte_order,
909
0
            &sub_directory_tree_node,
910
0
            error );
911
912
0
  if( result == -1 )
913
0
  {
914
0
    libcerror_error_set(
915
0
     error,
916
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
917
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
918
0
     "%s: unable to retrieve directory tree sub node by UTF-8 name.",
919
0
     function );
920
921
0
    return( -1 );
922
0
  }
923
0
  else if( result != 0 )
924
0
  {
925
0
    if( sub_directory_tree_node == NULL )
926
0
    {
927
0
      libcerror_error_set(
928
0
       error,
929
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
930
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
931
0
       "%s: invalid sub directory tree node.",
932
0
       function );
933
934
0
      return( -1 );
935
0
    }
936
0
    if( libolecf_item_initialize(
937
0
         sub_item,
938
0
         internal_item->io_handle,
939
0
         internal_item->file_io_handle,
940
0
         internal_item->file,
941
0
         sub_directory_tree_node,
942
0
         error ) != 1 )
943
0
    {
944
0
      libcerror_error_set(
945
0
       error,
946
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
947
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
948
0
       "%s: unable to create sub item.",
949
0
       function );
950
951
0
      return( -1 );
952
0
    }
953
0
  }
954
0
  return( result );
955
0
}
956
957
/* Retrieves the sub item for the specific UTF-16 encoded name
958
 * Returns 1 if successful, 0 if no such sub item or -1 on error
959
 */
960
int libolecf_item_get_sub_item_by_utf16_name(
961
     libolecf_item_t *item,
962
     const uint16_t *utf16_string,
963
     size_t utf16_string_length,
964
     libolecf_item_t **sub_item,
965
     libcerror_error_t **error )
966
0
{
967
0
  libolecf_internal_item_t *internal_item       = NULL;
968
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
969
0
  static char *function                         = "libolecf_item_get_sub_item_by_utf16_name";
970
0
  int result                                    = 0;
971
972
0
  if( item == NULL )
973
0
  {
974
0
    libcerror_error_set(
975
0
     error,
976
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
977
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
978
0
     "%s: invalid item.",
979
0
     function );
980
981
0
    return( -1 );
982
0
  }
983
0
  internal_item = (libolecf_internal_item_t *) item;
984
985
0
  if( internal_item->io_handle == NULL )
986
0
  {
987
0
    libcerror_error_set(
988
0
     error,
989
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
990
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
991
0
     "%s: invalid item - missing IO handle.",
992
0
     function );
993
994
0
    return( -1 );
995
0
  }
996
0
  if( sub_item == NULL )
997
0
  {
998
0
    libcerror_error_set(
999
0
     error,
1000
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1001
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1002
0
     "%s: invalid sub item.",
1003
0
     function );
1004
1005
0
    return( -1 );
1006
0
  }
1007
0
  if( *sub_item != NULL )
1008
0
  {
1009
0
    libcerror_error_set(
1010
0
     error,
1011
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1012
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1013
0
     "%s: sub item already set.",
1014
0
     function );
1015
1016
0
    return( -1 );
1017
0
  }
1018
0
  result = libolecf_directory_tree_get_sub_node_by_utf16_name(
1019
0
            internal_item->directory_tree_node,
1020
0
            utf16_string,
1021
0
            utf16_string_length,
1022
0
            internal_item->io_handle->byte_order,
1023
0
            &sub_directory_tree_node,
1024
0
            error );
1025
1026
0
  if( result == -1 )
1027
0
  {
1028
0
    libcerror_error_set(
1029
0
     error,
1030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1031
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1032
0
     "%s: unable to retrieve directory tree sub node by UTF-16 name.",
1033
0
     function );
1034
1035
0
    return( -1 );
1036
0
  }
1037
0
  else if( result != 0 )
1038
0
  {
1039
0
    if( sub_directory_tree_node == NULL )
1040
0
    {
1041
0
      libcerror_error_set(
1042
0
       error,
1043
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1044
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1045
0
       "%s: invalid sub directory tree node.",
1046
0
       function );
1047
1048
0
      return( -1 );
1049
0
    }
1050
0
    if( libolecf_item_initialize(
1051
0
         sub_item,
1052
0
         internal_item->io_handle,
1053
0
         internal_item->file_io_handle,
1054
0
         internal_item->file,
1055
0
         sub_directory_tree_node,
1056
0
         error ) != 1 )
1057
0
    {
1058
0
      libcerror_error_set(
1059
0
       error,
1060
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1061
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1062
0
       "%s: unable to create sub item.",
1063
0
       function );
1064
1065
0
      return( -1 );
1066
0
    }
1067
0
  }
1068
0
  return( result );
1069
0
}
1070
1071
/* Retrieves the sub item for the specific UTF-8 encoded path
1072
 * The path separator is the \ character
1073
 * Returns 1 if successful, 0 if no such item or -1 on error
1074
 */
1075
int libolecf_item_get_sub_item_by_utf8_path(
1076
     libolecf_item_t *item,
1077
     const uint8_t *utf8_string,
1078
     size_t utf8_string_length,
1079
     libolecf_item_t **sub_item,
1080
     libcerror_error_t **error )
1081
0
{
1082
0
  libolecf_internal_item_t *internal_item       = NULL;
1083
0
  libcdata_tree_node_t *directory_tree_node     = NULL;
1084
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
1085
0
  uint8_t *utf8_string_segment                  = NULL;
1086
0
  static char *function                         = "libolecf_item_get_sub_item_by_utf8_path";
1087
0
  libuna_unicode_character_t unicode_character  = 0;
1088
0
  size_t utf8_string_index                      = 0;
1089
0
  size_t utf8_string_segment_length             = 0;
1090
0
  int result                                    = 0;
1091
1092
0
  if( item == NULL )
1093
0
  {
1094
0
    libcerror_error_set(
1095
0
     error,
1096
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1097
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1098
0
     "%s: invalid item.",
1099
0
     function );
1100
1101
0
    return( -1 );
1102
0
  }
1103
0
  internal_item = (libolecf_internal_item_t *) item;
1104
1105
0
  if( internal_item->io_handle == 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 - missing IO handle.",
1112
0
     function );
1113
1114
0
    return( -1 );
1115
0
  }
1116
0
  if( sub_item == NULL )
1117
0
  {
1118
0
    libcerror_error_set(
1119
0
     error,
1120
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1121
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1122
0
     "%s: invalid sub item.",
1123
0
     function );
1124
1125
0
    return( -1 );
1126
0
  }
1127
0
  if( *sub_item != NULL )
1128
0
  {
1129
0
    libcerror_error_set(
1130
0
     error,
1131
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1132
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1133
0
     "%s: sub item already set.",
1134
0
     function );
1135
1136
0
    return( -1 );
1137
0
  }
1138
0
  directory_tree_node = internal_item->directory_tree_node;
1139
1140
0
  if( utf8_string_length > 0 )
1141
0
  {
1142
    /* Ignore a leading separator
1143
     */
1144
0
    if( utf8_string[ utf8_string_index ] == (uint8_t) LIBOLECF_SEPARATOR )
1145
0
    {
1146
0
      utf8_string_index++;
1147
0
    }
1148
0
  }
1149
0
  if( ( utf8_string_length == 0 )
1150
0
   || ( utf8_string_length == 1 ) )
1151
0
  {
1152
0
    result = 1;
1153
0
  }
1154
0
  else while( utf8_string_index < utf8_string_length )
1155
0
  {
1156
0
    utf8_string_segment        = (uint8_t *) &( utf8_string[ utf8_string_index ] );
1157
0
    utf8_string_segment_length = utf8_string_index;
1158
1159
0
    while( utf8_string_index < utf8_string_length )
1160
0
    {
1161
0
      if( libuna_unicode_character_copy_from_utf8(
1162
0
           &unicode_character,
1163
0
           utf8_string,
1164
0
           utf8_string_length,
1165
0
           &utf8_string_index,
1166
0
           error ) != 1 )
1167
0
      {
1168
0
        libcerror_error_set(
1169
0
         error,
1170
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1172
0
         "%s: unable to copy UTF-8 string to Unicode character.",
1173
0
         function );
1174
1175
0
        return( -1 );
1176
0
      }
1177
0
      if( ( unicode_character == (libuna_unicode_character_t) LIBOLECF_SEPARATOR )
1178
0
       || ( unicode_character == 0 ) )
1179
0
      {
1180
0
        utf8_string_segment_length += 1;
1181
1182
0
        break;
1183
0
      }
1184
0
    }
1185
0
    utf8_string_segment_length = utf8_string_index - utf8_string_segment_length;
1186
1187
0
    if( utf8_string_segment_length == 0 )
1188
0
    {
1189
0
      result = 0;
1190
0
    }
1191
0
    else
1192
0
    {
1193
0
      result = libolecf_directory_tree_get_sub_node_by_utf8_name(
1194
0
          directory_tree_node,
1195
0
          utf8_string_segment,
1196
0
          utf8_string_segment_length,
1197
0
          internal_item->io_handle->byte_order,
1198
0
          &sub_directory_tree_node,
1199
0
          error );
1200
0
    }
1201
0
    if( result == -1 )
1202
0
    {
1203
0
      libcerror_error_set(
1204
0
       error,
1205
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1206
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1207
0
       "%s: unable to retrieve directory tree sub node by UTF-8 name.",
1208
0
       function );
1209
1210
0
      return( -1 );
1211
0
    }
1212
0
    else if( result == 0 )
1213
0
    {
1214
0
      break;
1215
0
    }
1216
0
    directory_tree_node = sub_directory_tree_node;
1217
0
  }
1218
0
  if( result != 0 )
1219
0
  {
1220
0
    if( libolecf_item_initialize(
1221
0
         sub_item,
1222
0
         internal_item->io_handle,
1223
0
         internal_item->file_io_handle,
1224
0
         internal_item->file,
1225
0
         directory_tree_node,
1226
0
         error ) != 1 )
1227
0
    {
1228
0
      libcerror_error_set(
1229
0
       error,
1230
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1231
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1232
0
       "%s: unable to create sub item.",
1233
0
       function );
1234
1235
0
      return( -1 );
1236
0
    }
1237
0
  }
1238
0
  return( result );
1239
0
}
1240
1241
/* Retrieves the sub item for the specific UTF-16 encoded path
1242
 * The path separator is the \ character
1243
 * Returns 1 if successful, 0 if no such item or -1 on error
1244
 */
1245
int libolecf_item_get_sub_item_by_utf16_path(
1246
     libolecf_item_t *item,
1247
     const uint16_t *utf16_string,
1248
     size_t utf16_string_length,
1249
     libolecf_item_t **sub_item,
1250
     libcerror_error_t **error )
1251
0
{
1252
0
  libolecf_internal_item_t *internal_item       = NULL;
1253
0
  libcdata_tree_node_t *directory_tree_node     = NULL;
1254
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
1255
0
  uint16_t *utf16_string_segment                = NULL;
1256
0
  static char *function                         = "libolecf_item_get_sub_item_by_utf16_path";
1257
0
  libuna_unicode_character_t unicode_character  = 0;
1258
0
  size_t utf16_string_index                     = 0;
1259
0
  size_t utf16_string_segment_length            = 0;
1260
0
  int result                                    = 0;
1261
1262
0
  if( item == NULL )
1263
0
  {
1264
0
    libcerror_error_set(
1265
0
     error,
1266
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1267
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1268
0
     "%s: invalid item.",
1269
0
     function );
1270
1271
0
    return( -1 );
1272
0
  }
1273
0
  internal_item = (libolecf_internal_item_t *) item;
1274
1275
0
  if( internal_item->io_handle == NULL )
1276
0
  {
1277
0
    libcerror_error_set(
1278
0
     error,
1279
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1280
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1281
0
     "%s: invalid item - missing IO handle.",
1282
0
     function );
1283
1284
0
    return( -1 );
1285
0
  }
1286
0
  if( sub_item == NULL )
1287
0
  {
1288
0
    libcerror_error_set(
1289
0
     error,
1290
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1291
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1292
0
     "%s: invalid sub item.",
1293
0
     function );
1294
1295
0
    return( -1 );
1296
0
  }
1297
0
  if( *sub_item != NULL )
1298
0
  {
1299
0
    libcerror_error_set(
1300
0
     error,
1301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1302
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1303
0
     "%s: sub item already set.",
1304
0
     function );
1305
1306
0
    return( -1 );
1307
0
  }
1308
0
  directory_tree_node = internal_item->directory_tree_node;
1309
1310
0
  if( utf16_string_length > 0 )
1311
0
  {
1312
    /* Ignore a leading separator
1313
     */
1314
0
    if( utf16_string[ utf16_string_index ] == (uint16_t) LIBOLECF_SEPARATOR )
1315
0
    {
1316
0
      utf16_string_index++;
1317
0
    }
1318
0
  }
1319
0
  if( ( utf16_string_length == 0 )
1320
0
   || ( utf16_string_length == 1 ) )
1321
0
  {
1322
0
    result = 1;
1323
0
  }
1324
0
  else while( utf16_string_index < utf16_string_length )
1325
0
  {
1326
0
    utf16_string_segment        = (uint16_t *) &( utf16_string[ utf16_string_index ] );
1327
0
    utf16_string_segment_length = utf16_string_index;
1328
1329
0
    while( utf16_string_index < utf16_string_length )
1330
0
    {
1331
0
      if( libuna_unicode_character_copy_from_utf16(
1332
0
           &unicode_character,
1333
0
           utf16_string,
1334
0
           utf16_string_length,
1335
0
           &utf16_string_index,
1336
0
           error ) != 1 )
1337
0
      {
1338
0
        libcerror_error_set(
1339
0
         error,
1340
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1341
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1342
0
         "%s: unable to copy UTF-16 string to Unicode character.",
1343
0
         function );
1344
1345
0
        return( -1 );
1346
0
      }
1347
0
      if( ( unicode_character == (libuna_unicode_character_t) LIBOLECF_SEPARATOR )
1348
0
       || ( unicode_character == 0 ) )
1349
0
      {
1350
0
        utf16_string_segment_length += 1;
1351
1352
0
        break;
1353
0
      }
1354
0
    }
1355
0
    utf16_string_segment_length = utf16_string_index - utf16_string_segment_length;
1356
1357
0
    if( utf16_string_segment_length == 0 )
1358
0
    {
1359
0
      result = 0;
1360
0
    }
1361
0
    else
1362
0
    {
1363
0
      result = libolecf_directory_tree_get_sub_node_by_utf16_name(
1364
0
          directory_tree_node,
1365
0
          utf16_string_segment,
1366
0
          utf16_string_segment_length,
1367
0
          internal_item->io_handle->byte_order,
1368
0
          &sub_directory_tree_node,
1369
0
          error );
1370
0
    }
1371
0
    if( result == -1 )
1372
0
    {
1373
0
      libcerror_error_set(
1374
0
       error,
1375
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1376
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1377
0
       "%s: unable to retrieve directory tree sub node by UTF-16 name.",
1378
0
       function );
1379
1380
0
      return( -1 );
1381
0
    }
1382
0
    else if( result == 0 )
1383
0
    {
1384
0
      break;
1385
0
    }
1386
0
    directory_tree_node = sub_directory_tree_node;
1387
0
  }
1388
0
  if( result != 0 )
1389
0
  {
1390
0
    if( libolecf_item_initialize(
1391
0
         sub_item,
1392
0
         internal_item->io_handle,
1393
0
         internal_item->file_io_handle,
1394
0
         internal_item->file,
1395
0
         directory_tree_node,
1396
0
         error ) != 1 )
1397
0
    {
1398
0
      libcerror_error_set(
1399
0
       error,
1400
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1402
0
       "%s: unable to create sub item.",
1403
0
       function );
1404
1405
0
      return( -1 );
1406
0
    }
1407
0
  }
1408
0
  return( result );
1409
0
}
1410