Coverage Report

Created: 2024-06-12 07:07

/src/libvshadow/libvshadow/libvshadow_block_tree.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Block tree 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_tree.h"
28
#include "libvshadow_block_tree_node.h"
29
#include "libvshadow_definitions.h"
30
#include "libvshadow_libcdata.h"
31
#include "libvshadow_libcerror.h"
32
#include "libvshadow_libcnotify.h"
33
#include "libvshadow_unused.h"
34
35
/* Creates a block tree
36
 * Make sure the value block_tree is referencing, is set to NULL
37
 * Returns 1 if successful or -1 on error
38
 */
39
int libvshadow_block_tree_initialize(
40
     libvshadow_block_tree_t **block_tree,
41
     size64_t size,
42
     size64_t leaf_value_size,
43
     libcerror_error_t **error )
44
906
{
45
906
  static char *function = "libvshadow_block_tree_initialize";
46
47
906
  if( block_tree == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid block tree.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
906
  if( *block_tree != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid block tree value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
906
  *block_tree = memory_allocate_structure(
70
906
                 libvshadow_block_tree_t );
71
72
906
  if( *block_tree == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create block tree.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
906
  if( memory_set(
84
906
       *block_tree,
85
906
       0,
86
906
       sizeof( libvshadow_block_tree_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear block tree.",
93
0
     function );
94
95
0
    memory_free(
96
0
     *block_tree );
97
98
0
    *block_tree = NULL;
99
100
0
    return( -1 );
101
0
  }
102
906
  if( libvshadow_block_tree_node_initialize(
103
906
       &( ( *block_tree )->root_node ),
104
906
       0,
105
906
       size,
106
906
       leaf_value_size,
107
906
       error ) != 1 )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
112
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
113
0
     "%s: unable to create root node.",
114
0
     function );
115
116
0
    goto on_error;
117
0
  }
118
906
  ( *block_tree )->leaf_value_size = leaf_value_size;
119
120
906
  return( 1 );
121
122
0
on_error:
123
0
  if( *block_tree != NULL )
124
0
  {
125
0
    memory_free(
126
0
     *block_tree );
127
128
0
    *block_tree = NULL;
129
0
  }
130
0
  return( -1 );
131
906
}
132
133
/* Frees a block tree
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libvshadow_block_tree_free(
137
     libvshadow_block_tree_t **block_tree,
138
     int (*value_free_function)(
139
            intptr_t **value,
140
            libcerror_error_t **error ),
141
     libcerror_error_t **error )
142
906
{
143
906
  static char *function = "libvshadow_block_tree_free";
144
906
  int result            = 1;
145
146
906
  if( block_tree == NULL )
147
0
  {
148
0
    libcerror_error_set(
149
0
     error,
150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
151
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
152
0
     "%s: invalid block tree.",
153
0
     function );
154
155
0
    return( -1 );
156
0
  }
157
906
  if( *block_tree != NULL )
158
906
  {
159
906
    if( libvshadow_block_tree_node_free(
160
906
         &( ( *block_tree )->root_node ),
161
906
         value_free_function,
162
906
         error ) != 1 )
163
0
    {
164
0
      libcerror_error_set(
165
0
       error,
166
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
167
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
168
0
       "%s: unable to free root node.",
169
0
       function );
170
171
0
      result = -1;
172
0
    }
173
906
    memory_free(
174
906
     *block_tree );
175
176
906
    *block_tree = NULL;
177
906
  }
178
906
  return( result );
179
906
}
180
181
/* Retrieves the block descriptor for a specific offset
182
 * Returns 1 if successful, 0 if not available or -1 on error
183
 */
184
int libvshadow_block_tree_get_block_descriptor_by_offset(
185
     libvshadow_block_tree_t *block_tree,
186
     off64_t offset,
187
     libvshadow_block_descriptor_t **block_descriptor,
188
     off64_t *block_offset,
189
     libcerror_error_t **error )
190
0
{
191
0
  libvshadow_block_descriptor_t *safe_block_descriptor = NULL;
192
0
  libvshadow_block_tree_node_t *block_tree_node        = NULL;
193
0
  static char *function                                = "libvshadow_block_tree_get_block_descriptor_by_offset";
194
0
  off64_t safe_block_offset                            = 0;
195
196
0
  if( block_tree == NULL )
197
0
  {
198
0
    libcerror_error_set(
199
0
     error,
200
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
201
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
202
0
     "%s: invalid block tree.",
203
0
     function );
204
205
0
    return( -1 );
206
0
  }
207
0
  if( block_descriptor == NULL )
208
0
  {
209
0
    libcerror_error_set(
210
0
     error,
211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
213
0
     "%s: invalid block descriptor.",
214
0
     function );
215
216
0
    return( -1 );
217
0
  }
218
0
  if( block_offset == NULL )
219
0
  {
220
0
    libcerror_error_set(
221
0
     error,
222
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224
0
     "%s: invalid block offset.",
225
0
     function );
226
227
0
    return( -1 );
228
0
  }
229
0
  block_tree_node = block_tree->root_node;
230
231
0
  while( block_tree_node->is_leaf_node == 0 )
232
0
  {
233
0
    if( libvshadow_block_tree_node_get_sub_node_at_offset(
234
0
         block_tree_node,
235
0
         offset,
236
0
         &block_tree_node,
237
0
         error ) != 1 )
238
0
    {
239
0
      libcerror_error_set(
240
0
       error,
241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
242
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
243
0
       "%s: unable to retrieve sub node at offset: %" PRIi64 " (0x%08" PRIx64 ").",
244
0
       function,
245
0
       offset,
246
0
       offset );
247
248
0
      return( -1 );
249
0
    }
250
0
    if( block_tree_node == NULL )
251
0
    {
252
0
      return( 0 );
253
0
    }
254
0
  }
255
0
  if( libvshadow_block_tree_node_get_leaf_value_at_offset(
256
0
       block_tree_node,
257
0
       offset,
258
0
       &safe_block_descriptor,
259
0
       &safe_block_offset,
260
0
       error ) != 1 )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
265
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
266
0
     "%s: unable to retrieve leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
267
0
     function,
268
0
     offset,
269
0
     offset );
270
271
0
    return( -1 );
272
0
  }
273
0
  if( safe_block_descriptor == NULL )
274
0
  {
275
0
    return( 0 );
276
0
  }
277
0
  *block_descriptor = safe_block_descriptor;
278
0
  *block_offset     = safe_block_offset;
279
280
0
  return( 1 );
281
0
}
282
283
/* Inserts the block descriptor for a specific offset
284
 * Returns 1 if successful, 0 if already set or -1 on error
285
 */
