Coverage Report

Created: 2024-02-25 07:20

/src/libvslvm/libvslvm/libvslvm_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The internal handle functions
3
 *
4
 * Copyright (C) 2014-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <system_string.h>
26
#include <types.h>
27
#include <wide_string.h>
28
29
#include "libvslvm_data_area_descriptor.h"
30
#include "libvslvm_debug.h"
31
#include "libvslvm_definitions.h"
32
#include "libvslvm_handle.h"
33
#include "libvslvm_io_handle.h"
34
#include "libvslvm_libbfio.h"
35
#include "libvslvm_libcdata.h"
36
#include "libvslvm_libcerror.h"
37
#include "libvslvm_libcnotify.h"
38
#include "libvslvm_metadata.h"
39
#include "libvslvm_metadata_area.h"
40
#include "libvslvm_raw_location_descriptor.h"
41
#include "libvslvm_types.h"
42
43
/* Creates a handle
44
 * Make sure the value handle is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libvslvm_handle_initialize(
48
     libvslvm_handle_t **handle,
49
     libcerror_error_t **error )
50
6.41k
{
51
6.41k
  libvslvm_internal_handle_t *internal_handle = NULL;
52
6.41k
  static char *function                       = "libvslvm_handle_initialize";
53
54
6.41k
  if( handle == NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
59
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
60
0
     "%s: invalid handle.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
6.41k
  if( *handle != NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
70
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
71
0
     "%s: invalid handle value already set.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
6.41k
  internal_handle = memory_allocate_structure(
77
6.41k
                     libvslvm_internal_handle_t );
78
79
6.41k
  if( internal_handle == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
85
0
     "%s: unable to create handle.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
6.41k
  if( memory_set(
91
6.41k
       internal_handle,
92
6.41k
       0,
93
6.41k
       sizeof( libvslvm_internal_handle_t ) ) == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
98
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
99
0
     "%s: unable to clear handle.",
100
0
     function );
101
102
0
    memory_free(
103
0
     internal_handle );
104
105
0
    return( -1 );
106
0
  }
107
6.41k
  if( libvslvm_io_handle_initialize(
108
6.41k
       &( internal_handle->io_handle ),
109
6.41k
       error ) != 1 )
110
0
  {
111
0
    libcerror_error_set(
112
0
     error,
113
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
114
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
115
0
     "%s: unable to create IO handle.",
116
0
     function );
117
118
0
    goto on_error;
119
0
  }
120
6.41k
  *handle = (libvslvm_handle_t *) internal_handle;
121
122
6.41k
  return( 1 );
123
124
0
on_error:
125
0
  if( internal_handle != NULL )
126
0
  {
127
0
    if( internal_handle->io_handle != NULL )
128
0
    {
129
0
      libvslvm_io_handle_free(
130
0
       &( internal_handle->io_handle ),
131
0
       NULL );
132
0
    }
133
0
    memory_free(
134
0
     internal_handle );
135
0
  }
136
0
  return( -1 );
137
6.41k
}
138
139
/* Frees a handle
140
 * Returns 1 if successful or -1 on error
141
 */
142
int libvslvm_handle_free(
143
     libvslvm_handle_t **handle,
144
     libcerror_error_t **error )
145
6.41k
{
146
6.41k
  libvslvm_internal_handle_t *internal_handle = NULL;
147
6.41k
  static char *function                       = "libvslvm_handle_free";
148
6.41k
  int result                                  = 1;
149
150
6.41k
  if( handle == NULL )
151
0
  {
152
0
    libcerror_error_set(
153
0
     error,
154
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
155
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
156
0
     "%s: invalid handle.",
157
0
     function );
158
159
0
    return( -1 );
160
0
  }
161
6.41k
  if( *handle != NULL )
162
6.41k
  {
163
6.41k
    internal_handle = (libvslvm_internal_handle_t *) *handle;
164
165
6.41k
    if( ( internal_handle->file_io_handle != NULL )
166
6.41k
     || ( internal_handle->physical_volume_file_io_pool != NULL ) )
167
3.57k
    {
168
3.57k
      if( libvslvm_handle_close(
169
3.57k
           *handle,
170
3.57k
           error ) != 0 )
171
0
      {
172
0
        libcerror_error_set(
173
0
         error,
174
0
         LIBCERROR_ERROR_DOMAIN_IO,
175
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
176
0
         "%s: unable to close handle.",
177
0
         function );
178
179
0
        result = -1;
180
0
      }
181
3.57k
    }
182
6.41k
    *handle = NULL;
183
184
6.41k
    if( libvslvm_io_handle_free(
185
6.41k
         &( internal_handle->io_handle ),
186
6.41k
         error ) != 1 )
187
0
    {
188
0
      libcerror_error_set(
189
0
       error,
190
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
191
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
192
0
       "%s: unable to free IO handle.",
193
0
       function );
194
195
0
      result = -1;
196
0
    }
197
6.41k
    memory_free(
198
6.41k
     internal_handle );
199
6.41k
  }
200
6.41k
  return( result );
201
6.41k
}
202
203
/* Signals the handle to abort its current activity
204
 * Returns 1 if successful or -1 on error
205
 */
206
int libvslvm_handle_signal_abort(
207
     libvslvm_handle_t *handle,
208
     libcerror_error_t **error )
209
0
{
210
0
  libvslvm_internal_handle_t *internal_handle = NULL;
211
0
  static char *function                       = "libvslvm_handle_signal_abort";
212
213
0
  if( handle == NULL )
214
0
  {
215
0
    libcerror_error_set(
216
0
     error,
217
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
218
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
219
0
     "%s: invalid handle.",
220
0
     function );
221
222
0
    return( -1 );
223
0
  }
224
0
  internal_handle = (libvslvm_internal_handle_t *) handle;
225
226
0
  if( internal_handle->io_handle == NULL )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
231
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
232
0
     "%s: invalid handle - missing IO handle.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
0
  internal_handle->io_handle->abort = 1;
238
239
0
  return( 1 );
240
0
}
241
242
/* Opens a handle
243
 * Returns 1 if successful or -1 on error
244
 */
245
int libvslvm_handle_open(
246
     libvslvm_handle_t *handle,
247
     const char *filename,
248
     int access_flags,
249
     libcerror_error_t **error )
250
0
{
251
0
  libbfio_handle_t *file_io_handle            = NULL;
252
0
  libvslvm_internal_handle_t *internal_handle = NULL;
253
0
  static char *function                       = "libvslvm_handle_open";
254
0
  size_t filename_length                      = 0;
255
256
0
  if( handle == NULL )
257
0
  {
258
0
    libcerror_error_set(
259
0
     error,
260
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
261
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
262
0
     "%s: invalid handle.",
263
0
     function );
264
265
0
    return( -1 );
266
0
  }
267
0
  internal_handle = (libvslvm_internal_handle_t *) handle;
268
269
0
  if( filename == NULL )
270
0
  {
271
0
    libcerror_error_set(
272
0
     error,
273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
275
0
     "%s: invalid filename.",
276
0
     function );
277
278
0
    return( -1 );
279
0
  }
280
0
  if( ( ( access_flags & LIBVSLVM_ACCESS_FLAG_READ ) == 0 )
281
0
   && ( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) == 0 ) )
282
0
  {
283
0
    libcerror_error_set(
284
0
     error,
285
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
286
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
287
0
     "%s: unsupported accesss flags.",
288
0
     function );
289
290
0
    return( -1 );
291
0
  }
292
0
  if( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) != 0 )
293
0
  {
294
0
    libcerror_error_set(
295
0
     error,
296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
297
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
298
0
     "%s: write access currently not supported.",
299
0
     function );
300
301
0
    return( -1 );
302
0
  }
303
0
  if( libbfio_file_initialize(
304
0
       &file_io_handle,
305
0
       error ) != 1 )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
310
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
311
0
     "%s: unable to create file IO handle.",
312
0
     function );
313
314
0
    goto on_error;
315
0
  }
316
#if defined( HAVE_DEBUG_OUTPUT )
317
  if( libbfio_handle_set_track_offsets_read(
318
       file_io_handle,
319
       1,
320
       error ) != 1 )
321
  {
322
                libcerror_error_set(
323
                 error,
324
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
325
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
326
                 "%s: unable to set track offsets read in file IO handle.",
327
                 function );
328
329
    goto on_error;
330
  }
331
#endif
332
0
  filename_length = narrow_string_length(
333
0
                     filename );
334
335
0
  if( libbfio_file_set_name(
336
0
       file_io_handle,
337
0
       filename,
338
0
       filename_length + 1,
339
0
       error ) != 1 )
340
0
  {
341
0
                libcerror_error_set(
342
0
                 error,
343
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
344
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
345
0
                 "%s: unable to set filename in file IO handle.",
346
0
                 function );
347
348
0
                goto on_error;
349
0
  }
