Coverage Report

Created: 2024-06-12 07:07

/src/libvslvm/libvslvm/libvslvm_physical_volume.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Physical volume functions
3
 *
4
 * Copyright (C) 2014-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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libvslvm_checksum.h"
28
#include "libvslvm_data_area_descriptor.h"
29
#include "libvslvm_libbfio.h"
30
#include "libvslvm_libcdata.h"
31
#include "libvslvm_libcerror.h"
32
#include "libvslvm_libcnotify.h"
33
#include "libvslvm_physical_volume.h"
34
#include "libvslvm_types.h"
35
#include "libvslvm_unused.h"
36
37
#include "vslvm_physical_volume_label.h"
38
39
const char *vslvm_physical_volume_label_signature = "LABELONE";
40
41
const uint8_t vslvm_empty_data_area_descriptor[ 16 ] = {
42
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
43
44
/* Creates a physical volume
45
 * Make sure the value physical_volume is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libvslvm_physical_volume_initialize(
49
     libvslvm_physical_volume_t **physical_volume,
50
     libcerror_error_t **error )
51
47.0k
{
52
47.0k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
53
47.0k
  static char *function                                         = "libvslvm_physical_volume_initialize";
54
55
47.0k
  if( physical_volume == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid physical volume.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
47.0k
  if( *physical_volume != NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72
0
     "%s: invalid physical volume value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
47.0k
  internal_physical_volume = memory_allocate_structure(
78
47.0k
                              libvslvm_internal_physical_volume_t );
79
80
47.0k
  if( internal_physical_volume == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create physical volume.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
47.0k
  if( memory_set(
92
47.0k
       internal_physical_volume,
93
47.0k
       0,
94
47.0k
       sizeof( libvslvm_internal_physical_volume_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear physical volume.",
101
0
     function );
102
103
0
    memory_free(
104
0
     internal_physical_volume );
105
106
0
    return( -1 );
107
0
  }
108
47.0k
  if( libcdata_array_initialize(
109
47.0k
       &( internal_physical_volume->data_area_descriptors_array ),
110
47.0k
       0,
111
47.0k
       error ) != 1 )
112
0
  {
113
0
    libcerror_error_set(
114
0
     error,
115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
117
0
     "%s: unable to create data area descripors array.",
118
0
     function );
119
120
0
    goto on_error;
121
0
  }
122
47.0k
  if( libcdata_array_initialize(
123
47.0k
       &( internal_physical_volume->metadata_area_descriptors_array ),
124
47.0k
       0,
125
47.0k
       error ) != 1 )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
130
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
131
0
     "%s: unable to create metadata area descripors array.",
132
0
     function );
133
134
0
    goto on_error;
135
0
  }
136
47.0k
  *physical_volume= (libvslvm_physical_volume_t *) internal_physical_volume;
137
138
47.0k
  return( 1 );
139
140
0
on_error:
141
0
  if( internal_physical_volume != NULL )
142
0
  {
143
0
    if( internal_physical_volume->data_area_descriptors_array != NULL )
144
0
    {
145
0
      libcdata_array_free(
146
0
       &( internal_physical_volume->data_area_descriptors_array ),
147
0
       NULL,
148
0
       NULL );
149
0
    }
150
0
    memory_free(
151
0
     internal_physical_volume );
152
0
  }
153
0
  return( -1 );
154
47.0k
}
155
156
/* Frees a physical volume
157
 * Returns 1 if successful or -1 on error
158
 */
159
int libvslvm_physical_volume_free(
160
     libvslvm_physical_volume_t **physical_volume,
161
     libcerror_error_t **error )
162
0
{
163
0
  static char *function = "libvslvm_physical_volume_free";
164
165
0
  if( physical_volume == NULL )
166
0
  {
167
0
    libcerror_error_set(
168
0
     error,
169
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171
0
     "%s: invalid physical volume.",
172
0
     function );
173
174
0
    return( -1 );
175
0
  }
176
0
  if( *physical_volume != NULL )
177
0
  {
178
0
    *physical_volume = NULL;
179
0
  }
180
0
  return( 1 );
181
0
}
182
183
/* Frees a physical volume
184
 * Returns 1 if successful or -1 on error
185
 */
186
int libvslvm_internal_physical_volume_free(
187
     libvslvm_internal_physical_volume_t **internal_physical_volume,
188
     libcerror_error_t **error )
189
47.0k
{
190
47.0k
  static char *function = "libvslvm_internal_physical_volume_free";
191
47.0k
  int result            = 1;
192
193
47.0k
  if( internal_physical_volume == NULL )
194
0
  {
195
0
    libcerror_error_set(
196
0
     error,
197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
199
0
     "%s: invalid physical volume.",
200
0
     function );
201
202
0
    return( -1 );
203
0
  }
204
47.0k
  if( *internal_physical_volume != NULL )
205
47.0k
  {
206
47.0k
    if( ( *internal_physical_volume )->name != NULL )
207
41.0k
    {
208
41.0k
      memory_free(
209
41.0k
       ( *internal_physical_volume )->name );
210
41.0k
    }
211
47.0k
    if( ( *internal_physical_volume )->device_path != NULL )
212
504
    {
213
504
      memory_free(
214
504
       ( *internal_physical_volume )->device_path );
215
504
    }
216
47.0k
    if( libcdata_array_free(
217
47.0k
         &( ( *internal_physical_volume )->data_area_descriptors_array ),
218
47.0k
         (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
219
47.0k
         error ) != 1 )
220
0
    {
221
0
      libcerror_error_set(
222
0
       error,
223
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
224
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
225
0
       "%s: unable to free data area descriptors array.",
226
0
       function );
227
228
0
      result = -1;
229
0
    }
230
47.0k
    if( libcdata_array_free(
231
47.0k
         &( ( *internal_physical_volume )->metadata_area_descriptors_array ),
232
47.0k
         (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
233
47.0k
         error ) != 1 )
234
0
    {
235
0
      libcerror_error_set(
236
0
       error,
237
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
238
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
239
0
       "%s: unable to free metadata area descriptors array.",
240
0
       function );
241
242
0
      result = -1;
243
0
    }
244
47.0k
    memory_free(
245
47.0k
     *internal_physical_volume );
246
247
47.0k
    *internal_physical_volume = NULL;
248
47.0k
  }
249
47.0k
  return( result );
250
47.0k
}
251
252
/* Retrieves the size of the ASCII formatted name
253
 * Returns 1 if successful or -1 on error
254
 */
255
int libvslvm_physical_volume_get_name_size(
256
     libvslvm_physical_volume_t *physical_volume,
257
     size_t *name_size,
258
     libcerror_error_t **error )
259
0
{
260
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
261
0
  static char *function                                         = "libvslvm_physical_volume_get_name_size";
262
263
0
  if( physical_volume == NULL )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
269
0
     "%s: invalid physical volume.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
275
276
0
  if( name_size == 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 name size.",
283
0
     function );
284
285
0
    return( -1 );
286
0
  }
287
0
  *name_size = internal_physical_volume->name_size;
288
289
0
  return( 1 );
290
0
}
291
292
/* Retrieves the ASCII formatted name
293
 * Returns 1 if successful or -1 on error
294
 */
295
int libvslvm_physical_volume_get_name(
296
     libvslvm_physical_volume_t *physical_volume,
297
     char *name,
298
     size_t name_size,
299
     libcerror_error_t **error )
300
0
{
301
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
302
0
  static char *function                                         = "libvslvm_physical_volume_get_name";
303
304
0
  if( physical_volume == NULL )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
310
0
     "%s: invalid physical volume.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
316
317
0
  if( name == NULL )
318
0
  {
319
0
    libcerror_error_set(
320
0
     error,
321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
323
0
     "%s: invalid name.",
324
0
     function );
325
326
0
    return( -1 );
327
0
  }
328
0
  if( name_size > (size_t) SSIZE_MAX )
329
0
  {
330
0
    libcerror_error_set(
331
0
     error,
332
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
333
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
334
0
     "%s: invalid name size value exceeds maximum.",
335
0
     function );
336
337
0
    return( -1 );
338
0
  }
339
0
  if( name_size < internal_physical_volume->name_size )
340
0
  {
341
0
    libcerror_error_set(
342
0
     error,
343
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
344
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
345
0
     "%s: invalid name size value too small.",
346
0
     function );
347
348
0
    return( -1 );
349
0
  }
350
0
  if( memory_copy(
351
0
       name,
352
0
       internal_physical_volume->name,
353
0
       internal_physical_volume->name_size ) == NULL )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
358
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
359
0
     "%s: unable to copy name.",
360
0
     function );
361
362
0
    return( -1 );
363
0
  }
364
0
  name[ internal_physical_volume->name_size - 1 ] = 0;
365
366
0
  return( 1 );
367
0
}
368
369
/* Sets the name
370
 * Returns 1 if successful or -1 on error
371
 */