286
int libvshadow_block_tree_insert_block_descriptor_by_offset(
287
     libvshadow_block_tree_t *block_tree,
288
     off64_t offset,
289
     libvshadow_block_descriptor_t *block_descriptor,
290
     int *leaf_value_index,
291
     libvshadow_block_tree_node_t **leaf_block_tree_node,
292
     libvshadow_block_descriptor_t **existing_block_descriptor,
293
     libcerror_error_t **error )
294
915
{
295
915
  libvshadow_block_descriptor_t *safe_block_descriptor = NULL;
296
915
  libvshadow_block_tree_node_t *block_tree_node        = NULL;
297
915
  libvshadow_block_tree_node_t *safe_block_tree_node   = NULL;
298
915
  libvshadow_block_tree_node_t *sub_block_tree_node    = NULL;
299
915
  static char *function                                = "libvshadow_block_tree_insert_block_descriptor_by_offset";
300
915
  off64_t block_offset                                 = 0;
301
915
  off64_t sub_node_index                               = 0;
302
915
  off64_t sub_node_offset                              = 0;
303
304
915
  if( block_tree == NULL )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
310
0
     "%s: invalid block tree.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
915
  if( leaf_value_index == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321
0
     "%s: invalid leaf value index.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
915
  if( leaf_block_tree_node == NULL )
327
0
  {
328
0
    libcerror_error_set(
329
0
     error,
330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
331
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
332
0
     "%s: invalid leaf block tree node.",
333
0
     function );
334
335
0
    return( -1 );
336
0
  }
337
915
  if( existing_block_descriptor == NULL )
338
0
  {
339
0
    libcerror_error_set(
340
0
     error,
341
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
342
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
343
0
     "%s: invalid existing block descriptor.",
344
0
     function );
345
346
0
    return( -1 );
347
0
  }
348
915
  safe_block_tree_node = block_tree->root_node;
349
350
915
  while( safe_block_tree_node->is_leaf_node == 0 )
351
0
  {
352
0
    if( libvshadow_block_tree_node_get_sub_node_at_offset(
353
0
         safe_block_tree_node,
354
0
         offset,
355
0
         &block_tree_node,
356
0
         error ) != 1 )
357
0
    {
358
0
      libcerror_error_set(
359
0
       error,
360
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
361
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
362
0
       "%s: unable to retrieve sub node at offset: %" PRIi64 " (0x%08" PRIx64 ").",
363
0
       function,
364
0
       offset,
365
0
       offset );
366
367
0
      goto on_error;
368
0
    }
369
0
    if( block_tree_node == NULL )
370
0
    {
371
0
      sub_node_offset = offset - safe_block_tree_node->start_offset;
372
373
0
      sub_node_index  = sub_node_offset / safe_block_tree_node->sub_node_size;
374
0
      sub_node_offset = safe_block_tree_node->start_offset + ( sub_node_index * safe_block_tree_node->sub_node_size );
375
376
0
      if( libvshadow_block_tree_node_initialize(
377
0
           &sub_block_tree_node,
378
0
           sub_node_offset,
379
0
           safe_block_tree_node->sub_node_size,
380
0
           block_tree->leaf_value_size,
381
0
           error ) != 1 )
382
0
      {
383
0
        libcerror_error_set(
384
0
         error,
385
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
386
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
387
0
         "%s: unable to create sub node.",
388
0
         function );
389
390
0
        goto on_error;
391
0
      }
392
0
      if( libvshadow_block_tree_node_set_sub_node_at_offset(
393
0
           safe_block_tree_node,
394
0
           offset,
395
0
           sub_block_tree_node,
396
0
           error ) != 1 )
397
0
      {
398
0
        libcerror_error_set(
399
0
         error,
400
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
401
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
402
0
         "%s: unable to set sub node at offset: %" PRIi64 " (0x%08" PRIx64 ").",
403
0
         function,
404
0
         offset,
405
0
         offset );
406
407
0
        goto on_error;
408
0
      }
409
0
      block_tree_node     = sub_block_tree_node;
410
0
      sub_block_tree_node = NULL;
411
0
    }
412
0
    safe_block_tree_node = block_tree_node;
413
0
  }
414
915
  *leaf_block_tree_node = safe_block_tree_node;
415
416
915
  if( libvshadow_block_tree_node_get_leaf_value_at_offset(
417
915
       safe_block_tree_node,
418
915
       offset,
419
915
       &safe_block_descriptor,
420
915
       &block_offset,
421
915
       error ) != 1 )
422
66
  {
423
66
    libcerror_error_set(
424
66
     error,
425
66
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
426
66
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
427
66
     "%s: unable to retrieve leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
428
66
     function,
429
66
     offset,
430
66
     offset );
431
432
66
    goto on_error;
433
66
  }
434
849
  if( safe_block_descriptor != NULL )
435
2
  {
436
2
    *existing_block_descriptor = safe_block_descriptor;
437
438
2
    return( 0 );
439
2
  }
440
847
  if( libvshadow_block_tree_node_set_leaf_value_at_offset(
441
847
       safe_block_tree_node,
442
847
       offset,
443
847
       block_descriptor,
444
847
       error ) != 1 )
445
0
  {
446
0
    libcerror_error_set(
447
0
     error,
448
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
449
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
450
0
     "%s: unable to set leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
451
0
     function,
452
0
     offset,
453
0
     offset );
454
455
0
    goto on_error;
456
0
  }
457
847
  *leaf_value_index = (int) ( offset / block_tree->leaf_value_size );
458
459
847
  return( 1 );
460
461
66
on_error:
462
66
  if( sub_block_tree_node != NULL )
463
0
  {
464
0
    libvshadow_block_tree_node_free(
465
0
     &sub_block_tree_node,
466
0
     NULL,
467
0
     NULL );
468
0
  }
469
66
  return( -1 );
470
847
}
471
472
/* Removes the block descriptor for a specific offset
473
 * Returns 1 if successful, 0 if not available or -1 on error
474
 */
475
int libvshadow_block_tree_remove_block_descriptor_by_offset(
476
     libvshadow_block_tree_t *block_tree,
477
     off64_t offset,
478
     libcerror_error_t **error )
479
0
{
480
0
  libvshadow_block_descriptor_t *safe_block_descriptor = NULL;
481
0
  libvshadow_block_tree_node_t *block_tree_node        = NULL;
482
0
  static char *function                                = "libvshadow_block_tree_remove_block_descriptor_by_offset";
483
0
  off64_t block_offset                                 = 0;
484
485
0
  if( block_tree == NULL )
486
0
  {
487
0
    libcerror_error_set(
488
0
     error,
489
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
491
0
     "%s: invalid block tree.",
492
0
     function );
493
494
0
    return( -1 );
495
0
  }
496
0
  block_tree_node = block_tree->root_node;
497
498
0
  while( block_tree_node->is_leaf_node == 0 )
499
0
  {
500
0
    if( libvshadow_block_tree_node_get_sub_node_at_offset(
501
0
         block_tree_node,
502
0
         offset,
503
0
         &block_tree_node,
504
0
         error ) != 1 )
505
0
    {
506
0
      libcerror_error_set(
507
0
       error,
508
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
509
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
510
0
       "%s: unable to retrieve sub node at offset: %" PRIi64 " (0x%08" PRIx64 ").",
511
0
       function,
512
0
       offset,
513
0
       offset );
514
515
0
      return( -1 );
516
0
    }
517
0
    if( block_tree_node == NULL )
518
0
    {
519
0
      return( 0 );
520
0
    }
521
0
  }
522
0
  if( libvshadow_block_tree_node_get_leaf_value_at_offset(
523
0
       block_tree_node,
524
0
       offset,
525
0
       &safe_block_descriptor,
526
0
       &block_offset,
527
0
       error ) != 1 )
528
0
  {
529
0
    libcerror_error_set(
530
0
     error,
531
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
532
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
533
0
     "%s: unable to retrieve leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
534
0
     function,
535
0
     offset,
536
0
     offset );
537
538
0
    return( -1 );
539
0
  }
540
0
  if( safe_block_descriptor == NULL )
541
0
  {
542
0
    return( 0 );
543
0
  }
544
0
  if( libvshadow_block_tree_node_set_leaf_value_at_offset(
545
0
       block_tree_node,
546
0
       offset,
547
0
       NULL,
548
0
       error ) != 1 )
549
0
  {
550
0
    libcerror_error_set(
551
0
     error,
552
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
553
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
554
0
     "%s: unable to set leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
555
0
     function,
556
0
     offset,
557
0
     offset );
558
559
0
    return( -1 );
560
0
  }
561
0
  return( 1 );
562
0
}
563
564
/* Inserts a block descriptor in the block tree
565
 * Returns 1 if successful or -1 on error
566
 */
567
int libvshadow_block_tree_insert(
568
     libvshadow_block_tree_t *forward_block_tree,
569
     libvshadow_block_tree_t *reverse_block_tree,
570
     libvshadow_block_descriptor_t *block_descriptor,
571
     int store_index LIBVSHADOW_ATTRIBUTE_UNUSED,
572
     libcerror_error_t **error )
573
0
{
574
0
  libvshadow_block_descriptor_t *existing_block_descriptor = NULL;
575
0
  libvshadow_block_descriptor_t *new_block_descriptor      = NULL;
576
0
  libvshadow_block_descriptor_t *overlay_block_descriptor  = NULL;
577
0
  libvshadow_block_descriptor_t *reverse_block_descriptor  = NULL;
578
0
  libvshadow_block_tree_node_t *leaf_block_tree_node       = NULL;
579
0
  static char *function                                    = "libvshadow_block_tree_insert";
580
0
  off64_t block_offset                                     = 0;
581
0
  off64_t new_original_offset                              = 0;
582
0
  int result                                               = 0;
583
584
0
  LIBVSHADOW_UNREFERENCED_PARAMETER( store_index )
585
586
0
  if( forward_block_tree == NULL )
587
0
  {
588
0
    libcerror_error_set(
589
0
     error,
590
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
591
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
592
0
     "%s: invalid forward block tree.",
593
0
     function );
594
595
0
    return( -1 );
596
0
  }
597
0
  if( reverse_block_tree == NULL )
598
0
  {
599
0
    libcerror_error_set(
600
0
     error,
601
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
602
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
603
0
     "%s: invalid reverse block tree.",
604
0
     function );
605
606
0
    return( -1 );
607
0
  }
608
0
  if( block_descriptor == NULL )
609
0
  {
610
0
    libcerror_error_set(
611
0
     error,
612
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
613
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
614
0
     "%s: invalid block descriptor.",
615
0
     function );
616
617
0
    return( -1 );
618
0
  }
619
0
  if( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_NOT_USED ) != 0 )
620
0
  {
621
#if defined( HAVE_DEBUG_OUTPUT )
622
    if( libcnotify_verbose != 0 )
623
    {
624
      libcnotify_printf(
625
       "%s: store: %02d not used flag set - ignoring block descriptor.\n",
626
       function,
627
       store_index );
628
      libcnotify_printf(
629
       "\n" );
630
    }
631
#endif
632
0
    return( 1 );
633
0
  }
634
0
  new_original_offset = block_descriptor->original_offset;
635
636
0
  if( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) == 0 )
