Coverage Report

Created: 2024-02-25 07:20

/src/libscca/libscca/libscca_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "libscca_codepage.h"
29
#include "libscca_compressed_block.h"
30
#include "libscca_compressed_blocks_stream.h"
31
#include "libscca_debug.h"
32
#include "libscca_definitions.h"
33
#include "libscca_io_handle.h"
34
#include "libscca_file.h"
35
#include "libscca_file_header.h"
36
#include "libscca_file_information.h"
37
#include "libscca_file_metrics.h"
38
#include "libscca_filename_strings.h"
39
#include "libscca_libbfio.h"
40
#include "libscca_libcdata.h"
41
#include "libscca_libcerror.h"
42
#include "libscca_libcnotify.h"
43
#include "libscca_libfcache.h"
44
#include "libscca_libfdata.h"
45
#include "libscca_libfvalue.h"
46
#include "libscca_libuna.h"
47
#include "libscca_volume_information.h"
48
49
/* Creates a file
50
 * Make sure the value file is referencing, is set to NULL
51
 * Returns 1 if successful or -1 on error
52
 */
53
int libscca_file_initialize(
54
     libscca_file_t **file,
55
     libcerror_error_t **error )
56
1.92k
{
57
1.92k
  libscca_internal_file_t *internal_file = NULL;
58
1.92k
  static char *function                  = "libscca_file_initialize";
59
60
1.92k
  if( file == NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
65
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
66
0
     "%s: invalid file.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
1.92k
  if( *file != NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
76
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
77
0
     "%s: invalid file value already set.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
1.92k
  internal_file = memory_allocate_structure(
83
1.92k
                   libscca_internal_file_t );
84
85
1.92k
  if( internal_file == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
90
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
91
0
     "%s: unable to create file.",
92
0
     function );
93
94
0
    goto on_error;
95
0
  }
96
1.92k
  if( memory_set(
97
1.92k
       internal_file,
98
1.92k
       0,
99
1.92k
       sizeof( libscca_internal_file_t ) ) == NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
104
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
105
0
     "%s: unable to clear file.",
106
0
     function );
107
108
0
    memory_free(
109
0
     internal_file );
110
111
0
    return( -1 );
112
0
  }
113
1.92k
  if( libcdata_array_initialize(
114
1.92k
       &( internal_file->file_metrics_array ),
115
1.92k
       0,
116
1.92k
       error ) != 1 )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
121
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
122
0
     "%s: unable to create file metrics array.",
123
0
     function );
124
125
0
    goto on_error;
126
0
  }
127
1.92k
  if( libscca_filename_strings_initialize(
128
1.92k
       &( internal_file->filename_strings ),
129
1.92k
       error ) != 1 )
130
0
  {
131
0
    libcerror_error_set(
132
0
     error,
133
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
134
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
135
0
     "%s: unable to create filename strings.",
136
0
     function );
137
138
0
    goto on_error;
139
0
  }
140
1.92k
  if( libcdata_array_initialize(
141
1.92k
       &( internal_file->volumes_array ),
142
1.92k
       0,
143
1.92k
       error ) != 1 )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
148
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
149
0
     "%s: unable to create volumes array.",
150
0
     function );
151
152
0
    goto on_error;
153
0
  }
154
1.92k
  if( libscca_io_handle_initialize(
155
1.92k
       &( internal_file->io_handle ),
156
1.92k
       error ) != 1 )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
161
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
162
0
     "%s: unable to create IO handle.",
163
0
     function );
164
165
0
    goto on_error;
166
0
  }
167
1.92k
  *file = (libscca_file_t *) internal_file;
168
169
1.92k
  return( 1 );
170
171
0
on_error:
172
0
  if( internal_file != NULL )
173
0
  {
174
0
    if( internal_file->volumes_array != NULL )
175
0
    {
176
0
      libcdata_array_free(
177
0
       &( internal_file->volumes_array ),
178
0
       NULL,
179
0
       NULL );
180
0
    }
181
0
    if( internal_file->filename_strings != NULL )
182
0
    {
183
0
      libscca_filename_strings_free(
184
0
       &( internal_file->filename_strings ),
185
0
       NULL );
186
0
    }
187
0
    if( internal_file->file_metrics_array != NULL )
188
0
    {
189
0
      libcdata_array_free(
190
0
       &( internal_file->file_metrics_array ),
191
0
       NULL,
192
0
       NULL );
193
0
    }
194
0
    memory_free(
195
0
     internal_file );
196
0
  }
197
0
  return( -1 );
198
1.92k
}
199
200
/* Frees a file
201
 * Returns 1 if successful or -1 on error
202
 */
203
int libscca_file_free(
204
     libscca_file_t **file,
205
     libcerror_error_t **error )
206
1.92k
{
207
1.92k
  libscca_internal_file_t *internal_file = NULL;
208
1.92k
  static char *function                  = "libscca_file_free";
209
1.92k
  int result                             = 1;
210
211
1.92k
  if( file == 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 file.",
218
0
     function );
219
220
0
    return( -1 );
221
0
  }
222
1.92k
  if( *file != NULL )
223
1.92k
  {
224
1.92k
    internal_file = (libscca_internal_file_t *) *file;
225
226
1.92k
    if( internal_file->file_io_handle != NULL )
227
1.88k
    {
228
1.88k
      if( libscca_file_close(
229
1.88k
           *file,
230
1.88k
           error ) != 0 )
231
0
      {
232
0
        libcerror_error_set(
233
0
         error,
234
0
         LIBCERROR_ERROR_DOMAIN_IO,
235
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
236
0
         "%s: unable to close file.",
237
0
         function );
238
239
0
        result = -1;
240
0
      }
241
1.88k
    }
242
1.92k
    *file = NULL;
243
244
1.92k
    if( libcdata_array_free(
245
1.92k
         &( internal_file->volumes_array ),
246
1.92k
         (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_volume_information_free,
247
1.92k
         error ) != 1 )
248
0
    {
249
0
      libcerror_error_set(
250
0
       error,
251
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
252
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
253
0
       "%s: unable to free volumes array.",
254
0
       function );
255
256
0
      result = -1;
257
0
    }
258
1.92k
    if( libscca_filename_strings_free(
259
1.92k
         &( internal_file->filename_strings ),
260
1.92k
         error ) != 1 )
261
0
    {
262
0
      libcerror_error_set(
263
0
       error,
264
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
265
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
266
0
       "%s: unable to free filename strings.",
267
0
       function );
268
269
0
      result = -1;
270
0
    }
271
1.92k
    if( libcdata_array_free(
272
1.92k
         &( internal_file->file_metrics_array ),
273
1.92k
         (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_file_metrics_free,
274
1.92k
         error ) != 1 )
275
0
    {
276
0
      libcerror_error_set(
277
0
       error,
278
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
279
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
280
0
       "%s: unable to free file metrics array.",
281
0
       function );
282
283
0
      result = -1;
284
0
    }
285
1.92k
    if( libscca_io_handle_free(
286
1.92k
         &( internal_file->io_handle ),
287
1.92k
         error ) != 1 )
288
0
    {
289
0
      libcerror_error_set(
290
0
       error,
291
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
292
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
293
0
       "%s: unable to free IO handle.",
294
0
       function );
295
296
0
      result = -1;
297
0
    }
298
1.92k
    memory_free(
299
1.92k
     internal_file );
300
1.92k
  }
301
1.92k
  return( result );
302
1.92k
}
303
304
/* Signals the file to abort its current activity
305
 * Returns 1 if successful or -1 on error
306
 */
307
int libscca_file_signal_abort(
308
     libscca_file_t *file,
309
     libcerror_error_t **error )
310
0
{
311
0
  libscca_internal_file_t *internal_file = NULL;
312
0
  static char *function                  = "libscca_file_signal_abort";
313
314
0
  if( file == NULL )
315
0
  {
316
0
    libcerror_error_set(
317
0
     error,
318
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
319
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
320
0
     "%s: invalid file.",
321
0
     function );
322
323
0
    return( -1 );
324
0
  }
325
0
  internal_file = (libscca_internal_file_t *) file;
326
327
0
  if( internal_file->io_handle == NULL )
328
0
  {
329
0
    libcerror_error_set(
330
0
     error,
331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
332
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
333
0
     "%s: invalid file - missing IO handle.",
334
0
     function );
335
336
0
    return( -1 );
337
0
  }
338
0
  internal_file->io_handle->abort = 1;
339
340
0
  return( 1 );
341
0
}
342
343
/* Opens a file
344
 * Returns 1 if successful or -1 on error
345
 */
346
int libscca_file_open(
347
     libscca_file_t *file,
348
     const char *filename,
349
     int access_flags,
350
     libcerror_error_t **error )
351
0
{
352
0
  libbfio_handle_t *file_io_handle       = NULL;
353
0
  libscca_internal_file_t *internal_file = NULL;
354
0
  static char *function                  = "libscca_file_open";
355
356
0
  if( file == NULL )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
362
0
     "%s: invalid file.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
0
  internal_file = (libscca_internal_file_t *) file;
368
369
0
  if( filename == NULL )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
375
0
     "%s: invalid filename.",
376
0
     function );
377
378
0
    return( -1 );
379
0
  }
