Coverage Report

Created: 2024-06-12 07:07

/src/libphdi/libphdi/libphdi_storage_image.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Storage image functions
3
 *
4
 * Copyright (C) 2015-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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libphdi_block_descriptor.h"
28
#include "libphdi_block_tree.h"
29
#include "libphdi_libbfio.h"
30
#include "libphdi_libcerror.h"
31
#include "libphdi_libcnotify.h"
32
#include "libphdi_libfdata.h"
33
#include "libphdi_storage_image.h"
34
#include "libphdi_unused.h"
35
36
/* Creates a storage image
37
 * Make sure the value storage_image is referencing, is set to NULL
38
 * Returns 1 if successful or -1 on error
39
 */
40
int libphdi_storage_image_initialize(
41
     libphdi_storage_image_t **storage_image,
42
     libcerror_error_t **error )
43
0
{
44
0
  static char *function = "libphdi_storage_image_initialize";
45
46
0
  if( storage_image == NULL )
47
0
  {
48
0
    libcerror_error_set(
49
0
     error,
50
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
51
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
52
0
     "%s: invalid storage image.",
53
0
     function );
54
55
0
    return( -1 );
56
0
  }
57
0
  if( *storage_image != NULL )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
62
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
63
0
     "%s: invalid storage image value already set.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
0
  *storage_image = memory_allocate_structure(
69
0
                    libphdi_storage_image_t );
70
71
0
  if( *storage_image == NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
76
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
77
0
     "%s: unable to create storage image.",
78
0
     function );
79
80
0
    goto on_error;
81
0
  }
82
0
  if( memory_set(
83
0
       *storage_image,
84
0
       0,
85
0
       sizeof( libphdi_storage_image_t ) ) == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
90
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
91
0
     "%s: unable to clear storage image.",
92
0
     function );
93
94
0
    memory_free(
95
0
     *storage_image );
96
97
0
    *storage_image = NULL;
98
99
0
    return( -1 );
100
0
  }
101
0
  return( 1 );
102
103
0
on_error:
104
0
  if( *storage_image != NULL )
105
0
  {
106
0
    memory_free(
107
0
     *storage_image );
108
109
0
    *storage_image = NULL;
110
0
  }
111
0
  return( -1 );
112
0
}
113
114
/* Frees a storage image
115
 * Returns 1 if successful or -1 on error
116
 */
117
int libphdi_storage_image_free(
118
     libphdi_storage_image_t **storage_image,
119
     libcerror_error_t **error )
120
0
{
121
0
  static char *function = "libphdi_storage_image_free";
122
0
  int result            = 1;
123
124
0
  if( storage_image == NULL )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
129
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
130
0
     "%s: invalid storage image.",
131
0
     function );
132
133
0
    return( -1 );
134
0
  }
135
0
  if( *storage_image != NULL )
136
0
  {
137
0
    if( ( *storage_image )->sparse_image_header != NULL )
138
0
    {
139
0
      if( libphdi_sparse_image_header_free(
140
0
           &( ( *storage_image )->sparse_image_header ),
141
0
           error ) != 1 )
142
0
      {
143
0
        libcerror_error_set(
144
0
         error,
145
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
146
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
147
0
         "%s: unable to free sparse image header.",
148
0
         function );
149
150
0
        result = -1;
151
0
      }
152
0
    }
153
0
    if( ( *storage_image )->block_tree != NULL )
154
0
    {
155
0
      if( libphdi_block_tree_free(
156
0
           &( ( *storage_image )->block_tree ),
157
0
           (int (*)(intptr_t **, libcerror_error_t **)) &libphdi_block_descriptor_free,
158
0
           error ) != 1 )
159
0
      {
160
0
        libcerror_error_set(
161
0
         error,
162
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
163
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
164
0
         "%s: unable to free block tree.",
165
0
         function );
166
167
0
        result = -1;
168
0
      }
169
0
    }
170
0
    memory_free(
171
0
     *storage_image );
172
173
0
    *storage_image = NULL;
174
0
  }
175
0
  return( result );
176
0
}
177
178
/* Reads the file header from the storage image using the file IO pool entry
179
 * Returns 1 if successful or -1 on error
180
 */
