Coverage Report

Created: 2025-07-04 07:01

/src/libvsbsdl/libvsbsdl/libvsbsdl_sector_data.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Chunk data functions
3
 *
4
 * Copyright (C) 2023-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 "libvsbsdl_definitions.h"
27
#include "libvsbsdl_libbfio.h"
28
#include "libvsbsdl_libcerror.h"
29
#include "libvsbsdl_libcnotify.h"
30
#include "libvsbsdl_libfdata.h"
31
#include "libvsbsdl_sector_data.h"
32
#include "libvsbsdl_unused.h"
33
34
/* Creates a sector data
35
 * Make sure the value sector_data is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libvsbsdl_sector_data_initialize(
39
     libvsbsdl_sector_data_t **sector_data,
40
     size_t data_size,
41
     libcerror_error_t **error )
42
0
{
43
0
  static char *function = "libvsbsdl_sector_data_initialize";
44
45
0
  if( sector_data == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid sector data.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
0
  if( *sector_data != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid sector data value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
0
  if( ( data_size == 0 )
68
0
   || ( data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
73
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
74
0
     "%s: invalid data size value out of bounds.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
0
  *sector_data = memory_allocate_structure(
80
0
                  libvsbsdl_sector_data_t );
81
82
0
  if( *sector_data == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
88
0
     "%s: unable to create sector data.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
0
  if( memory_set(
94
0
       *sector_data,
95
0
       0,
96
0
       sizeof( libvsbsdl_sector_data_t ) ) == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
101
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
102
0
     "%s: unable to clear sector data.",
103
0
     function );
104
105
0
    memory_free(
106
0
     *sector_data );
107
108
0
    *sector_data = NULL;
109
110
0
    return( -1 );
111
0
  }
112
0
  ( *sector_data )->data = (uint8_t *) memory_allocate(
113
0
                                        sizeof( uint8_t ) * data_size );
114
115
0
  if( ( *sector_data )->data == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
120
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
121
0
     "%s: unable to create data.",
122
0
     function );
123
124
0
    goto on_error;
125
0
  }
126
0
  ( *sector_data )->data_size = data_size;
127
128
0
  return( 1 );
129
130
0
on_error:
131
0
  if( *sector_data != NULL )
132
0
  {
133
0
    memory_free(
134
0
     *sector_data );
135
136
0
    *sector_data = NULL;
137
0
  }
138
0
  return( -1 );
139
0
}
140
141
/* Frees a sector data
142
 * Returns 1 if successful or -1 on error
143
 */
144
int libvsbsdl_sector_data_free(
145
     libvsbsdl_sector_data_t **sector_data,
146
     libcerror_error_t **error )
147
0
{
148
0
  static char *function = "libvsbsdl_sector_data_free";
149
0
  int result            = 1;
150
151
0
  if( sector_data == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid sector data.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
0
  if( *sector_data != NULL )
163
0
  {
164
0
    if( memory_set(
165
0
         ( *sector_data )->data,
166
0
         0,
167
0
         ( *sector_data )->data_size ) == NULL )
168
0
    {
169
0
      libcerror_error_set(
170
0
       error,
171
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
172
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
173
0
       "%s: unable to clear data.",
174
0
       function );
175
176
0
      result = -1;
177
0
    }
178
0
    memory_free(
179
0
     ( *sector_data )->data );
180
181
0
    memory_free(
182
0
     *sector_data );
183
184
0
    *sector_data = NULL;
185
0
  }
186
0
  return( result );
187
0
}
188
189
/* Reads sector data
190
 * Returns 1 if successful or -1 on error
191
 */
192
int libvsbsdl_sector_data_read_file_io_handle(
193
     libvsbsdl_sector_data_t *sector_data,
194
     libbfio_handle_t *file_io_handle,
195
     off64_t sector_offset,
196
     libcerror_error_t **error )
197
0
{
198
0
  static char *function = "libvsbsdl_sector_data_read_file_io_handle";
199
0
  ssize_t read_count    = 0;
200
201
0
  if( sector_data == 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 sector data.",
208
0
     function );
209
210
0
    return( -1 );
211
0
  }
212
0
  if( sector_data->data == NULL )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
217
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
218
0
     "%s: invalid sector data - missing data.",
219
0
     function );
220
221
0
    return( -1 );
222
0
  }
223
0
  if( ( sector_data->data_size == 0 )
224
0
   || ( sector_data->data_size > (size_t) SSIZE_MAX ) )
225
0
  {
226
0
    libcerror_error_set(
227
0
     error,
228
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
229
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
230
0
     "%s: invalid sector data - data size value out of bounds.",
231
0
     function );
232
233
0
    return( -1 );
234
0
  }