637
0
  {
638
    /* The reverse block tree is used to detect forwarder block descriptors that point to each other
639
     */
640
0
    result = libvshadow_block_tree_get_block_descriptor_by_offset(
641
0
        reverse_block_tree,
642
0
        block_descriptor->original_offset,
643
0
        &reverse_block_descriptor,
644
0
        &block_offset,
645
0
        error );
646
647
0
    if( result == -1 )
648
0
    {
649
0
      libcerror_error_set(
650
0
       error,
651
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
652
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
653
0
       "%s: unable to retrieve reverse block descriptor for offset: %" PRIi64 " (0x%08" PRIx64 ").",
654
0
       function,
655
0
       block_descriptor->original_offset,
656
0
       block_descriptor->original_offset );
657
658
0
      goto on_error;
659
0
    }
660
0
    else if( result != 0 )
661
0
    {
662
0
      if( reverse_block_descriptor == NULL )
663
0
      {
664
0
        libcerror_error_set(
665
0
         error,
666
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
667
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
668
0
         "%s: missing reverse block descriptor.",
669
0
         function );
670
671
0
        goto on_error;
672
0
      }
673
#if defined( HAVE_DEBUG_OUTPUT )
674
      if( libcnotify_verbose != 0 )
675
      {
676
        libcnotify_printf(
677
         "%s: store: %02d found reverse block descriptor: %" PRIi64 " (0x%08" PRIx64 ").\n",
678
         function,
679
         store_index,
680
         reverse_block_descriptor->original_offset,
681
         reverse_block_descriptor->original_offset );
682
683
        libcnotify_printf(
684
         "%s: store: %02d swapping original offset.\n",
685
         function,
686
         store_index );
687
      }
688
#endif
689
0
      new_original_offset = reverse_block_descriptor->original_offset;
690
691
0
      if( libvshadow_block_tree_remove_block_descriptor_by_offset(
692
0
           reverse_block_tree,
693
0
           reverse_block_descriptor->relative_offset,
694
0
           error ) != 1 )
695
0
      {
696
0
        libcerror_error_set(
697
0
         error,
698
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
699
0
         LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
700
0
         "%s: unable to remove reverse block descriptor: %" PRIi64 " (0x%08" PRIx64 ") from reverse block tree node.",
701
0
         function,
702
0
         reverse_block_descriptor->original_offset,
703
0
         reverse_block_descriptor->original_offset );
704
705
0
        goto on_error;
706
0
      }
707
0
      reverse_block_descriptor->reverse_index = -1;
708
709
0
      if( reverse_block_descriptor->index == -1 )
710
0
      {
711
0
        if( libvshadow_block_descriptor_free(
712
0
             &reverse_block_descriptor,
713
0
             error ) != 1 )
714
0
        {
715
0
          libcerror_error_set(
716
0
           error,
717
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
718
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
719
0
           "%s: unable to free reverse block descriptor.",
720
0
           function );
721
722
0
          goto on_error;
723
0
        }
724
0
      }
725
0
    }
726
0
  }
