Coverage Report

Created: 2025-06-13 07:22

/src/libfsxfs/libfsxfs/libfsxfs_directory.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Directory functions
3
 *
4
 * Copyright (C) 2020-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 <types.h>
25
26
#include "libfsxfs_block_directory.h"
27
#include "libfsxfs_definitions.h"
28
#include "libfsxfs_directory.h"
29
#include "libfsxfs_directory_entry.h"
30
#include "libfsxfs_directory_table.h"
31
#include "libfsxfs_extent.h"
32
#include "libfsxfs_inode.h"
33
#include "libfsxfs_io_handle.h"
34
#include "libfsxfs_libbfio.h"
35
#include "libfsxfs_libcdata.h"
36
#include "libfsxfs_libcerror.h"
37
#include "libfsxfs_libcnotify.h"
38
#include "libfsxfs_libuna.h"
39
40
/* Creates a directory
41
 * Make sure the value directory is referencing, is set to NULL
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libfsxfs_directory_initialize(
45
     libfsxfs_directory_t **directory,
46
     libcerror_error_t **error )
47
1.46k
{
48
1.46k
  static char *function = "libfsxfs_directory_initialize";
49
50
1.46k
  if( directory == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid directory.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
1.46k
  if( *directory != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid directory value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
1.46k
  *directory = memory_allocate_structure(
73
1.46k
                libfsxfs_directory_t );
74
75
1.46k
  if( *directory == NULL )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
80
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
81
0
     "%s: unable to create directory.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
1.46k
  if( memory_set(
87
1.46k
       *directory,
88
1.46k
       0,
89
1.46k
       sizeof( libfsxfs_directory_t ) ) == NULL )
90
0
  {
91
0
    libcerror_error_set(
92
0
     error,
93
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
94
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
95
0
     "%s: unable to clear directory.",
96
0
     function );
97
98
0
    memory_free(
99
0
     *directory );
100
101
0
    *directory = NULL;
102
103
0
    return( -1 );
104
0
  }
105
1.46k
  if( libcdata_array_initialize(
106
1.46k
       &( ( *directory )->entries_array ),
107
1.46k
       0,
108
1.46k
       error ) != 1 )
109
0
  {
110
0
    libcerror_error_set(
111
0
     error,
112
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
113
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
114
0
     "%s: unable to create entries array.",
115
0
     function );
116
117
0
    goto on_error;
118
0
  }
119
1.46k
  return( 1 );
120
121
0
on_error:
122
0
  if( *directory != NULL )
123
0
  {
124
0
    memory_free(
125
0
     *directory );
126
127
0
    *directory = NULL;
128
0
  }
129
0
  return( -1 );
130
1.46k
}
131
132
/* Frees a directory
133
 * Returns 1 if successful or -1 on error
134
 */
135
int libfsxfs_directory_free(
136
     libfsxfs_directory_t **directory,
137
     libcerror_error_t **error )
138
1.46k
{
139
1.46k
  static char *function = "libfsxfs_directory_free";
140
1.46k
  int result            = 1;
141
142
1.46k
  if( directory == NULL )
143
0
  {
144
0
    libcerror_error_set(
145
0
     error,
146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
148
0
     "%s: invalid directory.",
149
0
     function );
150
151
0
    return( -1 );
152
0
  }
153
1.46k
  if( *directory != NULL )
154
1.46k
  {
155
1.46k
    if( libcdata_array_free(
156
1.46k
         &( ( *directory )->entries_array ),
157
1.46k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_directory_entry_free,
158
1.46k
         error ) != 1 )
159
0
    {
160
0
      libcerror_error_set(
161
0
       error,
162
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
163
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
164
0
       "%s: unable to free entries array.",
165
0
       function );
166
167
0
      result = -1;
168
0
    }
169
1.46k
    memory_free(
170
1.46k
     *directory );
171
172
1.46k
    *directory = NULL;
173
1.46k
  }
174
1.46k
  return( result );
175
1.46k
}
176
177
/* Reads the directory entries
178
 * Returns 1 if successful or -1 on error
179
 */
180
int libfsxfs_directory_read_file_io_handle(
181
     libfsxfs_directory_t *directory,
182
     libfsxfs_io_handle_t *io_handle,
183
     libbfio_handle_t *file_io_handle,
184
     libfsxfs_inode_t *inode,
185
     libcerror_error_t **error )
