1 /*
2 * Master File Table (MFT) entry header functions
3 *
4 * Copyright (C) 2010-2021, 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 "libfsntfs_debug.h"
28 #include "libfsntfs_libcerror.h"
29 #include "libfsntfs_libcnotify.h"
30 #include "libfsntfs_mft_entry_header.h"
31
32 #include "fsntfs_mft_entry.h"
33
34 /* Creates MFT entry header
35 * Make sure the value mft_entry_header is referencing, is set to NULL
36 * Returns 1 if successful or -1 on error
37 */
libfsntfs_mft_entry_header_initialize(libfsntfs_mft_entry_header_t ** mft_entry_header,libcerror_error_t ** error)38 int libfsntfs_mft_entry_header_initialize(
39 libfsntfs_mft_entry_header_t **mft_entry_header,
40 libcerror_error_t **error )
41 {
42 static char *function = "libfsntfs_mft_entry_header_initialize";
43
44 if( mft_entry_header == NULL )
45 {
46 libcerror_error_set(
47 error,
48 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 "%s: invalid MFT entry header.",
51 function );
52
53 return( -1 );
54 }
55 if( *mft_entry_header != NULL )
56 {
57 libcerror_error_set(
58 error,
59 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 "%s: invalid MFT entry header value already set.",
62 function );
63
64 return( -1 );
65 }
66 *mft_entry_header = memory_allocate_structure(
67 libfsntfs_mft_entry_header_t );
68
69 if( *mft_entry_header == NULL )
70 {
71 libcerror_error_set(
72 error,
73 LIBCERROR_ERROR_DOMAIN_MEMORY,
74 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75 "%s: unable to create MFT entry header.",
76 function );
77
78 goto on_error;
79 }
80 if( memory_set(
81 *mft_entry_header,
82 0,
83 sizeof( libfsntfs_mft_entry_header_t ) ) == NULL )
84 {
85 libcerror_error_set(
86 error,
87 LIBCERROR_ERROR_DOMAIN_MEMORY,
88 LIBCERROR_MEMORY_ERROR_SET_FAILED,
89 "%s: unable to clear MFT entry header.",
90 function );
91
92 goto on_error;
93 }
94 return( 1 );
95
96 on_error:
97 if( *mft_entry_header != NULL )
98 {
99 memory_free(
100 *mft_entry_header );
101
102 *mft_entry_header = NULL;
103 }
104 return( -1 );
105 }
106
107 /* Frees MFT entry header
108 * Returns 1 if successful or -1 on error
109 */
libfsntfs_mft_entry_header_free(libfsntfs_mft_entry_header_t ** mft_entry_header,libcerror_error_t ** error)110 int libfsntfs_mft_entry_header_free(
111 libfsntfs_mft_entry_header_t **mft_entry_header,
112 libcerror_error_t **error )
113 {
114 static char *function = "libfsntfs_mft_entry_header_free";
115
116 if( mft_entry_header == NULL )
117 {
118 libcerror_error_set(
119 error,
120 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
121 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
122 "%s: invalid MFT entry header.",
123 function );
124
125 return( -1 );
126 }
127 if( *mft_entry_header != NULL )
128 {
129 memory_free(
130 *mft_entry_header );
131
132 *mft_entry_header = NULL;
133 }
134 return( 1 );
135 }
136
137 /* Reads the MFT entry header
138 * Returns 1 if successful, 0 if FILE signature is not present or -1 on error
139 */
libfsntfs_mft_entry_header_read_data(libfsntfs_mft_entry_header_t * mft_entry_header,const uint8_t * data,size_t data_size,libcerror_error_t ** error)140 int libfsntfs_mft_entry_header_read_data(
141 libfsntfs_mft_entry_header_t *mft_entry_header,
142 const uint8_t *data,
143 size_t data_size,
144 libcerror_error_t **error )
145 {
146 static char *function = "libfsntfs_mft_entry_header_read_data";
147 size_t header_data_size = 0;
148
149 #if defined( HAVE_DEBUG_OUTPUT )
150 uint16_t value_16bit = 0;
151 #endif
152
153 if( mft_entry_header == NULL )
154 {
155 libcerror_error_set(
156 error,
157 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
158 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
159 "%s: invalid MFT entry header.",
160 function );
161
162 return( -1 );
163 }
164 if( data == NULL )
165 {
166 libcerror_error_set(
167 error,
168 LIBCERROR_ERROR_DOMAIN_RUNTIME,
169 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
170 "%s: invalid data.",
171 function );
172
173 return( -1 );
174 }
175 if( ( data_size < 2 )
176 || ( data_size > (size_t) SSIZE_MAX ) )
177 {
178 libcerror_error_set(
179 error,
180 LIBCERROR_ERROR_DOMAIN_RUNTIME,
181 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
182 "%s: invalid data size value out of bounds.",
183 function );
184
185 return( -1 );
186 }
187 byte_stream_copy_to_uint16_little_endian(
188 ( (fsntfs_mft_entry_header_t *) data )->fixup_values_offset,
189 mft_entry_header->fixup_values_offset );
190
191 if( mft_entry_header->fixup_values_offset > 42 )
192 {
193 header_data_size = sizeof( fsntfs_mft_entry_header_t );
194 }
195 else
196 {
197 header_data_size = 42;
198 }
199 #if defined( HAVE_DEBUG_OUTPUT )
200 if( libcnotify_verbose != 0 )
201 {
202 libcnotify_printf(
203 "%s: MFT entry header data:\n",
204 function );
205 libcnotify_print_data(
206 data,
207 header_data_size,
208 0 );
209 }
210 #endif
211 if( data_size < header_data_size )
212 {
213 libcerror_error_set(
214 error,
215 LIBCERROR_ERROR_DOMAIN_RUNTIME,
216 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
217 "%s: invalid data size value out of bounds.",
218 function );
219
220 return( -1 );
221 }
222 if( memory_compare(
223 ( (fsntfs_mft_entry_header_t *) data )->signature,
224 "BAAD",
225 4 ) == 0 )
226 {
227 mft_entry_header->is_bad = 1;
228
229 return( 0 );
230 }
231 mft_entry_header->is_bad = 0;
232
233 if( memory_compare(
234 ( (fsntfs_mft_entry_header_t *) data )->signature,
235 "FILE",
236 4 ) != 0 )
237 {
238 return( 0 );
239 }
240 byte_stream_copy_to_uint16_little_endian(
241 ( (fsntfs_mft_entry_header_t *) data )->number_of_fixup_values,
242 mft_entry_header->number_of_fixup_values );
243
244 byte_stream_copy_to_uint64_little_endian(
245 ( (fsntfs_mft_entry_header_t *) data )->journal_sequence_number,
246 mft_entry_header->journal_sequence_number );
247
248 byte_stream_copy_to_uint16_little_endian(
249 ( (fsntfs_mft_entry_header_t *) data )->sequence,
250 mft_entry_header->sequence );
251
252 byte_stream_copy_to_uint16_little_endian(
253 ( (fsntfs_mft_entry_header_t *) data )->reference_count,
254 mft_entry_header->reference_count );
255
256 byte_stream_copy_to_uint16_little_endian(
257 ( (fsntfs_mft_entry_header_t *) data )->attributes_offset,
258 mft_entry_header->attributes_offset );
259
260 byte_stream_copy_to_uint16_little_endian(
261 ( (fsntfs_mft_entry_header_t *) data )->flags,
262 mft_entry_header->flags );
263
264 byte_stream_copy_to_uint16_little_endian(
265 ( (fsntfs_mft_entry_header_t *) data )->used_entry_size,
266 mft_entry_header->used_entry_size );
267
268 byte_stream_copy_to_uint16_little_endian(
269 ( (fsntfs_mft_entry_header_t *) data )->total_entry_size,
270 mft_entry_header->total_entry_size );
271
272 byte_stream_copy_to_uint64_little_endian(
273 ( (fsntfs_mft_entry_header_t *) data )->base_record_file_reference,
274 mft_entry_header->base_record_file_reference );
275
276 if( header_data_size > 42 )
277 {
278 byte_stream_copy_to_uint32_little_endian(
279 ( (fsntfs_mft_entry_header_t *) data )->index,
280 mft_entry_header->index );
281 }
282 #if defined( HAVE_DEBUG_OUTPUT )
283 if( libcnotify_verbose != 0 )
284 {
285 libcnotify_printf(
286 "%s: signature\t\t\t\t\t: %c%c%c%c\n",
287 function,
288 ( (fsntfs_mft_entry_header_t *) data )->signature[ 0 ],
289 ( (fsntfs_mft_entry_header_t *) data )->signature[ 1 ],
290 ( (fsntfs_mft_entry_header_t *) data )->signature[ 2 ],
291 ( (fsntfs_mft_entry_header_t *) data )->signature[ 3 ] );
292
293 libcnotify_printf(
294 "%s: fix-up values offset\t\t\t: %" PRIu16 "\n",
295 function,
296 mft_entry_header->fixup_values_offset );
297
298 libcnotify_printf(
299 "%s: number of fix-up values\t\t\t: %" PRIu16 "\n",
300 function,
301 mft_entry_header->number_of_fixup_values );
302
303 libcnotify_printf(
304 "%s: journal sequence number\t\t\t: %" PRIu64 "\n",
305 function,
306 mft_entry_header->journal_sequence_number );
307
308 libcnotify_printf(
309 "%s: sequence\t\t\t\t\t: %" PRIu16 "\n",
310 function,
311 mft_entry_header->sequence );
312
313 libcnotify_printf(
314 "%s: reference count\t\t\t\t: %" PRIu16 "\n",
315 function,
316 mft_entry_header->reference_count );
317
318 libcnotify_printf(
319 "%s: attributes offset\t\t\t\t: %" PRIu16 "\n",
320 function,
321 mft_entry_header->attributes_offset );
322
323 libcnotify_printf(
324 "%s: flags\t\t\t\t\t: 0x%04" PRIx16 "\n",
325 function,
326 mft_entry_header->flags );
327 libfsntfs_debug_print_mft_entry_flags(
328 mft_entry_header->flags );
329 libcnotify_printf(
330 "\n" );
331
332 libcnotify_printf(
333 "%s: used entry size\t\t\t\t: %" PRIu16 "\n",
334 function,
335 mft_entry_header->used_entry_size );
336
337 libcnotify_printf(
338 "%s: total entry size\t\t\t\t: %" PRIu16 "\n",
339 function,
340 mft_entry_header->total_entry_size );
341
342 libcnotify_printf(
343 "%s: base record file reference\t\t: %" PRIu64 "-%" PRIu64 "\n",
344 function,
345 mft_entry_header->base_record_file_reference & 0xffffffffffffUL,
346 mft_entry_header->base_record_file_reference >> 48 );
347
348 byte_stream_copy_to_uint16_little_endian(
349 ( (fsntfs_mft_entry_header_t *) data )->first_available_attribute_identifier,
350 value_16bit );
351 libcnotify_printf(
352 "%s: first available attribute identifier\t: %" PRIu16 "\n",
353 function,
354 value_16bit );
355
356 if( header_data_size > 42 )
357 {
358 byte_stream_copy_to_uint16_little_endian(
359 ( (fsntfs_mft_entry_header_t *) data )->unknown1,
360 value_16bit );
361 libcnotify_printf(
362 "%s: unknown1\t\t\t\t\t: 0x%04" PRIu16 "\n",
363 function,
364 value_16bit );
365
366 libcnotify_printf(
367 "%s: index\t\t\t\t\t: %" PRIu32 "\n",
368 function,
369 mft_entry_header->index );
370 }
371 libcnotify_printf(
372 "\n" );
373 }
374 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
375
376 if( mft_entry_header->fixup_values_offset < header_data_size )
377 {
378 libcerror_error_set(
379 error,
380 LIBCERROR_ERROR_DOMAIN_RUNTIME,
381 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
382 "%s: invalid fix-up values offset value out of bounds.",
383 function );
384
385 return( -1 );
386 }
387 if( mft_entry_header->attributes_offset < header_data_size )
388 {
389 libcerror_error_set(
390 error,
391 LIBCERROR_ERROR_DOMAIN_RUNTIME,
392 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
393 "%s: invalid attributes offset value out of bounds.",
394 function );
395
396 return( -1 );
397 }
398 return( 1 );
399 }
400
401 /* Retrieves the fix-up values offset
402 * Returns 1 if successful or -1 on error
403 */
libfsntfs_mft_entry_header_get_fixup_values_offset(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * fixup_values_offset,libcerror_error_t ** error)404 int libfsntfs_mft_entry_header_get_fixup_values_offset(
405 libfsntfs_mft_entry_header_t *mft_entry_header,
406 uint16_t *fixup_values_offset,
407 libcerror_error_t **error )
408 {
409 static char *function = "libfsntfs_mft_entry_header_get_fixup_values_offset";
410
411 if( mft_entry_header == NULL )
412 {
413 libcerror_error_set(
414 error,
415 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
416 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
417 "%s: invalid MFT entry header.",
418 function );
419
420 return( -1 );
421 }
422 if( fixup_values_offset == NULL )
423 {
424 libcerror_error_set(
425 error,
426 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
427 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
428 "%s: invalid fix-up values offset.",
429 function );
430
431 return( -1 );
432 }
433 *fixup_values_offset = mft_entry_header->fixup_values_offset;
434
435 return( 1 );
436 }
437
438 /* Retrieves the number of fix-up values
439 * Returns 1 if successful or -1 on error
440 */
libfsntfs_mft_entry_header_get_number_of_fixup_values(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * number_of_fixup_values,libcerror_error_t ** error)441 int libfsntfs_mft_entry_header_get_number_of_fixup_values(
442 libfsntfs_mft_entry_header_t *mft_entry_header,
443 uint16_t *number_of_fixup_values,
444 libcerror_error_t **error )
445 {
446 static char *function = "libfsntfs_mft_entry_header_get_number_of_fixup_values";
447
448 if( mft_entry_header == NULL )
449 {
450 libcerror_error_set(
451 error,
452 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
453 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
454 "%s: invalid MFT entry header.",
455 function );
456
457 return( -1 );
458 }
459 if( number_of_fixup_values == NULL )
460 {
461 libcerror_error_set(
462 error,
463 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
464 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
465 "%s: invalid number of fix-up values.",
466 function );
467
468 return( -1 );
469 }
470 *number_of_fixup_values = mft_entry_header->number_of_fixup_values;
471
472 return( 1 );
473 }
474
475 /* Retrieves the journal sequence number
476 * Returns 1 if successful or -1 on error
477 */
libfsntfs_mft_entry_header_get_journal_sequence_number(libfsntfs_mft_entry_header_t * mft_entry_header,uint64_t * journal_sequence_number,libcerror_error_t ** error)478 int libfsntfs_mft_entry_header_get_journal_sequence_number(
479 libfsntfs_mft_entry_header_t *mft_entry_header,
480 uint64_t *journal_sequence_number,
481 libcerror_error_t **error )
482 {
483 static char *function = "libfsntfs_mft_entry_header_get_journal_sequence_number";
484
485 if( mft_entry_header == NULL )
486 {
487 libcerror_error_set(
488 error,
489 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
491 "%s: invalid MFT entry header.",
492 function );
493
494 return( -1 );
495 }
496 if( journal_sequence_number == NULL )
497 {
498 libcerror_error_set(
499 error,
500 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
501 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
502 "%s: invalid journal sequence number.",
503 function );
504
505 return( -1 );
506 }
507 *journal_sequence_number = mft_entry_header->journal_sequence_number;
508
509 return( 1 );
510 }
511
512 /* Retrieves the reference count
513 * Returns 1 if successful or -1 on error
514 */
libfsntfs_mft_entry_header_get_reference_count(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * reference_count,libcerror_error_t ** error)515 int libfsntfs_mft_entry_header_get_reference_count(
516 libfsntfs_mft_entry_header_t *mft_entry_header,
517 uint16_t *reference_count,
518 libcerror_error_t **error )
519 {
520 static char *function = "libfsntfs_mft_entry_header_get_reference_count";
521
522 if( mft_entry_header == NULL )
523 {
524 libcerror_error_set(
525 error,
526 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
527 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
528 "%s: invalid MFT entry header.",
529 function );
530
531 return( -1 );
532 }
533 if( reference_count == NULL )
534 {
535 libcerror_error_set(
536 error,
537 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
538 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
539 "%s: invalid reference count.",
540 function );
541
542 return( -1 );
543 }
544 *reference_count = mft_entry_header->reference_count;
545
546 return( 1 );
547 }
548
549 /* Retrieves the attributes offset
550 * Returns 1 if successful or -1 on error
551 */
libfsntfs_mft_entry_header_get_attributes_offset(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * attributes_offset,libcerror_error_t ** error)552 int libfsntfs_mft_entry_header_get_attributes_offset(
553 libfsntfs_mft_entry_header_t *mft_entry_header,
554 uint16_t *attributes_offset,
555 libcerror_error_t **error )
556 {
557 static char *function = "libfsntfs_mft_entry_header_get_attributes_offset";
558
559 if( mft_entry_header == NULL )
560 {
561 libcerror_error_set(
562 error,
563 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
564 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
565 "%s: invalid MFT entry header.",
566 function );
567
568 return( -1 );
569 }
570 if( attributes_offset == NULL )
571 {
572 libcerror_error_set(
573 error,
574 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
575 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
576 "%s: invalid attributes offset.",
577 function );
578
579 return( -1 );
580 }
581 *attributes_offset = mft_entry_header->attributes_offset;
582
583 return( 1 );
584 }
585
586 /* Retrieves the used entry size
587 * Returns 1 if successful or -1 on error
588 */
libfsntfs_mft_entry_header_get_used_entry_size(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * used_entry_size,libcerror_error_t ** error)589 int libfsntfs_mft_entry_header_get_used_entry_size(
590 libfsntfs_mft_entry_header_t *mft_entry_header,
591 uint16_t *used_entry_size,
592 libcerror_error_t **error )
593 {
594 static char *function = "libfsntfs_mft_entry_header_get_used_entry_size";
595
596 if( mft_entry_header == NULL )
597 {
598 libcerror_error_set(
599 error,
600 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
601 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
602 "%s: invalid MFT entry header.",
603 function );
604
605 return( -1 );
606 }
607 if( used_entry_size == NULL )
608 {
609 libcerror_error_set(
610 error,
611 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
612 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
613 "%s: invalid used entry size.",
614 function );
615
616 return( -1 );
617 }
618 *used_entry_size = mft_entry_header->used_entry_size;
619
620 return( 1 );
621 }
622
623 /* Retrieves the total entry size
624 * Returns 1 if successful or -1 on error
625 */
libfsntfs_mft_entry_header_get_total_entry_size(libfsntfs_mft_entry_header_t * mft_entry_header,uint16_t * total_entry_size,libcerror_error_t ** error)626 int libfsntfs_mft_entry_header_get_total_entry_size(
627 libfsntfs_mft_entry_header_t *mft_entry_header,
628 uint16_t *total_entry_size,
629 libcerror_error_t **error )
630 {
631 static char *function = "libfsntfs_mft_entry_header_get_total_entry_size";
632
633 if( mft_entry_header == NULL )
634 {
635 libcerror_error_set(
636 error,
637 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
638 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
639 "%s: invalid MFT entry header.",
640 function );
641
642 return( -1 );
643 }
644 if( total_entry_size == NULL )
645 {
646 libcerror_error_set(
647 error,
648 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
649 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
650 "%s: invalid total entry size.",
651 function );
652
653 return( -1 );
654 }
655 *total_entry_size = mft_entry_header->total_entry_size;
656
657 return( 1 );
658 }
659
660 /* Retrieves the base record file reference
661 * Returns 1 if successful or -1 on error
662 */
libfsntfs_mft_entry_header_get_base_record_file_reference(libfsntfs_mft_entry_header_t * mft_entry_header,uint64_t * base_record_file_reference,libcerror_error_t ** error)663 int libfsntfs_mft_entry_header_get_base_record_file_reference(
664 libfsntfs_mft_entry_header_t *mft_entry_header,
665 uint64_t *base_record_file_reference,
666 libcerror_error_t **error )
667 {
668 static char *function = "libfsntfs_mft_entry_header_get_base_record_file_reference";
669
670 if( mft_entry_header == NULL )
671 {
672 libcerror_error_set(
673 error,
674 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
675 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
676 "%s: invalid MFT entry header.",
677 function );
678
679 return( -1 );
680 }
681 if( base_record_file_reference == NULL )
682 {
683 libcerror_error_set(
684 error,
685 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
686 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
687 "%s: invalid base record file reference.",
688 function );
689
690 return( -1 );
691 }
692 *base_record_file_reference = mft_entry_header->base_record_file_reference;
693
694 return( 1 );
695 }
696
697