380
0
  if( ( ( access_flags & LIBSCCA_ACCESS_FLAG_READ ) == 0 )
381
0
   && ( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) == 0 ) )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
386
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
387
0
     "%s: unsupported access flags.",
388
0
     function );
389
390
0
    return( -1 );
391
0
  }
392
0
  if( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) != 0 )
393
0
  {
394
0
    libcerror_error_set(
395
0
     error,
396
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
397
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
398
0
     "%s: write access currently not supported.",
399
0
     function );
400
401
0
    return( -1 );
402
0
  }
403
0
  if( libbfio_file_initialize(
404
0
       &file_io_handle,
405
0
       error ) != 1 )
406
0
  {
407
0
    libcerror_error_set(
408
0
     error,
409
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
410
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
411
0
     "%s: unable to create file IO handle.",
412
0
     function );
413
414
0
    goto on_error;
415
0
  }
416
#if defined( HAVE_DEBUG_OUTPUT )
417
  if( libbfio_handle_set_track_offsets_read(
418
       file_io_handle,
419
       1,
420
       error ) != 1 )
421
  {
422
                libcerror_error_set(
423
                 error,
424
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
425
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
426
                 "%s: unable to set track offsets read in file IO handle.",
427
                 function );
428
429
    goto on_error;
430
  }
431
#endif
432
0
  if( libbfio_file_set_name(
433
0
       file_io_handle,
434
0
       filename,
435
0
       narrow_string_length(
436
0
        filename ) + 1,
437
0
       error ) != 1 )
438
0
  {
439
0
                libcerror_error_set(
440
0
                 error,
441
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
442
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
443
0
                 "%s: unable to set filename in file IO handle.",
444
0
                 function );
445
446
0
    goto on_error;
447
0
  }
448
0
  if( libscca_file_open_file_io_handle(
449
0
       file,
450
0
       file_io_handle,
451
0
       access_flags,
452
0
       error ) != 1 )
453
0
  {
454
0
    libcerror_error_set(
455
0
     error,
456
0
     LIBCERROR_ERROR_DOMAIN_IO,
457
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
458
0
     "%s: unable to open file: %s.",
459
0
     function,
460
0
     filename );
461
462
0
    goto on_error;
463
0
  }
464
0
  internal_file->file_io_handle_created_in_library = 1;
465
466
0
  return( 1 );
467
468
0
on_error:
469
0
  if( file_io_handle != NULL )
470
0
  {
471
0
    libbfio_handle_free(
472
0
     &file_io_handle,
473
0
     NULL );
474
0
  }
475
0
  return( -1 );
476
0
}
477
478
#if defined( HAVE_WIDE_CHARACTER_TYPE )
479
480
/* Opens a file
481
 * Returns 1 if successful or -1 on error
482
 */
483
int libscca_file_open_wide(
484
     libscca_file_t *file,
485
     const wchar_t *filename,
486
     int access_flags,
487
     libcerror_error_t **error )
488
{
489
  libbfio_handle_t *file_io_handle       = NULL;
490
  libscca_internal_file_t *internal_file = NULL;
491
  static char *function                  = "libscca_file_open_wide";
492
493
  if( file == NULL )
494
  {
495
    libcerror_error_set(
496
     error,
497
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
498
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
499
     "%s: invalid file.",
500
     function );
501
502
    return( -1 );
503
  }
504
  internal_file = (libscca_internal_file_t *) file;
505
506
  if( filename == NULL )
507
  {
508
    libcerror_error_set(
509
     error,
510
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
511
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
512
     "%s: invalid filename.",
513
     function );
514
515
    return( -1 );
516
  }
517
  if( ( ( access_flags & LIBSCCA_ACCESS_FLAG_READ ) == 0 )
518
   && ( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) == 0 ) )
519
  {
520
    libcerror_error_set(
521
     error,
522
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
523
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
524
     "%s: unsupported access flags.",
525
     function );
526
527
    return( -1 );
528
  }
529
  if( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) != 0 )
530
  {
531
    libcerror_error_set(
532
     error,
533
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
534
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
535
     "%s: write access currently not supported.",
536
     function );
537
538
    return( -1 );
539
  }
540
  if( libbfio_file_initialize(
541
       &file_io_handle,
542
       error ) != 1 )
543
  {
544
    libcerror_error_set(
545
     error,
546
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
547
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
548
     "%s: unable to create file IO handle.",
549
     function );
550
551
    goto on_error;
552
  }
553
#if defined( HAVE_DEBUG_OUTPUT )
554
  if( libbfio_handle_set_track_offsets_read(
555
       file_io_handle,
556
       1,
557
       error ) != 1 )
558
  {
559
                libcerror_error_set(
560
                 error,
561
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
562
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
563
                 "%s: unable to set track offsets read in file IO handle.",
564
                 function );
565
566
    goto on_error;
567
  }
568
#endif
569
  if( libbfio_file_set_name_wide(
570
       file_io_handle,
571
       filename,
572
       wide_string_length(
573
        filename ) + 1,
574
       error ) != 1 )
575
  {
576
                libcerror_error_set(
577
                 error,
578
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
579
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
580
                 "%s: unable to set filename in file IO handle.",
581
                 function );
582
583
    goto on_error;
584
  }
585
  if( libscca_file_open_file_io_handle(
586
       file,
587
       file_io_handle,
588
       access_flags,
589
       error ) != 1 )
590
  {
591
    libcerror_error_set(
592
     error,
593
     LIBCERROR_ERROR_DOMAIN_IO,
594
     LIBCERROR_IO_ERROR_OPEN_FAILED,
595
     "%s: unable to open file: %ls.",
596
     function,
597
     filename );
598
599
    goto on_error;
600
  }
601
  internal_file->file_io_handle_created_in_library = 1;
602
603
  return( 1 );
604
605
on_error:
606
  if( file_io_handle != NULL )
607
  {
608
    libbfio_handle_free(
609
     &file_io_handle,
610
     NULL );
611
  }
612
  return( -1 );
613
}
614
615
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
616
617
/* Opens a file using a Basic File IO (bfio) handle
618
 * Returns 1 if successful or -1 on error
619
 */
620
int libscca_file_open_file_io_handle(
621
     libscca_file_t *file,
622
     libbfio_handle_t *file_io_handle,
623
     int access_flags,
624
     libcerror_error_t **error )
625
1.92k
{
626
1.92k
  libscca_internal_file_t *internal_file   = NULL;
627
1.92k
  static char *function                    = "libscca_file_open_file_io_handle";
628
1.92k
  uint8_t file_io_handle_opened_in_library = 0;
629
1.92k
  int bfio_access_flags                    = 0;
630
1.92k
  int file_io_handle_is_open               = 0;
631
632
1.92k
  if( file == NULL )
633
0
  {
634
0
    libcerror_error_set(
635
0
     error,
636
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
637
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
638
0
     "%s: invalid file.",
639
0
     function );
640
641
0
    return( -1 );
642
0
  }
643
1.92k
  internal_file = (libscca_internal_file_t *) file;
644
645
1.92k
  if( internal_file->file_io_handle != NULL )
646
0
  {
647
0
    libcerror_error_set(
648
0
     error,
649
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
650
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
651
0
     "%s: invalid file - file IO handle already set.",
652
0
     function );
653
654
0
    return( -1 );
655
0
  }
656
1.92k
  if( file_io_handle == NULL )
657
0
  {
658
0
    libcerror_error_set(
659
0
     error,
660
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
661
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
662
0
     "%s: invalid file IO handle.",
663
0
     function );
664
665
0
    return( -1 );
666
0
  }
667
1.92k
  if( ( ( access_flags & LIBSCCA_ACCESS_FLAG_READ ) == 0 )
668
1.92k
   && ( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) == 0 ) )
669
0
  {
670
0
    libcerror_error_set(
671
0
     error,
672
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
673
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
674
0
     "%s: unsupported access flags.",
675
0
     function );
676
677
0
    return( -1 );
678
0
  }
679
1.92k
  if( ( access_flags & LIBSCCA_ACCESS_FLAG_WRITE ) != 0 )
680
0
  {
681
0
    libcerror_error_set(
682
0
     error,
683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
684
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
685
0
     "%s: write access currently not supported.",
686
0
     function );
687
688
0
    return( -1 );
689
0
  }
690
1.92k
  if( ( access_flags & LIBSCCA_ACCESS_FLAG_READ ) != 0 )
691
1.92k
  {
692
1.92k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
693
1.92k
  }
694
1.92k
  internal_file->file_io_handle = file_io_handle;
695
696
1.92k
  file_io_handle_is_open = libbfio_handle_is_open(
697
1.92k
                            internal_file->file_io_handle,
698
1.92k
                            error );
699
700
1.92k
  if( file_io_handle_is_open == -1 )
701
0
  {
702
0
    libcerror_error_set(
703
0
     error,
704
0
     LIBCERROR_ERROR_DOMAIN_IO,
705
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
706
0
     "%s: unable to determine if file IO handle is open.",
707
0
     function );
708
709
0
    goto on_error;
710
0
  }
711
1.92k
  else if( file_io_handle_is_open == 0 )
