Coverage Report

Created: 2025-07-04 07:01

/src/libolecf/libolecf/libolecf_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File 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 <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "libolecf_codepage.h"
29
#include "libolecf_debug.h"
30
#include "libolecf_definitions.h"
31
#include "libolecf_directory_entry.h"
32
#include "libolecf_directory_tree.h"
33
#include "libolecf_file.h"
34
#include "libolecf_file_header.h"
35
#include "libolecf_item.h"
36
#include "libolecf_io_handle.h"
37
#include "libolecf_libbfio.h"
38
#include "libolecf_libcdata.h"
39
#include "libolecf_libcerror.h"
40
#include "libolecf_libcnotify.h"
41
#include "libolecf_libuna.h"
42
#include "libolecf_types.h"
43
44
/* Creates a file
45
 * Make sure the value file is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libolecf_file_initialize(
49
     libolecf_file_t **file,
50
     libcerror_error_t **error )
51
1.92k
{
52
1.92k
  libolecf_internal_file_t *internal_file = NULL;
53
1.92k
  static char *function                   = "libolecf_file_initialize";
54
55
1.92k
  if( file == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid file.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
1.92k
  if( *file != NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72
0
     "%s: invalid file value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
1.92k
  internal_file = memory_allocate_structure(
78
1.92k
                   libolecf_internal_file_t );
79
80
1.92k
  if( internal_file == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create file.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
1.92k
  if( memory_set(
92
1.92k
       internal_file,
93
1.92k
       0,
94
1.92k
       sizeof( libolecf_internal_file_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear file.",
101
0
     function );
102
103
0
    goto on_error;
104
0
  }
105
1.92k
  if( libolecf_io_handle_initialize(
106
1.92k
       &( internal_file->io_handle ),
107
1.92k
       error ) != 1 )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
112
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
113
0
     "%s: unable to create IO handle.",
114
0
     function );
115
116
0
    goto on_error;
117
0
  }
118
1.92k
  *file = (libolecf_file_t *) internal_file;
119
120
1.92k
  return( 1 );
121
122
0
on_error:
123
0
  if( internal_file != NULL )
124
0
  {
125
0
    memory_free(
126
0
     internal_file );
127
0
  }
128
0
  return( -1 );
129
1.92k
}
130
131
/* Frees a file
132
 * Returns 1 if successful or -1 on error
133
 */
134
int libolecf_file_free(
135
     libolecf_file_t **file,
136
     libcerror_error_t **error )
137
1.92k
{
138
1.92k
  libolecf_internal_file_t *internal_file = NULL;
139
1.92k
  static char *function                   = "libolecf_file_free";
140
1.92k
  int result                              = 1;
141
142
1.92k
  if( file == NULL )
143
0
  {
144
0
    libcerror_error_set(
145
0
     error,
146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
148
0
     "%s: invalid file.",
149
0
     function );
150
151
0
    return( -1 );
152
0
  }
153
1.92k
  if( *file != NULL )
154
1.92k
  {
155
1.92k
    internal_file = (libolecf_internal_file_t *) *file;
156
157
1.92k
    if( internal_file->file_io_handle != NULL )
158
0
    {
159
0
      if( libolecf_file_close(
160
0
           *file,
161
0
           error ) != 0 )
162
0
      {
163
0
        libcerror_error_set(
164
0
         error,
165
0
         LIBCERROR_ERROR_DOMAIN_IO,
166
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
167
0
         "%s: unable to close file.",
168
0
         function );
169
170
0
        result = -1;
171
0
      }
172
0
    }
173
1.92k
    *file = NULL;
174
175
1.92k
    if( internal_file->io_handle != NULL )
176
1.92k
    {
177
1.92k
      if( libolecf_io_handle_free(
178
1.92k
           &( internal_file->io_handle ),
179
1.92k
           error ) != 1 )
180
0
      {
181
0
        libcerror_error_set(
182
0
         error,
183
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
184
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
185
0
         "%s: unable to free IO handle.",
186
0
         function );
187
188
0
        result = -1;
189
0
      }
190
1.92k
    }
191
1.92k
    memory_free(
192
1.92k
     internal_file );
193
1.92k
  }
194
1.92k
  return( result );
195
1.92k
}
196
197
/* Signals the file to abort its current activity
198
 * Returns 1 if successful or -1 on error
199
 */
200
int libolecf_file_signal_abort(
201
     libolecf_file_t *file,
202
     libcerror_error_t **error )
203
0
{
204
0
  libolecf_internal_file_t *internal_file = NULL;
205
0
  static char *function                   = "libolecf_file_signal_abort";
206
207
0
  if( file == NULL )
208
0
  {
209
0
    libcerror_error_set(
210
0
     error,
211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
213
0
     "%s: invalid file.",
214
0
     function );
215
216
0
    return( -1 );
217
0
  }
218
0
  internal_file = (libolecf_internal_file_t *) file;
219
220
0
  if( internal_file->io_handle == NULL )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
226
0
     "%s: invalid file - missing IO handle.",
227
0
     function );
228
229
0
    return( -1 );
230
0
  }
231
0
  internal_file->io_handle->abort = 1;
232
233
0
  return( 1 );
234
0
}
235
236
/* Opens a file
237
 * Returns 1 if successful or -1 on error
238
 */
239
int libolecf_file_open(
240
     libolecf_file_t *file,
241
     const char *filename,
242
     int access_flags,
243
     libcerror_error_t **error )
244
0
{
245
0
  libbfio_handle_t *file_io_handle        = NULL;
246
0
  libolecf_internal_file_t *internal_file = NULL;
247
0
  static char *function                   = "libolecf_file_open";
248
0
  size_t filename_length                  = 0;
249
250
0
  if( file == NULL )
251
0
  {
252
0
    libcerror_error_set(
253
0
     error,
254
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
255
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
256
0
     "%s: invalid file.",
257
0
     function );
258
259
0
    return( -1 );
260
0
  }
261
0
  internal_file = (libolecf_internal_file_t *) file;
262
263
0
  if( filename == NULL )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
269
0
     "%s: invalid filename.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
0
  if( libbfio_file_initialize(
275
0
       &file_io_handle,
276
0
       error ) != 1 )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
282
0
     "%s: unable to create file IO handle.",
283
0
     function );
284
285
0
    goto on_error;
286
0
  }
287
#if defined( HAVE_DEBUG_OUTPUT )
288
  if( libbfio_handle_set_track_offsets_read(
289
       file_io_handle,
290
       1,
291
       error ) != 1 )
292
  {
293
                libcerror_error_set(
294
                 error,
295
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
296
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
297
                 "%s: unable to set track offsets read in file IO handle.",
298
                 function );
299
300
    goto on_error;
301
  }
302
#endif
303
0
  filename_length = narrow_string_length(
304
0
                     filename );
305
306
0
  if( libbfio_file_set_name(
307
0
       file_io_handle,
308
0
       filename,
309
0
       filename_length + 1,
310
0
       error ) != 1 )
311
0
  {
312
0
                libcerror_error_set(
313
0
                 error,
314
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
315
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
316
0
                 "%s: unable to set filename in file IO handle.",
317
0
                 function );
318
319
0
    goto on_error;
320
0
  }
321
0
  if( libolecf_file_open_file_io_handle(
322
0
       file,
323
0
       file_io_handle,
324
0
       access_flags,
325
0
       error ) != 1 )
326
0
  {
327
0
    libcerror_error_set(
328
0
     error,
329
0
     LIBCERROR_ERROR_DOMAIN_IO,
330
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
331
0
     "%s: unable to open file: %s.",
332
0
     function,
333
0
     filename );
334
335
0
    goto on_error;
336
0
  }
