Coverage Report

Created: 2025-06-24 07:14

/src/libfvde/libfvde/libfvde_volume.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Volume functions
3
 *
4
 * Copyright (C) 2011-2024, Omar Choudary <choudary.omar@gmail.com>
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <memory.h>
25
#include <narrow_string.h>
26
#include <types.h>
27
#include <wide_string.h>
28
29
#include "libfvde_codepage.h"
30
#include "libfvde_debug.h"
31
#include "libfvde_definitions.h"
32
#include "libfvde_encrypted_metadata.h"
33
#include "libfvde_encryption_context_plist.h"
34
#include "libfvde_io_handle.h"
35
#include "libfvde_libbfio.h"
36
#include "libfvde_libcerror.h"
37
#include "libfvde_libcnotify.h"
38
#include "libfvde_libcthreads.h"
39
#include "libfvde_logical_volume.h"
40
#include "libfvde_logical_volume_descriptor.h"
41
#include "libfvde_metadata.h"
42
#include "libfvde_password.h"
43
#include "libfvde_volume.h"
44
#include "libfvde_volume_group.h"
45
#include "libfvde_volume_header.h"
46
47
#include "fvde_metadata.h"
48
49
/* Creates a volume
50
 * Make sure the value volume is referencing, is set to NULL
51
 * Returns 1 if successful or -1 on error
52
 */
53
int libfvde_volume_initialize(
54
     libfvde_volume_t **volume,
55
     libcerror_error_t **error )
56
1.38k
{
57
1.38k
  libfvde_internal_volume_t *internal_volume = NULL;
58
1.38k
  static char *function                      = "libfvde_volume_initialize";
59
60
1.38k
  if( volume == NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
65
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
66
0
     "%s: invalid volume.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
1.38k
  if( *volume != NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
76
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
77
0
     "%s: invalid volume value already set.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
1.38k
  internal_volume = memory_allocate_structure(
83
1.38k
                     libfvde_internal_volume_t );
84
85
1.38k
  if( internal_volume == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
90
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
91
0
     "%s: unable to create volume.",
92
0
     function );
93
94
0
    goto on_error;
95
0
  }
96
1.38k
  if( memory_set(
97
1.38k
       internal_volume,
98
1.38k
       0,
99
1.38k
       sizeof( libfvde_internal_volume_t ) ) == NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
104
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
105
0
     "%s: unable to clear volume.",
106
0
     function );
107
108
0
    memory_free(
109
0
     internal_volume );
110
111
0
    return( -1 );
112
0
  }
113
1.38k
  if( libfvde_io_handle_initialize(
114
1.38k
        &( internal_volume->io_handle ),
115
1.38k
        error ) != 1 )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
120
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
121
0
     "%s: unable to create IO handle.",
122
0
     function );
123
124
0
    goto on_error;
125
0
  }
126
1.38k
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
127
1.38k
  if( libcthreads_read_write_lock_initialize(
128
1.38k
       &( internal_volume->read_write_lock ),
129
1.38k
       error ) != 1 )
130
0
  {
131
0
    libcerror_error_set(
132
0
     error,
133
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
134
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
135
0
     "%s: unable to initialize read/write lock.",
136
0
     function );
137
138
0
    goto on_error;
139
0
  }
140
1.38k
#endif
141
1.38k
  *volume = (libfvde_volume_t *) internal_volume;
142
143
1.38k
  return( 1 );
144
145
0
on_error:
146
0
  if( internal_volume != NULL )
147
0
  {
148
0
    memory_free(
149
0
     internal_volume );
150
0
  }
151
0
  return( -1 );
152
1.38k
}
153
154
/* Frees a volume
155
 * Returns 1 if successful or -1 on error
156
 */
157
int libfvde_volume_free(
158
     libfvde_volume_t **volume,
159
     libcerror_error_t **error )
160
1.38k
{
161
1.38k
  libfvde_internal_volume_t *internal_volume = NULL;
162
1.38k
  static char *function                      = "libfvde_volume_free";
163
1.38k
  int result                                 = 1;
164
165
1.38k
  if( 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 volume.",
172
0
     function );
173
174
0
    return( -1 );
175
0
  }
176
1.38k
  if( *volume != NULL )
177
1.38k
  {
178
1.38k
    internal_volume = (libfvde_internal_volume_t *) *volume;
179
180
1.38k
    if( ( internal_volume->file_io_handle != NULL )
181
1.38k
     || ( internal_volume->physical_volume_file_io_pool != NULL ) )
182
0
    {
183
0
      if( libfvde_volume_close(
184
0
           *volume,
185
0
           error ) != 0 )
186
0
      {
187
0
        libcerror_error_set(
188
0
         error,
189
0
         LIBCERROR_ERROR_DOMAIN_IO,
190
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
191
0
         "%s: unable to close volume.",
192
0
         function );
193
194
0
        result = -1;
195
0
      }
196
0
    }
197
1.38k
    *volume = NULL;
198
199
1.38k
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
200
1.38k
    if( libcthreads_read_write_lock_free(
201
1.38k
         &( internal_volume->read_write_lock ),
202
1.38k
         error ) != 1 )
203
0
    {
204
0
      libcerror_error_set(
205
0
       error,
206
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
207
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
208
0
       "%s: unable to free read/write lock.",
209
0
       function );
210
211
0
      result = -1;
212
0
    }
213
1.38k
#endif
214
1.38k
    if( memory_set(
215
1.38k
         internal_volume->legacy_volume_master_key,
216
1.38k
         0,
217
1.38k
         16 ) == NULL )
218
0
    {
219
0
      libcerror_error_set(
220
0
       error,
221
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
222
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
223
0
       "%s: unable to clear user volume master key.",
224
0
       function );
225
226
0
      result = -1;
227
0
    }
228
1.38k
    if( internal_volume->legacy_user_password != NULL )
229
0
    {
230
0
      if( memory_set(
231
0
           internal_volume->legacy_user_password,
232
0
           0,
233
0
           internal_volume->legacy_user_password_size ) == NULL )
234
0
      {
235
0
        libcerror_error_set(
236
0
         error,
237
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
238
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
239
0
         "%s: unable to clear user password.",
240
0
         function );
241
242
0
        result = -1;
243
0
      }
244
0
      memory_free(
245
0
       internal_volume->legacy_user_password );
246
247
0
      internal_volume->legacy_user_password      = NULL;
248
0
      internal_volume->legacy_user_password_size = 0;
249
0
    }
250
1.38k
    if( internal_volume->legacy_recovery_password != NULL )
251
0
    {
252
0
      if( memory_set(
253
0
           internal_volume->legacy_recovery_password,
254
0
           0,
255
0
           internal_volume->legacy_recovery_password_size ) == NULL )
256
0
      {
257
0
        libcerror_error_set(
258
0
         error,
259
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
260
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
261
0
         "%s: unable to clear recovery password.",
262
0
         function );
263
264
0
        result = -1;
265
0
      }
266
0
      memory_free(
267
0
       internal_volume->legacy_recovery_password );
268
269
0
      internal_volume->legacy_recovery_password      = NULL;
270
0
      internal_volume->legacy_recovery_password_size = 0;
271
0
    }
272
1.38k
    if( internal_volume->encrypted_root_plist != NULL )
273
0
    {
274
0
      if( libfvde_encryption_context_plist_free(
275
0
           &( internal_volume->encrypted_root_plist ),
276
0
           error ) != 1 )
277
0
      {
278
0
        libcerror_error_set(
279
0
         error,
280
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
282
0
         "%s: unable to free encrypted root plist.",
283
0
         function );
284
285
0
        result = -1;
286
0
      }
287
0
    }
288
1.38k
    if( libfvde_io_handle_free(
289
1.38k
         &( internal_volume->io_handle ),
290
1.38k
         error ) != 1 )
291
0
    {
292
0
      libcerror_error_set(
293
0
       error,
294
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
296
0
       "%s: unable to free IO handle.",
297
0
       function );
298
299
0
      result = -1;
300
0
    }
301
1.38k
    memory_free(
302
1.38k
     internal_volume );
303
1.38k
  }
304
1.38k
  return( result );
305
1.38k
}
306
307
/* Signals the volume to abort its current activity
308
 * Returns 1 if successful or -1 on error
309
 */
310
int libfvde_volume_signal_abort(
311
     libfvde_volume_t *volume,
312
     libcerror_error_t **error )
313
0
{
314
0
  libfvde_internal_volume_t *internal_volume = NULL;
315
0
  static char *function                      = "libfvde_volume_signal_abort";
316
317
0
  if( volume == 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 volume.",
324
0
     function );
325
326
0
    return( -1 );
327
0
  }
328
0
  internal_volume = (libfvde_internal_volume_t *) volume;
329
330
0
  if( internal_volume->io_handle == NULL )
331
0
  {
332
0
    libcerror_error_set(
333
0
     error,
334
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
335
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
336
0
     "%s: invalid volume - missing IO handle.",
337
0
     function );
338
339
0
    return( -1 );
340
0
  }
341
0
  internal_volume->io_handle->abort = 1;
342
343
0
  return( 1 );
344
0
}
345
346
/* Opens a volume
347
 * Returns 1 if successful or -1 on error
348
 */
349
int libfvde_volume_open(
350
     libfvde_volume_t *volume,
351
     const char *filename,
352
     int access_flags,
353
     libcerror_error_t **error )
354
0
{
355
0
  libbfio_handle_t *file_io_handle           = NULL;
356
0
  libfvde_internal_volume_t *internal_volume = NULL;
357
0
  static char *function                      = "libfvde_volume_open";
358
0
  size_t filename_length                     = 0;
359
360
0
  if( volume == NULL )
361
0
  {
362
0
    libcerror_error_set(
363
0
     error,
364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
365
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
366
0
     "%s: invalid volume.",
367
0
     function );
368
369
0
    return( -1 );
370
0
  }
371
0
  internal_volume = (libfvde_internal_volume_t *) volume;
372
373
0
  if( filename == NULL )
374
0
  {
375
0
    libcerror_error_set(
376
0
     error,
377
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
378
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
379
0
     "%s: invalid filename.",
380
0
     function );
381
382
0
    return( -1 );
383
0
  }
384
0
  if( ( ( access_flags & LIBFVDE_ACCESS_FLAG_READ ) == 0 )
385
0
   && ( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) == 0 ) )
386
0
  {
387
0
    libcerror_error_set(
388
0
     error,
389
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
390
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
391
0
     "%s: unsupported access flags.",
392
0
     function );
393
394
0
    return( -1 );
395
0
  }
396
0
  if( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) != 0 )
397
0
  {
398
0
    libcerror_error_set(
399
0
     error,
400
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
401
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
402
0
     "%s: write access currently not supported.",
403
0
     function );
404
405
0
    return( -1 );
406
0
  }
407
0
  filename_length = narrow_string_length(
408
0
                     filename );
409
410
0
  if( filename_length == 0 )
411
0
  {
412
0
    libcerror_error_set(
413
0
     error,
414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
416
0
     "%s: invalid filename.",
417
0
     function );
418
419
0
    goto on_error;
420
0
  }
421
0
  if( libbfio_file_initialize(
422
0
       &file_io_handle,
423
0
       error ) != 1 )
424
0
  {
425
0
    libcerror_error_set(
426
0
     error,
427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
428
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
429
0
     "%s: unable to create file IO handle.",
430
0
     function );
431
432
0
    goto on_error;
433
0
  }
434
#if defined( HAVE_DEBUG_OUTPUT )
435
  if( libbfio_handle_set_track_offsets_read(
436
       file_io_handle,
437
       1,
438
       error ) != 1 )
439
  {
440
    libcerror_error_set(
441
     error,
442
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
443
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
444
     "%s: unable to set track offsets read in file IO handle.",
445
     function );
446
447
    goto on_error;
448
  }
449
#endif
450
0
  if( libbfio_file_set_name(
451
0
       file_io_handle,
452
0
       filename,
453
0
       filename_length,
454
0
       error ) != 1 )
455
0
  {
456
0
    libcerror_error_set(
457
0
     error,
458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
460
0
     "%s: unable to set filename in file IO handle.",
461
0
     function );
462
463
0
    goto on_error;
464
0
  }
465
0
  if( libfvde_volume_open_file_io_handle(
466
0
       volume,
467
0
       file_io_handle,
468
0
       access_flags,
469
0
       error ) != 1 )
470
0
  {
471
0
    libcerror_error_set(
472
0
     error,
473
0
     LIBCERROR_ERROR_DOMAIN_IO,
474
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
475
0
     "%s: unable to open volume: %s.",
476
0
     function,
477
0
     filename );
478
479
0
    goto on_error;
480
0
  }
481
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
482
0
  if( libcthreads_read_write_lock_grab_for_write(
483
0
       internal_volume->read_write_lock,
484
0
       error ) != 1 )
485
0
  {
486
0
    libcerror_error_set(
487
0
     error,
488
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
489
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
490
0
     "%s: unable to grab read/write lock for writing.",
491
0
     function );
492
493
0
    return( -1 );
494
0
  }
495
0
#endif
496
0
  internal_volume->file_io_handle_created_in_library = 1;
497
498
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
499
0
  if( libcthreads_read_write_lock_release_for_write(
500
0
       internal_volume->read_write_lock,
501
0
       error ) != 1 )
502
0
  {
503
0
    libcerror_error_set(
504
0
     error,
505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
507
0
     "%s: unable to release read/write lock for writing.",
508
0
     function );
509
510
0
    return( -1 );
511
0
  }
512
0
#endif
513
0
  return( 1 );
514
515
0
on_error:
516
0
  if( file_io_handle != NULL )
517
0
  {
518
0
    libbfio_handle_free(
519
0
     &file_io_handle,
520
0
     NULL );
521
0
  }
522
0
  return( -1 );
523
0
}
524
525
#if defined( HAVE_WIDE_CHARACTER_TYPE )
526
527
/* Opens a volume
528
 * Returns 1 if successful or -1 on error
529
 */
530
int libfvde_volume_open_wide(
531
     libfvde_volume_t *volume,
532
     const wchar_t *filename,
533
     int access_flags,
534
     libcerror_error_t **error )
535
{
536
  libbfio_handle_t *file_io_handle           = NULL;
537
  libfvde_internal_volume_t *internal_volume = NULL;
538
  static char *function                      = "libfvde_volume_open_wide";
539
  size_t filename_length                     = 0;
540
541
  if( volume == NULL )
542
  {
543
    libcerror_error_set(
544
     error,
545
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
546
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
547
     "%s: invalid volume.",
548
     function );
549
550
    return( -1 );
551
  }
552
  internal_volume = (libfvde_internal_volume_t *) volume;
553
554
  if( filename == NULL )
555
  {
556
    libcerror_error_set(
557
     error,
558
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
560
     "%s: invalid filename.",
561
     function );
562
563
    return( -1 );
564
  }
565
  if( ( ( access_flags & LIBFVDE_ACCESS_FLAG_READ ) == 0 )
566
   && ( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) == 0 ) )
567
  {
568
    libcerror_error_set(
569
     error,
570
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
571
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
572
     "%s: unsupported access flags.",
573
     function );
574
575
    return( -1 );
576
  }
577
  if( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) != 0 )
578
  {
579
    libcerror_error_set(
580
     error,
581
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
582
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
583
     "%s: write access currently not supported.",
584
     function );
585
586
    return( -1 );
587
  }
588
  filename_length = wide_string_length(
589
                     filename );
590
591
  if( filename_length == 0 )
592
  {
593
    libcerror_error_set(
594
     error,
595
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
596
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
597
     "%s: invalid filename.",
598
     function );
599
600
    goto on_error;
601
  }
602
  if( libbfio_file_initialize(
603
       &file_io_handle,
604
       error ) != 1 )
605
  {
606
    libcerror_error_set(
607
     error,
608
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
609
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
610
     "%s: unable to create file IO handle.",
611
     function );
612
613
    goto on_error;
614
  }
615
#if defined( HAVE_DEBUG_OUTPUT )
616
  if( libbfio_handle_set_track_offsets_read(
617
       file_io_handle,
618
       1,
619
       error ) != 1 )
620
  {
621
    libcerror_error_set(
622
     error,
623
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
624
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
625
     "%s: unable to set track offsets read in file IO handle.",
626
     function );
627
628
    goto on_error;
629
  }
630
#endif
631
  if( libbfio_file_set_name_wide(
632
       file_io_handle,
633
       filename,
634
       filename_length,
635
       error ) != 1 )
636
  {
637
    libcerror_error_set(
638
     error,
639
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
640
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
641
     "%s: unable to set filename in file IO handle.",
642
     function );
643
644
    goto on_error;
645
  }
646
  if( libfvde_volume_open_file_io_handle(
647
       volume,
648
       file_io_handle,
649
       access_flags,
650
       error ) != 1 )
651
  {
652
    libcerror_error_set(
653
     error,
654
     LIBCERROR_ERROR_DOMAIN_IO,
655
     LIBCERROR_IO_ERROR_OPEN_FAILED,
656
     "%s: unable to open volume: %ls.",
657
     function,
658
     filename );
659
660
    goto on_error;
661
  }
662
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
663
  if( libcthreads_read_write_lock_grab_for_write(
664
       internal_volume->read_write_lock,
665
       error ) != 1 )
666
  {
667
    libcerror_error_set(
668
     error,
669
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
670
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
671
     "%s: unable to grab read/write lock for writing.",
672
     function );
673
674
    return( -1 );
675
  }
676
#endif
677
  internal_volume->file_io_handle_created_in_library = 1;
678
679
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
680
  if( libcthreads_read_write_lock_release_for_write(
681
       internal_volume->read_write_lock,
682
       error ) != 1 )
683
  {
684
    libcerror_error_set(
685
     error,
686
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
687
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
688
     "%s: unable to release read/write lock for writing.",
689
     function );
690
691
    return( -1 );
692
  }
693
#endif
694
  return( 1 );
695
696
on_error:
697
  if( file_io_handle != NULL )
698
  {
699
    libbfio_handle_free(
700
     &file_io_handle,
701
     NULL );
702
  }
703
  return( -1 );
704
}
705
706
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
707
708
/* Opens a volume using a Basic File IO (bfio) handle
709
 * Returns 1 if successful or -1 on error
710
 */
711
int libfvde_volume_open_file_io_handle(
712
     libfvde_volume_t *volume,
713
     libbfio_handle_t *file_io_handle,
714
     int access_flags,
715
     libcerror_error_t **error )