350
0
  if( libvslvm_handle_open_file_io_handle(
351
0
       handle,
352
0
       file_io_handle,
353
0
       access_flags,
354
0
       error ) != 1 )
355
0
  {
356
0
    libcerror_error_set(
357
0
     error,
358
0
     LIBCERROR_ERROR_DOMAIN_IO,
359
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
360
0
     "%s: unable to open handle: %s.",
361
0
     function,
362
0
     filename );
363
364
0
                goto on_error;
365
0
  }
366
0
  internal_handle->file_io_handle_created_in_library = 1;
367
368
0
  return( 1 );
369
370
0
on_error:
371
0
  if( file_io_handle != NULL )
372
0
  {
373
0
    libbfio_handle_free(
374
0
     &file_io_handle,
375
0
     NULL );
376
0
  }
377
0
  return( -1 );
378
0
}
379
380
#if defined( HAVE_WIDE_CHARACTER_TYPE )
381
382
/* Opens a handle
383
 * Returns 1 if successful or -1 on error
384
 */
385
int libvslvm_handle_open_wide(
386
     libvslvm_handle_t *handle,
387
     const wchar_t *filename,
388
     int access_flags,
389
     libcerror_error_t **error )
390
{
391
  libbfio_handle_t *file_io_handle            = NULL;
392
  libvslvm_internal_handle_t *internal_handle = NULL;
393
  static char *function                       = "libvslvm_handle_open_wide";
394
  size_t filename_length                      = 0;
395
396
  if( handle == NULL )
397
  {
398
    libcerror_error_set(
399
     error,
400
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
401
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
402
     "%s: invalid handle.",
403
     function );
404
405
    return( -1 );
406
  }
407
  internal_handle = (libvslvm_internal_handle_t *) handle;
408
409
  if( filename == NULL )
410
  {
411
    libcerror_error_set(
412
     error,
413
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
414
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
415
     "%s: invalid filename.",
416
     function );
417
418
    return( -1 );
419
  }
420
  if( ( ( access_flags & LIBVSLVM_ACCESS_FLAG_READ ) == 0 )
421
   && ( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) == 0 ) )
422
  {
423
    libcerror_error_set(
424
     error,
425
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
426
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
427
     "%s: unsupported access flags.",
428
     function );
429
430
    return( -1 );
431
  }
432
  if( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) != 0 )
433
  {
434
    libcerror_error_set(
435
     error,
436
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
437
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
438
     "%s: write access currently not supported.",
439
     function );
440
441
    return( -1 );
442
  }
443
  if( libbfio_file_initialize(
444
       &file_io_handle,
445
       error ) != 1 )
446
  {
447
    libcerror_error_set(
448
     error,
449
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
450
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
451
     "%s: unable to create file IO handle.",
452
     function );
453
454
    goto on_error;
455
  }
456
#if defined( HAVE_DEBUG_OUTPUT )
457
  if( libbfio_handle_set_track_offsets_read(
458
       file_io_handle,
459
       1,
460
       error ) != 1 )
461
  {
462
                libcerror_error_set(
463
                 error,
464
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
465
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
466
                 "%s: unable to set track offsets read in file IO handle.",
467
                 function );
468
469
    goto on_error;
470
  }
471
#endif
472
  filename_length = wide_string_length(
473
                     filename );
474
475
  if( libbfio_file_set_name_wide(
476
       file_io_handle,
477
       filename,
478
       filename_length + 1,
479
       error ) != 1 )
480
  {
481
                libcerror_error_set(
482
                 error,
483
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
484
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
485
                 "%s: unable to set filename in file IO handle.",
486
                 function );
487
488
    goto on_error;
489
  }
490
  if( libvslvm_handle_open_file_io_handle(
491
       handle,
492
       file_io_handle,
493
       access_flags,
494
       error ) != 1 )
495
  {
496
    libcerror_error_set(
497
     error,
498
     LIBCERROR_ERROR_DOMAIN_IO,
499
     LIBCERROR_IO_ERROR_OPEN_FAILED,
500
     "%s: unable to open file: %ls.",
501
     function,
502
     filename );
503
504
    goto on_error;
505
  }
506
  internal_handle->file_io_handle_created_in_library = 1;
507
508
  return( 1 );
509
510
on_error:
511
  if( file_io_handle != NULL )
512
  {
513
    libbfio_handle_free(
514
     &file_io_handle,
515
     NULL );
516
  }
517
  return( -1 );
518
}
519
520
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
521
522
/* Opens a handle using a Basic File IO (bfio) handle
523
 * Returns 1 if successful or -1 on error
524
 */
525
int libvslvm_handle_open_file_io_handle(
526
     libvslvm_handle_t *handle,
527
     libbfio_handle_t *file_io_handle,
528
     int access_flags,
529
     libcerror_error_t **error )
530
6.41k
{
531
6.41k
  libvslvm_internal_handle_t *internal_handle = NULL;
532
6.41k
  static char *function                       = "libvslvm_handle_open_file_io_handle";
533
6.41k
  uint8_t file_io_handle_opened_in_library    = 0;
534
6.41k
  int bfio_access_flags                       = 0;
535
6.41k
  int file_io_handle_is_open                  = 0;
536
537
6.41k
  if( handle == NULL )
538
0
  {
539
0
    libcerror_error_set(
540
0
     error,
541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
542
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
543
0
     "%s: invalid handle.",
544
0
     function );
545
546
0
    return( -1 );
547
0
  }
548
6.41k
  internal_handle = (libvslvm_internal_handle_t *) handle;
549
550
6.41k
  if( internal_handle->file_io_handle != NULL )
551
0
  {
552
0
    libcerror_error_set(
553
0
     error,
554
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
555
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
556
0
     "%s: invalid handle - file IO handle already set.",
557
0
     function );
558
559
0
    return( -1 );
560
0
  }
561
6.41k
  if( file_io_handle == NULL )
562
0
  {
563
0
    libcerror_error_set(
564
0
     error,
565
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
566
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
567
0
     "%s: invalid file IO handle.",
568
0
     function );
569
570
0
    return( -1 );
571
0
  }
572
6.41k
  if( ( ( access_flags & LIBVSLVM_ACCESS_FLAG_READ ) == 0 )
573
6.41k
   && ( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) == 0 ) )
574
0
  {
575
0
    libcerror_error_set(
576
0
     error,
577
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
578
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
579
0
     "%s: unsupported access flags.",
580
0
     function );
581
582
0
    return( -1 );
583
0
  }
584
6.41k
  if( ( access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) != 0 )
585
0
  {
586
0
    libcerror_error_set(
587
0
     error,
588
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
589
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
590
0
     "%s: write access currently not supported.",
591
0
     function );
592
593
0
    return( -1 );
594
0
  }
595
6.41k
  if( ( access_flags & LIBVSLVM_ACCESS_FLAG_READ ) != 0 )
596
6.41k
  {
597
6.41k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
598
6.41k
  }
599
6.41k
  file_io_handle_is_open = libbfio_handle_is_open(
600
6.41k
                            file_io_handle,
601
6.41k
                            error );
602
603
6.41k
  if( file_io_handle_is_open == -1 )
604
0
  {
605
0
    libcerror_error_set(
606
0
     error,
607
0
     LIBCERROR_ERROR_DOMAIN_IO,
608
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
609
0
     "%s: unable to open file.",
610
0
     function );
611
612
0
    goto on_error;
613
0
  }
614
6.41k
  else if( file_io_handle_is_open == 0 )
615
6.41k
  {
616
6.41k
    if( libbfio_handle_open(
617
6.41k
         file_io_handle,
618
6.41k
         bfio_access_flags,
619
6.41k
         error ) != 1 )
620
0
    {
621
0
      libcerror_error_set(
622
0
       error,
623
0
       LIBCERROR_ERROR_DOMAIN_IO,
624
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
625
0
       "%s: unable to open file IO handle.",
626
0
       function );
627
628
0
      goto on_error;
629
0
    }
630
6.41k
    file_io_handle_opened_in_library = 1;
631
6.41k
  }
632
6.41k
  if( libvslvm_internal_handle_open_read(
633
6.41k
       internal_handle,
634
6.41k
       file_io_handle,
635
6.41k
       error ) != 1 )
636
2.33k
  {
637
2.33k
    libcerror_error_set(
638
2.33k
     error,
639
2.33k
     LIBCERROR_ERROR_DOMAIN_IO,
640
2.33k
     LIBCERROR_IO_ERROR_READ_FAILED,
641
2.33k
     "%s: unable to read from file IO handle.",
642
2.33k
     function );
643
644
2.33k
    goto on_error;
645
2.33k
  }
646
4.07k
  internal_handle->file_io_handle                   = file_io_handle;
647
4.07k
  internal_handle->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
648
4.07k
  internal_handle->access_flags                     = access_flags;
649
650
4.07k
  return( 1 );
651
652
2.33k
on_error:
653
2.33k
  if( ( file_io_handle_is_open == 0 )
654
2.33k
   && ( file_io_handle_opened_in_library != 0 ) )
