Coverage Report

Created: 2024-02-25 07:20

/src/libfsxfs/libfsxfs/libfsxfs_directory_entry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Directory entry 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_directory_entry.h"
27
#include "libfsxfs_libcerror.h"
28
#include "libfsxfs_libuna.h"
29
30
/* Creates directory entry
31
 * Make sure the value directory_entry is referencing, is set to NULL
32
 * Returns 1 if successful or -1 on error
33
 */
34
int libfsxfs_directory_entry_initialize(
35
     libfsxfs_directory_entry_t **directory_entry,
36
     libcerror_error_t **error )
37
176k
{
38
176k
  static char *function = "libfsxfs_directory_entry_initialize";
39
40
176k
  if( directory_entry == NULL )
41
0
  {
42
0
    libcerror_error_set(
43
0
     error,
44
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
45
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
46
0
     "%s: invalid directory entry.",
47
0
     function );
48
49
0
    return( -1 );
50
0
  }
51
176k
  if( *directory_entry != NULL )
52
0
  {
53
0
    libcerror_error_set(
54
0
     error,
55
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
56
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
57
0
     "%s: invalid directory entry value already set.",
58
0
     function );
59
60
0
    return( -1 );
61
0
  }
62
176k
  *directory_entry = memory_allocate_structure(
63
176k
                      libfsxfs_directory_entry_t );
64
65
176k
  if( *directory_entry == NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
70
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
71
0
     "%s: unable to create directory entry.",
72
0
     function );
73
74
0
    goto on_error;
75
0
  }
76
176k
  if( memory_set(
77
176k
       *directory_entry,
78
176k
       0,
79
176k
       sizeof( libfsxfs_directory_entry_t ) ) == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
85
0
     "%s: unable to clear directory entry.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
176k
  return( 1 );
91
92
0
on_error:
93
0
  if( *directory_entry != NULL )
94
0
  {
95
0
    memory_free(
96
0
     *directory_entry );
97
98
0
    *directory_entry = NULL;
99
0
  }
100
0
  return( -1 );
101
176k
}
102
103
/* Frees directory entry
104
 * Returns 1 if successful or -1 on error
105
 */
106
int libfsxfs_directory_entry_free(
107
     libfsxfs_directory_entry_t **directory_entry,
108
     libcerror_error_t **error )
109
176k
{
110
176k
  static char *function = "libfsxfs_directory_entry_free";
111
112
176k
  if( directory_entry == NULL )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
117
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
118
0
     "%s: invalid directory entry.",
119
0
     function );
120
121
0
    return( -1 );
122
0
  }
123
176k
  if( *directory_entry != NULL )
124
176k
  {
125
176k
    memory_free(
126
176k
     *directory_entry );
127
128
176k
    *directory_entry = NULL;
129
176k
  }
130
176k
  return( 1 );
131
176k
}
132
133
/* Clones the directory entry value
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libfsxfs_directory_entry_clone(
137
     libfsxfs_directory_entry_t **destination_directory_entry,
138
     libfsxfs_directory_entry_t *source_directory_entry,
139
     libcerror_error_t **error )
140
438
{
141
438
  static char *function = "libfsxfs_directory_entry_clone";
142
143
438
  if( destination_directory_entry == NULL )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
148
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
149
0
     "%s: invalid destination directory entry.",
150
0
     function );
151
152
0
    return( -1 );
153
0
  }
154
438
  if( *destination_directory_entry != NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
159
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
160
0
     "%s: invalid destination directory entry value already set.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
438
  if( source_directory_entry == NULL )
166
0
  {
167
0
    *destination_directory_entry = NULL;
168
169
0
    return( 1 );
170
0
  }
171
438
  *destination_directory_entry = memory_allocate_structure(
172
438
                                  libfsxfs_directory_entry_t );
173
174
438
  if( *destination_directory_entry == NULL )
175
0
  {
176
0
    libcerror_error_set(
177
0
     error,
178
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
179
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
180
0
     "%s: unable to create destination directory entry.",
181
0
     function );
182
183
0
    goto on_error;
184
0
  }
185
438
  if( memory_copy(
186
438
       *destination_directory_entry,
187
438
       source_directory_entry,
188
438
       sizeof( libfsxfs_directory_entry_t ) ) == NULL )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
193
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
194
0
     "%s: unable to copy source to destination directory entry.",
195
0
     function );
196
197
0
    goto on_error;
198
0
  }
199
438
  return( 1 );
200
201
0
on_error:
202
0
  if( *destination_directory_entry != NULL )
203
0
  {
204
0
    memory_free(
205
0
     *destination_directory_entry );
206
207
0
    *destination_directory_entry = NULL;
208
0
  }
209
0
  return( -1 );
210
438
}
211
212
/* Retrieves the inode number
213
 * Returns 1 if successful or -1 on error
214
 */