716
1.38k
{
717
1.38k
  libfvde_internal_volume_t *internal_volume = NULL;
718
1.38k
  static char *function                      = "libfvde_volume_open_file_io_handle";
719
1.38k
  uint8_t file_io_handle_opened_in_library   = 0;
720
1.38k
  int bfio_access_flags                      = 0;
721
1.38k
  int file_io_handle_is_open                 = 0;
722
1.38k
  int result                                 = 1;
723
724
1.38k
  if( volume == NULL )
725
0
  {
726
0
    libcerror_error_set(
727
0
     error,
728
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
729
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
730
0
     "%s: invalid volume.",
731
0
     function );
732
733
0
    return( -1 );
734
0
  }
735
1.38k
  internal_volume = (libfvde_internal_volume_t *) volume;
736
737
1.38k
  if( internal_volume->file_io_handle != NULL )
738
0
  {
739
0
    libcerror_error_set(
740
0
     error,
741
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
742
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
743
0
     "%s: invalid volume - file IO handle already set.",
744
0
     function );
745
746
0
    return( -1 );
747
0
  }
748
1.38k
  if( file_io_handle == NULL )
749
0
  {
750
0
    libcerror_error_set(
751
0
     error,
752
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
753
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
754
0
     "%s: invalid file IO handle.",
755
0
     function );
756
757
0
    return( -1 );
758
0
  }
759
1.38k
  if( ( ( access_flags & LIBFVDE_ACCESS_FLAG_READ ) == 0 )
760
1.38k
   && ( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) == 0 ) )
761
0
  {
762
0
    libcerror_error_set(
763
0
     error,
764
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
765
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
766
0
     "%s: unsupported access flags.",
767
0
     function );
768
769
0
    return( -1 );
770
0
  }
771
1.38k
  if( ( access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) != 0 )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
776
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
777
0
     "%s: write access currently not supported.",
778
0
     function );
779
780
0
    return( -1 );
781
0
  }
782
1.38k
  if( ( access_flags & LIBFVDE_ACCESS_FLAG_READ ) != 0 )
783
1.38k
  {
784
1.38k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
785
1.38k
  }
786
1.38k
  file_io_handle_is_open = libbfio_handle_is_open(
787
1.38k
                            file_io_handle,
788
1.38k
                            error );
789
790
1.38k
  if( file_io_handle_is_open == -1 )
791
0
  {
792
0
    libcerror_error_set(
793
0
     error,
794
0
     LIBCERROR_ERROR_DOMAIN_IO,
795
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
796
0
     "%s: unable to determine if file IO handle is open.",
797
0
     function );
798
799
0
    goto on_error;
800
0
  }
801
1.38k
  else if( file_io_handle_is_open == 0 )
802
1.38k
  {
803
1.38k
    if( libbfio_handle_open(
804
1.38k
         file_io_handle,
805
1.38k
         bfio_access_flags,
806
1.38k
         error ) != 1 )
807
0
    {
808
0
      libcerror_error_set(
809
0
       error,
810
0
       LIBCERROR_ERROR_DOMAIN_IO,
811
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
812
0
       "%s: unable to open file IO handle.",
813
0
       function );
814
815
0
      goto on_error;
816
0
    }
817
1.38k
    file_io_handle_opened_in_library = 1;
818
1.38k
  }
819
1.38k
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
820
1.38k
  if( libcthreads_read_write_lock_grab_for_write(
821
1.38k
       internal_volume->read_write_lock,
822
1.38k
       error ) != 1 )
823
0
  {
824
0
    libcerror_error_set(
825
0
     error,
826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
827
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
828
0
     "%s: unable to grab read/write lock for writing.",
829
0
     function );
830
831
0
    goto on_error;
832
0
  }
833
1.38k
#endif
834
1.38k
  if( libfvde_internal_volume_open_read(
835
1.38k
       internal_volume,
836
1.38k
       file_io_handle,
837
1.38k
       error ) != 1 )
838
1.38k
  {
839
1.38k
    libcerror_error_set(
840
1.38k
     error,
841
1.38k
     LIBCERROR_ERROR_DOMAIN_IO,
842
1.38k
     LIBCERROR_IO_ERROR_READ_FAILED,
843
1.38k
     "%s: unable to read volume from file IO handle.",
844
1.38k
     function );
845
846
1.38k
    result = -1;
847
1.38k
  }
848
0
  else
849
0
  {
850
0
    internal_volume->file_io_handle                   = file_io_handle;
851
0
    internal_volume->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
852
0
    internal_volume->access_flags                     = access_flags;
853
0
  }
854
1.38k
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
855
1.38k
  if( libcthreads_read_write_lock_release_for_write(
856
1.38k
       internal_volume->read_write_lock,
857
1.38k
       error ) != 1 )
858
0
  {
859
0
    libcerror_error_set(
860
0
     error,
861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
862
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
863
0
     "%s: unable to release read/write lock for writing.",
864
0
     function );
865
866
0
    goto on_error;
867
0
  }
868
1.38k
#endif
869
1.38k
  if( result == -1 )
870
1.38k
  {
871
1.38k
    goto on_error;
872
1.38k
  }
873
0
  return( 1 );
874
875
1.38k
on_error:
876
1.38k
  if( file_io_handle_opened_in_library != 0 )
877
1.38k
  {
878
1.38k
    libbfio_handle_close(
879
1.38k
     file_io_handle,
880
1.38k
     NULL );
881
1.38k
  }
882
1.38k
  return( -1 );
883
1.38k
}
884
885
/* Opens the physical volume files
886
 * This function assumes the physical volume files are in same order as defined by the metadata
887
 * Returns 1 if successful or -1 on error
888
 */
889
int libfvde_volume_open_physical_volume_files(
890
     libfvde_volume_t *volume,
891
     char * const filenames[],
892
     int number_of_filenames,
893
     libcerror_error_t **error )
894
0
{
895
0
        libbfio_pool_t *file_io_pool               = NULL;
896
0
  libfvde_internal_volume_t *internal_volume = NULL;
897
0
  static char *function                      = "libfvde_volume_open_physical_volume_files";
898
0
  int number_of_physical_volumes             = 0;
899
0
  int physical_volume_index                  = 0;
900
0
  int result                                 = 0;
901
902
0
  if( volume == NULL )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
907
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
908
0
     "%s: invalid volume.",
909
0
     function );
910
911
0
    return( -1 );
912
0
  }
913
0
  internal_volume = (libfvde_internal_volume_t *) volume;
914
915
0
  if( internal_volume->physical_volume_file_io_pool != NULL )
916
0
  {
917
0
    libcerror_error_set(
918
0
     error,
919
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
920
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
921
0
     "%s: invalid volume - physical volume file IO pool already exists.",
922
0
     function );
923
924
0
    return( -1 );
925
0
  }
926
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
927
0
  if( libcthreads_read_write_lock_grab_for_read(
928
0
       internal_volume->read_write_lock,
929
0
       error ) != 1 )
930
0
  {
931
0
    libcerror_error_set(
932
0
     error,
933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
934
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
935
0
     "%s: unable to grab read/write lock for reading.",
936
0
     function );
937
938
0
    goto on_error;
939
0
  }
940
0
#endif
941
0
  result = libfvde_metadata_get_number_of_physical_volume_descriptors(
942
0
            internal_volume->metadata,
943
0
            &number_of_physical_volumes,
944
0
            error );
945
946
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
947
0
  if( libcthreads_read_write_lock_release_for_read(
948
0
       internal_volume->read_write_lock,
949
0
       error ) != 1 )
950
0
  {
951
0
    libcerror_error_set(
952
0
     error,
953
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
954
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
955
0
     "%s: unable to release read/write lock for reading.",
956
0
     function );
957
958
0
    goto on_error;
959
0
  }
960
0
#endif
961
0
  if( result != 1 )
962
0
  {
963
0
    libcerror_error_set(
964
0
     error,
965
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
966
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
967
0
     "%s: unable to retrieve number of physical volumes - from metadata.",
968
0
     function );
969
970
0
    goto on_error;
971
0
  }
972
0
  if( number_of_physical_volumes != number_of_filenames )
973
0
  {
974
0
    libcerror_error_set(
975
0
     error,
976
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
977
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
978
0
     "%s: mismatch between number of filenames and physical volumes in metadata.",
979
0
     function );
980
981
0
    goto on_error;
982
0
  }
983
0
  if( libbfio_pool_initialize(
984
0
       &file_io_pool,
985
0
       number_of_physical_volumes,
986
0
       internal_volume->maximum_number_of_open_handles,
987
0
       error ) != 1 )
988
0
  {
989
0
    libcerror_error_set(
990
0
     error,
991
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
992
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
993
0
     "%s: unable to create file IO pool.",
994
0
     function );
995
996
0
    goto on_error;
997
0
  }
998
0
  for( physical_volume_index = 0;
999
0
       physical_volume_index < number_of_physical_volumes;
1000
0
       physical_volume_index++ )
1001
0
  {
1002
0
    if( filenames[ physical_volume_index ] == NULL )
1003
0
    {
1004
0
      libcerror_error_set(
1005
0
       error,
1006
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1007
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1008
0
       "%s: missing filename for physical volume: %d.",
1009
0
       function,
1010
0
       physical_volume_index );
1011
1012
0
      goto on_error;
1013
0
    }
1014
0
    if( libfvde_internal_volume_open_physical_volume_file(
1015
0
         internal_volume,
1016
0
         file_io_pool,
1017
0
         physical_volume_index,
1018
0
         filenames[ physical_volume_index ],
1019
0
         error ) != 1 )
1020
0
    {
1021
0
      libcerror_error_set(
1022
0
       error,
1023
0
       LIBCERROR_ERROR_DOMAIN_IO,
1024
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1025
0
       "%s: unable to open physical volume file: %" PRIs_SYSTEM ".",
1026
0
       function,
1027
0
       filenames[ physical_volume_index ] );
1028
1029
0
      goto on_error;
1030
0
    }
1031
0
  }
1032
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1033
0
  if( libcthreads_read_write_lock_grab_for_write(
1034
0
       internal_volume->read_write_lock,
1035
0
       error ) != 1 )
1036
0
  {
1037
0
    libcerror_error_set(
1038
0
     error,
1039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1041
0
     "%s: unable to grab read/write lock for writing.",
1042
0
     function );
1043
1044
0
    goto on_error;
1045
0
  }
1046
0
#endif
1047
0
  if( libfvde_internal_volume_open_read_physical_volume_files(
1048
0
       internal_volume,
1049
0
       file_io_pool,
1050
0
       error ) != 1 )
1051
0
  {
1052
0
                libcerror_error_set(
1053
0
                 error,
1054
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1055
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1056
0
     "%s: unable to read physical volume files from file IO pool.",
1057
0
                 function );
1058
1059
0
                result = -1;
1060
0
  }
1061
0
  else
1062
0
  {
1063
0
    internal_volume->physical_volume_file_io_pool                    = file_io_pool;
1064
0
    internal_volume->physical_volume_file_io_pool_created_in_library = 1;
1065
0
  }
1066
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1067
0
  if( libcthreads_read_write_lock_release_for_write(
1068
0
       internal_volume->read_write_lock,
1069
0
       error ) != 1 )
1070
0
  {
1071
0
    libcerror_error_set(
1072
0
     error,
1073
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1074
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1075
0
     "%s: unable to release read/write lock for writing.",
1076
0
     function );
1077
1078
0
    goto on_error;
1079
0
  }
1080
0
#endif
1081
0
  return( 1 );
1082
1083
0
on_error:
1084
0
  if( file_io_pool != NULL )
1085
0
  {
1086
0
    libbfio_pool_close_all(
1087
0
     file_io_pool,
1088
0
     NULL );
1089
0
    libbfio_pool_free(
1090
0
     &file_io_pool,
1091
0
     NULL );
1092
0
  }
1093
0
  return( -1 );
1094
0
}
1095
1096
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1097
1098
/* Opens the physical volume files
1099
 * This function assumes the physical volume files are in same order as defined by the metadata
1100
 * Returns 1 if successful or -1 on error
1101
 */
1102
int libfvde_volume_open_physical_volume_files_wide(
1103
     libfvde_volume_t *volume,
1104
     wchar_t * const filenames[],
1105
     int number_of_filenames,
1106
     libcerror_error_t **error )
1107
{
1108
        libbfio_pool_t *file_io_pool               = NULL;
1109
  libfvde_internal_volume_t *internal_volume = NULL;
1110
  static char *function                      = "libfvde_volume_open_physical_volume_files_wide";
1111
  int number_of_physical_volumes             = 0;
1112
  int physical_volume_index                  = 0;
1113
  int result                                 = 0;
1114
1115
  if( volume == NULL )
1116
  {
1117
    libcerror_error_set(
1118
     error,
1119
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1120
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1121
     "%s: invalid volume.",
1122
     function );
1123
1124
    return( -1 );
1125
  }
1126
  internal_volume = (libfvde_internal_volume_t *) volume;
1127
1128
  if( internal_volume->physical_volume_file_io_pool != NULL )
1129
  {
1130
    libcerror_error_set(
1131
     error,
1132
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1133
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1134
     "%s: invalid volume - physical volume file IO pool already exists.",
1135
     function );
1136
1137
    return( -1 );
1138
  }
1139
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1140
  if( libcthreads_read_write_lock_grab_for_read(
1141
       internal_volume->read_write_lock,
1142
       error ) != 1 )
1143
  {
1144
    libcerror_error_set(
1145
     error,
1146
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1147
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1148
     "%s: unable to grab read/write lock for reading.",
1149
     function );
1150
1151
    goto on_error;
1152
  }
1153
#endif
1154
  result = libfvde_metadata_get_number_of_physical_volume_descriptors(
1155
            internal_volume->metadata,
1156
            &number_of_physical_volumes,
1157
            error );
1158
1159
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1160
  if( libcthreads_read_write_lock_release_for_read(
1161
       internal_volume->read_write_lock,
1162
       error ) != 1 )
1163
  {
1164
    libcerror_error_set(
1165
     error,
1166
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1167
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1168
     "%s: unable to release read/write lock for reading.",
1169
     function );
1170
1171
    goto on_error;
1172
  }
1173
#endif
1174
  if( result != 1 )
1175
  {
1176
    libcerror_error_set(
1177
     error,
1178
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1180
     "%s: unable to retrieve number of physical volumes - from metadata.",
1181
     function );
1182
1183
    goto on_error;
1184
  }
1185
  if( number_of_physical_volumes != number_of_filenames )
1186
  {
1187
    libcerror_error_set(
1188
     error,
1189
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1190
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1191
     "%s: mismatch between number of filenames and physical volumes in metadata.",
1192
     function );
1193
1194
    goto on_error;
1195
  }
1196
  if( libbfio_pool_initialize(
1197
       &file_io_pool,
1198
       number_of_physical_volumes,
1199
       internal_volume->maximum_number_of_open_handles,
1200
       error ) != 1 )
1201
  {
1202
    libcerror_error_set(
1203
     error,
1204
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1205
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1206
     "%s: unable to create file IO pool.",
1207
     function );
1208
1209
    goto on_error;
1210
  }
1211
  for( physical_volume_index = 0;
1212
       physical_volume_index < number_of_physical_volumes;
1213
       physical_volume_index++ )
1214
  {
1215
    if( filenames[ physical_volume_index ] == NULL )
1216
    {
1217
      libcerror_error_set(
1218
       error,
1219
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1220
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1221
       "%s: missing filename for physical volume: %d.",
1222
       function,
1223
       physical_volume_index );
1224
1225
      goto on_error;
1226
    }
1227
    if( libfvde_internal_volume_open_physical_volume_file_wide(
1228
         internal_volume,
1229
         file_io_pool,
1230
         physical_volume_index,
1231
         filenames[ physical_volume_index ],
1232
         error ) != 1 )
1233
    {
1234
      libcerror_error_set(
1235
       error,
1236
       LIBCERROR_ERROR_DOMAIN_IO,
1237
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1238
       "%s: unable to open physical volume file: %" PRIs_SYSTEM ".",
1239
       function,
1240
       filenames[ physical_volume_index ] );
1241
1242
      goto on_error;
1243
    }
1244
  }
1245
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1246
  if( libcthreads_read_write_lock_grab_for_write(
1247
       internal_volume->read_write_lock,
1248
       error ) != 1 )
1249
  {
1250
    libcerror_error_set(
1251
     error,
1252
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1253
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1254
     "%s: unable to grab read/write lock for writing.",
1255
     function );
1256
1257
    goto on_error;
1258
  }
1259
#endif
1260
  if( libfvde_internal_volume_open_read_physical_volume_files(
1261
       internal_volume,
1262
       file_io_pool,
1263
       error ) != 1 )
1264
  {
1265
                libcerror_error_set(
1266
                 error,
1267
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1268
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1269
     "%s: unable to read physical volume files from file IO pool.",
1270
                 function );
1271
1272
                result = -1;
1273
  }
1274
  else
1275
  {
1276
    internal_volume->physical_volume_file_io_pool                    = file_io_pool;
1277
    internal_volume->physical_volume_file_io_pool_created_in_library = 1;
1278
  }
1279
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1280
  if( libcthreads_read_write_lock_release_for_write(
1281
       internal_volume->read_write_lock,
1282
       error ) != 1 )
1283
  {
1284
    libcerror_error_set(
1285
     error,
1286
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1287
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1288
     "%s: unable to release read/write lock for writing.",
1289
     function );
1290
1291
    goto on_error;
1292
  }
1293
#endif
1294
  return( 1 );
1295
1296
on_error:
1297
  if( file_io_pool != NULL )
1298
  {
1299
    libbfio_pool_close_all(
1300
     file_io_pool,
1301
     NULL );
1302
    libbfio_pool_free(
1303
     &file_io_pool,
1304
     NULL );
1305
  }
1306
  return( -1 );
1307
}
1308
1309
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1310
1311
/* Opens the physical volume files using a Basic File IO (bfio) pool
1312
 * This function assumes the physical volume files are in same order as defined by the metadata
1313
 * Returns 1 if successful or -1 on error
1314
 */
1315
int libfvde_volume_open_physical_volume_files_file_io_pool(
1316
     libfvde_volume_t *volume,
1317
     libbfio_pool_t *file_io_pool,
1318
     libcerror_error_t **error )
1319
0
{
1320
0
  libfvde_internal_volume_t *internal_volume = NULL;
1321
0
  static char *function                      = "libfvde_volume_open_physical_volume_files_file_io_pool";
1322
0
  int result                                 = 1;
1323
1324
0
  if( volume == NULL )
1325
0
  {
1326
0
    libcerror_error_set(
1327
0
     error,
1328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1330
0
     "%s: invalid volume.",
1331
0
     function );
1332
1333
0
    return( -1 );
1334
0
  }
1335
0
  internal_volume = (libfvde_internal_volume_t *) volume;
1336
1337
0
  if( internal_volume->physical_volume_file_io_pool != NULL )
1338
0
  {
1339
0
    libcerror_error_set(
1340
0
     error,
1341
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1342
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1343
0
     "%s: invalid volume - physical volume file IO pool already exists.",
1344
0
     function );
1345
1346
0
    return( -1 );
1347
0
  }
1348
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1349
0
  if( libcthreads_read_write_lock_grab_for_write(
1350
0
       internal_volume->read_write_lock,
1351
0
       error ) != 1 )
1352
0
  {
1353
0
    libcerror_error_set(
1354
0
     error,
1355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1356
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1357
0
     "%s: unable to grab read/write lock for writing.",
1358
0
     function );
1359
1360
0
    return( -1 );
1361
0
  }
1362
0
#endif
1363
0
  if( libfvde_internal_volume_open_read_physical_volume_files(
1364
0
       internal_volume,
1365
0
       file_io_pool,
1366
0
       error ) != 1 )
1367
0
  {
1368
0
                libcerror_error_set(
1369
0
                 error,
1370
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1371
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1372
0
     "%s: unable to read physical volume files from file IO pool.",
1373
0
                 function );
1374
1375
0
                result = -1;
1376
0
  }
1377
0
  else
1378
0
  {
1379
0
    internal_volume->physical_volume_file_io_pool = file_io_pool;
1380
0
  }
1381
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1382
0
  if( libcthreads_read_write_lock_release_for_write(
1383
0
       internal_volume->read_write_lock,
1384
0
       error ) != 1 )
1385
0
  {
1386
0
    libcerror_error_set(
1387
0
     error,
1388
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1389
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1390
0
     "%s: unable to release read/write lock for writing.",
1391
0
     function );
1392
1393
0
    return( -1 );
1394
0
  }
1395
0
#endif
1396
0
  return( result );
1397
0
}
1398
1399
/* Opens a specific physical volume file
1400
 * Returns 1 if successful or -1 on error
1401
 */