372
int libvslvm_physical_volume_set_name(
373
     libvslvm_physical_volume_t *physical_volume,
374
     const char *name,
375
     size_t name_size,
376
     libcerror_error_t **error )
377
41.0k
{
378
41.0k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
379
41.0k
  static char *function                                         = "libvslvm_physical_volume_set_name";
380
381
41.0k
  if( physical_volume == NULL )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
386
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
387
0
     "%s: invalid physical volume.",
388
0
     function );
389
390
0
    return( -1 );
391
0
  }
392
41.0k
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
393
394
41.0k
  if( name == NULL )
395
0
  {
396
0
    libcerror_error_set(
397
0
     error,
398
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
399
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
400
0
     "%s: invalid name.",
401
0
     function );
402
403
0
    return( -1 );
404
0
  }
405
41.0k
  if( ( name_size == 0 )
406
41.0k
   || ( name_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
407
0
  {
408
0
    libcerror_error_set(
409
0
     error,
410
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
411
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
412
0
     "%s: invalid name size value out of bounds.",
413
0
     function );
414
415
0
    return( -1 );
416
0
  }
417
41.0k
  if( internal_physical_volume->name != NULL )
418
0
  {
419
0
    memory_free(
420
0
     internal_physical_volume->name );
421
422
0
    internal_physical_volume->name      = NULL;
423
0
    internal_physical_volume->name_size = 0;
424
0
  }
425
41.0k
  internal_physical_volume->name = (char *) memory_allocate(
426
41.0k
                                             sizeof( char ) * name_size );
427
428
41.0k
  if( internal_physical_volume->name == NULL )
429
0
  {
430
0
    libcerror_error_set(
431
0
     error,
432
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
433
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
434
0
     "%s: unable to create name.",
435
0
     function );
436
437
0
    goto on_error;
438
0
  }
439
41.0k
  if( memory_copy(
440
41.0k
       internal_physical_volume->name,
441
41.0k
       name,
442
41.0k
       name_size ) == NULL )
443
0
  {
444
0
    libcerror_error_set(
445
0
     error,
446
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
447
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
448
0
     "%s: unable to copy name.",
449
0
     function );
450
451
0
    goto on_error;
452
0
  }
453
41.0k
  internal_physical_volume->name[ name_size - 1 ] = 0;
454
455
41.0k
  internal_physical_volume->name_size = name_size;
456
457
41.0k
  return( 1 );
458
459
0
on_error:
460
0
  if( internal_physical_volume->name != NULL )
461
0
  {
462
0
    memory_free(
463
0
     internal_physical_volume->name );
464
465
0
    internal_physical_volume->name = NULL;
466
0
  }
467
0
  internal_physical_volume->name_size = 0;
468
469
0
  return( -1 );
470
41.0k
}
471
472
/* Compares the name with that of the physical volume
473
 * Returns 1 if the name matches, 0 if not or -1 on error
474
 */
475
int libvslvm_physical_volume_compare_by_name(
476
     libvslvm_physical_volume_t *physical_volume,
477
     const char *name,
478
     size_t name_length,
479
     libcerror_error_t **error )
480
224
{
481
224
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
482
224
  static char *function                                         = "libvslvm_physical_volume_compare_by_name";
483
484
224
  if( physical_volume == NULL )
485
0
  {
486
0
    libcerror_error_set(
487
0
     error,
488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
490
0
     "%s: invalid physical volume.",
491
0
     function );
492
493
0
    return( -1 );
494
0
  }
495
224
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
496
497
224
  if( name == NULL )
498
0
  {
499
0
    libcerror_error_set(
500
0
     error,
501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
502
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
503
0
     "%s: invalid name.",
504
0
     function );
505
506
0
    return( -1 );
507
0
  }
508
224
  if( name_length > (size_t) ( SSIZE_MAX - 1 ) )
509
0
  {
510
0
    libcerror_error_set(
511
0
     error,
512
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
513
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
514
0
     "%s: name length value exceeds maximum.",
515
0
     function );
516
517
0
    return( -1 );
518
0
  }
519
224
  if( ( internal_physical_volume->name_size == ( name_length + 1 ) )
520
224
   && ( memory_compare(
521
189
         name,
522
189
         internal_physical_volume->name,
523
189
         internal_physical_volume->name_size ) == 0 ) )
524
159
  {
525
159
    return( 1 );
526
159
  }
527
65
  return( 0 );
528
224
}
529
530
/* Retrieves the size of the ASCII formatted identifier
531
 * Returns 1 if successful or -1 on error
532
 */
533
int libvslvm_physical_volume_get_identifier_size(
534
     libvslvm_physical_volume_t *physical_volume,
535
     size_t *identifier_size,
536
     libcerror_error_t **error )
537
0
{
538
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
539
0
  static char *function                                         = "libvslvm_physical_volume_get_identifier_size";
540
541
0
  if( physical_volume == NULL )
542
0
  {
543
0
    libcerror_error_set(
544
0
     error,
545
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
546
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
547
0
     "%s: invalid physical volume.",
548
0
     function );
549
550
0
    return( -1 );
551
0
  }
552
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
553
554
0
  if( identifier_size == NULL )
555
0
  {
556
0
    libcerror_error_set(
557
0
     error,
558
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
560
0
     "%s: invalid identifier size.",
561
0
     function );
562
563
0
    return( -1 );
564
0
  }
565
0
  if( internal_physical_volume->identifier[ 0 ] == 0 )
566
0
  {
567
0
    *identifier_size = 0;
568
0
  }
569
0
  else
570
0
  {
571
0
    *identifier_size = 39;
572
0
  }
573
0
  return( 1 );
574
0
}
575
576
/* Retrieves the ASCII formatted identifier
577
 * Returns 1 if successful or -1 on error
578
 */
579
int libvslvm_physical_volume_get_identifier(
580
     libvslvm_physical_volume_t *physical_volume,
581
     char *identifier,
582
     size_t identifier_size,
583
     libcerror_error_t **error )
584
0
{
585
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
586
0
  static char *function                                         = "libvslvm_physical_volume_set_identifier";
587
588
0
  if( physical_volume == NULL )
589
0
  {
590
0
    libcerror_error_set(
591
0
     error,
592
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
593
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
594
0
     "%s: invalid physical volume.",
595
0
     function );
596
597
0
    return( -1 );
598
0
  }
599
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
600
601
0
  if( identifier == NULL )
602
0
  {
603
0
    libcerror_error_set(
604
0
     error,
605
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
606
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
607
0
     "%s: invalid identifier.",
608
0
     function );
609
610
0
    return( -1 );
611
0
  }
612
0
  if( identifier_size > (size_t) SSIZE_MAX )
613
0
  {
614
0
    libcerror_error_set(
615
0
     error,
616
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
617
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
618
0
     "%s: invalid identifier size value exceeds maximum.",
619
0
     function );
620
621
0
    return( -1 );
622
0
  }
623
0
  if( identifier_size < 39 )
624
0
  {
625
0
    libcerror_error_set(
626
0
     error,
627
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
628
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
629
0
     "%s: invalid identifier size value too small.",
630
0
     function );
631
632
0
    return( -1 );
633
0
  }
634
0
  if( memory_copy(
635
0
       identifier,
636
0
       internal_physical_volume->identifier,
637
0
       39 ) == NULL )
638
0
  {
639
0
    libcerror_error_set(
640
0
     error,
641
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
642
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
643
0
     "%s: unable to copy identifier.",
644
0
     function );
645
646
0
    return( -1 );
647
0
  }
648
0
  identifier[ 38 ] = 0;
649
650
0
  return( 1 );
651
0
}
652
653
/* Sets the identifier
654
 * Returns 1 if successful or -1 on error
655
 */
656
int libvslvm_physical_volume_set_identifier(
657
     libvslvm_physical_volume_t *physical_volume,
658
     const char *identifier,
659
     size_t identifier_size,
660
     libcerror_error_t **error )
661
803
{
662
803
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
663
803
  static char *function                                         = "libvslvm_physical_volume_set_identifier";
664
665
803
  if( physical_volume == NULL )
666
0
  {
667
0
    libcerror_error_set(
668
0
     error,
669
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
670
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
671
0
     "%s: invalid physical volume.",
672
0
     function );
673
674
0
    return( -1 );
675
0
  }
676
803
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
677
678
803
  if( identifier == NULL )
679
0
  {
680
0
    libcerror_error_set(
681
0
     error,
682
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
683
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
684
0
     "%s: invalid identifier.",
685
0
     function );
686
687
0
    return( -1 );
688
0
  }
689
803
  if( identifier_size != 39 )
690
68
  {
691
68
    libcerror_error_set(
692
68
     error,
693
68
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
694
68
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
695
68
     "%s: identifier size value out of bounds.",
696
68
     function );
697
698
68
    return( -1 );
699
68
  }
700
735
  if( memory_copy(
701
735
       internal_physical_volume->identifier,
702
735
       identifier,
703
735
       39 ) == NULL )
704
0
  {
705
0
    libcerror_error_set(
706
0
     error,
707
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
708
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
709
0
     "%s: unable to copy identifier.",
710
0
     function );
711
712
0
    return( -1 );
713
0
  }
714
735
  internal_physical_volume->identifier[ 38 ] = 0;
715
716
735
  return( 1 );
717
735
}
718
719
/* Retrieves the size of the ASCII formatted device path
720
 * Returns 1 if successful or -1 on error
721
 */
722
int libvslvm_physical_volume_get_device_path_size(
723
     libvslvm_physical_volume_t *physical_volume,
724
     size_t *device_path_size,
725
     libcerror_error_t **error )
726
0
{
727
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
728
0
  static char *function                                         = "libvslvm_physical_volume_get_device_path_size";
729
730
0
  if( physical_volume == NULL )
731
0
  {
732
0
    libcerror_error_set(
733
0
     error,
734
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
735
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
736
0
     "%s: invalid physical volume.",
737
0
     function );
738
739
0
    return( -1 );
740
0
  }
741
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
742
743
0
  if( device_path_size == NULL )
744
0
  {
745
0
    libcerror_error_set(
746
0
     error,
747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
749
0
     "%s: invalid device path size.",
750
0
     function );
751
752
0
    return( -1 );
753
0
  }
754
0
  *device_path_size = internal_physical_volume->device_path_size;
755
756
0
  return( 1 );
757
0
}
758
759
/* Retrieves the ASCII formatted device path
760
 * Returns 1 if successful or -1 on error
761
 */
762
int libvslvm_physical_volume_get_device_path(
763
     libvslvm_physical_volume_t *physical_volume,
764
     char *device_path,
765
     size_t device_path_size,
766
     libcerror_error_t **error )
767
0
{
768
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
769
0
  static char *function                                         = "libvslvm_physical_volume_set_device_path";
770
771
0
  if( physical_volume == NULL )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
776
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
777
0
     "%s: invalid physical volume.",
778
0
     function );
779
780
0
    return( -1 );
781
0
  }
