Coverage Report

Created: 2024-06-12 07:07

/src/libphdi/libphdi/libphdi_extent_descriptor.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Extent descriptor functions
3
 *
4
 * Copyright (C) 2015-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 "libphdi_extent_descriptor.h"
27
#include "libphdi_extent_values.h"
28
#include "libphdi_libcerror.h"
29
#include "libphdi_libcthreads.h"
30
#include "libphdi_image_descriptor.h"
31
#include "libphdi_image_values.h"
32
#include "libphdi_types.h"
33
34
/* Creates an extent descriptor
35
 * Make sure the value extent_descriptor is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libphdi_extent_descriptor_initialize(
39
     libphdi_extent_descriptor_t **extent_descriptor,
40
     libphdi_extent_values_t *extent_values,
41
     libcerror_error_t **error )
42
0
{
43
0
  libphdi_internal_extent_descriptor_t *internal_extent_descriptor = NULL;
44
0
  static char *function                                            = "libphdi_extent_descriptor_initialize";
45
46
0
  if( extent_descriptor == 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 extent descriptor.",
53
0
     function );
54
55
0
    return( -1 );
56
0
  }
57
0
  if( *extent_descriptor != 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 extent descriptor value already set.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
0
  if( extent_values == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
73
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
74
0
     "%s: invalid extent values.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
0
  internal_extent_descriptor = memory_allocate_structure(
80
0
                                libphdi_internal_extent_descriptor_t );
81
82
0
  if( internal_extent_descriptor == 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 extent descriptor.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
0
  if( memory_set(
94
0
       internal_extent_descriptor,
95
0
       0,
96
0
       sizeof( libphdi_internal_extent_descriptor_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 extent descriptor.",
103
0
     function );
104
105
0
    memory_free(
106
0
     internal_extent_descriptor );
107
108
0
    return( -1 );
109
0
  }
110
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
111
0
  if( libcthreads_read_write_lock_initialize(
112
0
       &( internal_extent_descriptor->read_write_lock ),
113
0
       error ) != 1 )
114
0
  {
115
0
    libcerror_error_set(
116
0
     error,
117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
118
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
119
0
     "%s: unable to initialize read/write lock.",
120
0
     function );
121
122
0
    goto on_error;
123
0
  }
124
0
#endif
125
0
  internal_extent_descriptor->extent_values = extent_values;
126
127
0
  *extent_descriptor = (libphdi_extent_descriptor_t *) internal_extent_descriptor;
128
129
0
  return( 1 );
130
131
0
on_error:
132
0
  if( internal_extent_descriptor != NULL )
133
0
  {
134
0
    memory_free(
135
0
     internal_extent_descriptor );
136
0
  }
137
0
  return( -1 );
138
0
}
139
140
/* Frees an extent descriptor
141
 * Returns 1 if successful or -1 on error
142
 */
143
int libphdi_extent_descriptor_free(
144
     libphdi_extent_descriptor_t **extent_descriptor,
145
     libcerror_error_t **error )