712
1.92k
  {
713
1.92k
    if( libbfio_handle_open(
714
1.92k
         internal_file->file_io_handle,
715
1.92k
         bfio_access_flags,
716
1.92k
         error ) != 1 )
717
0
    {
718
0
      libcerror_error_set(
719
0
       error,
720
0
       LIBCERROR_ERROR_DOMAIN_IO,
721
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
722
0
       "%s: unable to open file IO handle.",
723
0
       function );
724
725
0
      goto on_error;
726
0
    }
727
1.92k
    file_io_handle_opened_in_library = 1;
728
1.92k
  }
729
1.92k
  if( libscca_file_open_read(
730
1.92k
       internal_file,
731
1.92k
       file_io_handle,
732
1.92k
       error ) != 1 )
733
1.88k
  {
734
1.88k
    libcerror_error_set(
735
1.88k
     error,
736
1.88k
     LIBCERROR_ERROR_DOMAIN_IO,
737
1.88k
     LIBCERROR_IO_ERROR_READ_FAILED,
738
1.88k
     "%s: unable to read from file handle.",
739
1.88k
     function );
740
741
1.88k
    goto on_error;
742
1.88k
  }
743
34
  internal_file->file_io_handle                   = file_io_handle;
744
34
  internal_file->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
745
746
34
  return( 1 );
747
748
1.88k
on_error:
749
1.88k
  if( file_io_handle_opened_in_library != 0 )
750
1.88k
  {
751
1.88k
    libbfio_handle_close(
752
1.88k
     file_io_handle,
753
1.88k
     error );
754
1.88k
  }
755
1.88k
  return( -1 );
756
1.92k
}
757
758
/* Closes a file
759
 * Returns 0 if successful or -1 on error
760
 */
761
int libscca_file_close(
762
     libscca_file_t *file,
763
     libcerror_error_t **error )