215
int libfsxfs_directory_entry_get_inode_number(
216
     libfsxfs_directory_entry_t *directory_entry,
217
     uint64_t *inode_number,
218
     libcerror_error_t **error )
219
31
{
220
31
  static char *function = "libfsxfs_directory_entry_get_inode_number";
221
222
31
  if( directory_entry == NULL )
223
0
  {
224
0
    libcerror_error_set(
225
0
     error,
226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
227
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
228
0
     "%s: invalid directory entry.",
229
0
     function );
230
231
0
    return( -1 );
232
0
  }
233
31
  if( inode_number == NULL )
234
0
  {
235
0
    libcerror_error_set(
236
0
     error,
237
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
239
0
     "%s: invalid inode number.",
240
0
     function );
241
242
0
    return( -1 );
243
0
  }
244
31
  *inode_number = directory_entry->inode_number;
245
246
31
  return( 1 );
247
31
}
248
249
/* Retrieves the size of the UTF-8 encoded name
250
 * The returned size includes the end of string character
251
 * Returns 1 if successful or -1 on error
252
 */
253
int libfsxfs_directory_entry_get_utf8_name_size(
254
     libfsxfs_directory_entry_t *directory_entry,
255
     size_t *utf8_string_size,
256
     libcerror_error_t **error )
257
388
{
258
388
  static char *function = "libfsxfs_directory_entry_get_utf8_name_size";
259
260
388
  if( directory_entry == NULL )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
265
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
266
0
     "%s: invalid directory entry.",
267
0
     function );
268
269
0
    return( -1 );
270
0
  }
271
388
  if( libuna_utf8_string_size_from_utf8_stream(
272
388
       directory_entry->name,
273
388
       (size_t) directory_entry->name_size,
274
388
       utf8_string_size,
275
388
       error ) != 1 )
276
308
  {
277
308
    libcerror_error_set(
278
308
     error,
279
308
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
280
308
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
281
308
     "%s: unable to retrieve UTF-8 string size.",
282
308
     function );
283
284
308
    return( -1 );
285
308
  }
286
80
  return( 1 );
287
388
}
288
289
/* Retrieves the UTF-8 encoded name
290
 * The size should include the end of string character
291
 * Returns 1 if successful or -1 on error
292
 */
293
int libfsxfs_directory_entry_get_utf8_name(
294
     libfsxfs_directory_entry_t *directory_entry,
295
     uint8_t *utf8_string,
296
     size_t utf8_string_size,
297
     libcerror_error_t **error )
298
388
{
299
388
  static char *function = "libfsxfs_directory_entry_get_utf8_name";
300
301
388
  if( directory_entry == NULL )
302
0
  {
303
0
    libcerror_error_set(
304
0
     error,
305
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
306
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
307
0
     "%s: invalid directory entry.",
308
0
     function );
309
310
0
    return( -1 );
311
0
  }
312
388
  if( libuna_utf8_string_copy_from_utf8_stream(
313
388
       utf8_string,
314
388
       utf8_string_size,
315
388
       directory_entry->name,
316
388
       (size_t) directory_entry->name_size,
317
388
       error ) != 1 )
318
325
  {
319
325
    libcerror_error_set(
320
325
     error,
321
325
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
322
325
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
323
325
     "%s: unable to retrieve UTF-8 string.",
324
325
     function );
325
326
325
    return( -1 );
327
325
  }
328
63
  return( 1 );
329
388
}
330
331
/* Compares an UTF-8 string with the name of the directory entry
332
 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
333
 */
334
int libfsxfs_directory_entry_compare_with_utf8_string(
335
     libfsxfs_directory_entry_t *directory_entry,
336
     const uint8_t *utf8_string,
337
     size_t utf8_string_length,
338
     libcerror_error_t **error )