782
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
783
784
0
  if( device_path == NULL )
785
0
  {
786
0
    libcerror_error_set(
787
0
     error,
788
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
789
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
790
0
     "%s: invalid device_path.",
791
0
     function );
792
793
0
    return( -1 );
794
0
  }
795
0
  if( device_path_size > (size_t) SSIZE_MAX )
796
0
  {
797
0
    libcerror_error_set(
798
0
     error,
799
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
800
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
801
0
     "%s: invalid device path size value exceeds maximum.",
802
0
     function );
803
804
0
    return( -1 );
805
0
  }
806
0
  if( device_path_size < internal_physical_volume->device_path_size )
807
0
  {
808
0
    libcerror_error_set(
809
0
     error,
810
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
811
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
812
0
     "%s: invalid device path size value too small.",
813
0
     function );
814
815
0
    return( -1 );
816
0
  }
817
0
  if( memory_copy(
818
0
       device_path,
819
0
       internal_physical_volume->device_path,
820
0
       internal_physical_volume->device_path_size ) == NULL )
821
0
  {
822
0
    libcerror_error_set(
823
0
     error,
824
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
825
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
826
0
     "%s: unable to copy device path.",
827
0
     function );
828
829
0
    return( -1 );
830
0
  }
831
0
  device_path[ internal_physical_volume->device_path_size - 1 ] = 0;
832
833
0
  return( 1 );
834
0
}
835
836
/* Sets the device path
837
 * Returns 1 if successful or -1 on error
838
 */
839
int libvslvm_physical_volume_set_device_path(
840
     libvslvm_physical_volume_t *physical_volume,
841
     const char *device_path,
842
     size_t device_path_size,
843
     libcerror_error_t **error )