181
int libphdi_storage_image_read_file_header(
182
     libphdi_storage_image_t *storage_image,
183
     libbfio_pool_t *file_io_pool,
184
     int file_io_pool_entry,
185
     libcerror_error_t **error )
186
0
{
187
0
  libbfio_handle_t *file_io_handle                   = NULL;
188
0
  libphdi_sparse_image_header_t *sparse_image_header = NULL;
189
0
  static char *function                              = "libphdi_storage_image_read_file_header";
190
0
  int result                                         = 0;
191
192
0
  if( storage_image == NULL )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
197
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
198
0
     "%s: invalid storage image.",
199
0
     function );
200
201
0
    return( -1 );
202
0
  }
203
0
  if( storage_image->sparse_image_header != NULL )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
208
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
209
0
     "%s: invalid storage image - sparse image header value already set.",
210
0
     function );
211
212
0
    return( -1 );
213
0
  }
214
0
  if( libbfio_pool_get_handle(
215
0
       file_io_pool,
216
0
       file_io_pool_entry,
217
0
       &file_io_handle,
218
0
       error ) != 1 )
219
0
  {
220
0
    libcerror_error_set(
221
0
     error,
222
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
223
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
224
0
     "%s: unable to retrieve file IO handle: %d from pool.",
225
0
     function,
226
0
     file_io_pool_entry );
227
228
0
    goto on_error;
229
0
  }
230
0
  if( libphdi_sparse_image_header_initialize(
231
0
       &sparse_image_header,
232
0
       error ) != 1 )
233
0
  {
234
0
    libcerror_error_set(
235
0
     error,
236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
237
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
238
0
     "%s: unable to create sparse image header.",
239
0
     function );
240
241
0
    goto on_error;
242
0
  }
243
0
  result = libphdi_sparse_image_header_read_file_io_handle(
244
0
            sparse_image_header,
245
0
            file_io_handle,
246
0
            error );
247
248
0
  if( result == -1 )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_IO,
253
0
     LIBCERROR_IO_ERROR_READ_FAILED,
254
0
     "%s: unable to read from file IO handle.",
255
0
     function );
256
257
0
    goto on_error;
258
0
  }
259
0
  else if( result == 0 )
260
0
  {
261
0
    if( libphdi_sparse_image_header_free(
262
0
         &sparse_image_header,
263
0
         error ) != 1 )
264
0
    {
265
0
      libcerror_error_set(
266
0
       error,
267
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
268
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
269
0
       "%s: unable to free sparse image header.",
270
0
       function );
271
272
0
      goto on_error;
273
0
    }
274
0
  }
275
0
  storage_image->sparse_image_header = sparse_image_header;
276
277
0
  return( 1 );
278
279
0
on_error:
280
0
  if( sparse_image_header != NULL )
281
0
  {
282
0
    libphdi_sparse_image_header_free(
283
0
     &sparse_image_header,
284
0
     NULL );
285
0
  }
286
0
  return( -1 );
287
0
}
288
289
/* Reads the block allocation table from the storage image using the file IO pool entry
290
 * Returns 1 if successful or -1 on error
291
 */
292
int libphdi_storage_image_read_block_allocation_table(
293
     libphdi_storage_image_t *storage_image,
294
     libbfio_pool_t *file_io_pool,
295
     int file_io_pool_entry,
296
     libcerror_error_t **error )
