Coverage Report

Created: 2026-10-22 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libscca/libscca/libscca_file_information.c
Line
Count
Source
1
/*
2
 * File information functions
3
 *
4
 * Copyright (C) 2011-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <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.50k
{
47
1.50k
  static char *function = "libscca_file_information_initialize";
48
49
1.50k
  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.50k
  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.50k
  *file_information = memory_allocate_structure(
72
1.50k
                       libscca_file_information_t );
73
74
1.50k
  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.50k
  if( memory_set(
86
1.50k
       *file_information,
87
1.50k
       0,
88
1.50k
       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.50k
  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.50k
}
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.50k
{
119
1.50k
  static char *function = "libscca_file_information_free";
120
121
1.50k
  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.50k
  if( *file_information != NULL )
133
1.50k
  {
134
1.50k
    memory_free(
135
1.50k
     *file_information );
136
137
1.50k
    *file_information = NULL;
138
1.50k
  }
139
1.50k
  return( 1 );
140
1.50k
}
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.42k
{
152
1.42k
  static char *function             = "libscca_file_information_read_data";
153
1.42k
  size_t file_information_data_size = 0;
154
155
#if defined( HAVE_DEBUG_OUTPUT )
156
  uint64_t value_64bit              = 0;
157
  uint32_t value_32bit              = 0;
158
  int last_run_time_index           = 0;
159
  int number_of_last_run_times      = 0;
160
  int result                        = 0;
161
#endif
162
163
1.42k
  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.42k
  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.42k
  if( ( io_handle->format_version != 17 )
186
109
   && ( io_handle->format_version != 23 )
187
86
   && ( io_handle->format_version != 26 )
188
69
   && ( io_handle->format_version != 30 )
189
16
   && ( io_handle->format_version != 31 ) )
190
0
  {
191
0
    libcerror_error_set(
192
0
     error,
193
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
194
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
195
0
     "%s: invalid IO handle - unsupported format version.",
196
0
     function );
197
198
0
    return( -1 );
199
0
  }
200
1.42k
  if( data == NULL )
201
0
  {
202
0
    libcerror_error_set(
203
0
     error,
204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
206
0
     "%s: invalid data.",
207
0
     function );
208
209
0
    return( -1 );
210
0
  }
211
1.42k
  if( ( data_size < 4 )
212
1.42k
   || ( data_size > (size_t) SSIZE_MAX ) )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
217
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
218
0
     "%s: invalid data size value out of bounds.",
219
0
     function );
220
221
0
    return( -1 );
222
0
  }
223
1.42k
  byte_stream_copy_to_uint32_little_endian(
224
1.42k
   ( (scca_file_information_v17_t *) data )->metrics_array_offset,
225
1.42k
   file_information->metrics_array_offset );
226
227
1.42k
  if( ( io_handle->format_version == 30 )
228
53
   && ( file_information->metrics_array_offset != 0x00000128 )
229
44
   && ( file_information->metrics_array_offset != 0x00000130 ) )
230
42
  {
231
42
    libcerror_error_set(
232
42
     error,
233
42
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
234
42
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
235
42
     "%s: invalid IO handle - unsupported format version: 30 variant.",
236
42
     function );
237
238
42
    return( -1 );
239
42
  }
240
1.38k
  if( io_handle->format_version == 17 )
241
1.31k
  {
242
1.31k
    file_information_data_size = sizeof( scca_file_information_v17_t );
243
1.31k
  }
244
67
  else if( io_handle->format_version == 23 )
245
23
  {
246
23
    file_information_data_size = sizeof( scca_file_information_v23_t );
247
23
  }
248
44
  else if( ( io_handle->format_version == 26 )
249
27
        || ( ( io_handle->format_version == 30 )
250
11
         &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
251
19
  {
252
19
    file_information_data_size = sizeof( scca_file_information_v26_t );
253
19
  }
254
25
  else if( ( ( io_handle->format_version == 30 )
255
9
         &&  ( file_information->metrics_array_offset == 0x00000128 ) )
256
16
        || ( io_handle->format_version == 31 ) )
257
25
  {
258
25
    file_information_data_size = sizeof( scca_file_information_v30_2_t );
259
25
  }
260
1.38k
  if( data_size < file_information_data_size )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
265
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
266
0
     "%s: invalid data size value too small.",
267
0
     function );
268
269
0
    return( -1 );
270
0
  }
271
#if defined( HAVE_DEBUG_OUTPUT )
272
  if( libcnotify_verbose != 0 )
273
  {
274
    libcnotify_printf(
275
     "%s: file information data:\n",
276
     function );
277
    libcnotify_print_data(
278
     data,
279
     file_information_data_size,
280
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
281
  }
282
#endif
283
1.38k
  byte_stream_copy_to_uint32_little_endian(
284
1.38k
   ( (scca_file_information_v17_t *) data )->number_of_file_metrics_entries,
285
1.38k
   file_information->number_of_file_metrics_entries );
286
287
1.38k
  byte_stream_copy_to_uint32_little_endian(
288
1.38k
   ( (scca_file_information_v17_t *) data )->trace_chain_array_offset,
289
1.38k
   file_information->trace_chain_array_offset );
290
291
1.38k
  byte_stream_copy_to_uint32_little_endian(
292
1.38k
   ( (scca_file_information_v17_t *) data )->number_of_trace_chain_array_entries,
293
1.38k
   file_information->number_of_trace_chain_array_entries );
294
295
1.38k
  byte_stream_copy_to_uint32_little_endian(
296
1.38k
   ( (scca_file_information_v17_t *) data )->filename_strings_offset,
297
1.38k
   file_information->filename_strings_offset );
298
299
1.38k
  byte_stream_copy_to_uint32_little_endian(
300
1.38k
   ( (scca_file_information_v17_t *) data )->filename_strings_size,
301
1.38k
   file_information->filename_strings_size );
302
303
1.38k
  byte_stream_copy_to_uint32_little_endian(
304
1.38k
   ( (scca_file_information_v17_t *) data )->volumes_information_offset,
305
1.38k
   file_information->volumes_information_offset );
306
307
1.38k
  byte_stream_copy_to_uint32_little_endian(
308
1.38k
   ( (scca_file_information_v17_t *) data )->number_of_volumes,
309
1.38k
   file_information->number_of_volumes );
310
311
1.38k
  byte_stream_copy_to_uint32_little_endian(
312
1.38k
   ( (scca_file_information_v17_t *) data )->volumes_information_size,
313
1.38k
   file_information->volumes_information_size );
314
315
1.38k
  if( io_handle->format_version == 17 )
316
1.31k
  {
317
1.31k
    byte_stream_copy_to_uint64_little_endian(
318
1.31k
     &( ( (scca_file_information_v17_t *) data )->last_run_time[ 0 ] ),
319
1.31k
     file_information->last_run_time[ 0 ] );
320
1.31k
  }
321
67
  else if( io_handle->format_version == 23 )
322
23
  {
323
23
    byte_stream_copy_to_uint64_little_endian(
324
23
     &( ( (scca_file_information_v23_t *) data )->last_run_time[ 0 ] ),
325
23
     file_information->last_run_time[ 0 ] );
326
23
  }
327
44
  else if( ( io_handle->format_version == 26 )
328
27
        || ( io_handle->format_version == 30 )
329
16
        || ( io_handle->format_version == 31 ) )
330
44
  {
331
    /* Keep this an unrolled loop to prevent aggressive loop optimization removing it
332
     */
