1 /*
2  * Python object definition of the libfsntfs file name attribute
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 <types.h>
24 
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28 
29 #include "pyfsntfs_attribute.h"
30 #include "pyfsntfs_datetime.h"
31 #include "pyfsntfs_error.h"
32 #include "pyfsntfs_file_name_attribute.h"
33 #include "pyfsntfs_integer.h"
34 #include "pyfsntfs_libcerror.h"
35 #include "pyfsntfs_libfsntfs.h"
36 #include "pyfsntfs_python.h"
37 #include "pyfsntfs_unused.h"
38 
39 PyMethodDef pyfsntfs_file_name_attribute_object_methods[] = {
40 
41 	/* Functions to access the attribute values */
42 
43 	{ "get_parent_file_reference",
44 	  (PyCFunction) pyfsntfs_file_name_attribute_get_parent_file_reference,
45 	  METH_NOARGS,
46 	  "get_parent_file_reference() -> Integer\n"
47 	  "\n"
48 	  "Returns the parent file reference, a combination of MFT entry index and sequence number." },
49 
50 	{ "get_creation_time",
51 	  (PyCFunction) pyfsntfs_file_name_attribute_get_creation_time,
52 	  METH_NOARGS,
53 	  "get_creation_time() -> Datetime or None\n"
54 	  "\n"
55 	  "Returns the creation date and time." },
56 
57 	{ "get_creation_time_as_integer",
58 	  (PyCFunction) pyfsntfs_file_name_attribute_get_creation_time_as_integer,
59 	  METH_NOARGS,
60 	  "get_creation_time_as_integer() -> Integer or None\n"
61 	  "\n"
62 	  "Returns the creation date and time as a 64-bit integer containing a FILETIME value." },
63 
64 	{ "get_modification_time",
65 	  (PyCFunction) pyfsntfs_file_name_attribute_get_modification_time,
66 	  METH_NOARGS,
67 	  "get_modification_time() -> Datetime or None\n"
68 	  "\n"
69 	  "Returns the modification date and time." },
70 
71 	{ "get_modification_time_as_integer",
72 	  (PyCFunction) pyfsntfs_file_name_attribute_get_modification_time_as_integer,
73 	  METH_NOARGS,
74 	  "get_modification_time_as_integer() -> Integer or None\n"
75 	  "\n"
76 	  "Returns the modification date and time as a 64-bit integer containing a FILETIME value." },
77 
78 	{ "get_access_time",
79 	  (PyCFunction) pyfsntfs_file_name_attribute_get_access_time,
80 	  METH_NOARGS,
81 	  "get_access_time() -> Datetime or None\n"
82 	  "\n"
83 	  "Returns the access date and time." },
84 
85 	{ "get_access_time_as_integer",
86 	  (PyCFunction) pyfsntfs_file_name_attribute_get_access_time_as_integer,
87 	  METH_NOARGS,
88 	  "get_access_time_as_integer() -> Integer or None\n"
89 	  "\n"
90 	  "Returns the access date and time as a 64-bit integer containing a FILETIME value." },
91 
92 	{ "get_entry_modification_time",
93 	  (PyCFunction) pyfsntfs_file_name_attribute_get_entry_modification_time,
94 	  METH_NOARGS,
95 	  "get_entry_modification_time() -> Datetime or None\n"
96 	  "\n"
97 	  "Returns the entry modification date and time." },
98 
99 	{ "get_entry_modification_time_as_integer",
100 	  (PyCFunction) pyfsntfs_file_name_attribute_get_entry_modification_time_as_integer,
101 	  METH_NOARGS,
102 	  "get_entry_modification_time_as_integer() -> Integer or None\n"
103 	  "\n"
104 	  "Returns the entry modification date and time as a 64-bit integer containing a FILETIME value." },
105 
106 	{ "get_file_attribute_flags",
107 	  (PyCFunction) pyfsntfs_file_name_attribute_get_file_attribute_flags,
108 	  METH_NOARGS,
109 	  "get_file_attribute_flags() -> Integer\n"
110 	  "\n"
111 	  "Returns the file attribute flags." },
112 
113 	{ "get_name_space",
114 	  (PyCFunction) pyfsntfs_file_name_attribute_get_name_space,
115 	  METH_NOARGS,
116 	  "get_name_space() -> Integer\n"
117 	  "\n"
118 	  "Returns the name space." },
119 
120 	{ "get_name",
121 	  (PyCFunction) pyfsntfs_file_name_attribute_get_name,
122 	  METH_NOARGS,
123 	  "get_name() -> Unicode string or None\n"
124 	  "\n"
125 	  "Returns the name." },
126 
127 	/* Sentinel */
128 	{ NULL, NULL, 0, NULL }
129 };
130 
131 PyGetSetDef pyfsntfs_file_name_attribute_object_get_set_definitions[] = {
132 
133 	{ "parent_file_reference",
134 	  (getter) pyfsntfs_file_name_attribute_get_parent_file_reference,
135 	  (setter) 0,
136 	  "The parent file reference, a combination of MFT entry index and sequence number.",
137 	  NULL },
138 
139 	{ "creation_time",
140 	  (getter) pyfsntfs_file_name_attribute_get_creation_time,
141 	  (setter) 0,
142 	  "The creation date and time.",
143 	  NULL },
144 
145 	{ "modification_time",
146 	  (getter) pyfsntfs_file_name_attribute_get_modification_time,
147 	  (setter) 0,
148 	  "The modification date and time.",
149 	  NULL },
150 
151 	{ "access_time",
152 	  (getter) pyfsntfs_file_name_attribute_get_access_time,
153 	  (setter) 0,
154 	  "The access date and time.",
155 	  NULL },
156 
157 	{ "entry_modification_time",
158 	  (getter) pyfsntfs_file_name_attribute_get_entry_modification_time,
159 	  (setter) 0,
160 	  "The entry modification date and time.",
161 	  NULL },
162 
163 	{ "file_attribute_flags",
164 	  (getter) pyfsntfs_file_name_attribute_get_file_attribute_flags,
165 	  (setter) 0,
166 	  "The file attribute flags.",
167 	  NULL },
168 
169 	{ "name_space",
170 	  (getter) pyfsntfs_file_name_attribute_get_name_space,
171 	  (setter) 0,
172 	  "The name space.",
173 	  NULL },
174 
175 	{ "name",
176 	  (getter) pyfsntfs_file_name_attribute_get_name,
177 	  (setter) 0,
178 	  "The name.",
179 	  NULL },
180 
181 	/* Sentinel */
182 	{ NULL, NULL, NULL, NULL, NULL }
183 };
184 
185 PyTypeObject pyfsntfs_file_name_attribute_type_object = {
186 	PyVarObject_HEAD_INIT( NULL, 0 )
187 
188 	/* tp_name */
189 	"pyfsntfs.file_name_attribute",
190 	/* tp_basicsize */
191 	sizeof( pyfsntfs_attribute_t ),
192 	/* tp_itemsize */
193 	0,
194 	/* tp_dealloc */
195 	0,
196 	/* tp_print */
197 	0,
198 	/* tp_getattr */
199 	0,
200 	/* tp_setattr */
201 	0,
202 	/* tp_compare */
203 	0,
204 	/* tp_repr */
205 	0,
206 	/* tp_as_number */
207 	0,
208 	/* tp_as_sequence */
209 	0,
210 	/* tp_as_mapping */
211 	0,
212 	/* tp_hash */
213 	0,
214 	/* tp_call */
215 	0,
216 	/* tp_str */
217 	0,
218 	/* tp_getattro */
219 	0,
220 	/* tp_setattro */
221 	0,
222 	/* tp_as_buffer */
223 	0,
224 	/* tp_flags */
225 	Py_TPFLAGS_DEFAULT,
226 	/* tp_doc */
227 	"pyfsntfs file name attribute object (wraps libfsntfs_attribute_t type LIBFSNTFS_ATTRIBUTE_TYPE_FILE_NAME)",
228 	/* tp_traverse */
229 	0,
230 	/* tp_clear */
231 	0,
232 	/* tp_richcompare */
233 	0,
234 	/* tp_weaklistoffset */
235 	0,
236 	/* tp_iter */
237 	0,
238 	/* tp_iternext */
239 	0,
240 	/* tp_methods */
241 	pyfsntfs_file_name_attribute_object_methods,
242 	/* tp_members */
243 	0,
244 	/* tp_getset */
245 	pyfsntfs_file_name_attribute_object_get_set_definitions,
246 	/* tp_base */
247 	&pyfsntfs_attribute_type_object,
248 	/* tp_dict */
249 	0,
250 	/* tp_descr_get */
251 	0,
252 	/* tp_descr_set */
253 	0,
254 	/* tp_dictoffset */
255 	0,
256 	/* tp_init */
257 	0,
258 	/* tp_alloc */
259 	0,
260 	/* tp_new */
261 	0,
262 	/* tp_free */
263 	0,
264 	/* tp_is_gc */
265 	0,
266 	/* tp_bases */
267 	NULL,
268 	/* tp_mro */
269 	NULL,
270 	/* tp_cache */
271 	NULL,
272 	/* tp_subclasses */
273 	NULL,
274 	/* tp_weaklist */
275 	NULL,
276 	/* tp_del */
277 	0
278 };
279 
280 /* Retrieves the parent file reference
281  * Returns a Python object if successful or NULL on error
282  */
pyfsntfs_file_name_attribute_get_parent_file_reference(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)283 PyObject *pyfsntfs_file_name_attribute_get_parent_file_reference(
284            pyfsntfs_attribute_t *pyfsntfs_attribute,
285            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
286 {
287 	libcerror_error_t *error = NULL;
288 	PyObject *integer_object = NULL;
289 	static char *function    = "pyfsntfs_file_name_attribute_get_parent_file_reference";
290 	uint64_t file_reference  = 0;
291 	int result               = 0;
292 
293 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
294 
295 	if( pyfsntfs_attribute == NULL )
296 	{
297 		PyErr_Format(
298 		 PyExc_TypeError,
299 		 "%s: invalid attribute.",
300 		 function );
301 
302 		return( NULL );
303 	}
304 	Py_BEGIN_ALLOW_THREADS
305 
306 	result = libfsntfs_file_name_attribute_get_parent_file_reference(
307 	          pyfsntfs_attribute->attribute,
308 	          &file_reference,
309 	          &error );
310 
311 	Py_END_ALLOW_THREADS
312 
313 	if( result != 1 )
314 	{
315 		pyfsntfs_error_raise(
316 		 error,
317 		 PyExc_IOError,
318 		 "%s: unable to retrieve parent file reference.",
319 		 function );
320 
321 		libcerror_error_free(
322 		 &error );
323 
324 		return( NULL );
325 	}
326 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
327 	                  file_reference );
328 
329 	return( integer_object );
330 }
331 
332 /* Retrieves the creation date and time
333  * Returns a Python object if successful or NULL on error
334  */
pyfsntfs_file_name_attribute_get_creation_time(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)335 PyObject *pyfsntfs_file_name_attribute_get_creation_time(
336            pyfsntfs_attribute_t *pyfsntfs_attribute,
337            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
338 {
339 	libcerror_error_t *error   = NULL;
340 	PyObject *date_time_object = NULL;
341 	static char *function      = "pyfsntfs_file_name_attribute_get_creation_time";
342 	uint64_t filetime          = 0;
343 	int result                 = 0;
344 
345 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
346 
347 	if( pyfsntfs_attribute == NULL )
348 	{
349 		PyErr_Format(
350 		 PyExc_ValueError,
351 		 "%s: invalid attribute.",
352 		 function );
353 
354 		return( NULL );
355 	}
356 	Py_BEGIN_ALLOW_THREADS
357 
358 	result = libfsntfs_file_name_attribute_get_creation_time(
359 	          pyfsntfs_attribute->attribute,
360 	          &filetime,
361 	          &error );
362 
363 	Py_END_ALLOW_THREADS
364 
365 	if( result == -1 )
366 	{
367 		pyfsntfs_error_raise(
368 		 error,
369 		 PyExc_IOError,
370 		 "%s: unable to retrieve creation time.",
371 		 function );
372 
373 		libcerror_error_free(
374 		 &error );
375 
376 		return( NULL );
377 	}
378 	else if( result == 0 )
379 	{
380 		Py_IncRef(
381 		 Py_None );
382 
383 		return( Py_None );
384 	}
385 	date_time_object = pyfsntfs_datetime_new_from_filetime(
386 	                    filetime );
387 
388 	return( date_time_object );
389 }
390 
391 /* Retrieves the creation date and time as an integer
392  * Returns a Python object if successful or NULL on error
393  */
pyfsntfs_file_name_attribute_get_creation_time_as_integer(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)394 PyObject *pyfsntfs_file_name_attribute_get_creation_time_as_integer(
395            pyfsntfs_attribute_t *pyfsntfs_attribute,
396            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
397 {
398 	libcerror_error_t *error = NULL;
399 	PyObject *integer_object = NULL;
400 	static char *function    = "pyfsntfs_file_name_attribute_get_creation_time_as_integer";
401 	uint64_t filetime        = 0;
402 	int result               = 0;
403 
404 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
405 
406 	if( pyfsntfs_attribute == NULL )
407 	{
408 		PyErr_Format(
409 		 PyExc_ValueError,
410 		 "%s: invalid attribute.",
411 		 function );
412 
413 		return( NULL );
414 	}
415 	Py_BEGIN_ALLOW_THREADS
416 
417 	result = libfsntfs_file_name_attribute_get_creation_time(
418 	          pyfsntfs_attribute->attribute,
419 	          &filetime,
420 	          &error );
421 
422 	Py_END_ALLOW_THREADS
423 
424 	if( result == -1 )
425 	{
426 		pyfsntfs_error_raise(
427 		 error,
428 		 PyExc_IOError,
429 		 "%s: unable to retrieve creation time.",
430 		 function );
431 
432 		libcerror_error_free(
433 		 &error );
434 
435 		return( NULL );
436 	}
437 	else if( result == 0 )
438 	{
439 		Py_IncRef(
440 		 Py_None );
441 
442 		return( Py_None );
443 	}
444 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
445 	                  filetime );
446 
447 	return( integer_object );
448 }
449 
450 /* Retrieves the modification date and time
451  * Returns a Python object if successful or NULL on error
452  */
pyfsntfs_file_name_attribute_get_modification_time(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)453 PyObject *pyfsntfs_file_name_attribute_get_modification_time(
454            pyfsntfs_attribute_t *pyfsntfs_attribute,
455            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
456 {
457 	libcerror_error_t *error   = NULL;
458 	PyObject *date_time_object = NULL;
459 	static char *function      = "pyfsntfs_file_name_attribute_get_modification_time";
460 	uint64_t filetime          = 0;
461 	int result                 = 0;
462 
463 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
464 
465 	if( pyfsntfs_attribute == NULL )
466 	{
467 		PyErr_Format(
468 		 PyExc_ValueError,
469 		 "%s: invalid attribute.",
470 		 function );
471 
472 		return( NULL );
473 	}
474 	Py_BEGIN_ALLOW_THREADS
475 
476 	result = libfsntfs_file_name_attribute_get_modification_time(
477 	          pyfsntfs_attribute->attribute,
478 	          &filetime,
479 	          &error );
480 
481 	Py_END_ALLOW_THREADS
482 
483 	if( result == -1 )
484 	{
485 		pyfsntfs_error_raise(
486 		 error,
487 		 PyExc_IOError,
488 		 "%s: unable to retrieve modification time.",
489 		 function );
490 
491 		libcerror_error_free(
492 		 &error );
493 
494 		return( NULL );
495 	}
496 	else if( result == 0 )
497 	{
498 		Py_IncRef(
499 		 Py_None );
500 
501 		return( Py_None );
502 	}
503 	date_time_object = pyfsntfs_datetime_new_from_filetime(
504 	                    filetime );
505 
506 	return( date_time_object );
507 }
508 
509 /* Retrieves the modification date and time as an integer
510  * Returns a Python object if successful or NULL on error
511  */
pyfsntfs_file_name_attribute_get_modification_time_as_integer(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)512 PyObject *pyfsntfs_file_name_attribute_get_modification_time_as_integer(
513            pyfsntfs_attribute_t *pyfsntfs_attribute,
514            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
515 {
516 	libcerror_error_t *error = NULL;
517 	PyObject *integer_object = NULL;
518 	static char *function    = "pyfsntfs_file_name_attribute_get_modification_time_as_integer";
519 	uint64_t filetime        = 0;
520 	int result               = 0;
521 
522 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
523 
524 	if( pyfsntfs_attribute == NULL )
525 	{
526 		PyErr_Format(
527 		 PyExc_ValueError,
528 		 "%s: invalid attribute.",
529 		 function );
530 
531 		return( NULL );
532 	}
533 	Py_BEGIN_ALLOW_THREADS
534 
535 	result = libfsntfs_file_name_attribute_get_modification_time(
536 	          pyfsntfs_attribute->attribute,
537 	          &filetime,
538 	          &error );
539 
540 	Py_END_ALLOW_THREADS
541 
542 	if( result == -1 )
543 	{
544 		pyfsntfs_error_raise(
545 		 error,
546 		 PyExc_IOError,
547 		 "%s: unable to retrieve modification time.",
548 		 function );
549 
550 		libcerror_error_free(
551 		 &error );
552 
553 		return( NULL );
554 	}
555 	else if( result == 0 )
556 	{
557 		Py_IncRef(
558 		 Py_None );
559 
560 		return( Py_None );
561 	}
562 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
563 	                  filetime );
564 
565 	return( integer_object );
566 }
567 
568 /* Retrieves the access date and time
569  * Returns a Python object if successful or NULL on error
570  */
pyfsntfs_file_name_attribute_get_access_time(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)571 PyObject *pyfsntfs_file_name_attribute_get_access_time(
572            pyfsntfs_attribute_t *pyfsntfs_attribute,
573            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
574 {
575 	libcerror_error_t *error   = NULL;
576 	PyObject *date_time_object = NULL;
577 	static char *function      = "pyfsntfs_file_name_attribute_get_access_time";
578 	uint64_t filetime          = 0;
579 	int result                 = 0;
580 
581 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
582 
583 	if( pyfsntfs_attribute == NULL )
584 	{
585 		PyErr_Format(
586 		 PyExc_ValueError,
587 		 "%s: invalid attribute.",
588 		 function );
589 
590 		return( NULL );
591 	}
592 	Py_BEGIN_ALLOW_THREADS
593 
594 	result = libfsntfs_file_name_attribute_get_access_time(
595 	          pyfsntfs_attribute->attribute,
596 	          &filetime,
597 	          &error );
598 
599 	Py_END_ALLOW_THREADS
600 
601 	if( result == -1 )
602 	{
603 		pyfsntfs_error_raise(
604 		 error,
605 		 PyExc_IOError,
606 		 "%s: unable to retrieve access time.",
607 		 function );
608 
609 		libcerror_error_free(
610 		 &error );
611 
612 		return( NULL );
613 	}
614 	else if( result == 0 )
615 	{
616 		Py_IncRef(
617 		 Py_None );
618 
619 		return( Py_None );
620 	}
621 	date_time_object = pyfsntfs_datetime_new_from_filetime(
622 	                    filetime );
623 
624 	return( date_time_object );
625 }
626 
627 /* Retrieves the access date and time as an integer
628  * Returns a Python object if successful or NULL on error
629  */
pyfsntfs_file_name_attribute_get_access_time_as_integer(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)630 PyObject *pyfsntfs_file_name_attribute_get_access_time_as_integer(
631            pyfsntfs_attribute_t *pyfsntfs_attribute,
632            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
633 {
634 	libcerror_error_t *error = NULL;
635 	PyObject *integer_object = NULL;
636 	static char *function    = "pyfsntfs_file_name_attribute_get_access_time_as_integer";
637 	uint64_t filetime        = 0;
638 	int result               = 0;
639 
640 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
641 
642 	if( pyfsntfs_attribute == NULL )
643 	{
644 		PyErr_Format(
645 		 PyExc_ValueError,
646 		 "%s: invalid attribute.",
647 		 function );
648 
649 		return( NULL );
650 	}
651 	Py_BEGIN_ALLOW_THREADS
652 
653 	result = libfsntfs_file_name_attribute_get_access_time(
654 	          pyfsntfs_attribute->attribute,
655 	          &filetime,
656 	          &error );
657 
658 	Py_END_ALLOW_THREADS
659 
660 	if( result == -1 )
661 	{
662 		pyfsntfs_error_raise(
663 		 error,
664 		 PyExc_IOError,
665 		 "%s: unable to retrieve access time.",
666 		 function );
667 
668 		libcerror_error_free(
669 		 &error );
670 
671 		return( NULL );
672 	}
673 	else if( result == 0 )
674 	{
675 		Py_IncRef(
676 		 Py_None );
677 
678 		return( Py_None );
679 	}
680 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
681 	                  filetime );
682 
683 	return( integer_object );
684 }
685 
686 /* Retrieves the entry modification date and time
687  * Returns a Python object if successful or NULL on error
688  */
pyfsntfs_file_name_attribute_get_entry_modification_time(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)689 PyObject *pyfsntfs_file_name_attribute_get_entry_modification_time(
690            pyfsntfs_attribute_t *pyfsntfs_attribute,
691            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
692 {
693 	libcerror_error_t *error   = NULL;
694 	PyObject *date_time_object = NULL;
695 	static char *function      = "pyfsntfs_file_name_attribute_get_entry_modification_time";
696 	uint64_t filetime          = 0;
697 	int result                 = 0;
698 
699 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
700 
701 	if( pyfsntfs_attribute == NULL )
702 	{
703 		PyErr_Format(
704 		 PyExc_ValueError,
705 		 "%s: invalid attribute.",
706 		 function );
707 
708 		return( NULL );
709 	}
710 	Py_BEGIN_ALLOW_THREADS
711 
712 	result = libfsntfs_file_name_attribute_get_entry_modification_time(
713 	          pyfsntfs_attribute->attribute,
714 	          &filetime,
715 	          &error );
716 
717 	Py_END_ALLOW_THREADS
718 
719 	if( result == -1 )
720 	{
721 		pyfsntfs_error_raise(
722 		 error,
723 		 PyExc_IOError,
724 		 "%s: unable to retrieve entry modification time.",
725 		 function );
726 
727 		libcerror_error_free(
728 		 &error );
729 
730 		return( NULL );
731 	}
732 	else if( result == 0 )
733 	{
734 		Py_IncRef(
735 		 Py_None );
736 
737 		return( Py_None );
738 	}
739 	date_time_object = pyfsntfs_datetime_new_from_filetime(
740 	                    filetime );
741 
742 	return( date_time_object );
743 }
744 
745 /* Retrieves the entry modification date and time as an integer
746  * Returns a Python object if successful or NULL on error
747  */
pyfsntfs_file_name_attribute_get_entry_modification_time_as_integer(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)748 PyObject *pyfsntfs_file_name_attribute_get_entry_modification_time_as_integer(
749            pyfsntfs_attribute_t *pyfsntfs_attribute,
750            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
751 {
752 	libcerror_error_t *error = NULL;
753 	PyObject *integer_object = NULL;
754 	static char *function    = "pyfsntfs_file_name_attribute_get_entry_modification_time_as_integer";
755 	uint64_t filetime        = 0;
756 	int result               = 0;
757 
758 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
759 
760 	if( pyfsntfs_attribute == NULL )
761 	{
762 		PyErr_Format(
763 		 PyExc_ValueError,
764 		 "%s: invalid attribute.",
765 		 function );
766 
767 		return( NULL );
768 	}
769 	Py_BEGIN_ALLOW_THREADS
770 
771 	result = libfsntfs_file_name_attribute_get_entry_modification_time(
772 	          pyfsntfs_attribute->attribute,
773 	          &filetime,
774 	          &error );
775 
776 	Py_END_ALLOW_THREADS
777 
778 	if( result == -1 )
779 	{
780 		pyfsntfs_error_raise(
781 		 error,
782 		 PyExc_IOError,
783 		 "%s: unable to retrieve entry modification time.",
784 		 function );
785 
786 		libcerror_error_free(
787 		 &error );
788 
789 		return( NULL );
790 	}
791 	else if( result == 0 )
792 	{
793 		Py_IncRef(
794 		 Py_None );
795 
796 		return( Py_None );
797 	}
798 	integer_object = pyfsntfs_integer_signed_new_from_64bit(
799 	                  filetime );
800 
801 	return( integer_object );
802 }
803 
804 /* Retrieves the file attribute flags
805  * Returns a Python object if successful or NULL on error
806  */
pyfsntfs_file_name_attribute_get_file_attribute_flags(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)807 PyObject *pyfsntfs_file_name_attribute_get_file_attribute_flags(
808            pyfsntfs_attribute_t *pyfsntfs_attribute,
809            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
810 {
811 	libcerror_error_t *error      = NULL;
812 	PyObject *integer_object      = NULL;
813 	static char *function         = "pyfsntfs_file_name_attribute_get_file_attribute_flags";
814 	uint32_t file_attribute_flags = 0;
815 	int result                    = 0;
816 
817 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
818 
819 	if( pyfsntfs_attribute == NULL )
820 	{
821 		PyErr_Format(
822 		 PyExc_TypeError,
823 		 "%s: invalid attribute.",
824 		 function );
825 
826 		return( NULL );
827 	}
828 	Py_BEGIN_ALLOW_THREADS
829 
830 	result = libfsntfs_file_name_attribute_get_file_attribute_flags(
831 	          pyfsntfs_attribute->attribute,
832 	          &file_attribute_flags,
833 	          &error );
834 
835 	Py_END_ALLOW_THREADS
836 
837 	if( result != 1 )
838 	{
839 		pyfsntfs_error_raise(
840 		 error,
841 		 PyExc_IOError,
842 		 "%s: unable to retrieve file attribute flags.",
843 		 function );
844 
845 		libcerror_error_free(
846 		 &error );
847 
848 		return( NULL );
849 	}
850 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
851 	                  (uint64_t) file_attribute_flags );
852 
853 	return( integer_object );
854 }
855 
856 /* Retrieves the name space
857  * Returns a Python object if successful or NULL on error
858  */
pyfsntfs_file_name_attribute_get_name_space(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)859 PyObject *pyfsntfs_file_name_attribute_get_name_space(
860            pyfsntfs_attribute_t *pyfsntfs_attribute,
861            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
862 {
863 	PyObject *integer_object = NULL;
864 	libcerror_error_t *error = NULL;
865 	static char *function    = "pyfsntfs_file_name_attribute_get_name_space";
866 	uint8_t name_space       = 0;
867 	int result               = 0;
868 
869 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
870 
871 	if( pyfsntfs_attribute == NULL )
872 	{
873 		PyErr_Format(
874 		 PyExc_TypeError,
875 		 "%s: invalid attribute.",
876 		 function );
877 
878 		return( NULL );
879 	}
880 	Py_BEGIN_ALLOW_THREADS
881 
882 	result = libfsntfs_file_name_attribute_get_name_space(
883 	          pyfsntfs_attribute->attribute,
884 	          &name_space,
885 	          &error );
886 
887 	Py_END_ALLOW_THREADS
888 
889 	if( result != 1 )
890 	{
891 		pyfsntfs_error_raise(
892 		 error,
893 		 PyExc_IOError,
894 		 "%s: unable to retrieve name space.",
895 		 function );
896 
897 		libcerror_error_free(
898 		 &error );
899 
900 		return( NULL );
901 	}
902 	integer_object = pyfsntfs_integer_unsigned_new_from_64bit(
903 	                  (uint64_t) name_space );
904 
905 	return( integer_object );
906 }
907 
908 /* Retrieves the name
909  * Returns a Python object if successful or NULL on error
910  */
pyfsntfs_file_name_attribute_get_name(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)911 PyObject *pyfsntfs_file_name_attribute_get_name(
912            pyfsntfs_attribute_t *pyfsntfs_attribute,
913            PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
914 {
915 	libcerror_error_t *error = NULL;
916 	PyObject *string_object  = NULL;
917 	const char *errors       = NULL;
918 	uint8_t *name            = NULL;
919 	static char *function    = "pyfsntfs_file_name_attribute_get_name";
920 	size_t name_size         = 0;
921 	int result               = 0;
922 
923 	PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
924 
925 	if( pyfsntfs_attribute == NULL )
926 	{
927 		PyErr_Format(
928 		 PyExc_TypeError,
929 		 "%s: invalid attribute.",
930 		 function );
931 
932 		return( NULL );
933 	}
934 	Py_BEGIN_ALLOW_THREADS
935 
936 	result = libfsntfs_file_name_attribute_get_utf8_name_size(
937 	          pyfsntfs_attribute->attribute,
938 	          &name_size,
939 	          &error );
940 
941 	Py_END_ALLOW_THREADS
942 
943 	if( result == -1 )
944 	{
945 		pyfsntfs_error_raise(
946 		 error,
947 		 PyExc_IOError,
948 		 "%s: unable to retrieve name size.",
949 		 function );
950 
951 		libcerror_error_free(
952 		 &error );
953 
954 		goto on_error;
955 	}
956 	else if( ( result == 0 )
957 	      || ( name_size == 0 ) )
958 	{
959 		Py_IncRef(
960 		 Py_None );
961 
962 		return( Py_None );
963 	}
964 	name = (uint8_t *) PyMem_Malloc(
965 	                    sizeof( uint8_t ) * name_size );
966 
967 	if( name == NULL )
968 	{
969 		PyErr_Format(
970 		 PyExc_IOError,
971 		 "%s: unable to create name.",
972 		 function );
973 
974 		goto on_error;
975 	}
976 	Py_BEGIN_ALLOW_THREADS
977 
978 	result = libfsntfs_file_name_attribute_get_utf8_name(
979 		  pyfsntfs_attribute->attribute,
980 		  name,
981 		  name_size,
982 		  &error );
983 
984 	Py_END_ALLOW_THREADS
985 
986 	if( result != 1 )
987 	{
988 		pyfsntfs_error_raise(
989 		 error,
990 		 PyExc_IOError,
991 		 "%s: unable to retrieve name.",
992 		 function );
993 
994 		libcerror_error_free(
995 		 &error );
996 
997 		goto on_error;
998 	}
999 	/* Pass the string length to PyUnicode_DecodeUTF8
1000 	 * otherwise it makes the end of string character is part
1001 	 * of the string
1002 	 */
1003 	string_object = PyUnicode_DecodeUTF8(
1004 			 (char *) name,
1005 			 (Py_ssize_t) name_size - 1,
1006 			 errors );
1007 
1008 	PyMem_Free(
1009 	 name );
1010 
1011 	return( string_object );
1012 
1013 on_error:
1014 	if( name != NULL )
1015 	{
1016 		PyMem_Free(
1017 		 name );
1018 	}
1019 	return( NULL );
1020 }
1021 
1022