337
0
  internal_file->file_io_handle_created_in_library = 1;
338
339
0
  return( 1 );
340
341
0
on_error:
342
0
  if( file_io_handle != NULL )
343
0
  {
344
0
    libbfio_handle_free(
345
0
     &file_io_handle,
346
0
     NULL );
347
0
  }
348
0
  return( -1 );
349
0
}
350
351
#if defined( HAVE_WIDE_CHARACTER_TYPE )
352
353
/* Opens a file
354
 * Returns 1 if successful or -1 on error
355
 */
356
int libolecf_file_open_wide(
357
     libolecf_file_t *file,
358
     const wchar_t *filename,
359
     int access_flags,
360
     libcerror_error_t **error )
361
{
362
  libbfio_handle_t *file_io_handle        = NULL;
363
  libolecf_internal_file_t *internal_file = NULL;
364
  static char *function                   = "libolecf_file_open_wide";
365
  size_t filename_length                  = 0;
366
367
  if( file == NULL )
368
  {
369
    libcerror_error_set(
370
     error,
371
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
373
     "%s: invalid file.",
374
     function );
375
376
    return( -1 );
377
  }
378
  internal_file = (libolecf_internal_file_t *) file;
379
380
  if( filename == NULL )
381
  {
382
    libcerror_error_set(
383
     error,
384
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
385
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
386
     "%s: invalid filename.",
387
     function );
388
389
    return( -1 );
390
  }
391
  if( libbfio_file_initialize(
392
       &file_io_handle,
393
       error ) != 1 )
394
  {
395
    libcerror_error_set(
396
     error,
397
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
398
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
399
     "%s: unable to create file IO handle.",
400
     function );
401
402
    goto on_error;
403
  }
404
#if defined( HAVE_DEBUG_OUTPUT )
405
  if( libbfio_handle_set_track_offsets_read(
406
       file_io_handle,
407
       1,
408
       error ) != 1 )
409
  {
410
                libcerror_error_set(
411
                 error,
412
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
413
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
414
                 "%s: unable to set track offsets read in file IO handle.",
415
                 function );
416
417
    goto on_error;
418
  }
419
#endif
420
  filename_length = wide_string_length(
421
                     filename );
422
423
  if( libbfio_file_set_name_wide(
424
       file_io_handle,
425
       filename,
426
       filename_length + 1,
427
       error ) != 1 )
428
  {
429
                libcerror_error_set(
430
                 error,
431
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
432
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
433
                 "%s: unable to set filename in file IO handle.",
434
                 function );
435
436
    goto on_error;
437
  }
438
  if( libolecf_file_open_file_io_handle(
439
       file,
440
       file_io_handle,
441
       access_flags,
442
       error ) != 1 )
443
  {
444
    libcerror_error_set(
445
     error,
446
     LIBCERROR_ERROR_DOMAIN_IO,
447
     LIBCERROR_IO_ERROR_OPEN_FAILED,
448
     "%s: unable to open file: %ls.",
449
     function,
450
     filename );
451
452
    goto on_error;
453
  }
454
  internal_file->file_io_handle_created_in_library = 1;
455
456
  return( 1 );
457
458
on_error:
459
  if( file_io_handle != NULL )
460
  {
461
    libbfio_handle_free(
462
     &file_io_handle,
463
     NULL );
464
  }
465
  return( -1 );
466
}
467
468
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
469
470
/* Opens a file using a Basic File IO (bfio) handle
471
 * Returns 1 if successful or -1 on error
472
 */
473
int libolecf_file_open_file_io_handle(
474
     libolecf_file_t *file,
475
     libbfio_handle_t *file_io_handle,
476
     int access_flags,
477
     libcerror_error_t **error )
478
1.92k
{
479
1.92k
  libolecf_internal_file_t *internal_file = NULL;
480
1.92k
  static char *function                   = "libolecf_file_open_file_io_handle";
481
1.92k
  int bfio_access_flags                   = 0;
482
1.92k
  int file_io_handle_is_open              = 0;
483
484
1.92k
  if( file == NULL )
485
0
  {
486
0
    libcerror_error_set(
487
0
     error,
488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
490
0
     "%s: invalid file.",
491
0
     function );
492
493
0
    return( -1 );
494
0
  }
495
1.92k
  internal_file = (libolecf_internal_file_t *) file;
496
497
1.92k
  if( internal_file->file_io_handle != NULL )
498
0
  {
499
0
    libcerror_error_set(
500
0
     error,
501
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
502
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
503
0
     "%s: invalid file - file IO handle already set.",
504
0
     function );
505
506
0
    return( -1 );
507
0
  }
508
1.92k
  if( file_io_handle == NULL )
509
0
  {
510
0
    libcerror_error_set(
511
0
     error,
512
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
513
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
514
0
     "%s: invalid file IO handle.",
515
0
     function );
516
517
0
    return( -1 );
518
0
  }
519
1.92k
  if( ( ( access_flags & LIBOLECF_ACCESS_FLAG_READ ) == 0 )
520
1.92k
   && ( ( access_flags & LIBOLECF_ACCESS_FLAG_WRITE ) == 0 ) )
521
0
  {
522
0
    libcerror_error_set(
523
0
     error,
524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
525
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
526
0
     "%s: unsupported access flags.",
527
0
     function );
528
529
0
    return( -1 );
530
0
  }
531
1.92k
  if( ( access_flags & LIBOLECF_ACCESS_FLAG_WRITE ) != 0 )
532
0
  {
533
0
    libcerror_error_set(
534
0
     error,
535
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
536
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
537
0
     "%s: write access currently not supported.",
538
0
     function );
539
540
0
    return( -1 );
541
0
  }
542
1.92k
  if( ( access_flags & LIBOLECF_ACCESS_FLAG_READ ) != 0 )
543
1.92k
  {
544
1.92k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
545
1.92k
  }
546
1.92k
  file_io_handle_is_open = libbfio_handle_is_open(
547
1.92k
                            file_io_handle,
548
1.92k
                            error );
549
550
1.92k
  if( file_io_handle_is_open == -1 )
551
0
  {
552
0
    libcerror_error_set(
553
0
     error,
554
0
     LIBCERROR_ERROR_DOMAIN_IO,
555
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
556
0
     "%s: unable to open file.",
557
0
     function );
558
559
0
    goto on_error;
560
0
  }
561
1.92k
  else if( file_io_handle_is_open == 0 )
562
1.92k
  {
563
1.92k
    if( libbfio_handle_open(
564
1.92k
         file_io_handle,
565
1.92k
         bfio_access_flags,
566
1.92k
         error ) != 1 )
567
0
    {
568
0
      libcerror_error_set(
569
0
       error,
570
0
       LIBCERROR_ERROR_DOMAIN_IO,
571
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
572
0
       "%s: unable to open file IO handle.",
573
0
       function );
574
575
0
      goto on_error;
576
0
    }
577
1.92k
    internal_file->file_io_handle_opened_in_library = 1;
578
1.92k
  }
579
1.92k
  if( libolecf_file_open_read(
580
1.92k
       internal_file,
581
1.92k
       file_io_handle,
582
1.92k
       error ) != 1 )
583
1.76k
  {
584
1.76k
    libcerror_error_set(
585
1.76k
     error,
586
1.76k
     LIBCERROR_ERROR_DOMAIN_IO,
587
1.76k
     LIBCERROR_IO_ERROR_READ_FAILED,
588
1.76k
     "%s: unable to read from file handle.",
589
1.76k
     function );
590
591
1.76k
    goto on_error;
592
1.76k
  }
593
162
  internal_file->file_io_handle = file_io_handle;
594
595
162
  return( 1 );
596
597
1.76k
on_error:
598
1.76k
  if( ( file_io_handle_is_open == 0 )
599
1.76k
   && ( internal_file->file_io_handle_opened_in_library != 0 ) )
600
1.76k
  {
601
1.76k
    libbfio_handle_close(
602
1.76k
     file_io_handle,
603
1.76k
     error );
604
605
1.76k
    internal_file->file_io_handle_opened_in_library = 0;
606
1.76k
  }
607
1.76k
  internal_file->file_io_handle = NULL;
608
609
1.76k
  return( -1 );
610
1.92k
}
611
612
/* Closes a file
613
 * Returns 0 if successful or -1 on error
614
 */