186
1.46k
{
187
1.46k
  libfsxfs_block_directory_t *block_directory = NULL;
188
1.46k
  libfsxfs_directory_table_t *directory_table = NULL;
189
1.46k
  libfsxfs_extent_t *extent                   = NULL;
190
1.46k
  static char *function                       = "libfsxfs_directory_read_file_io_handle";
191
1.46k
  size64_t extent_size                        = 0;
192
1.46k
  off64_t block_directory_offset              = 0;
193
1.46k
  off64_t logical_offset                      = 0;
194
1.46k
  uint64_t relative_block_number              = 0;
195
1.46k
  int allocation_group_index                  = 0;
196
1.46k
  int extent_index                            = 0;
197
1.46k
  int number_of_extents                       = 0;
198
199
1.46k
  if( directory == NULL )
200
0
  {
201
0
    libcerror_error_set(
202
0
     error,
203
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
204
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
205
0
     "%s: invalid directory.",
206
0
     function );
207
208
0
    return( -1 );
209
0
  }
210
1.46k
  if( io_handle == NULL )
211
0
  {
212
0
    libcerror_error_set(
213
0
     error,
214
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
215
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
216
0
     "%s: invalid IO handle.",
217
0
     function );
218
219
0
    return( -1 );
220
0
  }
221
1.46k
  if( io_handle->allocation_group_size == 0 )
222
0
  {
223
0
    libcerror_error_set(
224
0
     error,
225
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
226
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
227
0
     "%s: invalid IO handle - allocation group size value out of bounds.",
228
0
     function );
229
230
0
    return( -1 );
231
0
  }
232
1.46k
  if( io_handle->block_size == 0 )
233
0
  {
234
0
    libcerror_error_set(
235
0
     error,
236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
237
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
238
0
     "%s: invalid IO handle - block size value out of bounds.",
239
0
     function );
240
241
0
    return( -1 );
242
0
  }
243
1.46k
  if( inode == NULL )
244
0
  {
245
0
    libcerror_error_set(
246
0
     error,
247
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
248
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
249
0
     "%s: invalid inode.",
250
0
     function );
251
252
0
    return( -1 );
253
0
  }
254
1.46k
  if( ( inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_DIRECTORY )
255
1.40k
  {
256
1.40k
    if( ( inode->fork_type != LIBFSXFS_FORK_TYPE_INLINE_DATA )
257
1.40k
     && ( inode->fork_type != LIBFSXFS_FORK_TYPE_EXTENTS )
258
1.40k
     && ( inode->fork_type != LIBFSXFS_FORK_TYPE_BTREE ) )
259
21
    {
260
21
      libcerror_error_set(
261
21
       error,
262
21
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
21
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
264
21
       "%s: unsupported directory data fork type.",
265
21
       function );
266
267
21
      goto on_error;
268
21
    }
269
1.38k
    if( inode->fork_type == LIBFSXFS_FORK_TYPE_INLINE_DATA )
270
597
    {
271
597
      if( libfsxfs_directory_table_initialize(
272
597
           &directory_table,
273
597
           error ) != 1 )
274
0
      {
275
0
        libcerror_error_set(
276
0
         error,
277
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
278
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
279
0
         "%s: unable to initialize directory table.",
280
0
         function );
281
282
0
        goto on_error;
283
0
      }
284
597
      if( libfsxfs_directory_table_read_data(
285
597
           directory_table,
286
597
           io_handle,
287
597
           inode->inline_data,
288
597
           (size_t) inode->size,
289
597
           directory->entries_array,
290
597
           error ) != 1 )
291
75
      {
292
75
        libcerror_error_set(
293
75
         error,
294
75
         LIBCERROR_ERROR_DOMAIN_IO,
295
75
         LIBCERROR_IO_ERROR_READ_FAILED,
296
75
         "%s: unable to read directory table.",
297
75
         function );
298
299
75
        goto on_error;
300
75
      }
301
522
      if( libfsxfs_directory_table_free(
302
522
           &directory_table,
303
522
           error ) != 1 )
304
0
      {
305
0
        libcerror_error_set(
306
0
         error,
307
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
308
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
309
0
         "%s: unable to free directory table.",
310
0
         function );
311
312
0
        goto on_error;
313
0
      }
314
522
    }
315
791
    else
316
791
    {
317
791
      if( libfsxfs_inode_get_number_of_data_extents(
318
791
           inode,
319
791
           &number_of_extents,
320
791
           error ) != 1 )
321
0
      {
322
0
        libcerror_error_set(
323
0
         error,
324
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
325
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
326
0
         "%s: unable to retrieve number of data extents.",
327
0
         function );
328
329
0
        goto on_error;
330
0
      }
331
791
      for( extent_index = 0;
332
4.67k
           extent_index < number_of_extents;
333
3.88k
           extent_index++ )
334
4.61k
      {
335
4.61k
        if( libfsxfs_inode_get_data_extent_by_index(
336
4.61k
             inode,
337
4.61k
             extent_index,
338
4.61k
             &extent,
339
4.61k
             error ) != 1 )
340
0
        {
341
0
          libcerror_error_set(
342
0
           error,
343
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
344
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
345
0
           "%s: unable to retrieve data extent: %d.",
346
0
           function,
347
0
           extent_index );
348
349
0
          goto on_error;
350
0
        }
351
4.61k
        if( extent == NULL )
352
0
        {
353
0
          libcerror_error_set(
354
0
           error,
355
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
356
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
357
0
           "%s: missing extent: %d.",
358
0
           function,
359
0
           extent_index );
360
361
0
          goto on_error;
362
0
        }
363
4.61k
        if( extent->logical_block_number > ( (uint64_t) INT64_MAX / io_handle->block_size ) )
364
113
        {
365
113
          libcerror_error_set(
366
113
           error,
367
113
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
368
113
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
369
113
           "%s: invalid extent: %d - logical block number value out of bounds.",
370
113
           function,
371
113
           extent_index );
372
373
113
          goto on_error;
374
113
        }
375
4.49k
        logical_offset = (off64_t) extent->logical_block_number * io_handle->block_size;
376
377
4.49k
        if( logical_offset >= (off64_t) LIBFSXFS_DIRECTORY_LEAF_OFFSET )
378
167
        {
379
167
          break;
380
167
        }
381
4.33k
        allocation_group_index = (int) ( extent->physical_block_number >> io_handle->number_of_relative_block_number_bits );
382
4.33k
        relative_block_number  = extent->physical_block_number & ( ( 1 << io_handle->number_of_relative_block_number_bits ) - 1 );
383
384
#if defined( HAVE_DEBUG_OUTPUT )
385
        if( libcnotify_verbose != 0 )
386
        {
387
          libcnotify_printf(
388
           "%s: extent: %d physical block number\t\t: %" PRIu64 "\n",
389
           function,
390
           extent_index,
391
           extent->physical_block_number );
392
393
          libcnotify_printf(
394
           "%s: extent: %d allocation group index\t: %d\n",
395
           function,
396
           extent_index,
397
           allocation_group_index );
398
399
          libcnotify_printf(
400
           "%s: extent: %d relative block number\t\t: %" PRIu64 "\n",
401
           function,
402
           extent_index,
403
           relative_block_number );
404
405
          libcnotify_printf(
406
           "\n" );
407
        }
408
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
409
410
4.33k
        block_directory_offset = ( ( (off64_t) allocation_group_index * io_handle->allocation_group_size ) + relative_block_number ) * io_handle->block_size;
411
4.33k
        extent_size            = (size64_t) extent->number_of_blocks * io_handle->block_size;
412
413
8.71k
        while( extent_size > 0 )
414
4.83k
        {
415
4.83k
          if( libfsxfs_block_directory_initialize(
416
4.83k
               &block_directory,
417
4.83k
               io_handle->block_size,
418
4.83k
               error ) != 1 )
419
0
          {
420
0
            libcerror_error_set(
421
0
             error,
422
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
423
0
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
424
0
             "%s: unable to initialize block directory.",
425
0
             function );
426
427
0
            goto on_error;
428
0
          }
429
4.83k
          if( libfsxfs_block_directory_read_file_io_handle(
430
4.83k
               block_directory,
431
4.83k
               io_handle,
432
4.83k
               file_io_handle,
433
4.83k
               block_directory_offset,
434
4.83k
               directory->entries_array,
435
4.83k
               error ) != 1 )
436
447
          {
437
447
            libcerror_error_set(
438
447
             error,
439
447
             LIBCERROR_ERROR_DOMAIN_IO,
440
447
             LIBCERROR_IO_ERROR_READ_FAILED,
441
447
             "%s: unable to read block directory.",
442
447
             function );
443
444
447
            goto on_error;
445
447
          }
446
4.38k
          block_directory_offset += io_handle->directory_block_size;
447
4.38k
          extent_size            -= io_handle->directory_block_size;
448
449
4.38k
          if( libfsxfs_block_directory_free(
450
4.38k
               &block_directory,
451
4.38k
               error ) != 1 )
452
0
          {
453
0
            libcerror_error_set(
454
0
             error,
455
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
456
0
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
457
0
             "%s: unable to free block directory.",
458
0
             function );
459
460
0
            goto on_error;
461
0
          }
462
4.38k
        }
463
4.33k
      }
464
791
    }
465
1.38k
  }
466
811
  return( 1 );
467
468
656
on_error:
469
656
  if( block_directory != NULL )
470
447
  {
471
447
    libfsxfs_block_directory_free(
472
447
     &block_directory,
473
447
     NULL );
474
447
  }
475
656
  if( directory_table != NULL )
476
75
  {
477
75
    libfsxfs_directory_table_free(
478
75
     &directory_table,
479
75
     NULL );
480
75
  }
481
656
  libcdata_array_empty(
482
656
   directory->entries_array,
483
656
   (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_directory_entry_free,
484
656
   NULL );
485
486
656
  return( -1 );
487
1.46k
}
488
489
/* Retrieves the number of entries
490
 * Returns 1 if successful or -1 on error
491
 */
492
int libfsxfs_directory_get_number_of_entries(
493
     libfsxfs_directory_t *directory,
494
     int *number_of_entries,
495
     libcerror_error_t **error )
496
509
{
497
509
  static char *function = "libfsxfs_directory_get_number_of_entries";
498
499
509
  if( directory == NULL )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
504
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
505
0
     "%s: invalid directory.",
506
0
     function );
507
508
0
    return( -1 );
509
0
  }
510
509
  if( libcdata_array_get_number_of_entries(
511
509
       directory->entries_array,
512
509
       number_of_entries,
513
509
       error ) != 1 )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
518
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
519
0
     "%s: unable to retrieve number of entries.",
520
0
     function );