844
999
{
845
999
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
846
999
  static char *function                                         = "libvslvm_physical_volume_set_device_path";
847
848
999
  if( physical_volume == NULL )
849
0
  {
850
0
    libcerror_error_set(
851
0
     error,
852
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
853
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
854
0
     "%s: invalid physical volume.",
855
0
     function );
856
857
0
    return( -1 );
858
0
  }
859
999
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
860
861
999
  if( device_path == NULL )
862
0
  {
863
0
    libcerror_error_set(
864
0
     error,
865
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
866
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
867
0
     "%s: invalid device path.",
868
0
     function );
869
870
0
    return( -1 );
871
0
  }
872
999
  if( ( device_path_size == 0 )
873
999
   || ( device_path_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
874
2
  {
875
2
    libcerror_error_set(
876
2
     error,
877
2
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
878
2
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
879
2
     "%s: invalid device path size value out of bounds.",
880
2
     function );
881
882
2
    return( -1 );
883
2
  }
884
997
  if( internal_physical_volume->device_path != NULL )
885
493
  {
886
493
    memory_free(
887
493
     internal_physical_volume->device_path );
888
889
493
    internal_physical_volume->device_path      = NULL;
890
493
    internal_physical_volume->device_path_size = 0;
891
493
  }
892
997
  internal_physical_volume->device_path = (char *) memory_allocate(
893
997
                                                    sizeof( char ) * device_path_size );
894
895
997
  if( internal_physical_volume->device_path == NULL )
896
0
  {
897
0
    libcerror_error_set(
898
0
     error,
899
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
900
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
901
0
     "%s: unable to create device path.",
902
0
     function );
903
904
0
    goto on_error;
905
0
  }
906
997
  if( memory_copy(
907
997
       internal_physical_volume->device_path,
908
997
       device_path,
909
997
       device_path_size ) == NULL )
910
0
  {
911
0
    libcerror_error_set(
912
0
     error,
913
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
914
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
915
0
     "%s: unable to copy device path.",
916
0
     function );
917
918
0
    goto on_error;
919
0
  }
920
997
  internal_physical_volume->device_path[ device_path_size - 1 ] = 0;
921
922
997
  internal_physical_volume->device_path_size = device_path_size;
923
924
997
  return( 1 );
925
926
0
on_error:
927
0
  if( internal_physical_volume->device_path != NULL )
928
0
  {
929
0
    memory_free(
930
0
     internal_physical_volume->device_path );
931
932
0
    internal_physical_volume->device_path = NULL;
933
0
  }
934
0
  internal_physical_volume->device_path_size = 0;
935
936
0
  return( -1 );
937
997
}
938
939
/* Retrieves the size
940
 * Returns 1 if successful or -1 on error
941
 */
942
int libvslvm_physical_volume_get_size(
943
     libvslvm_physical_volume_t *physical_volume,
944
     size64_t *size,
945
     libcerror_error_t **error )
946
0
{
947
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
948
0
  static char *function                                         = "libvslvm_physical_volume_get_size";
949
950
0
  if( physical_volume == NULL )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
955
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
956
0
     "%s: invalid physical volume.",
957
0
     function );
958
959
0
    return( -1 );
960
0
  }
961
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
962
963
0
  if( size == NULL )
964
0
  {
965
0
    libcerror_error_set(
966
0
     error,
967
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
968
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
969
0
     "%s: invalid size.",
970
0
     function );
971
972
0
    return( -1 );
973
0
  }
974
0
  *size = internal_physical_volume->size;
975
976
0
  return( 1 );
977
0
}
978
979
/* Retrieves the number of data area descriptors
980
 * Returns 1 if successful or -1 on error
981
 */
982
int libvslvm_physical_volume_get_number_of_data_area_descriptors(
983
     libvslvm_physical_volume_t *physical_volume,
984
     int *number_of_data_area_descriptors,
985
     libcerror_error_t **error )
986
1.03k
{
987
1.03k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
988
1.03k
  static char *function                                         = "libvslvm_physical_volume_get_number_of_data_area_descriptors";
989
990
1.03k
  if( physical_volume == NULL )
991
0
  {
992
0
    libcerror_error_set(
993
0
     error,
994
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
995
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
996
0
     "%s: invalid physical volume.",
997
0
     function );
998
999
0
    return( -1 );
1000
0
  }
1001
1.03k
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1002
1003
1.03k
  if( libcdata_array_get_number_of_entries(
1004
1.03k
       internal_physical_volume->data_area_descriptors_array,
1005
1.03k
       number_of_data_area_descriptors,
1006
1.03k
       error ) != 1 )
1007
0
  {
1008
0
    libcerror_error_set(
1009
0
     error,
1010
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1011
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1012
0
     "%s: unable to retrieve number of data area descriptors from array.",
1013
0
     function );
1014
1015
0
    return( -1 );
1016
0
  }
1017
1.03k
  return( 1 );
1018
1.03k
}
1019
1020
/* Retrieves a specific data area descriptor
1021
 * Returns 1 if successful or -1 on error
1022
 */
1023
int libvslvm_physical_volume_get_data_area_descriptor(
1024
     libvslvm_physical_volume_t *physical_volume,
1025
     int data_area_descriptor_index,
1026
     libvslvm_data_area_descriptor_t **data_area_descriptor,
1027
     libcerror_error_t **error )
1028
0
{
1029
0
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
1030
0
  static char *function                                         = "libvslvm_physical_volume_get_data_area_descriptor";
1031
1032
0
  if( physical_volume == NULL )
1033
0
  {
1034
0
    libcerror_error_set(
1035
0
     error,
1036
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1037
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1038
0
     "%s: invalid physical volume.",
1039
0
     function );
1040
1041
0
    return( -1 );
1042
0
  }
1043
0
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1044
1045
0
  if( libcdata_array_get_entry_by_index(
1046
0
       internal_physical_volume->data_area_descriptors_array,
1047
0
       data_area_descriptor_index,
1048
0
       (intptr_t **) data_area_descriptor,
1049
0
       error ) != 1 )
1050
0
  {
1051
0
    libcerror_error_set(
1052
0
     error,
1053
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1054
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1055
0
     "%s: unable to retrieve data area descriptor: %d.",
1056
0
     function,
1057
0
     data_area_descriptor_index );
1058
1059
0
    return( -1 );
1060
0
  }
1061
0
  return( 1 );
1062
0
}
1063
1064
/* Retrieves the data area descriptor for a specific offset
1065
 * Returns 1 if successful, 0 if no such data area descriptor or -1 on error
1066
 */
1067
int libvslvm_physical_volume_get_data_area_descriptor_by_offset(
1068
     libvslvm_physical_volume_t *physical_volume,
1069
     uint64_t offset,
1070
     libvslvm_data_area_descriptor_t **data_area_descriptor,
1071
     libcerror_error_t **error )