1402
int libfvde_internal_volume_open_physical_volume_file(
1403
     libfvde_internal_volume_t *internal_volume,
1404
     libbfio_pool_t *file_io_pool,
1405
     int physical_volume_index,
1406
     const char *filename,
1407
     libcerror_error_t **error )
1408
0
{
1409
0
  libbfio_handle_t *file_io_handle = NULL;
1410
0
  static char *function            = "libfvde_internal_volume_open_physical_volume_file";
1411
0
  size_t filename_length           = 0;
1412
1413
0
  if( internal_volume == NULL )
1414
0
  {
1415
0
    libcerror_error_set(
1416
0
     error,
1417
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1418
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1419
0
     "%s: invalid volume.",
1420
0
     function );
1421
1422
0
    return( -1 );
1423
0
  }
1424
0
  if( filename == NULL )
1425
0
  {
1426
0
    libcerror_error_set(
1427
0
     error,
1428
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1429
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1430
0
     "%s: invalid filename.",
1431
0
     function );
1432
1433
0
    return( -1 );
1434
0
  }
1435
0
  if( libbfio_file_initialize(
1436
0
       &file_io_handle,
1437
0
       error ) != 1 )
1438
0
  {
1439
0
    libcerror_error_set(
1440
0
     error,
1441
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1442
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1443
0
     "%s: unable to create file IO handle.",
1444
0
     function );
1445
1446
0
    goto on_error;
1447
0
  }
1448
#if defined( HAVE_DEBUG_OUTPUT )
1449
  if( libbfio_handle_set_track_offsets_read(
1450
       file_io_handle,
1451
       1,
1452
       error ) != 1 )
1453
  {
1454
                libcerror_error_set(
1455
                 error,
1456
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1457
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1458
                 "%s: unable to set track offsets read in file IO handle.",
1459
                 function );
1460
1461
                goto on_error;
1462
  }
1463
#endif
1464
0
  filename_length = narrow_string_length(
1465
0
                     filename );
1466
1467
0
  if( libbfio_file_set_name(
1468
0
       file_io_handle,
1469
0
       filename,
1470
0
       filename_length + 1,
1471
0
       error ) != 1 )
1472
0
  {
1473
0
                libcerror_error_set(
1474
0
                 error,
1475
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1476
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1477
0
                 "%s: unable to set filename in file IO handle.",
1478
0
                 function );
1479
1480
0
                goto on_error;
1481
0
  }
1482
0
  if( libfvde_internal_volume_open_physical_volume_file_io_handle(
1483
0
       internal_volume,
1484
0
       file_io_pool,
1485
0
       physical_volume_index,
1486
0
       file_io_handle,
1487
0
       error ) != 1 )
1488
0
  {
1489
0
    libcerror_error_set(
1490
0
     error,
1491
0
     LIBCERROR_ERROR_DOMAIN_IO,
1492
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1493
0
     "%s: unable to open physical volume file: %s.",
1494
0
     function,
1495
0
     filename );
1496
1497
0
    goto on_error;
1498
0
  }
1499
0
  return( 1 );
1500
1501
0
on_error:
1502
0
  if( file_io_handle != NULL )
1503
0
  {
1504
0
    libbfio_handle_free(
1505
0
     &file_io_handle,
1506
0
     NULL );
1507
0
  }
1508
0
  return( -1 );
1509
0
}
1510
1511
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1512
1513
/* Opens a specific physical volume file
1514
 * Returns 1 if successful or -1 on error
1515
 */
1516
int libfvde_internal_volume_open_physical_volume_file_wide(
1517
     libfvde_internal_volume_t *internal_volume,
1518
     libbfio_pool_t *file_io_pool,
1519
     int physical_volume_index,
1520
     const wchar_t *filename,
1521
     libcerror_error_t **error )
1522
{
1523
  libbfio_handle_t *file_io_handle = NULL;
1524
  static char *function            = "libfvde_internal_volume_open_physical_volume_file_wide";
1525
  size_t filename_length           = 0;
1526
1527
  if( internal_volume == NULL )
1528
  {
1529
    libcerror_error_set(
1530
     error,
1531
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1532
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1533
     "%s: invalid volume.",
1534
     function );
1535
1536
    return( -1 );
1537
  }
1538
  if( filename == NULL )
1539
  {
1540
    libcerror_error_set(
1541
     error,
1542
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1543
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1544
     "%s: invalid filename.",
1545
     function );
1546
1547
    return( -1 );
1548
  }
1549
  if( libbfio_file_initialize(
1550
       &file_io_handle,
1551
       error ) != 1 )
1552
  {
1553
    libcerror_error_set(
1554
     error,
1555
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1556
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1557
     "%s: unable to create file IO handle.",
1558
     function );
1559
1560
                goto on_error;
1561
  }
1562
#if defined( HAVE_DEBUG_OUTPUT )
1563
  if( libbfio_handle_set_track_offsets_read(
1564
       file_io_handle,
1565
       1,
1566
       error ) != 1 )
1567
  {
1568
                libcerror_error_set(
1569
                 error,
1570
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1571
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1572
                 "%s: unable to set track offsets read in file IO handle.",
1573
                 function );
1574
1575
                goto on_error;
1576
  }
1577
#endif
1578
  filename_length = wide_string_length(
1579
                     filename );
1580
1581
  if( libbfio_file_set_name_wide(
1582
       file_io_handle,
1583
       filename,
1584
       filename_length + 1,
1585
       error ) != 1 )
1586
  {
1587
                libcerror_error_set(
1588
                 error,
1589
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1590
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1591
                 "%s: unable to set filename in file IO handle.",
1592
                 function );
1593
1594
                goto on_error;
1595
  }
1596
  if( libfvde_internal_volume_open_physical_volume_file_io_handle(
1597
       internal_volume,
1598
       file_io_pool,
1599
       physical_volume_index,
1600
       file_io_handle,
1601
       error ) != 1 )
1602
  {
1603
    libcerror_error_set(
1604
     error,
1605
     LIBCERROR_ERROR_DOMAIN_IO,
1606
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1607
     "%s: unable to open physical volume file: %ls.",
1608
     function,
1609
     filename );
1610
1611
    goto on_error;
1612
  }
1613
  return( 1 );
1614
1615
on_error:
1616
  if( file_io_handle != NULL )
1617
  {
1618
    libbfio_handle_free(
1619
     &file_io_handle,
1620
     NULL );
1621
  }
1622
  return( -1 );
1623
}
1624
1625
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1626
1627
/* Opens an physical volume file using a Basic File IO (bfio) handle
1628
 * Returns 1 if successful or -1 on error
1629
 */
1630
int libfvde_internal_volume_open_physical_volume_file_io_handle(
1631
     libfvde_internal_volume_t *internal_volume,
1632
     libbfio_pool_t *file_io_pool,
1633
     int physical_volume_index,
1634
     libbfio_handle_t *file_io_handle,
1635
     libcerror_error_t **error )
1636
0
{
1637
0
  static char *function                    = "libfvde_internal_volume_open_physical_volume_file_io_handle";
1638
0
  uint8_t file_io_handle_opened_in_library = 0;
1639
0
  int bfio_access_flags                    = 0;
1640
0
  int file_io_handle_is_open               = 0;
1641
1642
0
  if( internal_volume == NULL )
1643
0
  {
1644
0
    libcerror_error_set(
1645
0
     error,
1646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1647
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1648
0
     "%s: invalid volume.",
1649
0
     function );
1650
1651
0
    return( -1 );
1652
0
  }
1653
0
  if( ( ( internal_volume->access_flags & LIBFVDE_ACCESS_FLAG_READ ) == 0 )
1654
0
   && ( ( internal_volume->access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) == 0 ) )
1655
0
  {
1656
0
    libcerror_error_set(
1657
0
     error,
1658
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1659
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1660
0
     "%s: unsupported access flags.",
1661
0
     function );
1662
1663
0
    return( -1 );
1664
0
  }
1665
0
  if( ( internal_volume->access_flags & LIBFVDE_ACCESS_FLAG_WRITE ) != 0 )
1666
0
  {
1667
0
    libcerror_error_set(
1668
0
     error,
1669
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1670
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1671
0
     "%s: write access currently not supported.",
1672
0
     function );
1673
1674
0
    return( -1 );
1675
0
  }
1676
0
  if( ( internal_volume->access_flags & LIBFVDE_ACCESS_FLAG_READ ) != 0 )
1677
0
  {
1678
0
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
1679
0
  }
1680
0
  file_io_handle_is_open = libbfio_handle_is_open(
1681
0
                            file_io_handle,
1682
0
                            error );
1683
1684
0
  if( file_io_handle_is_open == -1 )
1685
0
  {
1686
0
    libcerror_error_set(
1687
0
     error,
1688
0
     LIBCERROR_ERROR_DOMAIN_IO,
1689
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1690
0
     "%s: unable to determine if file IO handle is open.",
1691
0
     function );
1692
1693
0
    goto on_error;
1694
0
  }
1695
0
  else if( file_io_handle_is_open == 0 )
1696
0
  {
1697
0
    if( libbfio_handle_open(
1698
0
         file_io_handle,
1699
0
         bfio_access_flags,
1700
0
         error ) != 1 )
1701
0
    {
1702
0
      libcerror_error_set(
1703
0
       error,
1704
0
       LIBCERROR_ERROR_DOMAIN_IO,
1705
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1706
0
       "%s: unable to open file IO handle.",
1707
0
       function );
1708
1709
0
      goto on_error;
1710
0
    }
1711
0
    file_io_handle_opened_in_library = 1;
1712
0
  }
1713
0
  if( libbfio_pool_set_handle(
1714
0
       file_io_pool,
1715
0
       physical_volume_index,
1716
0
       file_io_handle,
1717
0
       bfio_access_flags,
1718
0
       error ) != 1 )
1719
0
  {
1720
0
    libcerror_error_set(
1721
0
     error,
1722
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1723
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1724
0
     "%s: unable to set file IO handle: %d in pool.",
1725
0
     function,
1726
0
     physical_volume_index );
1727
1728
0
    goto on_error;
1729
0
  }
1730
0
  return( 1 );
1731
1732
0
on_error:
1733
0
  if( file_io_handle_opened_in_library != 0 )
1734
0
  {
1735
0
    libbfio_handle_close(
1736
0
     file_io_handle,
1737
0
     error );
1738
0
  }
1739
0
  return( -1 );
1740
0
}
1741
1742
/* Closes a volume
1743
 * Returns 0 if successful or -1 on error
1744
 */
1745
int libfvde_volume_close(
1746
     libfvde_volume_t *volume,
1747
     libcerror_error_t **error )
1748
0
{
1749
0
  libbfio_handle_t *legacy_file_io_handle    = NULL;
1750
0
  libfvde_internal_volume_t *internal_volume = NULL;
1751
0
  static char *function                      = "libfvde_volume_close";
1752
0
  int result                                 = 0;
1753
1754
0
  if( volume == NULL )
1755
0
  {
1756
0
    libcerror_error_set(
1757
0
     error,
1758
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1759
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1760
0
     "%s: invalid volume.",
1761
0
     function );
1762
1763
0
    return( -1 );
1764
0
  }
1765
0
  internal_volume = (libfvde_internal_volume_t *) volume;
1766
1767
0
  if( internal_volume->file_io_handle == NULL )
1768
0
  {
1769
0
    libcerror_error_set(
1770
0
     error,
1771
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1772
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1773
0
     "%s: invalid volume - missing file IO handle.",
1774
0
     function );
1775
1776
0
    return( -1 );
1777
0
  }
1778
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1779
0
  if( libcthreads_read_write_lock_grab_for_write(
1780
0
       internal_volume->read_write_lock,
1781
0
       error ) != 1 )
1782
0
  {
1783
0
    libcerror_error_set(
1784
0
     error,
1785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1786
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1787
0
     "%s: unable to grab read/write lock for writing.",
1788
0
     function );
1789
1790
0
    return( -1 );
1791
0
  }
1792
0
#endif
1793
#if defined( HAVE_DEBUG_OUTPUT )
1794
  if( libcnotify_verbose != 0 )
1795
  {
1796
    if( internal_volume->file_io_handle_created_in_library != 0 )
1797
    {
1798
      if( libfvde_debug_print_read_offsets(
1799
           internal_volume->file_io_handle,
1800
           error ) != 1 )
1801
      {
1802
        libcerror_error_set(
1803
         error,
1804
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1805
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1806
         "%s: unable to print the read offsets.",
1807
         function );
1808
      }
1809
    }
1810
  }
1811
#endif
1812
0
  if( internal_volume->file_io_handle_opened_in_library != 0 )
1813
0
  {
1814
0
    if( libbfio_handle_close(
1815
0
         internal_volume->file_io_handle,
1816
0
         error ) != 0 )
1817
0
    {
1818
0
      libcerror_error_set(
1819
0
       error,
1820
0
       LIBCERROR_ERROR_DOMAIN_IO,
1821
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1822
0
       "%s: unable to close file IO handle.",
1823
0
       function );
1824
1825
0
      result = -1;
1826
0
    }
1827
0
    internal_volume->file_io_handle_opened_in_library = 0;
1828
0
  }
1829
0
  if( internal_volume->file_io_handle_created_in_library != 0 )
1830
0
  {
1831
0
    if( libbfio_handle_free(
1832
0
         &( internal_volume->file_io_handle ),
1833
0
         error ) != 1 )
1834
0
    {
1835
0
      libcerror_error_set(
1836
0
       error,
1837
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1838
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1839
0
       "%s: unable to free file IO handle.",
1840
0
       function );
1841
1842
0
      result = -1;
1843
0
    }
1844
0
    internal_volume->file_io_handle_created_in_library = 0;
1845
0
  }
1846
0
  internal_volume->file_io_handle = NULL;
1847
1848
0
  if( internal_volume->physical_volume_file_io_pool_created_in_library != 0 )
1849
0
  {
1850
0
    if( libbfio_pool_close_all(
1851
0
         internal_volume->physical_volume_file_io_pool,
1852
0
         error ) != 0 )
1853
0
    {
1854
0
      libcerror_error_set(
1855
0
       error,
1856
0
       LIBCERROR_ERROR_DOMAIN_IO,
1857
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1858
0
       "%s: unable to close physical volume file IO pool.",
1859
0
       function );
1860
1861
0
      result = -1;
1862
0
    }
1863
0
    if( libbfio_pool_free(
1864
0
         &( internal_volume->physical_volume_file_io_pool ),
1865
0
         error ) != 1 )
1866
0
    {
1867
0
      libcerror_error_set(
1868
0
       error,
1869
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1870
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1871
0
       "%s: unable to free physical volume file IO pool.",
1872
0
       function );
1873
1874
0
      result = -1;
1875
0
    }
1876
0
    internal_volume->physical_volume_file_io_pool_created_in_library = 0;
1877
0
  }
1878
0
  internal_volume->physical_volume_file_io_pool = NULL;
1879
1880
0
  if( libfvde_io_handle_clear(
1881
0
       internal_volume->io_handle,
1882
0
       error ) != 1 )
1883
0
  {
1884
0
    libcerror_error_set(
1885
0
     error,
1886
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1887
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1888
0
     "%s: unable to clear IO handle.",
1889
0
     function );
1890
1891
0
    result = -1;
1892
0
  }
1893
0
  if( internal_volume->volume_header != NULL )
1894
0
  {
1895
0
    if( libfvde_volume_header_free(
1896
0
         &( internal_volume->volume_header ),
1897
0
         error ) != 1 )
1898
0
    {
1899
0
      libcerror_error_set(
1900
0
       error,
1901
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1902
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1903
0
       "%s: unable to free volume header.",
1904
0
       function );
1905
1906
0
      result = -1;
1907
0
    }
1908
0
  }
1909
0
  if( internal_volume->metadata != NULL )
1910
0
  {
1911
0
    if( libfvde_metadata_free(
1912
0
         &( internal_volume->metadata ),
1913
0
         error ) != 1 )
1914
0
    {
1915
0
      libcerror_error_set(
1916
0
       error,
1917
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1918
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1919
0
       "%s: unable to free metadata.",
1920
0
       function );
1921
1922
0
      result = -1;
1923
0
    }
1924
0
  }
1925
0
  if( internal_volume->encrypted_metadata1 != NULL )
1926
0
  {
1927
0
    if( libfvde_encrypted_metadata_free(
1928
0
         &( internal_volume->encrypted_metadata1 ),
1929
0
         error ) != 1 )
1930
0
    {
1931
0
      libcerror_error_set(
1932
0
       error,
1933
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1934
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1935
0
       "%s: unable to free encrypted metadata 1.",
1936
0
       function );
1937
1938
0
      result = -1;
1939
0
    }
1940
0
  }
1941
0
  if( internal_volume->encrypted_metadata2 != NULL )
1942
0
  {
1943
0
    if( libfvde_encrypted_metadata_free(
1944
0
         &( internal_volume->encrypted_metadata2 ),
1945
0
         error ) != 1 )
1946
0
    {
1947
0
      libcerror_error_set(
1948
0
       error,
1949
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1950
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1951
0
       "%s: unable to free encrypted metadata 2.",
1952
0
       function );
1953
1954
0
      result = -1;
1955
0
    }
1956
0
  }
1957
0
  if( internal_volume->legacy_logical_volume != NULL )
1958
0
  {
1959
0
    if( libfvde_logical_volume_free(
1960
0
         &( internal_volume->legacy_logical_volume ),
1961
0
         error ) != 1 )
1962
0
    {
1963
0
      libcerror_error_set(
1964
0
       error,
1965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1966
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1967
0
       "%s: unable to free logical volume.",
1968
0
       function );
1969
1970
0
      result = -1;
1971
0
    }
1972
0
  }
1973
0
  if( internal_volume->legacy_file_io_pool != NULL )
1974
0
  {
1975
0
    if( libbfio_pool_remove_handle(
1976
0
         internal_volume->legacy_file_io_pool,
1977
0
         0,
1978
0
         &legacy_file_io_handle,
1979
0
         error ) != 1 )
1980
0
    {
1981
0
      libcerror_error_set(
1982
0
       error,
1983
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1984
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1985
0
       "%s: unable to set file IO handle in pool.",
1986
0
       function );
1987
1988
0
      result = -1;
1989
0
    }
1990
0
    if( libbfio_pool_close_all(
1991
0
         internal_volume->legacy_file_io_pool,
1992
0
         error ) != 0 )
1993
0
    {
1994
0
      libcerror_error_set(
1995
0
       error,
1996
0
       LIBCERROR_ERROR_DOMAIN_IO,
1997
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1998
0
       "%s: unable to close legacy file IO pool.",
1999
0
       function );
2000
2001
0
      result = -1;
2002
0
    }
2003
0
    if( libbfio_pool_free(
2004
0
         &( internal_volume->legacy_file_io_pool ),
2005
0
         error ) != 1 )
2006
0
    {
2007
0
      libcerror_error_set(
2008
0
       error,
2009
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2010
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2011
0
       "%s: unable to free legacy file IO pool.",
2012
0
       function );
2013
2014
0
      result = -1;
2015
0
    }
2016
0
  }
2017
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2018
0
  if( libcthreads_read_write_lock_release_for_write(
2019
0
       internal_volume->read_write_lock,
2020
0
       error ) != 1 )
2021
0
  {
2022
0
    libcerror_error_set(
2023
0
     error,
2024
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2025
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2026
0
     "%s: unable to release read/write lock for writing.",
2027
0
     function );
2028
2029
0
    return( -1 );
2030
0
  }
2031
0
#endif
2032
0
  return( result );
2033
0
}
2034
2035
/* Opens a volume for reading
2036
 * Returns 1 if successful or -1 on error
2037
 */