235
#if defined( HAVE_DEBUG_OUTPUT )
236
  if( libcnotify_verbose != 0 )
237
  {
238
    libcnotify_printf(
239
     "%s: reading sector data at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
240
     function,
241
     sector_offset,
242
     sector_offset );
243
  }
244
#endif
245
0
  read_count = libbfio_handle_read_buffer_at_offset(
246
0
          file_io_handle,
247
0
          sector_data->data,
248
0
          sector_data->data_size,
249
0
          sector_offset,
250
0
          error );
251
252
0
  if( read_count != (ssize_t) sector_data->data_size )
253
0
  {
254
0
    libcerror_error_set(
255
0
     error,
256
0
     LIBCERROR_ERROR_DOMAIN_IO,
257
0
     LIBCERROR_IO_ERROR_READ_FAILED,
258
0
     "%s: unable to read sector data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
259
0
     function,
260
0
     sector_offset,
261
0
     sector_offset );
262
263
0
    return( -1 );
264
0
  }
265
#if defined( HAVE_DEBUG_OUTPUT )
266
  if( libcnotify_verbose != 0 )
267
  {
268
    libcnotify_printf(
269
     "%s: sector data:\n",
270
     function );
271
    libcnotify_print_data(
272
     sector_data->data,
273
     sector_data->data_size,
274
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
275
  }
276
#endif
277
0
  return( 1 );
278
0
}
279
280
/* Reads sector data
281
 * Callback function for the sector data vector
282
 * Returns 1 if successful or -1 on error
283
 */
284
int libvsbsdl_partition_read_element_data(
285
     intptr_t *data_handle LIBVSBSDL_ATTRIBUTE_UNUSED,
286
     libbfio_handle_t *file_io_handle,
287
     libfdata_vector_t *vector,
288
     libfdata_cache_t *cache,
289
     int element_index,
290
     int element_data_file_index LIBVSBSDL_ATTRIBUTE_UNUSED,
291
     off64_t element_data_offset,
292
     size64_t element_data_size,
293
     uint32_t element_data_flags LIBVSBSDL_ATTRIBUTE_UNUSED,
294
     uint8_t read_flags LIBVSBSDL_ATTRIBUTE_UNUSED,
295
     libcerror_error_t **error )
296
0
{
297
0
  libvsbsdl_sector_data_t *sector_data = NULL;
298
0
  static char *function               = "libvsbsdl_partition_read_element_data";
299
300
0
  LIBVSBSDL_UNREFERENCED_PARAMETER( data_handle );
301
0
  LIBVSBSDL_UNREFERENCED_PARAMETER( element_data_file_index );
302
0
  LIBVSBSDL_UNREFERENCED_PARAMETER( element_data_flags );
303
0
  LIBVSBSDL_UNREFERENCED_PARAMETER( read_flags );
304
305
0
  if( element_data_size > (size64_t) SSIZE_MAX )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
310
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
311
0
     "%s: invalid element data size value exceeds maximum.",
312
0
     function );
313
314
0
    goto on_error;
315
0
  }
316
0
  if( libvsbsdl_sector_data_initialize(
317
0
       &sector_data,
318
0
       (size_t) element_data_size,
319
0
       error ) != 1 )
320
0
  {
321
0
    libcerror_error_set(
322
0
     error,
323
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
324
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
325
0
     "%s: unable to create sector data.",
326
0
     function );
327
328
0
    goto on_error;
329
0
  }
330
0
  if( libvsbsdl_sector_data_read_file_io_handle(
331
0
       sector_data,
332
0
       file_io_handle,
333
0
             element_data_offset,
334
0
       error ) != 1 )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_IO,
339
0
     LIBCERROR_IO_ERROR_READ_FAILED,
340
0
     "%s: unable to read sector data.",
341
0
     function );
342
343
0
    goto on_error;
344
0
  }
345
0
  if( libfdata_vector_set_element_value_by_index(
346
0
       vector,
347
0
       (intptr_t *) file_io_handle,
348
0
       cache,
349
0
       element_index,
350
0
       (intptr_t *) sector_data,
351
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libvsbsdl_sector_data_free,
352
0
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
353
0
       error ) != 1 )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
359
0
     "%s: unable to set sector data as element value.",
360
0
     function );
361
362
0
    goto on_error;
363
0
  }
364
0
  return( 1 );
365
366
0
on_error:
367
0
  if( sector_data != NULL )
368
0
  {
369
0
    libvsbsdl_sector_data_free(
370
0
     &sector_data,
371
0
     NULL );
372
0
  }
373
0
  return( -1 );
374
0
}
375