Coverage Report

Created: 2023-06-07 06:53

/src/libscca/libscca/libscca_file_information.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File information functions
3
 *
4
 * Copyright (C) 2011-2023, 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 "libscca_debug.h"
28
#include "libscca_definitions.h"
29
#include "libscca_file_information.h"
30
#include "libscca_io_handle.h"
31
#include "libscca_libbfio.h"
32
#include "libscca_libcerror.h"
33
#include "libscca_libcnotify.h"
34
#include "libscca_libfdata.h"
35
#include "libscca_libfdatetime.h"
36
37
#include "scca_file_information.h"
38
39
/* Creates file information
40
 * Make sure the value file_information is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libscca_file_information_initialize(
44
     libscca_file_information_t **file_information,
45
     libcerror_error_t **error )
46
1.46k
{
47
1.46k
  static char *function = "libscca_file_information_initialize";
48
49
1.46k
  if( file_information == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid file information.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
1.46k
  if( *file_information != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid file information value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
1.46k
  *file_information = memory_allocate_structure(
72
1.46k
                       libscca_file_information_t );
73
74
1.46k
  if( *file_information == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
79
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80
0
     "%s: unable to create file information.",
81
0
     function );
82
83
0
    goto on_error;
84
0
  }
85
1.46k
  if( memory_set(
86
1.46k
       *file_information,
87
1.46k
       0,
88
1.46k
       sizeof( libscca_file_information_t ) ) == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
93
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
94
0
     "%s: unable to clear file.",
95
0
     function );
96
97
0
    goto on_error;
98
0
  }
99
1.46k
  return( 1 );
100
101
0
on_error:
102
0
  if( *file_information != NULL )
103
0
  {
104
0
    memory_free(
105
0
     *file_information );
106
107
0
    *file_information = NULL;
108
0
  }
109
0
  return( -1 );
110
1.46k
}
111
112
/* Frees file information
113
 * Returns 1 if successful or -1 on error
114
 */
115
int libscca_file_information_free(
116
     libscca_file_information_t **file_information,
117
     libcerror_error_t **error )
118
1.46k
{
119
1.46k
  static char *function = "libscca_file_information_free";
120
121
1.46k
  if( file_information == NULL )
122
0
  {
123
0
    libcerror_error_set(
124
0
     error,
125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
127
0
     "%s: invalid file information.",
128
0
     function );
129
130
0
    return( -1 );
131
0
  }
132
1.46k
  if( *file_information != NULL )
133
1.46k
  {
134
1.46k
    memory_free(
135
1.46k
     *file_information );
136
137
1.46k
    *file_information = NULL;
138
1.46k
  }
139
1.46k
  return( 1 );
140
1.46k
}
141
142
/* Reads the file information
143
 * Returns 1 if successful or -1 on error
144
 */
145
int libscca_file_information_read_data(
146
     libscca_file_information_t *file_information,
147
     libscca_io_handle_t *io_handle,
148
     const uint8_t *data,
149
     size_t data_size,
150
     libcerror_error_t **error )