2038
int libfvde_internal_volume_open_read(
2039
     libfvde_internal_volume_t *internal_volume,
2040
     libbfio_handle_t *file_io_handle,
2041
     libcerror_error_t **error )
2042
1.38k
{
2043
1.38k
  libfvde_logical_volume_descriptor_t *logical_volume_descriptor = NULL;
2044
1.38k
  libfvde_metadata_t *metadata                                   = NULL;
2045
1.38k
  libfvde_metadata_t *safe_metadata                              = NULL;
2046
1.38k
  static char *function                                          = "libfvde_internal_volume_open_read";
2047
1.38k
  off64_t metadata_offset                                        = 0;
2048
1.38k
  int metadata_index                                             = 0;
2049
1.38k
  int number_of_logical_volumes                                  = 0;
2050
1.38k
  int number_of_physical_volumes                                 = 0;
2051
2052
#if defined( HAVE_DEBUG_OUTPUT )
2053
  size64_t logical_volume_size                                   = 0;
2054
  off64_t logical_volume_offset                                  = 0;
2055
  int file_io_pool_entry                                         = 0;
2056
#endif
2057
2058
1.38k
  if( internal_volume == NULL )
2059
0
  {
2060
0
    libcerror_error_set(
2061
0
     error,
2062
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2063
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2064
0
     "%s: invalid volume.",
2065
0
     function );
2066
2067
0
    return( -1 );
2068
0
  }
2069
1.38k
  if( internal_volume->io_handle == NULL )
2070
0
  {
2071
0
    libcerror_error_set(
2072
0
     error,
2073
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2074
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2075
0
     "%s: invalid volume - missing IO handle.",
2076
0
     function );
2077
2078
0
    return( -1 );
2079
0
  }
2080
1.38k
  if( internal_volume->volume_header != NULL )
2081
0
  {
2082
0
    libcerror_error_set(
2083
0
     error,
2084
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2085
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2086
0
     "%s: invalid volume - volume header value already set.",
2087
0
     function );
2088
2089
0
    return( -1 );
2090
0
  }
2091
1.38k
  if( internal_volume->metadata != NULL )
2092
0
  {
2093
0
    libcerror_error_set(
2094
0
     error,
2095
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2096
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2097
0
     "%s: invalid volume - metadata value already set.",
2098
0
     function );
2099
2100
0
    return( -1 );
2101
0
  }
2102
#if defined( HAVE_DEBUG_OUTPUT )
2103
  if( libcnotify_verbose != 0 )
2104
  {
2105
    libcnotify_printf(
2106
     "Reading volume header:\n" );
2107
  }
2108
#endif
2109
1.38k
  if( libfvde_volume_header_initialize(
2110
1.38k
       &( internal_volume->volume_header ),
2111
1.38k
       error ) != 1 )
2112
0
  {
2113
0
    libcerror_error_set(
2114
0
     error,
2115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2117
0
     "%s: unable to create volume header.",
2118
0
     function );
2119
2120
0
    goto on_error;
2121
0
  }
2122
1.38k
  if( libfvde_volume_header_read_file_io_handle(
2123
1.38k
       internal_volume->volume_header,
2124
1.38k
       file_io_handle,
2125
1.38k
       0,
2126
1.38k
       error ) != 1 )
2127
331
  {
2128
331
    libcerror_error_set(
2129
331
     error,
2130
331
     LIBCERROR_ERROR_DOMAIN_IO,
2131
331
     LIBCERROR_IO_ERROR_READ_FAILED,
2132
331
     "%s: unable to read volume header.",
2133
331
     function );
2134
2135
331
    goto on_error;
2136
331
  }
2137
1.05k
  internal_volume->io_handle->serial_number    = internal_volume->volume_header->serial_number;
2138
1.05k
  internal_volume->io_handle->bytes_per_sector = internal_volume->volume_header->bytes_per_sector;
2139
1.05k
  internal_volume->io_handle->block_size       = internal_volume->volume_header->block_size;
2140
1.05k
  internal_volume->io_handle->metadata_size    = internal_volume->volume_header->metadata_size;
2141
2142
1.05k
  for( metadata_index = 0;
2143
1.11k
       metadata_index < 4;
2144
1.05k
       metadata_index++ )
2145
1.11k
  {
2146
#if defined( HAVE_DEBUG_OUTPUT )
2147
    if( libcnotify_verbose != 0 )
2148
    {
2149
      libcnotify_printf(
2150
       "Reading metadata: %d\n",
2151
       metadata_index + 1 );
2152
    }
2153
#endif
2154
1.11k
    if( libfvde_metadata_initialize(
2155
1.11k
         &metadata,
2156
1.11k
         error ) != 1 )
2157
0
    {
2158
0
      libcerror_error_set(
2159
0
       error,
2160
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2161
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2162
0
       "%s: unable to create metadata: %d.",
2163
0
       function,
2164
0
       metadata_index + 1 );
2165
2166
0
      goto on_error;
2167
0
    }
2168
1.11k
    metadata_offset = (off64_t) internal_volume->volume_header->metadata_offsets[ metadata_index ];
2169
2170
1.11k
    if( libfvde_metadata_read_file_io_handle(
2171
1.11k
         metadata,
2172
1.11k
         internal_volume->io_handle,
2173
1.11k
         file_io_handle,
2174
1.11k
         metadata_offset,
2175
1.11k
         error ) != 1 )
2176
1.05k
    {
2177
1.05k
      libcerror_error_set(
2178
1.05k
       error,
2179
1.05k
       LIBCERROR_ERROR_DOMAIN_IO,
2180
1.05k
       LIBCERROR_IO_ERROR_READ_FAILED,
2181
1.05k
       "%s: unable to read metadata: %d at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2182
1.05k
       function,
2183
1.05k
       metadata_index + 1,
2184
1.05k
       metadata_offset,
2185
1.05k
       metadata_offset );
2186
2187
1.05k
      goto on_error;
2188
1.05k
    }
2189
58
    if( internal_volume->metadata == NULL )
2190
58
    {
2191
58
      internal_volume->metadata = metadata;
2192
58
      metadata                  = NULL;
2193
58
    }
2194
0
    else if( metadata->transaction_identifier > internal_volume->metadata->transaction_identifier )
2195
0
    {
2196
0
      safe_metadata             = internal_volume->metadata;
2197
0
      internal_volume->metadata = metadata;
2198
0
      metadata                  = safe_metadata;
2199
0
    }
2200
58
    if( metadata != NULL )
2201
0
    {
2202
0
      if( libfvde_metadata_free(
2203
0
           &metadata,
2204
0
           error ) != 1 )
2205
0
      {
2206
0
        libcerror_error_set(
2207
0
         error,
2208
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2209
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2210
0
         "%s: unable to free metadata.",
2211
0
         function );
2212
2213
0
        goto on_error;
2214
0
      }
2215
0
    }
2216
58
  }
2217
0
  if( libfvde_metadata_get_number_of_physical_volume_descriptors(
2218
0
       internal_volume->metadata,
2219
0
       &number_of_physical_volumes,
2220
0
       error ) == -1 )
2221
0
  {
2222
0
    libcerror_error_set(
2223
0
     error,
2224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2225
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2226
0
     "%s: unable to retrieve number of physical volume descriptors from metadata.",
2227
0
     function );
2228
2229
0
    goto on_error;
2230
0
  }
2231
0
  if( number_of_physical_volumes == 0 )
2232
0
  {
2233
0
    libcerror_error_set(
2234
0
     error,
2235
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2236
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2237
0
     "%s: unsupported number of physical volumes: %d.",
2238
0
     function,
2239
0
     number_of_physical_volumes );
2240
2241
0
    goto on_error;
2242
0
  }
2243
#if defined( HAVE_DEBUG_OUTPUT )
2244
  if( libcnotify_verbose != 0 )
2245
  {
2246
  }
2247
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2248
2249
0
  if( number_of_physical_volumes == 1 )
2250
0
  {
2251
0
    if( libbfio_pool_initialize(
2252
0
         &( internal_volume->legacy_file_io_pool ),
2253
0
         1,
2254
0
         1,
2255
0
         error ) != 1 )
2256
0
    {
2257
0
      libcerror_error_set(
2258
0
       error,
2259
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2260
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2261
0
       "%s: unable to create file IO pool.",
2262
0
       function );
2263
2264
0
      goto on_error;
2265
0
    }
2266
0
    if( libbfio_pool_set_handle(
2267
0
         internal_volume->legacy_file_io_pool,
2268
0
         0,
2269
0
         file_io_handle,
2270
0
         LIBBFIO_ACCESS_FLAG_READ,
2271
0
         error ) != 1 )
2272
0
    {
2273
0
      libcerror_error_set(
2274
0
       error,
2275
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2276
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2277
0
       "%s: unable to set file IO handle in pool.",
2278
0
       function );
2279
2280
0
      goto on_error;
2281
0
    }
2282
0
    if( libfvde_internal_volume_open_read_physical_volume_files(
2283
0
         internal_volume,
2284
0
         internal_volume->legacy_file_io_pool,
2285
0
         error ) != 1 )
2286
0
    {
2287
0
      libcerror_error_set(
2288
0
       error,
2289
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2290
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2291
0
       "%s: unable to read physical volume files from file IO pool.",
2292
0
       function );
2293
2294
#if defined( HAVE_DEBUG_OUTPUT )
2295
      libcnotify_print_error_backtrace(
2296
       *error );
2297
#endif
2298
0
      libcerror_error_free(
2299
0
       error );
2300
0
    }
2301
0
    else
2302
0
    {
2303
0
      if( libfvde_encrypted_metadata_get_number_of_logical_volume_descriptors(
2304
0
           internal_volume->encrypted_metadata1,
2305
0
           &number_of_logical_volumes,
2306
0
           error ) == -1 )
2307
0
      {
2308
0
        libcerror_error_set(
2309
0
         error,
2310
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2311
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2312
0
         "%s: unable to retrieve number of logical volume descriptors from encrypted metadata 1.",
2313
0
         function );
2314
2315
0
        goto on_error;
2316
0
      }
2317
0
      if( number_of_logical_volumes == 1 )
2318
0
      {
2319
0
        if( libfvde_encrypted_metadata_get_logical_volume_descriptor_by_index(
2320
0
             internal_volume->encrypted_metadata1,
2321
0
             0,
2322
0
             &logical_volume_descriptor,
2323
0
             error ) == -1 )
2324
0
        {
2325
0
          libcerror_error_set(
2326
0
           error,
2327
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2328
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2329
0
           "%s: unable to retrieve first logical volume descriptor from encrypted metadata 1.",
2330
0
           function );
2331
2332
0
          goto on_error;
2333
0
        }
2334
#if defined( HAVE_DEBUG_OUTPUT )
2335
        if( libcnotify_verbose != 0 )
2336
        {
2337
          libcnotify_printf(
2338
           "%s: physical volume size\t\t\t: %" PRIu64 "\n",
2339
           function,
2340
           internal_volume->volume_header->physical_volume_size );
2341
2342
          if( libfvde_logical_volume_descriptor_get_first_block_number(
2343
               logical_volume_descriptor,
2344
               (uint16_t *) &file_io_pool_entry,
2345
               (uint64_t *) &logical_volume_offset,
2346
               error ) == -1 )
2347
          {
2348
            libcerror_error_set(
2349
             error,
2350
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2351
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2352
             "%s: unable to retrieve first block number from logical volume descriptor.",
2353
             function );
2354
2355
            goto on_error;
2356
          }
2357
          logical_volume_offset *= internal_volume->io_handle->block_size;
2358
2359
          libcnotify_printf(
2360
           "%s: logical volume offset\t\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
2361
           function,
2362
           logical_volume_offset,
2363
           logical_volume_offset );
2364
2365
          if( libfvde_logical_volume_descriptor_get_size(
2366
               logical_volume_descriptor,
2367
               &logical_volume_size,
2368
               error ) == -1 )
2369
          {
2370
            libcerror_error_set(
2371
             error,
2372
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2373
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2374
             "%s: unable to retrieve size from first logical volume descriptor.",
2375
             function );
2376
2377
            goto on_error;
2378
          }
2379
          libcnotify_printf(
2380
           "%s: logical volume size\t\t\t: %" PRIu64 "\n",
2381
           function,
2382
           logical_volume_size );
2383
2384
          libcnotify_printf(
2385
           "\n" );
2386
        }
2387
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2388
2389
0
        if( libfvde_logical_volume_initialize(
2390
0
              &( internal_volume->legacy_logical_volume ),
2391
0
              internal_volume->io_handle,
2392
0
              internal_volume->legacy_file_io_pool,
2393
0
              logical_volume_descriptor,
2394
0
              internal_volume->encrypted_metadata1,
2395
0
              internal_volume->encrypted_root_plist,
2396
0
              error ) != 1 )
2397
0
        {
2398
0
          libcerror_error_set(
2399
0
           error,
2400
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2401
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2402
0
           "%s: unable to create logical volume.",
2403
0
           function );
2404
2405
0
          goto on_error;
2406
0
        }
2407
0
        if( internal_volume->legacy_volume_master_key_is_set != 0 )
2408
0
        {
2409
0
          if( libfvde_logical_volume_set_key(
2410
0
               internal_volume->legacy_logical_volume,
2411
0
               internal_volume->legacy_volume_master_key,
2412
0
               16,
2413
0
               error ) != 1 )
2414
0
          {
2415
0
            libcerror_error_set(
2416
0
             error,
2417
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2418
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2419
0
             "%s: unable set key in logical volume.",
2420
0
             function );
2421
2422
0
            goto on_error;
2423
0
          }
2424
0
        }
2425
0
        if( internal_volume->legacy_user_password != NULL )
2426
0
        {
2427
0
          if( libfvde_logical_volume_set_utf8_password(
2428
0
               internal_volume->legacy_logical_volume,
2429
0
               internal_volume->legacy_user_password,
2430
0
               internal_volume->legacy_user_password_size - 1,
2431
0
               error ) != 1 )
2432
0
          {
2433
0
            libcerror_error_set(
2434
0
             error,
2435
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2436
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2437
0
             "%s: unable set user password in logical volume.",
2438
0
             function );
2439
2440
0
            goto on_error;
2441
0
          }
2442
0
        }
2443
0
        if( internal_volume->legacy_recovery_password != NULL )
2444
0
        {
2445
0
          if( libfvde_logical_volume_set_utf8_password(
2446
0
               internal_volume->legacy_logical_volume,
2447
0
               internal_volume->legacy_recovery_password,
2448
0
               internal_volume->legacy_recovery_password_size - 1,
2449
0
               error ) != 1 )
2450
0
          {
2451
0
            libcerror_error_set(
2452
0
             error,
2453
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2454
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2455
0
             "%s: unable set recovery password in logical volume.",
2456
0
             function );
2457
2458
0
            goto on_error;
2459
0
          }
2460
0
        }
2461
0
        if( libfvde_internal_logical_volume_open_read(
2462
0
             (libfvde_internal_logical_volume_t *) internal_volume->legacy_logical_volume,
2463
0
             internal_volume->legacy_file_io_pool,
2464
0
             error ) != 1 )
2465
0
        {
2466
0
          libcerror_error_set(
2467
0
           error,
2468
0
           LIBCERROR_ERROR_DOMAIN_IO,
2469
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2470
0
           "%s: unable to read logical volume.",
2471
0
           function );
2472
2473
0
          goto on_error;
2474
0
        }
2475
0
      }
2476
0
    }
2477
0
  }
2478
0
  return( 1 );
2479
2480
1.38k
on_error:
2481
1.38k
  if( internal_volume->legacy_logical_volume != NULL )
2482
0
  {
2483
0
    libfvde_logical_volume_free(
2484
0
     &( internal_volume->legacy_logical_volume ),
2485
0
     NULL );
2486
0
  }
2487
1.38k
  if( internal_volume->legacy_file_io_pool != NULL )
2488
0
  {
2489
0
    libbfio_pool_free(
2490
0
     &( internal_volume->legacy_file_io_pool ),
2491
0
     NULL );
2492
0
  }
2493
1.38k
  if( internal_volume->metadata != NULL )
2494
58
  {
2495
58
    libfvde_metadata_free(
2496
58
     &( internal_volume->metadata ),
2497
58
     NULL );
2498
58
  }
2499
1.38k
  if( metadata != NULL )
2500
1.05k
  {
2501
1.05k
    libfvde_metadata_free(
2502
1.05k
     &metadata,
2503
1.05k
     NULL );
2504
1.05k
  }
2505
1.38k
  if( internal_volume->volume_header != NULL )
2506
1.38k
  {
2507
1.38k
    libfvde_volume_header_free(
2508
1.38k
     &( internal_volume->volume_header ),
2509
1.38k
     NULL );
2510
1.38k
  }
2511
1.38k
  return( -1 );
2512
0
}
2513
2514
/* Opens the physical volume files for reading
2515
 * Returns 1 if successful or -1 on error
2516
 */
2517
int libfvde_internal_volume_open_read_physical_volume_files(
2518
     libfvde_internal_volume_t *internal_volume,
2519
     libbfio_pool_t *file_io_pool,
2520
     libcerror_error_t **error )