146
0
{
147
0
  libphdi_internal_extent_descriptor_t *internal_extent_descriptor = NULL;
148
0
  static char *function                                            = "libphdi_extent_descriptor_free";
149
0
  int result                                                       = 1;
150
151
0
  if( extent_descriptor == 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 extent descriptor.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
0
  if( *extent_descriptor != NULL )
163
0
  {
164
0
    internal_extent_descriptor = (libphdi_internal_extent_descriptor_t *) *extent_descriptor;
165
0
    *extent_descriptor         = NULL;
166
167
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
168
0
    if( libcthreads_read_write_lock_free(
169
0
         &( internal_extent_descriptor->read_write_lock ),
170
0
         error ) != 1 )
171
0
    {
172
0
      libcerror_error_set(
173
0
       error,
174
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
176
0
       "%s: unable to free read/write lock.",
177
0
       function );
178
179
0
      result = -1;
180
0
    }
181
0
#endif
182
    /* The extent values reference is freed elsewhere
183
     */
184
0
    memory_free(
185
0
     internal_extent_descriptor );
186
0
  }
187
0
  return( result );
188
0
}
189
190
/* Retrieves the extent range (offset and size)
191
 * Returns 1 if successful or -1 on error
192
 */
193
int libphdi_extent_descriptor_get_range(
194
     libphdi_extent_descriptor_t *extent_descriptor,
195
     off64_t *offset,
196
     size64_t *size,
197
     libcerror_error_t **error )
198
0
{
199
0
  libphdi_internal_extent_descriptor_t *internal_extent_descriptor = NULL;
200
0
  static char *function                                            = "libphdi_extent_descriptor_get_range";
201
0
  int result                                                       = 1;
202
203
0
  if( extent_descriptor == NULL )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
208
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
209
0
     "%s: invalid extent descriptor.",
210
0
     function );
211
212
0
    return( -1 );
213
0
  }
214
0
  internal_extent_descriptor = (libphdi_internal_extent_descriptor_t *) extent_descriptor;
215
216
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
217
0
  if( libcthreads_read_write_lock_grab_for_read(
218
0
       internal_extent_descriptor->read_write_lock,
219
0
       error ) != 1 )
220
0
  {
221
0
    libcerror_error_set(
222
0
     error,
223
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
224
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
225
0
     "%s: unable to grab read/write lock for reading.",
226
0
     function );
227
228
0
    return( -1 );
229
0
  }
230
0
#endif
231
0
  if( libphdi_extent_values_get_range(
232
0
       internal_extent_descriptor->extent_values,
233
0
       offset,
234
0
       size,
235
0
       error ) != 1 )
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
240
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
241
0
     "%s: unable to retrieve range.",
242
0
     function );
243
244
0
    result = -1;
245
0
  }
246
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
247
0
  if( libcthreads_read_write_lock_release_for_read(
248
0
       internal_extent_descriptor->read_write_lock,
249
0
       error ) != 1 )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
254
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
255
0
     "%s: unable to release read/write lock for reading.",
256
0
     function );
257
258
0
    return( -1 );
259
0
  }
260
0
#endif
261
0
  return( result );
262
0
}
263
264
/* Retrieves the number of images
265
 * Returns 1 if successful or -1 on error
266
 */
267
int libphdi_extent_descriptor_get_number_of_images(
268
     libphdi_extent_descriptor_t *extent_descriptor,
269
     int *number_of_images,
270
     libcerror_error_t **error )
271
0
{
272
0
  libphdi_internal_extent_descriptor_t *internal_extent_descriptor = NULL;
273
0
  static char *function                                            = "libphdi_extent_descriptor_get_number_of_images";
274
0
  int result                                                       = 1;
275
276
0
  if( extent_descriptor == NULL )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
281
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
282
0
     "%s: invalid extent descriptor.",
283
0
     function );
284
285
0
    return( -1 );
286
0
  }
287
0
  internal_extent_descriptor = (libphdi_internal_extent_descriptor_t *) extent_descriptor;
288
289
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
290
0
  if( libcthreads_read_write_lock_grab_for_read(
291
0
       internal_extent_descriptor->read_write_lock,
292
0
       error ) != 1 )
293
0
  {
294
0
    libcerror_error_set(
295
0
     error,
296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
297
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
298
0
     "%s: unable to grab read/write lock for reading.",
299
0
     function );
300
301
0
    return( -1 );
302
0
  }
303
0
#endif
304
0
  if( libphdi_extent_values_get_number_of_images(
305
0
       internal_extent_descriptor->extent_values,
306
0
       number_of_images,
307
0
       error ) != 1 )
308
0
  {
309
0
    libcerror_error_set(
310
0
     error,
311
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
312
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
313
0
     "%s: unable to retrieve number of images from extent values.",
314
0
     function );
315
316
0
    result = -1;
317
0
  }