151
1.39k
{
152
1.39k
  static char *function             = "libscca_file_information_read_data";
153
1.39k
  size_t file_information_data_size = 0;
154
1.39k
  int last_run_time_index           = 0;
155
1.39k
  int number_of_last_run_times      = 0;
156
157
#if defined( HAVE_DEBUG_OUTPUT )
158
  uint64_t value_64bit              = 0;
159
  uint32_t value_32bit              = 0;
160
  int result                        = 0;
161
#endif
162
163
1.39k
  if( file_information == NULL )
164
0
  {
165
0
    libcerror_error_set(
166
0
     error,
167
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
168
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
169
0
     "%s: invalid file information.",
170
0
     function );
171
172
0
    return( -1 );
173
0
  }
174
1.39k
  if( io_handle == NULL )
175
0
  {
176
0
    libcerror_error_set(
177
0
     error,
178
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
179
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
180
0
     "%s: invalid IO handle.",
181
0
     function );
182
183
0
    return( -1 );
184
0
  }
185
1.39k
  if( ( io_handle->format_version != 17 )
186
1.39k
   && ( io_handle->format_version != 23 )
187
1.39k
   && ( io_handle->format_version != 26 )
188
1.39k
   && ( io_handle->format_version != 30 ) )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
193
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
194
0
     "%s: invalid IO handle - unsupported format version.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
1.39k
  if( data == NULL )
200
0
  {
201
0
    libcerror_error_set(
202
0
     error,
203
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
204
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
205
0
     "%s: invalid data.",
206
0
     function );
207
208
0
    return( -1 );
209
0
  }
210
1.39k
  if( ( data_size < 4 )
211
1.39k
   || ( data_size > (size_t) SSIZE_MAX ) )
212
0
  {
213
0
    libcerror_error_set(
214
0
     error,
215
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
216
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
217
0
     "%s: invalid data size value out of bounds.",
218
0
     function );
219
220
0
    return( -1 );
221
0
  }
222
1.39k
  byte_stream_copy_to_uint32_little_endian(
223
1.39k
   ( (scca_file_information_v17_t *) data )->metrics_array_offset,
224
1.39k
   file_information->metrics_array_offset );
225
226
1.39k
  if( ( io_handle->format_version == 30 )
227
1.39k
   && ( file_information->metrics_array_offset != 0x00000128 )
228
1.39k
   && ( file_information->metrics_array_offset != 0x00000130 ) )
229
40
  {
230
40
    libcerror_error_set(
231
40
     error,
232
40
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233
40
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
234
40
     "%s: invalid IO handle - unsupported format version: 30 variant.",
235
40
     function );
236
237
40
    return( -1 );
238
40
  }
239
1.35k
  if( io_handle->format_version == 17 )
240
1.30k
  {
241
1.30k
    file_information_data_size = sizeof( scca_file_information_v17_t );
242
1.30k
  }
243
50
  else if( io_handle->format_version == 23 )
244
20
  {
245
20
    file_information_data_size = sizeof( scca_file_information_v23_t );
246
20
  }
247
30
  else if( ( io_handle->format_version == 26 )
248
30
        || ( ( io_handle->format_version == 30 )
249
12
         &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
250
21
  {
251
21
    file_information_data_size = sizeof( scca_file_information_v26_t );
252
21
  }
253
9
  else if( ( io_handle->format_version == 30 )
254
9
        && ( file_information->metrics_array_offset == 0x00000128 ) )
255
9
  {
256
9
    file_information_data_size = sizeof( scca_file_information_v30_2_t );
257
9
  }
258
1.35k
  if( data_size < file_information_data_size )
259
0
  {
260
0
    libcerror_error_set(
261
0
     error,
262
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
263
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
264
0
     "%s: invalid data size value too small.",
265
0
     function );
266
267
0
    return( -1 );
268
0
  }
269
#if defined( HAVE_DEBUG_OUTPUT )
270
  if( libcnotify_verbose != 0 )
271
  {
272
    libcnotify_printf(
273
     "%s: file information data:\n",
274
     function );
275
    libcnotify_print_data(
276
     data,
277
     file_information_data_size,
278
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
279
  }
280
#endif
281
1.35k
  byte_stream_copy_to_uint32_little_endian(
282
1.35k
   ( (scca_file_information_v17_t *) data )->number_of_file_metrics_entries,
283
1.35k
   file_information->number_of_file_metrics_entries );
284
285
1.35k
  byte_stream_copy_to_uint32_little_endian(
286
1.35k
   ( (scca_file_information_v17_t *) data )->trace_chain_array_offset,
287
1.35k
   file_information->trace_chain_array_offset );
288
289
1.35k
  byte_stream_copy_to_uint32_little_endian(
290
1.35k
   ( (scca_file_information_v17_t *) data )->number_of_trace_chain_array_entries,
291
1.35k
   file_information->number_of_trace_chain_array_entries );
292
293
1.35k
  byte_stream_copy_to_uint32_little_endian(
294
1.35k
   ( (scca_file_information_v17_t *) data )->filename_strings_offset,
295
1.35k
   file_information->filename_strings_offset );
296
297
1.35k
  byte_stream_copy_to_uint32_little_endian(
298
1.35k
   ( (scca_file_information_v17_t *) data )->filename_strings_size,
299
1.35k
   file_information->filename_strings_size );
300
301
1.35k
  byte_stream_copy_to_uint32_little_endian(
302
1.35k
   ( (scca_file_information_v17_t *) data )->volumes_information_offset,
303
1.35k
   file_information->volumes_information_offset );
304
305
1.35k
  byte_stream_copy_to_uint32_little_endian(
306
1.35k
   ( (scca_file_information_v17_t *) data )->number_of_volumes,
307
1.35k
   file_information->number_of_volumes );
308
309
1.35k
  byte_stream_copy_to_uint32_little_endian(
310
1.35k
   ( (scca_file_information_v17_t *) data )->volumes_information_size,
311
1.35k
   file_information->volumes_information_size );
312
313
1.35k
  if( io_handle->format_version < 26 )
314
1.32k
  {
315
1.32k
    number_of_last_run_times = 1;
316
1.32k
  }
317
30
  else
318
30
  {
319
30
    number_of_last_run_times = 8;
320
30
  }
321
1.35k
  for( last_run_time_index = 0;
322
2.91k
       last_run_time_index < number_of_last_run_times;
323
1.56k
       last_run_time_index++ )
324
1.56k
  {
325
1.56k
    if( io_handle->format_version == 17 )
326
1.30k
    {
327
1.30k
      byte_stream_copy_to_uint64_little_endian(
328
1.30k
       &( ( (scca_file_information_v17_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
329
1.30k
       file_information->last_run_time[ last_run_time_index ] );
330
1.30k
    }
331
260
    else if( io_handle->format_version == 23 )
332
20
    {
333
20
      byte_stream_copy_to_uint64_little_endian(
334
20
       &( ( (scca_file_information_v23_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
335
20
       file_information->last_run_time[ last_run_time_index ] );
336
20
    }
337
240
    else if( ( io_handle->format_version == 26 )
338
240
          || ( io_handle->format_version == 30 ) )
339
240
    {
340
240
      byte_stream_copy_to_uint64_little_endian(
341
240
       &( ( (scca_file_information_v26_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
342
240
       file_information->last_run_time[ last_run_time_index ] );
343
240
    }
344
1.56k
  }
345
1.35k
  if( io_handle->format_version == 17 )
346
1.30k
  {
347
1.30k
    byte_stream_copy_to_uint32_little_endian(
348
1.30k
     ( (scca_file_information_v17_t *) data )->run_count,
349
1.30k
     file_information->run_count );
350
1.30k
  }
351
50
  else if( io_handle->format_version == 23 )
352
20
  {
353
20
    byte_stream_copy_to_uint32_little_endian(
354
20
     ( (scca_file_information_v23_t *) data )->run_count,
355
20
     file_information->run_count );
356
20
  }
357
30
  else if( ( io_handle->format_version == 26 )
358
30
        || ( ( io_handle->format_version == 30 )
359
12
         &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
360
21
  {
361
21
    byte_stream_copy_to_uint32_little_endian(
362
21
     ( (scca_file_information_v26_t *) data )->run_count,
363
21
     file_information->run_count );
364
21
  }
365
9
  else if( ( io_handle->format_version == 30 )
366
9
        && ( file_information->metrics_array_offset == 0x00000128 ) )
367
9
  {
368
9
    byte_stream_copy_to_uint32_little_endian(
369
9
     ( (scca_file_information_v30_2_t *) data )->run_count,
370
9
     file_information->run_count );
371
9
  }
372
#if defined( HAVE_DEBUG_OUTPUT )
373
  if( libcnotify_verbose != 0 )
374
  {
375
    libcnotify_printf(
376
     "%s: metrics array offset\t\t: 0x%08" PRIx32 "\n",
377
     function,
378
     file_information->metrics_array_offset );
379
380
    libcnotify_printf(
381
     "%s: number of file metrics entries\t: %" PRIu32 "\n",
382
     function,
383
     file_information->number_of_file_metrics_entries );
384
385
    libcnotify_printf(
386
     "%s: trace chain array offset\t\t: 0x%08" PRIx32 "\n",
387
     function,
388
     file_information->trace_chain_array_offset );
389
390
    libcnotify_printf(
391
     "%s: number of trace chain array entries\t: %" PRIu32 "\n",
392
     function,
393
     file_information->number_of_trace_chain_array_entries );
394
395
    libcnotify_printf(
396
     "%s: filename strings offset\t\t: 0x%08" PRIx32 "\n",
397
     function,
398
     file_information->filename_strings_offset );
399
400
    libcnotify_printf(
401
     "%s: filename strings size\t\t: %" PRIu32 "\n",
402
     function,
403
     file_information->filename_strings_size );
404
405
    libcnotify_printf(
406
     "%s: volumes information offset\t\t: 0x%08" PRIx32 "\n",
407
     function,
408
     file_information->volumes_information_offset );
409
410
    libcnotify_printf(
411
     "%s: number of volumes\t\t\t: %" PRIu32 "\n",
412
     function,
413
     file_information->number_of_volumes );
414
415
    libcnotify_printf(
416
     "%s: volumes information size\t\t: %" PRIu32 "\n",
417
     function,
418
     file_information->volumes_information_size );
419
420
    if( io_handle->format_version == 23 )
421
    {
422
      byte_stream_copy_to_uint32_little_endian(
423
       ( (scca_file_information_v23_t *) data )->unknown3c,
424
       value_32bit );
425
      libcnotify_printf(
426
       "%s: unknown3c\t\t\t\t: 0x%08" PRIx64 "\n",
427
       function,
428
       value_64bit );
429
    }
430
    for( last_run_time_index = 0;
431
         last_run_time_index < number_of_last_run_times;
432
         last_run_time_index++ )
433
    {
434
      if( io_handle->format_version == 17 )
435
      {
436
        result = libscca_debug_print_filetime_value(
437
            function,
438
            "last run time\t\t\t",
439
                  &( ( (scca_file_information_v17_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
440
            8,
441
            LIBFDATETIME_ENDIAN_LITTLE,
442
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
443
            error );
444
      }
445
      else if( io_handle->format_version == 23 )
446
      {
447
        result = libscca_debug_print_filetime_value(
448
            function,
449
            "last run time\t\t\t",
450
                  &( ( (scca_file_information_v23_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
451
            8,
452
            LIBFDATETIME_ENDIAN_LITTLE,
453
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
454
            error );
455
      }
456
      else if( ( io_handle->format_version == 26 )
457
            || ( io_handle->format_version == 30 ) )
458
      {
459
        result = libscca_debug_print_filetime_value(
460
            function,
461
            "last run time\t\t\t",
462
                  &( ( (scca_file_information_v26_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
463
            8,
464
            LIBFDATETIME_ENDIAN_LITTLE,
465
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
466
            error );
467
      }
468
      if( result != 1 )
469
      {
470
        libcerror_error_set(
471
         error,
472
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
473
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
474
         "%s: unable to print filetime value.",
475
         function );
476
477
        return( -1 );
478
      }
479
    }
480
    libcnotify_printf(
481
     "%s: unknown4:\n",
482
     function );
483
484
    if( io_handle->format_version == 17 )
485
    {
486
      libcnotify_print_data(
487
       ( (scca_file_information_v17_t *) data )->unknown4,
488
       16,
489
       0 );
490
    }
491
    else if( io_handle->format_version == 23 )
492
    {
493
      libcnotify_print_data(
494
       ( (scca_file_information_v23_t *) data )->unknown4,
495
       16,
496
       0 );
497
    }
498
    else if( ( io_handle->format_version == 26 )
499
          || ( ( io_handle->format_version == 30 )
500
           &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
501
    {
502
      libcnotify_print_data(
503
       ( (scca_file_information_v26_t *) data )->unknown4,
504
       16,
505
       0 );
506
    }
507
    else if( ( io_handle->format_version == 30 )
508
          && ( file_information->metrics_array_offset == 0x00000128 ) )
509
    {
510
      libcnotify_print_data(
511
       ( (scca_file_information_v30_2_t *) data )->unknown4,
512
       8,
513
       0 );
514
    }
515
    libcnotify_printf(
516
     "%s: run count\t\t\t\t: %" PRIu32 "\n",
517
     function,
518
     file_information->run_count );
519
520
    if( io_handle->format_version == 17 )
521
    {
522
      byte_stream_copy_to_uint32_little_endian(
523
       ( (scca_file_information_v17_t *) data )->unknown5,
524
       value_32bit );
525
      libcnotify_printf(
526
       "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
527
       function,
528
       value_32bit );
529
530
      libcnotify_printf(
531
       "\n" );
532
    }
533
    else if( io_handle->format_version == 23 )
534
    {
535
      byte_stream_copy_to_uint32_little_endian(
536
       ( (scca_file_information_v23_t *) data )->unknown5,
537
       value_32bit );
538
      libcnotify_printf(
539
       "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
540
       function,
541
       value_32bit );
542
543
      libcnotify_printf(
544
       "%s: unknown6:\n",
545
       function );
546
      libcnotify_print_data(
547
       ( (scca_file_information_v23_t *) data )->unknown6,
548
       80,
549
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
550
    }
551
    else if( ( io_handle->format_version == 26 )
552
          || ( ( io_handle->format_version == 30 )
553
           &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
554
    {
555
      byte_stream_copy_to_uint32_little_endian(
556
       ( (scca_file_information_v26_t *) data )->unknown5a,
557
       value_32bit );
558
      libcnotify_printf(
559
       "%s: unknown5a\t\t\t\t: 0x%08" PRIx32 "\n",
560
       function,
561
       value_32bit );
562
563
      byte_stream_copy_to_uint32_little_endian(
564
       ( (scca_file_information_v26_t *) data )->unknown5b,
565
       value_32bit );
566
      libcnotify_printf(
567
       "%s: unknown5b\t\t\t\t: 0x%08" PRIx32 "\n",
568
       function,
569
       value_32bit );
570
571
      libcnotify_printf(
572
       "%s: unknown6:\n",
573
       function );
574
      libcnotify_print_data(
575
       ( (scca_file_information_v26_t *) data )->unknown6,
576
       88,
577
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
578
    }
579
    else if( ( io_handle->format_version == 30 )
580
          && ( file_information->metrics_array_offset == 0x00000128 ) )
581
    {
582
      byte_stream_copy_to_uint32_little_endian(
583
       ( (scca_file_information_v30_2_t *) data )->unknown5a,
584
       value_32bit );
585
      libcnotify_printf(
586
       "%s: unknown5a\t\t\t\t: 0x%08" PRIx32 "\n",
587
       function,
588
       value_32bit );
589
590
      byte_stream_copy_to_uint32_little_endian(
591
       ( (scca_file_information_v30_2_t *) data )->unknown5b,
592
       value_32bit );
593
      libcnotify_printf(
594
       "%s: unknown5b\t\t\t\t: 0x%08" PRIx32 "\n",
595
       function,
596
       value_32bit );
597
598
      libcnotify_printf(
599
       "%s: unknown6:\n",
600
       function );
601
      libcnotify_print_data(
602
       ( (scca_file_information_v30_2_t *) data )->unknown6,
603
       88,
604
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
605
    }
606
  }
607
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
608
609
1.35k
  return( 1 );
610
1.35k
}
611
612
/* Reads the file information
613
 * Returns 1 if successful or -1 on error
614
 */
615
int libscca_file_information_read_stream(
616
     libscca_file_information_t *file_information,
617
     libfdata_stream_t *uncompressed_data_stream,
618
     libbfio_handle_t *file_io_handle,
619
     libscca_io_handle_t *io_handle,
620
     libcerror_error_t **error )
621
1.46k
{
622
1.46k
  uint8_t *file_information_data    = NULL;
623
1.46k
  static char *function             = "libscca_file_information_read_stream";
624
1.46k
  size_t file_information_data_size = 0;
625
1.46k
  ssize_t read_count                = 0;
626
627
1.46k
  if( file_information == NULL )
628
0
  {
629
0
    libcerror_error_set(
630
0
     error,
631
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
632
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
633
0
     "%s: invalid file information.",
634
0
     function );
635
636
0
    return( -1 );
637
0
  }
638
1.46k
  if( io_handle == NULL )
639
0
  {
640
0
    libcerror_error_set(
641
0
     error,
642
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
643
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
644
0
     "%s: invalid IO handle.",
645
0
     function );
646
647
0
    return( -1 );
648
0
  }
649
1.46k
  if( ( io_handle->format_version != 17 )
650
1.46k
   && ( io_handle->format_version != 23 )
651
1.46k
   && ( io_handle->format_version != 26 )
652
1.46k
   && ( io_handle->format_version != 30 ) )
653
62
  {
654
62
    libcerror_error_set(
655
62
     error,
656
62
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
657
62
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
658
62
     "%s: invalid IO handle - unsupported format version.",
659
62
     function );
660
661
62
    return( -1 );
662
62
  }
663
1.40k
  if( io_handle->format_version == 17 )
664
1.30k
  {
665
1.30k
    file_information_data_size = sizeof( scca_file_information_v17_t );
666
1.30k
  }
667
100
  else if( io_handle->format_version == 23 )
668
25
  {
669
25
    file_information_data_size = sizeof( scca_file_information_v23_t );
670
25
  }
671
75
  else if( ( io_handle->format_version == 26 )
672
75
        || ( io_handle->format_version == 30 ) )
673
75
  {
674
75
    file_information_data_size = sizeof( scca_file_information_v26_t );
675
75
  }
676
1.40k
  file_information_data = (uint8_t *) memory_allocate(
677
1.40k
                                       sizeof( uint8_t ) * file_information_data_size );
678
679
1.40k
  if( file_information_data == NULL )
680
0
  {
681
0
    libcerror_error_set(
682
0
     error,
683
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
684
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
685
0
     "%s: unable to create file information data.",
686
0
     function );
687
688
0
    goto on_error;
689
0
  }
690
1.40k
  read_count = libfdata_stream_read_buffer(
691
1.40k
                uncompressed_data_stream,
692
1.40k
                (intptr_t *) file_io_handle,
693
1.40k
                file_information_data,
694
1.40k
                file_information_data_size,
695
1.40k
                0,
696
1.40k
                error );
697
698
1.40k
  if( read_count != (ssize_t) file_information_data_size )
699
17
  {
700
17
    libcerror_error_set(
701
17
     error,
702
17
     LIBCERROR_ERROR_DOMAIN_IO,
703
17
     LIBCERROR_IO_ERROR_READ_FAILED,
704
17
     "%s: unable to read file information data.",
705
17
     function );
706
707
17
    goto on_error;
708
17
  }
709
1.39k
  if( libscca_file_information_read_data(
710
1.39k
       file_information,
711
1.39k
       io_handle,
712
1.39k
       file_information_data,
713
1.39k
       file_information_data_size,
714
1.39k
       error ) != 1 )
715
40
  {
716
40
    libcerror_error_set(
717
40
     error,
718
40
     LIBCERROR_ERROR_DOMAIN_IO,
719
40
     LIBCERROR_IO_ERROR_READ_FAILED,
720
40
     "%s: unable to read file information data.",
721
40
     function );
722
723
40
    goto on_error;
724
40
  }
725
1.35k
  memory_free(
726
1.35k
   file_information_data );
727
728
1.35k
  return( 1 );
729
730
57
on_error:
731
57
  if( file_information_data != NULL )
732
57
  {
733
57
    memory_free(
734
57
     file_information_data );
735
57
  }
736
57
  return( -1 );
737
1.39k
}
738