1072
159
{
1073
159
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
1074
159
  static char *function                                         = "libvslvm_physical_volume_get_data_area_descriptor_by_offset";
1075
159
  int data_area_descriptor_index                                = 0;
1076
159
  int number_of_data_area_descriptors                           = 0;
1077
1078
159
  if( physical_volume == NULL )
1079
0
  {
1080
0
    libcerror_error_set(
1081
0
     error,
1082
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1083
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1084
0
     "%s: invalid physical volume.",
1085
0
     function );
1086
1087
0
    return( -1 );
1088
0
  }
1089
159
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1090
1091
159
  if( data_area_descriptor == NULL )
1092
0
  {
1093
0
    libcerror_error_set(
1094
0
     error,
1095
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1096
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1097
0
     "%s: invalid data area descriptor.",
1098
0
     function );
1099
1100
0
    return( -1 );
1101
0
  }
1102
159
  if( *data_area_descriptor != NULL )
1103
0
  {
1104
0
    libcerror_error_set(
1105
0
     error,
1106
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1107
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1108
0
     "%s: invalid data area descriptor value already set.",
1109
0
     function );
1110
1111
0
    return( -1 );
1112
0
  }
1113
159
  if( libcdata_array_get_number_of_entries(
1114
159
       internal_physical_volume->data_area_descriptors_array,
1115
159
       &number_of_data_area_descriptors,
1116
159
       error ) != 1 )
1117
0
  {
1118
0
    libcerror_error_set(
1119
0
     error,
1120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1121
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1122
0
     "%s: unable to retrieve number of data area descriptors from array.",
1123
0
     function );
1124
1125
0
    return( -1 );
1126
0
  }
1127
159
  for( data_area_descriptor_index = 0;
1128
1.95k
       data_area_descriptor_index < number_of_data_area_descriptors;
1129
1.79k
       data_area_descriptor_index++ )
1130
1.88k
  {
1131
1.88k
    if( libcdata_array_get_entry_by_index(
1132
1.88k
         internal_physical_volume->data_area_descriptors_array,
1133
1.88k
         data_area_descriptor_index,
1134
1.88k
         (intptr_t **) data_area_descriptor,
1135
1.88k
         error ) != 1 )
1136
0
    {
1137
0
      libcerror_error_set(
1138
0
       error,
1139
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1140
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1141
0
       "%s: unable to retrieve data area descriptor: %d.",
1142
0
       function,
1143
0
       data_area_descriptor_index );
1144
1145
0
      return( -1 );
1146
0
    }
1147
1.88k
    if( *data_area_descriptor == NULL )
1148
0
    {
1149
0
      libcerror_error_set(
1150
0
       error,
1151
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1152
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1153
0
       "%s: missing data area descriptor: %d.",
1154
0
       function,
1155
0
       data_area_descriptor_index );
1156
1157
0
      return( -1 );
1158
0
    }
1159
1.88k
    if( ( *data_area_descriptor )->size == 0 )
1160
91
    {
1161
91
      return( 1 );
1162
91
    }
1163
1.79k
    offset -= ( *data_area_descriptor )->size;
1164
1.79k
  }
1165
68
  return( 0 );
1166
159
}
1167
1168
/* Retrieves the number of metadata area descriptors
1169
 * Returns 1 if successful or -1 on error
1170
 */
1171
int libvslvm_physical_volume_get_number_of_metadata_area_descriptors(
1172
     libvslvm_physical_volume_t *physical_volume,
1173
     int *number_of_data_area_descriptors,
1174
     libcerror_error_t **error )
1175
5.53k
{
1176
5.53k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
1177
5.53k
  static char *function                                         = "libvslvm_physical_volume_get_number_of_metadata_area_descriptors";
1178
1179
5.53k
  if( physical_volume == NULL )
1180
0
  {
1181
0
    libcerror_error_set(
1182
0
     error,
1183
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1184
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1185
0
     "%s: invalid physical volume.",
1186
0
     function );
1187
1188
0
    return( -1 );
1189
0
  }
1190
5.53k
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1191
1192
5.53k
  if( libcdata_array_get_number_of_entries(
1193
5.53k
       internal_physical_volume->metadata_area_descriptors_array,
1194
5.53k
       number_of_data_area_descriptors,
1195
5.53k
       error ) != 1 )
1196
0
  {
1197
0
    libcerror_error_set(
1198
0
     error,
1199
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1200
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1201
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
1202
0
     function );
1203
1204
0
    return( -1 );
1205
0
  }
1206
5.53k
  return( 1 );
1207
5.53k
}
1208
1209
/* Retrieves a specific metadata area descriptor
1210
 * Returns 1 if successful or -1 on error
1211
 */
1212
int libvslvm_physical_volume_get_metadata_area_descriptor(
1213
     libvslvm_physical_volume_t *physical_volume,
1214
     int data_area_descriptor_index,
1215
     libvslvm_data_area_descriptor_t **data_area_descriptor,
1216
     libcerror_error_t **error )
1217
5.50k
{
1218
5.50k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
1219
5.50k
  static char *function                                         = "libvslvm_physical_volume_get_metadata_area_descriptor";
1220
1221
5.50k
  if( physical_volume == NULL )
1222
0
  {
1223
0
    libcerror_error_set(
1224
0
     error,
1225
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1226
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1227
0
     "%s: invalid physical volume.",
1228
0
     function );
1229
1230
0
    return( -1 );
1231
0
  }
1232
5.50k
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1233
1234
5.50k
  if( libcdata_array_get_entry_by_index(
1235
5.50k
       internal_physical_volume->metadata_area_descriptors_array,
1236
5.50k
       data_area_descriptor_index,
1237
5.50k
       (intptr_t **) data_area_descriptor,
1238
5.50k
       error ) != 1 )
1239
0
  {
1240
0
    libcerror_error_set(
1241
0
     error,
1242
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1243
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1244
0
     "%s: unable to retrieve metadata area descriptor: %d.",
1245
0
     function,
1246
0
     data_area_descriptor_index );
1247
1248
0
    return( -1 );
1249
0
  }
1250
5.50k
  return( 1 );
1251
5.50k
}
1252
1253
/* TODO move function into libvslvm_physical_volume_label.c */
1254
1255
/* Reads a physical volume label
1256
 * Returns 1 if successful, 0 if not found or -1 on error
1257
 */
1258
int libvslvm_internal_physical_volume_read_label_data(
1259
     libvslvm_internal_physical_volume_t *internal_physical_volume,
1260
     const uint8_t *data,
1261
     size_t data_size,
1262
     libcerror_error_t **error )
1263
7.53k
{
1264
7.53k
  libvslvm_data_area_descriptor_t *data_area_descriptor = NULL;
1265
7.53k
  static char *function                                 = "libvslvm_internal_physical_volume_read_label_data";
1266
7.53k
  size_t data_offset                                    = 0;
1267
7.53k
  uint64_t offset                                       = 0;
1268
7.53k
  uint64_t size                                         = 0;
1269
7.53k
  uint32_t calculated_checksum                          = 0;
1270
7.53k
  uint32_t stored_checksum                              = 0;
1271
7.53k
  int entry_index                                       = 0;
1272
7.53k
  int result                                            = 0;
1273
1274
#if defined( HAVE_DEBUG_OUTPUT )
1275
  uint64_t value_64bit                                  = 0;
1276
  uint32_t value_32bit                                  = 0;
1277
#endif
1278
1279
7.53k
  if( internal_physical_volume == NULL )
1280
0
  {
1281
0
    libcerror_error_set(
1282
0
     error,
1283
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1284
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1285
0
     "%s: invalid physical volume.",
1286
0
     function );
1287
1288
0
    return( -1 );
1289
0
  }
1290
7.53k
  if( data == NULL )
1291
0
  {
1292
0
    libcerror_error_set(
1293
0
     error,
1294
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1295
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1296
0
     "%s: invalid data.",
1297
0
     function );
1298
1299
0
    return( -1 );
1300
0
  }
1301
7.53k
  if( ( data_size == 0 )
1302
7.53k
   || ( data_size > (size_t) SSIZE_MAX ) )
1303
0
  {
1304
0
    libcerror_error_set(
1305
0
     error,
1306
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1307
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1308
0
     "%s: invalid data size value out of bounds.",
1309
0
     function );
1310
1311
0
    return( -1 );
1312
0
  }
1313
#if defined( HAVE_DEBUG_OUTPUT )
1314
  if( libcnotify_verbose != 0 )
1315
  {
1316
    libcnotify_printf(
1317
     "%s: physical volume label data:\n",
1318
     function );
1319
    libcnotify_print_data(
1320
     data,
1321
     512,
1322
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1323
  }
1324
#endif
1325
#if defined( HAVE_DEBUG_OUTPUT )
1326
  if( libcnotify_verbose != 0 )
1327
  {
1328
    libcnotify_printf(
1329
     "%s: physical volume label header:\n",
1330
     function );
1331
    libcnotify_print_data(
1332
     data,
1333
     sizeof( vslvm_physical_volume_label_header_t ),
1334
     0 );
1335
  }
1336
#endif
1337
7.53k
  if( memory_compare(
1338
7.53k
       ( (vslvm_physical_volume_label_header_t *) data )->signature,
1339
7.53k
       vslvm_physical_volume_label_signature,
1340
7.53k
       8 ) != 0 )
1341
586
  {
1342
586
    return( 0 );
1343
586
  }
1344
6.94k
  byte_stream_copy_to_uint32_little_endian(
1345
6.94k
   ( (vslvm_physical_volume_label_header_t *) data )->checksum,
1346
6.94k
   stored_checksum );
1347
1348
#if defined( HAVE_DEBUG_OUTPUT )
1349
  if( libcnotify_verbose != 0 )
1350
  {
1351
    libcnotify_printf(
1352
     "%s: signature\t\t: %c%c%c%c%c%c%c%c\n",
1353
     function,
1354
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 0 ],
1355
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 1 ],
1356
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 2 ],
1357
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 3 ],
1358
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 4 ],
1359
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 5 ],
1360
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 6 ],
1361
     ( (vslvm_physical_volume_label_header_t *) data )->signature[ 7 ] );