2521
0
{
2522
0
  libbfio_handle_t *file_io_handle                                 = NULL;
2523
0
  libfvde_physical_volume_descriptor_t *physical_volume_descriptor = NULL;
2524
0
  libfvde_volume_header_t *volume_header                           = NULL;
2525
0
  static char *function                                            = "libfvde_internal_volume_open_read";
2526
0
  int file_io_handle_is_open                                       = 0;
2527
0
  int file_io_pool_entry                                           = 0;
2528
0
  int number_of_file_io_handles                                    = 0;
2529
0
  int number_of_physical_volumes                                   = 0;
2530
2531
0
  if( internal_volume == NULL )
2532
0
  {
2533
0
    libcerror_error_set(
2534
0
     error,
2535
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2536
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2537
0
     "%s: invalid volume.",
2538
0
     function );
2539
2540
0
    return( -1 );
2541
0
  }
2542
0
  if( internal_volume->volume_header == NULL )
2543
0
  {
2544
0
    libcerror_error_set(
2545
0
     error,
2546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2547
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2548
0
     "%s: invalid volume - missing volume header.",
2549
0
     function );
2550
2551
0
    return( -1 );
2552
0
  }
2553
0
  if( internal_volume->metadata == NULL )
2554
0
  {
2555
0
    libcerror_error_set(
2556
0
     error,
2557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2558
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2559
0
     "%s: invalid volume - missing metadata.",
2560
0
     function );
2561
2562
0
    return( -1 );
2563
0
  }
2564
/* TODO remove, for backwards compatibility
2565
 */
2566
0
  if( internal_volume->encrypted_metadata1 != NULL )
2567
0
  {
2568
0
    return( 1 );
2569
0
  }
2570
0
  if( internal_volume->encrypted_metadata1 != NULL )
2571
0
  {
2572
0
    libcerror_error_set(
2573
0
     error,
2574
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2575
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2576
0
     "%s: invalid volume - encrypted metadata 1 value already set.",
2577
0
     function );
2578
2579
0
    return( -1 );
2580
0
  }
2581
0
  if( internal_volume->encrypted_metadata2 != NULL )
2582
0
  {
2583
0
    libcerror_error_set(
2584
0
     error,
2585
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2586
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2587
0
     "%s: invalid volume - encrypted metadata 2 value already set.",
2588
0
     function );
2589
2590
0
    return( -1 );
2591
0
  }
2592
0
  if( libbfio_pool_get_number_of_handles(
2593
0
       file_io_pool,
2594
0
       &number_of_file_io_handles,
2595
0
       error ) != 1 )
2596
0
  {
2597
0
    libcerror_error_set(
2598
0
     error,
2599
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2600
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2601
0
     "%s: unable to retrieve number of handles in file IO pool.",
2602
0
     function );
2603
2604
0
    goto on_error;
2605
0
  }
2606
0
  if( libfvde_metadata_get_number_of_physical_volume_descriptors(
2607
0
       internal_volume->metadata,
2608
0
       &number_of_physical_volumes,
2609
0
       error ) == -1 )
2610
0
  {
2611
0
    libcerror_error_set(
2612
0
     error,
2613
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2614
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2615
0
     "%s: unable to retrieve number of physical volume descriptors from metadata.",
2616
0
     function );
2617
2618
0
    goto on_error;
2619
0
  }
2620
0
  if( number_of_physical_volumes != number_of_file_io_handles )
2621
0
  {
2622
0
    libcerror_error_set(
2623
0
     error,
2624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2626
0
     "%s: mismatch between number of filenames and physical volumes in metadata.",
2627
0
     function );
2628
2629
0
    goto on_error;
2630
0
  }
2631
0
  for( file_io_pool_entry = 0;
2632
0
       file_io_pool_entry < number_of_file_io_handles;
2633
0
       file_io_pool_entry++ )
2634
0
  {
2635
0
    if( libbfio_pool_get_handle(
2636
0
         file_io_pool,
2637
0
         file_io_pool_entry,
2638
0
         &file_io_handle,
2639
0
         error ) != 1 )
2640
0
    {
2641
0
      libcerror_error_set(
2642
0
       error,
2643
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2644
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2645
0
       "%s: unable to retrieve file IO handle: %d from pool.",
2646
0
       function,
2647
0
       file_io_pool_entry );
2648
2649
0
      goto on_error;
2650
0
    }
2651
0
    file_io_handle_is_open = libbfio_handle_is_open(
2652
0
                              file_io_handle,
2653
0
                              error );
2654
2655
0
    if( file_io_handle_is_open == -1 )
2656
0
    {
2657
0
      libcerror_error_set(
2658
0
       error,
2659
0
       LIBCERROR_ERROR_DOMAIN_IO,
2660
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
2661
0
       "%s: unable to determine if file IO pool entry: %d is open.",
2662
0
       function,
2663
0
       file_io_pool_entry );
2664
2665
0
      goto on_error;
2666
0
    }
2667
0
    else if( file_io_handle_is_open == 0 )
2668
0
    {
2669
0
      if( libbfio_handle_open(
2670
0
           file_io_handle,
2671
0
           internal_volume->access_flags,
2672
0
           error ) != 1 )
2673
0
      {
2674
0
        libcerror_error_set(
2675
0
         error,
2676
0
         LIBCERROR_ERROR_DOMAIN_IO,
2677
0
         LIBCERROR_IO_ERROR_OPEN_FAILED,
2678
0
         "%s: unable to open file IO pool entry: %d.",
2679
0
         function,
2680
0
         file_io_pool_entry );
2681
2682
0
        goto on_error;
2683
0
      }
2684
0
    }
2685
#if defined( HAVE_DEBUG_OUTPUT )
2686
    if( libcnotify_verbose != 0 )
2687
    {
2688
      libcnotify_printf(
2689
       "Reading physical volume header from file IO pool entry: %d:\n",
2690
       file_io_pool_entry );
2691
    }
2692
#endif
2693
0
    if( libfvde_volume_header_initialize(
2694
0
         &volume_header,
2695
0
         error ) != 1 )
2696
0
    {
2697
0
      libcerror_error_set(
2698
0
       error,
2699
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2700
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2701
0
       "%s: unable to create physical volume header.",
2702
0
       function );
2703
2704
0
      goto on_error;
2705
0
    }
2706
0
    if( libfvde_volume_header_read_file_io_handle(
2707
0
         volume_header,
2708
0
         file_io_handle,
2709
0
         0,
2710
0
         error ) != 1 )
2711
0
    {
2712
0
      libcerror_error_set(
2713
0
       error,
2714
0
       LIBCERROR_ERROR_DOMAIN_IO,
2715
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2716
0
       "%s: unable to read physical volume header from file IO pool entry: %d.",
2717
0
       function,
2718
0
       file_io_pool_entry );
2719
2720
0
      goto on_error;
2721
0
    }
2722
0
    if( libfvde_metadata_get_physical_volume_descriptor_by_index(
2723
0
         internal_volume->metadata,
2724
0
         file_io_pool_entry,
2725
0
         &physical_volume_descriptor,
2726
0
         error ) != 1 )
2727
0
    {
2728
0
      libcerror_error_set(
2729
0
       error,
2730
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2731
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2732
0
       "%s: unable to retrieve physical volume descriptor: %d from metadata.",
2733
0
       function,
2734
0
       file_io_pool_entry );
2735
2736
0
      goto on_error;
2737
0
    }
2738
0
    if( memory_compare(
2739
0
         volume_header->physical_volume_identifier,
2740
0
         physical_volume_descriptor->identifier,
2741
0
         16 ) != 0 )
2742
0
    {
2743
0
      libcerror_error_set(
2744
0
       error,
2745
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2746
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2747
0
       "%s: mismatch in physical volume identifier for file IO pool entry: %d.",
2748
0
       function,
2749
0
       file_io_pool_entry );
2750
2751
0
      goto on_error;
2752
0
    }
2753
0
    if( memory_compare(
2754
0
         volume_header->volume_group_identifier,
2755
0
         internal_volume->volume_header->volume_group_identifier,
2756
0
         16 ) != 0 )
2757
0
    {
2758
0
      libcerror_error_set(
2759
0
       error,
2760
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2761
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2762
0
       "%s: mismatch in volume group identifier for file IO pool entry: %d.",
2763
0
       function,
2764
0
       file_io_pool_entry );
2765
2766
0
      goto on_error;
2767
0
    }
2768
/* TODO determine physical volume index and check with pool
2769
 */
2770
0
    if( file_io_pool_entry == internal_volume->metadata->encrypted_metadata1_volume_index )
2771
0
    {
2772
#if defined( HAVE_DEBUG_OUTPUT )
2773
      if( libcnotify_verbose != 0 )
2774
      {
2775
        libcnotify_printf(
2776
         "Reading encrypted metadata 1:\n" );
2777
      }
2778
#endif
2779
0
      if( libfvde_encrypted_metadata_initialize(
2780
0
           &( internal_volume->encrypted_metadata1 ),
2781
0
           error ) != 1 )
2782
0
      {
2783
0
        libcerror_error_set(
2784
0
         error,
2785
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2786
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2787
0
         "%s: unable to create encrypted metadata 1.",
2788
0
         function );
2789
2790
0
        goto on_error;
2791
0
      }
2792
0
      if( libfvde_encrypted_metadata_read_from_file_io_handle(
2793
0
           internal_volume->encrypted_metadata1,
2794
0
           internal_volume->io_handle,
2795
0
           file_io_handle,
2796
0
           (off64_t) internal_volume->metadata->encrypted_metadata1_offset,
2797
0
           internal_volume->metadata->encrypted_metadata_size,
2798
0
           volume_header->key_data,
2799
0
           128,
2800
0
           volume_header->physical_volume_identifier,
2801
0
           128,
2802
0
           error ) != 1 )
2803
0
      {
2804
0
        libcerror_error_set(
2805
0
         error,
2806
0
         LIBCERROR_ERROR_DOMAIN_IO,
2807
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2808
0
         "%s: unable to read encrypted metadata 1.",
2809
0
         function );
2810
2811
0
        goto on_error;
2812
0
      }
2813
0
    }
2814
0
    if( file_io_pool_entry == internal_volume->metadata->encrypted_metadata2_volume_index )
2815
0
    {
2816
#if defined( HAVE_DEBUG_OUTPUT )
2817
      if( libcnotify_verbose != 0 )
2818
      {
2819
        libcnotify_printf(
2820
         "Reading encrypted metadata 2:\n" );
2821
      }
2822
#endif
2823
0
      if( libfvde_encrypted_metadata_initialize(
2824
0
           &( internal_volume->encrypted_metadata2 ),
2825
0
           error ) != 1 )
2826
0
      {
2827
0
        libcerror_error_set(
2828
0
         error,
2829
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2830
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2831
0
         "%s: unable to create encrypted metadata 2.",
2832
0
         function );
2833
2834
0
        goto on_error;
2835
0
      }
2836
0
      if( libfvde_encrypted_metadata_read_from_file_io_handle(
2837
0
           internal_volume->encrypted_metadata2,
2838
0
           internal_volume->io_handle,
2839
0
           file_io_handle,
2840
0
           (off64_t) internal_volume->metadata->encrypted_metadata2_offset,
2841
0
           internal_volume->metadata->encrypted_metadata_size,
2842
0
           volume_header->key_data,
2843
0
           128,
2844
0
           volume_header->physical_volume_identifier,
2845
0
           128,
2846
0
           error ) != 1 )
2847
0
      {
2848
0
        libcerror_error_set(
2849
0
         error,
2850
0
         LIBCERROR_ERROR_DOMAIN_IO,
2851
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2852
0
         "%s: unable to read encrypted metadata 2.",
2853
0
         function );
2854
2855
0
        goto on_error;
2856
0
      }
2857
0
    }
2858
0
    if( libfvde_volume_header_free(
2859
0
         &volume_header,
2860
0
         error ) != 1 )
2861
0
    {
2862
0
      libcerror_error_set(
2863
0
       error,
2864
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2865
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2866
0
       "%s: unable to free volume header.",
2867
0
       function );
2868
2869
0
      goto on_error;
2870
0
    }
2871
0
  }
2872
0
  if( internal_volume->encrypted_root_plist != NULL )
2873
0
  {
2874
0
    if( libfvde_encryption_context_plist_decrypt(
2875
0
         internal_volume->encrypted_root_plist,
2876
0
         internal_volume->volume_header->key_data,
2877
0
         128,
2878
0
         error ) != 1 )
2879
0
    {
2880
0
      libcerror_error_set(
2881
0
       error,
2882
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2883
0
       LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
2884
0
       "%s: unable to decrypt encrypted root plist.",
2885
0
       function );
2886
2887
0
      goto on_error;
2888
0
    }
2889
0
  }
2890
0
  return( 1 );
2891
2892
0
on_error:
2893
0
  if( internal_volume->encrypted_metadata2 != NULL )
2894
0
  {
2895
0
    libfvde_encrypted_metadata_free(
2896
0
     &( internal_volume->encrypted_metadata2 ),
2897
0
     NULL );
2898
0
  }
2899
0
  if( internal_volume->encrypted_metadata1 != NULL )
2900
0
  {
2901
0
    libfvde_encrypted_metadata_free(
2902
0
     &( internal_volume->encrypted_metadata1 ),
2903
0
     NULL );
2904
0
  }
2905
0
  if( volume_header != NULL )
2906
0
  {
2907
0
    libfvde_volume_header_free(
2908
0
     &volume_header,
2909
0
     NULL );
2910
0
  }
2911
0
  return( -1 );
2912
0
}
2913
2914
/* Reads the EncryptedRoot.plist file
2915
 * This function needs to be used before one of the open or unlock functions
2916
 * Returns 1 if successful or -1 on error
2917
 */
2918
int libfvde_volume_read_encrypted_root_plist(
2919
     libfvde_volume_t *volume,
2920
     const char *filename,
2921
     libcerror_error_t **error )
2922
0
{
2923
0
  libbfio_handle_t *file_io_handle = NULL;
2924
0
  static char *function            = "libfvde_volume_read_encrypted_root_plist";
2925
0
  size_t filename_length           = 0;
2926
2927
0
  if( volume == NULL )
2928
0
  {
2929
0
    libcerror_error_set(
2930
0
     error,
2931
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2932
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2933
0
     "%s: invalid volume.",
2934
0
     function );
2935
2936
0
    return( -1 );
2937
0
  }
2938
0
  filename_length = narrow_string_length(
2939
0
                     filename );
2940
2941
0
  if( filename_length == 0 )
2942
0
  {
2943
0
    libcerror_error_set(
2944
0
     error,
2945
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2946
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2947
0
     "%s: invalid filename.",
2948
0
     function );
2949
2950
0
    goto on_error;
2951
0
  }
2952
0
  if( libbfio_file_initialize(
2953
0
       &file_io_handle,
2954
0
       error ) != 1 )
2955
0
  {
2956
0
    libcerror_error_set(
2957
0
     error,
2958
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2959
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2960
0
     "%s: unable to create file IO handle.",
2961
0
     function );
2962
2963
0
    goto on_error;
2964
0
  }
2965
0
  if( libbfio_file_set_name(
2966
0
       file_io_handle,
2967
0
       filename,
2968
0
       filename_length,
2969
0
       error ) != 1 )
2970
0
  {
2971
0
    libcerror_error_set(
2972
0
     error,
2973
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2974
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2975
0
     "%s: unable to set filename in file IO handle.",
2976
0
     function );
2977
2978
0
    goto on_error;
2979
0
  }
2980
0
  if( libfvde_volume_read_encrypted_root_plist_file_io_handle(
2981
0
       volume,
2982
0
       file_io_handle,
2983
0
       error ) != 1 )
2984
0
  {
2985
0
    libcerror_error_set(
2986
0
     error,
2987
0
     LIBCERROR_ERROR_DOMAIN_IO,
2988
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2989
0
     "%s: unable to read encrypted root plist file: %s.",
2990
0
     function,
2991
0
     filename );
2992
2993
0
    goto on_error;
2994
0
  }
2995
0
  if( libbfio_handle_free(
2996
0
       &file_io_handle,
2997
0
       error ) != 1 )
2998
0
  {
2999
0
    libcerror_error_set(
3000
0
     error,
3001
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3002
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3003
0
     "%s: unable to free file IO handle.",
3004
0
     function );
3005
3006
0
    goto on_error;
3007
0
  }
3008
0
  return( 1 );
3009
3010
0
on_error:
3011
0
  if( file_io_handle != NULL )
3012
0
  {
3013
0
    libbfio_handle_free(
3014
0
     &file_io_handle,
3015
0
     NULL );
3016
0
  }
3017
0
  return( -1 );
3018
0
}
3019
3020
#if defined( HAVE_WIDE_CHARACTER_TYPE )
3021
3022
/* Reads the EncryptedRoot.plist file
3023
 * This function needs to be used before one of the open or unlock functions
3024
 * Returns 1 if successful or -1 on error
3025
 */
3026
int libfvde_volume_read_encrypted_root_plist_wide(
3027
     libfvde_volume_t *volume,
3028
     const wchar_t *filename,
3029
     libcerror_error_t **error )
3030
{
3031
  libbfio_handle_t *file_io_handle = NULL;
3032
  static char *function            = "libfvde_volume_read_encrypted_root_plist_wide";
3033
  size_t filename_length           = 0;
3034
3035
  if( volume == NULL )
3036
  {
3037
    libcerror_error_set(
3038
     error,
3039
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3040
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3041
     "%s: invalid volume.",
3042
     function );
3043
3044
    return( -1 );
3045
  }
3046
  filename_length = wide_string_length(
3047
                     filename );
3048
3049
  if( filename_length == 0 )
3050
  {
3051
    libcerror_error_set(
3052
     error,
3053
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3054
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3055
     "%s: invalid filename.",
3056
     function );
3057
3058
    goto on_error;
3059
  }
3060
  if( libbfio_file_initialize(
3061
       &file_io_handle,
3062
       error ) != 1 )
3063
  {
3064
    libcerror_error_set(
3065
     error,
3066
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3067
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3068
     "%s: unable to create file IO handle.",
3069
     function );
3070
3071
    goto on_error;
3072
  }
3073
  if( libbfio_file_set_name_wide(
3074
       file_io_handle,
3075
       filename,
3076
       filename_length,
3077
       error ) != 1 )
3078
  {
3079
    libcerror_error_set(
3080
     error,
3081
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3082
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3083
     "%s: unable to set filename in file IO handle.",
3084
     function );
3085
3086
    goto on_error;
3087
  }
3088
  if( libfvde_volume_read_encrypted_root_plist_file_io_handle(
3089
       volume,
3090
       file_io_handle,
3091
       error ) != 1 )
3092
  {
3093
    libcerror_error_set(
3094
     error,
3095
     LIBCERROR_ERROR_DOMAIN_IO,
3096
     LIBCERROR_IO_ERROR_READ_FAILED,
3097
     "%s: unable to read encrypted root plist file: %s.",
3098
     function,
3099
     filename );
3100
3101
    goto on_error;
3102
  }
3103
  if( libbfio_handle_free(
3104
       &file_io_handle,
3105
       error ) != 1 )
3106
  {
3107
    libcerror_error_set(
3108
     error,
3109
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3110
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3111
     "%s: unable to free file IO handle.",
3112
     function );
3113
3114
    goto on_error;
3115
  }
3116
  return( 1 );
3117
3118
on_error:
3119
  if( file_io_handle != NULL )
3120
  {
3121
    libbfio_handle_free(
3122
     &file_io_handle,
3123
     NULL );
3124
  }
3125
  return( -1 );
3126
}
3127
3128
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
3129
3130
/* Reads the EncryptedRoot.plist file using a Basic File IO (bfio) handle
3131
 * This function needs to be used before one of the open or unlock functions
3132
 * Returns 1 if successful or -1 on error
3133
 */