297
0
{
298
0
  libphdi_block_descriptor_t *existing_block_descriptor = NULL;
299
0
  libphdi_block_descriptor_t *new_block_descriptor      = NULL;
300
0
  libphdi_block_tree_node_t *leaf_block_tree_node       = NULL;
301
0
  uint8_t *block_allocation_table_data                  = NULL;
302
0
  static char *function                                 = "libphdi_storage_image_read_block_allocation_table";
303
0
  size64_t block_size                                   = 0;
304
0
  size_t block_allocation_table_data_size               = 0;
305
0
  size_t data_offset                                    = 0;
306
0
  ssize_t read_count                                    = 0;
307
0
  off64_t file_offset                                   = 0;
308
0
  off64_t logical_offset                                = 0;
309
0
  uint32_t block_allocation_table_entry                 = 0;
310
0
  int leaf_value_index                                  = 0;
311
312
#if defined( HAVE_DEBUG_OUTPUT )
313
  int entry_index                                       = 0;
314
#endif
315
316
0
  if( storage_image == NULL )
317
0
  {
318
0
    libcerror_error_set(
319
0
     error,
320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
322
0
     "%s: invalid storage image.",
323
0
     function );
324
325
0
    return( -1 );
326
0
  }
327
0
  if( storage_image->block_tree != NULL )
328
0
  {
329
0
    libcerror_error_set(
330
0
     error,
331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
332
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
333
0
     "%s: invalid storage image - block tree value already set.",
334
0
     function );
335
336
0
    return( -1 );
337
0
  }
338
0
  if( libphdi_sparse_image_header_get_block_size(
339
0
       storage_image->sparse_image_header,
340
0
       &block_size,
341
0
       error ) != 1 )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
346
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
347
0
     "%s: unable to retrieve block size.",
348
0
     function );
349
350
0
    return( -1 );
351
0
  }
352
0
  if( ( storage_image->sparse_image_header->number_of_allocation_table_entries == 0 )
353
0
   || ( storage_image->sparse_image_header->number_of_allocation_table_entries > ( (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE / 4 ) ) )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
359
0
     "%s: invalid storage image - invalid sparse image header value - number of allocation table entries value out of bounds.",
360
0
     function );
361
362
0
    return( -1 );
363
0
  }
364
0
  block_allocation_table_data_size = (size_t) storage_image->sparse_image_header->number_of_allocation_table_entries * 4;
365
366
0
  block_allocation_table_data = (uint8_t *) memory_allocate(
367
0
                                             sizeof( uint8_t ) * block_allocation_table_data_size );
368
369
0
  if( block_allocation_table_data == NULL )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
374
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
375
0
     "%s: unable to create block allocation table data.",
376
0
     function );
377
378
0
    goto on_error;
379
0
  }
380
0
  read_count = libbfio_pool_read_buffer(
381
0
                file_io_pool,
382
0
                file_io_pool_entry,
383
0
                block_allocation_table_data,
384
0
                block_allocation_table_data_size,
385
0
                error );
386
387
0
  if( read_count != (ssize_t) block_allocation_table_data_size )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_IO,
392
0
     LIBCERROR_IO_ERROR_READ_FAILED,
393
0
     "%s: unable to read block allocation table data from file IO pool entry: %d.",
394
0
     function,
395
0
     file_io_pool_entry );
396
397
0
    goto on_error;
398
0
  }
399
#if defined( HAVE_DEBUG_OUTPUT )
400
  if( libcnotify_verbose != 0 )