615
int libolecf_file_close(
616
     libolecf_file_t *file,
617
     libcerror_error_t **error )
618
162
{
619
162
  libolecf_internal_file_t *internal_file = NULL;
620
162
  static char *function                   = "libolecf_file_close";
621
162
  int result                              = 0;
622
623
162
  if( file == NULL )
624
0
  {
625
0
    libcerror_error_set(
626
0
     error,
627
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
628
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
629
0
     "%s: invalid file.",
630
0
     function );
631
632
0
    return( -1 );
633
0
  }
634
162
  internal_file = (libolecf_internal_file_t *) file;
635
636
162
  if( internal_file->file_io_handle == NULL )
637
0
  {
638
0
    libcerror_error_set(
639
0
     error,
640
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
641
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
642
0
     "%s: invalid file - missing file IO handle.",
643
0
     function );
644
645
0
    return( -1 );
646
0
  }
647
#if defined( HAVE_DEBUG_OUTPUT )
648
  if( libcnotify_verbose != 0 )
649
  {
650
    if( internal_file->file_io_handle_created_in_library != 0 )
651
    {
652
      if( libolecf_debug_print_read_offsets(
653
           internal_file->file_io_handle,
654
           error ) != 1 )
655
      {
656
        libcerror_error_set(
657
         error,
658
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
659
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
660
         "%s: unable to print the read offsets.",
661
         function );
662
663
        result = -1;
664
      }
665
    }
666
  }
667
#endif
668
162
  if( internal_file->file_io_handle_opened_in_library != 0 )
669
162
  {
670
162
    if( libbfio_handle_close(
671
162
         internal_file->file_io_handle,
672
162
         error ) != 0 )
673
0
    {
674
0
      libcerror_error_set(
675
0
       error,
676
0
       LIBCERROR_ERROR_DOMAIN_IO,
677
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
678
0
       "%s: unable to close file IO handle.",
679
0
       function );
680
681
0
      result = -1;
682
0
    }
683
162
    internal_file->file_io_handle_opened_in_library = 0;
684
162
  }
685
162
  if( internal_file->file_io_handle_created_in_library != 0 )
686
0
  {
687
0
    if( libbfio_handle_free(
688
0
         &( internal_file->file_io_handle ),
689
0
         error ) != 1 )
690
0
    {
691
0
      libcerror_error_set(
692
0
       error,
693
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
694
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
695
0
       "%s: unable to free file IO handle.",
696
0
       function );
697
698
0
      result = -1;
699
0
    }
700
0
    internal_file->file_io_handle_created_in_library = 0;
701
0
  }
702
162
  internal_file->file_io_handle = NULL;
703
704
162
  if( libolecf_io_handle_clear(
705
162
       internal_file->io_handle,
706
162
       error ) != 1 )
707
0
  {
708
0
    libcerror_error_set(
709
0
     error,
710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
711
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
712
0
     "%s: unable to clear IO handle.",
713
0
     function );
714
715
0
    result = -1;
716
0
  }
717
162
  if( internal_file->msat != NULL )
718
162
  {
719
162
     if( libolecf_allocation_table_free(
720
162
          &( internal_file->msat ),
721
162
          error ) != 1 )
722
0
    {
723
0
      libcerror_error_set(
724
0
       error,
725
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
726
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
727
0
       "%s: unable to free MSAT.",
728
0
       function );
729
730
0
      result = -1;
731
0
    }
732
162
  }
733
162
  if( internal_file->sat != NULL )
734
162
  {
735
162
    if( libolecf_allocation_table_free(
736
162
         &( internal_file->sat ),
737
162
         error ) != 1 )
738
0
    {
739
0
      libcerror_error_set(
740
0
       error,
741
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
742
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
743
0
       "%s: unable to free SAT.",
744
0
       function );
745
746
0
      result = -1;
747
0
    }
748
162
  }
749
162
  if( internal_file->ssat != NULL )
750
162
  {
751
162
     if( libolecf_allocation_table_free(
752
162
          &( internal_file->ssat ),
753
162
          error ) != 1 )
754
0
    {
755
0
      libcerror_error_set(
756
0
       error,
757
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
758
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
759
0
       "%s: unable to free SSAT.",
760
0
       function );
761
762
0
      result = -1;
763
0
    }
764
162
  }
765
162
  if( internal_file->unallocated_block_list != NULL )
766
0
  {
767
0
    if( libcdata_range_list_free(
768
0
         &( internal_file->unallocated_block_list ),
769
0
         NULL,
770
0
         error ) != 1 )
771
0
    {
772
0
      libcerror_error_set(
773
0
       error,
774
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
776
0
       "%s: unable to free unallocated block list.",
777
0
       function );
778
779
0
      result = -1;
780
0
    }
781
0
  }
782
162
  if( internal_file->directory_tree_root_node != NULL )
783
74
  {
784
74
    if( libcdata_tree_node_free(
785
74
         &( internal_file->directory_tree_root_node ),
786
74
         (int (*)(intptr_t **, libcerror_error_t **)) &libolecf_directory_entry_free,
787
74
         error ) != 1 )
788
0
    {
789
0
      libcerror_error_set(
790
0
       error,
791
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
792
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
793
0
       "%s: unable to free directory tree.",
794
0
       function );
795
796
0
      result = -1;
797
0
    }
798
74
  }
799
162
  return( result );
800
162
}
801
802
/* Opens a file for reading
803
 * Returns 1 if successful or -1 on error
804
 */
805
int libolecf_file_open_read(
806
     libolecf_internal_file_t *internal_file,
807
     libbfio_handle_t *file_io_handle,
808
     libcerror_error_t **error )