727
0
  if( ( block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_FORWARDER ) != 0 )
728
0
  {
729
0
    if( new_original_offset == block_descriptor->relative_offset )
730
0
    {
731
#if defined( HAVE_DEBUG_OUTPUT )
732
      if( libcnotify_verbose != 0 )
733
      {
734
        libcnotify_printf(
735
         "%s: store: %02d forwarder points to itself - ignoring block descriptor.\n",
736
         function,
737
         store_index );
738
        libcnotify_printf(
739
         "\n" );
740
      }
741
#endif
742
0
      return( 1 );
743
0
    }
744
0
  }
745
0
  if( libvshadow_block_descriptor_clone(
746
0
       &new_block_descriptor,
747
0
       block_descriptor,
748
0
       error ) != 1 )
749
0
  {
750
0
    libcerror_error_set(
751
0
     error,
752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
753
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
754
0
     "%s: unable to create block descriptor.",
755
0
     function );
756
757
0
    goto on_error;
758
0
  }
759
0
  new_block_descriptor->original_offset = new_original_offset;
760
761
0
  result = libvshadow_block_tree_insert_block_descriptor_by_offset(
762
0
      forward_block_tree,
763
0
            new_block_descriptor->original_offset,
764
0
            new_block_descriptor,
765
0
            &( new_block_descriptor->index ),
766
0
            &leaf_block_tree_node,
767
0
            &existing_block_descriptor,
768
0
            error );
