Coverage Report

Created: 2025-07-04 07:01

/src/libvshadow/libvshadow/libvshadow_store_descriptor.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Store descriptor 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 <types.h>
25
26
#include "libvshadow_block_descriptor.h"
27
#include "libvshadow_block_range_descriptor.h"
28
#include "libvshadow_block_tree.h"
29
#include "libvshadow_debug.h"
30
#include "libvshadow_definitions.h"
31
#include "libvshadow_io_handle.h"
32
#include "libvshadow_libbfio.h"
33
#include "libvshadow_libcdata.h"
34
#include "libvshadow_libcerror.h"
35
#include "libvshadow_libcnotify.h"
36
#include "libvshadow_libcthreads.h"
37
#include "libvshadow_libfdatetime.h"
38
#include "libvshadow_libfguid.h"
39
#include "libvshadow_libuna.h"
40
#include "libvshadow_store_block.h"
41
#include "libvshadow_store_descriptor.h"
42
43
#include "vshadow_store.h"
44
45
/* Creates a store descriptor
46
 * ake sure the value store_descriptor is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libvshadow_store_descriptor_initialize(
50
     libvshadow_store_descriptor_t **store_descriptor,
51
     libcerror_error_t **error )
52
4.93k
{
53
4.93k
  static char *function = "libvshadow_store_descriptor_initialize";
54
55
4.93k
  if( store_descriptor == 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 store descriptor.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
4.93k
  if( *store_descriptor != 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 store descriptor value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
4.93k
  *store_descriptor = memory_allocate_structure(
78
4.93k
                       libvshadow_store_descriptor_t );
79
80
4.93k
  if( *store_descriptor == 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 store descriptor.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
4.93k
  if( memory_set(
92
4.93k
       *store_descriptor,
93
4.93k
       0,
94
4.93k
       sizeof( libvshadow_store_descriptor_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 store descriptor.",
101
0
     function );
102
103
0
    memory_free(
104
0
     *store_descriptor );
105
106
0
    *store_descriptor = NULL;
107
108
0
    return( -1 );
109
0
  }
110
4.93k
  if( libcdata_list_initialize(
111
4.93k
       &( ( *store_descriptor )->block_descriptors_list ),
112
4.93k
       error ) != 1 )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
117
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
118
0
     "%s: unable to create block descriptors list.",
119
0
     function );
120
121
0
    goto on_error;
122
0
  }
123
4.93k
  if( libcdata_range_list_initialize(
124
4.93k
       &( ( *store_descriptor )->block_offset_list ),
125
4.93k
       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 block offsets list.",
132
0
     function );
133
134
0
    goto on_error;
135
0
  }
136
4.93k
  if( libcdata_range_list_initialize(
137
4.93k
       &( ( *store_descriptor )->previous_block_offset_list ),
138
4.93k
       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 previous block offsets list.",
145
0
     function );
146
147
0
    goto on_error;
148
0
  }
149
4.93k
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
150
4.93k
  if( libcthreads_read_write_lock_initialize(
151
4.93k
       &( ( *store_descriptor )->read_write_lock ),
152
4.93k
       error ) != 1 )
153
0
  {
154
0
    libcerror_error_set(
155
0
     error,
156
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
157
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
158
0
     "%s: unable to initialize read/write lock.",
159
0
     function );
160
161
0
    goto on_error;
162
0
  }
163
4.93k
#endif
164
4.93k
  return( 1 );
165
166
0
on_error:
167
0
  if( *store_descriptor != NULL )
168
0
  {
169
0
    if( ( *store_descriptor )->block_offset_list != NULL )
170
0
    {
171
0
      libcdata_range_list_free(
172
0
       &( ( *store_descriptor )->block_offset_list ),
173
0
       NULL,
174
0
       NULL );
175
0
    }
176
0
    if( ( *store_descriptor )->block_descriptors_list != NULL )
177
0
    {
178
0
      libcdata_list_free(
179
0
       &( ( *store_descriptor )->block_descriptors_list ),
180
0
       NULL,
181
0
       NULL );
182
0
    }
183
0
    memory_free(
184
0
     *store_descriptor );
185
186
0
    *store_descriptor = NULL;
187
0
  }
188
0
  return( -1 );
189
4.93k
}
190
191
/* Frees a store descriptor
192
 * Returns 1 if successful or -1 on error
193
 */
194
int libvshadow_store_descriptor_free(
195
     libvshadow_store_descriptor_t **store_descriptor,
196
     libcerror_error_t **error )
197
4.93k
{
198
4.93k
  static char *function = "libvshadow_store_descriptor_free";
199
4.93k
  int result            = 1;
200
201
4.93k
  if( store_descriptor == NULL )
202
0
  {
203
0
    libcerror_error_set(
204
0
     error,
205
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
206
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
207
0
     "%s: invalid store descriptor.",
208
0
     function );
209
210
0
    return( -1 );
211
0
  }
212
4.93k
  if( *store_descriptor != NULL )
213
4.93k
  {
214
4.93k
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
215
4.93k
    if( libcthreads_read_write_lock_free(
216
4.93k
         &( ( *store_descriptor )->read_write_lock ),
217
4.93k
         error ) != 1 )
218
0
    {
219
0
      libcerror_error_set(
220
0
       error,
221
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
222
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
223
0
       "%s: unable to free read/write lock.",
224
0
       function );
225
226
0
      result = -1;
227
0
    }
228
4.93k
#endif
229
4.93k
    if( ( *store_descriptor )->operating_machine_string != NULL )
230
76
    {
231
76
      memory_free(
232
76
       ( *store_descriptor )->operating_machine_string );
233
76
    }
234
4.93k
    if( ( *store_descriptor )->service_machine_string != NULL )
235
49
    {
236
49
      memory_free(
237
49
       ( *store_descriptor )->service_machine_string );
238
49
    }
239
4.93k
    if( ( *store_descriptor )->reverse_block_tree != NULL )
240
0
    {
241
0
      if( libvshadow_block_tree_free(
242
0
           &( ( *store_descriptor )->reverse_block_tree ),
243
0
           (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free_reverse,
244
0
           error ) != 1 )
245
0
      {
246
0
        libcerror_error_set(
247
0
         error,
248
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
249
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
250
0
         "%s: unable to free reverse block tree.",
251
0
         function );
252
253
0
        result = -1;
254
0
      }
255
0
    }
256
4.93k
    if( ( *store_descriptor )->forward_block_tree != NULL )
257
0
    {
258
0
      if( libvshadow_block_tree_free(
259
0
           &( ( *store_descriptor )->forward_block_tree ),
260
0
           (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free,
261
0
           error ) != 1 )
262
0
      {
263
0
        libcerror_error_set(
264
0
         error,
265
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
266
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
267
0
         "%s: unable to free forward block tree.",
268
0
         function );
269
270
0
        result = -1;
271
0
      }
272
0
    }
273
4.93k
    if( libcdata_list_free(
274
4.93k
         &( ( *store_descriptor )->block_descriptors_list ),
275
4.93k
         (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free,
276
4.93k
         error ) != 1 )
277
0
    {
278
0
      libcerror_error_set(
279
0
       error,
280
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
282
0
       "%s: unable to free forward block descriptors tree.",
283
0
       function );
284
285
0
      result = -1;
286
0
    }
287
4.93k
    if( libcdata_range_list_free(
288
4.93k
         &( ( *store_descriptor )->block_offset_list ),
289
4.93k
         NULL,
290
4.93k
         error ) != 1 )
291
0
    {
292
0
      libcerror_error_set(
293
0
       error,
294
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
296
0
       "%s: unable to free block offsets list.",
297
0
       function );
298
299
0
      result = -1;
300
0
    }
301
4.93k
    if( libcdata_range_list_free(
302
4.93k
         &( ( *store_descriptor )->previous_block_offset_list ),
303
4.93k
         NULL,
304
4.93k
         error ) != 1 )
305
0
    {
306
0
      libcerror_error_set(
307
0
       error,
308
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
309
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
310
0
       "%s: unable to free previous block offsets list.",
311
0
       function );
312
313
0
      result = -1;
314
0
    }
315
4.93k
    memory_free(
316
4.93k
     *store_descriptor );
317
318
4.93k
    *store_descriptor = NULL;
319
4.93k
  }
320
4.93k
  return( result );
321
4.93k
}
322
323
/* Determines if the store has in-volume data
324
 * Returns 1 if the store has in-volume data, 0 if not or -1 on error
325
 */
326
int libvshadow_store_descriptor_has_in_volume_data(
327
     libvshadow_store_descriptor_t *store_descriptor,
328
     libcerror_error_t **error )
329
0
{
330
0
  static char *function = "libvshadow_store_descriptor_has_in_volume_data";
331
332
0
  if( store_descriptor == NULL )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
337
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
338
0
     "%s: invalid store descriptor.",
339
0
     function );
340
341
0
    return( -1 );
342
0
  }
343
0
  return( (int) store_descriptor->has_in_volume_store_data );
344
0
}
345
346
/* Compares 2 store descriptors by their creation time
347
 * Returns LIBCDATA_COMPARE_LESS, LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error
348
 */
349
int libvshadow_store_descriptor_compare_by_creation_time(
350
     libvshadow_store_descriptor_t *first_store_descriptor,
351
     libvshadow_store_descriptor_t *second_store_descriptor,
352
     libcerror_error_t **error )
353
22.9k
{
354
22.9k
  static char *function = "libvshadow_store_descriptor_compare_by_creation_time";
355
356
22.9k
  if( first_store_descriptor == 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 first store descriptor.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
22.9k
  if( second_store_descriptor == NULL )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
373
0
     "%s: invalid second store descriptor.",
374
0
     function );
375
376
0
    return( -1 );
377
0
  }
378
22.9k
  if( first_store_descriptor->creation_time < second_store_descriptor->creation_time )
379
2.85k
  {
380
2.85k
    return( LIBCDATA_COMPARE_LESS );
381
2.85k
  }
382
20.0k
  else if( first_store_descriptor->creation_time > second_store_descriptor->creation_time )
383
20.0k
  {
384
20.0k
    return( LIBCDATA_COMPARE_GREATER );
385
20.0k
  }
386
1
  return( LIBCDATA_COMPARE_EQUAL );
387
22.9k
}
388
389
/* Compares 2 store descriptors by their identifier
390
 * Returns LIBCDATA_COMPARE_LESS, LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error
391
 */
392
int libvshadow_store_descriptor_compare_by_identifier(
393
     libvshadow_store_descriptor_t *first_store_descriptor,
394
     libvshadow_store_descriptor_t *second_store_descriptor,
395
     libcerror_error_t **error )
396
10.8k
{
397
10.8k
  static char *function = "libvshadow_store_descriptor_compare_by_identifier";
398
10.8k
  int result            = 0;
399
400
10.8k
  if( first_store_descriptor == NULL )
401
0
  {
402
0
    libcerror_error_set(
403
0
     error,
404
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
405
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
406
0
     "%s: invalid first store descriptor.",
407
0
     function );
408
409
0
    return( -1 );
410
0
  }
411
10.8k
  if( second_store_descriptor == NULL )
412
0
  {
413
0
    libcerror_error_set(
414
0
     error,
415
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
416
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
417
0
     "%s: invalid second store descriptor.",
418
0
     function );
419
420
0
    return( -1 );
421
0
  }
422
10.8k
  result = memory_compare(
423
10.8k
            first_store_descriptor->identifier,
424
10.8k
            second_store_descriptor->identifier,
425
10.8k
            16 );
426
427
10.8k
  if( result < 0 )
428
10.5k
  {
429
10.5k
    return( LIBCDATA_COMPARE_LESS );
430
10.5k
  }
431
305
  else if( result > 0 )
432
0
  {
433
0
    return( LIBCDATA_COMPARE_GREATER );
434
0
  }
435
305
  return( LIBCDATA_COMPARE_EQUAL );
436
10.8k
}
437
438
/* Reads the catalog entry
439
 * Returns 1 if successful or -1 on error
440
 */
441
int libvshadow_store_descriptor_read_catalog_entry(
442
     libvshadow_store_descriptor_t *store_descriptor,
443
     const uint8_t *catalog_block_data,
444
     size_t catalog_block_data_size,
445
     uint64_t *entry_type,
446
     libcerror_error_t **error )