401
  {
402
    libcnotify_printf(
403
     "%s: block allocation table data:\n",
404
     function );
405
    libcnotify_print_data(
406
     block_allocation_table_data,
407
     block_allocation_table_data_size,
408
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
409
  }
410
#endif
411
0
  if( libphdi_block_tree_initialize(
412
0
       &( storage_image->block_tree ),
413
0
       (size64_t) storage_image->sparse_image_header->number_of_sectors * 512,
414
0
       block_size,
415
0
       error ) != 1 )
416
0
  {
417
0
    libcerror_error_set(
418
0
     error,
419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
420
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
421
0
     "%s: unable to create block tree.",
422
0
     function );
423
424
0
    goto on_error;
425
0
  }
426
0
  while( data_offset < block_allocation_table_data_size )
427
0
  {
428
0
    byte_stream_copy_to_uint32_little_endian(
429
0
     &( block_allocation_table_data[ data_offset ] ),
430
0
     block_allocation_table_entry );
431
432
0
    data_offset += 4;
433
434
0
    if( block_allocation_table_entry != 0 )
435
0
    {
436
0
      file_offset = (off64_t) block_allocation_table_entry * 512;
437
438
#if defined( HAVE_DEBUG_OUTPUT )
439
      if( libcnotify_verbose != 0 )
440
      {
441
        libcnotify_printf(
442
         "%s: entry index\t: %d\n",
443
         function,
444
         entry_index );
445
446
        libcnotify_printf(
447
         "%s: entry offset\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
448
         function,
449
         logical_offset,
450
         logical_offset );
451
452
        libcnotify_printf(
453
         "%s: entry value\t: %" PRIu32 "\n",
454
         function,
455
         block_allocation_table_entry );
456
457
        libcnotify_printf(
458
         "%s: file offset\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
459
         function,
460
         (off64_t) file_offset,
461
         (off64_t) file_offset );
462
463
        libcnotify_printf(
464
         "\n" );
465
      }
466
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
467
468
0
      if( libphdi_block_descriptor_initialize(
469
0
           &new_block_descriptor,
470
0
           error ) != 1 )
471
0
      {
472
0
        libcerror_error_set(
473
0
         error,
474
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
475
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
476
0
         "%s: unable to create block descriptor.",
477
0
         function );
478
479
0
        goto on_error;
480
0
      }
481
0
      new_block_descriptor->file_io_pool_entry = file_io_pool_entry;
482
0
      new_block_descriptor->file_offset        = file_offset;
483
484
0
      if( libphdi_block_tree_insert_block_descriptor_by_offset(
485
0
           storage_image->block_tree,
486
0
           logical_offset,
487
0
           new_block_descriptor,
488
0
           &leaf_value_index,
489
0
           &leaf_block_tree_node,
490
0
           &existing_block_descriptor,
491
0
           error ) != 1 )
492
0
      {
493
0
        libcerror_error_set(
494
0
         error,
495
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
496
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
497
0
         "%s: unable to insert block descriptor in block tree.",
498
0
         function );
499
500
0
        goto on_error;
501
0
      }
502
0
      new_block_descriptor = NULL;
503
0
    }
504
0
    logical_offset += (off64_t) block_size;
505
506
#if defined( HAVE_DEBUG_OUTPUT )
507
    entry_index++;
508
#endif
509
0
  }
510
0
  memory_free(
511
0
   block_allocation_table_data );
512
513
0
  return( 1 );
514
515
0
on_error:
516
0
  if( new_block_descriptor != NULL )
517
0
  {
518
0
    libphdi_block_descriptor_free(
519
0
     &new_block_descriptor,
520
0
     NULL );
521
0
  }
522
0
  if( storage_image->block_tree != NULL )
523
0
  {
524
0
    libphdi_block_tree_free(
525
0
     &( storage_image->block_tree ),
526
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libphdi_block_descriptor_free,
527
0
     NULL );
528
0
  }
529
0
  if( block_allocation_table_data != NULL )
530
0
  {
531
0
    memory_free(
532
0
     block_allocation_table_data );
533
0
  }
534
0
  return( -1 );
535
0
}
536
537
/* Retrieves the block size
538
 * Returns 1 if successful or -1 on error
539
 */
540
int libphdi_storage_image_get_block_size(
541
     libphdi_storage_image_t *storage_image,
542
     size64_t *block_size,
543
     libcerror_error_t **error )
544
0
{
545
0
  static char *function = "libphdi_storage_image_get_block_size";
546
547
0
  if( storage_image == NULL )
548
0
  {
549
0
    libcerror_error_set(
550
0
     error,
551
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
552
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
553
0
     "%s: invalid storage image.",
554
0
     function );
555
556
0
    return( -1 );
557
0
  }
558
0
  if( libphdi_sparse_image_header_get_block_size(
559
0
       storage_image->sparse_image_header,
560
0
       block_size,
561
0
       error ) != 1 )
562
0
  {
563
0
    libcerror_error_set(
564
0
     error,
565
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
566
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
567
0
     "%s: unable to retrieve block size.",
568
0
     function );
569
570
0
    return( -1 );
571
0
  }
572
0
  return( 1 );
573
0
}
574
575
/* Retrieves the block descriptor at a specific offset
576
 * Returns 1 if successful, 0 if not available or -1 on error
577
 */
578
int libphdi_storage_image_get_block_descriptor_at_offset(
579
     libphdi_storage_image_t *storage_image,
580
     off64_t offset,
581
     libphdi_block_descriptor_t **block_descriptor,
582
     off64_t *block_offset,
583
     libcerror_error_t **error )