1362
1363
    byte_stream_copy_to_uint64_little_endian(
1364
     ( (vslvm_physical_volume_label_header_t *) data )->sector_number,
1365
     value_64bit );
1366
    libcnotify_printf(
1367
     "%s: sector number\t: %" PRIu64 "\n",
1368
     function,
1369
     value_64bit );
1370
1371
    libcnotify_printf(
1372
     "%s: checksum\t\t: 0x%08" PRIx32 "\n",
1373
     function,
1374
     stored_checksum );
1375
1376
    byte_stream_copy_to_uint32_little_endian(
1377
     ( (vslvm_physical_volume_label_header_t *) data )->data_offset,
1378
     value_32bit );
1379
    libcnotify_printf(
1380
     "%s: data offset\t\t: 0x%08" PRIx32 "\n",
1381
     function,
1382
     value_32bit );
1383
1384
    libcnotify_printf(
1385
     "%s: type indicator\t: %c%c%c%c%c%c%c%c\n",
1386
     function,
1387
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 0 ],
1388
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 1 ],
1389
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 2 ],
1390
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 3 ],
1391
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 4 ],
1392
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 5 ],
1393
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 6 ],
1394
     ( (vslvm_physical_volume_label_header_t *) data )->type_indicator[ 7 ] );
1395
1396
    libcnotify_printf(
1397
     "\n" );
1398
  }
1399
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1400
1401
6.94k
  if( libvslvm_checksum_calculate_weak_crc32(
1402
6.94k
       &calculated_checksum,
1403
6.94k
       &( data[ 20 ] ),
1404
6.94k
       512 - 20,
1405
6.94k
       0xf597a6cfUL,
1406
6.94k
       error ) != 1 )
1407
0
  {
1408
0
    libcerror_error_set(
1409
0
     error,
1410
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1411
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1412
0
     "%s: unable to calculate CRC-32.",
1413
0
     function );
1414
1415
0
    goto on_error;
1416
0
  }
1417
6.94k
  if( ( stored_checksum != 0 )
1418
6.94k
   && ( stored_checksum != calculated_checksum ) )
1419
121
  {
1420
121
    libcerror_error_set(
1421
121
     error,
1422
121
     LIBCERROR_ERROR_DOMAIN_INPUT,
1423
121
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
1424
121
     "%s: mismatch in checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).",
1425
121
     function,
1426
121
     stored_checksum,
1427
121
     calculated_checksum );
1428
1429
121
    goto on_error;
1430
121
  }
1431
6.82k
  data_offset = sizeof( vslvm_physical_volume_label_header_t );
1432
1433
#if defined( HAVE_DEBUG_OUTPUT )
1434
  if( libcnotify_verbose != 0 )
1435
  {
1436
    libcnotify_printf(
1437
     "%s: physical volume header data:\n",
1438
     function );
1439
    libcnotify_print_data(
1440
     &( data[ data_offset ] ),
1441
     sizeof( vslvm_physical_volume_header_t ),
1442
     0 );
1443
  }
1444
#endif
1445
#if defined( HAVE_DEBUG_OUTPUT )
1446
  if( libcnotify_verbose != 0 )
1447
  {
1448
    libcnotify_printf(
1449
     "%s: identifier\t\t: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
1450
     function,
1451
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 0 ],
1452
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 1 ],
1453
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 2 ],
1454
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 3 ],
1455
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 4 ],
1456
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 5 ],
1457
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 6 ],
1458
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 7 ],
1459
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 8 ],
1460
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 9 ],
1461
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 10 ],
1462
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 11 ],
1463
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 12 ],
1464
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 13 ],
1465
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 14 ],
1466
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 15 ],
1467
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 16 ],
1468
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 17 ],
1469
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 18 ],
1470
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 19 ],
1471
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 20 ],
1472
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 21 ],
1473
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 22 ],
1474
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 23 ],
1475
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 24 ],
1476
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 25 ],
1477
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 26 ],
1478
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 27 ],
1479
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 28 ],
1480
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 29 ],
1481
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 30 ],
1482
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->identifier[ 31 ] );
1483
1484
    byte_stream_copy_to_uint64_little_endian(
1485
     ( (vslvm_physical_volume_header_t *) &( data[ data_offset ] ) )->volume_size,
1486
     value_64bit );
1487
    libcnotify_printf(
1488
     "%s: volume size\t\t: %" PRIu64 "\n",
1489
     function,
1490
     value_64bit );
1491
1492
    libcnotify_printf(
1493
     "\n" );
1494
  }
1495
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1496
1497
6.82k
  data_offset += sizeof( vslvm_physical_volume_header_t );
1498
1499
6.82k
  do