521
522
0
    return( -1 );
523
0
  }
524
509
  return( 1 );
525
509
}
526
527
/* Retrieves a specific entry
528
 * Returns 1 if successful or -1 on error
529
 */
530
int libfsxfs_directory_get_entry_by_index(
531
     libfsxfs_directory_t *directory,
532
     int entry_index,
533
     libfsxfs_directory_entry_t **directory_entry,
534
     libcerror_error_t **error )
535
462
{
536
462
  static char *function = "libfsxfs_directory_get_entry_by_index";
537
538
462
  if( directory == NULL )
539
0
  {
540
0
    libcerror_error_set(
541
0
     error,
542
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
543
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
544
0
     "%s: invalid directory.",
545
0
     function );
546
547
0
    return( -1 );
548
0
  }
549
462
  if( libcdata_array_get_entry_by_index(
550
462
       directory->entries_array,
551
462
       entry_index,
552
462
       (intptr_t **) directory_entry,
553
462
       error ) != 1 )
554
0
  {
555
0
    libcerror_error_set(
556
0
     error,
557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
558
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
559
0
     "%s: unable to retrieve entry: %d.",
560
0
     function,
561
0
     entry_index );
562
563
0
    return( -1 );
564
0
  }
565
462
  return( 1 );
566
462
}
567
568
/* Retrieves the directory entry for an UTF-8 encoded name
569
 * Returns 1 if successful, 0 if not found or -1 on error
570
 */