655
2.33k
  {
656
2.33k
    libbfio_handle_close(
657
2.33k
     file_io_handle,
658
2.33k
     error );
659
2.33k
  }
660
2.33k
  return( -1 );
661
6.41k
}
662
663
/* Opens the physical volume files
664
 * This function assumes the physical volume files are in same order as defined by the metadata
665
 * Returns 1 if successful or -1 on error
666
 */
667
int libvslvm_handle_open_physical_volume_files(
668
     libvslvm_handle_t *handle,
669
     char * const filenames[],
670
     int number_of_filenames,
671
     libcerror_error_t **error )
672
0
{
673
0
        libbfio_pool_t *file_io_pool                = NULL;
674
0
  libvslvm_internal_handle_t *internal_handle = NULL;
675
0
  libvslvm_volume_group_t *volume_group       = NULL;
676
0
  static char *function                       = "libvslvm_handle_open_physical_volume_files";
677
0
  int number_of_physical_volumes              = 0;
678
0
  int physical_volume_index                   = 0;
679
0
  int result                                  = 0;
680
681
0
  if( handle == NULL )
682
0
  {
683
0
    libcerror_error_set(
684
0
     error,
685
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
686
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
687
0
     "%s: invalid handle.",
688
0
     function );
689
690
0
    return( -1 );
691
0
  }
692
0
  internal_handle = (libvslvm_internal_handle_t *) handle;
693
694
0
  if( internal_handle->physical_volume_file_io_pool != NULL )
695
0
  {
696
0
    libcerror_error_set(
697
0
     error,
698
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
699
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
700
0
     "%s: invalid handle - physical volume file IO pool already exists.",
701
0
     function );
702
703
0
    return( -1 );
704
0
  }
705
0
  result = libvslvm_metadata_get_volume_group(
706
0
            internal_handle->metadata,
707
0
            &volume_group,
708
0
            error );
709
710
0
  if( result == -1 )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
716
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
717
0
     function );
718
719
0
    return( -1 );
720
0
  }
721
0
  else if( result == 0 )
722
0
  {
723
0
    return( 1 );
724
0
  }
725
0
  if( libvslvm_volume_group_get_number_of_physical_volumes(
726
0
       volume_group,
727
0
       &number_of_physical_volumes,
728
0
       error ) != 1 )
729
0
  {
730
0
    libcerror_error_set(
731
0
     error,
732
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
733
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
734
0
     "%s: unable to retrieve number of physical volumes.",
735
0
     function );
736
737
0
    goto on_error;
738
0
  }
739
0
  if( number_of_physical_volumes == 0 )
740
0
  {
741
0
    libcerror_error_set(
742
0
     error,
743
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
744
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
745
0
     "%s: missing physical volumes.",
746
0
     function );
747
748
0
    goto on_error;
749
0
  }
750
0
  if( number_of_filenames != number_of_physical_volumes )
751
0
  {
752
0
    libcerror_error_set(
753
0
     error,
754
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
755
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
756
0
     "%s: mismatch between number of filenames and physical volumes in metadata.",
757
0
     function );
758
759
0
    goto on_error;
760
0
  }
761
0
  if( libbfio_pool_initialize(
762
0
       &file_io_pool,
763
0
       number_of_physical_volumes,
764
0
       internal_handle->maximum_number_of_open_handles,
765
0
       error ) != 1 )
766
0
  {
767
0
    libcerror_error_set(
768
0
     error,
769
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
770
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
771
0
     "%s: unable to create file IO pool.",
772
0
     function );
773
774
0
    goto on_error;
775
0
  }
776
0
  for( physical_volume_index = 0;
777
0
       physical_volume_index < number_of_physical_volumes;
778
0
       physical_volume_index++ )
779
0
  {
780
0
    if( filenames[ physical_volume_index ] == NULL )
781
0
    {
782
0
      libcerror_error_set(
783
0
       error,
784
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
785
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
786
0
       "%s: missing filename for physical volume: %d.",
787
0
       function,
788
0
       physical_volume_index );
789
790
0
      goto on_error;
791
0
    }
792
0
    if( libvslvm_internal_handle_open_physical_volume_file(
793
0
         internal_handle,
794
0
         file_io_pool,
795
0
         physical_volume_index,
796
0
         filenames[ physical_volume_index ],
797
0
         error ) != 1 )
798
0
    {
799
0
      libcerror_error_set(
800
0
       error,
801
0
       LIBCERROR_ERROR_DOMAIN_IO,
802
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
803
0
       "%s: unable to open physical volume file: %" PRIs_SYSTEM ".",
804
0
       function,
805
0
       filenames[ physical_volume_index ] );
806
807
0
      goto on_error;
808
0
    }
809
0
  }
810
0
  if( libvslvm_internal_handle_open_read_data_area_table(
811
0
       internal_handle,
812
0
       file_io_pool,
813
0
       error ) != 1 )
814
0
  {
815
0
                libcerror_error_set(
816
0
                 error,
817
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
818
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
819
0
                 "%s: unable to read data area table.",
820
0
                 function );
821
822
0
                goto on_error;
823
0
  }
824
0
  internal_handle->physical_volume_file_io_pool                    = file_io_pool;
825
0
  internal_handle->physical_volume_file_io_pool_created_in_library = 1;
826
827
0
  return( 1 );
828
829
0
on_error:
830
0
  if( file_io_pool != NULL )
831
0
  {
832
0
    libbfio_pool_close_all(
833
0
     file_io_pool,
834
0
     NULL );
835
0
    libbfio_pool_free(
836
0
     &file_io_pool,
837
0
     NULL );
838
0
  }
839
0
  return( -1 );
840
0
}
841
842
#if defined( HAVE_WIDE_CHARACTER_TYPE )
843
844
/* Opens the physical volume files
845
 * This function assumes the physical volume files are in same order as defined by the metadata
846
 * Returns 1 if successful or -1 on error
847
 */
848
int libvslvm_handle_open_physical_volume_files_wide(
849
     libvslvm_handle_t *handle,
850
     wchar_t * const filenames[],
851
     int number_of_filenames,
852
     libcerror_error_t **error )
853
{
854
        libbfio_pool_t *file_io_pool                = NULL;
855
  libvslvm_internal_handle_t *internal_handle = NULL;
856
  libvslvm_volume_group_t *volume_group       = NULL;
857
  static char *function                       = "libvslvm_handle_open_physical_volume_files_wide";
858
  int number_of_physical_volumes              = 0;
859
  int physical_volume_index                   = 0;
860
  int result                                  = 0;
861
862
  if( handle == NULL )
863
  {
864
    libcerror_error_set(
865
     error,
866
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
867
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
868
     "%s: invalid handle.",
869
     function );
870
871
    return( -1 );
872
  }
873
  internal_handle = (libvslvm_internal_handle_t *) handle;
874
875
  if( internal_handle->physical_volume_file_io_pool != NULL )
876
  {
877
    libcerror_error_set(
878
     error,
879
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
880
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
881
     "%s: invalid handle - physical volume file IO pool already exists.",
882
     function );
883
884
    return( -1 );
885
  }
886
  result = libvslvm_metadata_get_volume_group(
887
            internal_handle->metadata,
888
            &volume_group,
889
            error );
890
891
  if( result == -1 )
892
  {
893
    libcerror_error_set(
894
     error,
895
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
896
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
897
     "%s: unable to retrieve number of metadata area descriptors from array.",
898
     function );
899
900
    return( -1 );
901
  }
902
  else if( result == 0 )
903
  {
904
    return( 1 );
905
  }
906
  if( libvslvm_volume_group_get_number_of_physical_volumes(
907
       volume_group,
908
       &number_of_physical_volumes,
909
       error ) != 1 )
910
  {
911
    libcerror_error_set(
912
     error,
913
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
914
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
915
     "%s: unable to retrieve number of physical volumes.",
916
     function );
917
918
    goto on_error;
919
  }
920
  if( number_of_physical_volumes == 0 )
921
  {
922
    libcerror_error_set(
923
     error,
924
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
925
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
926
     "%s: missing physical volumes.",
927
     function );
928
929
    goto on_error;
930
  }
931
  if( number_of_filenames != number_of_physical_volumes )
932
  {
933
    libcerror_error_set(
934
     error,
935
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
936
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
937
     "%s: mismatch between number of filenames and physical volumes in metadata.",
938
     function );
939
940
    goto on_error;
941
  }
942
  if( libbfio_pool_initialize(
943
       &file_io_pool,
944
       number_of_physical_volumes,
945
       internal_handle->maximum_number_of_open_handles,
946
       error ) != 1 )
947
  {
948
    libcerror_error_set(
949
     error,
950
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
951
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
952
     "%s: unable to create file IO pool.",
953
     function );
954
955
    goto on_error;
956
  }
957
  for( physical_volume_index = 0;
958
       physical_volume_index < number_of_physical_volumes;
959
       physical_volume_index++ )
960
  {
961
    if( filenames[ physical_volume_index ] == NULL )
962
    {
963
      libcerror_error_set(
964
       error,
965
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
966
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
967
       "%s: missing filename for physical volume: %d.",
968
       function,
969
       physical_volume_index );
970
971
      goto on_error;
972
    }
973
    if( libvslvm_internal_handle_open_physical_volume_file_wide(
974
         internal_handle,
975
         file_io_pool,
976
         physical_volume_index,
977
         filenames[ physical_volume_index ],
978
         error ) != 1 )
979
    {
980
      libcerror_error_set(
981
       error,
982
       LIBCERROR_ERROR_DOMAIN_IO,
983
       LIBCERROR_IO_ERROR_OPEN_FAILED,
984
       "%s: unable to open physical volume file: %" PRIs_SYSTEM ".",
985
       function,
986
       filenames[ physical_volume_index ] );
987
988
      goto on_error;
989
    }
990
  }
991
  if( libvslvm_internal_handle_open_read_data_area_table(
992
       internal_handle,
993
       file_io_pool,
994
       error ) != 1 )
995
  {
996
                libcerror_error_set(
997
                 error,
998
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
999
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1000
                 "%s: unable to read data area table.",
1001
                 function );
1002
1003
                goto on_error;
1004
  }
1005
  internal_handle->physical_volume_file_io_pool                    = file_io_pool;
1006
  internal_handle->physical_volume_file_io_pool_created_in_library = 1;
1007
1008
  return( 1 );
1009
1010
on_error:
1011
  if( file_io_pool != NULL )
1012
  {
1013
    libbfio_pool_close_all(
1014
     file_io_pool,
1015
     NULL );
1016
    libbfio_pool_free(
1017
     &file_io_pool,
1018
     NULL );
1019
  }
1020
  return( -1 );
1021
}
1022
1023
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1024
1025
/* Opens the physical volume files using a Basic File IO (bfio) pool
1026
 * This function assumes the physical volume files are in same order as defined by the metadata
1027
 * Returns 1 if successful or -1 on error
1028
 */
