Coverage Report

Created: 2025-12-05 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfvde/libfvde/libfvde_logical_volume_descriptor.c
Line
Count
Source
1
/*
2
 * Logical volume descriptor functions
3
 *
4
 * Copyright (C) 2011-2024, Omar Choudary <choudary.omar@gmail.com>
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfvde_libcdata.h"
28
#include "libfvde_libcerror.h"
29
#include "libfvde_libuna.h"
30
#include "libfvde_logical_volume_descriptor.h"
31
#include "libfvde_segment_descriptor.h"
32
33
/* Creates logical volume descriptor
34
 * Make sure the value logical_volume_descriptor is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libfvde_logical_volume_descriptor_initialize(
38
     libfvde_logical_volume_descriptor_t **logical_volume_descriptor,
39
     libcerror_error_t **error )
40
0
{
41
0
  static char *function = "libfvde_logical_volume_descriptor_initialize";
42
43
0
  if( logical_volume_descriptor == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid logical volume descriptor.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  if( *logical_volume_descriptor != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid logical volume descriptor value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
0
  *logical_volume_descriptor = memory_allocate_structure(
66
0
                                libfvde_logical_volume_descriptor_t );
67
68
0
  if( *logical_volume_descriptor == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to logical volume descriptor.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
0
  if( memory_set(
80
0
       *logical_volume_descriptor,
81
0
       0,
82
0
       sizeof( libfvde_logical_volume_descriptor_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear logical volume descriptor.",
89
0
     function );
90
91
0
    memory_free(
92
0
     *logical_volume_descriptor );
93
94
0
    *logical_volume_descriptor = NULL;
95
96
0
    return( -1 );
97
0
  }
98
0
  if( libcdata_array_initialize(
99
0
       &( ( *logical_volume_descriptor )->segment_descriptors ),
100
0
       0,
101
0
       error ) != 1 )
102
0
  {
103
0
    libcerror_error_set(
104
0
     error,
105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
106
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
107
0
     "%s: unable to create segment descriptors array.",
108
0
     function );
109
110
0
    goto on_error;
111
0
  }
112
0
  return( 1 );
113
114
0
on_error:
115
0
  if( *logical_volume_descriptor != NULL )
116
0
  {
117
0
    memory_free(
118
0
     *logical_volume_descriptor );
119
120
0
    *logical_volume_descriptor = NULL;
121
0
  }
122
0
  return( -1 );
123
0
}
124
125
/* Frees logical volume descriptor
126
 * Returns 1 if successful or -1 on error
127
 */
128
int libfvde_logical_volume_descriptor_free(
129
     libfvde_logical_volume_descriptor_t **logical_volume_descriptor,
130
     libcerror_error_t **error )
131
0
{
132
0
  static char *function = "libfvde_logical_volume_descriptor_free";
133
0
  int result            = 1;
134
135
0
  if( logical_volume_descriptor == NULL )
136
0
  {
137
0
    libcerror_error_set(
138
0
     error,
139
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
140
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
141
0
     "%s: invalid logical volume descriptor.",
142
0
     function );
143
144
0
    return( -1 );
145
0
  }
146
0
  if( *logical_volume_descriptor != NULL )
147
0
  {
148
0
    if( ( *logical_volume_descriptor )->name != NULL )
149
0
    {
150
0
      memory_free(
151
0
       ( *logical_volume_descriptor )->name );
152
0
    }
153
0
    if( libcdata_array_free(
154
0
         &( ( *logical_volume_descriptor )->segment_descriptors ),
155
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_segment_descriptor_free,
156
0
         error ) != 1 )
157
0
    {
158
0
      libcerror_error_set(
159
0
       error,
160
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
161
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
162
0
       "%s: unable to free segment descriptors array.",
163
0
       function );
164
165
0
      result = -1;
166
0
    }
167
0
    memory_free(
168
0
     *logical_volume_descriptor );
169
170
0
    *logical_volume_descriptor = NULL;
171
0
  }
172
0
  return( result );
173
0
}
174
175
/* Retrieves the identifier
176
 * The identifier is a UUID and is 16 bytes of size
177
 * Returns 1 if successful or -1 on error
178
 */
179
int libfvde_logical_volume_descriptor_get_identifier(
180
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
181
     uint8_t *uuid_data,
182
     size_t uuid_data_size,
183
     libcerror_error_t **error )
