Coverage Report

Created: 2025-06-13 07:22

/src/libvshadow/libvshadow/libvshadow_block_range_descriptor.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Block range 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_range_descriptor.h"
27
#include "libvshadow_debug.h"
28
#include "libvshadow_definitions.h"
29
#include "libvshadow_libcerror.h"
30
#include "libvshadow_libcnotify.h"
31
#include "libvshadow_unused.h"
32
33
#include "vshadow_store.h"
34
35
const uint8_t vshadow_empty_store_block_range_list_entry[ 24 ] = {
36
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37
  0, 0, 0, 0, 0, 0, 0, 0 };
38
39
/* Creates a block range descriptor
40
 * Make sure the value block_range_descriptor is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libvshadow_block_range_descriptor_initialize(
44
     libvshadow_block_range_descriptor_t **block_range_descriptor,
45
     libcerror_error_t **error )
46
0
{
47
0
  static char *function = "libvshadow_block_range_descriptor_initialize";
48
49
0
  if( block_range_descriptor == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid block range descriptor.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
0
  if( *block_range_descriptor != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid block range descriptor value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
0
  *block_range_descriptor = memory_allocate_structure(
72
0
                             libvshadow_block_range_descriptor_t );
73
74
0
  if( *block_range_descriptor == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
79
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80
0
     "%s: unable to create block range descriptor.",
81
0
     function );
82
83
0
    goto on_error;
84
0
  }
85
0
  if( memory_set(
86
0
       *block_range_descriptor,
87
0
       0,
88
0
       sizeof( libvshadow_block_range_descriptor_t ) ) == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
93
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
94
0
     "%s: unable to clear block range descriptor.",
95
0
     function );
96
97
0
    goto on_error;
98
0
  }
99
0
  return( 1 );
100
101
0
on_error:
102
0
  if( *block_range_descriptor != NULL )
103
0
  {
104
0
    memory_free(
105
0
     *block_range_descriptor );
106
107
0
    *block_range_descriptor = NULL;
108
0
  }
109
0
  return( -1 );
110
0
}
111
112
/* Frees a block range descriptor
113
 * Returns 1 if successful or -1 on error
114
 */
115
int libvshadow_block_range_descriptor_free(
116
     libvshadow_block_range_descriptor_t **block_range_descriptor,
117
     libcerror_error_t **error )
118
0
{
119
0
  static char *function = "libvshadow_block_range_descriptor_free";
120
121
0
  if( block_range_descriptor == NULL )
122
0
  {
123
0
    libcerror_error_set(
124
0
     error,
125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
127
0
     "%s: invalid block range descriptor.",
128
0
     function );
129
130
0
    return( -1 );
131
0
  }
132
0
  if( *block_range_descriptor != NULL )
133
0
  {
134
0
    memory_free(
135
0
     *block_range_descriptor );
136
137
0
    *block_range_descriptor = NULL;
138
0
  }
139
0
  return( 1 );
140
0
}
141
142
/* Reads the block range descriptor
143
 * Returns 1 if successful, 0 if block list entry is empty or -1 on error
144
 */
145
int libvshadow_block_range_descriptor_read_data(
146
     libvshadow_block_range_descriptor_t *block_range_descriptor,
147
     const uint8_t *data,
148
     size_t data_size,
149
     int store_index LIBVSHADOW_ATTRIBUTE_UNUSED,
150
     libcerror_error_t **error )
151
0
{
152
0
  static char *function = "libvshadow_block_range_descriptor_read_data";
153
154
0
  LIBVSHADOW_UNREFERENCED_PARAMETER( store_index )
155
156
0
  if( block_range_descriptor == NULL )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
161
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
162
0
     "%s: invalid block range descriptor.",
163
0
     function );
164
165
0
    return( -1 );
166
0
  }
167
0
  if( data == NULL )
168
0
  {
169
0
    libcerror_error_set(
170
0
     error,
171
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
172
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
173
0
     "%s: invalid data.",
174
0
     function );
175
176
0
    return( -1 );
177
0
  }
178
0
  if( ( data_size < sizeof( vshadow_store_block_range_list_entry_t ) )
179
0
   || ( data_size > (size_t) SSIZE_MAX ) )
180
0
  {
181
0
    libcerror_error_set(
182
0
     error,
183
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
184
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
185
0
     "%s: invalid data size value out of bounds.",
186
0
     function );
187
188
0
    return( -1 );
189
0
  }
190
0
  if( memory_compare(
191
0
       data,
192
0
             vshadow_empty_store_block_range_list_entry,
193
0
             sizeof( vshadow_store_block_range_list_entry_t ) ) == 0 )
194
0
  {
195
0
    return( 0 );
196
0
  }
197
#if defined( HAVE_DEBUG_OUTPUT )
198
  if( libcnotify_verbose != 0 )
199
  {
200
    libcnotify_printf(
201
     "%s: store: %02d block range list entry data:\n",
202
     function,
203
     store_index );
204
    libcnotify_print_data(
205
     data,
206
     sizeof( vshadow_store_block_range_list_entry_t ),
207
     0 );
208
  }
209
#endif
210
0
  byte_stream_copy_to_uint64_little_endian(
211
0
   ( (vshadow_store_block_range_list_entry_t *) data )->offset,
212
0
   block_range_descriptor->offset );
213
214
0
  byte_stream_copy_to_uint64_little_endian(
215
0
   ( (vshadow_store_block_range_list_entry_t *) data )->relative_offset,
216
0
   block_range_descriptor->relative_offset );
217
218
0
  byte_stream_copy_to_uint64_little_endian(
219
0
   ( (vshadow_store_block_range_list_entry_t *) data )->size,
220
0
   block_range_descriptor->size );
221
222
#if defined( HAVE_DEBUG_OUTPUT )
223
  if( libcnotify_verbose != 0 )
224
  {
225
    libcnotify_printf(
226
     "%s: store: %02d offset\t\t\t: 0x%08" PRIx64 "\n",
227
     function,
228
     store_index,
229
     block_range_descriptor->offset );
230
231
    libcnotify_printf(
232
     "%s: store: %02d relative offset\t\t: 0x%08" PRIx64 "\n",
233
     function,
234
     store_index,
235
     block_range_descriptor->relative_offset );
236
237
    libcnotify_printf(
238
     "%s: store: %02d size\t\t\t: %" PRIu64 "\n",
239
     function,
240
     store_index,
241
     block_range_descriptor->size );
242
243
    libcnotify_printf(
244
     "\n" );
245
  }
246
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
247
248
0
  return( 1 );
249
0
}
250