1029
int libvslvm_handle_open_physical_volume_files_file_io_pool(
1030
     libvslvm_handle_t *handle,
1031
     libbfio_pool_t *file_io_pool,
1032
     libcerror_error_t **error )
1033
4.07k
{
1034
4.07k
  libvslvm_internal_handle_t *internal_handle = NULL;
1035
4.07k
  libvslvm_volume_group_t *volume_group       = NULL;
1036
4.07k
  static char *function                       = "libvslvm_handle_open_physical_volume_files_file_io_pool";
1037
4.07k
  int number_of_file_io_handles               = 0;
1038
4.07k
  int number_of_physical_volumes              = 0;
1039
4.07k
  int result                                  = 0;
1040
1041
4.07k
  if( handle == NULL )
1042
0
  {
1043
0
    libcerror_error_set(
1044
0
     error,
1045
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1046
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1047
0
     "%s: invalid handle.",
1048
0
     function );
1049
1050
0
    return( -1 );
1051
0
  }
1052
4.07k
  internal_handle = (libvslvm_internal_handle_t *) handle;
1053
1054
4.07k
  if( internal_handle->physical_volume_file_io_pool != NULL )
1055
0
  {
1056
0
    libcerror_error_set(
1057
0
     error,
1058
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1059
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1060
0
     "%s: invalid handle - physical volume file IO pool already exists.",
1061
0
     function );
1062
1063
0
    return( -1 );
1064
0
  }
1065
4.07k
  result = libvslvm_metadata_get_volume_group(
1066
4.07k
            internal_handle->metadata,
1067
4.07k
            &volume_group,
1068
4.07k
            error );
1069
1070
4.07k
  if( result == -1 )
1071
0
  {
1072
0
    libcerror_error_set(
1073
0
     error,
1074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1075
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1076
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
1077
0
     function );
1078
1079
0
    return( -1 );
1080
0
  }
1081
4.07k
  else if( result == 0 )
1082
0
  {
1083
0
    return( 1 );
1084
0
  }
1085
4.07k
  if( libvslvm_volume_group_get_number_of_physical_volumes(
1086
4.07k
       volume_group,
1087
4.07k
       &number_of_physical_volumes,
1088
4.07k
       error ) != 1 )
1089
0
  {
1090
0
    libcerror_error_set(
1091
0
     error,
1092
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1093
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1094
0
     "%s: unable to retrieve number of physical volumes.",
1095
0
     function );
1096
1097
0
    return( -1 );
1098
0
  }
1099
4.07k
  if( libbfio_pool_get_number_of_handles(
1100
4.07k
       file_io_pool,
1101
4.07k
       &number_of_file_io_handles,
1102
4.07k
       error ) != 1 )
1103
0
  {
1104
0
    libcerror_error_set(
1105
0
     error,
1106
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1107
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1108
0
     "%s: unable to retrieve number of handles in file IO pool.",
1109
0
     function );
1110
1111
0
    return( -1 );
1112
0
  }
1113
4.07k
  if( number_of_physical_volumes == 0 )
1114
2.75k
  {
1115
2.75k
    libcerror_error_set(
1116
2.75k
     error,
1117
2.75k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1118
2.75k
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1119
2.75k
     "%s: missing physical volumes.",
1120
2.75k
     function );
1121
1122
2.75k
    return( -1 );
1123
2.75k
  }
1124
1.32k
  if( number_of_file_io_handles != number_of_physical_volumes )
1125
249
  {
1126
249
    libcerror_error_set(
1127
249
     error,
1128
249
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1129
249
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1130
249
     "%s: mismatch between number of filenames and physical volumes in metadata.",
1131
249
     function );
1132
1133
249
    return( -1 );
1134
249
  }
1135
1.07k
  if( libvslvm_internal_handle_open_read_data_area_table(
1136
1.07k
       internal_handle,
1137
1.07k
       file_io_pool,
1138
1.07k
       error ) != 1 )
1139
579
  {
1140
579
                libcerror_error_set(
1141
579
                 error,
1142
579
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1143
579
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1144
579
                 "%s: unable to read data area table.",
1145
579
                 function );
1146
1147
579
                return( -1 );
1148
579
  }
1149
496
  internal_handle->physical_volume_file_io_pool = file_io_pool;
1150
1151
496
  return( 1 );
1152
1.07k
}
1153
1154
/* Opens a specific physical volume file
1155
 * Returns 1 if successful or -1 on error
1156
 */
1157
int libvslvm_internal_handle_open_physical_volume_file(
1158
     libvslvm_internal_handle_t *internal_handle,
1159
     libbfio_pool_t *file_io_pool,
1160
     int physical_volume_index,
1161
     const char *filename,
1162
     libcerror_error_t **error )
1163
0
{
1164
0
  libbfio_handle_t *file_io_handle = NULL;
1165
0
  static char *function            = "libvslvm_internal_handle_open_physical_volume_file";
1166
0
  size_t filename_length           = 0;
1167
1168
0
  if( internal_handle == NULL )
1169
0
  {
1170
0
    libcerror_error_set(
1171
0
     error,
1172
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1173
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1174
0
     "%s: invalid handle.",
1175
0
     function );
1176
1177
0
    return( -1 );
1178
0
  }
1179
0
  if( filename == 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 filename.",
1186
0
     function );
1187
1188
0
    return( -1 );
1189
0
  }
1190
0
  if( libbfio_file_initialize(
1191
0
       &file_io_handle,
1192
0
       error ) != 1 )
1193
0
  {
1194
0
    libcerror_error_set(
1195
0
     error,
1196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1197
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1198
0
     "%s: unable to create file IO handle.",
1199
0
     function );
1200
1201
0
    goto on_error;
1202
0
  }
1203
#if defined( HAVE_DEBUG_OUTPUT )
1204
  if( libbfio_handle_set_track_offsets_read(
1205
       file_io_handle,
1206
       1,
1207
       error ) != 1 )
1208
  {
1209
                libcerror_error_set(
1210
                 error,
1211
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1212
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1213
                 "%s: unable to set track offsets read in file IO handle.",
1214
                 function );
1215
1216
                goto on_error;
1217
  }
1218
#endif
1219
0
  filename_length = narrow_string_length(
1220
0
                     filename );
1221
1222
0
  if( libbfio_file_set_name(
1223
0
       file_io_handle,
1224
0
       filename,
1225
0
       filename_length + 1,
1226
0
       error ) != 1 )
1227
0
  {
1228
0
                libcerror_error_set(
1229
0
                 error,
1230
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1231
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1232
0
                 "%s: unable to set filename in file IO handle.",
1233
0
                 function );
1234
1235
0
                goto on_error;
1236
0
  }
1237
0
  if( libvslvm_internal_handle_open_physical_volume_file_io_handle(
1238
0
       internal_handle,
1239
0
       file_io_pool,
1240
0
       physical_volume_index,
1241
0
       file_io_handle,
1242
0
       error ) != 1 )
