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