Coverage Report

Created: 2024-02-25 07:20

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