809
1.92k
{
810
1.92k
  libcdata_list_t *directory_entry_list = NULL;
811
1.92k
  libolecf_file_header_t *file_header   = NULL;
812
1.92k
  static char *function                 = "libolecf_file_open_read";
813
1.92k
  int result                            = 0;
814
815
1.92k
  if( internal_file == NULL )
816
0
  {
817
0
    libcerror_error_set(
818
0
     error,
819
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
820
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
821
0
     "%s: invalid file.",
822
0
     function );
823
824
0
    return( -1 );
825
0
  }
826
1.92k
  if( internal_file->io_handle == NULL )
827
0
  {
828
0
    libcerror_error_set(
829
0
     error,
830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
831
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
832
0
     "%s: invalid file - missing IO handle.",
833
0
     function );
834
835
0
    return( -1 );
836
0
  }
837
1.92k
  if( internal_file->msat != NULL )
838
0
  {
839
0
    libcerror_error_set(
840
0
     error,
841
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
842
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
843
0
     "%s: invalid file - MSAT already set.",
844
0
     function );
845
846
0
    return( -1 );
847
0
  }
848
1.92k
  if( internal_file->sat != NULL )
849
0
  {
850
0
    libcerror_error_set(
851
0
     error,
852
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
853
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
854
0
     "%s: invalid file - SAT already set.",
855
0
     function );
856
857
0
    return( -1 );
858
0
  }
859
1.92k
  if( internal_file->ssat != NULL )
860
0
  {
861
0
    libcerror_error_set(
862
0
     error,
863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
864
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
865
0
     "%s: invalid file - SSAT already set.",
866
0
     function );
867
868
0
    return( -1 );
869
0
  }
870
1.92k
  if( internal_file->unallocated_block_list != NULL )
871
0
  {
872
0
    libcerror_error_set(
873
0
     error,
874
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
875
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
876
0
     "%s: invalid file - unallocated block list already set.",
877
0
     function );
878
879
0
    return( -1 );
880
0
  }
881
1.92k
  if( internal_file->directory_tree_root_node != NULL )
882
0
  {
883
0
    libcerror_error_set(
884
0
     error,
885
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
886
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
887
0
     "%s: invalid file - directory tree root node already set.",
888
0
     function );
889
890
0
    return( -1 );
891
0
  }
892
#if defined( HAVE_DEBUG_OUTPUT )
893
  if( libcnotify_verbose != 0 )
894
  {
895
    libcnotify_printf(
896
     "Reading file header:\n" );
897
  }
898
#endif
899
1.92k
  if( libolecf_file_header_initialize(
900
1.92k
       &file_header,
901
1.92k
       error ) != 1 )
902
0
  {
903
0
    libcerror_error_set(
904
0
     error,
905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
906
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
907
0
     "%s: unable to create file header.",
908
0
     function );
909
910
0
    goto on_error;
911
0
  }
912
1.92k
  if( libolecf_allocation_table_initialize(
913
1.92k
       &( internal_file->msat ),
914
1.92k
       109,
915
1.92k
       error ) != 1 )
916
0
  {
917
0
    libcerror_error_set(
918
0
     error,
919
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
920
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
921
0
     "%s: unable to create MSAT.",
922
0
     function );
923
924
0
    goto on_error;
925
0
  }
926
1.92k
  if( libolecf_file_header_read_file_io_handle(
927
1.92k
       file_header,
928
1.92k
       file_io_handle,
929
1.92k
       internal_file->msat,
930
1.92k
       error ) != 1 )
931
269
  {
932
269
    libcerror_error_set(
933
269
     error,
934
269
     LIBCERROR_ERROR_DOMAIN_IO,
935
269
     LIBCERROR_IO_ERROR_READ_FAILED,
936
269
     "%s: unable to read file header.",
937
269
     function );
938
939
269
    goto on_error;
940
269
  }
941
1.65k
  internal_file->io_handle->byte_order                      = file_header->byte_order;
942
1.65k
  internal_file->io_handle->major_format_version            = file_header->major_format_version;
943
1.65k
  internal_file->io_handle->minor_format_version            = file_header->minor_format_version;
944
1.65k
  internal_file->io_handle->sector_stream_minimum_data_size = file_header->sector_stream_minimum_data_size;
945
1.65k
  internal_file->io_handle->sector_size                     = file_header->sector_size;
946
1.65k
  internal_file->io_handle->short_sector_size               = file_header->short_sector_size;
947
948
#if defined( HAVE_DEBUG_OUTPUT )
949
  if( libcnotify_verbose != 0 )
950
  {
951
    libcnotify_printf(
952
     "Reading master sector allocation table (MSAT):\n" );
953
  }
954
#endif
955
1.65k
  if( libolecf_io_handle_read_msat(
956
1.65k
       internal_file->io_handle,
957
1.65k
       file_io_handle,
958
1.65k
       internal_file->msat,
959
1.65k
       file_header->msat_sector_identifier,
960
1.65k
       file_header->number_of_msat_sectors,
961
1.65k
       error ) != 1 )
962
141
  {
963
141
    libcerror_error_set(
964
141
     error,
965
141
     LIBCERROR_ERROR_DOMAIN_IO,
966
141
     LIBCERROR_IO_ERROR_READ_FAILED,
967
141
     "%s: unable to read MSAT.",
968
141
     function );
969
970
141
    goto on_error;
971
141
  }
972
#if defined( HAVE_DEBUG_OUTPUT )
973
  if( libcnotify_verbose != 0 )
974
  {
975
    libcnotify_printf(
976
     "Reading sector allocation table (SAT):\n" );
977
  }
978
#endif
979
1.51k
  if( libolecf_allocation_table_initialize(
980
1.51k
       &( internal_file->sat ),
981
1.51k
       0,
982
1.51k
       error ) != 1 )
983
0
  {
984
0
    libcerror_error_set(
985
0
     error,
986
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
987
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
988
0
     "%s: unable to create SAT.",
989
0
     function );
990
991
0
    goto on_error;
992
0
  }
993
1.51k
  if( libolecf_io_handle_read_sat(
994
1.51k
       internal_file->io_handle,
995
1.51k
       file_io_handle,
996
1.51k
       internal_file->msat,
997
1.51k
       internal_file->sat,
998
1.51k
       file_header->number_of_sat_sectors,
999
1.51k
       error ) != 1 )
1000
0
  {
1001
0
    libcerror_error_set(
1002
0
     error,
1003
0
     LIBCERROR_ERROR_DOMAIN_IO,
1004
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1005
0
     "%s: unable to read SAT.",
1006
0
     function );
1007
1008
0
    goto on_error;
1009
0
  }
1010
#if defined( HAVE_DEBUG_OUTPUT )
1011
  if( libcnotify_verbose != 0 )
1012
  {
1013
    libcnotify_printf(
1014
     "Reading short sector allocation table (SSAT):\n" );
1015
  }
1016
#endif
1017
1.51k
  if( libolecf_allocation_table_initialize(
1018
1.51k
       &( internal_file->ssat ),
1019
1.51k
       0,
1020
1.51k
       error ) != 1 )
1021
0
  {
1022
0
    libcerror_error_set(
1023
0
     error,
1024
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1025
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1026
0
     "%s: unable to create SSAT.",
1027
0
     function );
1028
1029
0
    goto on_error;
1030
0
  }
1031
1.51k
  if( libolecf_io_handle_read_ssat(
1032
1.51k
       internal_file->io_handle,
1033
1.51k
       file_io_handle,
1034
1.51k
       internal_file->sat,
1035
1.51k
       internal_file->ssat,
1036
1.51k
       file_header->ssat_sector_identifier,
1037
1.51k
       file_header->number_of_ssat_sectors,
1038
1.51k
       error ) != 1 )
1039
0
  {
1040
0
    libcerror_error_set(
1041
0
     error,
1042
0
     LIBCERROR_ERROR_DOMAIN_IO,
1043
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1044
0
     "%s: unable to read SSAT.",
1045
0
     function );
1046
1047
0
    goto on_error;
1048
0
  }
1049
#if defined( HAVE_DEBUG_OUTPUT )
1050
  if( libcnotify_verbose != 0 )
1051
  {
1052
    libcnotify_printf(
1053
     "Reading directory entries:\n" );
1054
  }
1055
#endif
1056
1.51k
  if( libcdata_list_initialize(
1057
1.51k
       &directory_entry_list,
1058
1.51k
       error ) != 1 )
1059
0
  {
1060
0
    libcerror_error_set(
1061
0
     error,
1062
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1063
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1064
0
     "%s: unable to create directory entry list.",
1065
0
     function );
1066
1067
0
    goto on_error;
1068
0
  }
1069
1.51k
  if( libolecf_io_handle_read_directory_entries(
1070
1.51k
       internal_file->io_handle,
1071
1.51k
       file_io_handle,
1072
1.51k
       internal_file->sat,
1073
1.51k
       directory_entry_list,
1074
1.51k
       file_header->root_directory_sector_identifier,
1075
1.51k
       error ) != 1 )
1076
757
  {
1077
757
    libcerror_error_set(
1078
757
     error,
1079
757
     LIBCERROR_ERROR_DOMAIN_IO,
1080
757
     LIBCERROR_IO_ERROR_READ_FAILED,
1081
757
     "%s: unable to read directory entries.",
1082
757
     function );
1083
1084
757
    goto on_error;
1085
757
  }
1086
756
  if( libolecf_file_header_free(
1087
756
       &file_header,
1088
756
       error ) != 1 )
1089
0
  {
1090
0
    libcerror_error_set(
1091
0
     error,
1092
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1093
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1094
0
     "%s: unable to free file header.",
1095
0
     function );
1096
1097
0
    goto on_error;
1098
0
  }
1099
#if defined( HAVE_DEBUG_OUTPUT )
1100
  if( libcnotify_verbose != 0 )
1101
  {
1102
    libcnotify_printf(
1103
     "Creating directory tree:\n" );
1104
  }
1105
#endif
1106
756
  result = libolecf_directory_tree_create(
1107
756
            &( internal_file->directory_tree_root_node ),
1108
756
            &( internal_file->io_handle->short_sector_stream_start_sector_identifier ),
1109
756
            &( internal_file->document_summary_information_directory_entry ),
1110
756
            &( internal_file->summary_information_directory_entry ),
1111
756
            directory_entry_list,
1112
756
            internal_file->io_handle->byte_order,
1113
756
            error );
1114
1115
756
  if( result == -1 )
1116
594
  {
1117
594
    libcerror_error_set(
1118
594
     error,
1119
594
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1120
594
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1121
594
     "%s: unable to create directory tree.",
1122
594
     function );
1123
1124
594
    goto on_error;
1125
594
  }
1126
162
  if( libcdata_list_free(
1127
162
       &directory_entry_list,
1128
162
       (int (*)(intptr_t **, libcerror_error_t **)) &libolecf_directory_entry_free_not_in_tree,
1129
162
       error ) != 1 )
1130
0
  {
1131
0
    libcerror_error_set(
1132
0
     error,
1133
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1134
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1135
0
     "%s: unable to free directory entry list.",
1136
0
     function );
1137
1138
0
    goto on_error;
1139
0
  }
1140
162
  return( 1 );
1141
1142
1.76k
on_error:
1143
1.76k
  if( internal_file->unallocated_block_list != NULL )
1144
0
  {
1145
0
    libcdata_range_list_free(
1146
0
     &( internal_file->unallocated_block_list ),
1147
0
     NULL,
1148
0
     NULL );
1149
0
  }
1150
1.76k
  if( internal_file->directory_tree_root_node != NULL )
1151
0
  {
1152
0
    libcdata_tree_node_free(
1153
0
     &( internal_file->directory_tree_root_node ),
1154
0
     NULL,
1155
0
     NULL );
1156
0
  }
1157
1.76k
  if( directory_entry_list != NULL )
1158
1.35k
  {
1159
1.35k
    libcdata_list_free(
1160
1.35k
     &directory_entry_list,
1161
1.35k
     (int (*)(intptr_t **, libcerror_error_t **)) &libolecf_directory_entry_free,
1162
1.35k
     NULL );
1163
1.35k
  }
1164
1.76k
  if( internal_file->ssat != NULL )
1165
1.35k
  {
1166
1.35k
    libolecf_allocation_table_free(
1167
1.35k
     &( internal_file->ssat ),
1168
1.35k
     NULL );
1169
1.35k
  }
1170
1.76k
  if( internal_file->sat != NULL )
1171
1.35k
  {
1172
1.35k
    libolecf_allocation_table_free(
1173
1.35k
     &( internal_file->sat ),
1174
1.35k
     NULL );
1175
1.35k
  }
1176
1.76k
  if( internal_file->msat != NULL )
1177
1.76k
  {
1178
1.76k
    libolecf_allocation_table_free(
1179
1.76k
     &( internal_file->msat ),
1180
1.76k
     NULL );
1181
1.76k
  }
1182
1.76k
  if( file_header != NULL )
1183
1.16k
  {
1184
1.16k
    libolecf_file_header_free(
1185
1.16k
     &file_header,
1186
1.16k
     NULL );
1187
1.16k
  }
1188
1.76k
  return( -1 );
1189
162
}
1190
1191
/* Retrieves the sector size
1192
 * Returns 1 if successful or -1 on error
1193
 */