447
25.5k
{
448
25.5k
  static char *function                       = "libvshadow_store_descriptor_read_catalog_entry";
449
25.5k
  uint64_t safe_store_bitmap_offset           = 0;
450
25.5k
  uint64_t safe_store_block_list_offset       = 0;
451
25.5k
  uint64_t safe_store_block_range_list_offset = 0;
452
25.5k
  uint64_t safe_store_header_offset           = 0;
453
25.5k
  uint64_t safe_store_previous_bitmap_offset  = 0;
454
455
#if defined( HAVE_DEBUG_OUTPUT )
456
  uint64_t value_64bit                        = 0;
457
#endif
458
459
25.5k
  if( store_descriptor == NULL )
460
0
  {
461
0
    libcerror_error_set(
462
0
     error,
463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
465
0
     "%s: invalid store descriptor.",
466
0
     function );
467
468
0
    return( -1 );
469
0
  }
470
25.5k
  if( catalog_block_data == NULL )
471
0
  {
472
0
    libcerror_error_set(
473
0
     error,
474
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
475
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
476
0
     "%s: invalid catalog block data.",
477
0
     function );
478
479
0
    return( -1 );
480
0
  }
481
25.5k
  if( catalog_block_data_size < 128 )
482
0
  {
483
0
    libcerror_error_set(
484
0
     error,
485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
486
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
487
0
     "%s: invalid catalog block data size value too small.",
488
0
     function );
489
490
0
    return( -1 );
491
0
  }
492
25.5k
  if( catalog_block_data_size > (size_t) SSIZE_MAX )
493
0
  {
494
0
    libcerror_error_set(
495
0
     error,
496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
498
0
     "%s: invalid catalog block data size value exceeds maximum.",
499
0
     function );
500
501
0
    return( -1 );
502
0
  }
503
25.5k
  if( entry_type == NULL )
504
0
  {
505
0
    libcerror_error_set(
506
0
     error,
507
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
508
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
509
0
     "%s: invalid entry type.",
510
0
     function );
511
512
0
    return( -1 );
513
0
  }
514
25.5k
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
515
25.5k
  if( libcthreads_read_write_lock_grab_for_write(
516
25.5k
       store_descriptor->read_write_lock,
517
25.5k
       error ) != 1 )
518
0
  {
519
0
    libcerror_error_set(
520
0
     error,
521
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
522
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
523
0
     "%s: unable to grab read/write lock for writing.",
524
0
     function );
525
526
0
    return( -1 );
527
0
  }
528
25.5k
#endif
529
#if defined( HAVE_DEBUG_OUTPUT )
530
  if( libcnotify_verbose != 0 )
531
  {
532
    libcnotify_printf(
533
     "%s: catalog block entry data:\n",
534
     function );
535
    libcnotify_print_data(
536
     catalog_block_data,
537
     128,
538
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
539
  }
540
#endif
541
25.5k
  byte_stream_copy_to_uint64_little_endian(
542
25.5k
   catalog_block_data,
543
25.5k
   *entry_type );
544
545
#if defined( HAVE_DEBUG_OUTPUT )
546
  if( libcnotify_verbose != 0 )
547
  {
548
    libcnotify_printf(
549
     "%s: entry type\t\t\t: %" PRIu64 "\n",
550
     function,
551
     *entry_type );
552
  }
553
#endif
554
25.5k
  if( ( *entry_type != 0 )
555
25.5k
   && ( *entry_type != 1 )
556
25.5k
   && ( *entry_type != 2 )
557
25.5k
   && ( *entry_type != 3 ) )
558
98
  {
559
98
    libcerror_error_set(
560
98
     error,
561
98
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
562
98
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
563
98
     "%s: unsupported catalog entry type: %" PRIu64 ".",
564
98
     function,
565
98
     *entry_type );
566
567
98
    goto on_error;
568
98
  }
569
25.4k
  if( ( *entry_type == 0 )
570
25.4k
   || ( *entry_type == 1 ) )
571
18.4k
  {
572
#if defined( HAVE_DEBUG_OUTPUT )
573
    if( libcnotify_verbose != 0 )
574
    {
575
      libcnotify_printf(
576
       "\n" );
577
    }
578
#endif
579
/* TODO empty data check ? */
580
18.4k
  }
581
7.01k
  else if( *entry_type == 2 )
582
4.43k
  {
583
4.43k
    byte_stream_copy_to_uint64_little_endian(
584
4.43k
     &( catalog_block_data[ 8 ] ),
585
4.43k
     store_descriptor->volume_size );
586
587
4.43k
    if( memory_copy(
588
4.43k
         store_descriptor->identifier,
589
4.43k
         &( catalog_block_data[ 16 ] ),
590
4.43k
         16 ) == NULL )
591
0
    {
592
0
      libcerror_error_set(
593
0
       error,
594
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
595
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
596
0
       "%s: unable to copy identifier.",
597
0
       function );
598
599
0
      goto on_error;
600
0
    }
601
4.43k
    byte_stream_copy_to_uint64_little_endian(
602
4.43k
     &( catalog_block_data[ 48 ] ),
603
4.43k
     store_descriptor->creation_time );
604
605
#if defined( HAVE_DEBUG_OUTPUT )
606
    if( libcnotify_verbose != 0 )
607
    {
608
      libcnotify_printf(
609
       "%s: volume size\t\t\t: %" PRIu64 "\n",
610
       function,
611
       store_descriptor->volume_size );
612
613
      if( libvshadow_debug_print_guid_value(
614
           function,
615
           "store identifier\t\t",
616
           &( catalog_block_data[ 16 ] ),
617
           16,
618
           LIBFGUID_ENDIAN_LITTLE,
619
           LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
620
           error ) != 1 )
621
      {
622
        libcerror_error_set(
623
         error,
624
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
625
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
626
         "%s: unable to print GUID value.",
627
         function );
628
629
        goto on_error;
630
      }
631
      byte_stream_copy_to_uint64_little_endian(
632
       &( catalog_block_data[ 32 ] ),
633
       value_64bit );
634
      libcnotify_printf(
635
       "%s: unknown2\t\t\t: %" PRIu64 "\n",
636
       function,
637
       value_64bit );
638
639
      byte_stream_copy_to_uint64_little_endian(
640
       &( catalog_block_data[ 40 ] ),
641
       value_64bit );
642
      libcnotify_printf(
643
       "%s: unknown3\t\t\t: %" PRIu64 "\n",
644
       function,
645
       value_64bit );
646
647
      if( libvshadow_debug_print_filetime_value(
648
           function,
649
           "creation time\t\t\t",
650
           &( catalog_block_data[ 48 ] ),
651
           8,
652
           LIBFDATETIME_ENDIAN_LITTLE,
653
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
654
           error ) != 1 )
655
      {
656
        libcerror_error_set(
657
         error,
658
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
659
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
660
         "%s: unable to print filetime value.",
661
         function );
662
663
        goto on_error;
664
      }
665
      libcnotify_printf(
666
       "%s: unknown4:\n",
667
       function );
668
      libcnotify_print_data(
669
       &( catalog_block_data[ 56 ] ),
670
       72,
671
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
672
    }
673
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
674
4.43k
  }
675
2.58k
  else if( *entry_type == 3 )
676
2.58k
  {
677
2.58k
    byte_stream_copy_to_uint64_little_endian(
678
2.58k
     &( catalog_block_data[ 8 ] ),
679
2.58k
     safe_store_block_list_offset );
680
681
2.58k
    byte_stream_copy_to_uint64_little_endian(
682
2.58k
     &( catalog_block_data[ 32 ] ),
683
2.58k
     safe_store_header_offset );
684
685
2.58k
    byte_stream_copy_to_uint64_little_endian(
686
2.58k
     &( catalog_block_data[ 40 ] ),
687
2.58k
     safe_store_block_range_list_offset );
688
689
2.58k
    byte_stream_copy_to_uint64_little_endian(
690
2.58k
     &( catalog_block_data[ 48 ] ),
691
2.58k
     safe_store_bitmap_offset );
692
693
2.58k
    byte_stream_copy_to_uint64_little_endian(
694
2.58k
     &( catalog_block_data[ 72 ] ),
695
2.58k
     safe_store_previous_bitmap_offset );
696
697
#if defined( HAVE_DEBUG_OUTPUT )
698
    if( libcnotify_verbose != 0 )
699
    {
700
      libcnotify_printf(
701
       "%s: store block list offset\t\t: 0x%08" PRIx64 "\n",
702
       function,
703
       safe_store_block_list_offset );
704
705
      if( libvshadow_debug_print_guid_value(
706
           function,
707
           "store identifier\t\t",
708
           &( catalog_block_data[ 16 ] ),
709
           16,
710
           LIBFGUID_ENDIAN_LITTLE,
711
           LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
712
           error ) != 1 )
713
      {
714
        libcerror_error_set(
715
         error,
716
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
717
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
718
         "%s: unable to print GUID value.",
719
         function );
720
721
        goto on_error;
722
      }
723
      libcnotify_printf(
724
       "%s: store header offset\t\t: 0x%08" PRIx64 "\n",
725
       function,
726
       safe_store_header_offset );
727
728
      libcnotify_printf(
729
       "%s: store block range list offset\t: 0x%08" PRIx64 "\n",
730
       function,
731
       safe_store_block_range_list_offset );
732
733
      libcnotify_printf(
734
       "%s: store bitmap offset\t\t: 0x%08" PRIx64 "\n",
735
       function,
736
       safe_store_bitmap_offset );
737
738
      byte_stream_copy_to_uint64_little_endian(
739
       &( catalog_block_data[ 56 ] ),
740
       value_64bit );
741
      libcnotify_printf(
742
       "%s: store file reference\t\t: MFT entry: %" PRIu64 ", sequence: %" PRIu64 "\n",
743
       function,
744
       value_64bit & 0xffffffffffffUL,
745
       value_64bit >> 48 );
746
747
      byte_stream_copy_to_uint64_little_endian(
748
       &( catalog_block_data[ 64 ] ),
749
       value_64bit );
750
      libcnotify_printf(
751
       "%s: allocated size\t\t\t: %" PRIu64 "\n",
752
       function,
753
       value_64bit );
754
755
      libcnotify_printf(
756
       "%s: store previous bitmap offset\t: 0x%08" PRIx64 "\n",
757
       function,
758
       safe_store_previous_bitmap_offset );
759
760
      byte_stream_copy_to_uint64_little_endian(
761
       &( catalog_block_data[ 80 ] ),
762
       value_64bit );
763
      libcnotify_printf(
764
       "%s: unknown2\t\t\t: %" PRIu64 "\n",
765
       function,
766
       value_64bit );
767
768
      libcnotify_printf(
769
       "%s: unknown3:\n",
770
       function );
771
      libcnotify_print_data(
772
       &( catalog_block_data[ 88 ] ),
773
       40,
774
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
775
    }
776
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
777
2.58k
  }
778
25.4k
  if( safe_store_block_list_offset > (uint64_t) INT64_MAX )
779
67
  {
780
67
    libcerror_error_set(
781
67
     error,
782
67
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
783
67
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
784
67
     "%s: invalid store block list offset value out of bounds.",
785
67
     function );
786
787
67
    goto on_error;
788
67
  }
789
25.3k
  if( safe_store_header_offset > (uint64_t) INT64_MAX )
790
63
  {
791
63
    libcerror_error_set(
792
63
     error,
793
63
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
794
63
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
795
63
     "%s: invalid store header offset value out of bounds.",
796
63
     function );
797
798
63
    goto on_error;
799
63
  }
800
25.3k
  if( safe_store_block_range_list_offset > (uint64_t) INT64_MAX )
801
65
  {
802
65
    libcerror_error_set(
803
65
     error,
804
65
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
805
65
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
806
65
     "%s: invalid store block range list offset value out of bounds.",
807
65
     function );
808
809
65
    goto on_error;
810
65
  }
811
25.2k
  if( safe_store_bitmap_offset > (uint64_t) INT64_MAX )
812
66
  {
813
66
    libcerror_error_set(
814
66
     error,
815
66
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
816
66
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
817
66
     "%s: invalid store bitmap offset value out of bounds.",
818
66
     function );
819
820
66
    goto on_error;
821
66
  }
822
25.1k
  if( safe_store_previous_bitmap_offset > (uint64_t) INT64_MAX )
823
36
  {
824
36
    libcerror_error_set(
825
36
     error,
826
36
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
827
36
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
828
36
     "%s: invalid store previous bitmap offset value out of bounds.",
829
36
     function );
830
831
36
    goto on_error;
832
36
  }
833
25.1k
  store_descriptor->store_block_list_offset       = (off64_t) safe_store_block_list_offset;
834
25.1k
  store_descriptor->store_header_offset           = (off64_t) safe_store_header_offset;
835
25.1k
  store_descriptor->store_block_range_list_offset = (off64_t) safe_store_block_range_list_offset;
836
25.1k
  store_descriptor->store_bitmap_offset           = (off64_t) safe_store_bitmap_offset;
837
25.1k
  store_descriptor->store_previous_bitmap_offset  = (off64_t) safe_store_previous_bitmap_offset;
838
839
25.1k
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
840
25.1k
  if( libcthreads_read_write_lock_release_for_write(
841
25.1k
       store_descriptor->read_write_lock,
842
25.1k
       error ) != 1 )
843
0
  {
844
0
    libcerror_error_set(
845
0
     error,
846
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
847
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
848
0
     "%s: unable to release read/write lock for writing.",
849
0
     function );
850
851
0
    return( -1 );
852
0
  }
853
25.1k
#endif
854
25.1k
  return( 1 );
855
856
395
on_error:
857
395
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
858
395
  libcthreads_read_write_lock_release_for_write(
859
395
   store_descriptor->read_write_lock,
860
395
   NULL );
861
395
#endif
862
395
  return( -1 );
863
25.1k
}
864
865
/* Reads the store header
866
 * Returns 1 if successful or -1 on error
867
 */
868
int libvshadow_store_descriptor_read_store_header(
869
     libvshadow_store_descriptor_t *store_descriptor,
870
     libbfio_handle_t *file_io_handle,
871
     libcerror_error_t **error )
872
227
{
873
227
  libvshadow_store_block_t *store_block = NULL;
874
227
  uint8_t *store_header_data            = NULL;
875
227
  static char *function                 = "libvshadow_store_descriptor_read_store_header";
876
227
  size_t store_header_data_offset       = 0;
877
878
#if defined( HAVE_DEBUG_OUTPUT )
879
  uint32_t value_32bit                  = 0;
880
#endif
881
882
227
  if( store_descriptor == NULL )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
887
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
888
0
     "%s: invalid store descriptor.",
889
0
     function );
890
891
0
    return( -1 );
892
0
  }
893
227
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
894
227
  if( libcthreads_read_write_lock_grab_for_write(
895
227
       store_descriptor->read_write_lock,
896
227
       error ) != 1 )
897
0
  {
898
0
    libcerror_error_set(
899
0
     error,
900
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
901
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
902
0
     "%s: unable to grab read/write lock for writing.",
903
0
     function );
904
905
0
    return( -1 );
906
0
  }
907
227
#endif
908
227
  if( libvshadow_store_block_initialize(
909
227
       &store_block,
910
227
       0x4000,
911
227
       error ) != 1 )
912
0
  {
913
0
    libcerror_error_set(
914
0
     error,
915
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
916
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
917
0
     "%s: unable to create store block.",
918
0
     function );
919
920
0
    goto on_error;
921
0
  }
922
227
  if( libvshadow_store_block_read(
923
227
       store_block,
924
227
       file_io_handle,
925
227
       store_descriptor->store_header_offset,
926
227
       error ) == -1 )
927
84
  {
928
84
    libcerror_error_set(
929
84
     error,
930
84
     LIBCERROR_ERROR_DOMAIN_IO,
931
84
     LIBCERROR_IO_ERROR_READ_FAILED,
932
84
     "%s: unable to read store block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
933
84
     function,
934
84
     store_descriptor->store_header_offset,
935
84
     store_descriptor->store_header_offset );
936
937
84
    goto on_error;
938
84
  }
939
143
  if( store_block->record_type != LIBVSHADOW_RECORD_TYPE_STORE_HEADER )
940
38
  {
941
38
    libcerror_error_set(
942
38
     error,
943
38
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
944
38
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
945
38
     "%s: unsupported record type: %" PRIu32 ".",
946
38
     function,
947
38
     store_block->record_type );
948
949
38
    goto on_error;
950
38
  }
951
105
  store_header_data = &( store_block->data[ sizeof( vshadow_store_header_t ) ] );
952
953
#if defined( HAVE_DEBUG_OUTPUT )
954
  if( libcnotify_verbose != 0 )
955
  {
956
    libcnotify_printf(
957
     "%s: store header information:\n",
958
     function );
959
    libcnotify_print_data(
960
     store_header_data,
961
     sizeof( vshadow_store_information_t ),
962
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
963
  }
964
#endif
965
105
  if( memory_copy(
966
105
       store_descriptor->copy_identifier,
967
105
       ( (vshadow_store_information_t *) store_header_data )->copy_identifier,
968
105
       16 ) == NULL )
969
0
  {
970
0
    libcerror_error_set(
971
0
     error,
972
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
973
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
974
0
     "%s: unable to copy shadow copy identifier.",
975
0
     function );
976
977
0
    goto on_error;
978
0
  }
979
105
  if( memory_copy(
980
105
       store_descriptor->copy_set_identifier,
981
105
       ( (vshadow_store_information_t *) store_header_data )->copy_set_identifier,
982
105
       16 ) == NULL )
983
0
  {
984
0
    libcerror_error_set(
985
0
     error,
986
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
987
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
988
0
     "%s: unable to copy shadow copy set identifier.",
989
0
     function );
990
991
0
    goto on_error;
992
0
  }
993
105
  byte_stream_copy_to_uint32_little_endian(
994
105
   ( (vshadow_store_information_t *) store_header_data )->attribute_flags,
995
105
   store_descriptor->attribute_flags );
996
997
#if defined( HAVE_DEBUG_OUTPUT )
998
  if( libcnotify_verbose != 0 )
999
  {
1000
    if( libvshadow_debug_print_guid_value(
1001
         function,
1002
         "unknown5\t\t\t",
1003
         ( (vshadow_store_information_t *) store_header_data )->unknown5,
1004
         16,
1005
         LIBFGUID_ENDIAN_LITTLE,
1006
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1007
         error ) != 1 )
1008
    {
1009
      libcerror_error_set(
1010
       error,
1011
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1012
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1013
       "%s: unable to print GUID value.",
1014
       function );
1015
1016
      goto on_error;
1017
    }
1018
    if( libvshadow_debug_print_guid_value(
1019
         function,
1020
         "copy identifier\t\t",
1021
         ( (vshadow_store_information_t *) store_header_data )->copy_identifier,
1022
         16,
1023
         LIBFGUID_ENDIAN_LITTLE,
1024
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1025
         error ) != 1 )
1026
    {
1027
      libcerror_error_set(
1028
       error,
1029
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1030
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1031
       "%s: unable to print GUID value.",
1032
       function );
1033
1034
      goto on_error;
1035
    }
1036
    if( libvshadow_debug_print_guid_value(
1037
         function,
1038
         "copy set identifier\t",
1039
         ( (vshadow_store_information_t *) store_header_data )->copy_set_identifier,
1040
         16,
1041
         LIBFGUID_ENDIAN_LITTLE,
1042
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1043
         error ) != 1 )
1044
    {
1045
      libcerror_error_set(
1046
       error,
1047
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1048
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1049
       "%s: unable to print GUID value.",
1050
       function );
1051
1052
      goto on_error;
1053
    }
1054
    byte_stream_copy_to_uint32_little_endian(
1055
     ( (vshadow_store_information_t *) store_header_data )->type,
1056
     value_32bit );
1057
    libcnotify_printf(
1058
     "%s: type\t\t\t: 0x%08" PRIx32 "\n",
1059
     function,
1060
     value_32bit );
1061
1062
    byte_stream_copy_to_uint32_little_endian(
1063
     ( (vshadow_store_information_t *) store_header_data )->provider,
1064
     value_32bit );
1065
    libcnotify_printf(
1066
     "%s: provider\t\t\t: %" PRIu32 "\n",
1067
     function,
1068
     value_32bit );
1069
1070
    libcnotify_printf(
1071
     "%s: attribute flags\t\t: 0x%08" PRIx32 "\n",
1072
     function,
1073
     store_descriptor->attribute_flags );
1074
    libvshadow_debug_print_attribute_flags(
1075
     store_descriptor->attribute_flags );
1076
    libcnotify_printf(
1077
     "\n" );
1078
1079
    byte_stream_copy_to_uint32_little_endian(
1080
     ( (vshadow_store_information_t *) store_header_data )->unknown10,
1081
     value_32bit );
1082
    libcnotify_printf(
1083
     "%s: unknown10\t\t: 0x%08" PRIx32 "\n",
1084
     function,
1085
     value_32bit );
1086
  }
1087
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1088
1089
105
  store_header_data_offset = sizeof( vshadow_store_information_t );
1090
1091
105
  byte_stream_copy_to_uint16_little_endian(
1092
105
   &( store_header_data[ store_header_data_offset ] ),
1093
105
   store_descriptor->operating_machine_string_size );
1094
1095
105
  store_header_data_offset += 2;
1096
1097
105
  if( store_descriptor->operating_machine_string_size > 0 )
1098
82
  {
1099
82
    if( store_descriptor->operating_machine_string_size > ( store_block->data_size - sizeof( vshadow_store_header_t ) - store_header_data_offset ) )
1100
6
    {
1101
6
      libcerror_error_set(
1102
6
       error,
1103
6
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1104
6
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1105
6
       "%s: invalid operating machine string size value out of bounds.",
1106
6
       function );
1107
1108
6
      goto on_error;
1109
6
    }
1110
76
    store_descriptor->operating_machine_string = (uint8_t *) memory_allocate(
1111
76
                                                              sizeof( uint8_t ) * store_descriptor->operating_machine_string_size );
1112
1113
76
    if( store_descriptor->operating_machine_string == NULL )
1114
0
    {
1115
0
      libcerror_error_set(
1116
0
       error,
1117
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1118
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1119
0
       "%s: unable to create operating machine string.",
1120
0
       function );
1121
1122
0
      goto on_error;
1123
0
    }
1124
76
    if( memory_copy(
1125
76
         store_descriptor->operating_machine_string,
1126
76
         &( store_header_data[ store_header_data_offset ] ),
1127
76
         (size_t) store_descriptor->operating_machine_string_size ) == NULL )
1128
0
    {
1129
0
      libcerror_error_set(
1130
0
       error,
1131
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1132
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1133
0
       "%s: unable to copy operating machine string.",
1134
0
       function );
1135
1136
0
      goto on_error;
1137
0
    }
1138
76
    store_header_data_offset += store_descriptor->operating_machine_string_size;
1139
1140
#if defined( HAVE_DEBUG_OUTPUT )
1141
    if( libcnotify_verbose != 0 )
1142
    {
1143
      if( libvshadow_debug_print_utf16_string_value(
1144
           function,
1145
           "operating machine string\t",
1146
           store_descriptor->operating_machine_string,
1147
           (size_t) store_descriptor->operating_machine_string_size,
1148
           LIBUNA_ENDIAN_LITTLE,
1149
           error ) != 1 )
1150
      {
1151
        libcerror_error_set(
1152
         error,
1153
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1154
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1155
         "%s: unable to print UTF-16 string value.",
1156
         function );
1157
1158
        goto on_error;
1159
      }
1160
    }
1161
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1162
76
  }
1163
99
  if( store_header_data_offset > ( store_block->data_size - sizeof( vshadow_store_header_t ) - 2 ) )
1164
1
  {
1165
1
    libcerror_error_set(
1166
1
     error,
1167
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1168
1
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1169
1
     "%s: invalid store header data size value out of bounds.",
1170
1
     function );
1171
1172
1
    goto on_error;
1173
1
  }
1174
98
  byte_stream_copy_to_uint16_little_endian(
1175
98
   &( store_header_data[ store_header_data_offset ] ),
1176
98
   store_descriptor->service_machine_string_size );
1177
1178
98
  store_header_data_offset += 2;
1179
1180
98
  if( store_descriptor->service_machine_string_size > 0 )
1181
59
  {
1182
59
    if( store_descriptor->service_machine_string_size > ( store_block->data_size - sizeof( vshadow_store_header_t ) - store_header_data_offset ) )
1183
10
    {
1184
10
      libcerror_error_set(
1185
10
       error,
1186
10
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1187
10
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1188
10
       "%s: invalid operating machine string size value out of bounds.",
1189
10
       function );
1190
1191
10
      goto on_error;
1192
10
    }
1193
49
    store_descriptor->service_machine_string = (uint8_t *) memory_allocate(
1194
49
                                                            sizeof( uint8_t ) * store_descriptor->service_machine_string_size );
1195
1196
49
    if( store_descriptor->service_machine_string == NULL )
1197
0
    {
1198
0
      libcerror_error_set(
1199
0
       error,
1200
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1201
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1202
0
       "%s: unable to create service machine string.",
1203
0
       function );
1204
1205
0
      goto on_error;
1206
0
    }
1207
49
    if( memory_copy(
1208
49
         store_descriptor->service_machine_string,
1209
49
         &( store_header_data[ store_header_data_offset ] ),
1210
49
         (size_t) store_descriptor->service_machine_string_size ) == NULL )
1211
0
    {
1212
0
      libcerror_error_set(
1213
0
       error,
1214
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1215
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1216
0
       "%s: unable to copy service machine string.",
1217
0
       function );
1218
1219
0
      goto on_error;
1220
0
    }
1221
49
    store_header_data_offset += store_descriptor->service_machine_string_size;
1222
1223
#if defined( HAVE_DEBUG_OUTPUT )
1224
    if( libcnotify_verbose != 0 )
1225
    {
1226
      if( libvshadow_debug_print_utf16_string_value(
1227
           function,
1228
           "service machine string\t",
1229
           store_descriptor->service_machine_string,
1230
           (size_t) store_descriptor->service_machine_string_size,
1231
           LIBUNA_ENDIAN_LITTLE,
1232
           error ) != 1 )
1233
      {
1234
        libcerror_error_set(
1235
         error,
1236
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1237
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1238
         "%s: unable to print UTF-16 string value.",
1239
         function );
1240
1241
        goto on_error;
1242
      }
1243
    }
1244
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1245
49
  }
1246
#if defined( HAVE_DEBUG_OUTPUT )
1247
  if( libcnotify_verbose != 0 )
1248
  {
1249
    if( store_header_data_offset < ( store_block->data_size - sizeof( vshadow_store_header_t ) ) )
1250
    {
1251
      libcnotify_printf(
1252
       "%s: trailing data:\n",
1253
       function );
1254
      libcnotify_print_data(
1255
       &( store_header_data[ store_header_data_offset ] ),
1256
       store_block->data_size - sizeof( vshadow_store_header_t ) - store_header_data_offset,
1257
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1258
    }
1259
  }
1260
#endif
1261
88
  if( libvshadow_store_block_free(
1262
88
       &store_block,
1263
88
       error ) != 1 )
1264
0
  {
1265
0
    libcerror_error_set(
1266
0
     error,
1267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1268
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1269
0
     "%s: unable to free store block.",
1270
0
     function );
1271
1272
0
    goto on_error;
1273
0
  }
1274
#if defined( HAVE_DEBUG_OUTPUT )
1275
  if( libcnotify_verbose != 0 )
1276
  {
1277
    libcnotify_printf(
1278
     "\n" );
1279
  }
1280
#endif
1281
88
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
1282
88
  if( libcthreads_read_write_lock_release_for_write(
1283
88
       store_descriptor->read_write_lock,
1284
88
       error ) != 1 )
1285
0
  {
1286
0
    libcerror_error_set(
1287
0
     error,
1288
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1289
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1290
0
     "%s: unable to release read/write lock for writing.",
1291
0
     function );
1292
1293
0
    return( -1 );
1294
0
  }
1295
88
#endif
1296
88
  return( 1 );
1297
1298
139
on_error:
1299
139
  if( store_block != NULL )
1300
139
  {
1301
139
    libvshadow_store_block_free(
1302
139
     &store_block,
1303
139
     NULL );
1304
139
  }
1305
139
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
1306
139
  libcthreads_read_write_lock_release_for_write(
1307
139
   store_descriptor->read_write_lock,
1308
139
   NULL );
1309
139
#endif
1310
139
  return( -1 );
1311
88
}
1312
1313
/* Reads the store bitmap
1314
 * This function is not multi-thread safe acquire write lock before call
1315
 * Returns 1 if successful or -1 on error
1316
 */
1317
int libvshadow_store_descriptor_read_store_bitmap(
1318
     libvshadow_store_descriptor_t *store_descriptor,
1319
     libbfio_handle_t *file_io_handle,
1320
     off64_t file_offset,
1321
     libcdata_range_list_t *offset_list,
1322
     off64_t *bitmap_offset,
1323
     off64_t *next_offset,
1324
     libcerror_error_t **error )
1325
0
{
1326
0
  libvshadow_store_block_t *store_block = NULL;
1327
0
  static char *function                 = "libvshadow_store_descriptor_read_store_bitmap";
1328
0
  size_t block_data_offset              = 0;
1329
0
  off64_t safe_bitmap_offset            = 0;
1330
0
  off64_t safe_next_offset              = 0;
1331
0
  off64_t start_offset                  = 0;
1332
0
  uint32_t value_32bit                  = 0;
1333
0
  uint8_t bit_index                     = 0;
1334
0
  int result                            = 0;
1335
1336
0
  if( store_descriptor == NULL )
1337
0
  {
1338
0
    libcerror_error_set(
1339
0
     error,
1340
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1341
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1342
0
     "%s: invalid store descriptor.",
1343
0
     function );
1344
1345
0
    return( -1 );
1346
0
  }
1347
0
  if( bitmap_offset == NULL )
1348
0
  {
1349
0
    libcerror_error_set(
1350
0
     error,
1351
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1352
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1353
0
     "%s: invalid bitmap offset.",
1354
0
     function );
1355
1356
0
    return( -1 );
1357
0
  }
1358
0
  if( next_offset == NULL )
1359
0
  {
1360
0
    libcerror_error_set(
1361
0
     error,
1362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1364
0
     "%s: invalid next offset.",
1365
0
     function );
1366
1367
0
    return( -1 );
1368
0
  }
1369
0
  safe_bitmap_offset = *bitmap_offset;
1370
0
  safe_next_offset   = *next_offset;
1371
1372
0
  if( libvshadow_store_block_initialize(
1373
0
       &store_block,
1374
0
       0x4000,
1375
0
       error ) != 1 )
1376
0
  {
1377
0
    libcerror_error_set(
1378
0
     error,
1379
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1380
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1381
0
     "%s: unable to create store block.",
1382
0
     function );
1383
1384
0
    goto on_error;
1385
0
  }
1386
0
  if( libvshadow_store_block_read(
1387
0
       store_block,
1388
0
       file_io_handle,
1389
0
       file_offset,
1390
0
       error ) == -1 )
1391
0
  {
1392
0
    libcerror_error_set(
1393
0
     error,
1394
0
     LIBCERROR_ERROR_DOMAIN_IO,
1395
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1396
0
     "%s: unable to read store block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1397
0
     function,
1398
0
     file_offset,
1399
0
     file_offset );
1400
1401
0
    goto on_error;
1402
0
  }
1403
0
  if( store_block->record_type != LIBVSHADOW_RECORD_TYPE_STORE_BITMAP )
1404
0
  {
1405
0
    libcerror_error_set(
1406
0
     error,
1407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1408
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1409
0
     "%s: unsupported record type: %" PRIu32 ".",
1410
0
     function,
1411
0
     store_block->record_type );
1412
1413
0
    goto on_error;
1414
0
  }
1415
0
  safe_next_offset = store_block->next_offset;
1416
1417
0
  block_data_offset = sizeof( vshadow_store_block_header_t );
1418
1419
#if defined( HAVE_DEBUG_OUTPUT )
1420
  if( libcnotify_verbose != 0 )
1421
  {
1422
    libcnotify_printf(
1423
     "%s: store: %02d block bitmap:\n",
1424
     function,
1425
     store_descriptor->index );
1426
    libcnotify_print_data(
1427
     &( store_block->data[ block_data_offset ] ),
1428
     store_block->data_size - sizeof( vshadow_store_block_header_t ),
1429
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1430
  }
1431
#endif
1432
0
  start_offset = -1;
1433
1434
0
  while( block_data_offset < store_block->data_size )
1435
0
  {
1436
0
    byte_stream_copy_to_uint32_little_endian(
1437
0
     &( store_block->data[ block_data_offset ] ),
1438
0
     value_32bit );
1439
1440
0
    for( bit_index = 0;
1441
0
         bit_index < 32;
1442
0
         bit_index++ )
1443
0
    {
1444
0
      if( ( value_32bit & 0x00000001UL ) == 0 )
1445
0
      {
1446
0
        if( start_offset >= 0 )
1447
0
        {
1448
#if defined( HAVE_DEBUG_OUTPUT )
1449
          if( libcnotify_verbose != 0 )
1450
          {
1451
            libcnotify_printf(
1452
             "%s: store: %02d offset range\t: 0x%08" PRIx64 " - 0x%08" PRIx64 " (0x%08" PRIx64 ")\n",
1453
             function,
1454
             store_descriptor->index,
1455
             start_offset,
1456
             safe_bitmap_offset,
1457
             safe_bitmap_offset - start_offset );
1458
          }
1459
#endif
1460
0
          result = libcdata_range_list_insert_range(
1461
0
                    offset_list,
1462
0
                    (uint64_t) start_offset,
1463
0
                    (uint64_t) ( safe_bitmap_offset - start_offset ),
1464
0
                    NULL,
1465
0
                    NULL,
1466
0
                    NULL,
1467
0
                    error );
1468
1469
0
          if( result == -1 )
1470
0
          {
1471
0
            libcerror_error_set(
1472
0
             error,
1473
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1474
0
             LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1475
0
             "%s: unable to insert offset range to offset list.",
1476
0
             function );
1477
1478
0
            goto on_error;
1479
0
          }
1480
0
          start_offset = -1;
1481
0
        }
1482
0
      }
1483
0
      else
1484
0
      {
1485
0
        if( start_offset < 0 )
1486
0
        {
1487
0
          start_offset = safe_bitmap_offset;
1488
0
        }
1489
0
      }
1490
0
      safe_bitmap_offset += 0x4000;
1491
1492
0
      value_32bit >>= 1;
1493
0
    }
1494
0
    block_data_offset += 4;
1495
0
  }
1496
0
  if( start_offset >= 0 )
1497
0
  {
1498
#if defined( HAVE_DEBUG_OUTPUT )
1499
    if( libcnotify_verbose != 0 )
1500
    {
1501
      libcnotify_printf(
1502
       "%s: store: %02d offset range\t: 0x%08" PRIx64 " - 0x%08" PRIx64 " (0x%08" PRIx64 ")\n",
1503
       function,
1504
       store_descriptor->index,
1505
       start_offset,
1506
       safe_bitmap_offset,
1507
       safe_bitmap_offset - start_offset );
1508
    }
1509
#endif
1510
0
    result = libcdata_range_list_insert_range(
1511
0
              offset_list,
1512
0
              (uint64_t) start_offset,
1513
0
              (uint64_t) ( safe_bitmap_offset - start_offset ),
1514
0
              NULL,
1515
0
              NULL,
1516
0
              NULL,
1517
0
              error );
1518
1519
0
    if( result == -1 )
1520
0
    {
1521
0
      libcerror_error_set(
1522
0
       error,
1523
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1524
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1525
0
       "%s: unable to append offset range to offset list.",
1526
0
       function );
1527
1528
0
      goto on_error;
1529
0
    }
1530
0
  }
1531
0
  if( libvshadow_store_block_free(
1532
0
       &store_block,
1533
0
       error ) != 1 )
1534
0
  {
1535
0
    libcerror_error_set(
1536
0
     error,
1537
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1538
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1539
0
     "%s: unable to free store block.",
1540
0
     function );
1541
1542
0
    goto on_error;
1543
0
  }
1544
#if defined( HAVE_DEBUG_OUTPUT )
1545
  if( libcnotify_verbose != 0 )
1546
  {
1547
    libcnotify_printf(
1548
     "\n" );
1549
  }
1550
#endif
1551
0
  *bitmap_offset = safe_bitmap_offset;
1552
0
  *next_offset   = safe_next_offset;
1553
1554
0
  return( 1 );
1555
1556
0
on_error:
1557
0
  if( store_block != NULL )
1558
0
  {
1559
0
    libvshadow_store_block_free(
1560
0
     &store_block,
1561
0
     NULL );
1562
0
  }
1563
0
  return( -1 );
1564
0
}
1565
1566
/* Reads the store block list
1567
 * This function is not multi-thread safe acquire write lock before call
1568
 * Returns 1 if successful or -1 on error
1569
 */
1570
int libvshadow_store_descriptor_read_store_block_list(
1571
     libvshadow_store_descriptor_t *store_descriptor,
1572
     libbfio_handle_t *file_io_handle,
1573
     off64_t file_offset,
1574
     off64_t *next_offset,
1575
     libcerror_error_t **error )
1576
0
{
1577
0
  libvshadow_block_descriptor_t *block_descriptor = NULL;
1578
0
  libvshadow_store_block_t *store_block           = NULL;
1579
0
  static char *function                           = "libvshadow_store_descriptor_read_store_block_list";
1580
0
  size_t block_data_offset                        = 0;
1581
0
  int result                                      = 0;
1582
1583
0
  if( store_descriptor == NULL )
1584
0
  {
1585
0
    libcerror_error_set(
1586
0
     error,
1587
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1588
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1589
0
     "%s: invalid store descriptor.",
1590
0
     function );
1591
1592
0
    return( -1 );
1593
0
  }
1594
0
  if( next_offset == NULL )
1595
0
  {
1596
0
    libcerror_error_set(
1597
0
     error,
1598
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1599
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1600
0
     "%s: invalid next offset.",
1601
0
     function );
1602
1603
0
    return( -1 );
1604
0
  }
1605
0
  if( libvshadow_store_block_initialize(
1606
0
       &store_block,
1607
0
       0x4000,
1608
0
       error ) != 1 )
1609
0
  {
1610
0
    libcerror_error_set(
1611
0
     error,
1612
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1613
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1614
0
     "%s: unable to create store block.",
1615
0
     function );
1616
1617
0
    goto on_error;
1618
0
  }
1619
0
  if( libvshadow_store_block_read(
1620
0
       store_block,
1621
0
       file_io_handle,
1622
0
       file_offset,
1623
0
       error ) == -1 )
1624
0
  {
1625
0
    libcerror_error_set(
1626
0
     error,
1627
0
     LIBCERROR_ERROR_DOMAIN_IO,
1628
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1629
0
     "%s: unable to read store block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1630
0
     function,
1631
0
     file_offset,
1632
0
     file_offset );
1633
1634
0
    goto on_error;
1635
0
  }
1636
0
  if( store_block->record_type != LIBVSHADOW_RECORD_TYPE_STORE_INDEX )
1637
0
  {
1638
0
    libcerror_error_set(
1639
0
     error,
1640
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1641
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1642
0
     "%s: unsupported record type: %" PRIu32 ".",
1643
0
     function,
1644
0
     store_block->record_type );
1645
1646
0
    goto on_error;
1647
0
  }
1648
0
  *next_offset = store_block->next_offset;
1649
1650
0
  block_data_offset = sizeof( vshadow_store_block_header_t );
1651
1652
0
  while( block_data_offset <= ( store_block->data_size - sizeof( vshadow_store_block_list_entry_t ) ) )
1653
0
  {
1654
0
    if( libvshadow_block_descriptor_initialize(
1655
0
         &block_descriptor,
1656
0
         error ) != 1 )
1657
0
    {
1658
0
      libcerror_error_set(
1659
0
       error,
1660
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1661
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1662
0
       "%s: unable to create block descriptor.",
1663
0
       function );
1664
1665
0
      goto on_error;
1666
0
    }
1667
0
    result = libvshadow_block_descriptor_read_data(
1668
0
        block_descriptor,
1669
0
              &( store_block->data[ block_data_offset ] ),
1670
0
        store_block->data_size - block_data_offset,
1671
0
        store_descriptor->index,
1672
0
        error );
1673
1674
0
    if( result == -1 )
1675
0
    {
1676
0
      libcerror_error_set(
1677
0
       error,
1678
0
       LIBCERROR_ERROR_DOMAIN_IO,
1679
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1680
0
       "%s: unable to read block descriptor.",
1681
0
       function );
1682
1683
0
      goto on_error;
1684
0
    }
1685
0
    else if( result != 0 )
1686
0
    {
1687
0
      if( libvshadow_block_tree_insert(
1688
0
           store_descriptor->forward_block_tree,
1689
0
           store_descriptor->reverse_block_tree,
1690
0
           block_descriptor,
1691
0
           store_descriptor->index,
1692
0
           error ) != 1 )
1693
0
      {
1694
0
        libcerror_error_set(
1695
0
         error,
1696
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1697
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1698
0
         "%s: unable to insert block descriptor in tree.",
1699
0
         function );
1700
1701
0
        goto on_error;
1702
0
      }
1703
0
      if( libcdata_list_append_value(
1704
0
           store_descriptor->block_descriptors_list,
1705
0
           (intptr_t *) block_descriptor,
1706
0
           error ) != 1 )
1707
0
      {
1708
0
        libcerror_error_set(
1709
0
         error,
1710
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1711
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1712
0
         "%s: unable to append block descriptor to list.",
1713
0
         function );
1714
1715
0
        goto on_error;
1716
0
      }
1717
0
      block_descriptor = NULL;
1718
0
    }
1719
0
    if( block_descriptor != NULL )
1720
0
    {
1721
0
      if( libvshadow_block_descriptor_free(
1722
0
           &block_descriptor,
1723
0
           error ) != 1 )
1724
0
      {
1725
0
        libcerror_error_set(
1726
0
         error,
1727
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1728
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1729
0
         "%s: unable to free block descriptor.",
1730
0
         function );
1731
1732
0
        block_descriptor = NULL;
1733
1734
0
        goto on_error;
1735
0
      }
1736
0
      block_descriptor = NULL;
1737
0
    }
1738
0
    block_data_offset += sizeof( vshadow_store_block_list_entry_t );
1739
0
  }
1740
0
  if( libvshadow_store_block_free(
1741
0
       &store_block,
1742
0
       error ) != 1 )
1743
0
  {
1744
0
    libcerror_error_set(
1745
0
     error,
1746
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1747
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1748
0
     "%s: unable to free store block.",
1749
0
     function );
1750
1751
0
    goto on_error;
1752
0
  }
1753
0
  return( 1 );
1754
1755
0
on_error:
1756
0
  if( block_descriptor != NULL )
1757
0
  {
1758
0
    libvshadow_block_descriptor_free(
1759
0
     &block_descriptor,
1760
0
     NULL );
1761
0
  }
1762
0
  if( store_block != NULL )
1763
0
  {
1764
0
    libvshadow_store_block_free(
1765
0
     &store_block,
1766
0
     NULL );
1767
0
  }
1768
0
  return( -1 );
1769
0
}
1770
1771
/* Reads the store block range list
1772
 * This function is not multi-thread safe acquire write lock before call
1773
 * Returns 1 if successful or -1 on error
1774
 */
1775
int libvshadow_store_descriptor_read_store_block_range_list(
1776
     libvshadow_store_descriptor_t *store_descriptor,
1777
     libbfio_handle_t *file_io_handle,
1778
     off64_t file_offset,
1779
     off64_t *next_offset,
1780
     libcerror_error_t **error )
1781
0
{
1782
0
  libvshadow_block_range_descriptor_t *block_range_descriptor = NULL;
1783
0
  libvshadow_store_block_t *store_block                       = NULL;
1784
0
  static char *function                                       = "libvshadow_store_descriptor_read_store_block_range_list";
1785
0
  size_t block_data_offset                                    = 0;
1786
0
  int result                                                  = 0;
1787
1788
0
  if( store_descriptor == NULL )
1789
0
  {
1790
0
    libcerror_error_set(
1791
0
     error,
1792
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1793
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1794
0
     "%s: invalid store descriptor.",
1795
0
     function );
1796
1797
0
    return( -1 );
1798
0
  }
1799
0
  if( next_offset == NULL )
1800
0
  {
1801
0
    libcerror_error_set(
1802
0
     error,
1803
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1804
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1805
0
     "%s: invalid next offset.",
1806
0
     function );
1807
1808
0
    return( -1 );
1809
0
  }
1810
0
  if( libvshadow_store_block_initialize(
1811
0
       &store_block,
1812
0
       0x4000,
1813
0
       error ) != 1 )
1814
0
  {
1815
0
    libcerror_error_set(
1816
0
     error,
1817
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1818
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1819
0
     "%s: unable to create store block.",
1820
0
     function );
1821
1822
0
    goto on_error;
1823
0
  }
1824
0
  if( libvshadow_store_block_read(
1825
0
       store_block,
1826
0
       file_io_handle,
1827
0
       file_offset,
1828
0
       error ) == -1 )
1829
0
  {
1830
0
    libcerror_error_set(
1831
0
     error,
1832
0
     LIBCERROR_ERROR_DOMAIN_IO,
1833
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1834
0
     "%s: unable to read store block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1835
0
     function,
1836
0
     file_offset,
1837
0
     file_offset );
1838
1839
0
    goto on_error;
1840
0
  }
1841
0
  if( store_block->record_type != LIBVSHADOW_RECORD_TYPE_STORE_BLOCK_RANGE )
1842
0
  {
1843
0
    libcerror_error_set(
1844
0
     error,
1845
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1846
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1847
0
     "%s: unsupported record type: %" PRIu32 ".",
1848
0
     function,
1849
0
     store_block->record_type );
1850
1851
0
    goto on_error;
1852
0
  }
1853
0
  *next_offset = store_block->next_offset;
1854
1855
0
  block_data_offset = sizeof( vshadow_store_block_header_t );
1856
1857
0
  while( block_data_offset <= ( store_block->data_size - sizeof( vshadow_store_block_range_list_entry_t ) ) )
1858
0
  {
1859
0
    if( libvshadow_block_range_descriptor_initialize(
1860
0
         &block_range_descriptor,
1861
0
         error ) != 1 )
1862
0
    {
1863
0
      libcerror_error_set(
1864
0
       error,
1865
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1866
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1867
0
       "%s: unable to create block range descriptor.",
1868
0
       function );
1869
1870
0
      goto on_error;
1871
0
    }
1872
0
    result = libvshadow_block_range_descriptor_read_data(
1873
0
        block_range_descriptor,
1874
0
              &( store_block->data[ block_data_offset ] ),
1875
0
        store_block->data_size - block_data_offset,
1876
0
        store_descriptor->index,
1877
0
        error );
1878
1879
0
    if( result == -1 )
1880
0
    {
1881
0
      libcerror_error_set(
1882
0
       error,
1883
0
       LIBCERROR_ERROR_DOMAIN_IO,
1884
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1885
0
       "%s: unable to read block range descriptor.",
1886
0
       function );
1887
1888
0
      goto on_error;
1889
0
    }
1890
0
    else if( result != 0 )
1891
0
    {
1892
/* TODO do something useful with the range descriptors */
1893
0
    }
1894
0
    if( block_range_descriptor != NULL )
1895
0
    {
1896
0
      if( libvshadow_block_range_descriptor_free(
1897
0
           &block_range_descriptor,
1898
0
           error ) != 1 )
1899
0
      {
1900
0
        libcerror_error_set(
1901
0
         error,
1902
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1903
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1904
0
         "%s: unable to free block range descriptor.",
1905
0
         function );
1906
1907
0
        block_range_descriptor = NULL;
1908
1909
0
        goto on_error;
1910
0
      }
1911
0
      block_range_descriptor = NULL;
1912
0
    }
1913
0
    block_data_offset += sizeof( vshadow_store_block_range_list_entry_t );
1914
0
  }
1915
0
  if( libvshadow_store_block_free(
1916
0
       &store_block,
1917
0
       error ) != 1 )
1918
0
  {
1919
0
    libcerror_error_set(
1920
0
     error,
1921
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1922
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1923
0
     "%s: unable to free store block.",
1924
0
     function );
1925
1926
0
    goto on_error;
1927
0
  }
1928
0
  return( 1 );
1929
1930
0
on_error:
1931
0
  if( block_range_descriptor != NULL )
1932
0
  {
1933
0
    libvshadow_block_range_descriptor_free(
1934
0
     &block_range_descriptor,
1935
0
     NULL );
1936
0
  }
1937
0
  if( store_block != NULL )
1938
0
  {
1939
0
    libvshadow_store_block_free(
1940
0
     &store_block,
1941
0
     NULL );
1942
0
  }
1943
0
  return( -1 );
1944
0
}
1945
1946
/* Reads the block descriptors
1947
 * Returns 1 if successful or -1 on error
1948
 */
1949
int libvshadow_store_descriptor_read_block_descriptors(
1950
     libvshadow_store_descriptor_t *store_descriptor,
1951
     libvshadow_io_handle_t *io_handle,
1952
     libbfio_handle_t *file_io_handle,
1953
     libcerror_error_t **error )
1954
0
{
1955
0
  libvshadow_block_tree_t *store_block_tree = NULL;
1956
0
  static char *function                     = "libvshadow_store_descriptor_read_block_descriptors";
1957
0
  off64_t bitmap_offset                     = 0;
1958
0
  off64_t store_block_offset                = 0;
1959
1960
0
  if( store_descriptor == NULL )
1961
0
  {
1962
0
    libcerror_error_set(
1963
0
     error,
1964
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1965
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1966
0
     "%s: invalid store descriptor.",
1967
0
     function );
1968
1969
0
    return( -1 );
1970
0
  }
1971
0
  if( io_handle == NULL )
1972
0
  {
1973
0
    libcerror_error_set(
1974
0
     error,
1975
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1976
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1977
0
     "%s: invalid IO handle.",
1978
0
     function );
1979
1980
0
    return( -1 );
1981
0
  }
1982
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
1983
0
  if( libcthreads_read_write_lock_grab_for_write(
1984
0
       store_descriptor->read_write_lock,
1985
0
       error ) != 1 )
1986
0
  {
1987
0
    libcerror_error_set(
1988
0
     error,
1989
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1990
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1991
0
     "%s: unable to grab read/write lock for writing.",
1992
0
     function );
1993
1994
0
    return( -1 );
1995
0
  }
1996
0
#endif
1997
0
  if( store_descriptor->block_descriptors_read == 0 )
1998
0
  {
1999
0
    if( libvshadow_block_tree_initialize(
2000
0
         &( store_descriptor->forward_block_tree ),
2001
0
         store_descriptor->volume_size,
2002
0
         0x4000,
2003
0
         error ) != 1 )
2004
0
    {
2005
0
      libcerror_error_set(
2006
0
       error,
2007
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2008
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2009
0
       "%s: unable to create forward block tree.",
2010
0
       function );
2011
2012
0
      goto on_error;
2013
0
    }
2014
0
    if( libvshadow_block_tree_initialize(
2015
0
         &( store_descriptor->reverse_block_tree ),
2016
0
         store_descriptor->volume_size,
2017
0
         0x4000,
2018
0
         error ) != 1 )
2019
0
    {
2020
0
      libcerror_error_set(
2021
0
       error,
2022
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2023
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2024
0
       "%s: unable to create reverse block tree.",
2025
0
       function );
2026
2027
0
      goto on_error;
2028
0
    }
2029
0
    if( libvshadow_block_tree_initialize(
2030
0
         &store_block_tree,
2031
0
         io_handle->volume_size,
2032
0
         io_handle->block_size,
2033
0
         error ) != 1 )
2034
0
    {
2035
0
      libcerror_error_set(
2036
0
       error,
2037
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2038
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2039
0
       "%s: unable to create store block tree.",
2040
0
       function );
2041
2042
0
      goto on_error;
2043
0
    }
2044
0
    bitmap_offset      = 0;
2045
0
    store_block_offset = store_descriptor->store_bitmap_offset;
2046
2047
0
    while( store_block_offset != 0 )
2048
0
    {
2049
0
      if( libvshadow_io_handle_check_if_block_first_read(
2050
0
           io_handle,
2051
0
           store_block_tree,
2052
0
           store_block_offset,
2053
0
           error ) != 1 )
2054
0
      {
2055
0
        libcerror_error_set(
2056
0
         error,
2057
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2058
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
2059
0
         "%s: unable to check if first read of store bitmap block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2060
0
         function,
2061
0
         store_block_offset,
2062
0
         store_block_offset );
2063
2064
0
        goto on_error;
2065
0
      }
2066
0
      if( libvshadow_store_descriptor_read_store_bitmap(
2067
0
           store_descriptor,
2068
0
           file_io_handle,
2069
0
           store_block_offset,
2070
0
           store_descriptor->block_offset_list,
2071
0
           &bitmap_offset,
2072
0
           &store_block_offset,
2073
0
           error ) != 1 )
2074
0
      {
2075
0
        libcerror_error_set(
2076
0
         error,
2077
0
         LIBCERROR_ERROR_DOMAIN_IO,
2078
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2079
0
         "%s: unable to read store bitmap.",
2080
0
         function );
2081
2082
0
        goto on_error;
2083
0
      }
2084
0
    }
2085
0
    bitmap_offset      = 0;
2086
0
    store_block_offset = store_descriptor->store_previous_bitmap_offset;
2087
2088
0
    while( store_block_offset != 0 )
2089
0
    {
2090
0
      if( libvshadow_io_handle_check_if_block_first_read(
2091
0
           io_handle,
2092
0
           store_block_tree,
2093
0
           store_block_offset,
2094
0
           error ) != 1 )
2095
0
      {
2096
0
        libcerror_error_set(
2097
0
         error,
2098
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2099
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
2100
0
         "%s: unable to check if first read of store previous bitmap block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2101
0
         function,
2102
0
         store_block_offset,
2103
0
         store_block_offset );
2104
2105
0
        goto on_error;
2106
0
      }
2107
0
      if( libvshadow_store_descriptor_read_store_bitmap(
2108
0
           store_descriptor,
2109
0
           file_io_handle,
2110
0
           store_block_offset,
2111
0
           store_descriptor->previous_block_offset_list,
2112
0
           &bitmap_offset,
2113
0
           &store_block_offset,
2114
0
           error ) != 1 )
2115
0
      {
2116
0
        libcerror_error_set(
2117
0
         error,
2118
0
         LIBCERROR_ERROR_DOMAIN_IO,
2119
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2120
0
         "%s: unable to read store previous bitmap.",
2121
0
         function );
2122
2123
0
        goto on_error;
2124
0
      }
2125
0
    }
2126
0
    store_block_offset = store_descriptor->store_block_list_offset;
2127
2128
0
    while( store_block_offset != 0 )
2129
0
    {
2130
0
      if( libvshadow_io_handle_check_if_block_first_read(
2131
0
           io_handle,
2132
0
           store_block_tree,
2133
0
           store_block_offset,
2134
0
           error ) != 1 )
2135
0
      {
2136
0
        libcerror_error_set(
2137
0
         error,
2138
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2139
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
2140
0
         "%s: unable to check if first read of store block list block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2141
0
         function,
2142
0
         store_block_offset,
2143
0
         store_block_offset );
2144
2145
0
        goto on_error;
2146
0
      }
2147
0
      if( libvshadow_store_descriptor_read_store_block_list(
2148
0
           store_descriptor,
2149
0
           file_io_handle,
2150
0
           store_block_offset,
2151
0
           &store_block_offset,
2152
0
           error ) != 1 )
2153
0
      {
2154
0
        libcerror_error_set(
2155
0
         error,
2156
0
         LIBCERROR_ERROR_DOMAIN_IO,
2157
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2158
0
         "%s: unable to read store block list.",
2159
0
         function );
2160
2161
0
        goto on_error;
2162
0
      }
2163
0
    }
2164
0
    store_block_offset = store_descriptor->store_block_range_list_offset;
2165
2166
0
    while( store_block_offset != 0 )
2167
0
    {
2168
0
      if( libvshadow_io_handle_check_if_block_first_read(
2169
0
           io_handle,
2170
0
           store_block_tree,
2171
0
           store_block_offset,
2172
0
           error ) != 1 )
2173
0
      {
2174
0
        libcerror_error_set(
2175
0
         error,
2176
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2177
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
2178
0
         "%s: unable to check if first read of store block range list block at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2179
0
         function,
2180
0
         store_block_offset,
2181
0
         store_block_offset );
2182
2183
0
        goto on_error;
2184
0
      }
2185
0
      if( libvshadow_store_descriptor_read_store_block_range_list(
2186
0
           store_descriptor,
2187
0
           file_io_handle,
2188
0
           store_block_offset,
2189
0
           &store_block_offset,
2190
0
           error ) != 1 )
2191
0
      {
2192
0
        libcerror_error_set(
2193
0
         error,
2194
0
         LIBCERROR_ERROR_DOMAIN_IO,
2195
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2196
0
         "%s: unable to read store block range list.",
2197
0
         function );
2198
2199
0
        goto on_error;
2200
0
      }
2201
0
    }
2202
0
    if( libvshadow_block_tree_free(
2203
0
         &store_block_tree,
2204
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free,
2205
0
         error ) != 1 )
2206
0
    {
2207
0
      libcerror_error_set(
2208
0
       error,
2209
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2210
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2211
0
       "%s: unable to free store block tree.",
2212
0
       function );
2213
2214
0
      goto on_error;
2215
0
    }
2216
0
    store_descriptor->block_descriptors_read = 1;
2217
0
  }
2218
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
2219
0
  if( libcthreads_read_write_lock_release_for_write(
2220
0
       store_descriptor->read_write_lock,
2221
0
       error ) != 1 )
2222
0
  {
2223
0
    libcerror_error_set(
2224
0
     error,
2225
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2226
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2227
0
     "%s: unable to release read/write lock for writing.",
2228
0
     function );
2229
2230
0
    return( -1 );
2231
0
  }
2232
0
#endif
2233
0
  return( 1 );
2234
2235
0
on_error:
2236
0
  if( store_descriptor->block_descriptors_read == 0 )
2237
0
  {
2238
0
    if( store_block_tree != NULL )
2239
0
    {
2240
0
      libvshadow_block_tree_free(
2241
0
       &store_block_tree,
2242
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free,
2243
0
       NULL );
2244
0
    }
2245
0
    if( store_descriptor->reverse_block_tree != NULL )
2246
0
    {
2247
0
      libvshadow_block_tree_free(
2248
0
       &( store_descriptor->reverse_block_tree ),
2249
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free_reverse,
2250
0
       NULL );
2251
0
    }
2252
0
    if( store_descriptor->forward_block_tree != NULL )
2253
0
    {
2254
0
      libvshadow_block_tree_free(
2255
0
       &( store_descriptor->forward_block_tree ),
2256
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_block_descriptor_free,
2257
0
       NULL );
2258
0
    }
2259
0
  }
2260
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
2261
0
  libcthreads_read_write_lock_release_for_write(
2262
0
   store_descriptor->read_write_lock,
2263
0
   NULL );
2264
0
#endif
2265
0
  return( -1 );
2266
0
}
2267
2268
/* Retrieves the block range for a specific offset
2269
 * Returns 1 if successful, 0 if not available or -1 on error
2270
 */
2271
int libvshadow_store_descriptor_get_block_range_at_offset(
2272
     libvshadow_store_descriptor_t *store_descriptor,
2273
     off64_t offset,
2274
     int active_store_descriptor_index,
2275
     libvshadow_block_descriptor_t **block_descriptor,
2276
     size_t *block_size,
2277
     int *in_block_descriptor_list,
2278
     off64_t *block_descriptor_offset,
2279
     libcerror_error_t **error )
2280
0
{
2281
0
  libvshadow_block_descriptor_t *overlay_block_descriptor = NULL;
2282
0
  libvshadow_block_descriptor_t *safe_block_descriptor    = NULL;
2283
0
  static char *function                                   = "libvshadow_store_descriptor_get_block_range_at_offset";
2284
0
  size_t safe_block_size                                  = 0;
2285
0
  off64_t block_offset                                    = 0;
2286
0
  off64_t overlay_block_offset                            = 0;
2287
0
  off64_t safe_block_descriptor_offset                    = 0;
2288
0
  uint32_t overlay_bitmap                                 = 0;
2289
0
  uint32_t relative_block_offset                          = 0;
2290
0
  uint8_t bit_count                                       = 0;
2291
0
  int result                                              = 0;
2292
0
  int safe_in_block_descriptor_list                       = 0;
2293
2294
0
  if( store_descriptor == NULL )
2295
0
  {
2296
0
    libcerror_error_set(
2297
0
     error,
2298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2299
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2300
0
     "%s: invalid store descriptor.",
2301
0
     function );
2302
2303
0
    return( -1 );
2304
0
  }
2305
0
  if( block_descriptor == NULL )
2306
0
  {
2307
0
    libcerror_error_set(
2308
0
     error,
2309
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2310
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2311
0
     "%s: invalid block descriptor.",
2312
0
     function );
2313
2314
0
    return( -1 );
2315
0
  }
2316
0
  if( block_size == NULL )
2317
0
  {
2318
0
    libcerror_error_set(
2319
0
     error,
2320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2322
0
     "%s: invalid block size.",
2323
0
     function );
2324
2325
0
    return( -1 );
2326
0
  }
2327
0
  if( in_block_descriptor_list == NULL )
2328
0
  {
2329
0
    libcerror_error_set(
2330
0
     error,
2331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2333
0
     "%s: invalid in block descriptor list.",
2334
0
     function );
2335
2336
0
    return( -1 );
2337
0
  }
2338
0
  if( block_descriptor_offset == NULL )
2339
0
  {
2340
0
    libcerror_error_set(
2341
0
     error,
2342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2343
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2344
0
     "%s: invalid block descriptor offset.",
2345
0
     function );
2346
2347
0
    return( -1 );
2348
0
  }
2349
0
  if( store_descriptor->current_block_descriptor != NULL )
2350
0
  {
2351
0
    if( ( offset >= store_descriptor->current_block_descriptor->original_offset )
2352
0
     && ( offset < ( store_descriptor->current_block_descriptor->original_offset + 0x4000 ) ) )
2353
0
    {
2354
0
      result = 1;
2355
0
    }
2356
0
  }
2357
0
  if( result == 0 )
2358
0
  {
2359
0
    result = libvshadow_block_tree_get_block_descriptor_by_offset(
2360
0
              store_descriptor->forward_block_tree,
2361
0
              offset,
2362
0
              &safe_block_descriptor,
2363
0
              &block_offset,
2364
0
              error );
2365
2366
0
    if( result == -1 )
2367
0
    {
2368
0
      libcerror_error_set(
2369
0
       error,
2370
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2371
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2372
0
       "%s: unable to retrieve block range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
2373
0
       function,
2374
0
       offset,
2375
0
       offset );
2376
2377
0
      return( -1 );
2378
0
    }
2379
0
    else if( result != 0 )
2380
0
    {
2381
0
      store_descriptor->current_block_descriptor = safe_block_descriptor;
2382
0
    }
2383
0
  }
2384
0
  relative_block_offset = (uint32_t) (offset % 0x4000);
2385
0
  safe_block_size       = 0x4000 - relative_block_offset;
2386
2387
0
  if( result != 0 )
2388
0
  {
2389
0
    if( store_descriptor->current_block_descriptor == NULL )
2390
0
    {
2391
0
      libcerror_error_set(
2392
0
       error,
2393
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2394
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2395
0
       "%s: missing current block descriptor.",
2396
0
       function );
2397
2398
0
      return( -1 );
2399
0
    }
2400
0
    safe_block_descriptor         = store_descriptor->current_block_descriptor;
2401
0
    safe_in_block_descriptor_list = 1;
2402
2403
0
    if( ( safe_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_FORWARDER ) != 0 )
2404
0
    {
2405
0
      safe_block_descriptor_offset = safe_block_descriptor->relative_offset;
2406
0
    }
2407
0
    else
2408
0
    {
2409
0
      safe_block_descriptor_offset = safe_block_descriptor->offset;
2410
0
    }
2411
0
    if( ( safe_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) != 0 )
2412
0
    {
2413
0
      overlay_block_descriptor = safe_block_descriptor;
2414
0
    }
2415
0
    else
2416
0
    {
2417
0
      overlay_block_descriptor = safe_block_descriptor->overlay;
2418
0
    }
2419
0
    if( overlay_block_descriptor != NULL )
2420
0
    {
2421
0
      if( store_descriptor->index != active_store_descriptor_index )
2422
0
      {
2423
0
        if( safe_block_descriptor == overlay_block_descriptor )
2424
0
        {
2425
0
          safe_block_descriptor         = NULL;
2426
0
          safe_in_block_descriptor_list = 0;
2427
0
        }
2428
0
      }
2429
0
      else
2430
0
      {
2431
0
        overlay_block_offset = overlay_block_descriptor->original_offset;
2432
0
        overlay_bitmap       = overlay_block_descriptor->bitmap;
2433
2434
0
        bit_count = 32;
2435
2436
0
        while( overlay_block_offset < offset )
2437
0
        {
2438
0
          overlay_bitmap >>= 1;
2439
2440
0
          overlay_block_offset += 512;
2441
2442
0
          bit_count--;
2443
2444
0
          if( bit_count == 0 )
2445
0
          {
2446
0
            break;
2447
0
          }
2448
0
        }
2449
0
        if( ( overlay_bitmap & 0x00000001UL ) != 0 )
2450
0
        {
2451
0
          safe_block_descriptor_offset = overlay_block_descriptor->offset;
2452
0
          safe_block_descriptor        = overlay_block_descriptor;
2453
2454
0
          safe_block_size = 0;
2455
2456
0
          while( ( overlay_bitmap & 0x00000001UL ) != 0 )
2457
0
          {
2458
0
            overlay_bitmap >>= 1;
2459
2460
0
            safe_block_size += 512;
2461
2462
0
            bit_count--;
2463
2464
0
            if( bit_count == 0 )
2465
0
            {
2466
0
              break;
2467
0
            }
2468
0
          }
2469
0
        }
2470
0
        else
2471
0
        {
2472
0
          if( safe_block_descriptor == overlay_block_descriptor )
2473
0
          {
2474
0
            safe_block_descriptor         = NULL;
2475
0
            safe_in_block_descriptor_list = 0;
2476
0
          }
2477
0
          safe_block_size = 0;
2478
2479
0
          while( ( overlay_bitmap & 0x00000001UL ) == 0 )
2480
0
          {
2481
0
            overlay_bitmap >>= 1;
2482
2483
0
            safe_block_size += 512;
2484
2485
0
            bit_count--;
2486
2487
0
            if( bit_count == 0 )
2488
0
            {
2489
0
              break;
2490
0
            }
2491
0
          }
2492
0
        }
2493
0
      }
2494
0
    }
2495
0
    safe_block_descriptor_offset += relative_block_offset;
2496
0
  }
2497
0
  *block_descriptor         = safe_block_descriptor;
2498
0
  *block_size               = safe_block_size;
2499
0
  *in_block_descriptor_list = safe_in_block_descriptor_list;
2500
0
  *block_descriptor_offset  = safe_block_descriptor_offset;
2501
2502
0
  return( result );
2503
0
}
2504
2505
/* Retrieves the reverse block range for a specific offset
2506
 * Returns 1 if successful, 0 if not available or -1 on error
2507
 */
2508
int libvshadow_store_descriptor_get_reverse_block_range_at_offset(
2509
     libvshadow_store_descriptor_t *store_descriptor,
2510
     off64_t offset,
2511
     int *in_reverse_block_descriptor_list,
2512
     int *in_current_bitmap,
2513
     int *in_previous_bitmap,
2514
     libcerror_error_t **error )
2515
0
{
2516
0
  libvshadow_block_descriptor_t *reverse_block_descriptor = NULL;
2517
0
  intptr_t *value                                         = NULL;
2518
0
  static char *function                                   = "libvshadow_store_descriptor_get_reverse_block_range_at_offset";
2519
0
  size64_t block_range_size                               = 0;
2520
0
  size64_t previous_block_range_size                      = 0;
2521
0
  off64_t block_offset                                    = 0;
2522
0
  off64_t block_range_offset                              = 0;
2523
0
  off64_t previous_block_range_offset                     = 0;
2524
0
  int result                                              = 0;
2525
0
  int safe_in_current_bitmap                              = 0;
2526
0
  int safe_in_previous_bitmap                             = 0;
2527
0
  int safe_in_reverse_block_descriptor_list               = 0;
2528
2529
0
  if( store_descriptor == NULL )
2530
0
  {
2531
0
    libcerror_error_set(
2532
0
     error,
2533
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2534
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2535
0
     "%s: invalid store descriptor.",
2536
0
     function );
2537
2538
0
    return( -1 );
2539
0
  }
2540
0
  if( in_reverse_block_descriptor_list == NULL )
2541
0
  {
2542
0
    libcerror_error_set(
2543
0
     error,
2544
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2545
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2546
0
     "%s: invalid in reverse block descriptor list.",
2547
0
     function );
2548
2549
0
    return( -1 );
2550
0
  }
2551
0
  if( in_current_bitmap == NULL )
2552
0
  {
2553
0
    libcerror_error_set(
2554
0
     error,
2555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2557
0
     "%s: invalid in current bitmap.",
2558
0
     function );
2559
2560
0
    return( -1 );
2561
0
  }
2562
0
  if( in_previous_bitmap == NULL )
2563
0
  {
2564
0
    libcerror_error_set(
2565
0
     error,
2566
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2567
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2568
0
     "%s: invalid in previous bitmap.",
2569
0
     function );
2570
2571
0
    return( -1 );
2572
0
  }
2573
0
  if( store_descriptor->current_reverse_block_descriptor != NULL )
2574
0
  {
2575
0
    if( ( offset >= store_descriptor->current_reverse_block_descriptor->relative_offset )
2576
0
     && ( offset < ( store_descriptor->current_reverse_block_descriptor->relative_offset + 0x4000 ) ) )
2577
0
    {
2578
0
      result = 1;
2579
0
    }
2580
0
  }
2581
0
  if( result == 0 )
2582
0
  {
2583
0
    result = libvshadow_block_tree_get_block_descriptor_by_offset(
2584
0
        store_descriptor->reverse_block_tree,
2585
0
        offset,
2586
0
        &reverse_block_descriptor,
2587
0
        &block_offset,
2588
0
        error );
2589
2590
0
    if( result == -1 )
2591
0
    {
2592
0
      libcerror_error_set(
2593
0
       error,
2594
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2595
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2596
0
       "%s: unable to retrieve reverse block descriptor from tree.",
2597
0
       function );
2598
2599
0
      return( -1 );
2600
0
    }
2601
0
    else if( result != 0 )
2602
0
    {
2603
0
      store_descriptor->current_reverse_block_descriptor = reverse_block_descriptor;
2604
0
    }
2605
0
  }
2606
0
  safe_in_reverse_block_descriptor_list = result;
2607
2608
0
  result = libcdata_range_list_get_range_at_offset(
2609
0
      store_descriptor->block_offset_list,
2610
0
      (uint64_t) offset,
2611
0
      (uint64_t *) &block_range_offset,
2612
0
      (uint64_t *) &block_range_size,
2613
0
      &value,
2614
0
      error );
2615
2616
0
  if( result == -1 )
2617
0
  {
2618
0
    libcerror_error_set(
2619
0
     error,
2620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2621
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2622
0
     "%s: unable to retrieve offset: %" PRIi64 " (0x%08" PRIx64 ") from block offset list.",
2623
0
     function,
2624
0
     offset,
2625
0
     offset );
2626
2627
0
    return( -1 );
2628
0
  }
2629
#if defined( HAVE_DEBUG_OUTPUT )
2630
  else if( result != 0 )
2631
  {
2632
    if( libcnotify_verbose != 0 )
2633
    {
2634
      libcnotify_printf(
2635
       "%s: store: %02d block offset list: 0x%08" PRIx64 " - 0x%08" PRIx64 " (0x%08" PRIx64 ")\n",
2636
       function,
2637
       store_descriptor->index,
2638
       block_range_offset,
2639
       block_range_offset + block_range_size,
2640
       block_range_size );
2641
    }
2642
  }
2643
#endif
2644
0
  safe_in_current_bitmap = result;
2645
2646
0
  if( store_descriptor->store_previous_bitmap_offset == 0 )
2647
0
  {
2648
0
    safe_in_previous_bitmap = 1;
2649
0
  }
2650
0
  else
2651
0
  {
2652
0
    result = libcdata_range_list_get_range_at_offset(
2653
0
        store_descriptor->previous_block_offset_list,
2654
0
        (uint64_t) offset,
2655
0
        (uint64_t *) &previous_block_range_offset,
2656
0
        (uint64_t *) &previous_block_range_size,
2657
0
        &value,
2658
0
        error );
2659
2660
0
    if( result == -1 )
2661
0
    {
2662
0
      libcerror_error_set(
2663
0
       error,
2664
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2665
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2666
0
       "%s: unable to retrieve offset: %" PRIi64 " (0x%08" PRIx64 ") from previous block offset list.",
2667
0
       function,
2668
0
       offset,
2669
0
       offset );
2670
2671
0
      return( -1 );
2672
0
    }
2673
#if defined( HAVE_DEBUG_OUTPUT )
2674
    else if( result != 0 )
2675
    {
2676
      if( libcnotify_verbose != 0 )
2677
      {
2678
        libcnotify_printf(
2679
         "%s: store: %02d previous block offset list: 0x%08" PRIx64 " - 0x%08" PRIx64 " (0x%08" PRIx64 ")\n",
2680
         function,
2681
         store_descriptor->index,
2682
         previous_block_range_offset,
2683
         previous_block_range_offset + previous_block_range_size,
2684
         previous_block_range_size );
2685
      }
2686
    }
2687
#endif
2688
0
    safe_in_previous_bitmap = result;
2689
0
  }
2690
0
  *in_reverse_block_descriptor_list = safe_in_reverse_block_descriptor_list;
2691
0
  *in_current_bitmap                = safe_in_current_bitmap;
2692
0
  *in_previous_bitmap               = safe_in_previous_bitmap;
2693
2694
0
  return( 1 );
2695
0
}
2696
2697
/* Reads data at the specified offset into a buffer
2698
 * Returns the number of bytes read or -1 on error
2699
 */
2700
ssize_t libvshadow_store_descriptor_read_buffer(
2701
         libvshadow_store_descriptor_t *store_descriptor,
2702
         libvshadow_io_handle_t *io_handle,
2703
         libbfio_handle_t *file_io_handle,
2704
         uint8_t *buffer,
2705
         size_t buffer_size,
2706
         off64_t offset,
2707
         int active_store_descriptor_index,
2708
         libcerror_error_t **error )
2709
0
{
2710
0
  libvshadow_block_descriptor_t *block_descriptor = NULL;
2711
0
  static char *function                           = "libvshadow_store_descriptor_read_buffer";
2712
0
  size_t block_size                               = 0;
2713
0
  size_t buffer_offset                            = 0;
2714
0
  size_t read_size                                = 0;
2715
0
  ssize_t read_count                              = 0;
2716
0
  off64_t block_descriptor_offset                 = 0;
2717
0
  int in_block_descriptor_list                    = 0;
2718
0
  int in_current_bitmap                           = 0;
2719
0
  int in_previous_bitmap                          = 0;
2720
0
  int in_reverse_block_descriptor_list            = 0;
2721
0
  int result                                      = 0;
2722
2723
0
  if( store_descriptor == NULL )
2724
0
  {
2725
0
    libcerror_error_set(
2726
0
     error,
2727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2728
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2729
0
     "%s: invalid store descriptor.",
2730
0
     function );
2731
2732
0
    return( -1 );
2733
0
  }
2734
0
  if( store_descriptor->has_in_volume_store_data == 0 )
2735
0
  {
2736
0
    libcerror_error_set(
2737
0
     error,
2738
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2739
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2740
0
     "%s: invalid store descriptor - missing in-volume store data.",
2741
0
     function );
2742
2743
0
    return( -1 );
2744
0
  }
2745
  /* This function will acquire the write lock
2746
   */
2747
0
  if( libvshadow_store_descriptor_read_block_descriptors(
2748
0
       store_descriptor,
2749
0
       io_handle,
2750
0
       file_io_handle,
2751
0
       error ) != 1 )
2752
0
  {
2753
0
    libcerror_error_set(
2754
0
     error,
2755
0
     LIBCERROR_ERROR_DOMAIN_IO,
2756
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2757
0
     "%s: unable to read block descriptors.",
2758
0
     function );
2759
2760
0
    return( -1 );
2761
0
  }
2762
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
2763
0
  if( libcthreads_read_write_lock_grab_for_read(
2764
0
       store_descriptor->read_write_lock,
2765
0
       error ) != 1 )
2766
0
  {
2767
0
    libcerror_error_set(
2768
0
     error,
2769
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2770
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2771
0
     "%s: unable to grab read/write lock for reading.",
2772
0
     function );
2773
2774
0
    return( -1 );
2775
0
  }
2776
0
#endif
2777
0
  while( buffer_size > 0 )
2778
0
  {
2779
#if defined( HAVE_DEBUG_OUTPUT )
2780
    if( libcnotify_verbose != 0 )
2781
    {
2782
      libcnotify_printf(
2783
       "%s: store: %02d requested offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
2784
       function,
2785
       store_descriptor->index,
2786
       offset,
2787
       offset );
2788
    }
2789
#endif
2790
0
    in_reverse_block_descriptor_list = 0;
2791
0
    in_current_bitmap                = 0;
2792
0
    in_previous_bitmap               = 0;
2793
2794
/* TODO determine if block_descriptor_offset can be determined later only when needed */
2795
0
    result = libvshadow_store_descriptor_get_block_range_at_offset(
2796
0
              store_descriptor,
2797
0
              offset,
2798
0
              active_store_descriptor_index,
2799
0
              &block_descriptor,
2800
0
              &block_size,
2801
0
              &in_block_descriptor_list,
2802
0
              &block_descriptor_offset,
2803
0
              error );
2804
2805
0
    if( result == -1 )
2806
0
    {
2807
0
      libcerror_error_set(
2808
0
       error,
2809
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2810
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2811
0
       "%s: unable to retrieve block range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
2812
0
       function,
2813
0
       offset,
2814
0
       offset );
2815
2816
0
      goto on_error;
2817
0
    }
2818
0
    if( in_block_descriptor_list == 0 )
2819
0
    {
2820
      /* Only the most recent store seems to bother checking the current bitmap
2821
       */
2822
0
      if( ( store_descriptor->next_store_descriptor == NULL )
2823
0
       && ( store_descriptor->index == active_store_descriptor_index ) )
2824
0
      {
2825
0
        result = libvshadow_store_descriptor_get_reverse_block_range_at_offset(
2826
0
                  store_descriptor,
2827
0
                  offset,
2828
0
                  &in_reverse_block_descriptor_list,
2829
0
                  &in_current_bitmap,
2830
0
                  &in_previous_bitmap,
2831
0
                  error );
2832
2833
0
        if( result == -1 )
2834
0
        {
2835
0
          libcerror_error_set(
2836
0
           error,
2837
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2838
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2839
0
           "%s: unable to retrieve reverse block range for offset: %" PRIi64 " (0x%08" PRIx64 ").",
2840
0
           function,
2841
0
           offset,
2842
0
           offset );
2843
2844
0
          goto on_error;
2845
0
        }
2846
0
      }
2847
0
    }
2848
0
    if( buffer_size > block_size )
2849
0
    {
2850
0
      read_size = block_size;
2851
0
    }
2852
0
    else
2853
0
    {
2854
0
      read_size = buffer_size;
2855
0
    }
2856
#if defined( HAVE_DEBUG_OUTPUT )
2857
    if( libcnotify_verbose != 0 )
2858
    {
2859
      libcnotify_printf(
2860
       "%s: store: %02d range: 0x%08" PRIx64 " - 0x%08" PRIx64 " size: %" PRIzd "",
2861
       function,
2862
       store_descriptor->index,
2863
       offset,
2864
       offset + block_size,
2865
       block_size );
2866
2867
      if( block_descriptor != NULL )
2868
      {
2869
        libcnotify_printf(
2870
         ", flags: 0x%08" PRIx32 "",
2871
         block_descriptor->flags );
2872
      }
2873
      libcnotify_printf(
2874
       "\n" );
2875
2876
      if( in_block_descriptor_list != 0 )
2877
      {
2878
        libcnotify_printf(
2879
         "\tIn block list\n" );
2880
      }
2881
      if( block_descriptor != NULL )
2882
      {
2883
        if( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) != 0 )
2884
        {
2885
          libcnotify_printf(
2886
           "\tIs overlay\n" );
2887
        }
2888
      }
2889
      if( in_reverse_block_descriptor_list != 0 )
2890
      {
2891
        libcnotify_printf(
2892
         "\tIn reverse block list\n" );
2893
      }
2894
      if( in_current_bitmap != 0 )
2895
      {
2896
        libcnotify_printf(
2897
         "\tIn current bitmap\n" );
2898
      }
2899
      if( ( store_descriptor->store_previous_bitmap_offset != 0 )
2900
       && ( in_previous_bitmap != 0 ) )
2901
      {
2902
        libcnotify_printf(
2903
         "\tIn previous bitmap\n" );
2904
      }
2905
      libcnotify_printf(
2906
       "\n" );
2907
    }
2908
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2909
2910
0
    if( in_block_descriptor_list != 0 )
2911
0
    {
2912
0
      if( ( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_FORWARDER ) != 0 )
2913
0
       && ( store_descriptor->next_store_descriptor != NULL ) )
2914
0
      {
2915
#if defined( HAVE_DEBUG_OUTPUT )
2916
        if( libcnotify_verbose != 0 )
2917
        {
2918
          libcnotify_printf(
2919
           "%s: store: %02d reading block from next store at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
2920
           function,
2921
           store_descriptor->index,
2922
           block_descriptor_offset,
2923
           block_descriptor_offset );
2924
        }
2925
#endif
2926
0
        read_count = libvshadow_store_descriptor_read_buffer(
2927
0
                store_descriptor->next_store_descriptor,
2928
0
                io_handle,
2929
0
                file_io_handle,
2930
0
                &( buffer[ buffer_offset ] ),
2931
0
                read_size,
2932
0
                block_descriptor_offset,
2933
0
                active_store_descriptor_index,
2934
0
                error );
2935
2936
0
        if( read_count != (ssize_t) read_size )
2937
0
        {
2938
0
          libcerror_error_set(
2939
0
           error,
2940
0
           LIBCERROR_ERROR_DOMAIN_IO,
2941
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2942
0
           "%s: unable to read buffer from next store descriptor.",
2943
0
           function );
2944
2945
0
          goto on_error;
2946
0
        }
2947
0
      }
2948
0
      else
2949
0
      {
2950
#if defined( HAVE_DEBUG_OUTPUT )
2951
        if( libcnotify_verbose != 0 )
2952
        {
2953
          libcnotify_printf(
2954
           "%s: store: %02d reading block from current volume at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
2955
           function,
2956
           store_descriptor->index,
2957
           block_descriptor_offset,
2958
           block_descriptor_offset );
2959
        }
2960
#endif
2961
0
        read_count = libbfio_handle_read_buffer_at_offset(
2962
0
                file_io_handle,
2963
0
                &( buffer[ buffer_offset ] ),
2964
0
                read_size,
2965
0
                block_descriptor_offset,
2966
0
                error );
2967
2968
0
        if( read_count != (ssize_t) read_size )
2969
0
        {
2970
0
          libcerror_error_set(
2971
0
           error,
2972
0
           LIBCERROR_ERROR_DOMAIN_IO,
2973
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2974
0
           "%s: unable to read buffer at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2975
0
           function,
2976
0
           block_descriptor_offset,
2977
0
           block_descriptor_offset );
2978
2979
0
          goto on_error;
2980
0
        }
2981
0
      }
2982
0
    }
2983
0
    else
2984
0
    {
2985
      /* Check if the next store defines the block
2986
       */
2987
0
      if( store_descriptor->next_store_descriptor != NULL )
2988
0
      {
2989
#if defined( HAVE_DEBUG_OUTPUT )
2990
        if( libcnotify_verbose != 0 )
2991
        {
2992
          libcnotify_printf(
2993
           "%s: store: %02d reading block from next store at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
2994
           function,
2995
           store_descriptor->index,
2996
           offset,
2997
           offset );
2998
        }
2999
#endif
3000
0
        read_count = libvshadow_store_descriptor_read_buffer(
3001
0
                store_descriptor->next_store_descriptor,
3002
0
                io_handle,
3003
0
                file_io_handle,
3004
0
                &( buffer[ buffer_offset ] ),
3005
0
                read_size,
3006
0
                offset,
3007
0
                active_store_descriptor_index,
3008
0
                error );
3009
3010
0
        if( read_count != (ssize_t) read_size )
3011
0
        {
3012
0
          libcerror_error_set(
3013
0
           error,
3014
0
           LIBCERROR_ERROR_DOMAIN_IO,
3015
0
           LIBCERROR_IO_ERROR_READ_FAILED,
3016
0
           "%s: unable to read buffer from next store descriptor.",
3017
0
           function );
3018
3019
0
          goto on_error;
3020
0
        }
3021
0
      }
3022
0
      else if( ( in_reverse_block_descriptor_list == 0 )
3023
0
            && ( in_current_bitmap != 0 )
3024
0
            && ( in_previous_bitmap != 0 ) )
3025
0
      {
3026
#if defined( HAVE_DEBUG_OUTPUT )
3027
        if( libcnotify_verbose != 0 )
3028
        {
3029
          libcnotify_printf(
3030
           "%s: store: %02d filling block with zero bytes\n",
3031
           function,
3032
           store_descriptor->index,
3033
           offset,
3034
           read_size );
3035
        }
3036
#endif
3037
0
        if( memory_set(
3038
0
             &( buffer[ buffer_offset ] ),
3039
0
             0,
3040
0
             read_size ) == NULL )
3041
0
        {
3042
0
          libcerror_error_set(
3043
0
           error,
3044
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
3045
0
           LIBCERROR_MEMORY_ERROR_SET_FAILED,
3046
0
           "%s: unable to clear buffer.",
3047
0
           function );
3048
3049
0
          goto on_error;
3050
0
        }
3051
0
        read_count = (ssize_t) read_size;
3052
0
      }
3053
0
      else
3054
0
      {
3055
#if defined( HAVE_DEBUG_OUTPUT )
3056
        if( libcnotify_verbose != 0 )
3057
        {
3058
          libcnotify_printf(
3059
           "%s: store: %02d reading block from current volume at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
3060
           function,
3061
           store_descriptor->index,
3062
           offset,
3063
           offset );
3064
        }
3065
#endif
3066
0
        read_count = libbfio_handle_read_buffer_at_offset(
3067
0
                file_io_handle,
3068
0
                &( buffer[ buffer_offset ] ),
3069
0
                read_size,
3070
0
                offset,
3071
0
                error );
3072
3073
0
        if( read_count != (ssize_t) read_size )
3074
0
        {
3075
0
          libcerror_error_set(
3076
0
           error,
3077
0
           LIBCERROR_ERROR_DOMAIN_IO,
3078
0
           LIBCERROR_IO_ERROR_READ_FAILED,
3079
0
           "%s: unable to read buffer from file IO handle at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3080
0
           function,
3081
0
           offset,
3082
0
           offset );
3083
3084
0
          goto on_error;
3085
0
        }
3086
0
      }
3087
0
    }
3088
0
    offset        += read_count;
3089
0
    buffer_offset += read_count;
3090
0
    buffer_size   -= read_count;
3091
3092
#if defined( HAVE_DEBUG_OUTPUT )
3093
    if( libcnotify_verbose != 0 )
3094
    {
3095
      libcnotify_printf(
3096
       "\n" );
3097
    }
3098
#endif
3099
0
  }
3100
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3101
0
  if( libcthreads_read_write_lock_release_for_read(
3102
0
       store_descriptor->read_write_lock,
3103
0
       error ) != 1 )
3104
0
  {
3105
0
    libcerror_error_set(
3106
0
     error,
3107
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3108
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3109
0
     "%s: unable to release read/write lock for reading.",
3110
0
     function );
3111
3112
0
    return( -1 );
3113
0
  }
3114
0
#endif
3115
0
  return( (ssize_t) buffer_offset );
3116
3117
0
on_error:
3118
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3119
0
  libcthreads_read_write_lock_release_for_read(
3120
0
   store_descriptor->read_write_lock,
3121
0
   NULL );
3122
0
#endif
3123
0
  return( -1 );
3124
0
}
3125
3126
/* Retrieves the volume size
3127
 * Returns 1 if successful or -1 on error
3128
 */
3129
int libvshadow_store_descriptor_get_volume_size(
3130
     libvshadow_store_descriptor_t *store_descriptor,
3131
     size64_t *volume_size,
3132
     libcerror_error_t **error )
3133
0
{
3134
0
  static char *function = "libvshadow_store_descriptor_get_volume_size";
3135
3136
0
  if( store_descriptor == NULL )
3137
0
  {
3138
0
    libcerror_error_set(
3139
0
     error,
3140
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3141
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3142
0
     "%s: invalid store descriptor.",
3143
0
     function );
3144
3145
0
    return( -1 );
3146
0
  }
3147
0
  if( volume_size == NULL )
3148
0
  {
3149
0
    libcerror_error_set(
3150
0
     error,
3151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3153
0
     "%s: invalid volume size.",
3154
0
     function );
3155
3156
0
    return( -1 );
3157
0
  }
3158
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3159
0
  if( libcthreads_read_write_lock_grab_for_read(
3160
0
       store_descriptor->read_write_lock,
3161
0
       error ) != 1 )
3162
0
  {
3163
0
    libcerror_error_set(
3164
0
     error,
3165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3166
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3167
0
     "%s: unable to grab read/write lock for reading.",
3168
0
     function );
3169
3170
0
    return( -1 );
3171
0
  }
3172
0
#endif
3173
0
  *volume_size = store_descriptor->volume_size;
3174
3175
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3176
0
  if( libcthreads_read_write_lock_release_for_read(
3177
0
       store_descriptor->read_write_lock,
3178
0
       error ) != 1 )
3179
0
  {
3180
0
    libcerror_error_set(
3181
0
     error,
3182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3183
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3184
0
     "%s: unable to release read/write lock for reading.",
3185
0
     function );
3186
3187
0
    return( -1 );
3188
0
  }
3189
0
#endif
3190
0
  return( 1 );
3191
0
}
3192
3193
/* Retrieves the identifier
3194
 * Returns 1 if successful or -1 on error
3195
 */
3196
int libvshadow_store_descriptor_get_identifier(
3197
     libvshadow_store_descriptor_t *store_descriptor,
3198
     uint8_t *guid,
3199
     size_t size,
3200
     libcerror_error_t **error )
3201
0
{
3202
0
  static char *function = "libvshadow_store_descriptor_get_identifier";
3203
0
  int result            = 1;
3204
3205
0
  if( store_descriptor == NULL )
3206
0
  {
3207
0
    libcerror_error_set(
3208
0
     error,
3209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3211
0
     "%s: invalid store descriptor.",
3212
0
     function );
3213
3214
0
    return( -1 );
3215
0
  }
3216
0
  if( guid == NULL )
3217
0
  {
3218
0
    libcerror_error_set(
3219
0
     error,
3220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3221
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3222
0
     "%s: invalid GUID.",
3223
0
     function );
3224
3225
0
    return( -1 );
3226
0
  }
3227
0
  if( size < 16 )
3228
0
  {
3229
0
    libcerror_error_set(
3230
0
     error,
3231
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3232
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3233
0
     "%s: invalid GUID size value too small.",
3234
0
     function );
3235
3236
0
    return( -1 );
3237
0
  }
3238
0
  if( size > (size_t) SSIZE_MAX )
3239
0
  {
3240
0
    libcerror_error_set(
3241
0
     error,
3242
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3243
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3244
0
     "%s: invalid GUID size value exceeds maximum.",
3245
0
     function );
3246
3247
0
    return( -1 );
3248
0
  }
3249
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3250
0
  if( libcthreads_read_write_lock_grab_for_read(
3251
0
       store_descriptor->read_write_lock,
3252
0
       error ) != 1 )
3253
0
  {
3254
0
    libcerror_error_set(
3255
0
     error,
3256
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3257
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3258
0
     "%s: unable to grab read/write lock for reading.",
3259
0
     function );
3260
3261
0
    return( -1 );
3262
0
  }
3263
0
#endif
3264
0
  if( memory_copy(
3265
0
       guid,
3266
0
       store_descriptor->identifier,
3267
0
       16 ) == NULL )
3268
0
  {
3269
0
    libcerror_error_set(
3270
0
     error,
3271
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
3272
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3273
0
     "%s: unable to copy identifier.",
3274
0
     function );
3275
3276
0
    result = -1;
3277
0
  }
3278
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3279
0
  if( libcthreads_read_write_lock_release_for_read(
3280
0
       store_descriptor->read_write_lock,
3281
0
       error ) != 1 )
3282
0
  {
3283
0
    libcerror_error_set(
3284
0
     error,
3285
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3286
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3287
0
     "%s: unable to release read/write lock for reading.",
3288
0
     function );
3289
3290
0
    return( -1 );
3291
0
  }
3292
0
#endif
3293
0
  return( result );
3294
0
}
3295
3296
/* Retrieves the creation date and time
3297
 * Returns 1 if successful or -1 on error
3298
 */
3299
int libvshadow_store_descriptor_get_creation_time(
3300
     libvshadow_store_descriptor_t *store_descriptor,
3301
     uint64_t *filetime,
3302
     libcerror_error_t **error )
3303
0
{
3304
0
  static char *function = "libvshadow_store_descriptor_get_creation_time";
3305
3306
0
  if( store_descriptor == NULL )
3307
0
  {
3308
0
    libcerror_error_set(
3309
0
     error,
3310
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3311
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3312
0
     "%s: invalid store descriptor.",
3313
0
     function );
3314
3315
0
    return( -1 );
3316
0
  }
3317
0
  if( filetime == NULL )
3318
0
  {
3319
0
    libcerror_error_set(
3320
0
     error,
3321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3323
0
     "%s: invalid filetime.",
3324
0
     function );
3325
3326
0
    return( -1 );
3327
0
  }
3328
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3329
0
  if( libcthreads_read_write_lock_grab_for_read(
3330
0
       store_descriptor->read_write_lock,
3331
0
       error ) != 1 )
3332
0
  {
3333
0
    libcerror_error_set(
3334
0
     error,
3335
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3336
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3337
0
     "%s: unable to grab read/write lock for reading.",
3338
0
     function );
3339
3340
0
    return( -1 );
3341
0
  }
3342
0
#endif
3343
0
  *filetime = store_descriptor->creation_time;
3344
3345
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3346
0
  if( libcthreads_read_write_lock_release_for_read(
3347
0
       store_descriptor->read_write_lock,
3348
0
       error ) != 1 )
3349
0
  {
3350
0
    libcerror_error_set(
3351
0
     error,
3352
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3353
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3354
0
     "%s: unable to release read/write lock for reading.",
3355
0
     function );
3356
3357
0
    return( -1 );
3358
0
  }
3359
0
#endif
3360
0
  return( 1 );
3361
0
}
3362
3363
/* Retrieves the copy identifier
3364
 * Returns 1 if successful, 0 if not available or -1 on error
3365
 */
3366
int libvshadow_store_descriptor_get_copy_identifier(
3367
     libvshadow_store_descriptor_t *store_descriptor,
3368
     uint8_t *guid,
3369
     size_t size,
3370
     libcerror_error_t **error )
3371
0
{
3372
0
  static char *function = "libvshadow_store_descriptor_get_copy_identifier";
3373
0
  int result            = 0;
3374
3375
0
  if( store_descriptor == NULL )
3376
0
  {
3377
0
    libcerror_error_set(
3378
0
     error,
3379
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3380
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3381
0
     "%s: invalid store descriptor.",
3382
0
     function );
3383
3384
0
    return( -1 );
3385
0
  }
3386
0
  if( guid == NULL )
3387
0
  {
3388
0
    libcerror_error_set(
3389
0
     error,
3390
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3391
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3392
0
     "%s: invalid GUID.",
3393
0
     function );
3394
3395
0
    return( -1 );
3396
0
  }
3397
0
  if( size < 16 )
3398
0
  {
3399
0
    libcerror_error_set(
3400
0
     error,
3401
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3402
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3403
0
     "%s: invalid GUID value too small.",
3404
0
     function );
3405
3406
0
    return( -1 );
3407
0
  }
3408
0
  if( size > (size_t) SSIZE_MAX )
3409
0
  {
3410
0
    libcerror_error_set(
3411
0
     error,
3412
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3413
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3414
0
     "%s: invalid GUID size value exceeds maximum.",
3415
0
     function );
3416
3417
0
    return( -1 );
3418
0
  }
3419
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3420
0
  if( libcthreads_read_write_lock_grab_for_read(
3421
0
       store_descriptor->read_write_lock,
3422
0
       error ) != 1 )
3423
0
  {
3424
0
    libcerror_error_set(
3425
0
     error,
3426
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3427
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3428
0
     "%s: unable to grab read/write lock for reading.",
3429
0
     function );
3430
3431
0
    return( -1 );
3432
0
  }
3433
0
#endif
3434
0
  if( store_descriptor->has_in_volume_store_data != 0 )
3435
0
  {
3436
0
    result = 1;
3437
3438
0
    if( memory_copy(
3439
0
         guid,
3440
0
         store_descriptor->copy_identifier,
3441
0
         16 ) == NULL )
3442
0
    {
3443
0
      libcerror_error_set(
3444
0
       error,
3445
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3446
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3447
0
       "%s: unable to copy shadow copy identifier.",
3448
0
       function );
3449
3450
0
      result = -1;
3451
0
    }
3452
0
  }
3453
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3454
0
  if( libcthreads_read_write_lock_release_for_read(
3455
0
       store_descriptor->read_write_lock,
3456
0
       error ) != 1 )
3457
0
  {
3458
0
    libcerror_error_set(
3459
0
     error,
3460
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3461
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3462
0
     "%s: unable to release read/write lock for reading.",
3463
0
     function );
3464
3465
0
    return( -1 );
3466
0
  }
3467
0
#endif
3468
0
  return( result );
3469
0
}
3470
3471
/* Retrieves the copy set identifier
3472
 * Returns 1 if successful, 0 if not available or -1 on error
3473
 */
3474
int libvshadow_store_descriptor_get_copy_set_identifier(
3475
     libvshadow_store_descriptor_t *store_descriptor,
3476
     uint8_t *guid,
3477
     size_t size,
3478
     libcerror_error_t **error )
3479
0
{
3480
0
  static char *function = "libvshadow_store_descriptor_get_copy_set_identifier";
3481
0
  int result            = 0;
3482
3483
0
  if( store_descriptor == NULL )
3484
0
  {
3485
0
    libcerror_error_set(
3486
0
     error,
3487
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3488
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3489
0
     "%s: invalid store descriptor.",
3490
0
     function );
3491
3492
0
    return( -1 );
3493
0
  }
3494
0
  if( guid == NULL )
3495
0
  {
3496
0
    libcerror_error_set(
3497
0
     error,
3498
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3499
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3500
0
     "%s: invalid GUID.",
3501
0
     function );
3502
3503
0
    return( -1 );
3504
0
  }
3505
0
  if( size < 16 )
3506
0
  {
3507
0
    libcerror_error_set(
3508
0
     error,
3509
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3510
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3511
0
     "%s: invalid GUID value too small.",
3512
0
     function );
3513
3514
0
    return( -1 );
3515
0
  }
3516
0
  if( size > (size_t) SSIZE_MAX )
3517
0
  {
3518
0
    libcerror_error_set(
3519
0
     error,
3520
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3521
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3522
0
     "%s: invalid GUID size value exceeds maximum.",
3523
0
     function );
3524
3525
0
    return( -1 );
3526
0
  }
3527
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3528
0
  if( libcthreads_read_write_lock_grab_for_read(
3529
0
       store_descriptor->read_write_lock,
3530
0
       error ) != 1 )
3531
0
  {
3532
0
    libcerror_error_set(
3533
0
     error,
3534
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3535
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3536
0
     "%s: unable to grab read/write lock for reading.",
3537
0
     function );
3538
3539
0
    return( -1 );
3540
0
  }
3541
0
#endif
3542
0
  if( store_descriptor->has_in_volume_store_data != 0 )
3543
0
  {
3544
0
    result = 1;
3545
3546
0
    if( memory_copy(
3547
0
         guid,
3548
0
         store_descriptor->copy_set_identifier,
3549
0
         16 ) == NULL )
3550
0
    {
3551
0
      libcerror_error_set(
3552
0
       error,
3553
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3554
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3555
0
       "%s: unable to copy shadow copy set identifier.",
3556
0
       function );
3557
3558
0
      result = -1;
3559
0
    }
3560
0
  }
3561
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3562
0
  if( libcthreads_read_write_lock_release_for_read(
3563
0
       store_descriptor->read_write_lock,
3564
0
       error ) != 1 )
3565
0
  {
3566
0
    libcerror_error_set(
3567
0
     error,
3568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3569
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3570
0
     "%s: unable to release read/write lock for reading.",
3571
0
     function );
3572
3573
0
    return( -1 );
3574
0
  }
3575
0
#endif
3576
0
  return( result );
3577
0
}
3578
3579
/* Retrieves the attribute flags
3580
 * Returns 1 if successful, 0 if not available or -1 on error
3581
 */
3582
int libvshadow_store_descriptor_get_attribute_flags(
3583
     libvshadow_store_descriptor_t *store_descriptor,
3584
     uint32_t *attribute_flags,
3585
     libcerror_error_t **error )
3586
0
{
3587
0
  static char *function = "libvshadow_store_descriptor_get_attribute_flags";
3588
0
  int result            = 0;
3589
3590
0
  if( store_descriptor == NULL )
3591
0
  {
3592
0
    libcerror_error_set(
3593
0
     error,
3594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3596
0
     "%s: invalid store descriptor.",
3597
0
     function );
3598
3599
0
    return( -1 );
3600
0
  }
3601
0
  if( attribute_flags == NULL )
3602
0
  {
3603
0
    libcerror_error_set(
3604
0
     error,
3605
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3606
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3607
0
     "%s: invalid attribute flags.",
3608
0
     function );
3609
3610
0
    return( -1 );
3611
0
  }
3612
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3613
0
  if( libcthreads_read_write_lock_grab_for_read(
3614
0
       store_descriptor->read_write_lock,
3615
0
       error ) != 1 )
3616
0
  {
3617
0
    libcerror_error_set(
3618
0
     error,
3619
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3620
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3621
0
     "%s: unable to grab read/write lock for reading.",
3622
0
     function );
3623
3624
0
    return( -1 );
3625
0
  }
3626
0
#endif
3627
0
  if( store_descriptor->has_in_volume_store_data != 0 )
3628
0
  {
3629
0
    result = 1;
3630
3631
0
    *attribute_flags = store_descriptor->attribute_flags;
3632
0
  }
3633
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3634
0
  if( libcthreads_read_write_lock_release_for_read(
3635
0
       store_descriptor->read_write_lock,
3636
0
       error ) != 1 )
3637
0
  {
3638
0
    libcerror_error_set(
3639
0
     error,
3640
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3641
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3642
0
     "%s: unable to release read/write lock for reading.",
3643
0
     function );
3644
3645
0
    return( -1 );
3646
0
  }
3647
0
#endif
3648
0
  return( result );
3649
0
}
3650
3651
/* Retrieves the number of blocks
3652
 * Returns 1 if successful or -1 on error
3653
 */
3654
int libvshadow_store_descriptor_get_number_of_blocks(
3655
     libvshadow_store_descriptor_t *store_descriptor,
3656
     libvshadow_io_handle_t *io_handle,
3657
     libbfio_handle_t *file_io_handle,
3658
     int *number_of_blocks,
3659
     libcerror_error_t **error )
3660
0
{
3661
0
  static char *function = "libvshadow_store_descriptor_get_number_of_blocks";
3662
0
  int result            = 1;
3663
3664
0
  if( store_descriptor == NULL )
3665
0
  {
3666
0
    libcerror_error_set(
3667
0
     error,
3668
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3669
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3670
0
     "%s: invalid store descriptor.",
3671
0
     function );
3672
3673
0
    return( -1 );
3674
0
  }
3675
0
  if( store_descriptor->has_in_volume_store_data == 0 )
3676
0
  {
3677
0
    libcerror_error_set(
3678
0
     error,
3679
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3680
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3681
0
     "%s: invalid store descriptor - missing in-volume store data.",
3682
0
     function );
3683
3684
0
    return( -1 );
3685
0
  }
3686
  /* This function will acquire the write lock
3687
   */
3688
0
  if( libvshadow_store_descriptor_read_block_descriptors(
3689
0
       store_descriptor,
3690
0
       io_handle,
3691
0
       file_io_handle,
3692
0
       error ) != 1 )
3693
0
  {
3694
0
    libcerror_error_set(
3695
0
     error,
3696
0
     LIBCERROR_ERROR_DOMAIN_IO,
3697
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3698
0
     "%s: unable to read block descriptors.",
3699
0
     function );
3700
3701
0
    return( -1 );
3702
0
  }
3703
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3704
0
  if( libcthreads_read_write_lock_grab_for_read(
3705
0
       store_descriptor->read_write_lock,
3706
0
       error ) != 1 )
3707
0
  {
3708
0
    libcerror_error_set(
3709
0
     error,
3710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3711
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3712
0
     "%s: unable to grab read/write lock for reading.",
3713
0
     function );
3714
3715
0
    return( -1 );
3716
0
  }
3717
0
#endif
3718
0
  if( libcdata_list_get_number_of_elements(
3719
0
       store_descriptor->block_descriptors_list,
3720
0
       number_of_blocks,
3721
0
       error ) != 1 )
3722
0
  {
3723
0
    libcerror_error_set(
3724
0
     error,
3725
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3726
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3727
0
     "%s: unable to retrieve number of block descriptors.",
3728
0
     function );
3729
3730
0
    result = -1;
3731
0
  }
3732
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3733
0
  if( libcthreads_read_write_lock_release_for_read(
3734
0
       store_descriptor->read_write_lock,
3735
0
       error ) != 1 )
3736
0
  {
3737
0
    libcerror_error_set(
3738
0
     error,
3739
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3740
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3741
0
     "%s: unable to release read/write lock for reading.",
3742
0
     function );
3743
3744
0
    return( -1 );
3745
0
  }
3746
0
#endif
3747
0
  return( result );
3748
0
}
3749
3750
/* Retrieves a specific block descriptor
3751
 * Returns 1 if successful or -1 on error
3752
 */
3753
int libvshadow_store_descriptor_get_block_descriptor_by_index(
3754
     libvshadow_store_descriptor_t *store_descriptor,
3755
     libvshadow_io_handle_t *io_handle,
3756
     libbfio_handle_t *file_io_handle,
3757
     int block_index,
3758
     libvshadow_block_descriptor_t **block_descriptor,
3759
     libcerror_error_t **error )
3760
0
{
3761
0
  static char *function = "libvshadow_store_descriptor_get_block_descriptor_by_index";
3762
0
  int result            = 1;
3763
3764
0
  if( store_descriptor == NULL )
3765
0
  {
3766
0
    libcerror_error_set(
3767
0
     error,
3768
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3769
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3770
0
     "%s: invalid store descriptor.",
3771
0
     function );
3772
3773
0
    return( -1 );
3774
0
  }
3775
0
  if( store_descriptor->has_in_volume_store_data == 0 )
3776
0
  {
3777
0
    libcerror_error_set(
3778
0
     error,
3779
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3780
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3781
0
     "%s: invalid store descriptor - missing in-volume store data.",
3782
0
     function );
3783
3784
0
    return( -1 );
3785
0
  }
3786
  /* This function will acquire the write lock
3787
   */
3788
0
  if( libvshadow_store_descriptor_read_block_descriptors(
3789
0
       store_descriptor,
3790
0
       io_handle,
3791
0
       file_io_handle,
3792
0
       error ) != 1 )
3793
0
  {
3794
0
    libcerror_error_set(
3795
0
     error,
3796
0
     LIBCERROR_ERROR_DOMAIN_IO,
3797
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3798
0
     "%s: unable to read block descriptors.",
3799
0
     function );
3800
3801
0
    return( -1 );
3802
0
  }
3803
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3804
0
  if( libcthreads_read_write_lock_grab_for_read(
3805
0
       store_descriptor->read_write_lock,
3806
0
       error ) != 1 )
3807
0
  {
3808
0
    libcerror_error_set(
3809
0
     error,
3810
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3811
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3812
0
     "%s: unable to grab read/write lock for reading.",
3813
0
     function );
3814
3815
0
    return( -1 );
3816
0
  }
3817
0
#endif
3818
0
  if( libcdata_list_get_value_by_index(
3819
0
       store_descriptor->block_descriptors_list,
3820
0
       block_index,
3821
0
       (intptr_t **) block_descriptor,
3822
0
       error ) != 1 )
3823
0
  {
3824
0
    libcerror_error_set(
3825
0
     error,
3826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3827
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3828
0
     "%s: unable to retrieve block descriptor: %d.",
3829
0
     function,
3830
0
     block_index );
3831
3832
0
    result = -1;
3833
0
  }
3834
0
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
3835
0
  if( libcthreads_read_write_lock_release_for_read(
3836
0
       store_descriptor->read_write_lock,
3837
0
       error ) != 1 )
3838
0
  {
3839
0
    libcerror_error_set(
3840
0
     error,
3841
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3842
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3843
0
     "%s: unable to release read/write lock for reading.",
3844
0
     function );
3845
3846
0
    return( -1 );
3847
0
  }
3848
0
#endif
3849
0
  return( result );
3850
0
}
3851