184
0
{
185
0
  static char *function = "libfvde_logical_volume_descriptor_get_identifier";
186
187
0
  if( logical_volume_descriptor == NULL )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
193
0
     "%s: invalid logical volume descriptor.",
194
0
     function );
195
196
0
    return( -1 );
197
0
  }
198
0
  if( uuid_data == NULL )
199
0
  {
200
0
    libcerror_error_set(
201
0
     error,
202
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
203
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
204
0
     "%s: invalid UUID data.",
205
0
     function );
206
207
0
    return( -1 );
208
0
  }
209
0
  if( ( uuid_data_size < 16 )
210
0
   || ( uuid_data_size > (size_t) SSIZE_MAX ) )
211
0
  {
212
0
    libcerror_error_set(
213
0
     error,
214
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
215
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
216
0
     "%s: invalid UUID data size value out of bounds.",
217
0
     function );
218
219
0
    return( -1 );
220
0
  }
221
0
  if( memory_copy(
222
0
       uuid_data,
223
0
       logical_volume_descriptor->identifier,
224
0
       16 ) == NULL )
225
0
  {
226
0
    libcerror_error_set(
227
0
     error,
228
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
229
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
230
0
     "%s: unable to copy identifier.",
231
0
     function );
232
233
0
    return( -1 );
234
0
  }
235
0
  return( 1 );
236
0
}
237
238
/* Retrieves the family identifier
239
 * The identifier is a UUID and is 16 bytes of size
240
 * Returns 1 if successful or -1 on error
241
 */
242
int libfvde_logical_volume_descriptor_get_family_identifier(
243
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
244
     uint8_t *uuid_data,
245
     size_t uuid_data_size,
246
     libcerror_error_t **error )
247
0
{
248
0
  static char *function = "libfvde_logical_volume_descriptor_get_family_identifier";
249
250
0
  if( logical_volume_descriptor == NULL )
251
0
  {
252
0
    libcerror_error_set(
253
0
     error,
254
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
255
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
256
0
     "%s: invalid logical volume descriptor.",
257
0
     function );
258
259
0
    return( -1 );
260
0
  }
261
0
  if( uuid_data == NULL )
262
0
  {
263
0
    libcerror_error_set(
264
0
     error,
265
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
266
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
267
0
     "%s: invalid UUID data.",
268
0
     function );
269
270
0
    return( -1 );
271
0
  }
272
0
  if( ( uuid_data_size < 16 )
273
0
   || ( uuid_data_size > (size_t) SSIZE_MAX ) )
274
0
  {
275
0
    libcerror_error_set(
276
0
     error,
277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
278
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
279
0
     "%s: invalid UUID data size value out of bounds.",
280
0
     function );
281
282
0
    return( -1 );
283
0
  }
284
0
  if( memory_copy(
285
0
       uuid_data,
286
0
       logical_volume_descriptor->family_identifier,
287
0
       16 ) == NULL )
288
0
  {
289
0
    libcerror_error_set(
290
0
     error,
291
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
292
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
293
0
     "%s: unable to copy family identifier.",
294
0
     function );
295
296
0
    return( -1 );
297
0
  }
298
0
  return( 1 );
299
0
}
300
301
/* Retrieves the size of the UTF-8 encoded volume group name
302
 * The returned size includes the end of string character
303
 * Returns 1 if successful, 0 if not available or -1 on error
304
 */
305
int libfvde_logical_volume_descriptor_get_utf8_name_size(
306
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
307
     size_t *utf8_string_size,
308
     libcerror_error_t **error )
309
0
{
310
0
  static char *function = "libfvde_logical_volume_descriptor_get_utf8_name_size";
311
312
0
  if( logical_volume_descriptor == NULL )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
317
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
318
0
     "%s: invalid logical volume descriptor.",
319
0
     function );
320
321
0
    return( -1 );
322
0
  }
323
0
  if( ( logical_volume_descriptor->name == NULL )
324
0
   || ( logical_volume_descriptor->name_size == 0 ) )
325
0
  {
326
0
    return( 0 );
327
0
  }
328
0
  if( libuna_utf8_string_size_from_utf8_stream(
329
0
       logical_volume_descriptor->name,
330
0
       logical_volume_descriptor->name_size,
331
0
       utf8_string_size,
332
0
       error ) != 1 )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
337
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
338
0
     "%s: unable to retrieve UTF-8 string size.",
339
0
     function );
340
341
0
    return( -1 );
342
0
  }
343
0
  return( 1 );