764
1.92k
{
765
1.92k
  libscca_internal_file_t *internal_file = NULL;
766
1.92k
  static char *function                  = "libscca_file_close";
767
1.92k
  int result                             = 0;
768
769
1.92k
  if( file == NULL )
770
0
  {
771
0
    libcerror_error_set(
772
0
     error,
773
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
774
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
775
0
     "%s: invalid file.",
776
0
     function );
777
778
0
    return( -1 );
779
0
  }
780
1.92k
  internal_file = (libscca_internal_file_t *) file;
781
782
1.92k
  if( internal_file->file_io_handle == NULL )
783
0
  {
784
0
    libcerror_error_set(
785
0
     error,
786
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
787
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
788
0
     "%s: invalid file - missing file IO handle.",
789
0
     function );
790
791
0
    return( -1 );
792
0
  }
793
#if defined( HAVE_DEBUG_OUTPUT )
794
  if( libcnotify_verbose != 0 )
795
  {
796
    if( internal_file->file_io_handle_created_in_library != 0 )
797
    {
798
      if( libscca_debug_print_read_offsets(
799
           internal_file->file_io_handle,
800
           error ) != 1 )
801
      {
802
        libcerror_error_set(
803
         error,
804
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
805
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
806
         "%s: unable to print the read offsets.",
807
         function );
808
809
        result = -1;
810
      }
811
    }
812
  }
813
#endif
814
1.92k
  if( internal_file->file_io_handle_opened_in_library != 0 )
815
34
  {
816
34
    if( libbfio_handle_close(
817
34
         internal_file->file_io_handle,
818
34
         error ) != 0 )
819
0
    {
820
0
      libcerror_error_set(
821
0
       error,
822
0
       LIBCERROR_ERROR_DOMAIN_IO,
823
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
824
0
       "%s: unable to close file IO handle.",
825
0
       function );
826
827
0
      result = -1;
828
0
    }
829
34
    internal_file->file_io_handle_opened_in_library = 0;
830
34
  }
831
1.92k
  if( internal_file->file_io_handle_created_in_library != 0 )
832
0
  {
833
0
    if( libbfio_handle_free(
834
0
         &( internal_file->file_io_handle ),
835
0
         error ) != 1 )
836
0
    {
837
0
      libcerror_error_set(
838
0
       error,
839
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
840
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
841
0
       "%s: unable to free file IO handle.",
842
0
       function );
843
844
0
      result = -1;
845
0
    }
846
0
    internal_file->file_io_handle_created_in_library = 0;
847
0
  }
848
1.92k
  internal_file->file_io_handle = NULL;
849
850
1.92k
  if( libscca_io_handle_clear(
851
1.92k
       internal_file->io_handle,
852
1.92k
       error ) != 1 )
853
0
  {
854
0
    libcerror_error_set(
855
0
     error,
856
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
857
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
858
0
     "%s: unable to clear IO handle.",
859
0
     function );
860
861
0
    result = -1;
862
0
  }
863
1.92k
  if( internal_file->compressed_blocks_list != NULL )
864
411
  {
865
411
    if( libfdata_list_free(
866
411
         &( internal_file->compressed_blocks_list ),
867
411
         error ) != 1 )
868
0
    {
869
0
      libcerror_error_set(
870
0
       error,
871
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
872
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
873
0
       "%s: unable to free compressed blocks list.",
874
0
       function );
875
876
0
      result = -1;
877
0
    }
878
411
  }
879
1.92k
  if( internal_file->compressed_blocks_cache != NULL )
880
411
  {
881
411
    if( libfcache_cache_free(
882
411
         &( internal_file->compressed_blocks_cache ),
883
411
         error ) != 1 )
884
0
    {
885
0
      libcerror_error_set(
886
0
       error,
887
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
888
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
889
0
       "%s: unable to free compressed blocks cache.",
890
0
       function );
891
892
0
      result = -1;
893
0
    }
894
411
  }
895
1.92k
  if( internal_file->uncompressed_data_stream != NULL )
896
1.60k
  {
897
1.60k
    if( libfdata_stream_free(
898
1.60k
         &( internal_file->uncompressed_data_stream ),
899
1.60k
         error ) != 1 )
900
0
    {
901
0
      libcerror_error_set(
902
0
       error,
903
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
904
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
905
0
       "%s: unable to free uncompressed data strea,.",
906
0
       function );
907
908
0
      result = -1;
909
0
    }
910
1.60k
  }
911
1.92k
  if( internal_file->file_header != NULL )
912
34
  {
913
34
    if( libscca_file_header_free(
914
34
         &( internal_file->file_header ),
915
34
         error ) != 1 )
916
0
    {
917
0
      libcerror_error_set(
918
0
       error,
919
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
920
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
921
0
       "%s: unable to free file header.",
922
0
       function );
923
924
0
      result = -1;
925
0
    }
926
34
  }
927
1.92k
  if( internal_file->file_information != NULL )
928
34
  {
929
34
    if( libscca_file_information_free(
930
34
         &( internal_file->file_information ),
931
34
         error ) != 1 )
932
0
    {
933
0
      libcerror_error_set(
934
0
       error,
935
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
936
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
937
0
       "%s: unable to free file information.",
938
0
       function );
939
940
0
      result = -1;
941
0
    }
942
34
  }
943
1.92k
  if( libcdata_array_empty(
944
1.92k
       internal_file->file_metrics_array,
945
1.92k
       (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_file_metrics_free,
946
1.92k
       error ) != 1 )
947
0
  {
948
0
    libcerror_error_set(
949
0
     error,
950
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
951
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
952
0
     "%s: unable to empty file metrics array.",
953
0
     function );
954
955
0
    result = -1;
956
0
  }
957
1.92k
  if( libscca_filename_strings_clear(
958
1.92k
       internal_file->filename_strings,
959
1.92k
       error ) != 1 )
960
0
  {
961
0
    libcerror_error_set(
962
0
     error,
963
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
964
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
965
0
     "%s: unable to clear filename strings.",
966
0
     function );
967
968
0
    result = -1;
969
0
  }
970
1.92k
  if( libcdata_array_empty(
971
1.92k
       internal_file->volumes_array,
972
1.92k
       (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_volume_information_free,
973
1.92k
       error ) != 1 )
974
0
  {
975
0
    libcerror_error_set(
976
0
     error,
977
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
978
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
979
0
     "%s: unable to empty volumes array.",
980
0
     function );
981
982
0
    result = -1;
983
0
  }
984
1.92k
  return( result );
985
1.92k
}
986
987
/* Opens a file for reading
988
 * Returns 1 if successful or -1 on error
989
 */
990
int libscca_file_open_read(
991
     libscca_internal_file_t *internal_file,
992
     libbfio_handle_t *file_io_handle,
993
     libcerror_error_t **error )
994
1.92k
{
995
1.92k
  static char *function = "libscca_file_open_read";
996
1.92k
  size64_t file_size    = 0;
997
1.92k
  off64_t file_offset   = 0;
998
1.92k
  off64_t next_offset   = 0;
999
1.92k
  int segment_index     = 0;
1000
1001
1.92k
  if( internal_file == NULL )
1002
0
  {
1003
0
    libcerror_error_set(
1004
0
     error,
1005
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1006
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1007
0
     "%s: invalid file.",
1008
0
     function );
1009
1010
0
    return( -1 );
1011
0
  }
1012
1.92k
  if( internal_file->io_handle == NULL )
1013
0
  {
1014
0
    libcerror_error_set(
1015
0
     error,
1016
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1017
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1018
0
     "%s: invalid file - missing IO handle.",
1019
0
     function );
1020
1021
0
    return( -1 );
1022
0
  }
1023
1.92k
  if( internal_file->compressed_blocks_list != NULL )
1024
0
  {
1025
0
    libcerror_error_set(
1026
0
     error,
1027
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1028
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1029
0
     "%s: invalid file - compressed blocks list value already set.",
1030
0
     function );
1031
1032
0
    return( -1 );
1033
0
  }
1034
1.92k
  if( internal_file->compressed_blocks_cache != NULL )
1035
0
  {
1036
0
    libcerror_error_set(
1037
0
     error,
1038
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1040
0
     "%s: invalid file - compressed blocks cache value already set.",
1041
0
     function );
1042
1043
0
    return( -1 );
1044
0
  }
1045
1.92k
  if( internal_file->file_header != NULL )
1046
0
  {
1047
0
    libcerror_error_set(
1048
0
     error,
1049
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1050
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1051
0
     "%s: invalid file - file header value already set.",
1052
0
     function );
1053
1054
0
    return( -1 );
1055
0
  }
1056
1.92k
  if( internal_file->file_information != NULL )
1057
0
  {
1058
0
    libcerror_error_set(
1059
0
     error,
1060
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1061
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1062
0
     "%s: invalid file - file information value already set.",
1063
0
     function );
1064
1065
0
    return( -1 );
1066
0
  }
1067
1.92k
  if( internal_file->io_handle->abort != 0 )
1068
0
  {
1069
0
    internal_file->io_handle->abort = 0;
1070
0
  }
1071
#if defined( HAVE_DEBUG_OUTPUT )
1072
  if( libcnotify_verbose != 0 )
1073
  {
1074
    libcnotify_printf(
1075
     "Reading file header:\n" );
1076
  }
1077
#endif
1078
1.92k
  if( libscca_io_handle_read_compressed_file_header(
1079
1.92k
       internal_file->io_handle,
1080
1.92k
       file_io_handle,
1081
1.92k
       error ) != 1 )
1082
40
  {
1083
40
    libcerror_error_set(
1084
40
     error,
1085
40
     LIBCERROR_ERROR_DOMAIN_IO,
1086
40
     LIBCERROR_IO_ERROR_READ_FAILED,
1087
40
     "%s: unable to read file header.",
1088
40
     function );
1089
1090
40
    goto on_error;
1091
40
  }
1092
1.88k
  if( internal_file->io_handle->file_type != LIBSCCA_FILE_TYPE_UNCOMPRESSED )
1093
411
  {
1094
411
    if( libfdata_list_initialize(
1095
411
         &( internal_file->compressed_blocks_list ),
1096
411
         (intptr_t *) internal_file->io_handle,
1097
411
         NULL,
1098
411
         NULL,
1099
411
         (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libscca_compressed_block_read_element_data,
1100
411
         NULL,
1101
411
         LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1102
411
         error ) != 1 )
1103
0
    {
1104
0
      libcerror_error_set(
1105
0
       error,
1106
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1107
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1108
0
       "%s: unable to create compressed blocks list.",
1109
0
       function );
1110
1111
0
      goto on_error;
1112
0
    }
1113
411
    if( libfcache_cache_initialize(
1114
411
         &( internal_file->compressed_blocks_cache ),
1115
411
         LIBSCCA_MAXIMUM_CACHE_ENTRIES_COMPRESSED_BLOCKS,
1116
411
         error ) != 1 )
1117
0
    {
1118
0
      libcerror_error_set(
1119
0
       error,
1120
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1121
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1122
0
       "%s: unable to create compressed blocks cache.",
1123
0
       function );
1124
1125
0
      goto on_error;
1126
0
    }
1127
#if defined( HAVE_DEBUG_OUTPUT )
1128
    if( libcnotify_verbose != 0 )
1129
    {
1130
      libcnotify_printf(
1131
       "Reading compressed blocks:\n" );
1132
    }
1133
#endif
1134
411
    if( libscca_io_handle_read_compressed_blocks(
1135
411
         internal_file->io_handle,
1136
411
         file_io_handle,
1137
411
         internal_file->compressed_blocks_list,
1138
411
         internal_file->compressed_blocks_cache,
1139
411
         error ) != 1 )
1140
273
    {
1141
273
      libcerror_error_set(
1142
273
       error,
1143
273
       LIBCERROR_ERROR_DOMAIN_IO,
1144
273
       LIBCERROR_IO_ERROR_READ_FAILED,
1145
273
       "%s: unable to read compressed blocks.",
1146
273
       function );
1147
1148
273
      goto on_error;
1149
273
    }
1150
138
    if( libscca_compressed_blocks_stream_initialize(
1151
138
         &( internal_file->uncompressed_data_stream ),
1152
138
         internal_file->compressed_blocks_list,
1153
138
         internal_file->compressed_blocks_cache,
1154
138
         error ) != 1 )
1155
0
    {
1156
0
      libcerror_error_set(
1157
0
       error,
1158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1160
0
       "%s: unable to create compressed blocks stream.",
1161
0
       function );
1162
1163
0
      goto on_error;
1164
0
    }
1165
138
  }
1166
1.47k
  else
1167
1.47k
  {
1168
1.47k
    if( libfdata_stream_initialize(
1169
1.47k
         &( internal_file->uncompressed_data_stream ),
1170
1.47k
         NULL,
1171
1.47k
         NULL,
1172
1.47k
         NULL,
1173
1.47k
         NULL,
1174
1.47k
         (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libscca_io_handle_read_segment_data,
1175
1.47k
         NULL,
1176
1.47k
         (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libscca_io_handle_seek_segment_offset,
1177
1.47k
         0,
1178
1.47k
         error ) != 1 )
1179
0
    {
1180
0
      libcerror_error_set(
1181
0
       error,
1182
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1183
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1184
0
       "%s: unable to create uncompressed data stream.",
1185
0
       function );
1186
1187
0
      goto on_error;
1188
0
    }
1189
1.47k
    if( libfdata_stream_append_segment(
1190
1.47k
         internal_file->uncompressed_data_stream,
1191
1.47k
         &segment_index,
1192
1.47k
         0,
1193
1.47k
         0,
1194
1.47k
         (size64_t) internal_file->io_handle->uncompressed_data_size,
1195
1.47k
         0,
1196
1.47k
         error ) != 1 )
1197
0
    {
1198
0
      libcerror_error_set(
1199
0
       error,
1200
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1201
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1202
0
       "%s: unable to append uncompressed data stream segment: 0.",
1203
0
       function );
1204
1205
0
      goto on_error;
1206
0
    }
1207
1.47k
  }
1208
1.60k
  if( libfdata_stream_get_size(
1209
1.60k
       internal_file->uncompressed_data_stream,
1210
1.60k
       &file_size,
1211
1.60k
       error ) != 1 )
1212
0
  {
1213
0
    libcerror_error_set(
1214
0
     error,
1215
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1216
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1217
0
     "%s: unable to retrieve uncompressed data stream size.",
1218
0
     function );
1219
1220
0
    goto on_error;
1221
0
  }
1222
1.60k
  if( libscca_file_header_initialize(
1223
1.60k
       &( internal_file->file_header ),
1224
1.60k
       error ) != 1 )
1225
0
  {
1226
0
    libcerror_error_set(
1227
0
     error,
1228
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1229
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1230
0
     "%s: unable to create file header.",
1231
0
     function );
1232
1233
0
    goto on_error;
1234
0
  }
1235
1.60k
  if( libscca_file_header_read_data_stream(
1236
1.60k
       internal_file->file_header,
1237
1.60k
       internal_file->uncompressed_data_stream,
1238
1.60k
       file_io_handle,
1239
1.60k
       error ) != 1 )
1240
155
  {
1241
155
    libcerror_error_set(
1242
155
     error,
1243
155
     LIBCERROR_ERROR_DOMAIN_IO,
1244
155
     LIBCERROR_IO_ERROR_READ_FAILED,
1245
155
     "%s: unable to read file header.",
1246
155
     function );
1247
1248
155
    goto on_error;
1249
155
  }
1250
1.45k
  internal_file->io_handle->format_version = internal_file->file_header->format_version;
1251
1252
1.45k
  if( internal_file->io_handle->uncompressed_data_size != internal_file->file_header->file_size )
1253
1.45k
  {
1254
/* TODO flag mismatch and file as corrupted? */
1255
1.45k
  }
1256
#if defined( HAVE_DEBUG_OUTPUT )
1257
  if( libcnotify_verbose != 0 )
1258
  {
1259
    libcnotify_printf(
1260
     "Reading file information:\n" );
1261
  }
1262
#endif
1263
1.45k
  if( libscca_file_information_initialize(
1264
1.45k
       &( internal_file->file_information ),
1265
1.45k
       error ) != 1 )
1266
0
  {
1267
0
    libcerror_error_set(
1268
0
     error,
1269
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1270
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1271
0
     "%s: unable to create file information.",
1272
0
     function );
1273
1274
0
    goto on_error;
1275
0
  }
1276
1.45k
  if( libscca_file_information_read_stream(
1277
1.45k
       internal_file->file_information,
1278
1.45k
       internal_file->uncompressed_data_stream,
1279
1.45k
       file_io_handle,
1280
1.45k
       internal_file->io_handle,
1281
1.45k
       error ) != 1 )
1282
132
  {
1283
132
    libcerror_error_set(
1284
132
     error,
1285
132
     LIBCERROR_ERROR_DOMAIN_IO,
1286
132
     LIBCERROR_IO_ERROR_READ_FAILED,
1287
132
     "%s: unable to read file information from stream.",
1288
132
     function );
1289
1290
132
    goto on_error;
1291
132
  }
1292
1.32k
  if( libfdata_stream_get_offset(
1293
1.32k
       internal_file->uncompressed_data_stream,
1294
1.32k
       &file_offset,
1295
1.32k
       error ) != 1 )
1296
0
  {
1297
0
    libcerror_error_set(
1298
0
     error,
1299
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1300
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1301
0
     "%s: unable to retrieve uncompressed data stream current offset.",
1302
0
     function );
1303
1304
0
    goto on_error;
1305
0
  }
1306
1.32k
  if( internal_file->file_information->metrics_array_offset != 0 )
1307
264
  {
1308
264
    next_offset = internal_file->file_information->trace_chain_array_offset;
1309
1310
264
    if( next_offset == 0 )
1311
95
    {
1312
95
      next_offset = internal_file->file_information->filename_strings_offset;
1313
95
    }
1314
264
    if( next_offset == 0 )
1315
31
    {
1316
31
      next_offset = internal_file->file_information->volumes_information_offset;
1317
31
    }
1318
264
    if( next_offset == 0 )
1319
3
    {
1320
3
      next_offset = file_size;
1321
3
    }
1322
    /* Allow for a margin of 8 + 4 bytes for version 30 variant 2
1323
     */
1324
264
    if( ( internal_file->file_information->metrics_array_offset < ( file_offset - 12 ) )
1325
264
     || ( internal_file->file_information->metrics_array_offset >= next_offset ) )
1326
23
    {
1327
23
      libcerror_error_set(
1328
23
       error,
1329
23
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1330
23
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1331
23
       "%s: invalid metrics array offset value out of bounds: %jd > %jd > %jd.",
1332
23
       function, file_offset, internal_file->file_information->metrics_array_offset, next_offset );
1333
1334
23
      goto on_error;
1335
23
    }
1336
241
    if( libscca_io_handle_read_file_metrics_array(
1337
241
         internal_file->io_handle,
1338
241
         internal_file->uncompressed_data_stream,
1339
241
         file_io_handle,
1340
241
         internal_file->file_information->metrics_array_offset,
1341
241
         internal_file->file_information->number_of_file_metrics_entries,
1342
241
         internal_file->filename_strings,
1343
241
         internal_file->file_metrics_array,
1344
241
         error ) != 1 )
1345
145
    {
1346
145
      libcerror_error_set(
1347
145
       error,
1348
145
       LIBCERROR_ERROR_DOMAIN_IO,
1349
145
       LIBCERROR_IO_ERROR_READ_FAILED,
1350
145
       "%s: unable to read file metrics array.",
1351
145
       function );
1352
1353
145
      goto on_error;
1354
145
    }
1355
96
    if( libfdata_stream_get_offset(
1356
96
         internal_file->uncompressed_data_stream,
1357
96
         &file_offset,
1358
96
         error ) != 1 )
1359
0
    {
1360
0
      libcerror_error_set(
1361
0
       error,
1362
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1363
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1364
0
       "%s: unable to retrieve uncompressed data stream current offset.",
1365
0
       function );
1366
1367
0
      goto on_error;
1368
0
    }
1369
96
  }
1370
1.15k
  if( internal_file->file_information->trace_chain_array_offset != 0 )
1371
168
  {
1372
168
    next_offset = internal_file->file_information->filename_strings_offset;
1373
1374
168
    if( next_offset == 0 )
1375
44
    {
1376
44
      next_offset = internal_file->file_information->volumes_information_offset;
1377
44
    }
1378
168
    if( next_offset == 0 )
1379
5
    {
1380
5
      next_offset = file_size;
1381
5
    }
1382
168
    if( ( internal_file->file_information->trace_chain_array_offset < file_offset )
1383
168
     || ( internal_file->file_information->trace_chain_array_offset >= next_offset ) )
1384
34
    {
1385
34
      libcerror_error_set(
1386
34
       error,
1387
34
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1388
34
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1389
34
       "%s: invalid trace chain array offset value out of bounds.",
1390
34
       function );
1391
1392
34
      goto on_error;
1393
34
    }
1394
#if defined( HAVE_DEBUG_OUTPUT )
1395
    if( libcnotify_verbose != 0 )
1396
    {
1397
      if( libscca_io_handle_read_trace_chain_array(
1398
           internal_file->io_handle,
1399
           internal_file->uncompressed_data_stream,
1400
           file_io_handle,
1401
           internal_file->file_information->trace_chain_array_offset,
1402
           internal_file->file_information->number_of_trace_chain_array_entries,
1403
           error ) != 1 )
1404
      {
1405
        libcerror_error_set(
1406
         error,
1407
         LIBCERROR_ERROR_DOMAIN_IO,
1408
         LIBCERROR_IO_ERROR_READ_FAILED,
1409
         "%s: unable to read trace chain array.",
1410
         function );
1411
1412
        goto on_error;
1413
      }
1414
      if( libfdata_stream_get_offset(
1415
           internal_file->uncompressed_data_stream,
1416
           &file_offset,
1417
           error ) != 1 )
1418
      {
1419
        libcerror_error_set(
1420
         error,
1421
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1422
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1423
         "%s: unable to retrieve uncompressed data stream current offset.",
1424
         function );
1425
1426
        goto on_error;
1427
      }
1428
    }
1429
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1430
168
  }
1431
1.11k
  if( internal_file->file_information->filename_strings_offset != 0 )
1432
309
  {
1433
309
    next_offset = internal_file->file_information->volumes_information_offset;
1434
1435
309
    if( next_offset == 0 )
1436
45
    {
1437
45
      next_offset = file_size;
1438
45
    }
1439
309
    if( ( internal_file->file_information->filename_strings_offset < file_offset )
1440
309
     || ( internal_file->file_information->filename_strings_offset >= next_offset ) )
1441
52
    {
1442
52
      libcerror_error_set(
1443
52
       error,
1444
52
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1445
52
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1446
52
       "%s: invalid filename strings offset value out of bounds.",
1447
52
       function );
1448
1449
52
      goto on_error;
1450
52
    }
1451
257
    if( internal_file->file_information->filename_strings_size > ( next_offset - internal_file->file_information->filename_strings_offset ) )
1452
22
    {
1453
22
      libcerror_error_set(
1454
22
       error,
1455
22
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1456
22
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1457
22
       "%s: invalid filename strings size value out of bounds.",
1458
22
       function );
1459
1460
22
      goto on_error;
1461
22
    }
1462
235
    if( libscca_filename_strings_read_stream(
1463
235
         internal_file->filename_strings,
1464
235
         internal_file->uncompressed_data_stream,
1465
235
         file_io_handle,
1466
235
         internal_file->file_information->filename_strings_offset,
1467
235
         internal_file->file_information->filename_strings_size,
1468
235
         error ) != 1 )
1469
118
    {
1470
118
      libcerror_error_set(
1471
118
       error,
1472
118
       LIBCERROR_ERROR_DOMAIN_IO,
1473
118
       LIBCERROR_IO_ERROR_READ_FAILED,
1474
118
       "%s: unable to read filename strings from stream.",
1475
118
       function );
1476
1477
118
      goto on_error;
1478
118
    }
1479
117
    if( libfdata_stream_get_offset(
1480
117
         internal_file->uncompressed_data_stream,
1481
117
         &file_offset,
1482
117
         error ) != 1 )
1483
0
    {
1484
0
      libcerror_error_set(
1485
0
       error,
1486
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1487
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1488
0
       "%s: unable to retrieve uncompressed data stream current offset.",
1489
0
       function );
1490
1491
0
      goto on_error;
1492
0
    }
1493
117
  }
1494
927
  if( internal_file->file_information->volumes_information_offset != 0 )
1495
897
  {
1496
897
    if( ( internal_file->file_information->volumes_information_offset < file_offset )
1497
897
     || ( internal_file->file_information->volumes_information_offset > file_size ) )
1498
129
    {
1499
129
      libcerror_error_set(
1500
129
       error,
1501
129
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1502
129
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1503
129
       "%s: invalid volumes information offset value out of bounds.",
1504
129
       function );
1505
1506
129
      goto on_error;
1507
129
    }
1508
768
    if( internal_file->file_information->volumes_information_size > ( file_size - internal_file->file_information->volumes_information_offset ) )
1509
35
    {
1510
35
      libcerror_error_set(
1511
35
       error,
1512
35
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1513
35
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1514
35
       "%s: invalid volumes information size value out of bounds.",
1515
35
       function );
1516
1517
35
      goto on_error;
1518
35
    }
1519
733
    if( libscca_io_handle_read_volumes_information(
1520
733
         internal_file->io_handle,
1521
733
         internal_file->uncompressed_data_stream,
1522
733
         internal_file->file_io_handle,
1523
733
         internal_file->file_information->volumes_information_offset,
1524
733
         internal_file->file_information->volumes_information_size,
1525
733
         internal_file->file_information->number_of_volumes,
1526
733
         internal_file->volumes_array,
1527
733
         error ) != 1 )
1528
729
    {
1529
729
      libcerror_error_set(
1530
729
       error,
1531
729
       LIBCERROR_ERROR_DOMAIN_IO,
1532
729
       LIBCERROR_IO_ERROR_READ_FAILED,
1533
729
       "%s: unable to read volumes information.",
1534
729
       function );
1535
1536
729
      goto on_error;
1537
729
    }
1538
733
  }
1539
34
  return( 1 );
1540
1541
1.88k
on_error:
1542
1.88k
  if( internal_file->file_information != NULL )
1543
1.41k
  {
1544
1.41k
    libscca_file_information_free(
1545
1.41k
     &( internal_file->file_information ),
1546
1.41k
     NULL );
1547
1.41k
  }
1548
1.88k
  if( internal_file->file_header != NULL )
1549
1.57k
  {
1550
1.57k
    libscca_file_header_free(
1551
1.57k
     &( internal_file->file_header ),
1552
1.57k
     NULL );
1553
1.57k
  }
1554
1.88k
  libcdata_array_empty(
1555
1.88k
   internal_file->file_metrics_array,
1556
1.88k
   (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_file_metrics_free,
1557
1.88k
   NULL );
1558
1559
1.88k
  libscca_filename_strings_clear(
1560
1.88k
   internal_file->filename_strings,
1561
1.88k
   NULL );
1562
1563
1.88k
  libcdata_array_empty(
1564
1.88k
   internal_file->volumes_array,
1565
1.88k
   (int (*)(intptr_t **, libcerror_error_t **)) &libscca_internal_volume_information_free,
1566
1.88k
   NULL );
1567
1568
1.88k
  return( -1 );
1569
927
}
1570
1571
/* Retrieves the format version
1572
 * Returns 1 if successful or -1 on error
1573
 */
1574
int libscca_file_get_format_version(
1575
     libscca_file_t *file,
1576
     uint32_t *format_version,
1577
     libcerror_error_t **error )
1578
0
{
1579
0
  libscca_internal_file_t *internal_file = NULL;
1580
0
  static char *function                  = "libscca_file_get_format_version";
1581
1582
0
  if( file == NULL )
1583
0
  {
1584
0
    libcerror_error_set(
1585
0
     error,
1586
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1587
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1588
0
     "%s: invalid file.",
1589
0
     function );
1590
1591
0
    return( -1 );
1592
0
  }
1593
0
  internal_file = (libscca_internal_file_t *) file;
1594
1595
0
  if( internal_file->io_handle == NULL )
1596
0
  {
1597
0
    libcerror_error_set(
1598
0
     error,
1599
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1600
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1601
0
     "%s: invalid internal file - missing IO handle.",
1602
0
     function );
1603
1604
0
    return( -1 );
1605
0
  }
1606
0
  if( format_version == NULL )
1607
0
  {
1608
0
    libcerror_error_set(
1609
0
     error,
1610
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1611
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1612
0
     "%s: invalid format version.",
1613
0
     function );
1614
1615
0
    return( -1 );
1616
0
  }
1617
0
  *format_version = internal_file->io_handle->format_version;
1618
1619
0
  return( 1 );
1620
0
}
1621
1622
/* Retrieves the size of a specific UTF-8 encoded executable filename
1623
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1624
 * The returned size includes the end of string character
1625
 * Returns 1 if successful or -1 on error
1626
 */
1627
int libscca_file_get_utf8_executable_filename_size(
1628
     libscca_file_t *file,
1629
     size_t *utf8_string_size,
1630
     libcerror_error_t **error )
1631
0
{
1632
0
  libscca_internal_file_t *internal_file = NULL;
1633
0
  static char *function                  = "libscca_file_get_utf8_executable_filename_size";
1634
1635
0
  if( file == NULL )
1636
0
  {
1637
0
    libcerror_error_set(
1638
0
     error,
1639
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1640
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1641
0
     "%s: invalid file.",
1642
0
     function );
1643
1644
0
    return( -1 );
1645
0
  }
1646
0
  internal_file = (libscca_internal_file_t *) file;
1647
1648
0
  if( libscca_file_header_get_utf8_executable_filename_size(
1649
0
       internal_file->file_header,
1650
0
       utf8_string_size,
1651
0
       error ) != 1 )
1652
0
  {
1653
0
    libcerror_error_set(
1654
0
     error,
1655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1656
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1657
0
     "%s: unable to retrieve UTF-8 executable filename size.",
1658
0
     function );
1659
1660
0
    return( -1 );
1661
0
  }
1662
0
  return( 1 );
1663
0
}
1664
1665
/* Retrieves a specific UTF-8 encoded executable filename
1666
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1667
 * The size should include the end of string character
1668
 * Returns 1 if successful or -1 on error
1669
 */
1670
int libscca_file_get_utf8_executable_filename(
1671
     libscca_file_t *file,
1672
     uint8_t *utf8_string,
1673
     size_t utf8_string_size,
1674
     libcerror_error_t **error )
1675
0
{
1676
0
  libscca_internal_file_t *internal_file = NULL;
1677
0
  static char *function                  = "libscca_file_get_utf8_executable_filename";
1678
1679
0
  if( file == NULL )
1680
0
  {
1681
0
    libcerror_error_set(
1682
0
     error,
1683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1685
0
     "%s: invalid file.",
1686
0
     function );
1687
1688
0
    return( -1 );
1689
0
  }
1690
0
  internal_file = (libscca_internal_file_t *) file;
1691
1692
0
  if( libscca_file_header_get_utf8_executable_filename(
1693
0
       internal_file->file_header,
1694
0
       utf8_string,
1695
0
       utf8_string_size,
1696
0
       error ) != 1 )
1697
0
  {
1698
0
    libcerror_error_set(
1699
0
     error,
1700
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1701
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1702
0
     "%s: unable to retrieve UTF-8 executable filename.",
1703
0
     function );
1704
1705
0
    return( -1 );
1706
0
  }
1707
0
  return( 1 );
1708
0
}
1709
1710
/* Retrieves the size of a specific UTF-16 encoded executable filename
1711
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1712
 * The returned size includes the end of string character
1713
 * Returns 1 if successful or -1 on error
1714
 */
1715
int libscca_file_get_utf16_executable_filename_size(
1716
     libscca_file_t *file,
1717
     size_t *utf16_string_size,
1718
     libcerror_error_t **error )
1719
0
{
1720
0
  libscca_internal_file_t *internal_file = NULL;
1721
0
  static char *function                  = "libscca_file_get_utf16_executable_filename_size";
1722
1723
0
  if( file == NULL )
1724
0
  {
1725
0
    libcerror_error_set(
1726
0
     error,
1727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1728
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1729
0
     "%s: invalid file.",
1730
0
     function );
1731
1732
0
    return( -1 );
1733
0
  }
1734
0
  internal_file = (libscca_internal_file_t *) file;
1735
1736
0
  if( libscca_file_header_get_utf16_executable_filename_size(
1737
0
       internal_file->file_header,
1738
0
       utf16_string_size,
1739
0
       error ) != 1 )
1740
0
  {
1741
0
    libcerror_error_set(
1742
0
     error,
1743
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1744
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1745
0
     "%s: unable to retrieve UTF-16 executable filename size.",
1746
0
     function );
1747
1748
0
    return( -1 );
1749
0
  }
1750
0
  return( 1 );
1751
0
}
1752
1753
/* Retrieves a specific UTF-16 encoded executable filename
1754
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1755
 * The size should include the end of string character
1756
 * Returns 1 if successful or -1 on error
1757
 */
1758
int libscca_file_get_utf16_executable_filename(
1759
     libscca_file_t *file,
1760
     uint16_t *utf16_string,
1761
     size_t utf16_string_size,
1762
     libcerror_error_t **error )
1763
0
{
1764
0
  libscca_internal_file_t *internal_file = NULL;
1765
0
  static char *function                  = "libscca_file_get_utf16_executable_filename";
1766
1767
0
  if( file == NULL )
1768
0
  {
1769
0
    libcerror_error_set(
1770
0
     error,
1771
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1772
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1773
0
     "%s: invalid file.",
1774
0
     function );
1775
1776
0
    return( -1 );
1777
0
  }
1778
0
  internal_file = (libscca_internal_file_t *) file;
1779
1780
0
  if( libscca_file_header_get_utf16_executable_filename(
1781
0
       internal_file->file_header,
1782
0
       utf16_string,
1783
0
       utf16_string_size,
1784
0
       error ) != 1 )
1785
0
  {
1786
0
    libcerror_error_set(
1787
0
     error,
1788
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1789
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1790
0
     "%s: unable to retrieve UTF-16 executable filename.",
1791
0
     function );
1792
1793
0
    return( -1 );
1794
0
  }
1795
0
  return( 1 );
1796
0
}
1797
1798
/* Retrieves the prefetch hash
1799
 * Returns 1 if successful or -1 on error
1800
 */
1801
int libscca_file_get_prefetch_hash(
1802
     libscca_file_t *file,
1803
     uint32_t *prefetch_hash,
1804
     libcerror_error_t **error )
1805
0
{
1806
0
  libscca_internal_file_t *internal_file = NULL;
1807
0
  static char *function                  = "libscca_file_get_prefetch_hash";
1808
1809
0
  if( file == NULL )
1810
0
  {
1811
0
    libcerror_error_set(
1812
0
     error,
1813
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1814
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1815
0
     "%s: invalid file.",
1816
0
     function );
1817
1818
0
    return( -1 );
1819
0
  }
1820
0
  internal_file = (libscca_internal_file_t *) file;
1821
1822
0
  if( internal_file->file_header == NULL )
1823
0
  {
1824
0
    libcerror_error_set(
1825
0
     error,
1826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1827
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1828
0
     "%s: invalid internal file - missing file header.",
1829
0
     function );
1830
1831
0
    return( -1 );
1832
0
  }
1833
0
  if( prefetch_hash == NULL )
1834
0
  {
1835
0
    libcerror_error_set(
1836
0
     error,
1837
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1838
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1839
0
     "%s: invalid prefetch hash.",
1840
0
     function );
1841
1842
0
    return( -1 );
1843
0
  }
1844
0
  *prefetch_hash = internal_file->file_header->prefetch_hash;
1845
1846
0
  return( 1 );
1847
0
}
1848
1849
/* Retrieves a specific last run time
1850
 * The timestamp is a 64-bit FILETIME date and time value
1851
 * Files of format version 23 and earlier contain a single last run time
1852
 * Files of format version 26 and later contain up to 8 last run times
1853
 * A value if 0 means the last run time is not set
1854
 * Returns 1 if successful or -1 on error
1855
 */
1856
int libscca_file_get_last_run_time(
1857
     libscca_file_t *file,
1858
     int last_run_time_index,
1859
     uint64_t *filetime,
1860
     libcerror_error_t **error )
1861
0
{
1862
0
  libscca_internal_file_t *internal_file = NULL;
1863
0
  static char *function                  = "libscca_file_get_last_run_time";
1864
0
  int number_of_last_run_times           = 0;
1865
1866
0
  if( file == NULL )
1867
0
  {
1868
0
    libcerror_error_set(
1869
0
     error,
1870
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1871
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1872
0
     "%s: invalid file.",
1873
0
     function );
1874
1875
0
    return( -1 );
1876
0
  }
1877
0
  internal_file = (libscca_internal_file_t *) file;
1878
1879
0
  if( internal_file->io_handle == NULL )
1880
0
  {
1881
0
    libcerror_error_set(
1882
0
     error,
1883
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1884
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1885
0
     "%s: invalid internal file - missing IO handle.",
1886
0
     function );
1887
1888
0
    return( -1 );
1889
0
  }
1890
0
  if( internal_file->file_information == NULL )
1891
0
  {
1892
0
    libcerror_error_set(
1893
0
     error,
1894
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1895
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1896
0
     "%s: invalid internal file - missing file information.",
1897
0
     function );
1898
1899
0
    return( -1 );
1900
0
  }
1901
0
  if( internal_file->io_handle->format_version < 26 )
1902
0
  {
1903
0
    number_of_last_run_times = 1;
1904
0
  }
1905
0
  else
1906
0
  {
1907
0
    number_of_last_run_times = 8;
1908
0
  }
1909
0
  if( ( last_run_time_index < 0 )
1910
0
   || ( last_run_time_index >= number_of_last_run_times ) )
1911
0
  {
1912
0
    libcerror_error_set(
1913
0
     error,
1914
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1915
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1916
0
     "%s: invalid last run time index value out of bounds.",
1917
0
     function );
1918
1919
0
    return( -1 );
1920
0
  }
1921
0
  if( filetime == NULL )
1922
0
  {
1923
0
    libcerror_error_set(
1924
0
     error,
1925
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1926
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1927
0
     "%s: invalid filetime.",
1928
0
     function );
1929
1930
0
    return( -1 );
1931
0
  }
1932
0
  *filetime = internal_file->file_information->last_run_time[ last_run_time_index ];
1933
1934
0
  return( 1 );
1935
0
}
1936
1937
/* Retrieves the run count
1938
 * Returns 1 if successful or -1 on error
1939
 */
1940
int libscca_file_get_run_count(
1941
     libscca_file_t *file,
1942
     uint32_t *run_count,
1943
     libcerror_error_t **error )
1944
0
{
1945
0
  libscca_internal_file_t *internal_file = NULL;
1946
0
  static char *function                  = "libscca_file_get_run_count";
1947
1948
0
  if( file == NULL )
1949
0
  {
1950
0
    libcerror_error_set(
1951
0
     error,
1952
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1953
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1954
0
     "%s: invalid file.",
1955
0
     function );
1956
1957
0
    return( -1 );
1958
0
  }
1959
0
  internal_file = (libscca_internal_file_t *) file;
1960
1961
0
  if( internal_file->file_information == NULL )
1962
0
  {
1963
0
    libcerror_error_set(
1964
0
     error,
1965
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1966
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1967
0
     "%s: invalid internal file - missing file information.",
1968
0
     function );
1969
1970
0
    return( -1 );
1971
0
  }
1972
0
  if( run_count == NULL )
1973
0
  {
1974
0
    libcerror_error_set(
1975
0
     error,
1976
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1977
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1978
0
     "%s: invalid run count.",
1979
0
     function );
1980
1981
0
    return( -1 );
1982
0
  }
1983
0
  *run_count = internal_file->file_information->run_count;
1984
1985
0
  return( 1 );
1986
0
}
1987
1988
/* Retrieves the number of file metrics entries
1989
 * Returns 1 if successful or -1 on error
1990
 */
1991
int libscca_file_get_number_of_file_metrics_entries(
1992
     libscca_file_t *file,
1993
     int *number_of_entries,
1994
     libcerror_error_t **error )
1995
0
{
1996
0
  libscca_internal_file_t *internal_file = NULL;
1997
0
  static char *function                  = "libscca_file_get_number_of_file_metrics_entries";
1998
1999
0
  if( file == NULL )
2000
0
  {
2001
0
    libcerror_error_set(
2002
0
     error,
2003
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2004
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2005
0
     "%s: invalid file.",
2006
0
     function );
2007
2008
0
    return( -1 );
2009
0
  }
2010
0
  internal_file = (libscca_internal_file_t *) file;
2011
2012
0
  if( libcdata_array_get_number_of_entries(
2013
0
       internal_file->file_metrics_array,
2014
0
       number_of_entries,
2015
0
       error ) != 1 )
2016
0
  {
2017
0
    libcerror_error_set(
2018
0
     error,
2019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2020
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2021
0
     "%s: unable to retrieve number of file metrics entries.",
2022
0
     function );
2023
2024
0
    return( -1 );
2025
0
  }
2026
0
  return( 1 );
2027
0
}
2028
2029
/* Retrieves a specific file metrics entry
2030
 * Returns 1 if successful or -1 on error
2031
 */
2032
int libscca_file_get_file_metrics_entry(
2033
     libscca_file_t *file,
2034
     int entry_index,
2035
     libscca_file_metrics_t **file_metrics,
2036
     libcerror_error_t **error )
2037
0
{
2038
0
  libscca_internal_file_t *internal_file = NULL;
2039
0
  static char *function                  = "libscca_file_get_file_metrics_entry";
2040
2041
0
  if( file == NULL )
2042
0
  {
2043
0
    libcerror_error_set(
2044
0
     error,
2045
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2046
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2047
0
     "%s: invalid file.",
2048
0
     function );
2049
2050
0
    return( -1 );
2051
0
  }
2052
0
  internal_file = (libscca_internal_file_t *) file;
2053
2054
0
  if( libcdata_array_get_entry_by_index(
2055
0
       internal_file->file_metrics_array,
2056
0
       entry_index,
2057
0
       (intptr_t **) file_metrics,
2058
0
       error ) != 1 )
2059
0
  {
2060
0
    libcerror_error_set(
2061
0
     error,
2062
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2063
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2064
0
     "%s: unable to retrieve file metrics entry: %d.",
2065
0
     function,
2066
0
     entry_index );
2067
2068
0
    return( -1 );
2069
0
  }
2070
0
  return( 1 );
2071
0
}
2072
2073
/* Retrieves the number of filenames
2074
 * Returns 1 if successful or -1 on error
2075
 */
2076
int libscca_file_get_number_of_filenames(
2077
     libscca_file_t *file,
2078
     int *number_of_filenames,
2079
     libcerror_error_t **error )
2080
0
{
2081
0
  libscca_internal_file_t *internal_file = NULL;
2082
0
  static char *function                  = "libscca_file_get_number_of_filenames";
2083
2084
0
  if( file == NULL )
2085
0
  {
2086
0
    libcerror_error_set(
2087
0
     error,
2088
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2089
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2090
0
     "%s: invalid file.",
2091
0
     function );
2092
2093
0
    return( -1 );
2094
0
  }
2095
0
  internal_file = (libscca_internal_file_t *) file;
2096
2097
0
  if( libscca_filename_strings_get_number_of_filenames(
2098
0
       internal_file->filename_strings,
2099
0
       number_of_filenames,
2100
0
       error ) != 1 )
2101
0
  {
2102
0
    libcerror_error_set(
2103
0
     error,
2104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2105
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2106
0
     "%s: unable to retrieve number of filename strings.",
2107
0
     function );
2108
2109
0
    return( -1 );
2110
0
  }
2111
0
  return( 1 );
2112
0
}
2113
2114
/* Retrieves the size of a specific UTF-8 encoded filename
2115
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2116
 * The returned size includes the end of string character
2117
 * Returns 1 if successful or -1 on error
2118
 */
2119
int libscca_file_get_utf8_filename_size(
2120
     libscca_file_t *file,
2121
     int filename_index,
2122
     size_t *utf8_string_size,
2123
     libcerror_error_t **error )
2124
0
{
2125
0
  libscca_internal_file_t *internal_file = NULL;
2126
0
  static char *function                  = "libscca_file_get_utf8_filename_size";
2127
2128
0
  if( file == NULL )
2129
0
  {
2130
0
    libcerror_error_set(
2131
0
     error,
2132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2134
0
     "%s: invalid file.",
2135
0
     function );
2136
2137
0
    return( -1 );
2138
0
  }
2139
0
  internal_file = (libscca_internal_file_t *) file;
2140
2141
0
  if( libscca_filename_strings_get_utf8_filename_size(
2142
0
       internal_file->filename_strings,
2143
0
       filename_index,
2144
0
       utf8_string_size,
2145
0
       error ) != 1 )
2146
0
  {
2147
0
    libcerror_error_set(
2148
0
     error,
2149
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2150
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2151
0
     "%s: unable to retrieve filename: %d UTF-8 string size.",
2152
0
     function,
2153
0
     filename_index );
2154
2155
0
    return( -1 );
2156
0
  }
2157
0
  return( 1 );
2158
0
}
2159
2160
/* Retrieves a specific UTF-8 encoded filename
2161
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2162
 * The size should include the end of string character
2163
 * Returns 1 if successful or -1 on error
2164
 */
2165
int libscca_file_get_utf8_filename(
2166
     libscca_file_t *file,
2167
     int filename_index,
2168
     uint8_t *utf8_string,
2169
     size_t utf8_string_size,
2170
     libcerror_error_t **error )
2171
0
{
2172
0
  libscca_internal_file_t *internal_file = NULL;
2173
0
  static char *function                  = "libscca_file_get_utf8_filename";
2174
2175
0
  if( file == NULL )
2176
0
  {
2177
0
    libcerror_error_set(
2178
0
     error,
2179
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2180
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2181
0
     "%s: invalid file.",
2182
0
     function );
2183
2184
0
    return( -1 );
2185
0
  }
2186
0
  internal_file = (libscca_internal_file_t *) file;
2187
2188
0
  if( libscca_filename_strings_get_utf8_filename(
2189
0
       internal_file->filename_strings,
2190
0
       filename_index,
2191
0
       utf8_string,
2192
0
       utf8_string_size,
2193
0
       error ) != 1 )
2194
0
  {
2195
0
    libcerror_error_set(
2196
0
     error,
2197
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2198
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2199
0
     "%s: unable to copy filename: %d to UTF-8 string.",
2200
0
     function,
2201
0
     filename_index );
2202
2203
0
    return( -1 );
2204
0
  }
2205
0
  return( 1 );
2206
0
}
2207
2208
/* Retrieves the size of a specific UTF-16 encoded filename
2209
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2210
 * The returned size includes the end of string character
2211
 * Returns 1 if successful or -1 on error
2212
 */
2213
int libscca_file_get_utf16_filename_size(
2214
     libscca_file_t *file,
2215
     int filename_index,
2216
     size_t *utf16_string_size,
2217
     libcerror_error_t **error )
2218
0
{
2219
0
  libscca_internal_file_t *internal_file = NULL;
2220
0
  static char *function                  = "libscca_file_get_utf16_filename_size";
2221
2222
0
  if( file == NULL )
2223
0
  {
2224
0
    libcerror_error_set(
2225
0
     error,
2226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2227
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2228
0
     "%s: invalid file.",
2229
0
     function );
2230
2231
0
    return( -1 );
2232
0
  }
2233
0
  internal_file = (libscca_internal_file_t *) file;
2234
2235
0
  if( libscca_filename_strings_get_utf16_filename_size(
2236
0
       internal_file->filename_strings,
2237
0
       filename_index,
2238
0
       utf16_string_size,
2239
0
       error ) != 1 )
2240
0
  {
2241
0
    libcerror_error_set(
2242
0
     error,
2243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2244
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2245
0
     "%s: unable to retrieve filename: %d UTF-16 string size.",
2246
0
     function,
2247
0
     filename_index );
2248
2249
0
    return( -1 );
2250
0
  }
2251
0
  return( 1 );
2252
0
}
2253
2254
/* Retrieves a specific UTF-16 encoded filename
2255
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2256
 * The size should include the end of string character
2257
 * Returns 1 if successful or -1 on error
2258
 */
2259
int libscca_file_get_utf16_filename(
2260
     libscca_file_t *file,
2261
     int filename_index,
2262
     uint16_t *utf16_string,
2263
     size_t utf16_string_size,
2264
     libcerror_error_t **error )
2265
0
{
2266
0
  libscca_internal_file_t *internal_file = NULL;
2267
0
  static char *function                  = "libscca_file_get_utf16_filename";
2268
2269
0
  if( file == NULL )
2270
0
  {
2271
0
    libcerror_error_set(
2272
0
     error,
2273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2275
0
     "%s: invalid file.",
2276
0
     function );
2277
2278
0
    return( -1 );
2279
0
  }
2280
0
  internal_file = (libscca_internal_file_t *) file;
2281
2282
0
  if( libscca_filename_strings_get_utf16_filename(
2283
0
       internal_file->filename_strings,
2284
0
       filename_index,
2285
0
       utf16_string,
2286
0
       utf16_string_size,
2287
0
       error ) != 1 )
2288
0
  {
2289
0
    libcerror_error_set(
2290
0
     error,
2291
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2292
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2293
0
     "%s: unable to copy filename: %d to UTF-16 string.",
2294
0
     function,
2295
0
     filename_index );
2296
2297
0
    return( -1 );
2298
0
  }
2299
0
  return( 1 );
2300
0
}
2301
2302
/* Retrieves the number of volumes
2303
 * Returns 1 if successful or -1 on error
2304
 */
2305
int libscca_file_get_number_of_volumes(
2306
     libscca_file_t *file,
2307
     int *number_of_volumes,
2308
     libcerror_error_t **error )
2309
0
{
2310
0
  libscca_internal_file_t *internal_file = NULL;
2311
0
  static char *function                  = "libscca_file_get_number_of_volumes";
2312
2313
0
  if( file == NULL )
2314
0
  {
2315
0
    libcerror_error_set(
2316
0
     error,
2317
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2318
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2319
0
     "%s: invalid file.",
2320
0
     function );
2321
2322
0
    return( -1 );
2323
0
  }
2324
0
  internal_file = (libscca_internal_file_t *) file;
2325
2326
0
  if( libcdata_array_get_number_of_entries(
2327
0
       internal_file->volumes_array,
2328
0
       number_of_volumes,
2329
0
       error ) != 1 )
2330
0
  {
2331
0
    libcerror_error_set(
2332
0
     error,
2333
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2334
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2335
0
     "%s: unable to retrieve number of volumes.",
2336
0
     function );
2337
2338
0
    return( -1 );
2339
0
  }
2340
0
  return( 1 );
2341
0
}
2342
2343
/* Retrieves a specific volume information
2344
 * Returns 1 if successful or -1 on error
2345
 */
2346
int libscca_file_get_volume_information(
2347
     libscca_file_t *file,
2348
     int volume_index,
2349
     libscca_volume_information_t **volume_information,
2350
     libcerror_error_t **error )
2351
0
{
2352
0
  libscca_internal_file_t *internal_file = NULL;
2353
0
  static char *function                  = "libscca_file_get_volume_information";
2354
2355
0
  if( file == NULL )
2356
0
  {
2357
0
    libcerror_error_set(
2358
0
     error,
2359
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2360
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2361
0
     "%s: invalid file.",
2362
0
     function );
2363
2364
0
    return( -1 );
2365
0
  }
2366
0
  internal_file = (libscca_internal_file_t *) file;
2367
2368
0
  if( libcdata_array_get_entry_by_index(
2369
0
       internal_file->volumes_array,
2370
0
       volume_index,
2371
0
       (intptr_t **) volume_information,
2372
0
       error ) != 1 )
2373
0
  {
2374
0
    libcerror_error_set(
2375
0
     error,
2376
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2377
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2378
0
     "%s: unable to retrieve volume: %d information.",
2379
0
     function,
2380
0
     volume_index );
2381
2382
0
    return( -1 );
2383
0
  }
2384
0
  return( 1 );
2385
0
}
2386