1194
int libolecf_file_get_sector_size(
1195
     libolecf_file_t *file,
1196
     size32_t *sector_size,
1197
     libcerror_error_t **error )
1198
0
{
1199
0
  libolecf_internal_file_t *internal_file = NULL;
1200
0
  static char *function                   = "libolecf_file_get_sector_size";
1201
1202
0
  if( file == NULL )
1203
0
  {
1204
0
    libcerror_error_set(
1205
0
     error,
1206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1207
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1208
0
     "%s: invalid file.",
1209
0
     function );
1210
1211
0
    return( -1 );
1212
0
  }
1213
0
  internal_file = (libolecf_internal_file_t *) file;
1214
1215
0
  if( internal_file->io_handle == NULL )
1216
0
  {
1217
0
    libcerror_error_set(
1218
0
     error,
1219
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1220
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1221
0
     "%s: invalid file - missing IO handle.",
1222
0
     function );
1223
1224
0
    return( -1 );
1225
0
  }
1226
0
  if( sector_size == NULL )
1227
0
  {
1228
0
    libcerror_error_set(
1229
0
     error,
1230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1231
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1232
0
     "%s: invalid size.",
1233
0
     function );
1234
1235
0
    return( -1 );
1236
0
  }
1237
0
  if( internal_file->io_handle->sector_size > (size_t) UINT32_MAX )
1238
0
  {
1239
0
    libcerror_error_set(
1240
0
     error,
1241
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1242
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1243
0
     "%s: invalid sector size value exceeds maximum.",
1244
0
     function );
1245
1246
0
    return( -1 );
1247
0
  }
1248
0
  *sector_size = (size32_t) internal_file->io_handle->sector_size;
1249
1250
0
  return( 1 );
1251
0
}
1252
1253
/* Retrieves the short sector size
1254
 * Returns 1 if successful or -1 on error
1255
 */
1256
int libolecf_file_get_short_sector_size(
1257
     libolecf_file_t *file,
1258
     size32_t *short_sector_size,
1259
     libcerror_error_t **error )
1260
0
{
1261
0
  libolecf_internal_file_t *internal_file = NULL;
1262
0
  static char *function                   = "libolecf_file_get_short_sector_size";
1263
1264
0
  if( file == NULL )
1265
0
  {
1266
0
    libcerror_error_set(
1267
0
     error,
1268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1269
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1270
0
     "%s: invalid file.",
1271
0
     function );
1272
1273
0
    return( -1 );
1274
0
  }
1275
0
  internal_file = (libolecf_internal_file_t *) file;
1276
1277
0
  if( internal_file->io_handle == NULL )
1278
0
  {
1279
0
    libcerror_error_set(
1280
0
     error,
1281
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1282
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1283
0
     "%s: invalid file - missing IO handle.",
1284
0
     function );
1285
1286
0
    return( -1 );
1287
0
  }
1288
0
  if( short_sector_size == NULL )
1289
0
  {
1290
0
    libcerror_error_set(
1291
0
     error,
1292
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1293
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1294
0
     "%s: invalid size.",
1295
0
     function );
1296
1297
0
    return( -1 );
1298
0
  }
1299
0
  if( internal_file->io_handle->short_sector_size > (size_t) UINT32_MAX )
1300
0
  {
1301
0
    libcerror_error_set(
1302
0
     error,
1303
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1304
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1305
0
     "%s: invalid short sector size value exceeds maximum.",
1306
0
     function );
1307
1308
0
    return( -1 );
1309
0
  }
1310
0
  *short_sector_size = (size32_t) internal_file->io_handle->short_sector_size;
1311
1312
0
  return( 1 );
1313
0
}
1314
1315
/* Retrieves the ASCII codepage
1316
 * Returns 1 if successful or -1 on error
1317
 */