3134
int libfvde_volume_read_encrypted_root_plist_file_io_handle(
3135
     libfvde_volume_t *volume,
3136
     libbfio_handle_t *file_io_handle,
3137
     libcerror_error_t **error )
3138
0
{
3139
0
  libfvde_internal_volume_t *internal_volume = NULL;
3140
0
  static char *function                      = "libfvde_volume_read_encrypted_root_plist_file_io_handle";
3141
3142
0
  if( volume == NULL )
3143
0
  {
3144
0
    libcerror_error_set(
3145
0
     error,
3146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3148
0
     "%s: invalid volume.",
3149
0
     function );
3150
3151
0
    return( -1 );
3152
0
  }
3153
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3154
3155
0
  if( internal_volume->io_handle == NULL )
3156
0
  {
3157
0
    libcerror_error_set(
3158
0
     error,
3159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3160
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3161
0
     "%s: invalid volume - missing IO handle.",
3162
0
     function );
3163
3164
0
    return( -1 );
3165
0
  }
3166
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3167
0
  if( libcthreads_read_write_lock_grab_for_write(
3168
0
       internal_volume->read_write_lock,
3169
0
       error ) != 1 )
3170
0
  {
3171
0
    libcerror_error_set(
3172
0
     error,
3173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3174
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3175
0
     "%s: unable to grab read/write lock for writing.",
3176
0
     function );
3177
3178
0
    return( -1 );
3179
0
  }
3180
0
#endif
3181
0
  if( internal_volume->encrypted_root_plist != NULL )
3182
0
  {
3183
0
    if( libfvde_encryption_context_plist_free(
3184
0
         &( internal_volume->encrypted_root_plist ),
3185
0
         error ) != 1 )
3186
0
    {
3187
0
      libcerror_error_set(
3188
0
       error,
3189
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3190
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3191
0
       "%s: unable to free encrypted root plist.",
3192
0
       function );
3193
3194
0
      goto on_error;
3195
0
    }
3196
0
  }
3197
0
  if( libfvde_encryption_context_plist_initialize(
3198
0
       &( internal_volume->encrypted_root_plist ),
3199
0
       error ) != 1 )
3200
0
  {
3201
0
    libcerror_error_set(
3202
0
     error,
3203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3204
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3205
0
     "%s: unable to create encrypted root plist.",
3206
0
     function );
3207
3208
0
    goto on_error;
3209
0
  }
3210
0
  if( libfvde_encryption_context_plist_read_file_io_handle(
3211
0
       internal_volume->encrypted_root_plist,
3212
0
       file_io_handle,
3213
0
       error ) != 1 )
3214
0
  {
3215
0
    libcerror_error_set(
3216
0
     error,
3217
0
     LIBCERROR_ERROR_DOMAIN_IO,
3218
0
     LIBCERROR_IO_ERROR_GENERIC,
3219
0
     "%s: unable to read encrypted root plist.",
3220
0
     function );
3221
3222
0
    goto on_error;
3223
0
  }
3224
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3225
0
  if( libcthreads_read_write_lock_release_for_write(
3226
0
       internal_volume->read_write_lock,
3227
0
       error ) != 1 )
3228
0
  {
3229
0
    libcerror_error_set(
3230
0
     error,
3231
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3232
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3233
0
     "%s: unable to release read/write lock for writing.",
3234
0
     function );
3235
3236
0
    return( -1 );
3237
0
  }
3238
0
#endif
3239
0
  return( 1 );
3240
3241
0
on_error:
3242
0
  if( internal_volume->encrypted_root_plist != NULL )
3243
0
  {
3244
0
    libfvde_encryption_context_plist_free(
3245
0
     &( internal_volume->encrypted_root_plist ),
3246
0
     NULL );
3247
0
  }
3248
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3249
0
  libcthreads_read_write_lock_release_for_write(
3250
0
   internal_volume->read_write_lock,
3251
0
   NULL );
3252
0
#endif
3253
0
  return( -1 );
3254
0
}
3255
3256
/* Retrieves the volume group
3257
 * Returns 1 if successful or -1 on error
3258
 */
3259
int libfvde_volume_get_volume_group(
3260
     libfvde_volume_t *volume,
3261
     libfvde_volume_group_t **volume_group,
3262
     libcerror_error_t **error )
3263
0
{
3264
0
  libfvde_internal_volume_t *internal_volume = NULL;
3265
0
  static char *function                      = "libfvde_volume_get_volume_group";
3266
0
  int result                                 = 1;
3267
3268
0
  if( volume == NULL )
3269
0
  {
3270
0
    libcerror_error_set(
3271
0
     error,
3272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3273
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3274
0
     "%s: invalid volume.",
3275
0
     function );
3276
3277
0
    return( -1 );
3278
0
  }
3279
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3280
3281
0
  if( internal_volume->volume_header == NULL )
3282
0
  {
3283
0
    libcerror_error_set(
3284
0
     error,
3285
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3286
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3287
0
     "%s: invalid volume - missing volume header.",
3288
0
     function );
3289
3290
0
    return( -1 );
3291
0
  }
3292
0
  if( volume_group == NULL )
3293
0
  {
3294
0
    libcerror_error_set(
3295
0
     error,
3296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3298
0
     "%s: invalid volume group.",
3299
0
     function );
3300
3301
0
    return( -1 );
3302
0
  }
3303
0
  if( *volume_group != NULL )
3304
0
  {
3305
0
    libcerror_error_set(
3306
0
     error,
3307
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3308
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3309
0
     "%s: invalid volume group value already set.",
3310
0
     function );
3311
3312
0
    return( -1 );
3313
0
  }
3314
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3315
0
  if( libcthreads_read_write_lock_grab_for_read(
3316
0
       internal_volume->read_write_lock,
3317
0
       error ) != 1 )
3318
0
  {
3319
0
    libcerror_error_set(
3320
0
     error,
3321
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3322
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3323
0
     "%s: unable to grab read/write lock for reading.",
3324
0
     function );
3325
3326
0
    return( -1 );
3327
0
  }
3328
0
#endif
3329
0
  if( libfvde_volume_group_initialize(
3330
0
        volume_group,
3331
0
        internal_volume->io_handle,
3332
0
        internal_volume->physical_volume_file_io_pool,
3333
0
        internal_volume->volume_header,
3334
0
        internal_volume->metadata,
3335
0
        internal_volume->encrypted_metadata1,
3336
0
        internal_volume->encrypted_root_plist,
3337
0
        error ) != 1 )
3338
0
  {
3339
0
    libcerror_error_set(
3340
0
     error,
3341
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3342
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3343
0
     "%s: unable to create volume group.",
3344
0
     function );
3345
3346
0
    result = -1;
3347
0
  }
3348
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3349
0
  if( libcthreads_read_write_lock_release_for_read(
3350
0
       internal_volume->read_write_lock,
3351
0
       error ) != 1 )
3352
0
  {
3353
0
    libcerror_error_set(
3354
0
     error,
3355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3356
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3357
0
     "%s: unable to release read/write lock for reading.",
3358
0
     function );
3359
3360
0
    return( -1 );
3361
0
  }
3362
0
#endif
3363
0
  return( result );
3364
0
}
3365
3366
/* The following functions have been deprecated and will be removed
3367
 */
3368
3369
/* Unlocks the volume
3370
 * Returns 1 if the volume is unlocked, 0 if not or -1 on error
3371
 */
3372
int libfvde_volume_unlock(
3373
     libfvde_volume_t *volume,
3374
     libcerror_error_t **error )
3375
0
{
3376
0
  libfvde_internal_volume_t *internal_volume = NULL;
3377
0
  static char *function                      = "libfvde_volume_unlock";
3378
0
  int result                                 = 1;
3379
3380
0
  if( volume == NULL )
3381
0
  {
3382
0
    libcerror_error_set(
3383
0
     error,
3384
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3385
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3386
0
     "%s: invalid volume.",
3387
0
     function );
3388
3389
0
    return( -1 );
3390
0
  }
3391
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3392
3393
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3394
0
  if( libcthreads_read_write_lock_grab_for_write(
3395
0
       internal_volume->read_write_lock,
3396
0
       error ) != 1 )
3397
0
  {
3398
0
    libcerror_error_set(
3399
0
     error,
3400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3401
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3402
0
     "%s: unable to grab read/write lock for writing.",
3403
0
     function );
3404
3405
0
    return( -1 );
3406
0
  }
3407
0
#endif
3408
0
  result = libfvde_logical_volume_unlock(
3409
0
            internal_volume->legacy_logical_volume,
3410
0
            error );
3411
3412
0
  if( result == -1 )
3413
0
  {
3414
0
    libcerror_error_set(
3415
0
     error,
3416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3417
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
3418
0
     "%s: unable to unlock volume.",
3419
0
     function );
3420
3421
0
    result = -1;
3422
0
  }
3423
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3424
0
  if( libcthreads_read_write_lock_release_for_write(
3425
0
       internal_volume->read_write_lock,
3426
0
       error ) != 1 )
3427
0
  {
3428
0
    libcerror_error_set(
3429
0
     error,
3430
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3431
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3432
0
     "%s: unable to release read/write lock for writing.",
3433
0
     function );
3434
3435
0
    return( -1 );
3436
0
  }
3437
0
#endif
3438
0
  return( result );
3439
0
}
3440
3441
/* Determines if the volume is locked
3442
 * Returns 1 if locked, 0 if not or -1 on error
3443
 */
3444
int libfvde_volume_is_locked(
3445
     libfvde_volume_t *volume,
3446
     libcerror_error_t **error )
3447
0
{
3448
0
  libfvde_internal_volume_t *internal_volume = NULL;
3449
0
  static char *function                      = "libfvde_volume_is_locked";
3450
0
  int result                                 = 0;
3451
3452
0
  if( volume == NULL )
3453
0
  {
3454
0
    libcerror_error_set(
3455
0
     error,
3456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3458
0
     "%s: invalid volume.",
3459
0
     function );
3460
3461
0
    return( -1 );
3462
0
  }
3463
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3464
3465
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3466
0
  if( libcthreads_read_write_lock_grab_for_read(
3467
0
       internal_volume->read_write_lock,
3468
0
       error ) != 1 )
3469
0
  {
3470
0
    libcerror_error_set(
3471
0
     error,
3472
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3473
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3474
0
     "%s: unable to grab read/write lock for reading.",
3475
0
     function );
3476
3477
0
    return( -1 );
3478
0
  }
3479
0
#endif
3480
0
  result = libfvde_logical_volume_is_locked(
3481
0
            internal_volume->legacy_logical_volume,
3482
0
            error );
3483
3484
0
  if( result == -1 )
3485
0
  {
3486
0
    libcerror_error_set(
3487
0
     error,
3488
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3489
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3490
0
     "%s: unable to determine if logical volume is locked.",
3491
0
     function );
3492
3493
0
    result = -1;
3494
0
  }
3495
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3496
0
  if( libcthreads_read_write_lock_release_for_read(
3497
0
       internal_volume->read_write_lock,
3498
0
       error ) != 1 )
3499
0
  {
3500
0
    libcerror_error_set(
3501
0
     error,
3502
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3503
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3504
0
     "%s: unable to release read/write lock for reading.",
3505
0
     function );
3506
3507
0
    return( -1 );
3508
0
  }
3509
0
#endif
3510
0
  return( result );
3511
0
}
3512
3513
/* Reads data at the current offset into a buffer
3514
 * Returns the number of bytes read or -1 on error
3515
 */
3516
ssize_t libfvde_volume_read_buffer(
3517
         libfvde_volume_t *volume,
3518
         void *buffer,
3519
         size_t buffer_size,
3520
         libcerror_error_t **error )
3521
0
{
3522
0
  libfvde_internal_volume_t *internal_volume = NULL;
3523
0
  static char *function                      = "libfvde_volume_read_buffer";
3524
0
  ssize_t read_count                         = 0;
3525
3526
0
  if( volume == NULL )
3527
0
  {
3528
0
    libcerror_error_set(
3529
0
     error,
3530
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3531
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3532
0
     "%s: invalid volume.",
3533
0
     function );
3534
3535
0
    return( -1 );
3536
0
  }
3537
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3538
3539
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3540
0
  if( libcthreads_read_write_lock_grab_for_write(
3541
0
       internal_volume->read_write_lock,
3542
0
       error ) != 1 )
3543
0
  {
3544
0
    libcerror_error_set(
3545
0
     error,
3546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3547
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3548
0
     "%s: unable to grab read/write lock for writing.",
3549
0
     function );
3550
3551
0
    return( -1 );
3552
0
  }
3553
0
#endif
3554
0
  read_count = libfvde_logical_volume_read_buffer(
3555
0
          internal_volume->legacy_logical_volume,
3556
0
          buffer,
3557
0
          buffer_size,
3558
0
          error );
3559
3560
0
  if( read_count == -1 )
3561
0
  {
3562
0
    libcerror_error_set(
3563
0
     error,
3564
0
     LIBCERROR_ERROR_DOMAIN_IO,
3565
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3566
0
     "%s: unable to read buffer from logical volume.",
3567
0
     function );
3568
3569
0
    read_count = -1;
3570
0
  }
3571
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3572
0
  if( libcthreads_read_write_lock_release_for_write(
3573
0
       internal_volume->read_write_lock,
3574
0
       error ) != 1 )
3575
0
  {
3576
0
    libcerror_error_set(
3577
0
     error,
3578
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3579
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3580
0
     "%s: unable to release read/write lock for writing.",
3581
0
     function );
3582
3583
0
    return( -1 );
3584
0
  }
3585
0
#endif
3586
0
  return( read_count );
3587
0
}
3588
3589
/* Reads data at a specific offset
3590
 * Returns the number of bytes read or -1 on error
3591
 */
3592
ssize_t libfvde_volume_read_buffer_at_offset(
3593
         libfvde_volume_t *volume,
3594
         void *buffer,
3595
         size_t buffer_size,
3596
         off64_t offset,
3597
         libcerror_error_t **error )
3598
0
{
3599
0
  libfvde_internal_volume_t *internal_volume = NULL;
3600
0
  static char *function                      = "libfvde_volume_read_buffer_at_offset";
3601
0
  ssize_t read_count                         = 0;
3602
3603
0
  if( volume == NULL )
3604
0
  {
3605
0
    libcerror_error_set(
3606
0
     error,
3607
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3608
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3609
0
     "%s: invalid volume.",
3610
0
     function );
3611
3612
0
    return( -1 );
3613
0
  }
3614
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3615
3616
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3617
0
  if( libcthreads_read_write_lock_grab_for_write(
3618
0
       internal_volume->read_write_lock,
3619
0
       error ) != 1 )
3620
0
  {
3621
0
    libcerror_error_set(
3622
0
     error,
3623
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3624
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3625
0
     "%s: unable to grab read/write lock for writing.",
3626
0
     function );
3627
3628
0
    return( -1 );
3629
0
  }
3630
0
#endif
3631
0
  read_count = libfvde_logical_volume_read_buffer_at_offset(
3632
0
          internal_volume->legacy_logical_volume,
3633
0
          buffer,
3634
0
          buffer_size,
3635
0
          offset,
3636
0
          error );
3637
3638
0
  if( read_count == -1 )
3639
0
  {
3640
0
    libcerror_error_set(
3641
0
     error,
3642
0
     LIBCERROR_ERROR_DOMAIN_IO,
3643
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3644
0
     "%s: unable to read buffer from logical volume.",
3645
0
     function );
3646
3647
0
    read_count = -1;
3648
0
  }
3649
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3650
0
  if( libcthreads_read_write_lock_release_for_write(
3651
0
       internal_volume->read_write_lock,
3652
0
       error ) != 1 )
3653
0
  {
3654
0
    libcerror_error_set(
3655
0
     error,
3656
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3657
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3658
0
     "%s: unable to release read/write lock for writing.",
3659
0
     function );
3660
3661
0
    return( -1 );
3662
0
  }
3663
0
#endif
3664
0
  return( read_count );
3665
0
}
3666
3667
/* Seeks a certain offset of the data
3668
 * Returns the offset if seek is successful or -1 on error
3669
 */
3670
off64_t libfvde_volume_seek_offset(
3671
         libfvde_volume_t *volume,
3672
         off64_t offset,
3673
         int whence,
3674
         libcerror_error_t **error )
3675
0
{
3676
0
  libfvde_internal_volume_t *internal_volume = NULL;
3677
0
  static char *function                      = "libfvde_volume_seek_offset";
3678
3679
0
  if( volume == NULL )
3680
0
  {
3681
0
    libcerror_error_set(
3682
0
     error,
3683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3685
0
     "%s: invalid volume.",
3686
0
     function );
3687
3688
0
    return( -1 );
3689
0
  }
3690
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3691
3692
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3693
0
  if( libcthreads_read_write_lock_grab_for_write(
3694
0
       internal_volume->read_write_lock,
3695
0
       error ) != 1 )
3696
0
  {
3697
0
    libcerror_error_set(
3698
0
     error,
3699
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3700
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3701
0
     "%s: unable to grab read/write lock for writing.",
3702
0
     function );
3703
3704
0
    return( -1 );
3705
0
  }
3706
0
#endif
3707
0
  offset = libfvde_logical_volume_seek_offset(
3708
0
            internal_volume->legacy_logical_volume,
3709
0
            offset,
3710
0
            whence,
3711
0
            error );
3712
3713
0
  if( offset == -1 )
3714
0
  {
3715
0
    libcerror_error_set(
3716
0
     error,
3717
0
     LIBCERROR_ERROR_DOMAIN_IO,
3718
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
3719
0
     "%s: unable to seek offset in logical volume.",
3720
0
     function );
3721
3722
0
    offset = -1;
3723
0
  }
3724
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3725
0
  if( libcthreads_read_write_lock_release_for_write(
3726
0
       internal_volume->read_write_lock,
3727
0
       error ) != 1 )
3728
0
  {
3729
0
    libcerror_error_set(
3730
0
     error,
3731
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3732
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3733
0
     "%s: unable to release read/write lock for writing.",
3734
0
     function );
3735
3736
0
    return( -1 );
3737
0
  }
3738
0
#endif
3739
0
  return( offset );
3740
0
}
3741
3742
/* Retrieves the current offset of the data
3743
 * Returns 1 if successful or -1 on error
3744
 */
3745
int libfvde_volume_get_offset(
3746
     libfvde_volume_t *volume,
3747
     off64_t *offset,
3748
     libcerror_error_t **error )
