Coverage Report

Created: 2025-06-13 07:21

/src/libagdb/libagdb/libagdb_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File functions
3
 *
4
 * Copyright (C) 2014-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 "libagdb_compressed_block.h"
29
#include "libagdb_compressed_blocks_stream.h"
30
#include "libagdb_compressed_file_header.h"
31
#include "libagdb_debug.h"
32
#include "libagdb_definitions.h"
33
#include "libagdb_io_handle.h"
34
#include "libagdb_file.h"
35
#include "libagdb_libbfio.h"
36
#include "libagdb_libcdata.h"
37
#include "libagdb_libcerror.h"
38
#include "libagdb_libcnotify.h"
39
#include "libagdb_libfcache.h"
40
#include "libagdb_libfdata.h"
41
#include "libagdb_source_information.h"
42
#include "libagdb_volume_information.h"
43
44
/* Creates a file
45
 * Make sure the value file is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libagdb_file_initialize(
49
     libagdb_file_t **file,
50
     libcerror_error_t **error )
51
2.32k
{
52
2.32k
  libagdb_internal_file_t *internal_file = NULL;
53
2.32k
  static char *function                  = "libagdb_file_initialize";
54
55
2.32k
  if( file == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid file.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
2.32k
  if( *file != NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72
0
     "%s: invalid file value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
2.32k
  internal_file = memory_allocate_structure(
78
2.32k
                   libagdb_internal_file_t );
79
80
2.32k
  if( internal_file == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create file.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
2.32k
  if( memory_set(
92
2.32k
       internal_file,
93
2.32k
       0,
94
2.32k
       sizeof( libagdb_internal_file_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear file.",
101
0
     function );
102
103
0
    memory_free(
104
0
     internal_file );
105
106
0
    return( -1 );
107
0
  }
108
2.32k
  if( libcdata_array_initialize(
109
2.32k
       &( internal_file->volumes_array ),
110
2.32k
       0,
111
2.32k
       error ) != 1 )
112
0
  {
113
0
    libcerror_error_set(
114
0
     error,
115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
117
0
     "%s: unable to create volumes array.",
118
0
     function );
119
120
0
    goto on_error;
121
0
  }
122
2.32k
  if( libcdata_array_initialize(
123
2.32k
       &( internal_file->sources_array ),
124
2.32k
       0,
125
2.32k
       error ) != 1 )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
130
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
131
0
     "%s: unable to create sources array.",
132
0
     function );
133
134
0
    goto on_error;
135
0
  }
136
2.32k
  if( libagdb_io_handle_initialize(
137
2.32k
       &( internal_file->io_handle ),
138
2.32k
       error ) != 1 )
139
0
  {
140
0
    libcerror_error_set(
141
0
     error,
142
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
143
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
144
0
     "%s: unable to create IO handle.",
145
0
     function );
146
147
0
    goto on_error;
148
0
  }
149
2.32k
  *file = (libagdb_file_t *) internal_file;
150
151
2.32k
  return( 1 );
152
153
0
on_error:
154
0
  if( internal_file != NULL )
155
0
  {
156
0
    if( internal_file->sources_array != NULL )
157
0
    {
158
0
      libcdata_array_free(
159
0
       &( internal_file->sources_array ),
160
0
       NULL,
161
0
       NULL );
162
0
    }
163
0
    if( internal_file->volumes_array != NULL )
164
0
    {
165
0
      libcdata_array_free(
166
0
       &( internal_file->volumes_array ),
167
0
       NULL,
168
0
       NULL );
169
0
    }
170
0
    memory_free(
171
0
     internal_file );
172
0
  }
173
0
  return( -1 );
174
2.32k
}
175
176
/* Frees a file
177
 * Returns 1 if successful or -1 on error
178
 */
179
int libagdb_file_free(
180
     libagdb_file_t **file,
181
     libcerror_error_t **error )
182
2.32k
{
183
2.32k
  libagdb_internal_file_t *internal_file = NULL;
184
2.32k
  static char *function                  = "libagdb_file_free";
185
2.32k
  int result                             = 1;
186
187
2.32k
  if( file == NULL )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
193
0
     "%s: invalid file.",
194
0
     function );
195
196
0
    return( -1 );
197
0
  }
198
2.32k
  if( *file != NULL )
199
2.32k
  {
200
2.32k
    internal_file = (libagdb_internal_file_t *) *file;
201
202
2.32k
    if( internal_file->file_io_handle != NULL )
203
0
    {
204
0
      if( libagdb_file_close(
205
0
           *file,
206
0
           error ) != 0 )
207
0
      {
208
0
        libcerror_error_set(
209
0
         error,
210
0
         LIBCERROR_ERROR_DOMAIN_IO,
211
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
212
0
         "%s: unable to close file.",
213
0
         function );
214
215
0
        result = -1;
216
0
      }
217
0
    }
218
2.32k
    *file = NULL;
219
220
2.32k
    if( libcdata_array_free(
221
2.32k
         &( internal_file->volumes_array ),
222
2.32k
         (int (*)(intptr_t **, libcerror_error_t **)) &libagdb_internal_volume_information_free,
223
2.32k
         error ) != 1 )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
229
0
       "%s: unable to free volumes array.",
230
0
       function );
231
232
0
      result = -1;
233
0
    }
234
2.32k
    if( libcdata_array_free(
235
2.32k
         &( internal_file->sources_array ),
236
2.32k
         (int (*)(intptr_t **, libcerror_error_t **)) &libagdb_internal_source_information_free,
237
2.32k
         error ) != 1 )
238
0
    {
239
0
      libcerror_error_set(
240
0
       error,
241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
242
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
243
0
       "%s: unable to free sources array.",
244
0
       function );
245
246
0
      result = -1;
247
0
    }
248
2.32k
    if( libagdb_io_handle_free(
249
2.32k
         &( internal_file->io_handle ),
250
2.32k
         error ) != 1 )
251
0
    {
252
0
      libcerror_error_set(
253
0
       error,
254
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
255
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
256
0
       "%s: unable to free IO handle.",
257
0
       function );
258
259
0
      result = -1;
260
0
    }
261
2.32k
    memory_free(
262
2.32k
     internal_file );
263
2.32k
  }
264
2.32k
  return( result );