1243
0
  {
1244
0
    libcerror_error_set(
1245
0
     error,
1246
0
     LIBCERROR_ERROR_DOMAIN_IO,
1247
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1248
0
     "%s: unable to open physical volume file: %s.",
1249
0
     function,
1250
0
     filename );
1251
1252
0
    goto on_error;
1253
0
  }
1254
0
  return( 1 );
1255
1256
0
on_error:
1257
0
  if( file_io_handle != NULL )
1258
0
  {
1259
0
    libbfio_handle_free(
1260
0
     &file_io_handle,
1261
0
     NULL );
1262
0
  }
1263
0
  return( -1 );
1264
0
}
1265
1266
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1267
1268
/* Opens a specific physical volume file
1269
 * Returns 1 if successful or -1 on error
1270
 */
1271
int libvslvm_internal_handle_open_physical_volume_file_wide(
1272
     libvslvm_internal_handle_t *internal_handle,
1273
     libbfio_pool_t *file_io_pool,
1274
     int physical_volume_index,
1275
     const wchar_t *filename,
1276
     libcerror_error_t **error )
1277
{
1278
  libbfio_handle_t *file_io_handle = NULL;
1279
  static char *function            = "libvslvm_internal_handle_open_physical_volume_file_wide";
1280
  size_t filename_length           = 0;
1281
1282
  if( internal_handle == NULL )
1283
  {
1284
    libcerror_error_set(
1285
     error,
1286
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1287
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1288
     "%s: invalid handle.",
1289
     function );
1290
1291
    return( -1 );
1292
  }
1293
  if( filename == NULL )
1294
  {
1295
    libcerror_error_set(
1296
     error,
1297
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1298
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1299
     "%s: invalid filename.",
1300
     function );
1301
1302
    return( -1 );
1303
  }
1304
  if( libbfio_file_initialize(
1305
       &file_io_handle,
1306
       error ) != 1 )
1307
  {
1308
    libcerror_error_set(
1309
     error,
1310
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1311
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1312
     "%s: unable to create file IO handle.",
1313
     function );
1314
1315
                goto on_error;
1316
  }
1317
#if defined( HAVE_DEBUG_OUTPUT )
1318
  if( libbfio_handle_set_track_offsets_read(
1319
       file_io_handle,
1320
       1,
1321
       error ) != 1 )
1322
  {
1323
                libcerror_error_set(
1324
                 error,
1325
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1326
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1327
                 "%s: unable to set track offsets read in file IO handle.",
1328
                 function );
1329
1330
                goto on_error;
1331
  }
1332
#endif
1333
  filename_length = wide_string_length(
1334
                     filename );
1335
1336
  if( libbfio_file_set_name_wide(
1337
       file_io_handle,
1338
       filename,
1339
       filename_length + 1,
1340
       error ) != 1 )
1341
  {
1342
                libcerror_error_set(
1343
                 error,
1344
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1345
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1346
                 "%s: unable to set filename in file IO handle.",
1347
                 function );
1348
1349
                goto on_error;
1350
  }
1351
  if( libvslvm_internal_handle_open_physical_volume_file_io_handle(
1352
       internal_handle,
1353
       file_io_pool,
1354
       physical_volume_index,
1355
       file_io_handle,
1356
       error ) != 1 )
1357
  {
1358
    libcerror_error_set(
1359
     error,
1360
     LIBCERROR_ERROR_DOMAIN_IO,
1361
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1362
     "%s: unable to open physical volume file: %ls.",
1363
     function,
1364
     filename );
1365
1366
    goto on_error;
1367
  }
1368
  return( 1 );
1369
1370
on_error:
1371
  if( file_io_handle != NULL )
1372
  {
1373
    libbfio_handle_free(
1374
     &file_io_handle,
1375
     NULL );
1376
  }
1377
  return( -1 );
1378
}
1379
1380
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1381
1382
/* Opens an physical volume file using a Basic File IO (bfio) handle
1383
 * Returns 1 if successful or -1 on error
1384
 */
1385
int libvslvm_internal_handle_open_physical_volume_file_io_handle(
1386
     libvslvm_internal_handle_t *internal_handle,
1387
     libbfio_pool_t *file_io_pool,
1388
     int physical_volume_index,
1389
     libbfio_handle_t *file_io_handle,
1390
     libcerror_error_t **error )
1391
0
{
1392
0
  static char *function                    = "libvslvm_internal_handle_open_physical_volume_file_io_handle";
1393
0
  uint8_t file_io_handle_opened_in_library = 0;
1394
0
  int bfio_access_flags                    = 0;
1395
0
  int file_io_handle_is_open               = 0;
1396
1397
0
  if( internal_handle == NULL )
1398
0
  {
1399
0
    libcerror_error_set(
1400
0
     error,
1401
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1402
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1403
0
     "%s: invalid handle.",
1404
0
     function );
1405
1406
0
    return( -1 );
1407
0
  }
1408
0
  if( ( ( internal_handle->access_flags & LIBVSLVM_ACCESS_FLAG_READ ) == 0 )
1409
0
   && ( ( internal_handle->access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) == 0 ) )
1410
0
  {
1411
0
    libcerror_error_set(
1412
0
     error,
1413
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1414
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1415
0
     "%s: unsupported access flags.",
1416
0
     function );
1417
1418
0
    return( -1 );
1419
0
  }
1420
0
  if( ( internal_handle->access_flags & LIBVSLVM_ACCESS_FLAG_WRITE ) != 0 )
1421
0
  {
1422
0
    libcerror_error_set(
1423
0
     error,
1424
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1425
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1426
0
     "%s: write access currently not supported.",
1427
0
     function );
1428
1429
0
    return( -1 );
1430
0
  }
1431
0
  if( ( internal_handle->access_flags & LIBVSLVM_ACCESS_FLAG_READ ) != 0 )
1432
0
  {
1433
0
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
1434
0
  }
1435
0
  file_io_handle_is_open = libbfio_handle_is_open(
1436
0
                            file_io_handle,
1437
0
                            error );
1438
1439
0
  if( file_io_handle_is_open == -1 )
1440
0
  {
1441
0
    libcerror_error_set(
1442
0
     error,
1443
0
     LIBCERROR_ERROR_DOMAIN_IO,
1444
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1445
0
     "%s: unable to determine if file IO handle is open.",
1446
0
     function );
1447
1448
0
    goto on_error;
1449
0
  }
1450
0
  else if( file_io_handle_is_open == 0 )
1451
0
  {
1452
0
    if( libbfio_handle_open(
1453
0
         file_io_handle,
1454
0
         bfio_access_flags,
1455
0
         error ) != 1 )
1456
0
    {
1457
0
      libcerror_error_set(
1458
0
       error,
1459
0
       LIBCERROR_ERROR_DOMAIN_IO,
1460
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1461
0
       "%s: unable to open file IO handle.",
1462
0
       function );
1463
1464
0
      goto on_error;
1465
0
    }
1466
0
    file_io_handle_opened_in_library = 1;
1467
0
  }
1468
0
  if( libbfio_pool_set_handle(
1469
0
       file_io_pool,
1470
0
       physical_volume_index,
1471
0
       file_io_handle,
1472
0
       bfio_access_flags,
1473
0
       error ) != 1 )
1474
0
  {
1475
0
    libcerror_error_set(
1476
0
     error,
1477
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1478
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1479
0
     "%s: unable to set file IO handle: %d in pool.",
1480
0
     function,
1481
0
     physical_volume_index );
1482
1483
0
    goto on_error;
1484
0
  }
1485
0
  return( 1 );
1486
1487
0
on_error:
1488
0
  if( file_io_handle_opened_in_library != 0 )
1489
0
  {
1490
0
    libbfio_handle_close(
1491
0
     file_io_handle,
1492
0
     error );
1493
0
  }
1494
0
  return( -1 );
1495
0
}
1496
1497
/* Reads the data area table
1498
 * Returns 1 if successful or -1 on error
1499
 */
1500
int libvslvm_internal_handle_open_read_data_area_table(
1501
     libvslvm_internal_handle_t *internal_handle,
1502
     libbfio_pool_t *file_io_pool,
1503
     libcerror_error_t **error )