3749
0
{
3750
0
  libfvde_internal_volume_t *internal_volume = NULL;
3751
0
  static char *function                      = "libfvde_volume_get_offset";
3752
0
  int result                                 = 1;
3753
3754
0
  if( volume == NULL )
3755
0
  {
3756
0
    libcerror_error_set(
3757
0
     error,
3758
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3759
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3760
0
     "%s: invalid volume.",
3761
0
     function );
3762
3763
0
    return( -1 );
3764
0
  }
3765
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3766
3767
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3768
0
  if( libcthreads_read_write_lock_grab_for_read(
3769
0
       internal_volume->read_write_lock,
3770
0
       error ) != 1 )
3771
0
  {
3772
0
    libcerror_error_set(
3773
0
     error,
3774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3775
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3776
0
     "%s: unable to grab read/write lock for reading.",
3777
0
     function );
3778
3779
0
    return( -1 );
3780
0
  }
3781
0
#endif
3782
0
  if( libfvde_logical_volume_get_offset(
3783
0
       internal_volume->legacy_logical_volume,
3784
0
       offset,
3785
0
       error ) == -1 )
3786
0
  {
3787
0
    libcerror_error_set(
3788
0
     error,
3789
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3790
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3791
0
     "%s: unable to retrieve offset from logical volume.",
3792
0
     function );
3793
3794
0
    result = -1;
3795
0
  }
3796
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3797
0
  if( libcthreads_read_write_lock_release_for_read(
3798
0
       internal_volume->read_write_lock,
3799
0
       error ) != 1 )
3800
0
  {
3801
0
    libcerror_error_set(
3802
0
     error,
3803
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3804
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3805
0
     "%s: unable to release read/write lock for reading.",
3806
0
     function );
3807
3808
0
    return( -1 );
3809
0
  }
3810
0
#endif
3811
0
  return( result );
3812
0
}
3813
3814
/* Retrieves the size
3815
 * Returns 1 if successful or -1 on error
3816
 */
3817
int libfvde_volume_get_size(
3818
     libfvde_volume_t *volume,
3819
     size64_t *size,
3820
     libcerror_error_t **error )
3821
0
{
3822
0
  libfvde_internal_volume_t *internal_volume = NULL;
3823
0
  static char *function                      = "libfvde_volume_get_size";
3824
0
  int result                                 = 1;
3825
3826
0
  if( volume == NULL )
3827
0
  {
3828
0
    libcerror_error_set(
3829
0
     error,
3830
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3831
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3832
0
     "%s: invalid volume.",
3833
0
     function );
3834
3835
0
    return( -1 );
3836
0
  }
3837
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3838
3839
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3840
0
  if( libcthreads_read_write_lock_grab_for_read(
3841
0
       internal_volume->read_write_lock,
3842
0
       error ) != 1 )
3843
0
  {
3844
0
    libcerror_error_set(
3845
0
     error,
3846
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3847
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3848
0
     "%s: unable to grab read/write lock for reading.",
3849
0
     function );
3850
3851
0
    return( -1 );
3852
0
  }
3853
0
#endif
3854
0
  if( libfvde_logical_volume_get_size(
3855
0
       internal_volume->legacy_logical_volume,
3856
0
       size,
3857
0
       error ) == -1 )
3858
0
  {
3859
0
    libcerror_error_set(
3860
0
     error,
3861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3862
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3863
0
     "%s: unable to retrieve size from logical volume.",
3864
0
     function );
3865
3866
0
    result = -1;
3867
0
  }
3868
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3869
0
  if( libcthreads_read_write_lock_release_for_read(
3870
0
       internal_volume->read_write_lock,
3871
0
       error ) != 1 )
3872
0
  {
3873
0
    libcerror_error_set(
3874
0
     error,
3875
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3876
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3877
0
     "%s: unable to release read/write lock for reading.",
3878
0
     function );
3879
3880
0
    return( -1 );
3881
0
  }
3882
0
#endif
3883
0
  return( result );
3884
0
}
3885
3886
/* Retrieves the encryption method of the physical volume
3887
 * Returns 1 if successful or -1 on error
3888
 */
3889
int libfvde_volume_get_encryption_method(
3890
     libfvde_volume_t *volume,
3891
     uint32_t *encryption_method,
3892
     libcerror_error_t **error )
3893
0
{
3894
0
  libfvde_internal_volume_t *internal_volume = NULL;
3895
0
  static char *function                      = "libfvde_volume_get_encryption_method";
3896
3897
0
  if( volume == NULL )
3898
0
  {
3899
0
    libcerror_error_set(
3900
0
     error,
3901
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3902
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3903
0
     "%s: invalid volume.",
3904
0
     function );
3905
3906
0
    return( -1 );
3907
0
  }
3908
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3909
3910
0
  if( internal_volume->volume_header == NULL )
3911
0
  {
3912
0
    libcerror_error_set(
3913
0
     error,
3914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3915
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3916
0
     "%s: invalid volume - missing volume header.",
3917
0
     function );
3918
3919
0
    return( -1 );
3920
0
  }
3921
0
  if( encryption_method == NULL )
3922
0
  {
3923
0
    libcerror_error_set(
3924
0
     error,
3925
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3926
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3927
0
     "%s: invalid encryption method.",
3928
0
     function );
3929
3930
0
    return( -1 );
3931
0
  }
3932
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3933
0
  if( libcthreads_read_write_lock_grab_for_read(
3934
0
       internal_volume->read_write_lock,
3935
0
       error ) != 1 )
3936
0
  {
3937
0
    libcerror_error_set(
3938
0
     error,
3939
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3940
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3941
0
     "%s: unable to grab read/write lock for reading.",
3942
0
     function );
3943
3944
0
    return( -1 );
3945
0
  }
3946
0
#endif
3947
0
  *encryption_method = internal_volume->volume_header->physical_volume_encryption_method;
3948
3949
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3950
0
  if( libcthreads_read_write_lock_release_for_read(
3951
0
       internal_volume->read_write_lock,
3952
0
       error ) != 1 )
3953
0
  {
3954
0
    libcerror_error_set(
3955
0
     error,
3956
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3957
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3958
0
     "%s: unable to release read/write lock for reading.",
3959
0
     function );
3960
3961
0
    return( -1 );
3962
0
  }
3963
0
#endif
3964
0
  return( 1 );
3965
0
}
3966
3967
/* Retrieves the logical volume group identifier
3968
 * The identifier is a UUID and is 16 bytes of size
3969
 * Returns 1 if successful or -1 on error
3970
 */
3971
int libfvde_volume_get_logical_volume_group_identifier(
3972
     libfvde_volume_t *volume,
3973
     uint8_t *uuid_data,
3974
     size_t uuid_data_size,
3975
     libcerror_error_t **error )
3976
0
{
3977
0
  libfvde_internal_volume_t *internal_volume = NULL;
3978
0
  static char *function                      = "libfvde_volume_get_logical_volume_group_identifier";
3979
0
  int result                                 = 1;
3980
3981
0
  if( volume == NULL )
3982
0
  {
3983
0
    libcerror_error_set(
3984
0
     error,
3985
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3986
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3987
0
     "%s: invalid volume.",
3988
0
     function );
3989
3990
0
    return( -1 );
3991
0
  }
3992
0
  internal_volume = (libfvde_internal_volume_t *) volume;
3993
3994
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3995
0
  if( libcthreads_read_write_lock_grab_for_read(
3996
0
       internal_volume->read_write_lock,
3997
0
       error ) != 1 )
3998
0
  {
3999
0
    libcerror_error_set(
4000
0
     error,
4001
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4002
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4003
0
     "%s: unable to grab read/write lock for reading.",
4004
0
     function );
4005
4006
0
    return( -1 );
4007
0
  }
4008
0
#endif
4009
0
  if( libfvde_volume_header_get_volume_group_identifier(
4010
0
       internal_volume->volume_header,
4011
0
       uuid_data,
4012
0
       uuid_data_size,
4013
0
       error ) != 1 )
4014
0
  {
4015
0
    libcerror_error_set(
4016
0
     error,
4017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4018
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4019
0
     "%s: unable to retrieve volume group identifier from volume header.",
4020
0
     function );
4021
4022
0
    result = -1;
4023
0
  }
4024
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4025
0
  if( libcthreads_read_write_lock_release_for_read(
4026
0
       internal_volume->read_write_lock,
4027
0
       error ) != 1 )
4028
0
  {
4029
0
    libcerror_error_set(
4030
0
     error,
4031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4032
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4033
0
     "%s: unable to release read/write lock for reading.",
4034
0
     function );
4035
4036
0
    return( -1 );
4037
0
  }
4038
0
#endif
4039
0
  return( result );
4040
0
}
4041
4042
/* Retrieves the physical volume size
4043
 * Returns 1 if successful or -1 on error
4044
 */
4045
int libfvde_volume_get_physical_volume_size(
4046
     libfvde_volume_t *volume,
4047
     size64_t *size,
4048
     libcerror_error_t **error )
4049
0
{
4050
0
  libfvde_internal_volume_t *internal_volume = NULL;
4051
0
  static char *function                      = "libfvde_volume_get_physical_volume_size";
4052
0
  int result                                 = 1;
4053
4054
0
  if( volume == NULL )
4055
0
  {
4056
0
    libcerror_error_set(
4057
0
     error,
4058
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4059
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4060
0
     "%s: invalid volume.",
4061
0
     function );
4062
4063
0
    return( -1 );
4064
0
  }
4065
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4066
4067
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4068
0
  if( libcthreads_read_write_lock_grab_for_read(
4069
0
       internal_volume->read_write_lock,
4070
0
       error ) != 1 )
4071
0
  {
4072
0
    libcerror_error_set(
4073
0
     error,
4074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4075
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4076
0
     "%s: unable to grab read/write lock for reading.",
4077
0
     function );
4078
4079
0
    return( -1 );
4080
0
  }
4081
0
#endif
4082
0
  if( libfvde_volume_header_get_physical_volume_size(
4083
0
       internal_volume->volume_header,
4084
0
       size,
4085
0
       error ) != 1 )
4086
0
  {
4087
0
    libcerror_error_set(
4088
0
     error,
4089
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4090
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4091
0
     "%s: unable to retrieve physical volume size from volume header.",
4092
0
     function );
4093
4094
0
    result = -1;
4095
0
  }
4096
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4097
0
  if( libcthreads_read_write_lock_release_for_read(
4098
0
       internal_volume->read_write_lock,
4099
0
       error ) != 1 )
4100
0
  {
4101
0
    libcerror_error_set(
4102
0
     error,
4103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4104
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4105
0
     "%s: unable to release read/write lock for reading.",
4106
0
     function );
4107
4108
0
    return( -1 );
4109
0
  }
4110
0
#endif
4111
0
  return( result );
4112
0
}
4113
4114
/* Retrieves the encryption method of the physical volume
4115
 * Returns 1 if successful or -1 on error
4116
 */
4117
int libfvde_volume_get_physical_volume_encryption_method(
4118
     libfvde_volume_t *volume,
4119
     uint32_t *encryption_method,
4120
     libcerror_error_t **error )
4121
0
{
4122
0
  libfvde_internal_volume_t *internal_volume = NULL;
4123
0
  static char *function                      = "libfvde_volume_get_physical_volume_encryption_method";
4124
0
  int result                                 = 1;
4125
4126
0
  if( volume == NULL )
4127
0
  {
4128
0
    libcerror_error_set(
4129
0
     error,
4130
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4131
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4132
0
     "%s: invalid volume.",
4133
0
     function );
4134
4135
0
    return( -1 );
4136
0
  }
4137
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4138
4139
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4140
0
  if( libcthreads_read_write_lock_grab_for_read(
4141
0
       internal_volume->read_write_lock,
4142
0
       error ) != 1 )
4143
0
  {
4144
0
    libcerror_error_set(
4145
0
     error,
4146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4147
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4148
0
     "%s: unable to grab read/write lock for reading.",
4149
0
     function );
4150
4151
0
    return( -1 );
4152
0
  }
4153
0
#endif
4154
0
  if( libfvde_volume_header_get_physical_volume_encryption_method(
4155
0
       internal_volume->volume_header,
4156
0
       encryption_method,
4157
0
       error ) != 1 )
4158
0
  {
4159
0
    libcerror_error_set(
4160
0
     error,
4161
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4162
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4163
0
     "%s: unable to retrieve physical volume encryption method from volume header.",
4164
0
     function );
4165
4166
0
    result = -1;
4167
0
  }
4168
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4169
0
  if( libcthreads_read_write_lock_release_for_read(
4170
0
       internal_volume->read_write_lock,
4171
0
       error ) != 1 )
4172
0
  {
4173
0
    libcerror_error_set(
4174
0
     error,
4175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4176
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4177
0
     "%s: unable to release read/write lock for reading.",
4178
0
     function );
4179
4180
0
    return( -1 );
4181
0
  }
4182
0
#endif
4183
0
  return( result );
4184
0
}
4185
4186
/* Retrieves the physical volume identifier
4187
 * The identifier is a UUID and is 16 bytes of size
4188
 * Returns 1 if successful or -1 on error
4189
 */
4190
int libfvde_volume_get_physical_volume_identifier(
4191
     libfvde_volume_t *volume,
4192
     uint8_t *uuid_data,
4193
     size_t uuid_data_size,
4194
     libcerror_error_t **error )
4195
0
{
4196
0
  libfvde_internal_volume_t *internal_volume = NULL;
4197
0
  static char *function                      = "libfvde_volume_get_physical_volume_identifier";
4198
0
  int result                                 = 1;
4199
4200
0
  if( volume == NULL )
4201
0
  {
4202
0
    libcerror_error_set(
4203
0
     error,
4204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4206
0
     "%s: invalid volume.",
4207
0
     function );
4208
4209
0
    return( -1 );
4210
0
  }
4211
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4212
4213
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4214
0
  if( libcthreads_read_write_lock_grab_for_read(
4215
0
       internal_volume->read_write_lock,
4216
0
       error ) != 1 )
4217
0
  {
4218
0
    libcerror_error_set(
4219
0
     error,
4220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4221
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4222
0
     "%s: unable to grab read/write lock for reading.",
4223
0
     function );
4224
4225
0
    return( -1 );
4226
0
  }
4227
0
#endif
4228
0
  if( libfvde_volume_header_get_physical_volume_identifier(
4229
0
       internal_volume->volume_header,
4230
0
       uuid_data,
4231
0
       uuid_data_size,
4232
0
       error ) != 1 )
4233
0
  {
4234
0
    libcerror_error_set(
4235
0
     error,
4236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4237
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4238
0
     "%s: unable to retrieve physical volume identifier from volume header.",
4239
0
     function );
4240
4241
0
    result = -1;
4242
0
  }
4243
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4244
0
  if( libcthreads_read_write_lock_release_for_read(
4245
0
       internal_volume->read_write_lock,
4246
0
       error ) != 1 )
4247
0
  {
4248
0
    libcerror_error_set(
4249
0
     error,
4250
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4251
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4252
0
     "%s: unable to release read/write lock for reading.",
4253
0
     function );
4254
4255
0
    return( -1 );
4256
0
  }
4257
0
#endif
4258
0
  return( result );
4259
0
}
4260
4261
/* Retrieves the logical volume size
4262
 * Returns 1 if successful or -1 on error
4263
 */
4264
int libfvde_volume_get_logical_volume_size(
4265
     libfvde_volume_t *volume,
4266
     size64_t *size,
4267
     libcerror_error_t **error )
4268
0
{
4269
0
  libfvde_internal_volume_t *internal_volume = NULL;
4270
0
  static char *function                      = "libfvde_volume_get_logical_volume_size";
4271
0
  int result                                 = 1;
4272
4273
0
  if( volume == NULL )
4274
0
  {
4275
0
    libcerror_error_set(
4276
0
     error,
4277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4278
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4279
0
     "%s: invalid volume.",
4280
0
     function );
4281
4282
0
    return( -1 );
4283
0
  }
4284
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4285
4286
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4287
0
  if( libcthreads_read_write_lock_grab_for_read(
4288
0
       internal_volume->read_write_lock,
4289
0
       error ) != 1 )
4290
0
  {
4291
0
    libcerror_error_set(
4292
0
     error,
4293
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4294
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4295
0
     "%s: unable to grab read/write lock for reading.",
4296
0
     function );
4297
4298
0
    return( -1 );
4299
0
  }
4300
0
#endif
4301
0
  if( libfvde_logical_volume_get_size(
4302
0
       internal_volume->legacy_logical_volume,
4303
0
       size,
4304
0
       error ) == -1 )
4305
0
  {
4306
0
    libcerror_error_set(
4307
0
     error,
4308
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4309
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4310
0
     "%s: unable to retrieve size from logical volume.",
4311
0
     function );
4312
4313
0
    result = -1;
4314
0
  }
4315
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4316
0
  if( libcthreads_read_write_lock_release_for_read(
4317
0
       internal_volume->read_write_lock,
4318
0
       error ) != 1 )
4319
0
  {
4320
0
    libcerror_error_set(
4321
0
     error,
4322
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4323
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4324
0
     "%s: unable to release read/write lock for reading.",
4325
0
     function );
4326
4327
0
    return( -1 );
4328
0
  }
4329
0
#endif
4330
0
  return( result );
4331
0
}
4332
4333
/* Retrieves the encryption method of the logical volume
4334
 * Returns 1 if successful or -1 on error
4335
 */
4336
int libfvde_volume_get_logical_volume_encryption_method(
4337
     libfvde_volume_t *volume,
4338
     uint32_t *encryption_method,
4339
     libcerror_error_t **error )
4340
0
{
4341
0
  libfvde_internal_volume_t *internal_volume = NULL;
4342
0
  static char *function                      = "libfvde_volume_get_logical_volume_encryption_method";
4343
4344
0
  if( volume == NULL )
4345
0
  {
4346
0
    libcerror_error_set(
4347
0
     error,
4348
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4349
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4350
0
     "%s: invalid volume.",
4351
0
     function );
4352
4353
0
    return( -1 );
4354
0
  }
4355
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4356
4357
0
  if( internal_volume->io_handle == NULL )
4358
0
  {
4359
0
    libcerror_error_set(
4360
0
     error,
4361
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4362
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4363
0
     "%s: invalid volume - missing IO handle.",
4364
0
     function );
4365
4366
0
    return( -1 );
4367
0
  }
4368
0
  if( encryption_method == NULL )
4369
0
  {
4370
0
    libcerror_error_set(
4371
0
     error,
4372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4374
0
     "%s: invalid encryption method.",
4375
0
     function );
4376
4377
0
    return( -1 );
4378
0
  }
4379
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4380
0
  if( libcthreads_read_write_lock_grab_for_read(
4381
0
       internal_volume->read_write_lock,
4382
0
       error ) != 1 )
4383
0
  {
4384
0
    libcerror_error_set(
4385
0
     error,
4386
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4387
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4388
0
     "%s: unable to grab read/write lock for reading.",
4389
0
     function );
4390
4391
0
    return( -1 );
4392
0
  }
4393
0
#endif
4394
/* TODO implement */
4395
0
  *encryption_method = 0;
4396
4397
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4398
0
  if( libcthreads_read_write_lock_release_for_read(
4399
0
       internal_volume->read_write_lock,
4400
0
       error ) != 1 )
4401
0
  {
4402
0
    libcerror_error_set(
4403
0
     error,
4404
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4405
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4406
0
     "%s: unable to release read/write lock for reading.",
4407
0
     function );
4408
4409
0
    return( -1 );
4410
0
  }
4411
0
#endif
4412
0
  return( 1 );
4413
0
}
4414
4415
/* Retrieves the logical volume identifier
4416
 * The identifier is a UUID and is 16 bytes of size
4417
 * Returns 1 if successful or -1 on error
4418
 */