1318
int libolecf_file_get_ascii_codepage(
1319
     libolecf_file_t *file,
1320
     int *ascii_codepage,
1321
     libcerror_error_t **error )
1322
0
{
1323
0
  libolecf_internal_file_t *internal_file = NULL;
1324
0
  static char *function                   = "libolecf_file_get_ascii_codepage";
1325
1326
0
  if( file == NULL )
1327
0
  {
1328
0
    libcerror_error_set(
1329
0
     error,
1330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1331
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1332
0
     "%s: invalid file.",
1333
0
     function );
1334
1335
0
    return( -1 );
1336
0
  }
1337
0
  internal_file = (libolecf_internal_file_t *) file;
1338
1339
0
  if( internal_file->io_handle == NULL )
1340
0
  {
1341
0
    libcerror_error_set(
1342
0
     error,
1343
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1344
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1345
0
     "%s: invalid file - missing IO handle.",
1346
0
     function );
1347
1348
0
    return( -1 );
1349
0
  }
1350
0
  if( ascii_codepage == NULL )
1351
0
  {
1352
0
    libcerror_error_set(
1353
0
     error,
1354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1355
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1356
0
     "%s: invalid ASCII codepage.",
1357
0
     function );
1358
1359
0
    return( -1 );
1360
0
  }
1361
0
  *ascii_codepage = internal_file->io_handle->ascii_codepage;
1362
1363
0
  return( 1 );
1364
0
}
1365
1366
/* Sets the ASCII codepage
1367
 * Returns 1 if successful or -1 on error
1368
 */
1369
int libolecf_file_set_ascii_codepage(
1370
     libolecf_file_t *file,
1371
     int ascii_codepage,
1372
     libcerror_error_t **error )
1373
0
{
1374
0
  libolecf_internal_file_t *internal_file = NULL;
1375
0
  static char *function                   = "libolecf_file_set_ascii_codepage";
1376
1377
0
  if( file == NULL )
1378
0
  {
1379
0
    libcerror_error_set(
1380
0
     error,
1381
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1382
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1383
0
     "%s: invalid file.",
1384
0
     function );
1385
1386
0
    return( -1 );
1387
0
  }
1388
0
  internal_file = (libolecf_internal_file_t *) file;
1389
1390
0
  if( internal_file->io_handle == NULL )
1391
0
  {
1392
0
    libcerror_error_set(
1393
0
     error,
1394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1395
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1396
0
     "%s: invalid file - missing IO handle.",
1397
0
     function );
1398
1399
0
    return( -1 );
1400
0
  }
1401
0
  if( ( ascii_codepage != LIBOLECF_CODEPAGE_ASCII )
1402
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_874 )
1403
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_932 )
1404
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_936 )
1405
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_949 )
1406
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_950 )
1407
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1250 )
1408
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1251 )
1409
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1252 )
1410
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1253 )
1411
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1254 )
1412
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1255 )
1413
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1256 )
1414
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1257 )
1415
0
   && ( ascii_codepage != LIBOLECF_CODEPAGE_WINDOWS_1258 ) )
1416
0
  {
1417
0
    libcerror_error_set(
1418
0
     error,
1419
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1420
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1421
0
     "%s: unsupported ASCII codepage.",
1422
0
     function );
1423
1424
0
    return( -1 );
1425
0
  }
1426
0
  internal_file->io_handle->ascii_codepage = ascii_codepage;
1427
1428
0
  return( 1 );
1429
0
}
1430
1431
/* Retrieves the format version
1432
 * Returns 1 if successful or -1 on error
1433
 */
1434
int libolecf_file_get_format_version(
1435
     libolecf_file_t *file,
1436
     uint16_t *major_version,
1437
     uint16_t *minor_version,
1438
     libcerror_error_t **error )
1439
0
{
1440
0
  libolecf_internal_file_t *internal_file = NULL;
1441
0
  static char *function                   = "libolecf_file_get_format_version";
1442
1443
0
  if( file == NULL )
1444
0
  {
1445
0
    libcerror_error_set(
1446
0
     error,
1447
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1448
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1449
0
     "%s: invalid file.",
1450
0
     function );
1451
1452
0
    return( -1 );
1453
0
  }
1454
0
  internal_file = (libolecf_internal_file_t *) file;
1455
1456
0
  if( internal_file->io_handle == NULL )
1457
0
  {
1458
0
    libcerror_error_set(
1459
0
     error,
1460
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1461
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1462
0
     "%s: invalid file - missing IO handle.",
1463
0
     function );
1464
1465
0
    return( -1 );
1466
0
  }
1467
0
  if( major_version == NULL )
1468
0
  {
1469
0
    libcerror_error_set(
1470
0
     error,
1471
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1472
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1473
0
     "%s: invalid major version.",
1474
0
     function );
1475
1476
0
    return( -1 );
1477
0
  }
1478
0
  if( minor_version == NULL )
1479
0
  {
1480
0
    libcerror_error_set(
1481
0
     error,
1482
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1483
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1484
0
     "%s: invalid minor version.",
1485
0
     function );
1486
1487
0
    return( -1 );
1488
0
  }
1489
0
  *major_version = internal_file->io_handle->major_format_version;
1490
0
  *minor_version = internal_file->io_handle->minor_format_version;
1491
1492
0
  return( 1 );
1493
0
}
1494
1495
/* Retrieves the number of unallocated blocks
1496
 * Returns 1 if successful or -1 on error
1497
 */
1498
int libolecf_file_get_number_of_unallocated_blocks(
1499
     libolecf_file_t *file,
1500
     int *number_of_unallocated_blocks,
1501
     libcerror_error_t **error )
1502
0
{
1503
0
  libolecf_internal_file_t *internal_file = NULL;
1504
0
  static char *function                   = "libolecf_file_get_number_of_unallocated_blocks";
1505
1506
0
  if( file == NULL )
1507
0
  {
1508
0
    libcerror_error_set(
1509
0
     error,
1510
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1511
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1512
0
     "%s: invalid file.",
1513
0
     function );
1514
1515
0
    return( -1 );
1516
0
  }
1517
0
  internal_file = (libolecf_internal_file_t *) file;
1518
1519
0
  if( internal_file->unallocated_block_list == NULL )
1520
0
  {
1521
0
    if( number_of_unallocated_blocks == NULL )
1522
0
    {
1523
0
      libcerror_error_set(
1524
0
       error,
1525
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1526
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1527
0
       "%s: invalid number of unallocated blocks.",
1528
0
       function );
1529
1530
0
      return( -1 );
1531
0
    }
1532
0
    *number_of_unallocated_blocks = 0;
1533
0
  }
1534
0
  else
1535
0
  {
1536
0
    if( libcdata_range_list_get_number_of_elements(
1537
0
         internal_file->unallocated_block_list,
1538
0
         number_of_unallocated_blocks,
1539
0
         error ) != 1 )
1540
0
    {
1541
0
      libcerror_error_set(
1542
0
       error,
1543
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1544
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1545
0
       "%s: unable to retrieve number of elements.",
1546
0
       function );
1547
1548
0
      return( -1 );
1549
0
    }
1550
0
  }
1551
0
  return( 1 );
1552
0
}
1553
1554
/* Retrieves a specific unallocated block
1555
 * Returns 1 if successful or -1 on error
1556
 */