584
0
{
585
0
  static char *function = "libphdi_storage_image_get_block_descriptor_at_offset";
586
0
  int result            = 0;
587
588
0
  if( storage_image == NULL )
589
0
  {
590
0
    libcerror_error_set(
591
0
     error,
592
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
593
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
594
0
     "%s: invalid storage image.",
595
0
     function );
596
597
0
    return( -1 );
598
0
  }
599
0
  result = libphdi_block_tree_get_block_descriptor_by_offset(
600
0
            storage_image->block_tree,
601
0
            offset,
602
0
            block_descriptor,
603
0
            block_offset,
604
0
            error );
605
606
0
  if( result == -1 )
607
0
  {
608
0
    libcerror_error_set(
609
0
     error,
610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
611
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
612
0
     "%s: unable to retrieve block descriptor for offset: %" PRIi64 " (0x%08" PRIx64 ").",
613
0
     function,
614
0
     offset,
615
0
     offset );
616
617
0
    return( -1 );
618
0
  }
619
0
  return( result );
620
0
}
621
622
/* Reads a storage image
623
 * Callback function for the storage images list
624
 * Returns 1 if successful or -1 on error
625
 */
626
int libphdi_storage_image_read_element_data(
627
     intptr_t *data_handle LIBPHDI_ATTRIBUTE_UNUSED,
628
     libbfio_pool_t *file_io_pool,
629
     libfdata_list_element_t *element,
630
     libfdata_cache_t *storage_image_cache,
631
     int file_io_pool_entry,
632
     off64_t storage_image_offset LIBPHDI_ATTRIBUTE_UNUSED,
633
     size64_t storage_image_size LIBPHDI_ATTRIBUTE_UNUSED,
634
     uint32_t element_flags LIBPHDI_ATTRIBUTE_UNUSED,
635
     uint8_t read_flags LIBPHDI_ATTRIBUTE_UNUSED,
636
     libcerror_error_t **error )
637
0
{
638
0
  libphdi_storage_image_t *storage_image = NULL;
639
0
  static char *function                  = "libphdi_storage_image_read_element_data";
640
641
0
  LIBPHDI_UNREFERENCED_PARAMETER( data_handle )
642
0
  LIBPHDI_UNREFERENCED_PARAMETER( storage_image_offset )
643
0
  LIBPHDI_UNREFERENCED_PARAMETER( storage_image_size )
644
0
  LIBPHDI_UNREFERENCED_PARAMETER( element_flags )
645
0
  LIBPHDI_UNREFERENCED_PARAMETER( read_flags )
646
647
0
  if( libphdi_storage_image_initialize(
648
0
       &storage_image,
649
0
       error ) != 1 )
650
0
  {
651
0
    libcerror_error_set(
652
0
     error,
653
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
654
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
655
0
     "%s: unable to create storage image.",
656
0
     function );
657
658
0
    goto on_error;
659
0
  }
660
0
  if( libphdi_storage_image_read_file_header(
661
0
       storage_image,
662
0
       file_io_pool,
663
0
       file_io_pool_entry,
664
0
       error ) != 1 )
665
0
  {
666
0
    libcerror_error_set(
667
0
     error,
668
0
     LIBCERROR_ERROR_DOMAIN_IO,
669
0
     LIBCERROR_IO_ERROR_READ_FAILED,
670
0
     "%s: unable to read storage image file header.",
671
0
     function );
672
673
0
    goto on_error;
674
0
  }
675
0
  if( libphdi_storage_image_read_block_allocation_table(
676
0
       storage_image,
677
0
       file_io_pool,
678
0
       file_io_pool_entry,
679
0
       error ) != 1 )
680
0
  {
681
0
    libcerror_error_set(
682
0
     error,
683
0
     LIBCERROR_ERROR_DOMAIN_IO,
684
0
     LIBCERROR_IO_ERROR_READ_FAILED,
685
0
     "%s: unable to read storage image block allocation table.",
686
0
     function );
687
688
0
    goto on_error;
689
0
  }
690
0
  if( libfdata_list_element_set_element_value(
691
0
       element,
692
0
       (intptr_t *) file_io_pool,
693
0
       (libfdata_cache_t *) storage_image_cache,
694
0
       (intptr_t *) storage_image,
695
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libphdi_storage_image_free,
696
0
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
697
0
       error ) != 1 )
698
0
  {
699
0
    libcerror_error_set(
700
0
     error,
701
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
702
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
703
0
     "%s: unable to set storage image as element value.",
704
0
     function );
705
706
0
    goto on_error;
707
0
  }
708
0
  return( 1 );
709
710
0
on_error:
711
0
  if( storage_image != NULL )
712
0
  {
713
0
    libphdi_storage_image_free(
714
0
     &storage_image,
715
0
     NULL );
716
0
  }
717
0
  return( -1 );
718
0
}
719
720
/* Reads segment data into a buffer
721
 * Callback function for the segments stream
722
 * Returns the number of bytes read or -1 on error
723
 */
