Coverage Report

Created: 2024-06-12 07:07

/src/libfsapfs/libfsapfs/libfsapfs_inode.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Inode functions
3
 *
4
 * Copyright (C) 2018-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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfsapfs_debug.h"
28
#include "libfsapfs_definitions.h"
29
#include "libfsapfs_inode.h"
30
#include "libfsapfs_libcerror.h"
31
#include "libfsapfs_libcnotify.h"
32
#include "libfsapfs_libfdatetime.h"
33
#include "libfsapfs_libuna.h"
34
35
#include "fsapfs_file_system.h"
36
37
/* Creates a inode
38
 * Make sure the value inode is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libfsapfs_inode_initialize(
42
     libfsapfs_inode_t **inode,
43
     libcerror_error_t **error )
44
1.70k
{
45
1.70k
  static char *function = "libfsapfs_inode_initialize";
46
47
1.70k
  if( inode == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid inode.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
1.70k
  if( *inode != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid inode value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
1.70k
  *inode = memory_allocate_structure(
70
1.70k
            libfsapfs_inode_t );
71
72
1.70k
  if( *inode == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create inode.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
1.70k
  if( memory_set(
84
1.70k
       *inode,
85
1.70k
       0,
86
1.70k
       sizeof( libfsapfs_inode_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear inode.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
1.70k
  return( 1 );
98
99
0
on_error:
100
0
  if( *inode != NULL )
101
0
  {
102
0
    memory_free(
103
0
     *inode );
104
105
0
    *inode = NULL;
106
0
  }
107
0
  return( -1 );
108
1.70k
}
109
110
/* Frees a inode
111
 * Returns 1 if successful or -1 on error
112
 */
113
int libfsapfs_inode_free(
114
     libfsapfs_inode_t **inode,
115
     libcerror_error_t **error )
116
1.70k
{
117
1.70k
  static char *function = "libfsapfs_inode_free";
118
119
1.70k
  if( inode == NULL )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125
0
     "%s: invalid inode.",
126
0
     function );
127
128
0
    return( -1 );
129
0
  }
130
1.70k
  if( *inode != NULL )
131
1.70k
  {
132
1.70k
    if( ( *inode )->name != NULL )
133
308
    {
134
308
      memory_free(
135
308
       ( *inode )->name );
136
308
    }
137
1.70k
    memory_free(
138
1.70k
     *inode );
139
140
1.70k
    *inode = NULL;
141
1.70k
  }
142
1.70k
  return( 1 );
143
1.70k
}
144
145
/* Reads the inode key data
146
 * Returns 1 if successful or -1 on error
147
 */
148
int libfsapfs_inode_read_key_data(
149
     libfsapfs_inode_t *inode,
150
     const uint8_t *data,
151
     size_t data_size,
152
     libcerror_error_t **error )
153
1.70k
{
154
1.70k
  static char *function = "libfsapfs_inode_read_key_data";
155
156
1.70k
  if( inode == NULL )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
161
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
162
0
     "%s: invalid inode.",
163
0
     function );
164
165
0
    return( -1 );
166
0
  }
167
1.70k
  if( data == NULL )
168
0
  {
169
0
    libcerror_error_set(
170
0
     error,
171
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
172
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
173
0
     "%s: invalid data.",
174
0
     function );
175
176
0
    return( -1 );
177
0
  }
178
1.70k
  if( ( data_size < sizeof( fsapfs_file_system_btree_key_common_t ) )
179
1.70k
   || ( data_size > (size_t) SSIZE_MAX ) )
180
0
  {
181
0
    libcerror_error_set(
182
0
     error,
183
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
184
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
185
0
     "%s: invalid data size value out of bounds.",
186
0
     function );
187
188
0
    return( -1 );
189
0
  }
190
#if defined( HAVE_DEBUG_OUTPUT )
191
  if( libcnotify_verbose != 0 )
192
  {
193
    libcnotify_printf(
194
     "%s: inode key data:\n",
195
     function );
196
    libcnotify_print_data(
197
     data,
198
     data_size,
199
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
200
  }
201
#endif
202
1.70k
  byte_stream_copy_to_uint64_little_endian(
203
1.70k
   ( (fsapfs_file_system_btree_key_common_t *) data )->file_system_identifier,
204
1.70k
   inode->identifier );
205
206
#if defined( HAVE_DEBUG_OUTPUT )
207
  if( libcnotify_verbose != 0 )
208
  {
209
    libcnotify_printf(
210
     "%s: identifier\t\t\t\t: 0x%08" PRIx64 "\n",
211
     function,
212
     inode->identifier );
213
214
    libcnotify_printf(
215
     "\n" );
216
  }
217
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
218
219
1.70k
  inode->identifier &= (uint64_t) 0x0fffffffffffffffUL;
220
221
1.70k
  return( 1 );
222
1.70k
}
223
224
/* Reads the inode value data
225
 * Returns 1 if successful or -1 on error
226
 */
227
int libfsapfs_inode_read_value_data(
228
     libfsapfs_inode_t *inode,
229
     const uint8_t *data,
230
     size_t data_size,
231
     libcerror_error_t **error )