1504
1.07k
{
1505
1.07k
  libvslvm_physical_volume_t *physical_volume = NULL;
1506
1.07k
  libvslvm_volume_group_t *volume_group       = NULL;
1507
1.07k
  static char *function                       = "libvslvm_internal_handle_open_read_data_area_table";
1508
1.07k
  off64_t file_offset                         = 0;
1509
1.07k
  int number_of_file_io_handles               = 0;
1510
1.07k
  int number_of_data_area_descriptors         = 0;
1511
1.07k
  int number_of_physical_volumes              = 0;
1512
1.07k
  int physical_volume_index                   = 0;
1513
1.07k
  int result                                  = 0;
1514
1515
1.07k
  if( internal_handle == NULL )
1516
0
  {
1517
0
    libcerror_error_set(
1518
0
     error,
1519
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1520
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1521
0
     "%s: invalid handle.",
1522
0
     function );
1523
1524
0
    return( -1 );
1525
0
  }
1526
1.07k
  result = libvslvm_metadata_get_volume_group(
1527
1.07k
            internal_handle->metadata,
1528
1.07k
            &volume_group,
1529
1.07k
            error );
1530
1531
1.07k
  if( result == -1 )
1532
0
  {
1533
0
    libcerror_error_set(
1534
0
     error,
1535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1536
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1537
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
1538
0
     function );
1539
1540
0
    return( -1 );
1541
0
  }
1542
1.07k
  else if( result == 0 )
1543
0
  {
1544
0
    return( 1 );
1545
0
  }
1546
1.07k
  if( libvslvm_volume_group_get_number_of_physical_volumes(
1547
1.07k
       volume_group,
1548
1.07k
       &number_of_physical_volumes,
1549
1.07k
       error ) != 1 )
1550
0
  {
1551
0
    libcerror_error_set(
1552
0
     error,
1553
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1554
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1555
0
     "%s: unable to retrieve number of physical volumes.",
1556
0
     function );
1557
1558
0
    return( -1 );
1559
0
  }
1560
1.07k
  if( number_of_physical_volumes == 0 )
1561
0
  {
1562
0
    libcerror_error_set(
1563
0
     error,
1564
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1565
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1566
0
     "%s: missing physical volumes.",
1567
0
     function );
1568
1569
0
    return( -1 );
1570
0
  }
1571
1.07k
  if( libbfio_pool_get_number_of_handles(
1572
1.07k
       file_io_pool,
1573
1.07k
       &number_of_file_io_handles,
1574
1.07k
       error ) != 1 )
1575
0
  {
1576
0
    libcerror_error_set(
1577
0
     error,
1578
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1579
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1580
0
     "%s: unable to retrieve the number of file IO handles.",
1581
0
     function );
1582
1583
0
    return( -1 );
1584
0
  }
1585
1.07k
  if( number_of_file_io_handles != number_of_physical_volumes )
1586
0
  {
1587
0
    libcerror_error_set(
1588
0
     error,
1589
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1590
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1591
0
     "%s: mismatch between number of file IO handles in pool and physical volumes in metadata.",
1592
0
     function );
1593
1594
0
    return( -1 );
1595
0
  }
1596
1.07k
  for( physical_volume_index = 0;
1597
1.57k
       physical_volume_index < number_of_physical_volumes;
1598
1.07k
       physical_volume_index++ )
1599
1.07k
  {
1600
1.07k
    if( libvslvm_volume_group_get_physical_volume(
1601
1.07k
         volume_group,
1602
1.07k
         physical_volume_index,
1603
1.07k
         &physical_volume,
1604
1.07k
         error ) != 1 )
1605
0
    {
1606
0
      libcerror_error_set(
1607
0
       error,
1608
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1609
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1610
0
       "%s: unable to retrieve physical volume: %d from volume group.",
1611
0
       function,
1612
0
       physical_volume_index );
1613
1614
0
      return( -1 );
1615
0
    }
1616
    /* The physical volume label can be stored in one of the first 4 sectors
1617
     */
1618
1.07k
    file_offset = 0;
1619
1620
1.19k
    while( file_offset < 2048 )
1621
1.19k
    {
1622
1.19k
      result = libvslvm_physical_volume_read_label_file_io_pool(
1623
1.19k
          physical_volume,
1624
1.19k
          file_io_pool,
1625
1.19k
          physical_volume_index,
1626
1.19k
          file_offset,
1627
1.19k
          error );
1628
1629
1.19k
      if( result == -1 )
1630
0
      {
1631
0
        libcerror_error_set(
1632
0
         error,
1633
0
         LIBCERROR_ERROR_DOMAIN_IO,
1634
0
         LIBCERROR_IO_ERROR_READ_FAILED,
1635
0
         "%s: unable to read physical volume label at offset: %" PRIi64 ".",
1636
0
         function,
1637
0
         file_offset );
1638
1639
0
        return( -1 );
1640
0
      }
1641
1.19k
      else if( result != 0 )
1642
1.07k
      {
1643
1.07k
        break;
1644
1.07k
      }
1645
121
      file_offset += 512;
1646
121
    }
1647
1.07k
    if( libvslvm_physical_volume_get_number_of_data_area_descriptors(
1648
1.07k
         physical_volume,
1649
1.07k
         &number_of_data_area_descriptors,
1650
1.07k
         error ) != 1 )
1651
0
    {
1652
0
      libcerror_error_set(
1653
0
       error,
1654
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1655
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1656
0
       "%s: unable to retrieve number of data area descriptors from array.",
1657
0
       function );
1658
1659
0
      return( -1 );
1660
0
    }
1661
1.07k
    if( number_of_data_area_descriptors <= 0 )
1662
579
    {
1663
579
      libcerror_error_set(
1664
579
       error,
1665
579
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1666
579
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1667
579
       "%s: unsupported number of data area descriptors.",
1668
579
       function );
1669
1670
579
      return( -1 );
1671
579
    }
1672
1.07k
  }
1673
/* TODO build data area table */
1674
496
  return( 1 );
1675
1.07k
}
1676
1677
/* Closes a handle
1678
 * Returns 0 if successful or -1 on error
1679
 */
1680
int libvslvm_handle_close(
1681
     libvslvm_handle_t *handle,
1682
     libcerror_error_t **error )
1683
4.07k
{
1684
4.07k
  libvslvm_internal_handle_t *internal_handle = NULL;
1685
4.07k
  static char *function                       = "libvslvm_handle_close";
1686
4.07k
  int result                                  = 0;
1687
1688
4.07k
  if( handle == NULL )
1689
0
  {
1690
0
    libcerror_error_set(
1691
0
     error,
1692
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1693
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1694
0
     "%s: invalid handle.",
1695
0
     function );
1696
1697
0
    return( -1 );
1698
0
  }
1699
4.07k
  internal_handle = (libvslvm_internal_handle_t *) handle;
1700
1701
4.07k
  if( internal_handle->file_io_handle == NULL )
1702
0
  {
1703
0
    libcerror_error_set(
1704
0
     error,
1705
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1706
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1707
0
     "%s: invalid handle - missing file IO handle.",
1708
0
     function );
1709
1710
0
    return( -1 );
1711
0
  }
1712
#if defined( HAVE_DEBUG_OUTPUT )
1713
  if( libcnotify_verbose != 0 )
1714
  {
1715
    if( internal_handle->file_io_handle_created_in_library != 0 )
1716
    {
1717
      if( libvslvm_debug_print_read_offsets(
1718
           internal_handle->file_io_handle,
1719
           error ) != 1 )
1720
      {
1721
        libcerror_error_set(
1722
         error,
1723
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1724
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1725
         "%s: unable to print the read offsets.",
1726
         function );
1727
1728
        result = -1;
1729
      }
1730
    }
1731
  }
1732
#endif
1733
4.07k
  if( internal_handle->file_io_handle_opened_in_library != 0 )
1734
4.07k
  {
1735
4.07k
    if( libbfio_handle_close(
1736
4.07k
         internal_handle->file_io_handle,
1737
4.07k
         error ) != 0 )
1738
0
    {
1739
0
      libcerror_error_set(
1740
0
       error,
1741
0
       LIBCERROR_ERROR_DOMAIN_IO,
1742
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1743
0
       "%s: unable to close file IO handle.",
1744
0
       function );
1745
1746
0
      result = -1;
1747
0
    }
1748
4.07k
    internal_handle->file_io_handle_opened_in_library = 0;
1749
4.07k
  }
1750
4.07k
  if( internal_handle->file_io_handle_created_in_library != 0 )
1751
0
  {
1752
0
    if( libbfio_handle_free(
1753
0
         &( internal_handle->file_io_handle ),
1754
0
         error ) != 1 )
1755
0
    {
1756
0
      libcerror_error_set(
1757
0
       error,
1758
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1759
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1760
0
       "%s: unable to free file IO handle.",
1761
0
       function );
1762
1763
0
      result = -1;
1764
0
    }
1765
0
    internal_handle->file_io_handle_created_in_library = 0;
1766
0
  }
1767
4.07k
  internal_handle->file_io_handle = NULL;
1768
1769
4.07k
  if( internal_handle->physical_volume_file_io_pool_created_in_library != 0 )
1770
0
  {
1771
0
    if( libbfio_pool_close_all(
1772
0
         internal_handle->physical_volume_file_io_pool,
1773
0
         error ) != 0 )
1774
0
    {
1775
0
      libcerror_error_set(
1776
0
       error,
1777
0
       LIBCERROR_ERROR_DOMAIN_IO,
1778
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1779
0
       "%s: unable to close physical volume file IO pool.",
1780
0
       function );
1781
1782
0
      result = -1;
1783
0
    }
1784
0
    if( libbfio_pool_free(
1785
0
         &( internal_handle->physical_volume_file_io_pool ),
1786
0
         error ) != 1 )
1787
0
    {
1788
0
      libcerror_error_set(
1789
0
       error,
1790
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1791
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1792
0
       "%s: unable to free physical volume file IO pool.",
1793
0
       function );
1794
1795
0
      result = -1;
1796
0
    }
1797
0
    internal_handle->physical_volume_file_io_pool_created_in_library = 0;
1798
0
  }
1799
4.07k
  internal_handle->physical_volume_file_io_pool = NULL;
1800
1801
4.07k
  if( libvslvm_io_handle_clear(
1802
4.07k
       internal_handle->io_handle,
1803
4.07k
       error ) != 1 )
1804
0
  {
1805
0
    libcerror_error_set(
1806
0
     error,
1807
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1808
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1809
0
     "%s: unable to clear IO handle.",
1810
0
     function );
1811
1812
0
    result = -1;
1813
0
  }
1814
4.07k
  if( internal_handle->metadata != NULL )
1815
4.07k
  {
1816
4.07k
    if( libvslvm_metadata_free(
1817
4.07k
         &( internal_handle->metadata ),
1818
4.07k
         error ) != 1 )
1819
0
    {
1820
0
      libcerror_error_set(
1821
0
       error,
1822
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1823
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1824
0
       "%s: unable to free metadata.",
1825
0
       function );
1826
1827
0
      result = -1;
1828
0
    }
1829
4.07k
  }
1830
4.07k
  return( result );
1831
4.07k
}
1832
1833
/* Opens a handle for reading
1834
 * Returns 1 if successful or -1 on error
1835
 */