344
0
}
345
346
/* Retrieves the UTF-8 encoded volume group name
347
 * The size should include the end of string character
348
 * Returns 1 if successful, 0 if not available or -1 on error
349
 */
350
int libfvde_logical_volume_descriptor_get_utf8_name(
351
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
352
     uint8_t *utf8_string,
353
     size_t utf8_string_size,
354
     libcerror_error_t **error )
355
0
{
356
0
  static char *function = "libfvde_logical_volume_descriptor_get_utf8_name";
357
358
0
  if( logical_volume_descriptor == NULL )
359
0
  {
360
0
    libcerror_error_set(
361
0
     error,
362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
364
0
     "%s: invalid logical volume descriptor.",
365
0
     function );
366
367
0
    return( -1 );
368
0
  }
369
0
  if( ( logical_volume_descriptor->name == NULL )
370
0
   || ( logical_volume_descriptor->name_size == 0 ) )
371
0
  {
372
0
    return( 0 );
373
0
  }
374
0
  if( libuna_utf8_string_copy_from_utf8_stream(
375
0
       utf8_string,
376
0
       utf8_string_size,
377
0
       logical_volume_descriptor->name,
378
0
       logical_volume_descriptor->name_size,
379
0
       error ) != 1 )
380
0
  {
381
0
    libcerror_error_set(
382
0
     error,
383
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
384
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
385
0
     "%s: unable to retrieve UTF-8 string.",
386
0
     function );
387
388
0
    return( -1 );
389
0
  }
390
0
  return( 1 );
391
0
}
392
393
/* Retrieves the size of the UTF-16 encoded volume group name
394
 * The returned size includes the end of string character
395
 * Returns 1 if successful, 0 if not available or -1 on error
396
 */
397
int libfvde_logical_volume_descriptor_get_utf16_name_size(
398
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
399
     size_t *utf16_string_size,
400
     libcerror_error_t **error )
401
0
{
402
0
  static char *function = "libfvde_logical_volume_descriptor_get_utf16_name_size";
403
404
0
  if( logical_volume_descriptor == NULL )
405
0
  {
406
0
    libcerror_error_set(
407
0
     error,
408
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
409
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
410
0
     "%s: invalid logical volume descriptor.",
411
0
     function );
412
413
0
    return( -1 );
414
0
  }
415
0
  if( ( logical_volume_descriptor->name == NULL )
416
0
   || ( logical_volume_descriptor->name_size == 0 ) )
417
0
  {
418
0
    return( 0 );
419
0
  }
420
0
  if( libuna_utf16_string_size_from_utf8_stream(
421
0
       logical_volume_descriptor->name,
422
0
       logical_volume_descriptor->name_size,
423
0
       utf16_string_size,
424
0
       error ) != 1 )
425
0
  {
426
0
    libcerror_error_set(
427
0
     error,
428
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
429
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
430
0
     "%s: unable to retrieve UTF-16 string size.",
431
0
     function );
432
433
0
    return( -1 );
434
0
  }
435
0
  return( 1 );
436
0
}
437
438
/* Retrieves the UTF-16 encoded volume group name
439
 * The size should include the end of string character
440
 * Returns 1 if successful, 0 if not available or -1 on error
441
 */
442
int libfvde_logical_volume_descriptor_get_utf16_name(
443
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
444
     uint16_t *utf16_string,
445
     size_t utf16_string_size,
446
     libcerror_error_t **error )
447
0
{
448
0
  static char *function = "libfvde_logical_volume_descriptor_get_utf16_name";
449
450
0
  if( logical_volume_descriptor == NULL )
451
0
  {
452
0
    libcerror_error_set(
453
0
     error,
454
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
455
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
456
0
     "%s: invalid logical volume descriptor.",
457
0
     function );
458
459
0
    return( -1 );
460
0
  }
461
0
  if( ( logical_volume_descriptor->name == NULL )
462
0
   || ( logical_volume_descriptor->name_size == 0 ) )
463
0
  {
464
0
    return( 0 );
465
0
  }
466
0
  if( libuna_utf16_string_copy_from_utf8_stream(
467
0
       utf16_string,
468
0
       utf16_string_size,
469
0
       logical_volume_descriptor->name,
470
0
       logical_volume_descriptor->name_size,
471
0
       error ) != 1 )
472
0
  {
473
0
    libcerror_error_set(
474
0
     error,
475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
476
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
477
0
     "%s: unable to retrieve UTF-16 string.",
478
0
     function );
479
480
0
    return( -1 );
481
0
  }
482
0
  return( 1 );
483
0
}
484
485
/* Retrieves the size
486
 * Returns 1 if successful or -1 on error
487
 */
