Coverage Report

Created: 2023-06-07 06:53

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