769
770
0
  if( result == -1 )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
776
0
     "%s: unable to insert block descriptor in forward block tree.",
777
0
     function );
778
779
0
    goto on_error;
780
0
  }
781
0
  else if( result == 0 )
782
0
  {
783
0
    if( existing_block_descriptor == NULL )
784
0
    {
785
0
      libcerror_error_set(
786
0
       error,
787
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
788
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
789
0
       "%s: missing existing block descriptor.",
790
0
       function );
791
792
0
      goto on_error;
793
0
    }
794
0
    if( ( new_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) != 0 )
795
0
    {
796
0
      if( ( existing_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) != 0 )
797
0
      {
798
0
        overlay_block_descriptor = existing_block_descriptor;
799
0
      }
800
0
      else
801
0
      {
802
0
        overlay_block_descriptor = existing_block_descriptor->overlay;
803
0
      }
804
0
      if( overlay_block_descriptor != NULL )
805
0
      {
806
#if defined( HAVE_DEBUG_OUTPUT )
807
        if( libcnotify_verbose != 0 )
808
        {
809
          if( new_block_descriptor->original_offset != overlay_block_descriptor->original_offset )
810
          {
811
            libcnotify_printf(
812
             "%s: store: %02d mismatch in block descriptor store original offset (0x%08" PRIx64 ").\n",
813
             function,
814
             store_index,
815
             overlay_block_descriptor->original_offset );
816
          }
817
          if( new_block_descriptor->offset != overlay_block_descriptor->offset )
818
          {
819
            libcnotify_printf(
820
             "%s: store: %02d mismatch in block descriptor store offset (0x%08" PRIx64 ").\n",
821
             function,
822
             store_index,
823
             overlay_block_descriptor->offset );
824
          }
825
          if( new_block_descriptor->relative_offset != 0x00000001UL )
826
          {
827
            libcnotify_printf(
828
             "%s: store: %02d mismatch in block descriptor relative store offset (0x%08" PRIx64 ").\n",
829
             function,
830
             store_index,
831
             new_block_descriptor->relative_offset );
832
          }
833
          libcnotify_printf(
834
           "%s: store: %02d expanding overlay.\n",
835
           function,
836
           store_index );
837
        }
838
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
839
840
0
        overlay_block_descriptor->bitmap |= new_block_descriptor->bitmap;
841
842
0
        if( libvshadow_block_descriptor_free(
843
0
             &new_block_descriptor,
844
0
             error ) != 1 )
845
0
        {
846
0
          libcerror_error_set(
847
0
           error,
848
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
849
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
850
0
           "%s: unable to free block descriptor.",
851
0
           function );
852
853
0
          goto on_error;
854
0
        }
855
0
      }
856
0
      else
857
0
      {
858
#if defined( HAVE_DEBUG_OUTPUT )
859
        if( libcnotify_verbose != 0 )
860
        {
861
          if( new_block_descriptor->relative_offset == 0x00000001UL )
862
          {
863
            libcnotify_printf(
864
             "%s: store: %02d mismatch in block descriptor relative store offset (0x%08" PRIx64 ").\n",
865
             function,
866
             store_index,
867
             new_block_descriptor->relative_offset );
868
          }
869
          libcnotify_printf(
870
           "%s: store: %02d creating overlay.\n",
871
           function,
872
           store_index );
873
        }
874
#endif
875
0
        existing_block_descriptor->overlay = new_block_descriptor;
876
0
      }
877
#if defined( HAVE_DEBUG_OUTPUT )
878
      if( libcnotify_verbose != 0 )
879
      {
880
        libcnotify_printf(
881
         "\n" );
882
      }
883
#endif
884
0
      return( 1 );
885
0
    }
886
#if defined( HAVE_DEBUG_OUTPUT )
887
    if( libcnotify_verbose != 0 )
888
    {
889
      libcnotify_printf(
890
       "%s: store: %02d replacing existing block descriptor.\n",
891
       function,
892
       store_index );
893
    }
894
#endif
895
0
    if( libvshadow_block_tree_node_set_leaf_value_at_offset(
896
0
         leaf_block_tree_node,
897
0
         new_block_descriptor->original_offset,
898
0
         new_block_descriptor,
899
0
         error ) != 1 )
900
0
    {
901
0
      libcerror_error_set(
902
0
       error,
903
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
904
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
905
0
       "%s: unable to set leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
906
0
       function,
907
0
       new_block_descriptor->original_offset,
908
0
       new_block_descriptor->original_offset );
909
910
0
      goto on_error;
911
0
    }
912
0
    new_block_descriptor->index      = existing_block_descriptor->index;
913
0
    existing_block_descriptor->index = -1;
914
915
0
    if( ( existing_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_OVERLAY ) != 0 )
916
0
    {
917
#if defined( HAVE_DEBUG_OUTPUT )
918
      if( libcnotify_verbose != 0 )
919
      {
920
        libcnotify_printf(
921
         "%s: store: %02d adding existing block descriptor as overlay.\n",
922
         function,
923
         store_index );
924
      }
925
#endif
926
0
      if( existing_block_descriptor->overlay != NULL )
927
0
      {
928
0
        libcerror_error_set(
929
0
         error,
930
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
931
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
932
0
         "%s: invalid existing overlay block descriptor.",
933
0
         function );
934
935
0
        goto on_error;
936
0
      }
937
0
      new_block_descriptor->overlay = existing_block_descriptor;
938
0
    }
939
0
    else
940
0
    {
941
#if defined( HAVE_DEBUG_OUTPUT )
942
      if( libcnotify_verbose != 0 )
943
      {
944
        libcnotify_printf(
945
         "%s: store: %02d swapping overlay block descriptor.\n",
946
         function,
947
         store_index );
948
      }
949
#endif
950
      /* Swap the overlay block descriptor of the existing block descriptor with the new block descriptor
951
       */
952
0
      new_block_descriptor->overlay      = existing_block_descriptor->overlay;
953
0
      existing_block_descriptor->overlay = NULL;
954
955
0
      if( existing_block_descriptor->reverse_index == -1 )
956
0
      {
957
0
        if( libvshadow_block_descriptor_free(
958
0
             &existing_block_descriptor,
959
0
             error ) != 1 )
960
0
        {
961
0
          libcerror_error_set(
962
0
           error,
963
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
964
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
965
0
           "%s: unable to free existing block descriptor.",
966
0
           function );
967
968
0
          goto on_error;
969
0
        }
970
0
      }
971
0
    }
972
0
  }