265
2.32k
}
266
267
/* Signals the file to abort its current activity
268
 * Returns 1 if successful or -1 on error
269
 */
270
int libagdb_file_signal_abort(
271
     libagdb_file_t *file,
272
     libcerror_error_t **error )
273
0
{
274
0
  libagdb_internal_file_t *internal_file = NULL;
275
0
  static char *function                  = "libagdb_file_signal_abort";
276
277
0
  if( file == NULL )
278
0
  {
279
0
    libcerror_error_set(
280
0
     error,
281
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
282
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
283
0
     "%s: invalid file.",
284
0
     function );
285
286
0
    return( -1 );
287
0
  }
288
0
  internal_file = (libagdb_internal_file_t *) file;
289
290
0
  if( internal_file->io_handle == NULL )
291
0
  {
292
0
    libcerror_error_set(
293
0
     error,
294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
296
0
     "%s: invalid file - missing IO handle.",
297
0
     function );
298
299
0
    return( -1 );
300
0
  }
301
0
  internal_file->io_handle->abort = 1;
302
303
0
  return( 1 );
304
0
}
305
306
/* Opens a file
307
 * Returns 1 if successful or -1 on error
308
 */
309
int libagdb_file_open(
310
     libagdb_file_t *file,
311
     const char *filename,
312
     int access_flags,
313
     libcerror_error_t **error )
314
0
{
315
0
  libbfio_handle_t *file_io_handle       = NULL;
316
0
  libagdb_internal_file_t *internal_file = NULL;
317
0
  static char *function                  = "libagdb_file_open";
318
0
  size_t filename_length                 = 0;
319
320
0
  if( file == NULL )
321
0
  {
322
0
    libcerror_error_set(
323
0
     error,
324
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
325
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
326
0
     "%s: invalid file.",
327
0
     function );
328
329
0
    return( -1 );
330
0
  }
331
0
  internal_file = (libagdb_internal_file_t *) file;
332
333
0
  if( filename == NULL )
334
0
  {
335
0
    libcerror_error_set(
336
0
     error,
337
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
338
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
339
0
     "%s: invalid filename.",
340
0
     function );
341
342
0
    return( -1 );
343
0
  }
344
0
  if( ( ( access_flags & LIBAGDB_ACCESS_FLAG_READ ) == 0 )
345
0
   && ( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) == 0 ) )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
351
0
     "%s: unsupported access flags.",
352
0
     function );
353
354
0
    return( -1 );
355
0
  }
356
0
  if( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) != 0 )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
362
0
     "%s: write access currently not supported.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
0
  if( libbfio_file_initialize(
368
0
       &file_io_handle,
369
0
       error ) != 1 )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
374
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
375
0
     "%s: unable to create file IO handle.",
376
0
     function );
377
378
0
    goto on_error;
379
0
  }
380
#if defined( HAVE_DEBUG_OUTPUT )
381
  if( libbfio_handle_set_track_offsets_read(
382
       file_io_handle,
383
       1,
384
       error ) != 1 )
385
  {
386
                libcerror_error_set(
387
                 error,
388
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
389
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
390
                 "%s: unable to set track offsets read in file IO handle.",
391
                 function );
392
393
    goto on_error;
394
  }
395
#endif
396
0
  filename_length = narrow_string_length(
397
0
                     filename );
398
399
0
  if( libbfio_file_set_name(
400
0
       file_io_handle,
401
0
       filename,
402
0
       filename_length + 1,
403
0
       error ) != 1 )
404
0
  {
405
0
                libcerror_error_set(
406
0
                 error,
407
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
408
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
409
0
                 "%s: unable to set filename in file IO handle.",
410
0
                 function );
411
412
0
    goto on_error;
413
0
  }
414
0
  if( libagdb_file_open_file_io_handle(
415
0
       file,
416
0
       file_io_handle,
417
0
       access_flags,
418
0
       error ) != 1 )
419
0
  {
420
0
    libcerror_error_set(
421
0
     error,
422
0
     LIBCERROR_ERROR_DOMAIN_IO,
423
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
424
0
     "%s: unable to open file: %s.",
425
0
     function,
426
0
     filename );
427
428
0
    goto on_error;
429
0
  }
430
0
  internal_file->file_io_handle_created_in_library = 1;
431
432
0
  return( 1 );
433
434
0
on_error:
435
0
  if( file_io_handle != NULL )
436
0
  {
437
0
    libbfio_handle_free(
438
0
     &file_io_handle,
439
0
     NULL );
440
0
  }
441
0
  return( -1 );
442
0
}
443
444
#if defined( HAVE_WIDE_CHARACTER_TYPE )
445
446
/* Opens a file
447
 * Returns 1 if successful or -1 on error
448
 */
449
int libagdb_file_open_wide(
450
     libagdb_file_t *file,
451
     const wchar_t *filename,
452
     int access_flags,
453
     libcerror_error_t **error )
454
{
455
  libbfio_handle_t *file_io_handle       = NULL;
456
  libagdb_internal_file_t *internal_file = NULL;
457
  static char *function                  = "libagdb_file_open_wide";
458
  size_t filename_length                 = 0;
459
460
  if( file == NULL )
461
  {
462
    libcerror_error_set(
463
     error,
464
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
465
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
466
     "%s: invalid file.",
467
     function );
468
469
    return( -1 );
470
  }
471
  internal_file = (libagdb_internal_file_t *) file;
472
473
  if( filename == NULL )
474
  {
475
    libcerror_error_set(
476
     error,
477
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
478
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
479
     "%s: invalid filename.",
480
     function );
481
482
    return( -1 );
483
  }
484
  if( ( ( access_flags & LIBAGDB_ACCESS_FLAG_READ ) == 0 )
485
   && ( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) == 0 ) )
486
  {
487
    libcerror_error_set(
488
     error,
489
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
491
     "%s: unsupported access flags.",
492
     function );
493
494
    return( -1 );
495
  }
496
  if( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) != 0 )
497
  {
498
    libcerror_error_set(
499
     error,
500
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
501
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
502
     "%s: write access currently not supported.",
503
     function );
504
505
    return( -1 );
506
  }
507
  if( libbfio_file_initialize(
508
       &file_io_handle,
509
       error ) != 1 )