333
44
    byte_stream_copy_to_uint64_little_endian(
334
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 0 ] ),
335
44
     file_information->last_run_time[ 0 ] );
336
337
44
    byte_stream_copy_to_uint64_little_endian(
338
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 8 ] ),
339
44
     file_information->last_run_time[ 1 ] );
340
341
44
    byte_stream_copy_to_uint64_little_endian(
342
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 16 ] ),
343
44
     file_information->last_run_time[ 2 ] );
344
345
44
    byte_stream_copy_to_uint64_little_endian(
346
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 24 ] ),
347
44
     file_information->last_run_time[ 3 ] );
348
349
44
    byte_stream_copy_to_uint64_little_endian(
350
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 32 ] ),
351
44
     file_information->last_run_time[ 4 ] );
352
353
44
    byte_stream_copy_to_uint64_little_endian(
354
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 40 ] ),
355
44
     file_information->last_run_time[ 5 ] );
356
357
44
    byte_stream_copy_to_uint64_little_endian(
358
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 48 ] ),
359
44
     file_information->last_run_time[ 6 ] );
360
361
44
    byte_stream_copy_to_uint64_little_endian(
362
44
     &( ( (scca_file_information_v26_t *) data )->last_run_time[ 56 ] ),
363
44
     file_information->last_run_time[ 7 ] );