1500
43.7k
  {
1501
43.7k
    if( data_offset >= ( data_size - sizeof( vslvm_data_area_descriptor_t ) ) )
1502
3
    {
1503
3
      libcerror_error_set(
1504
3
       error,
1505
3
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1506
3
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1507
3
       "%s: invalid data offset value out of bounds.",
1508
3
       function );
1509
1510
3
      goto on_error;
1511
3
    }
1512
#if defined( HAVE_DEBUG_OUTPUT )
1513
    if( libcnotify_verbose != 0 )
1514
    {
1515
      libcnotify_printf(
1516
       "%s: data area descriptor data:\n",
1517
       function );
1518
      libcnotify_print_data(
1519
       &( data[ data_offset ] ),
1520
       sizeof( vslvm_data_area_descriptor_t ),
1521
       0 );
1522
    }
1523
#endif
1524
43.7k
    result = memory_compare(
1525
43.7k
              &( data[ data_offset ] ),
1526
43.7k
              vslvm_empty_data_area_descriptor,
1527
43.7k
              sizeof( vslvm_data_area_descriptor_t ) );
1528
1529
43.7k
    if( result != 0 )
1530
37.1k
    {
1531
37.1k
      byte_stream_copy_to_uint64_little_endian(
1532
37.1k
       ( (vslvm_data_area_descriptor_t *) &( data[ data_offset ] ) )->offset,
1533
37.1k
       offset );
1534
1535
37.1k
      byte_stream_copy_to_uint64_little_endian(
1536
37.1k
       ( (vslvm_data_area_descriptor_t *) &( data[ data_offset ] ) )->size,
1537
37.1k
       size );
1538
1539
#if defined( HAVE_DEBUG_OUTPUT )
1540
      if( libcnotify_verbose != 0 )
1541
      {
1542
        libcnotify_printf(
1543
         "%s: data area offset\t: 0x%08" PRIx64 "\n",
1544
         function,
1545
         offset );
1546
1547
        libcnotify_printf(
1548
         "%s: data area size\t: %" PRIu64 "\n",
1549
         function,
1550
         size );
1551
1552
        libcnotify_printf(
1553
         "\n" );
1554
      }
1555
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1556
1557
37.1k
      if( libvslvm_data_area_descriptor_initialize(
1558
37.1k
           &data_area_descriptor,
1559
37.1k
           error ) != 1 )
1560
0
      {
1561
0
        libcerror_error_set(
1562
0
         error,
1563
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1564
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1565
0
         "%s: unable to create data area descriptor.",
1566
0
         function );
1567
1568
0
        goto on_error;
1569
0
      }
1570
37.1k
      if( libvslvm_data_area_descriptor_set(
1571
37.1k
           data_area_descriptor,
1572
37.1k
           (off64_t) offset,
1573
37.1k
           (size64_t) size,
1574
37.1k
           error ) != 1 )
1575
162
      {
1576
162
        libcerror_error_set(
1577
162
         error,
1578
162
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1579
162
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1580
162
         "%s: unable to set data area descriptor.",
1581
162
         function );
1582
1583
162
        goto on_error;
1584
162
      }
1585
36.9k
      if( libcdata_array_append_entry(
1586
36.9k
           internal_physical_volume->data_area_descriptors_array,
1587
36.9k
           &entry_index,
1588
36.9k
           (intptr_t *) data_area_descriptor,
1589
36.9k
           error ) != 1 )
1590
0
      {
1591
0
        libcerror_error_set(
1592
0
         error,
1593
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1594
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1595
0
         "%s: unable to append entry to data area descriptors array.",
1596
0
         function );
1597
1598
0
        goto on_error;
1599
0
      }
1600
36.9k
      data_area_descriptor = NULL;
1601
36.9k
    }
1602
43.6k
    data_offset += sizeof( vslvm_data_area_descriptor_t );
1603
43.6k
  }
1604
43.6k
  while( result != 0 );
1605
1606
6.65k
  do
1607
13.6k
  {
1608
13.6k
    if( data_offset >= ( data_size - sizeof( vslvm_data_area_descriptor_t ) ) )
1609
2
    {
1610
2
      libcerror_error_set(
1611
2
       error,
1612
2
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1613
2
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1614
2
       "%s: invalid data offset value out of bounds.",
1615
2
       function );
1616
1617
2
      goto on_error;
1618
2
    }
1619
#if defined( HAVE_DEBUG_OUTPUT )
1620
    if( libcnotify_verbose != 0 )
1621
    {
1622
      libcnotify_printf(
1623
       "%s: metadata area descriptor data:\n",
1624
       function );
1625
      libcnotify_print_data(
1626
       &( data[ data_offset ] ),
1627
       sizeof( vslvm_data_area_descriptor_t ),
1628
       0 );
1629
    }
1630
#endif
1631
13.6k
    result = memory_compare(
1632
13.6k
              &( data[ data_offset ] ),
1633
13.6k
              vslvm_empty_data_area_descriptor,
1634
13.6k
              sizeof( vslvm_data_area_descriptor_t ) );
1635
1636
13.6k
    if( result != 0 )
1637
7.09k
    {
1638
7.09k
      byte_stream_copy_to_uint64_little_endian(
1639
7.09k
       ( (vslvm_data_area_descriptor_t *) &( data[ data_offset ] ) )->offset,
1640
7.09k
       offset );
1641
1642
7.09k
      byte_stream_copy_to_uint64_little_endian(
1643
7.09k
       ( (vslvm_data_area_descriptor_t *) &( data[ data_offset ] ) )->size,
1644
7.09k
       size );
1645
1646
#if defined( HAVE_DEBUG_OUTPUT )
1647
      if( libcnotify_verbose != 0 )
1648
      {
1649
        libcnotify_printf(
1650
         "%s: metadata area offset\t: 0x%08" PRIx64 "\n",
1651
         function,
1652
         offset );
1653
1654
        libcnotify_printf(
1655
         "%s: metadata area size\t: %" PRIu64 "\n",
1656
         function,
1657
         size );
1658
1659
        libcnotify_printf(
1660
         "\n" );
1661
      }
1662
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1663
1664
7.09k
      if( libvslvm_data_area_descriptor_initialize(
1665
7.09k
           &data_area_descriptor,
1666
7.09k
           error ) != 1 )
1667
0
      {
1668
0
        libcerror_error_set(
1669
0
         error,
1670
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1671
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1672
0
         "%s: unable to create data area descriptor.",
1673
0
         function );
1674
1675
0
        goto on_error;
1676
0
      }
1677
7.09k
      if( libvslvm_data_area_descriptor_set(
1678
7.09k
           data_area_descriptor,
1679
7.09k
           (off64_t) offset,
1680
7.09k
           (size64_t) size,
1681
7.09k
           error ) != 1 )
1682
100
      {
1683
100
        libcerror_error_set(
1684
100
         error,
1685
100
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1686
100
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1687
100
         "%s: unable to set data area descriptor.",
1688
100
         function );
1689
1690
100
        goto on_error;
1691
100
      }
1692
6.99k
      if( libcdata_array_append_entry(
1693
6.99k
           internal_physical_volume->metadata_area_descriptors_array,
1694
6.99k
           &entry_index,
1695
6.99k
           (intptr_t *) data_area_descriptor,
1696
6.99k
           error ) != 1 )
1697
0
      {
1698
0
        libcerror_error_set(
1699
0
         error,
1700
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1701
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1702
0
         "%s: unable to append entry to metadata area descriptors array.",
1703
0
         function );
1704
1705
0
        goto on_error;
1706
0
      }
1707
6.99k
      data_area_descriptor = NULL;
1708
6.99k
    }
1709
13.5k
    data_offset += sizeof( vslvm_data_area_descriptor_t );
1710
13.5k
  }
1711
13.5k
  while( result != 0 );
1712
1713
6.55k
  return( 1 );
1714
1715
388
on_error:
1716
388
  if( data_area_descriptor != NULL )
1717
262
  {
1718
262
    libvslvm_data_area_descriptor_free(
1719
262
     &data_area_descriptor,
1720
262
     NULL );
1721
262
  }