510
  {
511
    libcerror_error_set(
512
     error,
513
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
514
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
515
     "%s: unable to create file IO handle.",
516
     function );
517
518
    goto on_error;
519
  }
520
#if defined( HAVE_DEBUG_OUTPUT )
521
  if( libbfio_handle_set_track_offsets_read(
522
       file_io_handle,
523
       1,
524
       error ) != 1 )
525
  {
526
                libcerror_error_set(
527
                 error,
528
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
529
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
530
                 "%s: unable to set track offsets read in file IO handle.",
531
                 function );
532
533
    goto on_error;
534
  }
535
#endif
536
  filename_length = wide_string_length(
537
                     filename );
538
539
  if( libbfio_file_set_name_wide(
540
       file_io_handle,
541
       filename,
542
       filename_length + 1,
543
       error ) != 1 )
544
  {
545
                libcerror_error_set(
546
                 error,
547
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
548
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
549
                 "%s: unable to set filename in file IO handle.",
550
                 function );
551
552
    goto on_error;
553
  }
554
  if( libagdb_file_open_file_io_handle(
555
       file,
556
       file_io_handle,
557
       access_flags,
558
       error ) != 1 )
559
  {
560
    libcerror_error_set(
561
     error,
562
     LIBCERROR_ERROR_DOMAIN_IO,
563
     LIBCERROR_IO_ERROR_OPEN_FAILED,
564
     "%s: unable to open file: %ls.",
565
     function,
566
     filename );
567
568
    goto on_error;
569
  }
570
  internal_file->file_io_handle_created_in_library = 1;
571
572
  return( 1 );
573
574
on_error:
575
  if( file_io_handle != NULL )
576
  {
577
    libbfio_handle_free(
578
     &file_io_handle,
579
     NULL );
580
  }
581
  return( -1 );
582
}
583
584
#endif
585
586
/* Opens a file using a Basic File IO (bfio) handle
587
 * Returns 1 if successful or -1 on error
588
 */
589
int libagdb_file_open_file_io_handle(
590
     libagdb_file_t *file,
591
     libbfio_handle_t *file_io_handle,
592
     int access_flags,
593
     libcerror_error_t **error )
594
2.32k
{
595
2.32k
  libagdb_internal_file_t *internal_file = NULL;
596
2.32k
  static char *function                  = "libagdb_file_open_file_io_handle";
597
2.32k
  int bfio_access_flags                  = 0;
598
2.32k
  int file_io_handle_is_open             = 0;
599
600
2.32k
  if( file == NULL )
601
0
  {
602
0
    libcerror_error_set(
603
0
     error,
604
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
605
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
606
0
     "%s: invalid file.",
607
0
     function );
608
609
0
    return( -1 );
610
0
  }
611
2.32k
  internal_file = (libagdb_internal_file_t *) file;
612
613
2.32k
  if( internal_file->file_io_handle != NULL )
614
0
  {
615
0
    libcerror_error_set(
616
0
     error,
617
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
618
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
619
0
     "%s: invalid file - file IO handle already set.",
620
0
     function );
621
622
0
    return( -1 );
623
0
  }
624
2.32k
  if( file_io_handle == NULL )
625
0
  {
626
0
    libcerror_error_set(
627
0
     error,
628
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
629
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
630
0
     "%s: invalid file IO handle.",
631
0
     function );
632
633
0
    return( -1 );
634
0
  }
635
2.32k
  if( ( ( access_flags & LIBAGDB_ACCESS_FLAG_READ ) == 0 )
636
2.32k
   && ( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) == 0 ) )
637
0
  {
638
0
    libcerror_error_set(
639
0
     error,
640
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
641
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
642
0
     "%s: unsupported access flags.",
643
0
     function );
644
645
0
    return( -1 );
646
0
  }
647
2.32k
  if( ( access_flags & LIBAGDB_ACCESS_FLAG_WRITE ) != 0 )
648
0
  {
649
0
    libcerror_error_set(
650
0
     error,
651
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
652
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
653
0
     "%s: write access currently not supported.",
654
0
     function );
655
656
0
    return( -1 );
657
0
  }
658
2.32k
  if( ( access_flags & LIBAGDB_ACCESS_FLAG_READ ) != 0 )
659
2.32k
  {
660
2.32k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
661
2.32k
  }
662
2.32k
  internal_file->file_io_handle = file_io_handle;
663
664
2.32k
  file_io_handle_is_open = libbfio_handle_is_open(
665
2.32k
                            internal_file->file_io_handle,
666
2.32k
                            error );
667
668
2.32k
  if( file_io_handle_is_open == -1 )
669
0
  {
670
0
    libcerror_error_set(
671
0
     error,
672
0
     LIBCERROR_ERROR_DOMAIN_IO,
673
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
674
0
     "%s: unable to determine if file IO handle is open.",
675
0
     function );
676
677
0
    goto on_error;
678
0
  }
679
2.32k
  else if( file_io_handle_is_open == 0 )
680
2.32k
  {
681
2.32k
    if( libbfio_handle_open(
682
2.32k
         internal_file->file_io_handle,
683
2.32k
         bfio_access_flags,
684
2.32k
         error ) != 1 )
685
0
    {
686
0
      libcerror_error_set(
687
0
       error,
688
0
       LIBCERROR_ERROR_DOMAIN_IO,
689
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
690
0
       "%s: unable to open file IO handle.",
691
0
       function );
692
693
0
      goto on_error;
694
0
    }
695
2.32k
    internal_file->file_io_handle_opened_in_library = 1;
696
2.32k
  }
697
2.32k
  if( libagdb_file_open_read(
698
2.32k
       internal_file,
699
2.32k
       file_io_handle,
700
2.32k
       error ) != 1 )
701
2.29k
  {
702
2.29k
    libcerror_error_set(
703
2.29k
     error,
704
2.29k
     LIBCERROR_ERROR_DOMAIN_IO,
705
2.29k
     LIBCERROR_IO_ERROR_READ_FAILED,
706
2.29k
     "%s: unable to read from file handle.",
707
2.29k
     function );
708
709
2.29k
    goto on_error;
710
2.29k
  }
711
22
  internal_file->file_io_handle = file_io_handle;
712
713
22
  return( 1 );
