1 /*
2 * Attribute list entry 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_libcdata.h"
29 #include "libfsntfs_libcerror.h"
30 #include "libfsntfs_libcnotify.h"
31 #include "libfsntfs_libuna.h"
32 #include "libfsntfs_mft_attribute_list_entry.h"
33 #include "libfsntfs_name.h"
34
35 #include "fsntfs_mft_attribute_list.h"
36
37 /* Creates attribute list entry
38 * Make sure the value attribute_list_entry is referencing, is set to NULL
39 * Returns 1 if successful or -1 on error
40 */
libfsntfs_mft_attribute_list_entry_initialize(libfsntfs_mft_attribute_list_entry_t ** attribute_list_entry,libcerror_error_t ** error)41 int libfsntfs_mft_attribute_list_entry_initialize(
42 libfsntfs_mft_attribute_list_entry_t **attribute_list_entry,
43 libcerror_error_t **error )
44 {
45 static char *function = "libfsntfs_mft_attribute_list_entry_initialize";
46
47 if( attribute_list_entry == NULL )
48 {
49 libcerror_error_set(
50 error,
51 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53 "%s: invalid attribute list entry.",
54 function );
55
56 return( -1 );
57 }
58 if( *attribute_list_entry != NULL )
59 {
60 libcerror_error_set(
61 error,
62 LIBCERROR_ERROR_DOMAIN_RUNTIME,
63 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64 "%s: invalid attribute list entry value already set.",
65 function );
66
67 return( -1 );
68 }
69 *attribute_list_entry = memory_allocate_structure(
70 libfsntfs_mft_attribute_list_entry_t );
71
72 if( *attribute_list_entry == NULL )
73 {
74 libcerror_error_set(
75 error,
76 LIBCERROR_ERROR_DOMAIN_MEMORY,
77 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78 "%s: unable to create attribute list entry.",
79 function );
80
81 goto on_error;
82 }
83 if( memory_set(
84 *attribute_list_entry,
85 0,
86 sizeof( libfsntfs_mft_attribute_list_entry_t ) ) == NULL )
87 {
88 libcerror_error_set(
89 error,
90 LIBCERROR_ERROR_DOMAIN_MEMORY,
91 LIBCERROR_MEMORY_ERROR_SET_FAILED,
92 "%s: unable to clear attribute list entry.",
93 function );
94
95 goto on_error;
96 }
97 return( 1 );
98
99 on_error:
100 if( *attribute_list_entry != NULL )
101 {
102 memory_free(
103 *attribute_list_entry );
104
105 *attribute_list_entry = NULL;
106 }
107 return( -1 );
108 }
109
110 /* Frees attribute list entry
111 * Returns 1 if successful or -1 on error
112 */
libfsntfs_mft_attribute_list_entry_free(libfsntfs_mft_attribute_list_entry_t ** attribute_list_entry,libcerror_error_t ** error)113 int libfsntfs_mft_attribute_list_entry_free(
114 libfsntfs_mft_attribute_list_entry_t **attribute_list_entry,
115 libcerror_error_t **error )
116 {
117 static char *function = "libfsntfs_mft_attribute_list_entry_free";
118
119 if( attribute_list_entry == NULL )
120 {
121 libcerror_error_set(
122 error,
123 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125 "%s: invalid attribute list entry.",
126 function );
127
128 return( -1 );
129 }
130 if( *attribute_list_entry != NULL )
131 {
132 if( ( *attribute_list_entry )->name != NULL )
133 {
134 memory_free(
135 ( *attribute_list_entry )->name );
136 }
137 memory_free(
138 *attribute_list_entry );
139
140 *attribute_list_entry = NULL;
141 }
142 return( 1 );
143 }
144
145 /* Reads the attribute list entry
146 * Returns 1 if successful or -1 on error
147 */
libfsntfs_mft_attribute_list_entry_read_data(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,const uint8_t * data,size_t data_size,libcerror_error_t ** error)148 int libfsntfs_mft_attribute_list_entry_read_data(
149 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
150 const uint8_t *data,
151 size_t data_size,
152 libcerror_error_t **error )
153 {
154 static char *function = "libfsntfs_mft_attribute_list_entry_read_data";
155 size_t data_offset = 0;
156 uint8_t name_offset = 0;
157
158 if( attribute_list_entry == NULL )
159 {
160 libcerror_error_set(
161 error,
162 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164 "%s: invalid attribute list entry.",
165 function );
166
167 return( -1 );
168 }
169 if( attribute_list_entry->name != NULL )
170 {
171 libcerror_error_set(
172 error,
173 LIBCERROR_ERROR_DOMAIN_RUNTIME,
174 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
175 "%s: invalid attribute list entry - name value already set.",
176 function );
177
178 return( -1 );
179 }
180 if( data == NULL )
181 {
182 libcerror_error_set(
183 error,
184 LIBCERROR_ERROR_DOMAIN_RUNTIME,
185 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
186 "%s: invalid data.",
187 function );
188
189 return( -1 );
190 }
191 if( data_size > (size_t) SSIZE_MAX )
192 {
193 libcerror_error_set(
194 error,
195 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
197 "%s: data size value exceeds maximum.",
198 function );
199
200 return( -1 );
201 }
202 if( data_size < sizeof( fsntfs_mft_attribute_list_entry_header_t ) )
203 {
204 libcerror_error_set(
205 error,
206 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
207 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
208 "%s: unsupported data size value too small.",
209 function );
210
211 return( -1 );
212 }
213 #if defined( HAVE_DEBUG_OUTPUT )
214 if( libcnotify_verbose != 0 )
215 {
216 libcnotify_printf(
217 "%s: attribute list entry header data:\n",
218 function );
219 libcnotify_print_data(
220 data,
221 sizeof( fsntfs_mft_attribute_list_entry_header_t ),
222 0 );
223 }
224 #endif
225 byte_stream_copy_to_uint32_little_endian(
226 ( (fsntfs_mft_attribute_list_entry_header_t *) data )->type,
227 attribute_list_entry->attribute_type );
228
229 byte_stream_copy_to_uint16_little_endian(
230 ( (fsntfs_mft_attribute_list_entry_header_t *) data )->size,
231 attribute_list_entry->size );
232
233 attribute_list_entry->name_size = (uint16_t) ( (fsntfs_mft_attribute_list_entry_header_t *) data )->name_size;
234
235 name_offset = ( (fsntfs_mft_attribute_list_entry_header_t *) data )->name_offset;
236
237 byte_stream_copy_to_uint64_little_endian(
238 ( (fsntfs_mft_attribute_list_entry_header_t *) data )->data_first_vcn,
239 attribute_list_entry->data_first_vcn );
240
241 byte_stream_copy_to_uint64_little_endian(
242 ( (fsntfs_mft_attribute_list_entry_header_t *) data )->file_reference,
243 attribute_list_entry->file_reference );
244
245 byte_stream_copy_to_uint16_little_endian(
246 ( (fsntfs_mft_attribute_list_entry_header_t *) data )->identifier,
247 attribute_list_entry->identifier );
248
249 #if defined( HAVE_DEBUG_OUTPUT )
250 if( libcnotify_verbose != 0 )
251 {
252 libcnotify_printf(
253 "%s: type\t\t\t: 0x%08" PRIx32 " (%s)\n",
254 function,
255 attribute_list_entry->attribute_type,
256 libfsntfs_debug_print_attribute_type(
257 attribute_list_entry->attribute_type ) );
258
259 libcnotify_printf(
260 "%s: size\t\t\t: %" PRIu16 "\n",
261 function,
262 attribute_list_entry->size );
263
264 libcnotify_printf(
265 "%s: name size\t\t\t: %" PRIu16 "\n",
266 function,
267 attribute_list_entry->name_size );
268
269 libcnotify_printf(
270 "%s: name offset\t\t: %" PRIu8 "\n",
271 function,
272 name_offset );
273
274 libcnotify_printf(
275 "%s: data first VCN\t\t: %" PRIu64 "\n",
276 function,
277 attribute_list_entry->data_first_vcn );
278
279 libcnotify_printf(
280 "%s: file reference\t\t: %" PRIu64 "-%" PRIu64 "\n",
281 function,
282 attribute_list_entry->file_reference & 0xffffffffffffUL,
283 attribute_list_entry->file_reference >> 48 );
284
285 libcnotify_printf(
286 "%s: identifier\t\t: %" PRIu16 "\n",
287 function,
288 attribute_list_entry->identifier );
289 }
290 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
291
292 data_offset = sizeof( fsntfs_mft_attribute_list_entry_header_t );
293
294 if( ( attribute_list_entry->size < sizeof( fsntfs_mft_attribute_list_entry_header_t ) )
295 || ( attribute_list_entry->size > data_size ) )
296 {
297 libcerror_error_set(
298 error,
299 LIBCERROR_ERROR_DOMAIN_RUNTIME,
300 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
301 "%s: size value out of bounds.",
302 function );
303
304 goto on_error;
305 }
306 attribute_list_entry->name_size *= 2;
307
308 if( attribute_list_entry->name_size > 0 )
309 {
310 if( ( name_offset < sizeof( fsntfs_mft_attribute_list_entry_header_t ) )
311 || ( name_offset >= attribute_list_entry->size ) )
312 {
313 libcerror_error_set(
314 error,
315 LIBCERROR_ERROR_DOMAIN_RUNTIME,
316 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
317 "%s: name offset value out of bounds.",
318 function );
319
320 goto on_error;
321 }
322 #if defined( HAVE_DEBUG_OUTPUT )
323 if( libcnotify_verbose != 0 )
324 {
325 if( data_offset < name_offset )
326 {
327 libcnotify_printf(
328 "%s: unknown data:\n",
329 function );
330 libcnotify_print_data(
331 &( data[ data_offset ] ),
332 (size_t) name_offset - data_offset,
333 0 );
334 }
335 }
336 #endif
337 if( attribute_list_entry->name_size > ( attribute_list_entry->size - name_offset ) )
338 {
339 libcerror_error_set(
340 error,
341 LIBCERROR_ERROR_DOMAIN_RUNTIME,
342 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
343 "%s: name size value out of bounds.",
344 function );
345
346 goto on_error;
347 }
348 data_offset = (size_t) name_offset;
349
350 #if defined( HAVE_DEBUG_OUTPUT )
351 if( libcnotify_verbose != 0 )
352 {
353 libcnotify_printf(
354 "%s: name data:\n",
355 function );
356 libcnotify_print_data(
357 &( data[ data_offset ] ),
358 (size_t) attribute_list_entry->name_size,
359 0 );
360 }
361 #endif
362 attribute_list_entry->name = (uint8_t *) memory_allocate(
363 sizeof( uint8_t ) * (size_t) attribute_list_entry->name_size );
364
365 if( attribute_list_entry->name == NULL )
366 {
367 libcerror_error_set(
368 error,
369 LIBCERROR_ERROR_DOMAIN_MEMORY,
370 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
371 "%s: unable to create name.",
372 function );
373
374 goto on_error;
375 }
376 if( memory_copy(
377 attribute_list_entry->name,
378 &( data[ data_offset ] ),
379 (size_t) attribute_list_entry->name_size ) == NULL )
380 {
381 libcerror_error_set(
382 error,
383 LIBCERROR_ERROR_DOMAIN_MEMORY,
384 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
385 "%s: unable to copy name.",
386 function );
387
388 goto on_error;
389 }
390 data_offset += (size_t) attribute_list_entry->name_size;
391
392 #if defined( HAVE_DEBUG_OUTPUT )
393 if( libcnotify_verbose != 0 )
394 {
395 if( libfsntfs_debug_print_utf16_string_value(
396 function,
397 "name\t\t\t",
398 attribute_list_entry->name,
399 (size_t) attribute_list_entry->name_size,
400 LIBUNA_ENDIAN_LITTLE,
401 error ) != 1 )
402 {
403 libcerror_error_set(
404 error,
405 LIBCERROR_ERROR_DOMAIN_RUNTIME,
406 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
407 "%s: unable to print UTF-16 string value.",
408 function );
409
410 goto on_error;
411 }
412 libcnotify_printf(
413 "\n" );
414 }
415 #endif
416 }
417 #if defined( HAVE_DEBUG_OUTPUT )
418 if( libcnotify_verbose != 0 )
419 {
420 if( data_offset < attribute_list_entry->size )
421 {
422 libcnotify_printf(
423 "%s: trailing data:\n",
424 function );
425 libcnotify_print_data(
426 &( data[ data_offset ] ),
427 (size_t) attribute_list_entry->size - data_offset,
428 0 );
429 }
430 else
431 {
432 libcnotify_printf(
433 "\n" );
434 }
435 }
436 #endif
437 return( 1 );
438
439 on_error:
440 if( attribute_list_entry->name != NULL )
441 {
442 memory_free(
443 attribute_list_entry->name );
444
445 attribute_list_entry->name = NULL;
446 }
447 attribute_list_entry->name_size = 0;
448
449 return( -1 );
450 }
451
452 /* Retrieves the attribute type
453 * Returns 1 if successful or -1 on error
454 */
libfsntfs_mft_attribute_list_entry_get_attribute_type(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,uint32_t * attribute_type,libcerror_error_t ** error)455 int libfsntfs_mft_attribute_list_entry_get_attribute_type(
456 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
457 uint32_t *attribute_type,
458 libcerror_error_t **error )
459 {
460 static char *function = "libfsntfs_mft_attribute_list_entry_get_attribute_type";
461
462 if( attribute_list_entry == NULL )
463 {
464 libcerror_error_set(
465 error,
466 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
467 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
468 "%s: invalid attribute list entry.",
469 function );
470
471 return( -1 );
472 }
473 if( attribute_type == NULL )
474 {
475 libcerror_error_set(
476 error,
477 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
478 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
479 "%s: invalid attribute type.",
480 function );
481
482 return( -1 );
483 }
484 *attribute_type = attribute_list_entry->attribute_type;
485
486 return( 1 );
487 }
488
489 /* Retrieves the file references as an MFT entry index and sequence number
490 * If the value sequence_number is NULL it will be ignored
491 * Returns 1 if successful or -1 on error
492 */
libfsntfs_mft_attribute_list_entry_get_file_reference(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,uint64_t * file_reference,libcerror_error_t ** error)493 int libfsntfs_mft_attribute_list_entry_get_file_reference(
494 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
495 uint64_t *file_reference,
496 libcerror_error_t **error )
497 {
498 static char *function = "libfsntfs_mft_attribute_list_entry_get_file_reference";
499
500 if( attribute_list_entry == NULL )
501 {
502 libcerror_error_set(
503 error,
504 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
505 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
506 "%s: invalid attribute list entry.",
507 function );
508
509 return( -1 );
510 }
511 if( file_reference == NULL )
512 {
513 libcerror_error_set(
514 error,
515 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
516 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
517 "%s: invalid file reference.",
518 function );
519
520 return( -1 );
521 }
522 *file_reference = attribute_list_entry->file_reference;
523
524 return( 1 );
525 }
526
527 /* Retrieves the size of the UTF-8 encoded name
528 * The returned size includes the end of string character
529 * Returns 1 if successful or -1 on error
530 */
libfsntfs_mft_attribute_list_entry_get_utf8_name_size(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,size_t * utf8_string_size,libcerror_error_t ** error)531 int libfsntfs_mft_attribute_list_entry_get_utf8_name_size(
532 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
533 size_t *utf8_string_size,
534 libcerror_error_t **error )
535 {
536 static char *function = "libfsntfs_mft_attribute_list_entry_get_utf8_name_size";
537
538 if( attribute_list_entry == NULL )
539 {
540 libcerror_error_set(
541 error,
542 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
543 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
544 "%s: invalid attribute list entry.",
545 function );
546
547 return( -1 );
548 }
549 if( ( attribute_list_entry->name == NULL )
550 || ( attribute_list_entry->name_size == 0 ) )
551 {
552 if( utf8_string_size == NULL )
553 {
554 libcerror_error_set(
555 error,
556 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
557 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
558 "%s: invalid UTF-8 string size.",
559 function );
560
561 return( -1 );
562 }
563 *utf8_string_size = 0;
564 }
565 else
566 {
567 if( libuna_utf8_string_size_from_utf16_stream(
568 attribute_list_entry->name,
569 (size_t) attribute_list_entry->name_size,
570 LIBUNA_ENDIAN_LITTLE,
571 utf8_string_size,
572 error ) != 1 )
573 {
574 libcerror_error_set(
575 error,
576 LIBCERROR_ERROR_DOMAIN_RUNTIME,
577 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
578 "%s: unable to retrieve UTF-8 string size.",
579 function );
580
581 return( -1 );
582 }
583 }
584 return( 1 );
585 }
586
587 /* Retrieves the UTF-8 encoded name
588 * The size should include the end of string character
589 * Returns 1 if successful or -1 on error
590 */
libfsntfs_mft_attribute_list_entry_get_utf8_name(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,uint8_t * utf8_string,size_t utf8_string_size,libcerror_error_t ** error)591 int libfsntfs_mft_attribute_list_entry_get_utf8_name(
592 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
593 uint8_t *utf8_string,
594 size_t utf8_string_size,
595 libcerror_error_t **error )
596 {
597 static char *function = "libfsntfs_mft_attribute_list_entry_get_utf8_name";
598
599 if( attribute_list_entry == NULL )
600 {
601 libcerror_error_set(
602 error,
603 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
604 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
605 "%s: invalid attribute list entry.",
606 function );
607
608 return( -1 );
609 }
610 if( attribute_list_entry->name == NULL )
611 {
612 libcerror_error_set(
613 error,
614 LIBCERROR_ERROR_DOMAIN_RUNTIME,
615 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
616 "%s: invalid attribute list entry - missing name.",
617 function );
618
619 return( -1 );
620 }
621 if( libuna_utf8_string_copy_from_utf16_stream(
622 utf8_string,
623 utf8_string_size,
624 attribute_list_entry->name,
625 (size_t) attribute_list_entry->name_size,
626 LIBUNA_ENDIAN_LITTLE,
627 error ) != 1 )
628 {
629 libcerror_error_set(
630 error,
631 LIBCERROR_ERROR_DOMAIN_RUNTIME,
632 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
633 "%s: unable to retrieve UTF-8 string.",
634 function );
635
636 return( -1 );
637 }
638 return( 1 );
639 }
640
641 /* Retrieves the size of the UTF-16 encoded name
642 * The returned size includes the end of string character
643 * Returns 1 if successful or -1 on error
644 */
libfsntfs_mft_attribute_list_entry_get_utf16_name_size(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,size_t * utf16_string_size,libcerror_error_t ** error)645 int libfsntfs_mft_attribute_list_entry_get_utf16_name_size(
646 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
647 size_t *utf16_string_size,
648 libcerror_error_t **error )
649 {
650 static char *function = "libfsntfs_mft_attribute_list_entry_get_utf16_name_size";
651
652 if( attribute_list_entry == NULL )
653 {
654 libcerror_error_set(
655 error,
656 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
657 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
658 "%s: invalid attribute list entry.",
659 function );
660
661 return( -1 );
662 }
663 if( ( attribute_list_entry->name == NULL )
664 || ( attribute_list_entry->name_size == 0 ) )
665 {
666 if( utf16_string_size == NULL )
667 {
668 libcerror_error_set(
669 error,
670 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
671 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
672 "%s: invalid UTF-16 string size.",
673 function );
674
675 return( -1 );
676 }
677 *utf16_string_size = 0;
678 }
679 else
680 {
681 if( libuna_utf16_string_size_from_utf16_stream(
682 attribute_list_entry->name,
683 (size_t) attribute_list_entry->name_size,
684 LIBUNA_ENDIAN_LITTLE,
685 utf16_string_size,
686 error ) != 1 )
687 {
688 libcerror_error_set(
689 error,
690 LIBCERROR_ERROR_DOMAIN_RUNTIME,
691 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
692 "%s: unable to retrieve UTF-16 string size.",
693 function );
694
695 return( -1 );
696 }
697 }
698 return( 1 );
699 }
700
701 /* Retrieves the UTF-16 encoded name
702 * The size should include the end of string character
703 * Returns 1 if successful or -1 on error
704 */
libfsntfs_mft_attribute_list_entry_get_utf16_name(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,uint16_t * utf16_string,size_t utf16_string_size,libcerror_error_t ** error)705 int libfsntfs_mft_attribute_list_entry_get_utf16_name(
706 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
707 uint16_t *utf16_string,
708 size_t utf16_string_size,
709 libcerror_error_t **error )
710 {
711 static char *function = "libfsntfs_mft_attribute_list_entry_get_utf16_name";
712
713 if( attribute_list_entry == NULL )
714 {
715 libcerror_error_set(
716 error,
717 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
718 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
719 "%s: invalid attribute list entry.",
720 function );
721
722 return( -1 );
723 }
724 if( attribute_list_entry->name == NULL )
725 {
726 libcerror_error_set(
727 error,
728 LIBCERROR_ERROR_DOMAIN_RUNTIME,
729 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
730 "%s: invalid attribute list entry - missing name.",
731 function );
732
733 return( -1 );
734 }
735 if( libuna_utf16_string_copy_from_utf16_stream(
736 utf16_string,
737 utf16_string_size,
738 attribute_list_entry->name,
739 (size_t) attribute_list_entry->name_size,
740 LIBUNA_ENDIAN_LITTLE,
741 error ) != 1 )
742 {
743 libcerror_error_set(
744 error,
745 LIBCERROR_ERROR_DOMAIN_RUNTIME,
746 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
747 "%s: unable to retrieve UTF-16 string.",
748 function );
749
750 return( -1 );
751 }
752 return( 1 );
753 }
754
755 /* Compares the name with an UTF-8 encoded string
756 * Returns 1 if the strings are equal, 0 if not or -1 on error
757 */
libfsntfs_mft_attribute_list_entry_compare_name_with_utf8_string(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,const uint8_t * utf8_string,size_t utf8_string_length,libcerror_error_t ** error)758 int libfsntfs_mft_attribute_list_entry_compare_name_with_utf8_string(
759 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
760 const uint8_t *utf8_string,
761 size_t utf8_string_length,
762 libcerror_error_t **error )
763 {
764 static char *function = "libfsntfs_mft_attribute_list_entry_compare_name_with_utf8_string";
765 int result = 0;
766
767 if( attribute_list_entry == NULL )
768 {
769 libcerror_error_set(
770 error,
771 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
772 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
773 "%s: invalid MFT attribute.",
774 function );
775
776 return( -1 );
777 }
778 if( attribute_list_entry->name == NULL )
779 {
780 return( 0 );
781 }
782 result = libfsntfs_name_compare_with_utf8_string(
783 attribute_list_entry->name,
784 attribute_list_entry->name_size,
785 utf8_string,
786 utf8_string_length,
787 0,
788 error );
789
790 if( result == -1 )
791 {
792 libcerror_error_set(
793 error,
794 LIBCERROR_ERROR_DOMAIN_RUNTIME,
795 LIBCERROR_RUNTIME_ERROR_GENERIC,
796 "%s: unable to compare UTF-8 string with name.",
797 function );
798
799 return( -1 );
800 }
801 else if( result == LIBUNA_COMPARE_EQUAL )
802 {
803 return( 1 );
804 }
805 return( 0 );
806 }
807
808 /* Compares the name with an UTF-16 encoded string
809 * Returns 1 if the strings are equal, 0 if not or -1 on error
810 */
libfsntfs_mft_attribute_list_entry_compare_name_with_utf16_string(libfsntfs_mft_attribute_list_entry_t * attribute_list_entry,const uint16_t * utf16_string,size_t utf16_string_length,libcerror_error_t ** error)811 int libfsntfs_mft_attribute_list_entry_compare_name_with_utf16_string(
812 libfsntfs_mft_attribute_list_entry_t *attribute_list_entry,
813 const uint16_t *utf16_string,
814 size_t utf16_string_length,
815 libcerror_error_t **error )
816 {
817 static char *function = "libfsntfs_mft_attribute_list_entry_compare_name_with_utf16_string";
818 int result = 0;
819
820 if( attribute_list_entry == NULL )
821 {
822 libcerror_error_set(
823 error,
824 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
825 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
826 "%s: invalid MFT attribute.",
827 function );
828
829 return( -1 );
830 }
831 if( attribute_list_entry->name == NULL )
832 {
833 return( 0 );
834 }
835 result = libfsntfs_name_compare_with_utf16_string(
836 attribute_list_entry->name,
837 attribute_list_entry->name_size,
838 utf16_string,
839 utf16_string_length,
840 0,
841 error );
842
843 if( result == -1 )
844 {
845 libcerror_error_set(
846 error,
847 LIBCERROR_ERROR_DOMAIN_RUNTIME,
848 LIBCERROR_RUNTIME_ERROR_GENERIC,
849 "%s: unable to compare UTF-16 string with name.",
850 function );
851
852 return( -1 );
853 }
854 else if( result == LIBUNA_COMPARE_EQUAL )
855 {
856 return( 1 );
857 }
858 return( 0 );
859 }
860
861