232
1.70k
{
233
1.70k
  const uint8_t *value_data          = NULL;
234
1.70k
  static char *function              = "libfsapfs_inode_read_value_data";
235
1.70k
  size_t data_offset                 = 0;
236
1.70k
  size_t trailing_data_size          = 0;
237
1.70k
  size_t value_data_offset           = 0;
238
1.70k
  uint16_t extended_field_index      = 0;
239
1.70k
  uint16_t number_of_extended_fields = 0;
240
1.70k
  uint16_t value_data_size           = 0;
241
1.70k
  uint8_t extended_field_flags       = 0;
242
1.70k
  uint8_t extended_field_type        = 0;
243
244
#if defined( HAVE_DEBUG_OUTPUT )
245
  uint64_t value_64bit               = 0;
246
  uint32_t value_32bit               = 0;
247
  uint16_t value_16bit               = 0;
248
#endif
249
250
1.70k
  if( inode == NULL )
251
0
  {
252
0
    libcerror_error_set(
253
0
     error,
254
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
255
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
256
0
     "%s: invalid inode.",
257
0
     function );
258
259
0
    return( -1 );
260
0
  }
261
1.70k
  if( inode->name != NULL )
262
0
  {
263
0
    libcerror_error_set(
264
0
     error,
265
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
266
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
267
0
     "%s: invalid inode - name value already set.",
268
0
     function );
269
270
0
    return( -1 );
271
0
  }
272
1.70k
  if( data == NULL )
273
13
  {
274
13
    libcerror_error_set(
275
13
     error,
276
13
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
277
13
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
278
13
     "%s: invalid data.",
279
13
     function );
280
281
13
    return( -1 );
282
13
  }
283
1.69k
  if( ( data_size < sizeof( fsapfs_file_system_btree_value_inode_t ) )
284
1.69k
   || ( data_size > (size_t) SSIZE_MAX ) )
285
22
  {
286
22
    libcerror_error_set(
287
22
     error,
288
22
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
289
22
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
290
22
     "%s: invalid data size value out of bounds.",
291
22
     function );
292
293
22
    return( -1 );
294
22
  }
295
#if defined( HAVE_DEBUG_OUTPUT )
296
  if( libcnotify_verbose != 0 )
297
  {
298
    libcnotify_printf(
299
     "%s: inode value data:\n",
300
     function );
301
    libcnotify_print_data(
302
     data,
303
     data_size,
304
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
305
  }
306
#endif
307
1.66k
  byte_stream_copy_to_uint64_little_endian(
308
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->parent_identifier,
309
1.66k
   inode->parent_identifier );
310
311
1.66k
  byte_stream_copy_to_uint64_little_endian(
312
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->data_stream_identifier,
313
1.66k
   inode->data_stream_identifier );
314
315
1.66k
  byte_stream_copy_to_uint64_little_endian(
316
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->modification_time,
317
1.66k
   inode->modification_time );
318
319
1.66k
  byte_stream_copy_to_uint64_little_endian(
320
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->creation_time,
321
1.66k
   inode->creation_time );
322
323
1.66k
  byte_stream_copy_to_uint64_little_endian(
324
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->inode_change_time,
325
1.66k
   inode->inode_change_time );
326
327
1.66k
  byte_stream_copy_to_uint64_little_endian(
328
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->access_time,
329
1.66k
   inode->access_time );
330
331
1.66k
  byte_stream_copy_to_uint64_little_endian(
332
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->inode_flags,
333
1.66k
   inode->flags );
334
335
1.66k
  byte_stream_copy_to_uint32_little_endian(
336
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->number_of_links,
337
1.66k
   inode->number_of_links );
338
339
1.66k
  byte_stream_copy_to_uint32_little_endian(
340
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->owner_identifier,
341
1.66k
   inode->owner_identifier );
342
343
1.66k
  byte_stream_copy_to_uint32_little_endian(
344
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->group_identifier,
345
1.66k
   inode->group_identifier );
346
347
1.66k
  byte_stream_copy_to_uint16_little_endian(
348
1.66k
   ( (fsapfs_file_system_btree_value_inode_t *) data )->file_mode,
349
1.66k
   inode->file_mode );
350
351
#if defined( HAVE_DEBUG_OUTPUT )
352
  if( libcnotify_verbose != 0 )
353
  {
354
    libcnotify_printf(
355
     "%s: parent identifier\t\t\t: %" PRIu64 "\n",
356
     function,
357
     inode->parent_identifier );
358
359
    libcnotify_printf(
360
     "%s: data stream identifier\t\t\t: %" PRIu64 "\n",
361
     function,
362
     inode->data_stream_identifier );
363
364
    if( libfsapfs_debug_print_posix_time_value(
365
         function,
366
         "modification time\t\t\t",
367
         ( (fsapfs_file_system_btree_value_inode_t *) data )->modification_time,
368
         8,
369
         LIBFDATETIME_ENDIAN_LITTLE,
370
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
371
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
372
         error ) != 1 )
373
    {
374
      libcerror_error_set(
375
       error,
376
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
377
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
378
       "%s: unable to print POSIX time value.",
379
       function );
380
381
      goto on_error;
382
    }
383
    if( libfsapfs_debug_print_posix_time_value(
384
         function,
385
         "creation time\t\t\t\t",
386
         ( (fsapfs_file_system_btree_value_inode_t *) data )->creation_time,
387
         8,
388
         LIBFDATETIME_ENDIAN_LITTLE,
389
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
390
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
391
         error ) != 1 )
392
    {
393
      libcerror_error_set(
394
       error,
395
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
396
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
397
       "%s: unable to print POSIX time value.",
398
       function );
399
400
      goto on_error;
401
    }
402
    if( libfsapfs_debug_print_posix_time_value(
403
         function,
404
         "inode change time\t\t\t",
405
         ( (fsapfs_file_system_btree_value_inode_t *) data )->inode_change_time,
406
         8,
407
         LIBFDATETIME_ENDIAN_LITTLE,
408
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
409
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
410
         error ) != 1 )
411
    {
412
      libcerror_error_set(
413
       error,
414
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
415
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
416
       "%s: unable to print POSIX time value.",
417
       function );
418
419
      goto on_error;
420
    }
421
    if( libfsapfs_debug_print_posix_time_value(
422
         function,
423
         "access time\t\t\t\t",
424
         ( (fsapfs_file_system_btree_value_inode_t *) data )->access_time,
425
         8,
426
         LIBFDATETIME_ENDIAN_LITTLE,
427
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
428
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
429
         error ) != 1 )
430
    {
431
      libcerror_error_set(
432
       error,
433
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
434
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
435
       "%s: unable to print POSIX time value.",
436
       function );
437
438
      goto on_error;
439
    }
440
    libcnotify_printf(
441
     "%s: inode flags\t\t\t\t: 0x%08" PRIx64 "\n",
442
     function,
443
     inode->flags );
444
    libfsapfs_debug_print_inode_flags(
445
     inode->flags );
446
    libcnotify_printf(
447
     "\n" );
448
449
    if( ( inode->file_mode & 0xf000 ) == LIBFSAPFS_FILE_TYPE_DIRECTORY )
450
    {
451
      libcnotify_printf(
452
       "%s: number of children\t\t\t: %" PRIu32 "\n",
453
       function,
454
       inode->number_of_links );
455
    }
456
    else
457
    {
458
      libcnotify_printf(
459
       "%s: number of links\t\t\t: %" PRIu32 "\n",
460
       function,
461
       inode->number_of_links );
462
    }
463
    byte_stream_copy_to_uint32_little_endian(
464
     ( (fsapfs_file_system_btree_value_inode_t *) data )->unknown1,
465
     value_32bit );
466
    libcnotify_printf(
467
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
468
     function,
469
     value_32bit );
470
471
    byte_stream_copy_to_uint32_little_endian(
472
     ( (fsapfs_file_system_btree_value_inode_t *) data )->unknown2,
473
     value_32bit );
474
    libcnotify_printf(
475
     "%s: unknown2\t\t\t\t: 0x%08" PRIx32 "\n",
476
     function,
477
     value_32bit );
478
479
    byte_stream_copy_to_uint32_little_endian(
480
     ( (fsapfs_file_system_btree_value_inode_t *) data )->bsd_flags,
481
     value_32bit );
482
    libcnotify_printf(
483
     "%s: BSD flags\t\t\t\t: 0x%08" PRIx32 "\n",
484
     function,
485
     value_32bit );
486
487
    libcnotify_printf(
488
     "%s: owner identifier\t\t\t: %" PRIu32 "\n",
489
     function,
490
     inode->owner_identifier );
491
492
    libcnotify_printf(
493
     "%s: group identifier\t\t\t: %" PRIu32 "\n",
494
     function,
495
     inode->group_identifier );
496
497
    libcnotify_printf(
498
     "%s: file mode\t\t\t\t: %" PRIo16 "\n",
499
     function,
500
     inode->file_mode );
501
502
    byte_stream_copy_to_uint16_little_endian(
503
     ( (fsapfs_file_system_btree_value_inode_t *) data )->unknown3,
504
     value_16bit );
505
    libcnotify_printf(
506
     "%s: unknown3\t\t\t\t: 0x%04" PRIx16 "\n",
507
     function,
508
     value_16bit );
509
510
    byte_stream_copy_to_uint64_little_endian(
511
     ( (fsapfs_file_system_btree_value_inode_t *) data )->unknown4,
512
     value_64bit );
513
    libcnotify_printf(
514
     "%s: unknown4\t\t\t\t: 0x%08" PRIx64 "\n",
515
     function,
516
     value_64bit );
517
  }
518
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
519
520
1.66k
  if( data_size > sizeof( fsapfs_file_system_btree_value_inode_t ) )
521
1.61k
  {
522
1.61k
    data_offset = sizeof( fsapfs_file_system_btree_value_inode_t );
523
524
1.61k
    if( data_offset > ( data_size - 4 ) )
525
2
    {
526
2
      libcerror_error_set(
527
2
       error,
528
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
529
2
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
530
2
       "%s: invalid data size value out of bounds.",
531
2
       function );
532
533
2
      goto on_error;
534
2
    }
535
1.61k
    byte_stream_copy_to_uint16_little_endian(
536
1.61k
     &( data[ data_offset ] ),
537
1.61k
     number_of_extended_fields );
538
539
#if defined( HAVE_DEBUG_OUTPUT )
540
    if( libcnotify_verbose != 0 )
541
    {
542
      libcnotify_printf(
543
       "%s: number of extended fields\t\t: %" PRIu16 "\n",
544
       function,
545
       number_of_extended_fields );
546
547
      byte_stream_copy_to_uint16_little_endian(
548
       &( data[ data_offset + 2 ] ),
549
       value_16bit );
550
      libcnotify_printf(
551
       "%s: extended field value data size\t\t: %" PRIu16 "\n",
552
       function,
553
       value_16bit );
554
    }
555
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
556
557
1.61k
    data_offset      += 4;
558
1.61k
    value_data_offset = data_offset + ( number_of_extended_fields * 4 );
559
560
1.61k
    for( extended_field_index = 0;
561
2.10k
         extended_field_index < number_of_extended_fields;
562
1.61k
         extended_field_index++ )
563
588
    {
564
588
      if( data_offset > ( data_size - 4 ) )
565
2
      {
566
2
        libcerror_error_set(
567
2
         error,
568
2
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
569
2
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
570
2
         "%s: invalid data size value out of bounds.",
571
2
         function );
572
573
2
        goto on_error;
574
2
      }
575
586
      extended_field_type  = data[ data_offset ];
576
586
      extended_field_flags = data[ data_offset + 1 ];
577
578
586
      byte_stream_copy_to_uint16_little_endian(
579
586
       &( data[ data_offset + 2 ] ),
580
586
       value_data_size );
581
582
#if defined( HAVE_DEBUG_OUTPUT )
583
      if( libcnotify_verbose != 0 )
584
      {
585
        libcnotify_printf(
586
         "%s: extended field: %" PRIu16 " type\t\t\t: %" PRIu8 " %s\n",
587
         function,
588
         extended_field_index,
589
         extended_field_type,
590
         libfsapfs_debug_print_inode_extended_field_type(
591
          extended_field_type ) );
592
593
        libcnotify_printf(
594
         "%s: extended field: %" PRIu16 " flags\t\t: 0x%02" PRIx8 "\n",
595
         function,
596
         extended_field_index,
597
         extended_field_flags );
598
        libfsapfs_debug_print_extended_field_flags(
599
         extended_field_flags );
600
        libcnotify_printf(
601
         "\n" );
602
603
        libcnotify_printf(
604
         "%s: extended field: %" PRIu16 " value data size\t: %" PRIu16 "\n",
605
         function,
606
         extended_field_index,
607
         value_data_size );
608
      }
609
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
610
611
586
      data_offset += 4;
612
613
586
      if( value_data_offset > data_size )
614
40
      {
615
40
        libcerror_error_set(
616
40
         error,
617
40
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
618
40
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
619
40
         "%s: invalid data size value out of bounds.",
620
40
         function );
621
622
40
        goto on_error;
623
40
      }
624
546
      if( ( value_data_size == 0 )
625
546
       || ( (size_t) value_data_size > ( data_size - value_data_offset ) ) )
626
34
      {
627
34
        libcerror_error_set(
628
34
         error,
629
34
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
630
34
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
631
34
         "%s: invalid value data size value out of bounds.",
632
34
         function );
633
634
34
        goto on_error;
635
34
      }
636
512
      value_data = &( data[ value_data_offset ] );
637
638
#if defined( HAVE_DEBUG_OUTPUT )
639
      if( libcnotify_verbose != 0 )
640
      {
641
        libcnotify_printf(
642
         "%s: extended field: %" PRIu16 " value data:\n",
643
         function,
644
         extended_field_index );
645
        libcnotify_print_data(
646
         value_data,
647
         value_data_size,
648
         0 );
649
      }
650
#endif
651
512
      switch( extended_field_type )
652
512
      {
653
6
        case 1:
654
13
        case 2:
655
20
        case 3:
656
25
        case 5:
657
30
        case 7:
658
39
        case 10:
659
43
        case 11:
660
49
        case 13:
661
54
        case 15:
662
54
          break;
663
664
324
        case 4:
665
          /* Error in case the inode defines multiple name extended fields
666
           */
667
324
          if( inode->name != NULL )
668
2
          {
669
2
            libcerror_error_set(
670
2
             error,
671
2
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
672
2
             LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
673
2
             "%s: invalid inode - name value already set.",
674
2
             function );
675
676
2
            goto on_error;
677
2
          }
678
322
          inode->name = (uint8_t *) memory_allocate(
679
322
                                     sizeof( uint8_t ) * (size_t) value_data_size );
680
681
322
          if( inode->name == NULL )
682
0
          {
683
0
            libcerror_error_set(
684
0
             error,
685
0
             LIBCERROR_ERROR_DOMAIN_MEMORY,
686
0
             LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
687
0
             "%s: unable to create name.",
688
0
             function );
689
690
0
            goto on_error;
691
0
          }
692
322
          inode->name_size = (size_t) value_data_size;
693
694
322
          if( memory_copy(
695
322
               inode->name,
696
322
               value_data,
697
322
               (size_t) value_data_size ) == NULL )
698
0
          {
699
0
            libcerror_error_set(
700
0
             error,
701
0
             LIBCERROR_ERROR_DOMAIN_MEMORY,
702
0
             LIBCERROR_MEMORY_ERROR_COPY_FAILED,
703
0
             "%s: unable to copy name.",
704
0
             function );
705
706
0
            goto on_error;
707
0
          }
708
#if defined( HAVE_DEBUG_OUTPUT )
709
          if( libcnotify_verbose != 0 )
710
          {
711
            libcnotify_printf(
712
             "%s: name\t\t\t\t\t: %s\n",
713
             function,
714
             inode->name );
715
          }
716
#endif
717
322
          break;
718
719
322
        case 8:
720
127
          if( value_data_size < sizeof( fsapfs_file_system_data_stream_attribute_t ) )
721
10
          {
722
10
            libcerror_error_set(
723
10
             error,
724
10
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
725
10
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
726
10
             "%s: invalid value data size value out of bounds.",
727
10
             function );
728
729
10
            goto on_error;
730
10
          }
731
117
          byte_stream_copy_to_uint64_little_endian(
732
117
           ( (fsapfs_file_system_data_stream_attribute_t *) value_data )->used_size,
733
117
           inode->data_stream_size );
734
735
#if defined( HAVE_DEBUG_OUTPUT )
736
          if( libcnotify_verbose != 0 )
737
          {
738
            libcnotify_printf(
739
             "%s: used size\t\t\t\t: %" PRIu64 "\n",
740
             function,
741
             inode->data_stream_size );
742
743
            byte_stream_copy_to_uint64_little_endian(
744
             ( (fsapfs_file_system_data_stream_attribute_t *) value_data )->allocated_size,
745
             value_64bit );
746
            libcnotify_printf(
747
             "%s: allocated size\t\t\t\t: %" PRIu64 "\n",
748
             function,
749
             value_64bit );
750
751
            byte_stream_copy_to_uint64_little_endian(
752
             ( (fsapfs_file_system_data_stream_attribute_t *) value_data )->encryption_identifier,
753
             value_64bit );
754
            libcnotify_printf(
755
             "%s: encryption identifier\t\t\t: %" PRIu64 "\n",
756
             function,
757
             value_64bit );
758
759
            byte_stream_copy_to_uint64_little_endian(
760
             ( (fsapfs_file_system_data_stream_attribute_t *) value_data )->number_of_bytes_written,
761
             value_64bit );
762
            libcnotify_printf(
763
             "%s: number of bytes written\t\t: %" PRIu64 "\n",
764
             function,
765
             value_64bit );
766
767
            byte_stream_copy_to_uint64_little_endian(
768
             ( (fsapfs_file_system_data_stream_attribute_t *) value_data )->number_of_bytes_read,
769
             value_64bit );
770
            libcnotify_printf(
771
             "%s: number of bytes read\t\t\t: %" PRIu64 "\n",
772
             function,
773
             value_64bit );
774
775
            libcnotify_printf(
776
             "\n" );
777
          }
778
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
779
117
          break;
780
781
3
        case 14:
782
3
          if( value_data_size != 4 )
783
2
          {
784
2
            libcerror_error_set(
785
2
             error,
786
2
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
787
2
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
788
2
             "%s: invalid value data size value out of bounds.",
789
2
             function );
790
791
2
            goto on_error;
792
2
          }
793
1
          byte_stream_copy_to_uint32_little_endian(
794
1
           value_data,
795
1
           inode->device_identifier );
796
797
#if defined( HAVE_DEBUG_OUTPUT )
798
          if( libcnotify_verbose != 0 )
799
          {
800
            libcnotify_printf(
801
             "%s: device identifier\t\t\t: 0x%08" PRIx32 "\n",
802
             function,
803
             inode->device_identifier );
804
805
            libcnotify_printf(
806
             "\n" );
807
          }
808
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
809
1
          break;
810
811
4
        default:
812
4
          libcerror_error_set(
813
4
           error,
814
4
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
815
4
           LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
816
4
           "%s: unsupported extended field type: %" PRIu8 ".",
817
4
           function,
818
4
           extended_field_type );
819
820
4
          goto on_error;
821
512
      }
822
494
      value_data_offset += value_data_size;
823
824
494
      trailing_data_size = value_data_size % 8;
825
826
494
      if( trailing_data_size > 0 )
827
361
      {
828
361
        trailing_data_size = 8 - trailing_data_size;
829
830
361
        if( value_data_offset > ( data_size - trailing_data_size ) )
831
13
        {
832
13
          trailing_data_size = data_size - value_data_offset;
833
13
        }
834
#if defined( HAVE_DEBUG_OUTPUT )
835
        if( libcnotify_verbose != 0 )
836
        {
837
          libcnotify_printf(
838
           "%s: extended field: %" PRIu16 " trailing data:\n",
839
           function,
840
           extended_field_index );
841
          libcnotify_print_data(
842
           &( data[ value_data_offset ] ),
843
           trailing_data_size,
844
           0 );
845
        }
846
#endif
847
361
        value_data_offset += trailing_data_size;
848
361
      }
849
494
    }
850
1.61k
  }
851
#if defined( HAVE_DEBUG_OUTPUT )
852
  else if( libcnotify_verbose != 0 )
853
  {
854
    libcnotify_printf(
855
     "\n" );
856
  }
857
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
858
859
1.57k
  return( 1 );
860
861
96
on_error:
862
96
  if( inode->name != NULL )
863
14
  {
864
14
    memory_free(
865
14
     inode->name );
866
867
14
    inode->name = NULL;
868
14
  }
869
96
  inode->name_size = 0;
870
871
96
  return( -1 );
872
1.66k
}
873
874
/* Retrieves the identifier
875
 * Returns 1 if successful or -1 on error
876
 */
877
int libfsapfs_inode_get_identifier(
878
     libfsapfs_inode_t *inode,
879
     uint64_t *identifier,
880
     libcerror_error_t **error )
881
2.40k
{
882
2.40k
  static char *function = "libfsapfs_inode_get_identifier";
883
884
2.40k
  if( inode == NULL )
885
0
  {
886
0
    libcerror_error_set(
887
0
     error,
888
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
889
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
890
0
     "%s: invalid inode.",
891
0
     function );
892
893
0
    return( -1 );
894
0
  }
895
2.40k
  if( identifier == NULL )
896
0
  {
897
0
    libcerror_error_set(
898
0
     error,
899
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
900
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
901
0
     "%s: invalid identifier.",
902
0
     function );
903
904
0
    return( -1 );
905
0
  }
906
2.40k
  *identifier = inode->identifier;
907
908
2.40k
  return( 1 );
909
2.40k
}
910
911
/* Retrieves the parent identifier
912
 * Returns 1 if successful or -1 on error
913
 */
914
int libfsapfs_inode_get_parent_identifier(
915
     libfsapfs_inode_t *inode,
916
     uint64_t *parent_identifier,
917
     libcerror_error_t **error )
918
569
{
919
569
  static char *function = "libfsapfs_inode_get_parent_identifier";
920
921
569
  if( inode == NULL )
922
0
  {
923
0
    libcerror_error_set(
924
0
     error,
925
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
926
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
927
0
     "%s: invalid inode.",
928
0
     function );
929
930
0
    return( -1 );
931
0
  }
932
569
  if( parent_identifier == NULL )
933
0
  {
934
0
    libcerror_error_set(
935
0
     error,
936
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
937
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
938
0
     "%s: invalid parent identifier.",
939
0
     function );
940
941
0
    return( -1 );
942
0
  }
943
569
  *parent_identifier = inode->parent_identifier;
944
945
569
  return( 1 );
946
569
}
947
948
/* Retrieves the creation time
949
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
950
 * Returns 1 if successful or -1 on error
951
 */
952
int libfsapfs_inode_get_creation_time(
953
     libfsapfs_inode_t *inode,
954
     int64_t *posix_time,
955
     libcerror_error_t **error )
956
569
{
957
569
  static char *function = "libfsapfs_inode_get_creation_time";
958
959
569
  if( inode == NULL )
960
0
  {
961
0
    libcerror_error_set(
962
0
     error,
963
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
964
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
965
0
     "%s: invalid inode.",
966
0
     function );
967
968
0
    return( -1 );
969
0
  }
970
569
  if( posix_time == NULL )
971
0
  {
972
0
    libcerror_error_set(
973
0
     error,
974
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
975
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
976
0
     "%s: invalid POSIX time.",
977
0
     function );
978
979
0
    return( -1 );
980
0
  }
981
569
  *posix_time = (int64_t) inode->creation_time;
982
983
569
  return( 1 );
984
569
}
985
986
/* Retrieves the modification time
987
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
988
 * Returns 1 if successful or -1 on error
989
 */
990
int libfsapfs_inode_get_modification_time(
991
     libfsapfs_inode_t *inode,
992
     int64_t *posix_time,
993
     libcerror_error_t **error )
994
569
{
995
569
  static char *function = "libfsapfs_inode_get_modification_time";
996
997
569
  if( inode == NULL )
998
0
  {
999
0
    libcerror_error_set(
1000
0
     error,
1001
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1002
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1003
0
     "%s: invalid inode.",
1004
0
     function );
1005
1006
0
    return( -1 );
1007
0
  }
1008
569
  if( posix_time == NULL )
1009
0
  {
1010
0
    libcerror_error_set(
1011
0
     error,
1012
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1013
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1014
0
     "%s: invalid POSIX time.",
1015
0
     function );
1016
1017
0
    return( -1 );
1018
0
  }
1019
569
  *posix_time = (int64_t) inode->modification_time;
1020
1021
569
  return( 1 );
1022
569
}
1023
1024
/* Retrieves the inode change time
1025
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
1026
 * Returns 1 if successful or -1 on error
1027
 */
1028
int libfsapfs_inode_get_inode_change_time(
1029
     libfsapfs_inode_t *inode,
1030
     int64_t *posix_time,
1031
     libcerror_error_t **error )
1032
569
{
1033
569
  static char *function = "libfsapfs_inode_get_inode_change_time";
1034
1035
569
  if( inode == NULL )
1036
0
  {
1037
0
    libcerror_error_set(
1038
0
     error,
1039
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1040
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1041
0
     "%s: invalid inode.",
1042
0
     function );
1043
1044
0
    return( -1 );
1045
0
  }
1046
569
  if( posix_time == NULL )
1047
0
  {
1048
0
    libcerror_error_set(
1049
0
     error,
1050
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1051
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1052
0
     "%s: invalid POSIX time.",
1053
0
     function );
1054
1055
0
    return( -1 );
1056
0
  }
1057
569
  *posix_time = (int64_t) inode->inode_change_time;
1058
1059
569
  return( 1 );
1060
569
}
1061
1062
/* Retrieves the access time
1063
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
1064
 * Returns 1 if successful or -1 on error
1065
 */
1066
int libfsapfs_inode_get_access_time(
1067
     libfsapfs_inode_t *inode,
1068
     int64_t *posix_time,
1069
     libcerror_error_t **error )
1070
569
{
1071
569
  static char *function = "libfsapfs_inode_get_access_time";
1072
1073
569
  if( inode == NULL )
1074
0
  {
1075
0
    libcerror_error_set(
1076
0
     error,
1077
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1078
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1079
0
     "%s: invalid inode.",
1080
0
     function );
1081
1082
0
    return( -1 );
1083
0
  }
1084
569
  if( posix_time == NULL )
1085
0
  {
1086
0
    libcerror_error_set(
1087
0
     error,
1088
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1089
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1090
0
     "%s: invalid POSIX time.",
1091
0
     function );
1092
1093
0
    return( -1 );
1094
0
  }
1095
569
  *posix_time = (int64_t) inode->access_time;
1096
1097
569
  return( 1 );
1098
569
}
1099
1100
/* Retrieves the owner identifier
1101
 * Returns 1 if successful or -1 on error
1102
 */
1103
int libfsapfs_inode_get_owner_identifier(
1104
     libfsapfs_inode_t *inode,
1105
     uint32_t *owner_identifier,
1106
     libcerror_error_t **error )
1107
569
{
1108
569
  static char *function = "libfsapfs_inode_get_owner_identifier";
1109
1110
569
  if( inode == NULL )
1111
0
  {
1112
0
    libcerror_error_set(
1113
0
     error,
1114
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1115
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1116
0
     "%s: invalid inode.",
1117
0
     function );
1118
1119
0
    return( -1 );
1120
0
  }
1121
569
  if( owner_identifier == NULL )
1122
0
  {
1123
0
    libcerror_error_set(
1124
0
     error,
1125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1127
0
     "%s: invalid owner identifier.",
1128
0
     function );
1129
1130
0
    return( -1 );
1131
0
  }
1132
569
  *owner_identifier = inode->owner_identifier;
1133
1134
569
  return( 1 );
1135
569
}
1136
1137
/* Retrieves the group identifier
1138
 * Returns 1 if successful or -1 on error
1139
 */
1140
int libfsapfs_inode_get_group_identifier(
1141
     libfsapfs_inode_t *inode,
1142
     uint32_t *group_identifier,
1143
     libcerror_error_t **error )
1144
569
{
1145
569
  static char *function = "libfsapfs_inode_get_group_identifier";
1146
1147
569
  if( inode == NULL )
1148
0
  {
1149
0
    libcerror_error_set(
1150
0
     error,
1151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1153
0
     "%s: invalid inode.",
1154
0
     function );
1155
1156
0
    return( -1 );
1157
0
  }
1158
569
  if( group_identifier == NULL )
1159
0
  {
1160
0
    libcerror_error_set(
1161
0
     error,
1162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1164
0
     "%s: invalid group identifier.",
1165
0
     function );
1166
1167
0
    return( -1 );
1168
0
  }
1169
569
  *group_identifier = inode->group_identifier;
1170
1171
569
  return( 1 );
1172
569
}
1173
1174
/* Retrieves the device identifier
1175
 * Returns 1 if successful, 0 if not available or -1 on error
1176
 */
1177
int libfsapfs_inode_get_device_identifier(
1178
     libfsapfs_inode_t *inode,
1179
     uint32_t *device_identifier,
1180
     libcerror_error_t **error )
1181
569
{
1182
569
  static char *function = "libfsapfs_inode_get_device_identifier";
1183
1184
569
  if( inode == NULL )
1185
0
  {
1186
0
    libcerror_error_set(
1187
0
     error,
1188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1190
0
     "%s: invalid inode.",
1191
0
     function );
1192
1193
0
    return( -1 );
1194
0
  }
1195
569
  if( device_identifier == NULL )
1196
0
  {
1197
0
    libcerror_error_set(
1198
0
     error,
1199
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1200
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1201
0
     "%s: invalid major device identifier.",
1202
0
     function );
1203
1204
0
    return( -1 );
1205
0
  }
1206
569
  if( ( ( inode->file_mode & 0xf000 ) == LIBFSAPFS_FILE_TYPE_CHARACTER_DEVICE )
1207
569
   || ( ( inode->file_mode & 0xf000 ) == LIBFSAPFS_FILE_TYPE_BLOCK_DEVICE ) )
1208
12
  {
1209
12
    *device_identifier = inode->device_identifier;
1210
1211
12
    return( 1 );
1212
12
  }
1213
557
  return( 0 );
1214
569
}
1215
1216
/* Retrieves the device number
1217
 * Returns 1 if successful, 0 if not available or -1 on error
1218
 */
1219
int libfsapfs_inode_get_device_number(
1220
     libfsapfs_inode_t *inode,
1221
     uint32_t *major_device_number,
1222
     uint32_t *minor_device_number,
1223
     libcerror_error_t **error )
1224
569
{
1225
569
  static char *function = "libfsapfs_inode_get_device_number";
1226
569
  int result            = 0;
1227
1228
569
  if( inode == NULL )
1229
0
  {
1230
0
    libcerror_error_set(
1231
0
     error,
1232
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1233
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1234
0
     "%s: invalid inode.",
1235
0
     function );
1236
1237
0
    return( -1 );
1238
0
  }
1239
569
  if( major_device_number == NULL )
1240
0
  {
1241
0
    libcerror_error_set(
1242
0
     error,
1243
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1244
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1245
0
     "%s: invalid major device number.",
1246
0
     function );
1247
1248
0
    return( -1 );
1249
0
  }
1250
569
  if( minor_device_number == NULL )
1251
0
  {
1252
0
    libcerror_error_set(
1253
0
     error,
1254
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1255
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1256
0
     "%s: invalid minor device number.",
1257
0
     function );
1258
1259
0
    return( -1 );
1260
0
  }
1261
569
  if( ( ( inode->file_mode & 0xf000 ) == LIBFSAPFS_FILE_TYPE_CHARACTER_DEVICE )
1262
569
   || ( ( inode->file_mode & 0xf000 ) == LIBFSAPFS_FILE_TYPE_BLOCK_DEVICE ) )
1263
12
  {
1264
12
    if( ( inode->device_identifier & 0xffff0000UL ) == 0 )
1265
12
    {
1266
12
      *major_device_number = ( inode->device_identifier >> 8 ) & 0x000000ffUL;
1267
12
      *minor_device_number = inode->device_identifier & 0x000000ffUL;
1268
1269
12
      result = 1;
1270
12
    }
1271
0
    else if( ( inode->device_identifier & 0x00ffff00UL ) == 0 )
1272
0
    {
1273
0
      *major_device_number = ( inode->device_identifier >> 24 ) & 0x000000ffUL;
1274
0
      *minor_device_number = inode->device_identifier & 0x000000ffUL;
1275
1276
0
      result = 1;
1277
0
    }
1278
12
  }
1279
569
  return( result );
1280
569
}
1281
1282
/* Retrieves the file mode
1283
 * Returns 1 if successful or -1 on error
1284
 */
1285
int libfsapfs_inode_get_file_mode(
1286
     libfsapfs_inode_t *inode,
1287
     uint16_t *file_mode,
1288
     libcerror_error_t **error )
1289
569
{
1290
569
  static char *function = "libfsapfs_inode_get_file_mode";
1291
1292
569
  if( inode == NULL )
1293
0
  {
1294
0
    libcerror_error_set(
1295
0
     error,
1296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1298
0
     "%s: invalid inode.",
1299
0
     function );
1300
1301
0
    return( -1 );
1302
0
  }
1303
569
  if( file_mode == NULL )
1304
0
  {
1305
0
    libcerror_error_set(
1306
0
     error,
1307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1309
0
     "%s: invalid file mode.",
1310
0
     function );
1311
1312
0
    return( -1 );
1313
0
  }
1314
569
  *file_mode = inode->file_mode;
1315
1316
569
  return( 1 );
1317
569
}
1318
1319
/* Retrieves the size of the UTF-8 encoded name
1320
 * The returned size includes the end of string character
1321
 * Returns 1 if successful or -1 on error
1322
 */
1323
int libfsapfs_inode_get_utf8_name_size(
1324
     libfsapfs_inode_t *inode,
1325
     size_t *utf8_string_size,
1326
     libcerror_error_t **error )
1327
0
{
1328
0
  static char *function = "libfsapfs_inode_get_utf8_name_size";
1329
1330
0
  if( inode == NULL )
1331
0
  {
1332
0
    libcerror_error_set(
1333
0
     error,
1334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1335
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1336
0
     "%s: invalid inode.",
1337
0
     function );
1338
1339
0
    return( -1 );
1340
0
  }
1341
0
  if( libuna_utf8_string_size_from_utf8_stream(
1342
0
       inode->name,
1343
0
       (size_t) inode->name_size,
1344
0
       utf8_string_size,
1345
0
       error ) != 1 )
1346
0
  {
1347
0
    libcerror_error_set(
1348
0
     error,
1349
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1350
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1351
0
     "%s: unable to retrieve UTF-8 string size.",
1352
0
     function );
1353
1354
0
    return( -1 );
1355
0
  }
1356
0
  return( 1 );
1357
0
}
1358
1359
/* Retrieves the number of (hard) links (or children of a directory)
1360
 * Returns 1 if successful or -1 on error
1361
 */
1362
int libfsapfs_inode_get_number_of_links(
1363
     libfsapfs_inode_t *inode,
1364
     uint32_t *number_of_links,
1365
     libcerror_error_t **error )
1366
569
{
1367
569
  static char *function = "libfsapfs_inode_get_number_of_links";
1368
1369
569
  if( inode == NULL )
1370
0
  {
1371
0
    libcerror_error_set(
1372
0
     error,
1373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1375
0
     "%s: invalid inode.",
1376
0
     function );
1377
1378
0
    return( -1 );
1379
0
  }
1380
569
  if( number_of_links == NULL )
1381
0
  {
1382
0
    libcerror_error_set(
1383
0
     error,
1384
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1385
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1386
0
     "%s: invalid number of links.",
1387
0
     function );
1388
1389
0
    return( -1 );
1390
0
  }
1391
569
  *number_of_links = inode->number_of_links;
1392
1393
569
  return( 1 );
1394
569
}
1395
1396
/* Retrieves the UTF-8 encoded name
1397
 * The size should include the end of string character
1398
 * Returns 1 if successful or -1 on error
1399
 */
1400
int libfsapfs_inode_get_utf8_name(
1401
     libfsapfs_inode_t *inode,
1402
     uint8_t *utf8_string,
1403
     size_t utf8_string_size,
1404
     libcerror_error_t **error )
1405
0
{
1406
0
  static char *function = "libfsapfs_inode_get_utf8_name";
1407
1408
0
  if( inode == NULL )
1409
0
  {
1410
0
    libcerror_error_set(
1411
0
     error,
1412
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1413
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1414
0
     "%s: invalid inode.",
1415
0
     function );
1416
1417
0
    return( -1 );
1418
0
  }
1419
0
  if( libuna_utf8_string_copy_from_utf8_stream(
1420
0
       utf8_string,
1421
0
       utf8_string_size,
1422
0
       inode->name,
1423
0
       (size_t) inode->name_size,
1424
0
       error ) != 1 )
1425
0
  {
1426
0
    libcerror_error_set(
1427
0
     error,
1428
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1429
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1430
0
     "%s: unable to retrieve UTF-8 string.",
1431
0
     function );
1432
1433
0
    return( -1 );
1434
0
  }
1435
0
  return( 1 );
1436
0
}
1437
1438
/* Retrieves the size of the UTF-16 encoded name
1439
 * The returned size includes the end of string character
1440
 * Returns 1 if successful or -1 on error
1441
 */
1442
int libfsapfs_inode_get_utf16_name_size(
1443
     libfsapfs_inode_t *inode,
1444
     size_t *utf16_string_size,
1445
     libcerror_error_t **error )
1446
0
{
1447
0
  static char *function = "libfsapfs_inode_get_utf16_name_size";
1448
1449
0
  if( inode == NULL )
1450
0
  {
1451
0
    libcerror_error_set(
1452
0
     error,
1453
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1454
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1455
0
     "%s: invalid inode.",
1456
0
     function );
1457
1458
0
    return( -1 );
1459
0
  }
1460
0
  if( libuna_utf16_string_size_from_utf8_stream(
1461
0
       inode->name,
1462
0
       (size_t) inode->name_size,
1463
0
       utf16_string_size,
1464
0
       error ) != 1 )
1465
0
  {
1466
0
    libcerror_error_set(
1467
0
     error,
1468
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1469
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1470
0
     "%s: unable to retrieve UTF-16 string size.",
1471
0
     function );
1472
1473
0
    return( -1 );
1474
0
  }
1475
0
  return( 1 );
1476
0
}
1477
1478
/* Retrieves the UTF-16 encoded name
1479
 * The size should include the end of string character
1480
 * Returns 1 if successful or -1 on error
1481
 */
1482
int libfsapfs_inode_get_utf16_name(
1483
     libfsapfs_inode_t *inode,
1484
     uint16_t *utf16_string,
1485
     size_t utf16_string_size,
1486
     libcerror_error_t **error )
1487
0
{
1488
0
  static char *function = "libfsapfs_inode_get_utf16_name";
1489
1490
0
  if( inode == NULL )
1491
0
  {
1492
0
    libcerror_error_set(
1493
0
     error,
1494
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1495
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1496
0
     "%s: invalid inode.",
1497
0
     function );
1498
1499
0
    return( -1 );
1500
0
  }
1501
0
  if( libuna_utf16_string_copy_from_utf8_stream(
1502
0
       utf16_string,
1503
0
       utf16_string_size,
1504
0
       inode->name,
1505
0
       (size_t) inode->name_size,
1506
0
       error ) != 1 )
1507
0
  {
1508
0
    libcerror_error_set(
1509
0
     error,
1510
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1511
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1512
0
     "%s: unable to retrieve UTF-16 string.",
1513
0
     function );
1514
1515
0
    return( -1 );
1516
0
  }
1517
0
  return( 1 );
1518
0
}
1519
1520
/* Retrieves the flags
1521
 * Returns 1 if successful or -1 on error
1522
 */
1523
int libfsapfs_inode_get_flags(
1524
     libfsapfs_inode_t *inode,
1525
     uint64_t *flags,
1526
     libcerror_error_t **error )
1527
440
{
1528
440
  static char *function = "libfsapfs_inode_get_flags";
1529
1530
440
  if( inode == NULL )
1531
0
  {
1532
0
    libcerror_error_set(
1533
0
     error,
1534
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1535
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1536
0
     "%s: invalid inode.",
1537
0
     function );
1538
1539
0
    return( -1 );
1540
0
  }
1541
440
  if( flags == NULL )
1542
0
  {
1543
0
    libcerror_error_set(
1544
0
     error,
1545
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1546
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1547
0
     "%s: invalid flags.",
1548
0
     function );
1549
1550
0
    return( -1 );
1551
0
  }
1552
440
  *flags = inode->flags;
1553
1554
440
  return( 1 );
1555
440
}
1556
1557
/* Retrieves the data stream identifier
1558
 * Returns 1 if successful or -1 on error
1559
 */
1560
int libfsapfs_inode_get_data_stream_identifier(
1561
     libfsapfs_inode_t *inode,
1562
     uint64_t *data_stream_identifier,
1563
     libcerror_error_t **error )
1564
610
{
1565
610
  static char *function = "libfsapfs_inode_get_data_stream_identifier";
1566
1567
610
  if( inode == NULL )
1568
0
  {
1569
0
    libcerror_error_set(
1570
0
     error,
1571
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1572
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1573
0
     "%s: invalid inode.",
1574
0
     function );
1575
1576
0
    return( -1 );
1577
0
  }
1578
610
  if( data_stream_identifier == NULL )
1579
0
  {
1580
0
    libcerror_error_set(
1581
0
     error,
1582
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1583
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1584
0
     "%s: invalid data stream identifier.",
1585
0
     function );
1586
1587
0
    return( -1 );
1588
0
  }
1589
610
  *data_stream_identifier = inode->data_stream_identifier;
1590
1591
610
  return( 1 );
1592
610
}
1593
1594
/* Retrieves the data stream size
1595
 * Returns 1 if successful or -1 on error
1596
 */
1597
int libfsapfs_inode_get_data_stream_size(
1598
     libfsapfs_inode_t *inode,
1599
     uint64_t *data_stream_size,
1600
     libcerror_error_t **error )
1601
928
{
1602
928
  static char *function = "libfsapfs_inode_get_data_stream_size";
1603
1604
928
  if( inode == NULL )
1605
0
  {
1606
0
    libcerror_error_set(
1607
0
     error,
1608
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1609
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1610
0
     "%s: invalid inode.",
1611
0
     function );
1612
1613
0
    return( -1 );
1614
0
  }
1615
928
  if( data_stream_size == NULL )
1616
0
  {
1617
0
    libcerror_error_set(
1618
0
     error,
1619
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1620
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1621
0
     "%s: invalid data stream size.",
1622
0
     function );
1623
1624
0
    return( -1 );
1625
0
  }
1626
928
  *data_stream_size = inode->data_stream_size;
1627
1628
928
  return( 1 );
1629
928
}
1630