973
#if defined( HAVE_DEBUG_OUTPUT )
974
  else if( libcnotify_verbose != 0 )
975
  {
976
    libcnotify_printf(
977
     "%s: store: %02d adding block descriptor.\n",
978
     function,
979
     store_index );
980
  }
981
#endif
982
0
  if( ( new_block_descriptor->flags & LIBVSHADOW_BLOCK_FLAG_IS_FORWARDER ) != 0 )
983
0
  {
984
0
    result = libvshadow_block_tree_insert_block_descriptor_by_offset(
985
0
        reverse_block_tree,
986
0
        new_block_descriptor->relative_offset,
987
0
        new_block_descriptor,
988
0
        &( new_block_descriptor->reverse_index ),
989
0
        &leaf_block_tree_node,
990
0
        &reverse_block_descriptor,
991
0
        error );
992
993
0
    if( result == -1 )
994
0
    {
995
0
      libcerror_error_set(
996
0
       error,
997
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
998
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
999
0
       "%s: unable to insert block descriptor in reverse block tree.",
1000
0
       function );
1001
1002
0
      new_block_descriptor = NULL;
1003
1004
0
      goto on_error;
1005
0
    }
1006
0
    else if( result == 0 )
1007
0
    {
1008
0
      if( reverse_block_descriptor == NULL )
1009
0
      {
1010
0
        libcerror_error_set(
1011
0
         error,
1012
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1013
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1014
0
         "%s: missing reverse block descriptor.",
1015
0
         function );
1016
1017
0
        new_block_descriptor = NULL;
1018
1019
0
        goto on_error;
1020
0
      }
1021
#if defined( HAVE_DEBUG_OUTPUT )
1022
      if( libcnotify_verbose != 0 )
1023
      {
1024
        libcnotify_printf(
1025
         "%s: store: %02d replacing existing reverse block descriptor: 0x08%" PRIx64 ".\n",
1026
         function,
1027
         store_index,
1028
         reverse_block_descriptor->original_offset );
1029
      }
1030
#endif
1031
0
      if( libvshadow_block_tree_node_set_leaf_value_at_offset(
1032
0
           leaf_block_tree_node,
1033
0
           new_block_descriptor->relative_offset,
1034
0
           new_block_descriptor,
1035
0
           error ) != 1 )
1036
0
      {
1037
0
        libcerror_error_set(
1038
0
         error,
1039
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1040
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1041
0
         "%s: unable to set reverse leaf value at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1042
0
         function,
1043
0
         new_block_descriptor->relative_offset,
1044
0
         new_block_descriptor->relative_offset );
1045
1046
0
        new_block_descriptor = NULL;
1047
1048
0
        goto on_error;
1049
0
      }
1050
0
      new_block_descriptor->reverse_index     = reverse_block_descriptor->reverse_index;
1051
0
      reverse_block_descriptor->reverse_index = -1;
1052
1053
0
      if( reverse_block_descriptor->index == -1 )
1054
0
      {
1055
0
        if( libvshadow_block_descriptor_free(
1056
0
             &reverse_block_descriptor,
1057
0
             error ) != 1 )
1058
0
        {
1059
0
          libcerror_error_set(
1060
0
           error,
1061
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1062
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1063
0
           "%s: unable to free reverse block descriptor.",
1064
0
           function );
1065
1066
0
          new_block_descriptor = NULL;
1067
1068
0
          goto on_error;
1069
0
        }
1070
0
      }
1071
0
    }
1072
#if defined( HAVE_DEBUG_OUTPUT )
1073
    else if( libcnotify_verbose != 0 )
1074
    {
1075
      libcnotify_printf(
1076
       "%s: store: %02d adding reverse block descriptor.\n",
1077
       function,
1078
       store_index );
1079
    }
1080
#endif
1081
0
  }
1082
#if defined( HAVE_DEBUG_OUTPUT )
1083
  if( libcnotify_verbose != 0 )
1084
  {
1085
    libcnotify_printf(
1086
     "\n" );
1087
  }
1088
#endif
1089
0
  return( 1 );
1090
1091
0
on_error:
1092
0
  if( new_block_descriptor != NULL )
1093
0
  {
1094
0
    libvshadow_block_descriptor_free(
1095
0
     &new_block_descriptor,
1096
0
     NULL );
1097
0
  }
1098
0
  return( -1 );
1099
0
}
1100