488
int libfvde_logical_volume_descriptor_get_size(
489
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
490
     size64_t *size,
491
     libcerror_error_t **error )
492
0
{
493
0
  static char *function = "libfvde_logical_volume_descriptor_get_size";
494
495
0
  if( logical_volume_descriptor == NULL )
496
0
  {
497
0
    libcerror_error_set(
498
0
     error,
499
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
500
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
501
0
     "%s: invalid logical volume descriptor.",
502
0
     function );
503
504
0
    return( -1 );
505
0
  }
506
0
  if( size == NULL )
507
0
  {
508
0
    libcerror_error_set(
509
0
     error,
510
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
511
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
512
0
     "%s: invalid size.",
513
0
     function );
514
515
0
    return( -1 );
516
0
  }
517
0
  *size = logical_volume_descriptor->size;
518
519
0
  return( 1 );
520
0
}
521
522
/* Retrieves the first block number
523
 * Returns 1 if successful or -1 on error
524
 */
525
int libfvde_logical_volume_descriptor_get_first_block_number(
526
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
527
     uint16_t *volume_index,
528
     uint64_t *block_number,
529
     libcerror_error_t **error )
530
0
{
531
0
  libfvde_segment_descriptor_t *segment_descriptor = NULL;
532
0
  static char *function                            = "libfvde_logical_volume_descriptor_get_first_block_number";
533
534
0
  if( logical_volume_descriptor == NULL )
535
0
  {
536
0
    libcerror_error_set(
537
0
     error,
538
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
539
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
540
0
     "%s: invalid logical volume descriptor.",
541
0
     function );
542
543
0
    return( -1 );
544
0
  }
545
0
  if( volume_index == NULL )
546
0
  {
547
0
    libcerror_error_set(
548
0
     error,
549
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
550
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
551
0
     "%s: invalid volume index.",
552
0
     function );
553
554
0
    return( -1 );
555
0
  }
556
0
  if( block_number == NULL )
557
0
  {
558
0
    libcerror_error_set(
559
0
     error,
560
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
561
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
562
0
     "%s: invalid block number.",
563
0
     function );
564
565
0
    return( -1 );
566
0
  }
567
0
  if( libcdata_array_get_entry_by_index(
568
0
       logical_volume_descriptor->segment_descriptors,
569
0
       0,
570
0
       (intptr_t **) &segment_descriptor,
571
0
       error ) != 1 )
572
0
  {
573
0
    libcerror_error_set(
574
0
     error,
575
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
576
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
577
0
     "%s: unable to retrieve segment descriptor: 0 from array.",
578
0
     function );
579
580
0
    return( -1 );
581
0
  }
582
0
  if( segment_descriptor == NULL )
583
0
  {
584
0
    libcerror_error_set(
585
0
     error,
586
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
587
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
588
0
     "%s: missing segment descriptor: 0.",
589
0
     function );
590
591
0
    return( -1 );
592
0
  }
593
0
  *volume_index = segment_descriptor->physical_volume_index;
594
0
  *block_number = logical_volume_descriptor->base_physical_block_number + segment_descriptor->physical_block_number;
595
596
0
  return( 1 );
597
0
}
598
599
/* Retrieves the last block number
600
 * Returns 1 if successful or -1 on error
601
 */
602
int libfvde_logical_volume_descriptor_get_last_block_number(
603
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
604
     uint16_t *volume_index,
605
     uint64_t *block_number,
606
     libcerror_error_t **error )