1557
int libolecf_file_get_unallocated_block(
1558
     libolecf_file_t *file,
1559
     int unallocated_block_index,
1560
     off64_t *offset,
1561
     size64_t *size,
1562
     libcerror_error_t **error )
1563
0
{
1564
0
  libolecf_internal_file_t *internal_file = NULL;
1565
0
  static char *function                   = "libolecf_file_get_unallocated_block";
1566
0
  intptr_t *value                         = NULL;
1567
1568
0
  if( file == NULL )
1569
0
  {
1570
0
    libcerror_error_set(
1571
0
     error,
1572
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1573
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1574
0
     "%s: invalid file.",
1575
0
     function );
1576
1577
0
    return( -1 );
1578
0
  }
1579
0
  internal_file = (libolecf_internal_file_t *) file;
1580
1581
0
  if( libcdata_range_list_get_range_by_index(
1582
0
       internal_file->unallocated_block_list,
1583
0
       unallocated_block_index,
1584
0
       (uint64_t *) offset,
1585
0
       (uint64_t *) size,
1586
0
       &value,
1587
0
       error ) != 1 )
1588
0
  {
1589
0
    libcerror_error_set(
1590
0
     error,
1591
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1592
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1593
0
     "%s: unable to retrieve unallocated block range: %d.",
1594
0
     function,
1595
0
     internal_file->unallocated_block_list );
1596
1597
0
    return( -1 );
1598
0
  }
1599
0
  return( 1 );
1600
0
}
1601
1602
/* Retrieves the root item from the file
1603
 * Returns 1 if successful, 0 if no such item or -1 on error
1604
 */
1605
int libolecf_file_get_root_item(
1606
     libolecf_file_t *file,
1607
     libolecf_item_t **root_item,
1608
     libcerror_error_t **error )
1609
87
{
1610
87
  libolecf_internal_file_t *internal_file = NULL;
1611
87
  static char *function                   = "libolecf_file_get_root_item";
1612
1613
87
  if( file == NULL )
1614
0
  {
1615
0
    libcerror_error_set(
1616
0
     error,
1617
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1618
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1619
0
     "%s: invalid file.",
1620
0
     function );
1621
1622
0
    return( -1 );
1623
0
  }
1624
87
  internal_file = (libolecf_internal_file_t *) file;
1625
1626
87
  if( root_item == NULL )
1627
0
  {
1628
0
    libcerror_error_set(
1629
0
     error,
1630
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1631
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1632
0
     "%s: invalid root item.",
1633
0
     function );
1634
1635
0
    return( -1 );
1636
0
  }
1637
87
  if( *root_item != NULL )
1638
0
  {
1639
0
    libcerror_error_set(
1640
0
     error,
1641
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1642
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1643
0
     "%s: root item already set.",
1644
0
     function );
1645
1646
0
    return( -1 );
1647
0
  }
1648
87
  if( internal_file->directory_tree_root_node == NULL )
1649
41
  {
1650
41
    return( 0 );
1651
41
  }
1652
46
  if( libolecf_item_initialize(
1653
46
       root_item,
1654
46
       internal_file->io_handle,
1655
46
       internal_file->file_io_handle,
1656
46
       internal_file,
1657
46
       internal_file->directory_tree_root_node,
1658
46
       error ) != 1 )
1659
0
  {
1660
0
    libcerror_error_set(
1661
0
     error,
1662
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1663
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1664
0
     "%s: unable to create root item.",
1665
0
     function );
1666
1667
0
    return( -1 );
1668
0
  }
1669
46
  return( 1 );
1670
46
}
1671
1672
/* Retrieves the item for the specific UTF-8 encoded path
1673
 * The path separator is the \ character
1674
 * Returns 1 if successful, 0 if no such item or -1 on error
1675
 */
1676
int libolecf_file_get_item_by_utf8_path(
1677
     libolecf_file_t *file,
1678
     const uint8_t *utf8_string,
1679
     size_t utf8_string_length,
1680
     libolecf_item_t **item,
1681
     libcerror_error_t **error )
1682
0
{
1683
0
  libolecf_internal_file_t *internal_file       = NULL;
1684
0
  libcdata_tree_node_t *directory_tree_node     = NULL;
1685
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
1686
0
  uint8_t *utf8_string_segment                  = NULL;
1687
0
  static char *function                         = "libolecf_file_get_item_by_utf8_path";
1688
0
  libuna_unicode_character_t unicode_character  = 0;
1689
0
  size_t utf8_string_index                      = 0;
1690
0
  size_t utf8_string_segment_length             = 0;
1691
0
  int result                                    = 0;
1692
1693
0
  if( file == NULL )
1694
0
  {
1695
0
    libcerror_error_set(
1696
0
     error,
1697
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1698
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1699
0
     "%s: invalid file.",
1700
0
     function );
1701
1702
0
    return( -1 );
1703
0
  }
1704
0
  internal_file = (libolecf_internal_file_t *) file;
1705
1706
0
  if( internal_file->io_handle == NULL )
1707
0
  {
1708
0
    libcerror_error_set(
1709
0
     error,
1710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1711
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1712
0
     "%s: invalid file - missing IO handle.",
1713
0
     function );
1714
1715
0
    return( -1 );
1716
0
  }
1717
0
  if( item == NULL )
1718
0
  {
1719
0
    libcerror_error_set(
1720
0
     error,
1721
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1722
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1723
0
     "%s: invalid item.",
1724
0
     function );
1725
1726
0
    return( -1 );
1727
0
  }
1728
0
  if( *item != NULL )
1729
0
  {
1730
0
    libcerror_error_set(
1731
0
     error,
1732
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1733
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1734
0
     "%s: item already set.",
1735
0
     function );
1736
1737
0
    return( -1 );
1738
0
  }
1739
0
  directory_tree_node = internal_file->directory_tree_root_node;
1740
1741
0
  if( utf8_string_length > 0 )
1742
0
  {
1743
    /* Ignore a leading separator
1744
     */
1745
0
    if( utf8_string[ utf8_string_index ] == (uint8_t) LIBOLECF_SEPARATOR )
1746
0
    {
1747
0
      utf8_string_index++;
1748
0
    }
1749
0
  }
1750
0
  if( ( utf8_string_length == 0 )
1751
0
   || ( utf8_string_length == 1 ) )
1752
0
  {
1753
0
    result = 1;
1754
0
  }
1755
0
  else while( utf8_string_index < utf8_string_length )
1756
0
  {
1757
0
    utf8_string_segment        = (uint8_t *) &( utf8_string[ utf8_string_index ] );
1758
0
    utf8_string_segment_length = utf8_string_index;
1759
1760
0
    while( utf8_string_index < utf8_string_length )
1761
0
    {
1762
0
      if( libuna_unicode_character_copy_from_utf8(
1763
0
           &unicode_character,
1764
0
           utf8_string,
1765
0
           utf8_string_length,
1766
0
           &utf8_string_index,
1767
0
           error ) != 1 )
1768
0
      {
1769
0
        libcerror_error_set(
1770
0
         error,
1771
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1772
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1773
0
         "%s: unable to copy UTF-8 string to Unicode character.",
1774
0
         function );
1775
1776
0
        return( -1 );
1777
0
      }
1778
0
      if( ( unicode_character == (libuna_unicode_character_t) LIBOLECF_SEPARATOR )
1779
0
       || ( unicode_character == 0 ) )
1780
0
      {
1781
0
        utf8_string_segment_length += 1;
1782
1783
0
        break;
1784
0
      }
1785
0
    }
1786
0
    utf8_string_segment_length = utf8_string_index - utf8_string_segment_length;
1787
1788
0
    if( utf8_string_segment_length == 0 )
1789
0
    {
1790
0
      result = 0;
1791
0
    }
1792
0
    else
1793
0
    {
1794
0
      result = libolecf_directory_tree_get_sub_node_by_utf8_name(
1795
0
          directory_tree_node,
1796
0
          utf8_string_segment,
1797
0
          utf8_string_segment_length,
1798
0
          internal_file->io_handle->byte_order,
1799
0
          &sub_directory_tree_node,
1800
0
          error );
1801
0
    }
1802
0
    if( result == -1 )
1803
0
    {
1804
0
      libcerror_error_set(
1805
0
       error,
1806
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1807
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1808
0
       "%s: unable to retrieve directory tree sub node by UTF-8 name.",
1809
0
       function );
1810
1811
0
      return( -1 );
1812
0
    }
1813
0
    else if( result == 0 )
1814
0
    {
1815
0
      break;
1816
0
    }
1817
0
    directory_tree_node = sub_directory_tree_node;
1818
0
  }
1819
0
  if( result != 0 )
1820
0
  {
1821
0
    if( libolecf_item_initialize(
1822
0
         item,
1823
0
         internal_file->io_handle,
1824
0
         internal_file->file_io_handle,
1825
0
         internal_file,
1826
0
         directory_tree_node,
1827
0
         error ) != 1 )
1828
0
    {
1829
0
      libcerror_error_set(
1830
0
       error,
1831
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1832
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1833
0
       "%s: unable to create item.",
1834
0
       function );
1835
1836
0
      return( -1 );
1837
0
    }
1838
0
  }
1839
0
  return( result );
1840
0
}
1841
1842
/* Retrieves the item for the specific UTF-16 encoded path
1843
 * The path separator is the \ character
1844
 * Returns 1 if successful, 0 if no such item or -1 on error
1845
 */