1836
int libvslvm_internal_handle_open_read(
1837
     libvslvm_internal_handle_t *internal_handle,
1838
     libbfio_handle_t *file_io_handle,
1839
     libcerror_error_t **error )
1840
6.41k
{
1841
6.41k
  libbfio_pool_t *file_io_pool                                = NULL;
1842
6.41k
  libvslvm_data_area_descriptor_t *data_area_descriptor       = NULL;
1843
6.41k
  libvslvm_metadata_area_t *metadata_area                     = NULL;
1844
6.41k
  libvslvm_physical_volume_t *physical_volume                 = NULL;
1845
6.41k
  libvslvm_raw_location_descriptor_t *raw_location_descriptor = NULL;
1846
6.41k
  static char *function                                       = "libvslvm_internal_handle_open_read";
1847
6.41k
  size64_t data_area_size                                     = 0;
1848
6.41k
  size64_t metadata_size                                      = 0;
1849
6.41k
  off64_t data_area_offset                                    = 0;
1850
6.41k
  off64_t file_offset                                         = 0;
1851
6.41k
  off64_t metadata_offset                                     = 0;
1852
6.41k
  uint32_t raw_location_descriptor_flags                      = 0;
1853
6.41k
  uint32_t stored_checksum                                    = 0;
1854
6.41k
  int number_of_data_area_descriptors                         = 0;
1855
6.41k
  int number_of_raw_location_descriptors                      = 0;
1856
6.41k
  int result                                                  = 0;
1857
1858
6.41k
  if( internal_handle == NULL )
1859
0
  {
1860
0
    libcerror_error_set(
1861
0
     error,
1862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1863
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1864
0
     "%s: invalid handle.",
1865
0
     function );
1866
1867
0
    return( -1 );
1868
0
  }
1869
6.41k
  if( internal_handle->metadata != NULL )
1870
0
  {
1871
0
    libcerror_error_set(
1872
0
     error,
1873
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1874
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1875
0
     "%s: invalid handle - metadata value already set.",
1876
0
     function );
1877
1878
0
    return( -1 );
1879
0
  }
1880
6.41k
  if( libbfio_pool_initialize(
1881
6.41k
       &file_io_pool,
1882
6.41k
       1,
1883
6.41k
       0,
1884
6.41k
       error ) != 1 )
1885
0
  {
1886
0
    libcerror_error_set(
1887
0
     error,
1888
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1889
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1890
0
     "%s: unable to create file IO pool.",
1891
0
     function );
1892
1893
0
    goto on_error;
1894
0
  }
1895
6.41k
  if( libbfio_pool_set_handle(
1896
6.41k
       file_io_pool,
1897
6.41k
       0,
1898
6.41k
       file_io_handle,
1899
6.41k
       LIBBFIO_OPEN_READ,
1900
6.41k
       error ) != 1 )
1901
0
  {
1902
0
    libcerror_error_set(
1903
0
     error,
1904
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1905
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1906
0
     "%s: unable to set file IO handle: 0 in pool.",
1907
0
     function );
1908
1909
0
    goto on_error;
1910
0
  }
1911
6.41k
  if( libvslvm_physical_volume_initialize(
1912
6.41k
       &physical_volume,
1913
6.41k
       error ) != 1 )
1914
0
  {
1915
0
    libcerror_error_set(
1916
0
     error,
1917
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1918
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1919
0
     "%s: unable to create physical volume.",
1920
0
     function );
1921
1922
0
    goto on_error;
1923
0
  }
1924
  /* The physical volume label can be stored in one of the first 4 sectors
1925
   */
1926
6.91k
  while( file_offset < 2048 )
1927
6.90k
  {
1928
6.90k
    result = libvslvm_physical_volume_read_label_file_io_pool(
1929
6.90k
              physical_volume,
1930
6.90k
              file_io_pool,
1931
6.90k
              0,
1932
6.90k
              file_offset,
1933
6.90k
              error );
1934
1935
6.90k
    if( result == -1 )
1936
468
    {
1937
468
      libcerror_error_set(
1938
468
       error,
1939
468
       LIBCERROR_ERROR_DOMAIN_IO,
1940
468
       LIBCERROR_IO_ERROR_READ_FAILED,
1941
468
       "%s: unable to read physical volume label at offset: %" PRIi64 ".",
1942
468
       function,
1943
468
       file_offset );
1944
1945
468
      goto on_error;
1946
468
    }
1947
6.43k
    else if( result != 0 )
1948
5.93k
    {
1949
5.93k
      break;
1950
5.93k
    }
1951
502
    file_offset += 512;
1952
502
  }
1953
5.94k
  if( libbfio_pool_remove_handle(
1954
5.94k
       file_io_pool,
1955
5.94k
       0,
1956
5.94k
       &file_io_handle,
1957
5.94k
       error ) != 1 )
1958
0
  {
1959
0
    libcerror_error_set(
1960
0
     error,
1961
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1962
0
     LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED,
1963
0
     "%s: unable to remove file IO handle: 0 from pool.",
1964
0
     function );
1965
1966
0
    goto on_error;
1967
0
  }
1968
5.94k
  if( libbfio_pool_free(
1969
5.94k
       &file_io_pool,
1970
5.94k
       error ) != 1 )
1971
0
  {
1972
0
    libcerror_error_set(
1973
0
     error,
1974
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1975
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1976
0
     "%s: unable to free file IO pool.",
1977
0
     function );
1978
1979
0
    goto on_error;
1980
0
  }
1981
5.94k
  if( libvslvm_physical_volume_get_number_of_metadata_area_descriptors(
1982
5.94k
       physical_volume,
1983
5.94k
       &number_of_data_area_descriptors,
1984
5.94k
       error ) != 1 )
1985
0
  {
1986
0
    libcerror_error_set(
1987
0
     error,
1988
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1989
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1990
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
1991
0
     function );
1992
1993
0
    goto on_error;
1994
0
  }
1995
/* TODO add support for more than one metadata area descriptors */
1996
5.94k
  if( number_of_data_area_descriptors != 1 )
1997
21
  {
1998
21
    libcerror_error_set(
1999
21
     error,
2000
21
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2001
21
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2002
21
     "%s: unsupported number of metadata area descriptors: %d.",
2003
21
     function,
2004
21
     number_of_data_area_descriptors );
2005
2006
21
    goto on_error;
2007
21
  }
2008
5.92k
  if( libvslvm_physical_volume_get_metadata_area_descriptor(
2009
5.92k
       physical_volume,
2010
5.92k
       0,
2011
5.92k
       &data_area_descriptor,
2012
5.92k
       error ) != 1 )
2013
0
  {
2014
0
    libcerror_error_set(
2015
0
     error,
2016
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2017
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2018
0
     "%s: unable to retrieve metadata area descriptor: 0.",
2019
0
     function );
2020
2021
0
    goto on_error;
2022
0
  }
2023
5.92k
  if( libvslvm_data_area_descriptor_get(
2024
5.92k
       data_area_descriptor,
2025
5.92k
       &data_area_offset,
2026
5.92k
       &data_area_size,
2027
5.92k
       error ) != 1 )
2028
0
  {
2029
0
    libcerror_error_set(
2030
0
     error,
2031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2032
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2033
0
     "%s: unable to retrieve metadata area descriptor: 0 values.",
2034
0
     function );
2035
2036
0
    goto on_error;
2037
0
  }
2038
  /* Read the metadata area
2039
   */
2040
5.92k
  if( libvslvm_metadata_area_initialize(
2041
5.92k
       &metadata_area,
2042
5.92k
       error ) != 1 )
2043
0
  {
2044
0
    libcerror_error_set(
2045
0
     error,
2046
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2047
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2048
0
     "%s: unable to create metadata area.",
2049
0
     function );
2050
2051
0
    goto on_error;
2052
0
  }
2053
5.92k
  if( libvslvm_metadata_area_read_file_io_handle(
2054
5.92k
       metadata_area,
2055
5.92k
       file_io_handle,
2056
5.92k
       data_area_offset,
2057
5.92k
       error ) != 1 )
2058
565
  {
2059
565
    libcerror_error_set(
2060
565
     error,
2061
565
     LIBCERROR_ERROR_DOMAIN_IO,
2062
565
     LIBCERROR_IO_ERROR_READ_FAILED,
2063
565
     "%s: unable to read metadata area.",
2064
565
     function );
2065
2066
565
    goto on_error;
2067
565
  }
2068
5.35k
  if( libcdata_array_get_number_of_entries(
2069
5.35k
       metadata_area->raw_location_descriptors_array,
2070
5.35k
       &number_of_raw_location_descriptors,
2071
5.35k
       error ) != 1 )
2072
0
  {
2073
0
    libcerror_error_set(
2074
0
     error,
2075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2076
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2077
0
     "%s: unable to retrieve number of raw location descriptors from array.",
2078
0
     function );
2079
2080
0
    goto on_error;
2081
0
  }
2082
/* TODO add support for more than one raw location descriptors */
2083
5.35k
  if( number_of_raw_location_descriptors != 1 )
2084
7
  {
2085
7
    libcerror_error_set(
2086
7
     error,
2087
7
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2088
7
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2089
7
     "%s: unsupported number of raw location area descriptors.",
2090
7
     function );
2091
2092
7
    goto on_error;
2093
7
  }
2094
5.35k
  if( libcdata_array_get_entry_by_index(
2095
5.35k
       metadata_area->raw_location_descriptors_array,
2096
5.35k
       0,
2097
5.35k
       (intptr_t **) &raw_location_descriptor,
2098
5.35k
       error ) != 1 )
2099
0
  {
2100
0
    libcerror_error_set(
2101
0
     error,
2102
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2103
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2104
0
     "%s: unable to retrieve raw location descriptor: 0.",
2105
0
     function );
2106
2107
0
    goto on_error;
2108
0
  }
2109
5.35k
  if( libvslvm_raw_location_descriptor_get(
2110
5.35k
       raw_location_descriptor,
2111
5.35k
       &metadata_offset,
2112
5.35k
       &metadata_size,
2113
5.35k
       &stored_checksum,
2114
5.35k
       &raw_location_descriptor_flags,
2115
5.35k
       error ) != 1 )
2116
0
  {
2117
0
    libcerror_error_set(
2118
0
     error,
2119
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2120
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2121
0
     "%s: unable to retrieve raw location descriptor: 0 values.",
2122
0
     function );
2123
2124
0
    goto on_error;
2125
0
  }
2126
5.35k
  if( libvslvm_metadata_area_free(
2127
5.35k
       &metadata_area,
2128
5.35k
       error ) != 1 )
2129
0
  {
2130
0
    libcerror_error_set(
2131
0
     error,
2132
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2133
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2134
0
     "%s: unable to free metadata area.",
2135
0
     function );
2136
2137
0
    goto on_error;
2138
0
  }
2139
  /* Read the metadata
2140
   */
2141
5.35k
  if( libvslvm_metadata_initialize(
2142
5.35k
       &( internal_handle->metadata ),
2143
5.35k
       error ) != 1 )
2144
0
  {
2145
0
    libcerror_error_set(
2146
0
     error,
2147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2148
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2149
0
     "%s: unable to create metadata.",
2150
0
     function );
2151
2152
0
    goto on_error;
2153
0
  }
2154
5.35k
  if( libvslvm_metadata_read_file_io_handle(
2155
5.35k
       internal_handle->metadata,
2156
5.35k
       file_io_handle,
2157
5.35k
       metadata_offset,
2158
5.35k
       metadata_size,
2159
5.35k
       stored_checksum,
2160
5.35k
       error ) != 1 )
2161
1.27k
  {
2162
1.27k
    libcerror_error_set(
2163
1.27k
     error,
2164
1.27k
     LIBCERROR_ERROR_DOMAIN_IO,
2165
1.27k
     LIBCERROR_IO_ERROR_READ_FAILED,
2166
1.27k
     "%s: unable to read metadata.",
2167
1.27k
     function );
2168
2169
1.27k
    goto on_error;
2170
1.27k
  }
2171
4.07k
  if( libvslvm_internal_physical_volume_free(
2172
4.07k
       (libvslvm_internal_physical_volume_t **) &physical_volume,
2173
4.07k
       error ) != 1 )
2174
0
  {
2175
0
    libcerror_error_set(
2176
0
     error,
2177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2178
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2179
0
     "%s: unable to free physical volume.",
2180
0
     function );
2181
2182
0
    goto on_error;
2183
0
  }
2184
4.07k
  return( 1 );
2185
2186
2.33k
on_error:
2187
2.33k
  if( internal_handle->metadata != NULL )
2188
1.27k
  {
2189
1.27k
    libvslvm_metadata_free(
2190
1.27k
     &( internal_handle->metadata ),
2191
1.27k
     NULL );
2192
1.27k
  }
2193
2.33k
  if( metadata_area != NULL )
2194
572
  {
2195
572
    libvslvm_metadata_area_free(
2196
572
     &metadata_area,
2197
572
     NULL );
2198
572
  }
2199
2.33k
  if( physical_volume != NULL )
2200
2.33k
  {
2201
2.33k
    libvslvm_internal_physical_volume_free(
2202
2.33k
     (libvslvm_internal_physical_volume_t **) &physical_volume,
2203
2.33k
     NULL );
2204
2.33k
  }
2205
2.33k
  if( file_io_pool != NULL )
2206
468
  {
2207
468
    libbfio_pool_remove_handle(
2208
468
     file_io_pool,
2209
468
     0,
2210
468
     &file_io_handle,
2211
468
     NULL );
2212
468
    libbfio_pool_free(
2213
468
     &file_io_pool,
2214
468
     NULL );
2215
468
  }
2216
2.33k
  return( -1 );
2217
4.07k
}
2218
2219
/* Retrieves the volume group
2220
 * Returns 1 if successful, 0 if not available or -1 on error
2221
 */
