Coverage Report

Created: 2026-01-20 07:11

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