1846
int libolecf_file_get_item_by_utf16_path(
1847
     libolecf_file_t *file,
1848
     const uint16_t *utf16_string,
1849
     size_t utf16_string_length,
1850
     libolecf_item_t **item,
1851
     libcerror_error_t **error )
1852
0
{
1853
0
  libolecf_internal_file_t *internal_file       = NULL;
1854
0
  libcdata_tree_node_t *directory_tree_node     = NULL;
1855
0
  libcdata_tree_node_t *sub_directory_tree_node = NULL;
1856
0
  uint16_t *utf16_string_segment                = NULL;
1857
0
  static char *function                         = "libolecf_file_get_item_by_utf16_path";
1858
0
  libuna_unicode_character_t unicode_character  = 0;
1859
0
  size_t utf16_string_index                     = 0;
1860
0
  size_t utf16_string_segment_length            = 0;
1861
0
  int result                                    = 0;
1862
1863
0
  if( file == NULL )
1864
0
  {
1865
0
    libcerror_error_set(
1866
0
     error,
1867
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1868
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1869
0
     "%s: invalid file.",
1870
0
     function );
1871
1872
0
    return( -1 );
1873
0
  }
1874
0
  internal_file = (libolecf_internal_file_t *) file;
1875
1876
0
  if( internal_file->io_handle == NULL )
1877
0
  {
1878
0
    libcerror_error_set(
1879
0
     error,
1880
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1881
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1882
0
     "%s: invalid file - missing IO handle.",
1883
0
     function );
1884
1885
0
    return( -1 );
1886
0
  }
1887
0
  if( item == NULL )
1888
0
  {
1889
0
    libcerror_error_set(
1890
0
     error,
1891
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1892
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1893
0
     "%s: invalid item.",
1894
0
     function );
1895
1896
0
    return( -1 );
1897
0
  }
1898
0
  if( *item != NULL )
1899
0
  {
1900
0
    libcerror_error_set(
1901
0
     error,
1902
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1903
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1904
0
     "%s: item already set.",
1905
0
     function );
1906
1907
0
    return( -1 );
1908
0
  }
1909
0
  directory_tree_node = internal_file->directory_tree_root_node;
1910
1911
0
  if( utf16_string_length > 0 )
1912
0
  {
1913
    /* Ignore a leading separator
1914
     */
1915
0
    if( utf16_string[ utf16_string_index ] == (uint16_t) LIBOLECF_SEPARATOR )
1916
0
    {
1917
0
      utf16_string_index++;
1918
0
    }
1919
0
  }
1920
0
  if( ( utf16_string_length == 0 )
1921
0
   || ( utf16_string_length == 1 ) )
1922
0
  {
1923
0
    result = 1;
1924
0
  }
1925
0
  else while( utf16_string_index < utf16_string_length )
1926
0
  {
1927
0
    utf16_string_segment        = (uint16_t *) &( utf16_string[ utf16_string_index ] );
1928
0
    utf16_string_segment_length = utf16_string_index;
1929
1930
0
    while( utf16_string_index < utf16_string_length )
1931
0
    {
1932
0
      if( libuna_unicode_character_copy_from_utf16(
1933
0
           &unicode_character,
1934
0
           utf16_string,
1935
0
           utf16_string_length,
1936
0
           &utf16_string_index,
1937
0
           error ) != 1 )
1938
0
      {
1939
0
        libcerror_error_set(
1940
0
         error,
1941
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1942
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1943
0
         "%s: unable to copy UTF-16 string to Unicode character.",
1944
0
         function );
1945
1946
0
        return( -1 );
1947
0
      }
1948
0
      if( ( unicode_character == (libuna_unicode_character_t) LIBOLECF_SEPARATOR )
1949
0
       || ( unicode_character == 0 ) )
1950
0
      {
1951
0
        utf16_string_segment_length += 1;
1952
1953
0
        break;
1954
0
      }
1955
0
    }
1956
0
    utf16_string_segment_length = utf16_string_index - utf16_string_segment_length;
1957
1958
0
    if( utf16_string_segment_length == 0 )
1959
0
    {
1960
0
      result = 0;
1961
0
    }
1962
0
    else
1963
0
    {
1964
0
      result = libolecf_directory_tree_get_sub_node_by_utf16_name(
1965
0
          directory_tree_node,
1966
0
          utf16_string_segment,
1967
0
          utf16_string_segment_length,
1968
0
          internal_file->io_handle->byte_order,
1969
0
          &sub_directory_tree_node,
1970
0
          error );
1971
0
    }
1972
0
    if( result == -1 )
1973
0
    {
1974
0
      libcerror_error_set(
1975
0
       error,
1976
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1977
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1978
0
       "%s: unable to retrieve directory tree sub node by UTF-16 name.",
1979
0
       function );
1980
1981
0
      return( -1 );
1982
0
    }
1983
0
    else if( result == 0 )
1984
0
    {
1985
0
      break;
1986
0
    }
1987
0
    directory_tree_node = sub_directory_tree_node;
1988
0
  }
1989
0
  if( result != 0 )
1990
0
  {
1991
0
    if( libolecf_item_initialize(
1992
0
         item,
1993
0
         internal_file->io_handle,
1994
0
         internal_file->file_io_handle,
1995
0
         internal_file,
1996
0
         directory_tree_node,
1997
0
         error ) != 1 )
1998
0
    {
1999
0
      libcerror_error_set(
2000
0
       error,
2001
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2002
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2003
0
       "%s: unable to create item.",
2004
0
       function );
2005
2006
0
      return( -1 );
2007
0
    }
2008
0
  }
2009
0
  return( result );
2010
0
}
2011