714
715
2.29k
on_error:
716
2.29k
  if( ( file_io_handle_is_open == 0 )
717
2.29k
   && ( internal_file->file_io_handle_opened_in_library != 0 ) )
718
2.29k
  {
719
2.29k
    libbfio_handle_close(
720
2.29k
     file_io_handle,
721
2.29k
     error );
722
723
2.29k
    internal_file->file_io_handle_opened_in_library = 0;
724
2.29k
  }
725
2.29k
  internal_file->file_io_handle = NULL;
726
727
2.29k
  return( -1 );
728
2.32k
}
729
730
/* Closes a file
731
 * Returns 0 if successful or -1 on error
732
 */
733
int libagdb_file_close(
734
     libagdb_file_t *file,
735
     libcerror_error_t **error )
736
22
{
737
22
  libagdb_internal_file_t *internal_file = NULL;
738
22
  static char *function                  = "libagdb_file_close";
739
22
  int result                             = 0;
740
741
22
  if( file == NULL )
742
0
  {
743
0
    libcerror_error_set(
744
0
     error,
745
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
746
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
747
0
     "%s: invalid file.",
748
0
     function );
749
750
0
    return( -1 );
751
0
  }
752
22
  internal_file = (libagdb_internal_file_t *) file;
753
754
22
  if( internal_file->file_io_handle == NULL )
755
0
  {
756
0
    libcerror_error_set(
757
0
     error,
758
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
759
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
760
0
     "%s: invalid file - missing file IO handle.",
761
0
     function );
762
763
0
    return( -1 );
764
0
  }
765
#if defined( HAVE_DEBUG_OUTPUT )
766
  if( libcnotify_verbose != 0 )
767
  {
768
    if( internal_file->file_io_handle_created_in_library != 0 )
769
    {
770
      if( libagdb_debug_print_read_offsets(
771
           internal_file->file_io_handle,
772
           error ) != 1 )
773
      {
774
        libcerror_error_set(
775
         error,
776
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
777
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
778
         "%s: unable to print the read offsets.",
779
         function );
780
781
        result = -1;
782
      }
783
    }
784
  }
785
#endif
786
22
  if( internal_file->file_io_handle_opened_in_library != 0 )
787
22
  {
788
22
    if( libbfio_handle_close(
789
22
         internal_file->file_io_handle,
790
22
         error ) != 0 )
791
0
    {
792
0
      libcerror_error_set(
793
0
       error,
794
0
       LIBCERROR_ERROR_DOMAIN_IO,
795
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
796
0
       "%s: unable to close file IO handle.",
797
0
       function );
798
799
0
      result = -1;
800
0
    }
801
22
    internal_file->file_io_handle_opened_in_library = 0;
802
22
  }
803
22
  if( internal_file->file_io_handle_created_in_library != 0 )
804
0
  {
805
0
    if( libbfio_handle_free(
806
0
         &( internal_file->file_io_handle ),
807
0
         error ) != 1 )
808
0
    {
809
0
      libcerror_error_set(
810
0
       error,
811
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
812
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
813
0
       "%s: unable to free file IO handle.",
814
0
       function );
815
816
0
      result = -1;
817
0
    }
818
0
    internal_file->file_io_handle_created_in_library = 0;
819
0
  }
820
22
  internal_file->file_io_handle = NULL;
821
822
22
  if( libagdb_io_handle_clear(
823
22
       internal_file->io_handle,
824
22
       error ) != 1 )
825
0
  {
826
0
    libcerror_error_set(
827
0
     error,
828
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
829
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
830
0
     "%s: unable to clear IO handle.",
831
0
     function );
832
833
0
    result = -1;
834
0
  }
835
22
  if( internal_file->compressed_blocks_list != NULL )
836
19
  {
837
19
    if( libfdata_list_free(
838
19
         &( internal_file->compressed_blocks_list ),
839
19
         error ) != 1 )
840
0
    {
841
0
      libcerror_error_set(
842
0
       error,
843
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
844
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
845
0
       "%s: unable to free compressed blocks list.",
846
0
       function );
847
848
0
      result = -1;
849
0
    }
850
19
  }
851
22
  if( internal_file->compressed_blocks_cache != NULL )
852
19
  {
853
19
    if( libfcache_cache_free(
854
19
         &( internal_file->compressed_blocks_cache ),
855
19
         error ) != 1 )
856
0
    {
857
0
      libcerror_error_set(
858
0
       error,
859
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
860
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
861
0
       "%s: unable to free compressed blocks cache.",
862
0
       function );
863
864
0
      result = -1;
865
0
    }
866
19
  }
867
22
  if( internal_file->uncompressed_data_stream != NULL )
868
22
  {
869
22
    if( libfdata_stream_free(
870
22
         &( internal_file->uncompressed_data_stream ),
871
22
         error ) != 1 )
872
0
    {
873
0
      libcerror_error_set(
874
0
       error,
875
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
876
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
877
0
       "%s: unable to free uncompressed data strea,.",
878
0
       function );
879
880
0
      result = -1;
881
0
    }
882
22
  }
883
22
  if( libcdata_array_resize(
884
22
       internal_file->volumes_array,
885
22
       0,
886
22
       (int (*)(intptr_t **, libcerror_error_t **)) &libagdb_internal_volume_information_free,
887
22
       error ) != 1 )
888
0
  {
889
0
    libcerror_error_set(
890
0
     error,
891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
893
0
     "%s: unable to resize volumes array.",
894
0
     function );
895
896
0
    result = -1;
897
0
  }
898
22
  if( libcdata_array_resize(
899
22
       internal_file->sources_array,
900
22
       0,
901
22
       (int (*)(intptr_t **, libcerror_error_t **)) &libagdb_internal_source_information_free,
902
22
       error ) != 1 )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
907
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
908
0
     "%s: unable to resize sources array.",
909
0
     function );
910
911
0
    result = -1;
912
0
  }
913
22
  return( result );
914
22
}
915
916
/* Opens a file for reading
917
 * Returns 1 if successful or -1 on error
918
 */
919
int libagdb_file_open_read(
920
     libagdb_internal_file_t *internal_file,
921
     libbfio_handle_t *file_io_handle,
922
     libcerror_error_t **error )
