1 /*
2 * Python object definition of the libfsntfs volume 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_error.h"
31 #include "pyfsntfs_integer.h"
32 #include "pyfsntfs_libcerror.h"
33 #include "pyfsntfs_libfsntfs.h"
34 #include "pyfsntfs_python.h"
35 #include "pyfsntfs_unused.h"
36 #include "pyfsntfs_volume_name_attribute.h"
37
38 PyMethodDef pyfsntfs_volume_name_attribute_object_methods[] = {
39
40 /* Functions to access the attribute values */
41
42 { "get_name",
43 (PyCFunction) pyfsntfs_volume_name_attribute_get_name,
44 METH_NOARGS,
45 "get_name() -> Unicode string or None\n"
46 "\n"
47 "Returns the name." },
48
49 /* Sentinel */
50 { NULL, NULL, 0, NULL }
51 };
52
53 PyGetSetDef pyfsntfs_volume_name_attribute_object_get_set_definitions[] = {
54
55 { "name",
56 (getter) pyfsntfs_volume_name_attribute_get_name,
57 (setter) 0,
58 "The name.",
59 NULL },
60
61 /* Sentinel */
62 { NULL, NULL, NULL, NULL, NULL }
63 };
64
65 PyTypeObject pyfsntfs_volume_name_attribute_type_object = {
66 PyVarObject_HEAD_INIT( NULL, 0 )
67
68 /* tp_name */
69 "pyfsntfs.volume_name_attribute",
70 /* tp_basicsize */
71 sizeof( pyfsntfs_attribute_t ),
72 /* tp_itemsize */
73 0,
74 /* tp_dealloc */
75 0,
76 /* tp_print */
77 0,
78 /* tp_getattr */
79 0,
80 /* tp_setattr */
81 0,
82 /* tp_compare */
83 0,
84 /* tp_repr */
85 0,
86 /* tp_as_number */
87 0,
88 /* tp_as_sequence */
89 0,
90 /* tp_as_mapping */
91 0,
92 /* tp_hash */
93 0,
94 /* tp_call */
95 0,
96 /* tp_str */
97 0,
98 /* tp_getattro */
99 0,
100 /* tp_setattro */
101 0,
102 /* tp_as_buffer */
103 0,
104 /* tp_flags */
105 Py_TPFLAGS_DEFAULT,
106 /* tp_doc */
107 "pyfsntfs volume name attribute object (wraps libfsntfs_attribute_t type LIBFSNTFS_ATTRIBUTE_TYPE_VOLUME_NAME)",
108 /* tp_traverse */
109 0,
110 /* tp_clear */
111 0,
112 /* tp_richcompare */
113 0,
114 /* tp_weaklistoffset */
115 0,
116 /* tp_iter */
117 0,
118 /* tp_iternext */
119 0,
120 /* tp_methods */
121 pyfsntfs_volume_name_attribute_object_methods,
122 /* tp_members */
123 0,
124 /* tp_getset */
125 pyfsntfs_volume_name_attribute_object_get_set_definitions,
126 /* tp_base */
127 &pyfsntfs_attribute_type_object,
128 /* tp_dict */
129 0,
130 /* tp_descr_get */
131 0,
132 /* tp_descr_set */
133 0,
134 /* tp_dictoffset */
135 0,
136 /* tp_init */
137 0,
138 /* tp_alloc */
139 0,
140 /* tp_new */
141 0,
142 /* tp_free */
143 0,
144 /* tp_is_gc */
145 0,
146 /* tp_bases */
147 NULL,
148 /* tp_mro */
149 NULL,
150 /* tp_cache */
151 NULL,
152 /* tp_subclasses */
153 NULL,
154 /* tp_weaklist */
155 NULL,
156 /* tp_del */
157 0
158 };
159
160 /* Retrieves the name
161 * Returns a Python object if successful or NULL on error
162 */
pyfsntfs_volume_name_attribute_get_name(pyfsntfs_attribute_t * pyfsntfs_attribute,PyObject * arguments PYFSNTFS_ATTRIBUTE_UNUSED)163 PyObject *pyfsntfs_volume_name_attribute_get_name(
164 pyfsntfs_attribute_t *pyfsntfs_attribute,
165 PyObject *arguments PYFSNTFS_ATTRIBUTE_UNUSED )
166 {
167 libcerror_error_t *error = NULL;
168 PyObject *string_object = NULL;
169 const char *errors = NULL;
170 uint8_t *name = NULL;
171 static char *function = "pyfsntfs_volume_name_attribute_get_name";
172 size_t name_size = 0;
173 int result = 0;
174
175 PYFSNTFS_UNREFERENCED_PARAMETER( arguments )
176
177 if( pyfsntfs_attribute == NULL )
178 {
179 PyErr_Format(
180 PyExc_TypeError,
181 "%s: invalid attribute.",
182 function );
183
184 return( NULL );
185 }
186 Py_BEGIN_ALLOW_THREADS
187
188 result = libfsntfs_volume_name_attribute_get_utf8_name_size(
189 pyfsntfs_attribute->attribute,
190 &name_size,
191 &error );
192
193 Py_END_ALLOW_THREADS
194
195 if( result == -1 )
196 {
197 pyfsntfs_error_raise(
198 error,
199 PyExc_IOError,
200 "%s: unable to retrieve name size.",
201 function );
202
203 libcerror_error_free(
204 &error );
205
206 goto on_error;
207 }
208 else if( ( result == 0 )
209 || ( name_size == 0 ) )
210 {
211 Py_IncRef(
212 Py_None );
213
214 return( Py_None );
215 }
216 name = (uint8_t *) PyMem_Malloc(
217 sizeof( uint8_t ) * name_size );
218
219 if( name == NULL )
220 {
221 PyErr_Format(
222 PyExc_IOError,
223 "%s: unable to create name.",
224 function );
225
226 goto on_error;
227 }
228 Py_BEGIN_ALLOW_THREADS
229
230 result = libfsntfs_volume_name_attribute_get_utf8_name(
231 pyfsntfs_attribute->attribute,
232 name,
233 name_size,
234 &error );
235
236 Py_END_ALLOW_THREADS
237
238 if( result != 1 )
239 {
240 pyfsntfs_error_raise(
241 error,
242 PyExc_IOError,
243 "%s: unable to retrieve name.",
244 function );
245
246 libcerror_error_free(
247 &error );
248
249 goto on_error;
250 }
251 /* Pass the string length to PyUnicode_DecodeUTF8
252 * otherwise it makes the end of string character is part
253 * of the string
254 */
255 string_object = PyUnicode_DecodeUTF8(
256 (char *) name,
257 (Py_ssize_t) name_size - 1,
258 errors );
259
260 PyMem_Free(
261 name );
262
263 return( string_object );
264
265 on_error:
266 if( name != NULL )
267 {
268 PyMem_Free(
269 name );
270 }
271 return( NULL );
272 }
273
274