724
ssize_t libphdi_storage_image_read_segment_data(
725
         intptr_t *data_handle LIBPHDI_ATTRIBUTE_UNUSED,
726
         libbfio_pool_t *file_io_pool,
727
         int segment_index LIBPHDI_ATTRIBUTE_UNUSED,
728
         int segment_file_index,
729
         uint8_t *segment_data,
730
         size_t segment_data_size,
731
         uint32_t segment_flags LIBPHDI_ATTRIBUTE_UNUSED,
732
         uint8_t read_flags LIBPHDI_ATTRIBUTE_UNUSED,
733
         libcerror_error_t **error )
734
0
{
735
0
  static char *function = "libphdi_storage_image_read_segment_data";
736
0
  ssize_t read_count    = 0;
737
738
0
  LIBPHDI_UNREFERENCED_PARAMETER( data_handle )
739
0
  LIBPHDI_UNREFERENCED_PARAMETER( segment_index )
740
0
  LIBPHDI_UNREFERENCED_PARAMETER( segment_flags )
741
0
  LIBPHDI_UNREFERENCED_PARAMETER( read_flags )
742
743
0
  read_count = libbfio_pool_read_buffer(
744
0
                file_io_pool,
745
0
                segment_file_index,
746
0
                segment_data,
747
0
                segment_data_size,
748
0
                error );
749
750
0
  if( read_count == -1 )
751
0
  {
752
0
    libcerror_error_set(
753
0
     error,
754
0
     LIBCERROR_ERROR_DOMAIN_IO,
755
0
     LIBCERROR_IO_ERROR_READ_FAILED,
756
0
     "%s: unable to read segment data.",
757
0
     function );
758
759
0
    return( -1 );
760
0
  }
761
0
  return( read_count );
762
0
}
763
764
/* Seeks a certain segment offset
765
 * Callback function for the segments stream
766
 * Returns the offset or -1 on error
767
 */
768
off64_t libphdi_storage_image_seek_segment_offset(
769
         intptr_t *data_handle LIBPHDI_ATTRIBUTE_UNUSED,
770
         libbfio_pool_t *file_io_pool,
771
         int segment_index LIBPHDI_ATTRIBUTE_UNUSED,
772
         int segment_file_index,
773
         off64_t segment_offset,
774
         libcerror_error_t **error )
775
0
{
776
0
  static char *function = "libphdi_storage_image_seek_segment_offset";
777
778
0
  LIBPHDI_UNREFERENCED_PARAMETER( data_handle )
779
0
  LIBPHDI_UNREFERENCED_PARAMETER( segment_index )
780
781
0
  segment_offset = libbfio_pool_seek_offset(
782
0
                    file_io_pool,
783
0
                    segment_file_index,
784
0
                    segment_offset,
785
0
                    SEEK_SET,
786
0
                    error );
787
788
0
  if( segment_offset == -1 )
789
0
  {
790
0
    libcerror_error_set(
791
0
     error,
792
0
     LIBCERROR_ERROR_DOMAIN_IO,
793
0
     LIBCERROR_IO_ERROR_READ_FAILED,
794
0
     "%s: unable to seek segment offset.",
795
0
     function );
796
797
0
    return( -1 );
798
0
  }
799
0
  return( segment_offset );
800
0
}
801