571
int libfsxfs_directory_get_entry_by_utf8_name(
572
     libfsxfs_directory_t *directory,
573
     const uint8_t *utf8_string,
574
     size_t utf8_string_length,
575
     libfsxfs_directory_entry_t **directory_entry,
576
     libcerror_error_t **error )
577
302
{
578
302
  libfsxfs_directory_entry_t *safe_directory_entry = NULL;
579
302
  static char *function                            = "libfsxfs_directory_get_entry_by_utf8_name";
580
302
  int entry_index                                  = 0;
581
302
  int number_of_entries                            = 0;
582
302
  int result                                       = 0;
583
584
302
  if( directory == NULL )
585
0
  {
586
0
    libcerror_error_set(
587
0
     error,
588
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
589
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
590
0
     "%s: invalid directory.",
591
0
     function );
592
593
0
    return( -1 );
594
0
  }
595
302
  if( libcdata_array_get_number_of_entries(
596
302
       directory->entries_array,
597
302
       &number_of_entries,
598
302
       error ) != 1 )
599
0
  {
600
0
    libcerror_error_set(
601
0
     error,
602
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
603
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
604
0
     "%s: unable to retrieve number of entries.",
605
0
     function );
606
607
0
    return( -1 );
608
0
  }
609
302
  for( entry_index = 0;
610
8.22k
       entry_index < number_of_entries;
611
7.92k
       entry_index++ )
612
8.05k
  {
613
8.05k
    if( libcdata_array_get_entry_by_index(
614
8.05k
         directory->entries_array,
615
8.05k
         entry_index,
616
8.05k
         (intptr_t **) &safe_directory_entry,
617
8.05k
         error ) != 1 )
618
0
    {
619
0
      libcerror_error_set(
620
0
       error,
621
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
622
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
623
0
       "%s: unable to retrieve entry: %d.",
624
0
       function,
625
0
       entry_index );
626
627
0
      return( -1 );
628
0
    }
629
8.05k
    result = libfsxfs_directory_entry_compare_with_utf8_string(
630
8.05k
              safe_directory_entry,
631
8.05k
              utf8_string,
632
8.05k
              utf8_string_length,
633
8.05k
              error );
634
635
8.05k
    if( result == -1 )
636
99
    {
637
99
      libcerror_error_set(
638
99
       error,
639
99
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
640
99
       LIBCERROR_RUNTIME_ERROR_GENERIC,
641
99
       "%s: unable to compare UTF-8 string with directory entry: %d.",
642
99
       function,
643
99
       entry_index );
644
645
99
      return( -1 );
646
99
    }
647
7.95k
    else if( result == LIBUNA_COMPARE_EQUAL )
648
37
    {
649
37
      *directory_entry = safe_directory_entry;
650
651
37
      return( 1 );
652
37
    }
653
8.05k
  }
654
166
  *directory_entry = NULL;
655
656
166
  return( 0 );
657
302
}
658
659
/* Retrieves the directory entry for an UTF-16 encoded name
660
 * Returns 1 if successful, 0 if not found or -1 on error
661
 */