339
6.09k
{
340
6.09k
  static char *function = "libfsxfs_directory_entry_compare_with_utf8_string";
341
6.09k
  int result            = 0;
342
343
6.09k
  if( directory_entry == NULL )
344
0
  {
345
0
    libcerror_error_set(
346
0
     error,
347
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349
0
     "%s: invalid directory entry.",
350
0
     function );
351
352
0
    return( -1 );
353
0
  }
354
6.09k
  result = libuna_utf8_string_compare_with_utf8_stream(
355
6.09k
            utf8_string,
356
6.09k
            utf8_string_length,
357
6.09k
            directory_entry->name,
358
6.09k
            directory_entry->name_size,
359
6.09k
            error );
360
361
6.09k
  if( result == -1 )
362
131
  {
363
131
    libcerror_error_set(
364
131
     error,
365
131
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
366
131
     LIBCERROR_RUNTIME_ERROR_GENERIC,
367
131
     "%s: unable to compare UTF-8 string with directory entry name.",
368
131
     function );
369
370
131
    return( -1 );
371
131
  }
372
5.96k
  return( result );
373
6.09k
}
374
375
/* Retrieves the size of the UTF-16 encoded name
376
 * The returned size includes the end of string character
377
 * Returns 1 if successful or -1 on error
378
 */
379
int libfsxfs_directory_entry_get_utf16_name_size(
380
     libfsxfs_directory_entry_t *directory_entry,
381
     size_t *utf16_string_size,
382
     libcerror_error_t **error )
383
0
{
384
0
  static char *function = "libfsxfs_directory_entry_get_utf16_name_size";
385
386
0
  if( directory_entry == NULL )
387
0
  {
388
0
    libcerror_error_set(
389
0
     error,
390
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
391
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
392
0
     "%s: invalid directory entry.",
393
0
     function );
394
395
0
    return( -1 );
396
0
  }
397
0
  if( libuna_utf16_string_size_from_utf8_stream(
398
0
       directory_entry->name,
399
0
       (size_t) directory_entry->name_size,
400
0
       utf16_string_size,
401
0
       error ) != 1 )
402
0
  {
403
0
    libcerror_error_set(
404
0
     error,
405
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
406
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
407
0
     "%s: unable to retrieve UTF-16 string size.",
408
0
     function );
409
410
0
    return( -1 );
411
0
  }
412
0
  return( 1 );
413
0
}
414
415
/* Retrieves the UTF-16 encoded name
416
 * The size should include the end of string character
417
 * Returns 1 if successful or -1 on error
418
 */
419
int libfsxfs_directory_entry_get_utf16_name(
420
     libfsxfs_directory_entry_t *directory_entry,
421
     uint16_t *utf16_string,
422
     size_t utf16_string_size,
423
     libcerror_error_t **error )
424
0
{
425
0
  static char *function = "libfsxfs_directory_entry_get_utf16_name";
426
427
0
  if( directory_entry == NULL )
428
0
  {
429
0
    libcerror_error_set(
430
0
     error,
431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
433
0
     "%s: invalid directory entry.",
434
0
     function );
435
436
0
    return( -1 );
437
0
  }
438
0
  if( libuna_utf16_string_copy_from_utf8_stream(
439
0
       utf16_string,
440
0
       utf16_string_size,
441
0
       directory_entry->name,
442
0
       (size_t) directory_entry->name_size,
443
0
       error ) != 1 )
444
0
  {
445
0
    libcerror_error_set(
446
0
     error,
447
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
448
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
449
0
     "%s: unable to retrieve UTF-16 string.",
450
0
     function );
451
452
0
    return( -1 );
453
0
  }
454
0
  return( 1 );
455
0
}
456
457
/* Compares an UTF-16 string with the name of the directory entry
458
 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
459
 */
460
int libfsxfs_directory_entry_compare_with_utf16_string(
461
     libfsxfs_directory_entry_t *directory_entry,
462
     const uint16_t *utf16_string,
463
     size_t utf16_string_length,
464
     libcerror_error_t **error )
465
0
{
466
0
  static char *function = "libfsxfs_directory_entry_compare_with_utf16_string";
467
0
  int result            = 0;
468
469
0
  if( directory_entry == NULL )
470
0
  {
471
0
    libcerror_error_set(
472
0
     error,
473
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
474
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
475
0
     "%s: invalid directory entry.",
476
0
     function );
477
478
0
    return( -1 );
479
0
  }
480
0
  result = libuna_utf16_string_compare_with_utf8_stream(
481
0
            utf16_string,
482
0
            utf16_string_length,
483
0
            directory_entry->name,
484
0
            directory_entry->name_size,
485
0
            error );
486
487
0
  if( result == -1 )
488
0
  {
489
0
    libcerror_error_set(
490
0
     error,
491
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
492
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
493
0
     "%s: unable to compare UTF-16 string with directory entry name.",
494
0
     function );
495
496
0
    return( -1 );
497
0
  }
498
0
  return( result );
499
0
}
500