364
44
  }
365
1.38k
  if( io_handle->format_version == 17 )
366
1.31k
  {
367
1.31k
    byte_stream_copy_to_uint32_little_endian(
368
1.31k
     ( (scca_file_information_v17_t *) data )->run_count,
369
1.31k
     file_information->run_count );
370
1.31k
  }
371
67
  else if( io_handle->format_version == 23 )
372
23
  {
373
23
    byte_stream_copy_to_uint32_little_endian(
374
23
     ( (scca_file_information_v23_t *) data )->run_count,
375
23
     file_information->run_count );
376
23
  }
377
44
  else if( ( io_handle->format_version == 26 )
378
27
        || ( ( io_handle->format_version == 30 )
379
11
         &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
380
19
  {
381
19
    byte_stream_copy_to_uint32_little_endian(
382
19
     ( (scca_file_information_v26_t *) data )->run_count,
383
19
     file_information->run_count );
384
19
  }
385
25
  else if( ( ( io_handle->format_version == 30 )
386
9
         &&  ( file_information->metrics_array_offset == 0x00000128 ) )
387
16
        || ( io_handle->format_version == 31 ) )
388
25
  {
389
25
    byte_stream_copy_to_uint32_little_endian(
390
25
     ( (scca_file_information_v30_2_t *) data )->run_count,
391
25
     file_information->run_count );
392
25
  }
393
#if defined( HAVE_DEBUG_OUTPUT )
394
  if( libcnotify_verbose != 0 )
395
  {
396
    libcnotify_printf(
397
     "%s: metrics array offset\t\t: 0x%08" PRIx32 "\n",
398
     function,
399
     file_information->metrics_array_offset );
400
401
    libcnotify_printf(
402
     "%s: number of file metrics entries\t: %" PRIu32 "\n",
403
     function,
404
     file_information->number_of_file_metrics_entries );
405
406
    libcnotify_printf(
407
     "%s: trace chain array offset\t\t: 0x%08" PRIx32 "\n",
408
     function,
409
     file_information->trace_chain_array_offset );
410
411
    libcnotify_printf(
412
     "%s: number of trace chain array entries\t: %" PRIu32 "\n",
413
     function,
414
     file_information->number_of_trace_chain_array_entries );
415
416
    libcnotify_printf(
417
     "%s: filename strings offset\t\t: 0x%08" PRIx32 "\n",
418
     function,
419
     file_information->filename_strings_offset );
420
421
    libcnotify_printf(
422
     "%s: filename strings size\t\t: %" PRIu32 "\n",
423
     function,
424
     file_information->filename_strings_size );
425
426
    libcnotify_printf(
427
     "%s: volumes information offset\t\t: 0x%08" PRIx32 "\n",
428
     function,
429
     file_information->volumes_information_offset );
430
431
    libcnotify_printf(
432
     "%s: number of volumes\t\t\t: %" PRIu32 "\n",
433
     function,
434
     file_information->number_of_volumes );
435
436
    libcnotify_printf(
437
     "%s: volumes information size\t\t: %" PRIu32 "\n",
438
     function,
439
     file_information->volumes_information_size );
440
441
    if( io_handle->format_version == 23 )
442
    {
443
      byte_stream_copy_to_uint32_little_endian(
444
       ( (scca_file_information_v23_t *) data )->unknown3c,
445
       value_32bit );
446
      libcnotify_printf(
447
       "%s: unknown3c\t\t\t\t: 0x%08" PRIx64 "\n",
448
       function,
449
       value_64bit );
450
    }
451
    if( io_handle->format_version < 26 )
452
    {
453
      number_of_last_run_times = 1;
454
    }
455
    else
456
    {
457
      number_of_last_run_times = 8;
458
    }
459
    for( last_run_time_index = 0;
460
         last_run_time_index < number_of_last_run_times;
461
         last_run_time_index++ )
462
    {
463
      if( io_handle->format_version == 17 )
464
      {
465
        result = libscca_debug_print_filetime_value(
466
            function,
467
            "last run time\t\t\t",
468
                  &( ( (scca_file_information_v17_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
469
            8,
470
            LIBFDATETIME_ENDIAN_LITTLE,
471
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
472
            error );
473
      }
474
      else if( io_handle->format_version == 23 )
475
      {
476
        result = libscca_debug_print_filetime_value(
477
            function,
478
            "last run time\t\t\t",
479
                  &( ( (scca_file_information_v23_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
480
            8,
481
            LIBFDATETIME_ENDIAN_LITTLE,
482
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
483
            error );
484
      }
485
      else if( ( io_handle->format_version == 26 )
486
            || ( io_handle->format_version == 30 )
487
            || ( io_handle->format_version == 31 ) )
488
      {
489
        result = libscca_debug_print_filetime_value(
490
            function,
491
            "last run time\t\t\t",
492
                  &( ( (scca_file_information_v26_t *) data )->last_run_time[ last_run_time_index * 8 ] ),
493
            8,
494
            LIBFDATETIME_ENDIAN_LITTLE,
495
                  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
496
            error );
497
      }
498
      if( result != 1 )
499
      {
500
        libcerror_error_set(
501
         error,
502
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
503
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
504
         "%s: unable to print filetime value.",
505
         function );
506
507
        return( -1 );
508
      }
509
    }
510
    libcnotify_printf(
511
     "%s: unknown4:\n",
512
     function );
513
514
    if( io_handle->format_version == 17 )
515
    {
516
      libcnotify_print_data(
517
       ( (scca_file_information_v17_t *) data )->unknown4,
518
       16,
519
       0 );
520
    }
521
    else if( io_handle->format_version == 23 )
522
    {
523
      libcnotify_print_data(
524
       ( (scca_file_information_v23_t *) data )->unknown4,
525
       16,
526
       0 );
527
    }
528
    else if( ( io_handle->format_version == 26 )
529
          || ( ( io_handle->format_version == 30 )
530
           &&  ( file_information->metrics_array_offset == 0x00000130 ) ) )
531
    {
532
      libcnotify_print_data(
533
       ( (scca_file_information_v26_t *) data )->unknown4,
534
       16,
535
       0 );
536
    }
537
    else if( ( ( io_handle->format_version == 30 )
538
           &&  ( file_information->metrics_array_offset == 0x00000128 ) )
539
          || ( io_handle->format_version == 31 ) )
540
    {
541
      libcnotify_print_data(
542
       ( (scca_file_information_v30_2_t *) data )->unknown4,
543
       8,
544
       0 );
545
    }
546
    libcnotify_printf(
547
     "%s: run count\t\t\t\t: %" PRIu32 "\n",
548
     function,
549
     file_information->run_count );
550
551
    if( io_handle->format_version == 17 )
552
    {
553
      byte_stream_copy_to_uint32_little_endian(
554
       ( (scca_file_information_v17_t *) data )->unknown5,
555
       value_32bit );
556
      libcnotify_printf(
557
       "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
558
       function,
559
       value_32bit );
560
561
      libcnotify_printf(
562
       "\n" );
563
    }
564
    else if( io_handle->format_version == 23 )
565
    {
566
      byte_stream_copy_to_uint32_little_endian(
567
       ( (scca_file_information_v23_t *) data )->unknown5,
568
       value_32bit );
569
      libcnotify_printf(
570
       "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
571
       function,
572
       value_32bit );
573
574
      libcnotify_printf(
575
       "%s: unknown6:\n",
576
       function );
577
      libcnotify_print_data(
578
       ( (scca_file_information_v23_t *) data )->unknown6,
579
       80,
580
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
581
    }
582
    else if( io_handle->format_version == 26 )
583
    {
584
      byte_stream_copy_to_uint32_little_endian(
585
       ( (scca_file_information_v26_t *) data )->unknown5a,
586
       value_32bit );
587
      libcnotify_printf(
588
       "%s: unknown5a\t\t\t\t: 0x%08" PRIx32 "\n",
589
       function,
590
       value_32bit );
591
592
      byte_stream_copy_to_uint32_little_endian(
593
       ( (scca_file_information_v26_t *) data )->unknown5b,
594
       value_32bit );
595
      libcnotify_printf(
596
       "%s: unknown5b\t\t\t\t: 0x%08" PRIx32 "\n",
597
       function,
598
       value_32bit );
599
600
      libcnotify_printf(
601
       "%s: unknown6:\n",
602
       function );
603
      libcnotify_print_data(
604
       ( (scca_file_information_v26_t *) data )->unknown6,
605
       84,
606
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
607
    }
608
    else if( ( io_handle->format_version == 30 )
609
          && ( file_information->metrics_array_offset == 0x00000130 ) )
610
    {
611
      byte_stream_copy_to_uint32_little_endian(
612
       ( (scca_file_information_v30_1_t *) data )->unknown5a,
613
       value_32bit );
614
      libcnotify_printf(
615
       "%s: unknown5a\t\t\t\t: 0x%08" PRIx32 "\n",
616
       function,
617
       value_32bit );
618
619
      byte_stream_copy_to_uint32_little_endian(
620
       ( (scca_file_information_v30_1_t *) data )->unknown5b,
621
       value_32bit );
622
      libcnotify_printf(
623
       "%s: unknown5b\t\t\t\t: 0x%08" PRIx32 "\n",
624
       function,
625
       value_32bit );
626
627
      byte_stream_copy_to_uint32_little_endian(
628
       ( (scca_file_information_v30_1_t *) data )->hash_string_offset,
629
       value_32bit );
630
      libcnotify_printf(
631
       "%s: hash string offset\t\t\t: 0x%08" PRIx32 "\n",
632
       function,
633
       value_32bit );
634
635
      byte_stream_copy_to_uint32_little_endian(
636
       ( (scca_file_information_v30_1_t *) data )->hash_string_size,
637
       value_32bit );
638
      libcnotify_printf(
639
       "%s: hash string size\t\t\t: %" PRIu32 "\n",
640
       function,
641
       value_32bit );
642
643
      libcnotify_printf(
644
       "%s: unknown6:\n",
645
       function );
646
      libcnotify_print_data(
647
       ( (scca_file_information_v30_1_t *) data )->unknown6,
648
       76,
649
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
650
    }
651
    else if( ( ( io_handle->format_version == 30 )
652
           && ( file_information->metrics_array_offset == 0x00000128 ) )
653
          || ( io_handle->format_version == 31 ) )
654
    {
655
      byte_stream_copy_to_uint32_little_endian(
656
       ( (scca_file_information_v30_2_t *) data )->unknown5a,
657
       value_32bit );
658
      libcnotify_printf(
659
       "%s: unknown5a\t\t\t\t: 0x%08" PRIx32 "\n",
660
       function,
661
       value_32bit );
662
663
      byte_stream_copy_to_uint32_little_endian(
664
       ( (scca_file_information_v30_2_t *) data )->unknown5b,
665
       value_32bit );
666
      libcnotify_printf(
667
       "%s: unknown5b\t\t\t\t: 0x%08" PRIx32 "\n",
668
       function,
669
       value_32bit );
670
671
      byte_stream_copy_to_uint32_little_endian(
672
       ( (scca_file_information_v30_2_t *) data )->hash_string_offset,
673
       value_32bit );
674
      libcnotify_printf(
675
       "%s: hash string offset\t\t\t: 0x%08" PRIx32 "\n",
676
       function,
677
       value_32bit );
678
679
      byte_stream_copy_to_uint32_little_endian(
680
       ( (scca_file_information_v30_2_t *) data )->hash_string_size,
681
       value_32bit );
682
      libcnotify_printf(
683
       "%s: hash string size\t\t\t: %" PRIu32 "\n",
684
       function,
685
       value_32bit );
686
687
      libcnotify_printf(
688
       "%s: unknown6:\n",
689
       function );
690
      libcnotify_print_data(
691
       ( (scca_file_information_v30_2_t *) data )->unknown6,
692
       76,
693
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
694
    }
695
  }
696
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
697
698
1.38k
  return( 1 );
699
1.38k
}
700
701
/* Reads the file information
702
 * Returns 1 if successful or -1 on error
703
 */
704
int libscca_file_information_read_stream(
705
     libscca_file_information_t *file_information,
706
     libfdata_stream_t *uncompressed_data_stream,
707
     libbfio_handle_t *file_io_handle,
708
     libscca_io_handle_t *io_handle,
709
     libcerror_error_t **error )
710
1.50k
{
711
1.50k
  uint8_t *file_information_data    = NULL;
712
1.50k
  static char *function             = "libscca_file_information_read_stream";
713
1.50k
  size_t file_information_data_size = 0;
714
1.50k
  ssize_t read_count                = 0;
715
716
1.50k
  if( file_information == NULL )
717
0
  {
718
0
    libcerror_error_set(
719
0
     error,
720
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
721
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
722
0
     "%s: invalid file information.",
723
0
     function );
724
725
0
    return( -1 );
726
0
  }
727
1.50k
  if( io_handle == NULL )
728
0
  {
729
0
    libcerror_error_set(
730
0
     error,
731
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
732
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
733
0
     "%s: invalid IO handle.",
734
0
     function );
735
736
0
    return( -1 );
737
0
  }
738
1.50k
  if( ( io_handle->format_version != 17 )
739
187
   && ( io_handle->format_version != 23 )
740
163
   && ( io_handle->format_version != 26 )
741
145
   && ( io_handle->format_version != 30 )
742
89
   && ( io_handle->format_version != 31 ) )
743
70
  {
744
70
    libcerror_error_set(
745
70
     error,
746
70
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
747
70
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
748
70
     "%s: invalid IO handle - unsupported format version.",
749
70
     function );
750
751
70
    return( -1 );
752
70
  }
753
1.43k
  if( io_handle->format_version == 17 )
754
1.31k
  {
755
1.31k
    file_information_data_size = sizeof( scca_file_information_v17_t );
756
1.31k
  }
757
117
  else if( io_handle->format_version == 23 )
758
24
  {
759
24
    file_information_data_size = sizeof( scca_file_information_v23_t );
760
24
  }
761
93
  else if( ( io_handle->format_version == 26 )
762
75
        || ( io_handle->format_version == 30 )
763
19
        || ( io_handle->format_version == 31 ) )
764
93
  {
765
93
    file_information_data_size = sizeof( scca_file_information_v26_t );
766
93
  }
767
1.43k
  file_information_data = (uint8_t *) memory_allocate(
768
1.43k
                                       sizeof( uint8_t ) * file_information_data_size );
769
770
1.43k
  if( file_information_data == NULL )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
775
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
776
0
     "%s: unable to create file information data.",
777
0
     function );
778
779
0
    goto on_error;
780
0
  }
781
1.43k
  read_count = libfdata_stream_read_buffer(
782
1.43k
                uncompressed_data_stream,
783
1.43k
                (intptr_t *) file_io_handle,
784
1.43k
                file_information_data,
785
1.43k
                file_information_data_size,
786
1.43k
                0,
787
1.43k
                error );
788
789
1.43k
  if( read_count != (ssize_t) file_information_data_size )
790
12
  {
791
12
    libcerror_error_set(
792
12
     error,
793
12
     LIBCERROR_ERROR_DOMAIN_IO,
794
12
     LIBCERROR_IO_ERROR_READ_FAILED,
795
12
     "%s: unable to read file information data.",
796
12
     function );
797
798
12
    goto on_error;
799
12
  }
800
1.42k
  if( libscca_file_information_read_data(
801
1.42k
       file_information,
802
1.42k
       io_handle,
803
1.42k
       file_information_data,
804
1.42k
       file_information_data_size,
805
1.42k
       error ) != 1 )
806
42
  {
807
42
    libcerror_error_set(
808
42
     error,
809
42
     LIBCERROR_ERROR_DOMAIN_IO,
810
42
     LIBCERROR_IO_ERROR_READ_FAILED,
811
42
     "%s: unable to read file information data.",
812
42
     function );
813
814
42
    goto on_error;
815
42
  }
816
1.38k
  memory_free(
817
1.38k
   file_information_data );
818
819
1.38k
  return( 1 );
820
821
54
on_error:
822
54
  if( file_information_data != NULL )
823
54
  {
824
54
    memory_free(
825
54
     file_information_data );
826
54
  }
827
54
  return( -1 );
828
1.42k
}
829