662
int libfsxfs_directory_get_entry_by_utf16_name(
663
     libfsxfs_directory_t *directory,
664
     const uint16_t *utf16_string,
665
     size_t utf16_string_length,
666
     libfsxfs_directory_entry_t **directory_entry,
667
     libcerror_error_t **error )
668
0
{
669
0
  libfsxfs_directory_entry_t *safe_directory_entry = NULL;
670
0
  static char *function                            = "libfsxfs_directory_get_entry_by_utf16_name";
671
0
  int entry_index                                  = 0;
672
0
  int number_of_entries                            = 0;
673
0
  int result                                       = 0;
674
675
0
  if( directory == NULL )
676
0
  {
677
0
    libcerror_error_set(
678
0
     error,
679
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
680
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
681
0
     "%s: invalid directory.",
682
0
     function );
683
684
0
    return( -1 );
685
0
  }
686
0
  if( libcdata_array_get_number_of_entries(
687
0
       directory->entries_array,
688
0
       &number_of_entries,
689
0
       error ) != 1 )
690
0
  {
691
0
    libcerror_error_set(
692
0
     error,
693
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
694
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
695
0
     "%s: unable to retrieve number of entries.",
696
0
     function );
697
698
0
    return( -1 );
699
0
  }
700
0
  for( entry_index = 0;
701
0
       entry_index < number_of_entries;
702
0
       entry_index++ )
703
0
  {
704
0
    if( libcdata_array_get_entry_by_index(
705
0
         directory->entries_array,
706
0
         entry_index,
707
0
         (intptr_t **) &safe_directory_entry,
708
0
         error ) != 1 )
709
0
    {
710
0
      libcerror_error_set(
711
0
       error,
712
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
713
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
714
0
       "%s: unable to retrieve entry: %d.",
715
0
       function,
716
0
       entry_index );
717
718
0
      return( -1 );
719
0
    }
720
0
    result = libfsxfs_directory_entry_compare_with_utf16_string(
721
0
              safe_directory_entry,
722
0
              utf16_string,
723
0
              utf16_string_length,
724
0
              error );
725
726
0
    if( result == -1 )
727
0
    {
728
0
      libcerror_error_set(
729
0
       error,
730
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
731
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
732
0
       "%s: unable to compare UTF-16 string with directory entry: %d.",
733
0
       function,
734
0
       entry_index );
735
736
0
      return( -1 );
737
0
    }
738
0
    else if( result == LIBUNA_COMPARE_EQUAL )
739
0
    {
740
0
      *directory_entry = safe_directory_entry;
741
742
0
      return( 1 );
743
0
    }
744
0
  }
745
0
  *directory_entry = NULL;
746
747
0
  return( 0 );
748
0
}
749