923
2.32k
{
924
2.32k
  uint8_t alignment_padding_data[ 8 ];
925
926
2.32k
  libagdb_compressed_file_header_t *compressed_file_header = NULL;
927
2.32k
  libagdb_source_information_t *source_information         = NULL;
928
2.32k
  libagdb_volume_information_t *volume_information         = NULL;
929
2.32k
  static char *function                                    = "libagdb_file_open_read";
930
2.32k
  ssize64_t read_count                                     = 0;
931
2.32k
  size_t alignment_padding_size                            = 0;
932
2.32k
  off64_t file_offset                                      = 0;
933
2.32k
  uint32_t number_of_sources                               = 0;
934
2.32k
  uint32_t number_of_volumes                               = 0;
935
2.32k
  uint32_t source_index                                    = 0;
936
2.32k
  uint32_t volume_index                                    = 0;
937
2.32k
  int entry_index                                          = 0;
938
2.32k
  int segment_index                                        = 0;
939
940
2.32k
  if( internal_file == NULL )
941
0
  {
942
0
    libcerror_error_set(
943
0
     error,
944
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
945
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
946
0
     "%s: invalid file.",
947
0
     function );
948
949
0
    return( -1 );
950
0
  }
951
2.32k
  if( internal_file->io_handle == NULL )
952
0
  {
953
0
    libcerror_error_set(
954
0
     error,
955
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
956
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
957
0
     "%s: invalid file - missing IO handle.",
958
0
     function );
959
960
0
    return( -1 );
961
0
  }
962
2.32k
  if( internal_file->compressed_blocks_list != NULL )
963
0
  {
964
0
    libcerror_error_set(
965
0
     error,
966
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
967
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
968
0
     "%s: invalid file - compressed blocks list value already set.",
969
0
     function );
970
971
0
    return( -1 );
972
0
  }
973
2.32k
  if( internal_file->compressed_blocks_cache != NULL )
974
0
  {
975
0
    libcerror_error_set(
976
0
     error,
977
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
978
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
979
0
     "%s: invalid file - compressed blocks cache value already set.",
980
0
     function );
981
982
0
    return( -1 );
983
0
  }
984
2.32k
  if( internal_file->io_handle->abort != 0 )
985
0
  {
986
0
    internal_file->io_handle->abort = 0;
987
0
  }
988
#if defined( HAVE_DEBUG_OUTPUT )
989
  if( libcnotify_verbose != 0 )
990
  {
991
    libcnotify_printf(
992
     "Reading file header:\n" );
993
  }
994
#endif
995
2.32k
  if( libagdb_compressed_file_header_initialize(
996
2.32k
       &compressed_file_header,
997
2.32k
       error ) != 1 )
998
0
  {
999
0
    libcerror_error_set(
1000
0
     error,
1001
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1002
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1003
0
     "%s: unable to create compressed file header.",
1004
0
     function );
1005
1006
0
    goto on_error;
1007
0
  }
1008
2.32k
  if( libagdb_compressed_file_header_read_file_io_handle(
1009
2.32k
       compressed_file_header,
1010
2.32k
       file_io_handle,
1011
2.32k
       error ) != 1 )
1012
101
  {
1013
101
    libcerror_error_set(
1014
101
     error,
1015
101
     LIBCERROR_ERROR_DOMAIN_IO,
1016
101
     LIBCERROR_IO_ERROR_READ_FAILED,
1017
101
     "%s: unable to read compressed file header.",
1018
101
     function );
1019
1020
101
    goto on_error;
1021
101
  }
1022
2.22k
  internal_file->io_handle->file_type               = compressed_file_header->file_type;
1023
2.22k
  internal_file->io_handle->file_size               = compressed_file_header->file_size;
1024
2.22k
  internal_file->io_handle->uncompressed_block_size = compressed_file_header->uncompressed_block_size;
1025
2.22k
  internal_file->io_handle->uncompressed_data_size  = compressed_file_header->uncompressed_data_size;
1026
1027
2.22k
  if( libagdb_compressed_file_header_free(
1028
2.22k
       &compressed_file_header,
1029
2.22k
       error ) != 1 )
1030
0
  {
1031
0
    libcerror_error_set(
1032
0
     error,
1033
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1034
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1035
0
     "%s: unable to free compressed file header.",
1036
0
     function );
1037
1038
0
    goto on_error;
1039
0
  }
1040
2.22k
  if( internal_file->io_handle->file_type != LIBAGDB_FILE_TYPE_UNCOMPRESSED )
1041
2.05k
  {
1042
2.05k
    if( libfdata_list_initialize(
1043
2.05k
         &( internal_file->compressed_blocks_list ),
1044
2.05k
         (intptr_t *) internal_file->io_handle,
1045
2.05k
         NULL,
1046
2.05k
         NULL,
1047
2.05k
         (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libagdb_compressed_block_read_element_data,
1048
2.05k
         NULL,
1049
2.05k
         LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
1050
2.05k
         error ) != 1 )
1051
0
    {
1052
0
      libcerror_error_set(
1053
0
       error,
1054
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1055
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1056
0
       "%s: unable to create compressed blocks list.",
1057
0
       function );
1058
1059
0
      goto on_error;
1060
0
    }
1061
#if defined( HAVE_DEBUG_OUTPUT )
1062
    if( libcnotify_verbose != 0 )
1063
    {
1064
      libcnotify_printf(
1065
       "Reading compressed blocks:\n" );
1066
    }
1067
#endif
1068
2.05k
    if( libagdb_io_handle_read_compressed_blocks(
1069
2.05k
         internal_file->io_handle,
1070
2.05k
         file_io_handle,
1071
2.05k
         internal_file->compressed_blocks_list,
1072
2.05k
         error ) != 1 )
1073
44
    {
1074
44
      libcerror_error_set(
1075
44
       error,
1076
44
       LIBCERROR_ERROR_DOMAIN_IO,
1077
44
       LIBCERROR_IO_ERROR_READ_FAILED,
1078
44
       "%s: unable to read compressed blocks.",
1079
44
       function );
1080
1081
44
      goto on_error;
1082
44
    }
1083
2.01k
    if( libfcache_cache_initialize(
1084
2.01k
         &( internal_file->compressed_blocks_cache ),
1085
2.01k
         LIBAGDB_MAXIMUM_CACHE_ENTRIES_COMPRESSED_BLOCKS,
1086
2.01k
         error ) != 1 )
1087
0
    {
1088
0
      libcerror_error_set(
1089
0
       error,
1090
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1091
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1092
0
       "%s: unable to create compressed blocks cache.",
1093
0
       function );
1094
1095
0
      goto on_error;
1096
0
    }
1097
2.01k
    if( libagdb_compressed_blocks_stream_initialize(
1098
2.01k
         &( internal_file->uncompressed_data_stream ),
1099
2.01k
         internal_file->compressed_blocks_list,
1100
2.01k
         internal_file->compressed_blocks_cache,
1101
2.01k
         error ) != 1 )
1102
0
    {
1103
0
      libcerror_error_set(
1104
0
       error,
1105
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1106
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1107
0
       "%s: unable to create compressed blocks stream.",
1108
0
       function );
1109
1110
0
      goto on_error;
1111
0
    }
1112
2.01k
  }
1113
163
  else
1114
163
  {
1115
163
    if( libfdata_stream_initialize(
1116
163
         &( internal_file->uncompressed_data_stream ),
1117
163
         NULL,
1118
163
         NULL,
1119
163
         NULL,
1120
163
         NULL,
1121
163
         (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libagdb_io_handle_read_segment_data,
1122
163
         NULL,
1123
163
         (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libagdb_io_handle_seek_segment_offset,
1124
163
         0,
1125
163
         error ) != 1 )
1126
0
    {
1127
0
      libcerror_error_set(
1128
0
       error,
1129
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1130
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1131
0
       "%s: unable to create uncompressed data stream.",
1132
0
       function );
1133
1134
0
      goto on_error;
1135
0
    }
1136
163
    if( libfdata_stream_append_segment(
1137
163
         internal_file->uncompressed_data_stream,
1138
163
         &segment_index,
1139
163
         0,
1140
163
         0,
1141
163
         (size64_t) internal_file->io_handle->uncompressed_data_size,
1142
163
         0,
1143
163
         error ) != 1 )
1144
0
    {
1145
0
      libcerror_error_set(
1146
0
       error,
1147
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1148
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1149
0
       "%s: unable to append uncompressed data stream segment: 0.",
1150
0
       function );
1151
1152
0
      goto on_error;
1153
0
    }
1154
163
  }
1155
2.17k
  if( libagdb_io_handle_read_uncompressed_file_header(
1156
2.17k
       internal_file->io_handle,
1157
2.17k
       internal_file->uncompressed_data_stream,
1158
2.17k
       file_io_handle,
1159
2.17k
       &file_offset,
1160
2.17k
       &number_of_volumes,
1161
2.17k
       &number_of_sources,
1162
2.17k
       error ) != 1 )
1163
865
  {
1164
865
    libcerror_error_set(
1165
865
     error,
1166
865
     LIBCERROR_ERROR_DOMAIN_IO,
1167
865
     LIBCERROR_IO_ERROR_READ_FAILED,
1168
865
     "%s: unable to read file header.",
1169
865
     function );
1170
1171
865
    goto on_error;
1172
865
  }
1173
1.31k
  for( volume_index = 0;
1174
19.3k
       volume_index < number_of_volumes;
1175
18.0k
       volume_index++ )
1176
18.9k
  {
1177
18.9k
    alignment_padding_size = (size_t) ( file_offset % 8 );
1178
1179
18.9k
    if( alignment_padding_size != 0 )
1180
1.03k
    {
1181
1.03k
      alignment_padding_size = 8 - alignment_padding_size;
1182
#if defined( HAVE_DEBUG_OUTPUT )
1183
      if( libcnotify_verbose != 0 )
1184
      {
1185
        libcnotify_printf(
1186
         "%s: alignment padding size\t\t\t\t: %" PRIzd "\n",
1187
         function,
1188
         alignment_padding_size );
1189
      }
1190
#endif
1191
1.03k
      read_count = libfdata_stream_read_buffer(
1192
1.03k
                    internal_file->uncompressed_data_stream,
1193
1.03k
                    (intptr_t *) internal_file->file_io_handle,
1194
1.03k
                    alignment_padding_data,
1195
1.03k
                    alignment_padding_size,
1196
1.03k
                    0,
1197
1.03k
                    error );
1198
1199
1.03k
      if( read_count != (ssize_t) alignment_padding_size )
1200
12
      {
1201
12
        libcerror_error_set(
1202
12
         error,
1203
12
         LIBCERROR_ERROR_DOMAIN_IO,
1204
12
         LIBCERROR_IO_ERROR_READ_FAILED,
1205
12
         "%s: unable to read alignment padding data.",
1206
12
         function );
1207
1208
12
        goto on_error;
1209
12
      }
1210
1.02k
      file_offset += read_count;
1211
1212
#if defined( HAVE_DEBUG_OUTPUT )
1213
      if( libcnotify_verbose != 0 )
1214
      {
1215
        libcnotify_printf(
1216
         "%s: alignment padding data:\n",
1217
         function );
1218
        libcnotify_print_data(
1219
         alignment_padding_data,
1220
         alignment_padding_size,
1221
         0 );
1222
      }
1223
#endif
1224
1.02k
    }
1225
18.9k
    if( libagdb_volume_information_initialize(
1226
18.9k
         &volume_information,
1227
18.9k
         error ) != 1 )
1228
0
    {
1229
0
      libcerror_error_set(
1230
0
       error,
1231
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1232
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1233
0
       "%s: unable to create volume: %" PRIu32 " information.",
1234
0
       function,
1235
0
       volume_index );
1236
1237
0
      goto on_error;
1238
0
    }
1239
18.9k
    read_count = libagdb_internal_volume_information_read_file_io_handle(
1240
18.9k
                  (libagdb_internal_volume_information_t *) volume_information,
1241
18.9k
                  internal_file->io_handle,
1242
18.9k
                  internal_file->uncompressed_data_stream,
1243
18.9k
                  internal_file->file_io_handle,
1244
18.9k
                  file_offset,
1245
18.9k
                  volume_index,
1246
18.9k
                  error );
1247
1248
18.9k
    if( read_count == -1 )
1249
874
    {
1250
874
      libcerror_error_set(
1251
874
       error,
1252
874
       LIBCERROR_ERROR_DOMAIN_IO,
1253
874
       LIBCERROR_IO_ERROR_READ_FAILED,
1254
874
       "%s: unable to read volume: %" PRIu32 " information.",
1255
874
       function,
1256
874
       volume_index );
1257
1258
874
      goto on_error;
1259
874
    }
1260
18.0k
    file_offset += read_count;
1261
1262
18.0k
    if( libcdata_array_append_entry(
1263
18.0k
         internal_file->volumes_array,
1264
18.0k
         &entry_index,
1265
18.0k
         (intptr_t *) volume_information,
1266
18.0k
         error ) != 1 )
1267
0
    {
1268
0
      libcerror_error_set(
1269
0
       error,
1270
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1271
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1272
0
       "%s: unable to append volume: %" PRIu32 " information to array.",
1273
0
       function,
1274
0
       volume_index );
1275
1276
0
      goto on_error;
1277
0
    }
1278
18.0k
    volume_information = NULL;
1279
18.0k
  }
1280
425
  for( source_index = 0;
1281
5.99k
       source_index < number_of_sources;
1282
5.56k
       source_index++ )
1283
5.96k
  {
1284
5.96k
    if( libagdb_source_information_initialize(
1285
5.96k
         &source_information,
1286
5.96k
         error ) != 1 )
1287
0
    {
1288
0
      libcerror_error_set(
1289
0
       error,
1290
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1291
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1292
0
       "%s: unable to create source: %" PRIu32 " information.",
1293
0
       function,
1294
0
       source_index );
1295
1296
0
      goto on_error;
1297
0
    }
1298
5.96k
    read_count = libagdb_source_information_read(
1299
5.96k
                  (libagdb_internal_source_information_t *) source_information,
1300
5.96k
                  internal_file->io_handle,
1301
5.96k
                  internal_file->uncompressed_data_stream,
1302
5.96k
                  internal_file->file_io_handle,
1303
5.96k
                  source_index,
1304
5.96k
                  file_offset,
1305
5.96k
                  error );
1306
1307
5.96k
    if( read_count == -1 )
1308
403
    {
1309
403
      libcerror_error_set(
1310
403
       error,
1311
403
       LIBCERROR_ERROR_DOMAIN_IO,
1312
403
       LIBCERROR_IO_ERROR_READ_FAILED,
1313
403
       "%s: unable to read source: %" PRIu32 " information.",
1314
403
       function,
1315
403
       source_index );
1316
1317
403
      goto on_error;
1318
403
    }
1319
5.56k
    file_offset += read_count;
1320
1321
5.56k
    if( libcdata_array_append_entry(
1322
5.56k
         internal_file->sources_array,
1323
5.56k
         &entry_index,
1324
5.56k
         (intptr_t *) source_information,
1325
5.56k
         error ) != 1 )
1326
0
    {
1327
0
      libcerror_error_set(
1328
0
       error,
1329
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1330
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1331
0
       "%s: unable to append source: %" PRIu32 " information to array.",
1332
0
       function,
1333
0
       source_index );
1334
1335
0
      goto on_error;
1336
0
    }
1337
5.56k
    source_information = NULL;
1338
5.56k
  }
1339
/* TODO remove use offset instead */
1340
#if defined( HAVE_DEBUG_OUTPUT )
1341
  if( libcnotify_verbose != 0 )
1342
  {
1343
    uint8_t trailing_data[ 128 ];
1344
1345
    read_count = libfdata_stream_read_buffer(
1346
            internal_file->uncompressed_data_stream,
1347
            (intptr_t *) internal_file->file_io_handle,
1348
            trailing_data,
1349
            128,
1350
            0,
1351
            error );
1352
1353
    if( read_count == -1 )
1354
    {
1355
      libcerror_error_set(
1356
       error,
1357
       LIBCERROR_ERROR_DOMAIN_IO,
1358
       LIBCERROR_IO_ERROR_READ_FAILED,
1359
       "%s: unable to read trailing data.",
1360
       function );
1361
1362
      goto on_error;
1363
    }
1364
    if( read_count > 0 )
1365
    {
1366
      libcnotify_printf(
1367
       "%s: trailing data:\n",
1368
       function );
1369
      libcnotify_print_data(
1370
       trailing_data,
1371
       read_count,
1372
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1373
    }
1374
  }
1375
#endif
1376
22
  return( 1 );
1377
1378
2.29k
on_error:
1379
2.29k
  if( source_information != NULL )
1380
403
  {
1381
403
    libagdb_internal_source_information_free(
1382
403
     (libagdb_internal_source_information_t **) &source_information,
1383
403
     NULL );
1384
403
  }
1385
2.29k
  if( volume_information != NULL )
1386
874
  {
1387
874
    libagdb_internal_volume_information_free(
1388
874
     (libagdb_internal_volume_information_t **) &volume_information,
1389
874
     NULL );
1390
874
  }
1391
2.29k
  if( internal_file->uncompressed_data_stream != NULL )
1392
2.15k
  {
1393
2.15k
    libfdata_stream_free(
1394
2.15k
     &( internal_file->uncompressed_data_stream ),
1395
2.15k
     NULL );
1396
2.15k
  }
1397
2.29k
  if( internal_file->compressed_blocks_cache != NULL )
1398
1.99k
  {
1399
1.99k
    libfcache_cache_free(
1400
1.99k
     &( internal_file->compressed_blocks_cache ),
1401
1.99k
     NULL );
1402
1.99k
  }
1403
2.29k
  if( internal_file->compressed_blocks_list != NULL )
1404
2.03k
  {
1405
2.03k
    libfdata_list_free(
1406
2.03k
     &( internal_file->compressed_blocks_list ),
1407
2.03k
     NULL );
1408
2.03k
  }
1409
2.29k
  if( compressed_file_header != NULL )
1410
101
  {
1411
101
    libagdb_compressed_file_header_free(
1412
101
     &compressed_file_header,
1413
101
     NULL );
1414
101
  }
1415
2.29k
  return( -1 );
1416
425
}
1417
1418
/* Retrieves the number of volumes
1419
 * Returns 1 if successful or -1 on error
1420
 */
1421
int libagdb_file_get_number_of_volumes(
1422
     libagdb_file_t *file,
1423
     int *number_of_volumes,
1424
     libcerror_error_t **error )
1425
0
{
1426
0
  libagdb_internal_file_t *internal_file = NULL;
1427
0
  static char *function                  = "libagdb_file_get_number_of_volumes";
1428
1429
0
  if( file == NULL )
1430
0
  {
1431
0
    libcerror_error_set(
1432
0
     error,
1433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1434
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1435
0
     "%s: invalid file.",
1436
0
     function );
1437
1438
0
    return( -1 );
1439
0
  }
1440
0
  internal_file = (libagdb_internal_file_t *) file;
1441
1442
0
  if( libcdata_array_get_number_of_entries(
1443
0
       internal_file->volumes_array,
1444
0
       number_of_volumes,
1445
0
       error ) != 1 )
1446
0
  {
1447
0
    libcerror_error_set(
1448
0
     error,
1449
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1450
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1451
0
     "%s: unable to retrieve number of volumes.",
1452
0
     function );
1453
1454
0
    return( -1 );
1455
0
  }
1456
0
  return( 1 );
1457
0
}
1458
1459
/* Retrieves a specific volume information
1460
 * Returns 1 if successful or -1 on error
1461
 */
1462
int libagdb_file_get_volume_information(
1463
     libagdb_file_t *file,
1464
     int volume_index,
1465
     libagdb_volume_information_t **volume_information,
1466
     libcerror_error_t **error )
1467
0
{
1468
0
  libagdb_internal_file_t *internal_file = NULL;
1469
0
  static char *function                  = "libagdb_file_get_volume_information";
1470
1471
0
  if( file == NULL )
1472
0
  {
1473
0
    libcerror_error_set(
1474
0
     error,
1475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1477
0
     "%s: invalid file.",
1478
0
     function );
1479
1480
0
    return( -1 );
1481
0
  }
1482
0
  internal_file = (libagdb_internal_file_t *) file;
1483
1484
0
  if( volume_information == NULL )
1485
0
  {
1486
0
    libcerror_error_set(
1487
0
     error,
1488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1490
0
     "%s: invalid volume information.",
1491
0
     function );
1492
1493
0
    return( -1 );
1494
0
  }
1495
0
  if( *volume_information != NULL )
1496
0
  {
1497
0
    libcerror_error_set(
1498
0
     error,
1499
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1500
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1501
0
     "%s: invalid volume information value already set.",
1502
0
     function );
1503
1504
0
    return( -1 );
1505
0
  }
1506
0
  if( libcdata_array_get_entry_by_index(
1507
0
       internal_file->volumes_array,
1508
0
       volume_index,
1509
0
       (intptr_t **) volume_information,
1510
0
       error ) != 1 )
1511
0
  {
1512
0
    libcerror_error_set(
1513
0
     error,
1514
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1515
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1516
0
     "%s: unable to retrieve volume: %d information.",
1517
0
     function,
1518
0
     volume_index );
1519
1520
0
    return( -1 );
1521
0
  }
1522
0
  return( 1 );
1523
0
}
1524
1525
/* Retrieves the number of sources
1526
 * Returns 1 if successful or -1 on error
1527
 */
1528
int libagdb_file_get_number_of_sources(
1529
     libagdb_file_t *file,
1530
     int *number_of_sources,
1531
     libcerror_error_t **error )
1532
0
{
1533
0
  libagdb_internal_file_t *internal_file = NULL;
1534
0
  static char *function                  = "libagdb_file_get_number_of_sources";
1535
1536
0
  if( file == NULL )
1537
0
  {
1538
0
    libcerror_error_set(
1539
0
     error,
1540
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1541
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1542
0
     "%s: invalid file.",
1543
0
     function );
1544
1545
0
    return( -1 );
1546
0
  }
1547
0
  internal_file = (libagdb_internal_file_t *) file;
1548
1549
0
  if( libcdata_array_get_number_of_entries(
1550
0
       internal_file->sources_array,
1551
0
       number_of_sources,
1552
0
       error ) != 1 )
1553
0
  {
1554
0
    libcerror_error_set(
1555
0
     error,
1556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1557
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1558
0
     "%s: unable to retrieve number of sources.",
1559
0
     function );
1560
1561
0
    return( -1 );
1562
0
  }
1563
0
  return( 1 );
1564
0
}
1565
1566
/* Retrieves a specific source information
1567
 * Returns 1 if successful or -1 on error
1568
 */
1569
int libagdb_file_get_source_information(
1570
     libagdb_file_t *file,
1571
     int source_index,
1572
     libagdb_source_information_t **source_information,
1573
     libcerror_error_t **error )
1574
0
{
1575
0
  libagdb_internal_file_t *internal_file = NULL;
1576
0
  static char *function                  = "libagdb_file_get_source_information";
1577
1578
0
  if( file == NULL )
1579
0
  {
1580
0
    libcerror_error_set(
1581
0
     error,
1582
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1583
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1584
0
     "%s: invalid file.",
1585
0
     function );
1586
1587
0
    return( -1 );
1588
0
  }
1589
0
  internal_file = (libagdb_internal_file_t *) file;
1590
1591
0
  if( source_information == NULL )
1592
0
  {
1593
0
    libcerror_error_set(
1594
0
     error,
1595
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1596
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1597
0
     "%s: invalid source information.",
1598
0
     function );
1599
1600
0
    return( -1 );
1601
0
  }
1602
0
  if( *source_information != NULL )
1603
0
  {
1604
0
    libcerror_error_set(
1605
0
     error,
1606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1607
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1608
0
     "%s: invalid source information value already set.",
1609
0
     function );
1610
1611
0
    return( -1 );
1612
0
  }
1613
0
  if( libcdata_array_get_entry_by_index(
1614
0
       internal_file->sources_array,
1615
0
       source_index,
1616
0
       (intptr_t **) source_information,
1617
0
       error ) != 1 )
1618
0
  {
1619
0
    libcerror_error_set(
1620
0
     error,
1621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1622
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1623
0
     "%s: unable to retrieve source: %d information.",
1624
0
     function,
1625
0
     source_index );
1626
1627
0
    return( -1 );
1628
0
  }
1629
0
  return( 1 );
1630
0
}
1631