607
0
{
608
0
  libfvde_segment_descriptor_t *segment_descriptor = NULL;
609
0
  static char *function                            = "libfvde_logical_volume_descriptor_get_last_block_number";
610
0
  int number_of_segment_descriptors                = 0;
611
612
0
  if( logical_volume_descriptor == NULL )
613
0
  {
614
0
    libcerror_error_set(
615
0
     error,
616
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
617
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
618
0
     "%s: invalid logical volume descriptor.",
619
0
     function );
620
621
0
    return( -1 );
622
0
  }
623
0
  if( volume_index == NULL )
624
0
  {
625
0
    libcerror_error_set(
626
0
     error,
627
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
628
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
629
0
     "%s: invalid volume index.",
630
0
     function );
631
632
0
    return( -1 );
633
0
  }
634
0
  if( block_number == NULL )
635
0
  {
636
0
    libcerror_error_set(
637
0
     error,
638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
639
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
640
0
     "%s: invalid block number.",
641
0
     function );
642
643
0
    return( -1 );
644
0
  }
645
0
  if( libcdata_array_get_number_of_entries(
646
0
       logical_volume_descriptor->segment_descriptors,
647
0
       &number_of_segment_descriptors,
648
0
       error ) != 1 )
649
0
  {
650
0
    libcerror_error_set(
651
0
     error,
652
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
653
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
654
0
     "%s: unable to retrieve number of segment descriptors from array.",
655
0
     function );
656
657
0
    return( -1 );
658
0
  }
659
0
  number_of_segment_descriptors -= 1;
660
661
0
  if( libcdata_array_get_entry_by_index(
662
0
       logical_volume_descriptor->segment_descriptors,
663
0
       number_of_segment_descriptors,
664
0
       (intptr_t **) &segment_descriptor,
665
0
       error ) != 1 )
666
0
  {
667
0
    libcerror_error_set(
668
0
     error,
669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
670
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
671
0
     "%s: unable to retrieve segment descriptor: %d from array.",
672
0
     function,
673
0
     number_of_segment_descriptors );
674
675
0
    return( -1 );
676
0
  }
677
0
  if( segment_descriptor == NULL )
678
0
  {
679
0
    libcerror_error_set(
680
0
     error,
681
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
682
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
683
0
     "%s: missing segment descriptor: %d.",
684
0
     function,
685
0
     number_of_segment_descriptors );
686
687
0
    return( -1 );
688
0
  }
689
0
  *volume_index = segment_descriptor->physical_volume_index;
690
0
  *block_number = logical_volume_descriptor->base_physical_block_number + segment_descriptor->physical_block_number + segment_descriptor->number_of_blocks;
691
692
0
  return( 1 );
693
0
}
694
695
/* Retrieves the number of segment descriptors
696
 * Returns 1 if successful or -1 on error
697
 */
698
int libfvde_logical_volume_descriptor_get_number_of_segment_descriptors(
699
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
700
     int *number_of_segment_descriptors,
701
     libcerror_error_t **error )
702
0
{
703
0
  static char *function = "libfvde_logical_volume_descriptor_get_number_of_segment_descriptors";
704
705
0
  if( logical_volume_descriptor == NULL )
706
0
  {
707
0
    libcerror_error_set(
708
0
     error,
709
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
710
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
711
0
     "%s: invalid logical volume descriptor.",
712
0
     function );
713
714
0
    return( -1 );
715
0
  }
716
0
  if( libcdata_array_get_number_of_entries(
717
0
       logical_volume_descriptor->segment_descriptors,
718
0
       number_of_segment_descriptors,
719
0
       error ) != 1 )
720
0
  {
721
0
    libcerror_error_set(
722
0
     error,
723
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
724
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
725
0
     "%s: unable to retrieve number of segment descriptors from array.",
726
0
     function );
727
728
0
    return( -1 );
729
0
  }
730
0
  return( 1 );
731
0
}
732
733
/* Retrieves a specific segment descriptor
734
 * Returns 1 if successful or -1 on error
735
 */
736
int libfvde_logical_volume_descriptor_get_segment_descriptor_by_index(
737
     libfvde_logical_volume_descriptor_t *logical_volume_descriptor,
738
     int segment_index,
739
     libfvde_segment_descriptor_t **segment_descriptor,
740
     libcerror_error_t **error )
741
0
{
742
0
  static char *function = "libfvde_logical_volume_descriptor_get_segment_descriptor_by_index";
743
744
0
  if( logical_volume_descriptor == NULL )
745
0
  {
746
0
    libcerror_error_set(
747
0
     error,
748
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
749
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
750
0
     "%s: invalid logical volume descriptor.",
751
0
     function );
752
753
0
    return( -1 );
754
0
  }
755
0
  if( libcdata_array_get_entry_by_index(
756
0
       logical_volume_descriptor->segment_descriptors,
757
0
       segment_index,
758
0
       (intptr_t **) segment_descriptor,
759
0
       error ) != 1 )
760
0
  {
761
0
    libcerror_error_set(
762
0
     error,
763
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
764
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
765
0
     "%s: unable to retrieve segment descriptor: %d from array.",
766
0
     function,
767
0
     segment_index );
768
769
0
    return( -1 );
770
0
  }
771
0
  return( 1 );
772
0
}