2222
int libvslvm_handle_get_volume_group(
2223
     libvslvm_handle_t *handle,
2224
     libvslvm_volume_group_t **volume_group,
2225
     libcerror_error_t **error )
2226
453
{
2227
453
  libvslvm_internal_handle_t *internal_handle = NULL;
2228
453
  static char *function                       = "libvslvm_handle_get_volume_group";
2229
453
  int result                                  = 0;
2230
2231
453
  if( handle == NULL )
2232
0
  {
2233
0
    libcerror_error_set(
2234
0
     error,
2235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2237
0
     "%s: invalid handle.",
2238
0
     function );
2239
2240
0
    return( -1 );
2241
0
  }
2242
453
  internal_handle = (libvslvm_internal_handle_t *) handle;
2243
2244
453
  if( volume_group == NULL )
2245
0
  {
2246
0
    libcerror_error_set(
2247
0
     error,
2248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2250
0
     "%s: invalid volume group.",
2251
0
     function );
2252
2253
0
    return( -1 );
2254
0
  }
2255
453
  result = libvslvm_metadata_get_volume_group(
2256
453
            internal_handle->metadata,
2257
453
            volume_group,
2258
453
            error );
2259
2260
453
  if( result == -1 )
2261
0
  {
2262
0
    libcerror_error_set(
2263
0
     error,
2264
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2265
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2266
0
     "%s: unable to retrieve number of metadata area descriptors from array.",
2267
0
     function );
2268
2269
0
    return( -1 );
2270
0
  }
2271
453
  else if( result != 0 )
2272
453
  {
2273
453
    if( libvslvm_volume_group_set_io_values(
2274
453
         *volume_group,
2275
453
         internal_handle->io_handle,
2276
453
         internal_handle->physical_volume_file_io_pool,
2277
453
         error ) != 1 )
2278
0
    {
2279
0
      libcerror_error_set(
2280
0
       error,
2281
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2282
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2283
0
       "%s: unable to set IO values in volume group.",
2284
0
       function );
2285
2286
0
      return( -1 );
2287
0
    }
2288
453
  }
2289
453
  return( result );
2290
453
}
2291