1722
388
  libcdata_array_empty(
1723
388
   internal_physical_volume->metadata_area_descriptors_array,
1724
388
   (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
1725
388
   NULL );
1726
1727
388
  libcdata_array_empty(
1728
388
   internal_physical_volume->data_area_descriptors_array,
1729
388
   (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
1730
388
   NULL );
1731
1732
388
  return( -1 );
1733
6.65k
}
1734
1735
/* Reads a physical volume label
1736
 * Returns 1 if successful, 0 if not found or -1 on error
1737
 */
1738
int libvslvm_physical_volume_read_label_file_io_pool(
1739
     libvslvm_physical_volume_t *physical_volume,
1740
     libbfio_pool_t *file_io_pool,
1741
     int file_io_pool_entry,
1742
     off64_t file_offset,
1743
     libcerror_error_t **error )
1744
7.59k
{
1745
7.59k
  uint8_t physical_volume_label_data[ 512 ];
1746
1747
7.59k
  libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
1748
7.59k
  static char *function                                         = "libvslvm_physical_volume_read_label_file_io_pool";
1749
7.59k
  ssize_t read_count                                            = 0;
1750
7.59k
  int result                                                    = 0;
1751
1752
7.59k
  if( physical_volume == NULL )
1753
0
  {
1754
0
    libcerror_error_set(
1755
0
     error,
1756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1757
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1758
0
     "%s: invalid physical volume.",
1759
0
     function );
1760
1761
0
    return( -1 );
1762
0
  }
1763
7.59k
  internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;
1764
1765
#if defined( HAVE_DEBUG_OUTPUT )
1766
  if( libcnotify_verbose != 0 )
1767
  {
1768
    libcnotify_printf(
1769
     "%s: reading physical volume label at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1770
     function,
1771
     file_offset,
1772
     file_offset );
1773
  }
1774
#endif
1775
7.59k
  read_count = libbfio_pool_read_buffer_at_offset(
1776
7.59k
                file_io_pool,
1777
7.59k
                file_io_pool_entry,
1778
7.59k
                physical_volume_label_data,
1779
7.59k
                512,
1780
7.59k
                file_offset,
1781
7.59k
                error );
1782
1783
7.59k
  if( read_count != (ssize_t) 512 )
1784
68
  {
1785
68
    libcerror_error_set(
1786
68
     error,
1787
68
     LIBCERROR_ERROR_DOMAIN_IO,
1788
68
     LIBCERROR_IO_ERROR_READ_FAILED,
1789
68
     "%s: unable to read physical volume label at offset %" PRIi64 " (0x%08" PRIx64 ").",
1790
68
     function,
1791
68
     file_offset,
1792
68
     file_offset );
1793
1794
68
    return( -1 );
1795
68
  }
1796
7.53k
  result = libvslvm_internal_physical_volume_read_label_data(
1797
7.53k
            internal_physical_volume,
1798
7.53k
            physical_volume_label_data,
1799
7.53k
            512,
1800
7.53k
            error );
1801
1802
7.53k
  if( result == -1 )
1803
388
  {
1804
388
    libcerror_error_set(
1805
388
     error,
1806
388
     LIBCERROR_ERROR_DOMAIN_IO,
1807
388
     LIBCERROR_IO_ERROR_READ_FAILED,
1808
388
     "%s: unable to read physical volume label.",
1809
388
     function );
1810
1811
388
    return( -1 );
1812
388
  }
1813
7.14k
  return( result );
1814
7.53k
}
1815
1816
/* Reads the physical volume
1817
 * Callback function for the physical volume files list
1818
 * Returns 1 if successful or -1 on error
1819
 */
1820
int libvslvm_physical_volume_read_element_data(
1821
     intptr_t *data_handle LIBVSLVM_ATTRIBUTE_UNUSED,
1822
     libbfio_pool_t *file_io_pool,
1823
     libfdata_list_element_t *element,
1824
     libfdata_cache_t *cache,
1825
     int file_io_pool_entry,
1826
     off64_t physical_volume_offset,
1827
     size64_t physical_volume_size LIBVSLVM_ATTRIBUTE_UNUSED,
1828
     uint32_t element_flags LIBVSLVM_ATTRIBUTE_UNUSED,
1829
     uint8_t read_flags LIBVSLVM_ATTRIBUTE_UNUSED,
1830
     libcerror_error_t **error )
1831
0
{
1832
0
  libvslvm_physical_volume_t *physical_volume = NULL;
1833
0
  static char *function                       = "libvslvm_physical_volume_read_element_data";
1834
0
  off64_t label_offset                        = 0;
1835
0
  int result                                  = 0;
1836
1837
0
  LIBVSLVM_UNREFERENCED_PARAMETER( data_handle )
1838
0
  LIBVSLVM_UNREFERENCED_PARAMETER( physical_volume_size )
1839
0
  LIBVSLVM_UNREFERENCED_PARAMETER( element_flags )
1840
0
  LIBVSLVM_UNREFERENCED_PARAMETER( read_flags )
1841
1842
0
  if( libvslvm_physical_volume_initialize(
1843
0
       &physical_volume,
1844
0
       error ) != 1 )
1845
0
  {
1846
0
    libcerror_error_set(
1847
0
     error,
1848
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1849
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1850
0
     "%s: unable to create physical volume.",
1851
0
     function );
1852
1853
0
    goto on_error;
1854
0
  }
1855
  /* The physical volume label can be stored in one of the first 4 sectors
1856
   */
1857
0
  label_offset = 0;
1858
1859
0
  while( label_offset < 2048 )
1860
0
  {
1861
0
    result = libvslvm_physical_volume_read_label_file_io_pool(
1862
0
        physical_volume,
1863
0
        file_io_pool,
1864
0
        file_io_pool_entry,
1865
0
        physical_volume_offset + label_offset,
1866
0
        error );
1867
1868
0
    if( result == -1 )
1869
0
    {
1870
0
      libcerror_error_set(
1871
0
       error,
1872
0
       LIBCERROR_ERROR_DOMAIN_IO,
1873
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1874
0
       "%s: unable to read physical volume label at offset: %" PRIi64 ".",
1875
0
       function,
1876
0
       physical_volume_offset + label_offset );
1877
1878
0
      goto on_error;
1879
0
    }
1880
0
    else if( result != 0 )
1881
0
    {
1882
0
      break;
1883
0
    }
1884
0
    label_offset += 512;
1885
0
  }
1886
0
  if( result != 1 )
1887
0
  {
1888
0
    libcerror_error_set(
1889
0
     error,
1890
0
     LIBCERROR_ERROR_DOMAIN_IO,
1891
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1892
0
     "%s: unable to read physical volume label.",
1893
0
     function );
1894
1895
0
    goto on_error;
1896
0
  }
1897
0
  if( libfdata_list_element_set_element_value(
1898
0
       element,
1899
0
       (intptr_t *) file_io_pool,
1900
0
       cache,
1901
0
       (intptr_t *) physical_volume,
1902
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_internal_physical_volume_free,
1903
0
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
1904
0
       error ) != 1 )
1905
0
  {
1906
0
    libcerror_error_set(
1907
0
     error,
1908
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1909
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1910
0
     "%s: unable to set physical volume as element value.",
1911
0
     function );
1912
1913
0
    goto on_error;
1914
0
  }
1915
0
  return( 1 );
1916
1917
0
on_error:
1918
0
  if( physical_volume != NULL )
1919
0
  {
1920
0
    libvslvm_internal_physical_volume_free(
1921
0
     (libvslvm_internal_physical_volume_t **) &physical_volume,
1922
0
     NULL );
1923
0
  }
1924
0
  return( -1 );
1925
0
}
1926