4419
int libfvde_volume_get_logical_volume_identifier(
4420
     libfvde_volume_t *volume,
4421
     uint8_t *uuid_data,
4422
     size_t uuid_data_size,
4423
     libcerror_error_t **error )
4424
0
{
4425
0
  libfvde_internal_volume_t *internal_volume = NULL;
4426
0
  static char *function                      = "libfvde_volume_get_logical_volume_identifier";
4427
0
  int result                                 = 1;
4428
4429
0
  if( volume == NULL )
4430
0
  {
4431
0
    libcerror_error_set(
4432
0
     error,
4433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4434
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4435
0
     "%s: invalid volume.",
4436
0
     function );
4437
4438
0
    return( -1 );
4439
0
  }
4440
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4441
4442
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4443
0
  if( libcthreads_read_write_lock_grab_for_read(
4444
0
       internal_volume->read_write_lock,
4445
0
       error ) != 1 )
4446
0
  {
4447
0
    libcerror_error_set(
4448
0
     error,
4449
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4450
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4451
0
     "%s: unable to grab read/write lock for reading.",
4452
0
     function );
4453
4454
0
    return( -1 );
4455
0
  }
4456
0
#endif
4457
0
  if( libfvde_logical_volume_get_identifier(
4458
0
       internal_volume->legacy_logical_volume,
4459
0
       uuid_data,
4460
0
       uuid_data_size,
4461
0
       error ) == -1 )
4462
0
  {
4463
0
    libcerror_error_set(
4464
0
     error,
4465
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4466
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4467
0
     "%s: unable to retrieve identifier from logical volume.",
4468
0
     function );
4469
4470
0
    result = -1;
4471
0
  }
4472
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4473
0
  if( libcthreads_read_write_lock_release_for_read(
4474
0
       internal_volume->read_write_lock,
4475
0
       error ) != 1 )
4476
0
  {
4477
0
    libcerror_error_set(
4478
0
     error,
4479
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4480
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4481
0
     "%s: unable to release read/write lock for reading.",
4482
0
     function );
4483
4484
0
    return( -1 );
4485
0
  }
4486
0
#endif
4487
0
  return( result );
4488
0
}
4489
4490
/* Sets the keys
4491
 * This function needs to be used before one of the open or unlock functions
4492
 * Returns 1 if successful or -1 on error
4493
 */
4494
int libfvde_volume_set_keys(
4495
     libfvde_volume_t *volume,
4496
     const uint8_t *volume_master_key,
4497
     size_t volume_master_key_size,
4498
     libcerror_error_t **error )
4499
0
{
4500
0
  libfvde_internal_volume_t *internal_volume = NULL;
4501
0
  static char *function                      = "libfvde_volume_set_keys";
4502
0
  int result                                 = 1;
4503
4504
0
  if( volume == NULL )
4505
0
  {
4506
0
    libcerror_error_set(
4507
0
     error,
4508
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4509
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4510
0
     "%s: invalid volume.",
4511
0
     function );
4512
4513
0
    return( -1 );
4514
0
  }
4515
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4516
4517
0
  if( volume_master_key == NULL )
4518
0
  {
4519
0
    libcerror_error_set(
4520
0
     error,
4521
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4522
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4523
0
     "%s: invalid volume master key.",
4524
0
     function );
4525
4526
0
    return( -1 );
4527
0
  }
4528
0
  if( volume_master_key_size != 16 )
4529
0
  {
4530
0
    libcerror_error_set(
4531
0
     error,
4532
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4533
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
4534
0
     "%s: unsupported volume master key size.",
4535
0
     function );
4536
4537
0
    return( -1 );
4538
0
  }
4539
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4540
0
  if( libcthreads_read_write_lock_grab_for_write(
4541
0
       internal_volume->read_write_lock,
4542
0
       error ) != 1 )
4543
0
  {
4544
0
    libcerror_error_set(
4545
0
     error,
4546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4547
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4548
0
     "%s: unable to grab read/write lock for writing.",
4549
0
     function );
4550
4551
0
    return( -1 );
4552
0
  }
4553
0
#endif
4554
0
  if( memory_copy(
4555
0
       internal_volume->legacy_volume_master_key,
4556
0
       volume_master_key,
4557
0
       16 ) == NULL )
4558
0
  {
4559
0
    libcerror_error_set(
4560
0
     error,
4561
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
4562
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4563
0
     "%s: unable to copy volume master key.",
4564
0
     function );
4565
4566
0
    result = -1;
4567
0
  }
4568
0
  else
4569
0
  {
4570
0
    internal_volume->legacy_volume_master_key_is_set = 1;
4571
0
  }
4572
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4573
0
  if( libcthreads_read_write_lock_release_for_write(
4574
0
       internal_volume->read_write_lock,
4575
0
       error ) != 1 )
4576
0
  {
4577
0
    libcerror_error_set(
4578
0
     error,
4579
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4580
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4581
0
     "%s: unable to release read/write lock for writing.",
4582
0
     function );
4583
4584
0
    return( -1 );
4585
0
  }
4586
0
#endif
4587
0
  return( result );
4588
0
}
4589
4590
/* Sets an UTF-8 formatted password
4591
 * This function needs to be used before the unlock function
4592
 * Returns 1 if successful, 0 if password is invalid or -1 on error
4593
 */
4594
int libfvde_volume_set_utf8_password(
4595
     libfvde_volume_t *volume,
4596
     const uint8_t *utf8_string,
4597
     size_t utf8_string_length,
4598
     libcerror_error_t **error )
4599
0
{
4600
0
  libfvde_internal_volume_t *internal_volume = NULL;
4601
0
  static char *function                      = "libfvde_volume_set_utf8_password";
4602
0
  int result                                 = 1;
4603
4604
0
  if( volume == NULL )
4605
0
  {
4606
0
    libcerror_error_set(
4607
0
     error,
4608
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4609
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4610
0
     "%s: invalid volume.",
4611
0
     function );
4612
4613
0
    return( -1 );
4614
0
  }
4615
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4616
4617
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4618
0
  if( libcthreads_read_write_lock_grab_for_write(
4619
0
       internal_volume->read_write_lock,
4620
0
       error ) != 1 )
4621
0
  {
4622
0
    libcerror_error_set(
4623
0
     error,
4624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4625
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4626
0
     "%s: unable to grab read/write lock for writing.",
4627
0
     function );
4628
4629
0
    return( -1 );
4630
0
  }
4631
0
#endif
4632
0
  if( internal_volume->legacy_user_password != NULL )
4633
0
  {
4634
0
    if( memory_set(
4635
0
         internal_volume->legacy_user_password,
4636
0
         0,
4637
0
         internal_volume->legacy_user_password_size ) == NULL )
4638
0
    {
4639
0
      libcerror_error_set(
4640
0
       error,
4641
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4642
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
4643
0
       "%s: unable to clear user password.",
4644
0
       function );
4645
4646
0
      result = -1;
4647
0
    }
4648
0
    memory_free(
4649
0
     internal_volume->legacy_user_password );
4650
4651
0
    internal_volume->legacy_user_password      = NULL;
4652
0
    internal_volume->legacy_user_password_size = 0;
4653
0
  }
4654
0
  if( result == 1 )
4655
0
  {
4656
0
    if( libfvde_password_copy_from_utf8_string(
4657
0
         &( internal_volume->legacy_user_password ),
4658
0
         &( internal_volume->legacy_user_password_size ),
4659
0
         utf8_string,
4660
0
         utf8_string_length,
4661
0
         error ) != 1 )
4662
0
    {
4663
0
      libcerror_error_set(
4664
0
       error,
4665
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4666
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4667
0
       "%s: unable to set user password.",
4668
0
       function );
4669
4670
0
      result = -1;
4671
0
    }
4672
#if defined( HAVE_DEBUG_OUTPUT )
4673
    else if( libcnotify_verbose != 0 )
4674
    {
4675
      libcnotify_printf(
4676
       "%s: user password: %s\n",
4677
       function,
4678
       internal_volume->legacy_user_password );
4679
    }
4680
#endif
4681
0
  }
4682
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4683
0
  if( libcthreads_read_write_lock_release_for_write(
4684
0
       internal_volume->read_write_lock,
4685
0
       error ) != 1 )
4686
0
  {
4687
0
    libcerror_error_set(
4688
0
     error,
4689
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4690
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4691
0
     "%s: unable to release read/write lock for writing.",
4692
0
     function );
4693
4694
0
    return( -1 );
4695
0
  }
4696
0
#endif
4697
0
  return( result );
4698
0
}
4699
4700
/* Sets an UTF-16 formatted password
4701
 * This function needs to be used before the unlock function
4702
 * Returns 1 if successful, 0 if password is invalid or -1 on error
4703
 */
4704
int libfvde_volume_set_utf16_password(
4705
     libfvde_volume_t *volume,
4706
     const uint16_t *utf16_string,
4707
     size_t utf16_string_length,
4708
     libcerror_error_t **error )
4709
0
{
4710
0
  libfvde_internal_volume_t *internal_volume = NULL;
4711
0
  static char *function                      = "libfvde_volume_set_utf16_password";
4712
0
  int result                                 = 1;
4713
4714
0
  if( volume == NULL )
4715
0
  {
4716
0
    libcerror_error_set(
4717
0
     error,
4718
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4719
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4720
0
     "%s: invalid volume.",
4721
0
     function );
4722
4723
0
    return( -1 );
4724
0
  }
4725
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4726
4727
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4728
0
  if( libcthreads_read_write_lock_grab_for_write(
4729
0
       internal_volume->read_write_lock,
4730
0
       error ) != 1 )
4731
0
  {
4732
0
    libcerror_error_set(
4733
0
     error,
4734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4735
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4736
0
     "%s: unable to grab read/write lock for writing.",
4737
0
     function );
4738
4739
0
    return( -1 );
4740
0
  }
4741
0
#endif
4742
0
  if( internal_volume->legacy_user_password != NULL )
4743
0
  {
4744
0
    if( memory_set(
4745
0
         internal_volume->legacy_user_password,
4746
0
         0,
4747
0
         internal_volume->legacy_user_password_size ) == NULL )
4748
0
    {
4749
0
      libcerror_error_set(
4750
0
       error,
4751
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4752
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
4753
0
       "%s: unable to clear user password.",
4754
0
       function );
4755
4756
0
      result = -1;
4757
0
    }
4758
0
    memory_free(
4759
0
     internal_volume->legacy_user_password );
4760
4761
0
    internal_volume->legacy_user_password      = NULL;
4762
0
    internal_volume->legacy_user_password_size = 0;
4763
0
  }
4764
0
  if( result == 1 )
4765
0
  {
4766
0
    if( libfvde_password_copy_from_utf16_string(
4767
0
         &( internal_volume->legacy_user_password ),
4768
0
         &( internal_volume->legacy_user_password_size ),
4769
0
         utf16_string,
4770
0
         utf16_string_length,
4771
0
         error ) != 1 )
4772
0
    {
4773
0
      libcerror_error_set(
4774
0
       error,
4775
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4776
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4777
0
       "%s: unable to set user password.",
4778
0
       function );
4779
4780
0
      result = -1;
4781
0
    }
4782
#if defined( HAVE_DEBUG_OUTPUT )
4783
    else if( libcnotify_verbose != 0 )
4784
    {
4785
      libcnotify_printf(
4786
       "%s: user password: %s\n",
4787
       function,
4788
       internal_volume->legacy_user_password );
4789
    }
4790
#endif
4791
0
  }
4792
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4793
0
  if( libcthreads_read_write_lock_release_for_write(
4794
0
       internal_volume->read_write_lock,
4795
0
       error ) != 1 )
4796
0
  {
4797
0
    libcerror_error_set(
4798
0
     error,
4799
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4800
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4801
0
     "%s: unable to release read/write lock for writing.",
4802
0
     function );
4803
4804
0
    return( -1 );
4805
0
  }
4806
0
#endif
4807
0
  return( result );
4808
0
}
4809
4810
/* Sets an UTF-8 formatted recovery password
4811
 * This function needs to be used before the unlock function
4812
 * Returns 1 if successful, 0 if recovery password is invalid or -1 on error
4813
 */
4814
int libfvde_volume_set_utf8_recovery_password(
4815
     libfvde_volume_t *volume,
4816
     const uint8_t *utf8_string,
4817
     size_t utf8_string_length,
4818
     libcerror_error_t **error )
4819
0
{
4820
0
  libfvde_internal_volume_t *internal_volume = NULL;
4821
0
  static char *function                      = "libfvde_volume_set_utf8_recovery_password";
4822
0
  int result                                 = 1;
4823
4824
0
  if( volume == NULL )
4825
0
  {
4826
0
    libcerror_error_set(
4827
0
     error,
4828
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4829
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4830
0
     "%s: invalid volume.",
4831
0
     function );
4832
4833
0
    return( -1 );
4834
0
  }
4835
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4836
4837
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4838
0
  if( libcthreads_read_write_lock_grab_for_write(
4839
0
       internal_volume->read_write_lock,
4840
0
       error ) != 1 )
4841
0
  {
4842
0
    libcerror_error_set(
4843
0
     error,
4844
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4845
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4846
0
     "%s: unable to grab read/write lock for writing.",
4847
0
     function );
4848
4849
0
    return( -1 );
4850
0
  }
4851
0
#endif
4852
0
  if( internal_volume->legacy_recovery_password != NULL )
4853
0
  {
4854
0
    if( memory_set(
4855
0
         internal_volume->legacy_recovery_password,
4856
0
         0,
4857
0
         internal_volume->legacy_recovery_password_size ) == NULL )
4858
0
    {
4859
0
      libcerror_error_set(
4860
0
       error,
4861
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4862
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
4863
0
       "%s: unable to clear recovery password.",
4864
0
       function );
4865
4866
0
      result = -1;
4867
0
    }
4868
0
    memory_free(
4869
0
     internal_volume->legacy_recovery_password );
4870
4871
0
    internal_volume->legacy_recovery_password      = NULL;
4872
0
    internal_volume->legacy_recovery_password_size = 0;
4873
0
  }
4874
0
  if( result == 1 )
4875
0
  {
4876
0
    if( libfvde_password_copy_from_utf8_string(
4877
0
         &( internal_volume->legacy_recovery_password ),
4878
0
         &( internal_volume->legacy_recovery_password_size ),
4879
0
         utf8_string,
4880
0
         utf8_string_length,
4881
0
         error ) != 1 )
4882
0
    {
4883
0
      libcerror_error_set(
4884
0
       error,
4885
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4886
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4887
0
       "%s: unable to set recovery password.",
4888
0
       function );
4889
4890
0
      result = -1;
4891
0
    }
4892
#if defined( HAVE_DEBUG_OUTPUT )
4893
    else if( libcnotify_verbose != 0 )
4894
    {
4895
      libcnotify_printf(
4896
       "%s: recovery password: %s\n",
4897
       function,
4898
       internal_volume->legacy_recovery_password );
4899
    }
4900
#endif
4901
0
  }
4902
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4903
0
  if( libcthreads_read_write_lock_release_for_write(
4904
0
       internal_volume->read_write_lock,
4905
0
       error ) != 1 )
4906
0
  {
4907
0
    libcerror_error_set(
4908
0
     error,
4909
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4910
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4911
0
     "%s: unable to release read/write lock for writing.",
4912
0
     function );
4913
4914
0
    return( -1 );
4915
0
  }
4916
0
#endif
4917
0
  return( result );
4918
0
}
4919
4920
/* Sets an UTF-16 formatted recovery password
4921
 * This function needs to be used before the unlock function
4922
 * Returns 1 if successful, 0 if recovery password is invalid or -1 on error
4923
 */
4924
int libfvde_volume_set_utf16_recovery_password(
4925
     libfvde_volume_t *volume,
4926
     const uint16_t *utf16_string,
4927
     size_t utf16_string_length,
4928
     libcerror_error_t **error )
4929
0
{
4930
0
  libfvde_internal_volume_t *internal_volume = NULL;
4931
0
  static char *function                      = "libfvde_volume_set_utf16_recovery_password";
4932
0
  int result                                 = 1;
4933
4934
0
  if( volume == NULL )
4935
0
  {
4936
0
    libcerror_error_set(
4937
0
     error,
4938
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4939
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4940
0
     "%s: invalid volume.",
4941
0
     function );
4942
4943
0
    return( -1 );
4944
0
  }
4945
0
  internal_volume = (libfvde_internal_volume_t *) volume;
4946
4947
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
4948
0
  if( libcthreads_read_write_lock_grab_for_write(
4949
0
       internal_volume->read_write_lock,
4950
0
       error ) != 1 )
4951
0
  {
4952
0
    libcerror_error_set(
4953
0
     error,
4954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4955
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4956
0
     "%s: unable to grab read/write lock for writing.",
4957
0
     function );
4958
4959
0
    return( -1 );
4960
0
  }
4961
0
#endif
4962
0
  if( internal_volume->legacy_recovery_password != NULL )
4963
0
  {
4964
0
    if( memory_set(
4965
0
         internal_volume->legacy_recovery_password,
4966
0
         0,
4967
0
         internal_volume->legacy_recovery_password_size ) == NULL )
4968
0
    {
4969
0
      libcerror_error_set(
4970
0
       error,
4971
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4972
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
4973
0
       "%s: unable to clear recovery password.",
4974
0
       function );
4975
4976
0
      result = -1;
4977
0
    }
4978
0
    memory_free(
4979
0
     internal_volume->legacy_recovery_password );
4980
4981
0
    internal_volume->legacy_recovery_password      = NULL;
4982
0
    internal_volume->legacy_recovery_password_size = 0;
4983
0
  }
4984
0
  if( result == 1 )
4985
0
  {
4986
0
    if( libfvde_password_copy_from_utf16_string(
4987
0
         &( internal_volume->legacy_recovery_password ),
4988
0
         &( internal_volume->legacy_recovery_password_size ),
4989
0
         utf16_string,
4990
0
         utf16_string_length,
4991
0
         error ) != 1 )
4992
0
    {
4993
0
      libcerror_error_set(
4994
0
       error,
4995
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4996
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4997
0
       "%s: unable to set recovery password.",
4998
0
       function );
4999
5000
0
      result = -1;
5001
0
    }
5002
#if defined( HAVE_DEBUG_OUTPUT )
5003
    else if( libcnotify_verbose != 0 )
5004
    {
5005
      libcnotify_printf(
5006
       "%s: recovery password: %s\n",
5007
       function,
5008
       internal_volume->legacy_recovery_password );
5009
    }
5010
#endif
5011
0
  }
5012
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
5013
0
  if( libcthreads_read_write_lock_release_for_write(
5014
0
       internal_volume->read_write_lock,
5015
0
       error ) != 1 )
5016
0
  {
5017
0
    libcerror_error_set(
5018
0
     error,
5019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5020
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5021
0
     "%s: unable to release read/write lock for writing.",
5022
0
     function );
5023
5024
0
    return( -1 );
5025
0
  }
5026
0
#endif
5027
0
  return( result );
5028
0
}
5029