318
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
319
0
  if( libcthreads_read_write_lock_release_for_read(
320
0
       internal_extent_descriptor->read_write_lock,
321
0
       error ) != 1 )
322
0
  {
323
0
    libcerror_error_set(
324
0
     error,
325
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
326
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
327
0
     "%s: unable to release read/write lock for reading.",
328
0
     function );
329
330
0
    return( -1 );
331
0
  }
332
0
#endif
333
0
  return( result );
334
0
}
335
336
/* Retrieves a specific image descriptor
337
 * Returns 1 if successful or -1 on error
338
 */
339
int libphdi_extent_descriptor_get_image_descriptor_by_index(
340
     libphdi_extent_descriptor_t *extent_descriptor,
341
     int image_index,
342
     libphdi_image_descriptor_t **image_descriptor,
343
     libcerror_error_t **error )
344
0
{
345
0
  libphdi_image_values_t *image_values                             = NULL;
346
0
  libphdi_internal_extent_descriptor_t *internal_extent_descriptor = NULL;
347
0
  static char *function                                            = "libphdi_extent_descriptor_get_image_descriptor_by_index";
348
0
  int result                                                       = 1;
349
350
0
  if( extent_descriptor == NULL )
351
0
  {
352
0
    libcerror_error_set(
353
0
     error,
354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
355
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
356
0
     "%s: invalid extent descriptor.",
357
0
     function );
358
359
0
    return( -1 );
360
0
  }
361
0
  internal_extent_descriptor = (libphdi_internal_extent_descriptor_t *) extent_descriptor;
362
363
0
  if( image_descriptor == NULL )
364
0
  {
365
0
    libcerror_error_set(
366
0
     error,
367
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
368
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
369
0
     "%s: invalid image descriptor.",
370
0
     function );
371
372
0
    return( -1 );
373
0
  }
374
0
  if( *image_descriptor != NULL )
375
0
  {
376
0
    libcerror_error_set(
377
0
     error,
378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
379
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
380
0
     "%s: invalid image descriptor value already set.",
381
0
     function );
382
383
0
    return( -1 );
384
0
  }
385
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
386
0
  if( libcthreads_read_write_lock_grab_for_read(
387
0
       internal_extent_descriptor->read_write_lock,
388
0
       error ) != 1 )
389
0
  {
390
0
    libcerror_error_set(
391
0
     error,
392
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
393
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
394
0
     "%s: unable to grab read/write lock for reading.",
395
0
     function );
396
397
0
    return( -1 );
398
0
  }
399
0
#endif
400
0
  if( libphdi_extent_values_get_image_values_by_index(
401
0
       internal_extent_descriptor->extent_values,
402
0
       image_index,
403
0
       &image_values,
404
0
       error ) != 1 )
405
0
  {
406
0
    libcerror_error_set(
407
0
     error,
408
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
409
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
410
0
     "%s: unable to retrieve image: %d values from extent values.",
411
0
     function,
412
0
     image_index );
413
414
0
    result = -1;
415
0
  }
416
0
  else if( libphdi_image_descriptor_initialize(
417
0
            image_descriptor,
418
0
            image_values,
419
0
            error ) != 1 )
420
0
  {
421
0
    libcerror_error_set(
422
0
     error,
423
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
424
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
425
0
     "%s: unable to create image descriptor.",
426
0
     function );
427
428
0
    result = -1;
429
0
  }
430
0
#if defined( HAVE_LIBPHDI_MULTI_THREAD_SUPPORT )
431
0
  if( libcthreads_read_write_lock_release_for_read(
432
0
       internal_extent_descriptor->read_write_lock,
433
0
       error ) != 1 )
434
0
  {
435
0
    libcerror_error_set(
436
0
     error,
437
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
438
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
439
0
     "%s: unable to release read/write lock for reading.",
440
0
     function );
441
442
0
    return( -1 );
443
0
  }
444
0
#endif
445
0
  return( result );
446
0
}
447