1 /*
2 * Directory entry functions
3 *
4 * Copyright (C) 2020-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 <memory.h>
24 #include <types.h>
25
26 #include "libfsxfs_directory_entry.h"
27 #include "libfsxfs_libcerror.h"
28 #include "libfsxfs_libuna.h"
29
30 /* Creates directory entry
31 * Make sure the value directory_entry is referencing, is set to NULL
32 * Returns 1 if successful or -1 on error
33 */
libfsxfs_directory_entry_initialize(libfsxfs_directory_entry_t ** directory_entry,libcerror_error_t ** error)34 int libfsxfs_directory_entry_initialize(
35 libfsxfs_directory_entry_t **directory_entry,
36 libcerror_error_t **error )
37 {
38 static char *function = "libfsxfs_directory_entry_initialize";
39
40 if( directory_entry == NULL )
41 {
42 libcerror_error_set(
43 error,
44 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
45 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
46 "%s: invalid directory entry.",
47 function );
48
49 return( -1 );
50 }
51 if( *directory_entry != NULL )
52 {
53 libcerror_error_set(
54 error,
55 LIBCERROR_ERROR_DOMAIN_RUNTIME,
56 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
57 "%s: invalid directory entry value already set.",
58 function );
59
60 return( -1 );
61 }
62 *directory_entry = memory_allocate_structure(
63 libfsxfs_directory_entry_t );
64
65 if( *directory_entry == NULL )
66 {
67 libcerror_error_set(
68 error,
69 LIBCERROR_ERROR_DOMAIN_MEMORY,
70 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
71 "%s: unable to create directory entry.",
72 function );
73
74 goto on_error;
75 }
76 if( memory_set(
77 *directory_entry,
78 0,
79 sizeof( libfsxfs_directory_entry_t ) ) == NULL )
80 {
81 libcerror_error_set(
82 error,
83 LIBCERROR_ERROR_DOMAIN_MEMORY,
84 LIBCERROR_MEMORY_ERROR_SET_FAILED,
85 "%s: unable to clear directory entry.",
86 function );
87
88 goto on_error;
89 }
90 return( 1 );
91
92 on_error:
93 if( *directory_entry != NULL )
94 {
95 memory_free(
96 *directory_entry );
97
98 *directory_entry = NULL;
99 }
100 return( -1 );
101 }
102
103 /* Frees directory entry
104 * Returns 1 if successful or -1 on error
105 */
libfsxfs_directory_entry_free(libfsxfs_directory_entry_t ** directory_entry,libcerror_error_t ** error)106 int libfsxfs_directory_entry_free(
107 libfsxfs_directory_entry_t **directory_entry,
108 libcerror_error_t **error )
109 {
110 static char *function = "libfsxfs_directory_entry_free";
111
112 if( directory_entry == NULL )
113 {
114 libcerror_error_set(
115 error,
116 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
117 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
118 "%s: invalid directory entry.",
119 function );
120
121 return( -1 );
122 }
123 if( *directory_entry != NULL )
124 {
125 memory_free(
126 *directory_entry );
127
128 *directory_entry = NULL;
129 }
130 return( 1 );
131 }
132
133 /* Clones the directory entry value
134 * Returns 1 if successful or -1 on error
135 */
libfsxfs_directory_entry_clone(libfsxfs_directory_entry_t ** destination_directory_entry,libfsxfs_directory_entry_t * source_directory_entry,libcerror_error_t ** error)136 int libfsxfs_directory_entry_clone(
137 libfsxfs_directory_entry_t **destination_directory_entry,
138 libfsxfs_directory_entry_t *source_directory_entry,
139 libcerror_error_t **error )
140 {
141 static char *function = "libfsxfs_directory_entry_clone";
142
143 if( destination_directory_entry == NULL )
144 {
145 libcerror_error_set(
146 error,
147 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
148 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
149 "%s: invalid destination directory entry.",
150 function );
151
152 return( -1 );
153 }
154 if( *destination_directory_entry != NULL )
155 {
156 libcerror_error_set(
157 error,
158 LIBCERROR_ERROR_DOMAIN_RUNTIME,
159 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
160 "%s: invalid destination directory entry value already set.",
161 function );
162
163 return( -1 );
164 }
165 if( source_directory_entry == NULL )
166 {
167 *destination_directory_entry = NULL;
168
169 return( 1 );
170 }
171 *destination_directory_entry = memory_allocate_structure(
172 libfsxfs_directory_entry_t );
173
174 if( *destination_directory_entry == NULL )
175 {
176 libcerror_error_set(
177 error,
178 LIBCERROR_ERROR_DOMAIN_MEMORY,
179 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
180 "%s: unable to create destination directory entry.",
181 function );
182
183 goto on_error;
184 }
185 if( memory_copy(
186 *destination_directory_entry,
187 source_directory_entry,
188 sizeof( libfsxfs_directory_entry_t ) ) == NULL )
189 {
190 libcerror_error_set(
191 error,
192 LIBCERROR_ERROR_DOMAIN_MEMORY,
193 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
194 "%s: unable to copy source to destination directory entry.",
195 function );
196
197 goto on_error;
198 }
199 return( 1 );
200
201 on_error:
202 if( *destination_directory_entry != NULL )
203 {
204 memory_free(
205 *destination_directory_entry );
206
207 *destination_directory_entry = NULL;
208 }
209 return( -1 );
210 }
211
212 /* Retrieves the inode number
213 * Returns 1 if successful or -1 on error
214 */
libfsxfs_directory_entry_get_inode_number(libfsxfs_directory_entry_t * directory_entry,uint64_t * inode_number,libcerror_error_t ** error)215 int libfsxfs_directory_entry_get_inode_number(
216 libfsxfs_directory_entry_t *directory_entry,
217 uint64_t *inode_number,
218 libcerror_error_t **error )
219 {
220 static char *function = "libfsxfs_directory_entry_get_inode_number";
221
222 if( directory_entry == NULL )
223 {
224 libcerror_error_set(
225 error,
226 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
227 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
228 "%s: invalid directory entry.",
229 function );
230
231 return( -1 );
232 }
233 if( inode_number == NULL )
234 {
235 libcerror_error_set(
236 error,
237 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
239 "%s: invalid inode number.",
240 function );
241
242 return( -1 );
243 }
244 *inode_number = directory_entry->inode_number;
245
246 return( 1 );
247 }
248
249 /* Retrieves the size of the UTF-8 encoded name
250 * The returned size includes the end of string character
251 * Returns 1 if successful or -1 on error
252 */
libfsxfs_directory_entry_get_utf8_name_size(libfsxfs_directory_entry_t * directory_entry,size_t * utf8_string_size,libcerror_error_t ** error)253 int libfsxfs_directory_entry_get_utf8_name_size(
254 libfsxfs_directory_entry_t *directory_entry,
255 size_t *utf8_string_size,
256 libcerror_error_t **error )
257 {
258 static char *function = "libfsxfs_directory_entry_get_utf8_name_size";
259
260 if( directory_entry == NULL )
261 {
262 libcerror_error_set(
263 error,
264 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
265 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
266 "%s: invalid directory entry.",
267 function );
268
269 return( -1 );
270 }
271 if( libuna_utf8_string_size_from_utf8_stream(
272 directory_entry->name,
273 (size_t) directory_entry->name_size,
274 utf8_string_size,
275 error ) != 1 )
276 {
277 libcerror_error_set(
278 error,
279 LIBCERROR_ERROR_DOMAIN_RUNTIME,
280 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
281 "%s: unable to retrieve UTF-8 string size.",
282 function );
283
284 return( -1 );
285 }
286 return( 1 );
287 }
288
289 /* Retrieves the UTF-8 encoded name
290 * The size should include the end of string character
291 * Returns 1 if successful or -1 on error
292 */
libfsxfs_directory_entry_get_utf8_name(libfsxfs_directory_entry_t * directory_entry,uint8_t * utf8_string,size_t utf8_string_size,libcerror_error_t ** error)293 int libfsxfs_directory_entry_get_utf8_name(
294 libfsxfs_directory_entry_t *directory_entry,
295 uint8_t *utf8_string,
296 size_t utf8_string_size,
297 libcerror_error_t **error )
298 {
299 static char *function = "libfsxfs_directory_entry_get_utf8_name";
300
301 if( directory_entry == NULL )
302 {
303 libcerror_error_set(
304 error,
305 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
306 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
307 "%s: invalid directory entry.",
308 function );
309
310 return( -1 );
311 }
312 if( libuna_utf8_string_copy_from_utf8_stream(
313 utf8_string,
314 utf8_string_size,
315 directory_entry->name,
316 (size_t) directory_entry->name_size,
317 error ) != 1 )
318 {
319 libcerror_error_set(
320 error,
321 LIBCERROR_ERROR_DOMAIN_RUNTIME,
322 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
323 "%s: unable to retrieve UTF-8 string.",
324 function );
325
326 return( -1 );
327 }
328 return( 1 );
329 }
330
331 /* Compares an UTF-8 string with the name of the directory entry
332 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
333 */
libfsxfs_directory_entry_compare_with_utf8_string(libfsxfs_directory_entry_t * directory_entry,const uint8_t * utf8_string,size_t utf8_string_length,libcerror_error_t ** error)334 int libfsxfs_directory_entry_compare_with_utf8_string(
335 libfsxfs_directory_entry_t *directory_entry,
336 const uint8_t *utf8_string,
337 size_t utf8_string_length,
338 libcerror_error_t **error )
339 {
340 static char *function = "libfsxfs_directory_entry_compare_with_utf8_string";
341 int result = 0;
342
343 if( directory_entry == NULL )
344 {
345 libcerror_error_set(
346 error,
347 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349 "%s: invalid directory entry.",
350 function );
351
352 return( -1 );
353 }
354 result = libuna_utf8_string_compare_with_utf8_stream(
355 utf8_string,
356 utf8_string_length,
357 directory_entry->name,
358 directory_entry->name_size,
359 error );
360
361 if( result == -1 )
362 {
363 libcerror_error_set(
364 error,
365 LIBCERROR_ERROR_DOMAIN_RUNTIME,
366 LIBCERROR_RUNTIME_ERROR_GENERIC,
367 "%s: unable to compare UTF-8 string with directory entry name.",
368 function );
369
370 return( -1 );
371 }
372 return( result );
373 }
374
375 /* Retrieves the size of the UTF-16 encoded name
376 * The returned size includes the end of string character
377 * Returns 1 if successful or -1 on error
378 */
libfsxfs_directory_entry_get_utf16_name_size(libfsxfs_directory_entry_t * directory_entry,size_t * utf16_string_size,libcerror_error_t ** error)379 int libfsxfs_directory_entry_get_utf16_name_size(
380 libfsxfs_directory_entry_t *directory_entry,
381 size_t *utf16_string_size,
382 libcerror_error_t **error )
383 {
384 static char *function = "libfsxfs_directory_entry_get_utf16_name_size";
385
386 if( directory_entry == NULL )
387 {
388 libcerror_error_set(
389 error,
390 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
391 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
392 "%s: invalid directory entry.",
393 function );
394
395 return( -1 );
396 }
397 if( libuna_utf16_string_size_from_utf8_stream(
398 directory_entry->name,
399 (size_t) directory_entry->name_size,
400 utf16_string_size,
401 error ) != 1 )
402 {
403 libcerror_error_set(
404 error,
405 LIBCERROR_ERROR_DOMAIN_RUNTIME,
406 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
407 "%s: unable to retrieve UTF-16 string size.",
408 function );
409
410 return( -1 );
411 }
412 return( 1 );
413 }
414
415 /* Retrieves the UTF-16 encoded name
416 * The size should include the end of string character
417 * Returns 1 if successful or -1 on error
418 */
libfsxfs_directory_entry_get_utf16_name(libfsxfs_directory_entry_t * directory_entry,uint16_t * utf16_string,size_t utf16_string_size,libcerror_error_t ** error)419 int libfsxfs_directory_entry_get_utf16_name(
420 libfsxfs_directory_entry_t *directory_entry,
421 uint16_t *utf16_string,
422 size_t utf16_string_size,
423 libcerror_error_t **error )
424 {
425 static char *function = "libfsxfs_directory_entry_get_utf16_name";
426
427 if( directory_entry == NULL )
428 {
429 libcerror_error_set(
430 error,
431 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
432 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
433 "%s: invalid directory entry.",
434 function );
435
436 return( -1 );
437 }
438 if( libuna_utf16_string_copy_from_utf8_stream(
439 utf16_string,
440 utf16_string_size,
441 directory_entry->name,
442 (size_t) directory_entry->name_size,
443 error ) != 1 )
444 {
445 libcerror_error_set(
446 error,
447 LIBCERROR_ERROR_DOMAIN_RUNTIME,
448 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
449 "%s: unable to retrieve UTF-16 string.",
450 function );
451
452 return( -1 );
453 }
454 return( 1 );
455 }
456
457 /* Compares an UTF-16 string with the name of the directory entry
458 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
459 */
libfsxfs_directory_entry_compare_with_utf16_string(libfsxfs_directory_entry_t * directory_entry,const uint16_t * utf16_string,size_t utf16_string_length,libcerror_error_t ** error)460 int libfsxfs_directory_entry_compare_with_utf16_string(
461 libfsxfs_directory_entry_t *directory_entry,
462 const uint16_t *utf16_string,
463 size_t utf16_string_length,
464 libcerror_error_t **error )
465 {
466 static char *function = "libfsxfs_directory_entry_compare_with_utf16_string";
467 int result = 0;
468
469 if( directory_entry == NULL )
470 {
471 libcerror_error_set(
472 error,
473 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
474 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
475 "%s: invalid directory entry.",
476 function );
477
478 return( -1 );
479 }
480 result = libuna_utf16_string_compare_with_utf8_stream(
481 utf16_string,
482 utf16_string_length,
483 directory_entry->name,
484 directory_entry->name_size,
485 error );
486
487 if( result == -1 )
488 {
489 libcerror_error_set(
490 error,
491 LIBCERROR_ERROR_DOMAIN_RUNTIME,
492 LIBCERROR_RUNTIME_ERROR_GENERIC,
493 "%s: unable to compare UTF-16 string with directory entry name.",
494 function );
495
496 return( -1 );
497 }
498 return( result );
499 }
500
501