1 /*
2  * File entry functions
3  *
4  * Copyright (c) 2006-2014, 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 "libewf_definitions.h"
27 #include "libewf_extern.h"
28 #include "libewf_file_entry.h"
29 #include "libewf_handle.h"
30 #include "libewf_libcdata.h"
31 #include "libewf_libcerror.h"
32 #include "libewf_libcnotify.h"
33 #include "libewf_single_file_entry.h"
34 #include "libewf_single_file_tree.h"
35 #include "libewf_types.h"
36 
37 /* Initializes the file entry and its values
38  * Returns 1 if successful or -1 on error
39  */
libewf_file_entry_initialize(libewf_file_entry_t ** file_entry,libewf_internal_handle_t * internal_handle,libcdata_tree_node_t * file_entry_tree_node,uint8_t flags,libcerror_error_t ** error)40 int libewf_file_entry_initialize(
41      libewf_file_entry_t **file_entry,
42      libewf_internal_handle_t *internal_handle,
43      libcdata_tree_node_t *file_entry_tree_node,
44      uint8_t flags,
45      libcerror_error_t **error )
46 {
47 	libewf_internal_file_entry_t *internal_file_entry = NULL;
48 	static char *function                             = "libewf_file_entry_initialize";
49 
50 	if( file_entry == NULL )
51 	{
52 		libcerror_error_set(
53 		 error,
54 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56 		 "%s: invalid file entry.",
57 		 function );
58 
59 		return( -1 );
60 	}
61 	if( *file_entry != NULL )
62 	{
63 		libcerror_error_set(
64 		 error,
65 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
66 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67 		 "%s: invalid file entry value already set.",
68 		 function );
69 
70 		return( -1 );
71 	}
72 	if( ( flags & ~( LIBEWF_ITEM_FLAG_MANAGED_FILE_ENTRY_TREE_NODE ) ) != 0 )
73 	{
74 		libcerror_error_set(
75 		 error,
76 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
77 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
78 		 "%s: unsupported flags: 0x%02" PRIx8 ".",
79 		 function,
80 		 flags );
81 
82 		return( -1 );
83 	}
84 	if( file_entry_tree_node == NULL )
85 	{
86 		libcerror_error_set(
87 		 error,
88 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
89 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
90 		 "%s: invalid file entry tree node.",
91 		 function );
92 
93 		return( -1 );
94 	}
95 	internal_file_entry = memory_allocate_structure(
96 	                       libewf_internal_file_entry_t );
97 
98 	if( internal_file_entry == NULL )
99 	{
100 		libcerror_error_set(
101 		 error,
102 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
103 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
104 		 "%s: unable to create file entry.",
105 		 function );
106 
107 		goto on_error;
108 	}
109 	if( memory_set(
110 	     internal_file_entry,
111 	     0,
112 	     sizeof( libewf_internal_file_entry_t ) ) == NULL )
113 	{
114 		libcerror_error_set(
115 		 error,
116 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
117 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
118 		 "%s: unable to clear file entry.",
119 		 function );
120 
121 		goto on_error;
122 	}
123 	internal_file_entry->internal_handle = internal_handle;
124 	internal_file_entry->flags           = flags;
125 
126 	if( ( flags & LIBEWF_ITEM_FLAG_MANAGED_FILE_ENTRY_TREE_NODE ) == 0 )
127 	{
128 		internal_file_entry->file_entry_tree_node = file_entry_tree_node;
129 	}
130 	else
131 	{
132 		if( libcdata_tree_node_clone(
133 		     &( internal_file_entry->file_entry_tree_node ),
134 		     file_entry_tree_node,
135 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_single_file_entry_free,
136 		     (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libewf_single_file_entry_clone,
137 		     error ) != 1 )
138 		{
139 			libcerror_error_set(
140 			 error,
141 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
142 			 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
143 			 "%s: unable to copy file entry tree node.",
144 			 function );
145 
146 			goto on_error;
147 		}
148 	}
149 	*file_entry = (libewf_file_entry_t *) internal_file_entry;
150 
151 	return( 1 );
152 
153 on_error:
154 	if( internal_file_entry != NULL )
155 	{
156 		memory_free(
157 		 internal_file_entry );
158 	}
159 	return( -1 );
160 }
161 
162 /* Frees a file entry
163  * Returns 1 if successful or -1 on error
164  */
libewf_file_entry_free(libewf_file_entry_t ** file_entry,libcerror_error_t ** error)165 int libewf_file_entry_free(
166      libewf_file_entry_t **file_entry,
167      libcerror_error_t **error )
168 {
169 	libewf_internal_file_entry_t *internal_file_entry = NULL;
170 	static char *function                             = "libewf_file_entry_free";
171 	int result                                        = 1;
172 
173 	if( file_entry == NULL )
174 	{
175 		libcerror_error_set(
176 		 error,
177 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
178 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
179 		 "%s: invalid file entry.",
180 		 function );
181 
182 		return( -1 );
183 	}
184 	if( *file_entry != NULL )
185 	{
186 		internal_file_entry = (libewf_internal_file_entry_t *) *file_entry;
187 		*file_entry         = NULL;
188 
189 		/* The internal_handle reference is freed elsewhere
190 		 */
191 		/* If not managed the file_entry_tree_node reference is freed elsewhere
192 		 */
193 		if( ( internal_file_entry->flags & LIBEWF_ITEM_FLAG_MANAGED_FILE_ENTRY_TREE_NODE ) != 0 )
194 		{
195 			if( internal_file_entry->file_entry_tree_node != NULL )
196 			{
197 				if( libcdata_tree_node_free(
198 				     &( internal_file_entry->file_entry_tree_node ),
199 				     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_single_file_entry_free,
200 				     error ) != 1 )
201 				{
202 					libcerror_error_set(
203 					 error,
204 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
205 					 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
206 					 "%s: unable to free file entry tree node.",
207 					 function );
208 
209 					return( -1 );
210 				}
211 			}
212 		}
213 		memory_free(
214 		 internal_file_entry );
215 	}
216 	return( result );
217 }
218 
219 /* Retrieves the type
220  * Returns 1 if successful or -1 on error
221  */
libewf_file_entry_get_type(libewf_file_entry_t * file_entry,uint8_t * type,libcerror_error_t ** error)222 int libewf_file_entry_get_type(
223      libewf_file_entry_t *file_entry,
224      uint8_t *type,
225      libcerror_error_t **error )
226 {
227 	libewf_internal_file_entry_t *internal_file_entry = NULL;
228 	libewf_single_file_entry_t *single_file_entry     = NULL;
229 	static char *function                             = "libewf_file_entry_get_type";
230 
231 	if( file_entry == NULL )
232 	{
233 		libcerror_error_set(
234 		 error,
235 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
237 		 "%s: invalid file entry.",
238 		 function );
239 
240 		return( -1 );
241 	}
242 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
243 
244 	if( libcdata_tree_node_get_value(
245 	     internal_file_entry->file_entry_tree_node,
246 	     (intptr_t **) &single_file_entry,
247 	     error ) != 1 )
248 	{
249 		libcerror_error_set(
250 		 error,
251 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
252 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
253 		 "%s: unable to retrieve value from file entry tree node.",
254 		 function );
255 
256 		return( -1 );
257 	}
258 	if( libewf_single_file_entry_get_type(
259 	     single_file_entry,
260 	     type,
261 	     error ) != 1 )
262 	{
263 		libcerror_error_set(
264 		 error,
265 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
266 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
267 		 "%s: unable to retrieve type.",
268 		 function );
269 
270 		return( -1 );
271 	}
272 	return( 1 );
273 }
274 
275 /* Retrieves the flags
276  * Returns 1 if successful or -1 on error
277  */
libewf_file_entry_get_flags(libewf_file_entry_t * file_entry,uint32_t * flags,libcerror_error_t ** error)278 int libewf_file_entry_get_flags(
279      libewf_file_entry_t *file_entry,
280      uint32_t *flags,
281      libcerror_error_t **error )
282 {
283 	libewf_internal_file_entry_t *internal_file_entry = NULL;
284 	libewf_single_file_entry_t *single_file_entry     = NULL;
285 	static char *function                             = "libewf_file_entry_get_flags";
286 
287 	if( file_entry == NULL )
288 	{
289 		libcerror_error_set(
290 		 error,
291 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
292 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
293 		 "%s: invalid file entry.",
294 		 function );
295 
296 		return( -1 );
297 	}
298 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
299 
300 	if( libcdata_tree_node_get_value(
301 	     internal_file_entry->file_entry_tree_node,
302 	     (intptr_t **) &single_file_entry,
303 	     error ) != 1 )
304 	{
305 		libcerror_error_set(
306 		 error,
307 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
308 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
309 		 "%s: unable to retrieve value from file entry tree node.",
310 		 function );
311 
312 		return( -1 );
313 	}
314 	if( libewf_single_file_entry_get_flags(
315 	     single_file_entry,
316 	     flags,
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 flags.",
324 		 function );
325 
326 		return( -1 );
327 	}
328 	return( 1 );
329 }
330 
331 /* Retrieves the media data offset
332  * Returns 1 if successful or -1 on error
333  */
libewf_file_entry_get_media_data_offset(libewf_file_entry_t * file_entry,off64_t * media_data_offset,libcerror_error_t ** error)334 int libewf_file_entry_get_media_data_offset(
335      libewf_file_entry_t *file_entry,
336      off64_t *media_data_offset,
337      libcerror_error_t **error )
338 {
339 	libewf_internal_file_entry_t *internal_file_entry = NULL;
340 	libewf_single_file_entry_t *single_file_entry     = NULL;
341 	static char *function                             = "libewf_file_entry_get_media_data_offset";
342 
343 	if( file_entry == NULL )
344 	{
345 		libcerror_error_set(
346 		 error,
347 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349 		 "%s: invalid file entry.",
350 		 function );
351 
352 		return( -1 );
353 	}
354 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
355 
356 	if( libcdata_tree_node_get_value(
357 	     internal_file_entry->file_entry_tree_node,
358 	     (intptr_t **) &single_file_entry,
359 	     error ) != 1 )
360 	{
361 		libcerror_error_set(
362 		 error,
363 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
364 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
365 		 "%s: unable to retrieve value from file entry tree node.",
366 		 function );
367 
368 		return( -1 );
369 	}
370 	if( libewf_single_file_entry_get_data_offset(
371 	     single_file_entry,
372 	     media_data_offset,
373 	     error ) != 1 )
374 	{
375 		libcerror_error_set(
376 		 error,
377 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
378 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
379 		 "%s: unable to retrieve data offset.",
380 		 function );
381 
382 		return( -1 );
383 	}
384 	return( 1 );
385 }
386 
387 /* Retrieves the media data size
388  * Returns 1 if successful or -1 on error
389  */
libewf_file_entry_get_media_data_size(libewf_file_entry_t * file_entry,size64_t * media_data_size,libcerror_error_t ** error)390 int libewf_file_entry_get_media_data_size(
391      libewf_file_entry_t *file_entry,
392      size64_t *media_data_size,
393      libcerror_error_t **error )
394 {
395 	libewf_internal_file_entry_t *internal_file_entry = NULL;
396 	libewf_single_file_entry_t *single_file_entry     = NULL;
397 	static char *function                             = "libewf_file_entry_get_media_data_size";
398 
399 	if( file_entry == NULL )
400 	{
401 		libcerror_error_set(
402 		 error,
403 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
404 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
405 		 "%s: invalid file entry.",
406 		 function );
407 
408 		return( -1 );
409 	}
410 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
411 
412 	if( libcdata_tree_node_get_value(
413 	     internal_file_entry->file_entry_tree_node,
414 	     (intptr_t **) &single_file_entry,
415 	     error ) != 1 )
416 	{
417 		libcerror_error_set(
418 		 error,
419 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
420 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
421 		 "%s: unable to retrieve value from file entry tree node.",
422 		 function );
423 
424 		return( -1 );
425 	}
426 	if( libewf_single_file_entry_get_data_size(
427 	     single_file_entry,
428 	     media_data_size,
429 	     error ) != 1 )
430 	{
431 		libcerror_error_set(
432 		 error,
433 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
434 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
435 		 "%s: unable to retrieve data size.",
436 		 function );
437 
438 		return( -1 );
439 	}
440 	return( 1 );
441 }
442 
443 /* Retrieves the duplicate media data offset
444  * Returns 1 if successful or -1 on error
445  */
libewf_file_entry_get_duplicate_media_data_offset(libewf_file_entry_t * file_entry,off64_t * duplicate_media_data_offset,libcerror_error_t ** error)446 int libewf_file_entry_get_duplicate_media_data_offset(
447      libewf_file_entry_t *file_entry,
448      off64_t *duplicate_media_data_offset,
449      libcerror_error_t **error )
450 {
451 	libewf_internal_file_entry_t *internal_file_entry = NULL;
452 	libewf_single_file_entry_t *single_file_entry     = NULL;
453 	static char *function                             = "libewf_file_entry_get_media_data_offset";
454 
455 	if( file_entry == NULL )
456 	{
457 		libcerror_error_set(
458 		 error,
459 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
460 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
461 		 "%s: invalid file entry.",
462 		 function );
463 
464 		return( -1 );
465 	}
466 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
467 
468 	if( libcdata_tree_node_get_value(
469 	     internal_file_entry->file_entry_tree_node,
470 	     (intptr_t **) &single_file_entry,
471 	     error ) != 1 )
472 	{
473 		libcerror_error_set(
474 		 error,
475 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
476 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
477 		 "%s: unable to retrieve value from file entry tree node.",
478 		 function );
479 
480 		return( -1 );
481 	}
482 	if( libewf_single_file_entry_get_duplicate_data_offset(
483 	     single_file_entry,
484 	     duplicate_media_data_offset,
485 	     error ) != 1 )
486 	{
487 		libcerror_error_set(
488 		 error,
489 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
490 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
491 		 "%s: unable to retrieve duplicate data offset.",
492 		 function );
493 
494 		return( -1 );
495 	}
496 	return( 1 );
497 }
498 
499 /* Retrieves the size of the UTF-8 encoded name
500  * The returned size includes the end of string character
501  * Returns 1 if successful or -1 on error
502  */
libewf_file_entry_get_utf8_name_size(libewf_file_entry_t * file_entry,size_t * utf8_name_size,libcerror_error_t ** error)503 int libewf_file_entry_get_utf8_name_size(
504      libewf_file_entry_t *file_entry,
505      size_t *utf8_name_size,
506      libcerror_error_t **error )
507 {
508 	libewf_internal_file_entry_t *internal_file_entry = NULL;
509 	libewf_single_file_entry_t *single_file_entry     = NULL;
510 	static char *function                             = "libewf_file_entry_get_utf8_name_size";
511 
512 	if( file_entry == NULL )
513 	{
514 		libcerror_error_set(
515 		 error,
516 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
517 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
518 		 "%s: invalid file entry.",
519 		 function );
520 
521 		return( -1 );
522 	}
523 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
524 
525 	if( libcdata_tree_node_get_value(
526 	     internal_file_entry->file_entry_tree_node,
527 	     (intptr_t **) &single_file_entry,
528 	     error ) != 1 )
529 	{
530 		libcerror_error_set(
531 		 error,
532 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
533 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
534 		 "%s: unable to retrieve value from file entry tree node.",
535 		 function );
536 
537 		return( -1 );
538 	}
539 	if( libewf_single_file_entry_get_utf8_name_size(
540 	     single_file_entry,
541 	     utf8_name_size,
542 	     error ) != 1 )
543 	{
544 		libcerror_error_set(
545 		 error,
546 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
547 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
548 		 "%s: unable to retrieve UTF-8 name size.",
549 		 function );
550 
551 		return( -1 );
552 	}
553 	return( 1 );
554 }
555 
556 /* Retrieves the UTF-8 encoded name value
557  * The size should include the end of string character
558  * Returns 1 if successful or -1 on error
559  */
libewf_file_entry_get_utf8_name(libewf_file_entry_t * file_entry,uint8_t * utf8_name,size_t utf8_name_size,libcerror_error_t ** error)560 int libewf_file_entry_get_utf8_name(
561      libewf_file_entry_t *file_entry,
562      uint8_t *utf8_name,
563      size_t utf8_name_size,
564      libcerror_error_t **error )
565 {
566 	libewf_internal_file_entry_t *internal_file_entry = NULL;
567 	libewf_single_file_entry_t *single_file_entry     = NULL;
568 	static char *function                             = "libewf_file_entry_get_utf8_name_size";
569 
570 	if( file_entry == NULL )
571 	{
572 		libcerror_error_set(
573 		 error,
574 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
575 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
576 		 "%s: invalid file entry.",
577 		 function );
578 
579 		return( -1 );
580 	}
581 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
582 
583 	if( libcdata_tree_node_get_value(
584 	     internal_file_entry->file_entry_tree_node,
585 	     (intptr_t **) &single_file_entry,
586 	     error ) != 1 )
587 	{
588 		libcerror_error_set(
589 		 error,
590 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
591 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
592 		 "%s: unable to retrieve value from file entry tree node.",
593 		 function );
594 
595 		return( -1 );
596 	}
597 	if( libewf_single_file_entry_get_utf8_name(
598 	     single_file_entry,
599 	     utf8_name,
600 	     utf8_name_size,
601 	     error ) != 1 )
602 	{
603 		libcerror_error_set(
604 		 error,
605 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
606 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
607 		 "%s: unable to retrieve UTF-8 name.",
608 		 function );
609 
610 		return( -1 );
611 	}
612 	return( 1 );
613 }
614 
615 /* Retrieves the size of the UTF-16 encoded name
616  * The returned size includes the end of string character
617  * Returns 1 if successful or -1 on error
618  */
libewf_file_entry_get_utf16_name_size(libewf_file_entry_t * file_entry,size_t * utf16_name_size,libcerror_error_t ** error)619 int libewf_file_entry_get_utf16_name_size(
620      libewf_file_entry_t *file_entry,
621      size_t *utf16_name_size,
622      libcerror_error_t **error )
623 {
624 	libewf_internal_file_entry_t *internal_file_entry = NULL;
625 	libewf_single_file_entry_t *single_file_entry     = NULL;
626 	static char *function                             = "libewf_file_entry_get_utf16_name_size";
627 
628 	if( file_entry == NULL )
629 	{
630 		libcerror_error_set(
631 		 error,
632 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
633 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
634 		 "%s: invalid file entry.",
635 		 function );
636 
637 		return( -1 );
638 	}
639 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
640 
641 	if( libcdata_tree_node_get_value(
642 	     internal_file_entry->file_entry_tree_node,
643 	     (intptr_t **) &single_file_entry,
644 	     error ) != 1 )
645 	{
646 		libcerror_error_set(
647 		 error,
648 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
649 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
650 		 "%s: unable to retrieve value from file entry tree node.",
651 		 function );
652 
653 		return( -1 );
654 	}
655 	if( libewf_single_file_entry_get_utf16_name_size(
656 	     single_file_entry,
657 	     utf16_name_size,
658 	     error ) != 1 )
659 	{
660 		libcerror_error_set(
661 		 error,
662 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
663 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
664 		 "%s: unable to retrieve UTF-16 name size.",
665 		 function );
666 
667 		return( -1 );
668 	}
669 	return( 1 );
670 }
671 
672 /* Retrieves the UTF-16 encoded name value
673  * The size should include the end of string character
674  * Returns 1 if successful or -1 on error
675  */
libewf_file_entry_get_utf16_name(libewf_file_entry_t * file_entry,uint16_t * utf16_name,size_t utf16_name_size,libcerror_error_t ** error)676 int libewf_file_entry_get_utf16_name(
677      libewf_file_entry_t *file_entry,
678      uint16_t *utf16_name,
679      size_t utf16_name_size,
680      libcerror_error_t **error )
681 {
682 	libewf_internal_file_entry_t *internal_file_entry = NULL;
683 	libewf_single_file_entry_t *single_file_entry     = NULL;
684 	static char *function                             = "libewf_file_entry_get_utf16_name_size";
685 
686 	if( file_entry == NULL )
687 	{
688 		libcerror_error_set(
689 		 error,
690 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
691 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
692 		 "%s: invalid file entry.",
693 		 function );
694 
695 		return( -1 );
696 	}
697 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
698 
699 	if( libcdata_tree_node_get_value(
700 	     internal_file_entry->file_entry_tree_node,
701 	     (intptr_t **) &single_file_entry,
702 	     error ) != 1 )
703 	{
704 		libcerror_error_set(
705 		 error,
706 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
707 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
708 		 "%s: unable to retrieve value from file entry tree node.",
709 		 function );
710 
711 		return( -1 );
712 	}
713 	if( libewf_single_file_entry_get_utf16_name(
714 	     single_file_entry,
715 	     utf16_name,
716 	     utf16_name_size,
717 	     error ) != 1 )
718 	{
719 		libcerror_error_set(
720 		 error,
721 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
722 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
723 		 "%s: unable to retrieve UTF-8 name.",
724 		 function );
725 
726 		return( -1 );
727 	}
728 	return( 1 );
729 }
730 
731 /* Retrieves the size
732  * Returns 1 if successful or -1 on error
733  */
libewf_file_entry_get_size(libewf_file_entry_t * file_entry,size64_t * size,libcerror_error_t ** error)734 int libewf_file_entry_get_size(
735      libewf_file_entry_t *file_entry,
736      size64_t *size,
737      libcerror_error_t **error )
738 {
739 	libewf_internal_file_entry_t *internal_file_entry = NULL;
740 	libewf_single_file_entry_t *single_file_entry     = NULL;
741 	static char *function                             = "libewf_file_entry_get_size";
742 
743 	if( file_entry == NULL )
744 	{
745 		libcerror_error_set(
746 		 error,
747 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
748 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
749 		 "%s: invalid file entry.",
750 		 function );
751 
752 		return( -1 );
753 	}
754 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
755 
756 	if( libcdata_tree_node_get_value(
757 	     internal_file_entry->file_entry_tree_node,
758 	     (intptr_t **) &single_file_entry,
759 	     error ) != 1 )
760 	{
761 		libcerror_error_set(
762 		 error,
763 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
764 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
765 		 "%s: unable to retrieve value from file entry tree node.",
766 		 function );
767 
768 		return( -1 );
769 	}
770 	if( libewf_single_file_entry_get_size(
771 	     single_file_entry,
772 	     size,
773 	     error ) != 1 )
774 	{
775 		libcerror_error_set(
776 		 error,
777 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
778 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
779 		 "%s: unable to retrieve size.",
780 		 function );
781 
782 		return( -1 );
783 	}
784 	return( 1 );
785 }
786 
787 /* Retrieves the creation date and time
788  * Returns 1 if successful or -1 on error
789  */
libewf_file_entry_get_creation_time(libewf_file_entry_t * file_entry,uint32_t * creation_time,libcerror_error_t ** error)790 int libewf_file_entry_get_creation_time(
791      libewf_file_entry_t *file_entry,
792      uint32_t *creation_time,
793      libcerror_error_t **error )
794 {
795 	libewf_internal_file_entry_t *internal_file_entry = NULL;
796 	libewf_single_file_entry_t *single_file_entry     = NULL;
797 	static char *function                             = "libewf_file_entry_get_creation_time";
798 
799 	if( file_entry == NULL )
800 	{
801 		libcerror_error_set(
802 		 error,
803 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
804 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
805 		 "%s: invalid file entry.",
806 		 function );
807 
808 		return( -1 );
809 	}
810 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
811 
812 	if( libcdata_tree_node_get_value(
813 	     internal_file_entry->file_entry_tree_node,
814 	     (intptr_t **) &single_file_entry,
815 	     error ) != 1 )
816 	{
817 		libcerror_error_set(
818 		 error,
819 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
820 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
821 		 "%s: unable to retrieve value from file entry tree node.",
822 		 function );
823 
824 		return( -1 );
825 	}
826 	if( libewf_single_file_entry_get_creation_time(
827 	     single_file_entry,
828 	     creation_time,
829 	     error ) != 1 )
830 	{
831 		libcerror_error_set(
832 		 error,
833 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
834 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
835 		 "%s: unable to retrieve creation time.",
836 		 function );
837 
838 		return( -1 );
839 	}
840 	return( 1 );
841 }
842 
843 /* Retrieves the (file) modification (last written) date and time
844  * Returns 1 if successful or -1 on error
845  */
libewf_file_entry_get_modification_time(libewf_file_entry_t * file_entry,uint32_t * modification_time,libcerror_error_t ** error)846 int libewf_file_entry_get_modification_time(
847      libewf_file_entry_t *file_entry,
848      uint32_t *modification_time,
849      libcerror_error_t **error )
850 {
851 	libewf_internal_file_entry_t *internal_file_entry = NULL;
852 	libewf_single_file_entry_t *single_file_entry     = NULL;
853 	static char *function                             = "libewf_file_entry_get_modification_time";
854 
855 	if( file_entry == NULL )
856 	{
857 		libcerror_error_set(
858 		 error,
859 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
860 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
861 		 "%s: invalid file entry.",
862 		 function );
863 
864 		return( -1 );
865 	}
866 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
867 
868 	if( libcdata_tree_node_get_value(
869 	     internal_file_entry->file_entry_tree_node,
870 	     (intptr_t **) &single_file_entry,
871 	     error ) != 1 )
872 	{
873 		libcerror_error_set(
874 		 error,
875 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
876 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
877 		 "%s: unable to retrieve value from file entry tree node.",
878 		 function );
879 
880 		return( -1 );
881 	}
882 	if( libewf_single_file_entry_get_modification_time(
883 	     single_file_entry,
884 	     modification_time,
885 	     error ) != 1 )
886 	{
887 		libcerror_error_set(
888 		 error,
889 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
890 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
891 		 "%s: unable to retrieve modification time.",
892 		 function );
893 
894 		return( -1 );
895 	}
896 	return( 1 );
897 }
898 
899 /* Retrieves the access date and time
900  * Returns 1 if successful or -1 on error
901  */
libewf_file_entry_get_access_time(libewf_file_entry_t * file_entry,uint32_t * access_time,libcerror_error_t ** error)902 int libewf_file_entry_get_access_time(
903      libewf_file_entry_t *file_entry,
904      uint32_t *access_time,
905      libcerror_error_t **error )
906 {
907 	libewf_internal_file_entry_t *internal_file_entry = NULL;
908 	libewf_single_file_entry_t *single_file_entry     = NULL;
909 	static char *function                             = "libewf_file_entry_get_access_time";
910 
911 	if( file_entry == NULL )
912 	{
913 		libcerror_error_set(
914 		 error,
915 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
916 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
917 		 "%s: invalid file entry.",
918 		 function );
919 
920 		return( -1 );
921 	}
922 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
923 
924 	if( libcdata_tree_node_get_value(
925 	     internal_file_entry->file_entry_tree_node,
926 	     (intptr_t **) &single_file_entry,
927 	     error ) != 1 )
928 	{
929 		libcerror_error_set(
930 		 error,
931 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
932 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
933 		 "%s: unable to retrieve value from file entry tree node.",
934 		 function );
935 
936 		return( -1 );
937 	}
938 	if( libewf_single_file_entry_get_access_time(
939 	     single_file_entry,
940 	     access_time,
941 	     error ) != 1 )
942 	{
943 		libcerror_error_set(
944 		 error,
945 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
946 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
947 		 "%s: unable to retrieve access time.",
948 		 function );
949 
950 		return( -1 );
951 	}
952 	return( 1 );
953 }
954 
955 /* Retrieves the (file system entry) modification date and time
956  * Returns 1 if successful or -1 on error
957  */
libewf_file_entry_get_entry_modification_time(libewf_file_entry_t * file_entry,uint32_t * entry_modification_time,libcerror_error_t ** error)958 int libewf_file_entry_get_entry_modification_time(
959      libewf_file_entry_t *file_entry,
960      uint32_t *entry_modification_time,
961      libcerror_error_t **error )
962 {
963 	libewf_internal_file_entry_t *internal_file_entry = NULL;
964 	libewf_single_file_entry_t *single_file_entry     = NULL;
965 	static char *function                             = "libewf_file_entry_get_entry_modification_time";
966 
967 	if( file_entry == NULL )
968 	{
969 		libcerror_error_set(
970 		 error,
971 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
972 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
973 		 "%s: invalid file entry.",
974 		 function );
975 
976 		return( -1 );
977 	}
978 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
979 
980 	if( libcdata_tree_node_get_value(
981 	     internal_file_entry->file_entry_tree_node,
982 	     (intptr_t **) &single_file_entry,
983 	     error ) != 1 )
984 	{
985 		libcerror_error_set(
986 		 error,
987 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
988 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
989 		 "%s: unable to retrieve value from file entry tree node.",
990 		 function );
991 
992 		return( -1 );
993 	}
994 	if( libewf_single_file_entry_get_entry_modification_time(
995 	     single_file_entry,
996 	     entry_modification_time,
997 	     error ) != 1 )
998 	{
999 		libcerror_error_set(
1000 		 error,
1001 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1002 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1003 		 "%s: unable to retrieve entry modification time.",
1004 		 function );
1005 
1006 		return( -1 );
1007 	}
1008 	return( 1 );
1009 }
1010 
1011 /* Retrieves the UTF-8 encoded MD5 hash value
1012  * Returns 1 if successful, 0 if value not present or -1 on error
1013  */
libewf_file_entry_get_utf8_hash_value_md5(libewf_file_entry_t * file_entry,uint8_t * utf8_string,size_t utf8_string_size,libcerror_error_t ** error)1014 int libewf_file_entry_get_utf8_hash_value_md5(
1015      libewf_file_entry_t *file_entry,
1016      uint8_t *utf8_string,
1017      size_t utf8_string_size,
1018      libcerror_error_t **error )
1019 {
1020 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1021 	libewf_single_file_entry_t *single_file_entry     = NULL;
1022 	static char *function                             = "libewf_file_entry_get_utf8_hash_value_md5";
1023 	int result                                        = 0;
1024 
1025 	if( file_entry == NULL )
1026 	{
1027 		libcerror_error_set(
1028 		 error,
1029 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1030 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1031 		 "%s: invalid file entry.",
1032 		 function );
1033 
1034 		return( -1 );
1035 	}
1036 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1037 
1038 	if( libcdata_tree_node_get_value(
1039 	     internal_file_entry->file_entry_tree_node,
1040 	     (intptr_t **) &single_file_entry,
1041 	     error ) != 1 )
1042 	{
1043 		libcerror_error_set(
1044 		 error,
1045 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1046 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1047 		 "%s: unable to retrieve value from file entry tree node.",
1048 		 function );
1049 
1050 		return( -1 );
1051 	}
1052 	result = libewf_single_file_entry_get_utf8_hash_value_md5(
1053 	          single_file_entry,
1054 	          utf8_string,
1055 	          utf8_string_size,
1056 	          error );
1057 
1058 	if( result == -1 )
1059 	{
1060 		libcerror_error_set(
1061 		 error,
1062 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1063 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1064 		 "%s: unable to retrieve hash value: MD5.",
1065 		 function );
1066 
1067 		return( -1 );
1068 	}
1069 	return( result );
1070 }
1071 
1072 /* Retrieves the UTF-16 encoded MD5 hash value
1073  * Returns 1 if successful, 0 if value not present or -1 on error
1074  */
libewf_file_entry_get_utf16_hash_value_md5(libewf_file_entry_t * file_entry,uint16_t * utf16_string,size_t utf16_string_size,libcerror_error_t ** error)1075 int libewf_file_entry_get_utf16_hash_value_md5(
1076      libewf_file_entry_t *file_entry,
1077      uint16_t *utf16_string,
1078      size_t utf16_string_size,
1079      libcerror_error_t **error )
1080 {
1081 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1082 	libewf_single_file_entry_t *single_file_entry     = NULL;
1083 	static char *function                             = "libewf_file_entry_get_utf16_hash_value_md5";
1084 	int result                                        = 0;
1085 
1086 	if( file_entry == NULL )
1087 	{
1088 		libcerror_error_set(
1089 		 error,
1090 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1091 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1092 		 "%s: invalid file entry.",
1093 		 function );
1094 
1095 		return( -1 );
1096 	}
1097 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1098 
1099 	if( libcdata_tree_node_get_value(
1100 	     internal_file_entry->file_entry_tree_node,
1101 	     (intptr_t **) &single_file_entry,
1102 	     error ) != 1 )
1103 	{
1104 		libcerror_error_set(
1105 		 error,
1106 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1107 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1108 		 "%s: unable to retrieve value from file entry tree node.",
1109 		 function );
1110 
1111 		return( -1 );
1112 	}
1113 	result = libewf_single_file_entry_get_utf16_hash_value_md5(
1114 	          single_file_entry,
1115 	          utf16_string,
1116 	          utf16_string_size,
1117 	          error );
1118 
1119 	if( result == -1 )
1120 	{
1121 		libcerror_error_set(
1122 		 error,
1123 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1124 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1125 		 "%s: unable to retrieve hash value: MD5.",
1126 		 function );
1127 
1128 		return( -1 );
1129 	}
1130 	return( result );
1131 }
1132 
1133 /* Retrieves the UTF-8 encoded SHA1 hash value
1134  * Returns 1 if successful, 0 if value not present or -1 on error
1135  */
libewf_file_entry_get_utf8_hash_value_sha1(libewf_file_entry_t * file_entry,uint8_t * utf8_string,size_t utf8_string_size,libcerror_error_t ** error)1136 int libewf_file_entry_get_utf8_hash_value_sha1(
1137      libewf_file_entry_t *file_entry,
1138      uint8_t *utf8_string,
1139      size_t utf8_string_size,
1140      libcerror_error_t **error )
1141 {
1142 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1143 	libewf_single_file_entry_t *single_file_entry     = NULL;
1144 	static char *function                             = "libewf_file_entry_get_utf8_hash_value_sha1";
1145 	int result                                        = 0;
1146 
1147 	if( file_entry == NULL )
1148 	{
1149 		libcerror_error_set(
1150 		 error,
1151 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1152 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1153 		 "%s: invalid file entry.",
1154 		 function );
1155 
1156 		return( -1 );
1157 	}
1158 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1159 
1160 	if( libcdata_tree_node_get_value(
1161 	     internal_file_entry->file_entry_tree_node,
1162 	     (intptr_t **) &single_file_entry,
1163 	     error ) != 1 )
1164 	{
1165 		libcerror_error_set(
1166 		 error,
1167 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1168 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1169 		 "%s: unable to retrieve value from file entry tree node.",
1170 		 function );
1171 
1172 		return( -1 );
1173 	}
1174 	result = libewf_single_file_entry_get_utf8_hash_value_sha1(
1175 	          single_file_entry,
1176 	          utf8_string,
1177 	          utf8_string_size,
1178 	          error );
1179 
1180 	if( result == -1 )
1181 	{
1182 		libcerror_error_set(
1183 		 error,
1184 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1185 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1186 		 "%s: unable to retrieve hash value: SHA1.",
1187 		 function );
1188 
1189 		return( -1 );
1190 	}
1191 	return( result );
1192 }
1193 
1194 /* Retrieves the UTF-16 encoded SHA1 hash value
1195  * Returns 1 if successful, 0 if value not present or -1 on error
1196  */
libewf_file_entry_get_utf16_hash_value_sha1(libewf_file_entry_t * file_entry,uint16_t * utf16_string,size_t utf16_string_size,libcerror_error_t ** error)1197 int libewf_file_entry_get_utf16_hash_value_sha1(
1198      libewf_file_entry_t *file_entry,
1199      uint16_t *utf16_string,
1200      size_t utf16_string_size,
1201      libcerror_error_t **error )
1202 {
1203 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1204 	libewf_single_file_entry_t *single_file_entry     = NULL;
1205 	static char *function                             = "libewf_file_entry_get_utf16_hash_value_sha1";
1206 	int result                                        = 0;
1207 
1208 	if( file_entry == NULL )
1209 	{
1210 		libcerror_error_set(
1211 		 error,
1212 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1213 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1214 		 "%s: invalid file entry.",
1215 		 function );
1216 
1217 		return( -1 );
1218 	}
1219 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1220 
1221 	if( libcdata_tree_node_get_value(
1222 	     internal_file_entry->file_entry_tree_node,
1223 	     (intptr_t **) &single_file_entry,
1224 	     error ) != 1 )
1225 	{
1226 		libcerror_error_set(
1227 		 error,
1228 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1229 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1230 		 "%s: unable to retrieve value from file entry tree node.",
1231 		 function );
1232 
1233 		return( -1 );
1234 	}
1235 	result = libewf_single_file_entry_get_utf16_hash_value_sha1(
1236 	          single_file_entry,
1237 	          utf16_string,
1238 	          utf16_string_size,
1239 	          error );
1240 
1241 	if( result == -1 )
1242 	{
1243 		libcerror_error_set(
1244 		 error,
1245 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1246 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1247 		 "%s: unable to retrieve hash value: SHA1.",
1248 		 function );
1249 
1250 		return( -1 );
1251 	}
1252 	return( result );
1253 }
1254 
1255 /* Reads data at the current offset
1256  * Returns the number of bytes read or -1 on error
1257  */
libewf_file_entry_read_buffer(libewf_file_entry_t * file_entry,void * buffer,size_t buffer_size,libcerror_error_t ** error)1258 ssize_t libewf_file_entry_read_buffer(
1259          libewf_file_entry_t *file_entry,
1260          void *buffer,
1261          size_t buffer_size,
1262          libcerror_error_t **error )
1263 {
1264 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1265 	libewf_single_file_entry_t *single_file_entry     = NULL;
1266 	static char *function                             = "libewf_file_entry_read_buffer";
1267 	off64_t data_offset                               = 0;
1268 	off64_t duplicate_data_offset                     = 0;
1269 	size64_t data_size                                = 0;
1270 	size64_t size                                     = 0;
1271 	size_t read_size                                  = 0;
1272 	ssize_t read_count                                = 0;
1273 	uint32_t flags                                    = 0;
1274 
1275 	if( file_entry == NULL )
1276 	{
1277 		libcerror_error_set(
1278 		 error,
1279 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1280 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1281 		 "%s: invalid file entry.",
1282 		 function );
1283 
1284 		return( -1 );
1285 	}
1286 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1287 
1288 	if( buffer == NULL )
1289 	{
1290 		libcerror_error_set(
1291 		 error,
1292 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1293 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1294 		 "%s: invalid buffer.",
1295 		 function );
1296 
1297 		return( -1 );
1298 	}
1299 	if( buffer_size > (size_t) SSIZE_MAX )
1300 	{
1301 		libcerror_error_set(
1302 		 error,
1303 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1304 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1305 		 "%s: invalid buffer size value exceeds maximum.",
1306 		 function );
1307 
1308 		return( -1 );
1309 	}
1310 	if( internal_file_entry->offset < 0 )
1311 	{
1312 		libcerror_error_set(
1313 		 error,
1314 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1315 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1316 		 "%s: invalid file entry - offset value out of bounds.",
1317 		 function );
1318 
1319 		return( -1 );
1320 	}
1321 	if( libcdata_tree_node_get_value(
1322 	     internal_file_entry->file_entry_tree_node,
1323 	     (intptr_t **) &single_file_entry,
1324 	     error ) != 1 )
1325 	{
1326 		libcerror_error_set(
1327 		 error,
1328 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1329 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1330 		 "%s: unable to retrieve value from file entry tree node.",
1331 		 function );
1332 
1333 		return( -1 );
1334 	}
1335 	if( libewf_single_file_entry_get_size(
1336 	     single_file_entry,
1337 	     &size,
1338 	     error ) != 1 )
1339 	{
1340 		libcerror_error_set(
1341 		 error,
1342 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1343 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1344 		 "%s: unable to retrieve size.",
1345 		 function );
1346 
1347 		return( -1 );
1348 	}
1349 	if( libewf_single_file_entry_get_data_offset(
1350 	     single_file_entry,
1351 	     &data_offset,
1352 	     error ) != 1 )
1353 	{
1354 		libcerror_error_set(
1355 		 error,
1356 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1357 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1358 		 "%s: unable to retrieve data offset.",
1359 		 function );
1360 
1361 		return( -1 );
1362 	}
1363 	if( libewf_single_file_entry_get_data_size(
1364 	     single_file_entry,
1365 	     &data_size,
1366 	     error ) != 1 )
1367 	{
1368 		libcerror_error_set(
1369 		 error,
1370 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1371 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1372 		 "%s: unable to retrieve data size.",
1373 		 function );
1374 
1375 		return( -1 );
1376 	}
1377 	if( libewf_single_file_entry_get_flags(
1378 	     single_file_entry,
1379 	     &flags,
1380 	     error ) != 1 )
1381 	{
1382 		libcerror_error_set(
1383 		 error,
1384 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1385 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1386 		 "%s: unable to retrieve flags.",
1387 		 function );
1388 
1389 		return( -1 );
1390 	}
1391 	if( ( flags & LIBEWF_FILE_ENTRY_FLAG_SPARSE_DATA ) == 0 )
1392 	{
1393 		if( ( ( size == 0 )
1394 		  &&  ( data_size != 1 ) )
1395 		 || ( ( size != 0 )
1396 		  &&  ( data_size != size ) ) )
1397 		{
1398 			libcerror_error_set(
1399 			 error,
1400 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401 			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1402 			 "%s: unsupported data size.",
1403 			 function );
1404 
1405 			return( -1 );
1406 		}
1407 	}
1408 	else
1409 	{
1410 		if( ( data_size != 1 )
1411 		 && ( data_size != size ) )
1412 		{
1413 			libcerror_error_set(
1414 			 error,
1415 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1416 			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1417 			 "%s: unsupported data size.",
1418 			 function );
1419 
1420 			return( -1 );
1421 		}
1422 		if( libewf_single_file_entry_get_duplicate_data_offset(
1423 		     single_file_entry,
1424 		     &duplicate_data_offset,
1425 		     error ) != 1 )
1426 		{
1427 			libcerror_error_set(
1428 			 error,
1429 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1430 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1431 			 "%s: unable to retrieve duplicate data offset.",
1432 			 function );
1433 
1434 			return( -1 );
1435 		}
1436 	}
1437 	if( internal_file_entry->offset >= (off64_t) size )
1438 	{
1439 		return( 0 );
1440 	}
1441 	if( (off64_t) ( internal_file_entry->offset + buffer_size ) > (off64_t) size )
1442 	{
1443 		buffer_size = (size_t) ( size - internal_file_entry->offset );
1444 	}
1445 	if( ( flags & LIBEWF_FILE_ENTRY_FLAG_SPARSE_DATA ) == 0 )
1446 	{
1447 		data_offset += internal_file_entry->offset;
1448 		read_size    = buffer_size;
1449 	}
1450 	else if( duplicate_data_offset >= 0 )
1451 	{
1452 		data_offset = duplicate_data_offset + internal_file_entry->offset;
1453 		read_size   = buffer_size;
1454 	}
1455 	else
1456 	{
1457 		read_size = 1;
1458 	}
1459 	if( libewf_handle_seek_offset(
1460 	     (libewf_handle_t *) internal_file_entry->internal_handle,
1461 	     data_offset,
1462 	     SEEK_SET,
1463 	     error ) == -1 )
1464 	{
1465 		libcerror_error_set(
1466 		 error,
1467 		 LIBCERROR_ERROR_DOMAIN_IO,
1468 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
1469 		 "%s: unable to seek offset: %" PRIi64 ".",
1470 		 function,
1471 		 data_offset );
1472 
1473 		return( -1 );
1474 	}
1475 	read_count = libewf_handle_read_buffer(
1476 		      (libewf_handle_t *) internal_file_entry->internal_handle,
1477 		      buffer,
1478 		      read_size,
1479 		      error );
1480 
1481 	if( read_count <= -1 )
1482 	{
1483 		libcerror_error_set(
1484 		 error,
1485 		 LIBCERROR_ERROR_DOMAIN_IO,
1486 		 LIBCERROR_IO_ERROR_READ_FAILED,
1487 		 "%s: unable to read buffer.",
1488 		 function );
1489 
1490 		return( -1 );
1491 	}
1492 	internal_file_entry->offset += read_count;
1493 
1494 	if( ( flags & LIBEWF_FILE_ENTRY_FLAG_SPARSE_DATA ) != 0 )
1495 	{
1496 		if( read_count == 1 )
1497 		{
1498 			if( memory_set(
1499 			     &( ( (uint8_t *) buffer )[ 1 ] ),
1500 			     ( (uint8_t *) buffer )[ 0 ],
1501 			     buffer_size - 1 ) == NULL )
1502 			{
1503 				libcerror_error_set(
1504 				 error,
1505 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
1506 				 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1507 				 "%s: unable to set sparse data in buffer.",
1508 				 function );
1509 
1510 				return( -1 );
1511 			}
1512 			read_count = (ssize_t) buffer_size;
1513 		}
1514 	}
1515 	return( read_count );
1516 }
1517 
1518 /* Reads data at a specific offset
1519  * Returns the number of bytes read or -1 on error
1520  */
libewf_file_entry_read_random(libewf_file_entry_t * file_entry,void * buffer,size_t buffer_size,off64_t offset,libcerror_error_t ** error)1521 ssize_t libewf_file_entry_read_random(
1522          libewf_file_entry_t *file_entry,
1523          void *buffer,
1524          size_t buffer_size,
1525          off64_t offset,
1526          libcerror_error_t **error )
1527 {
1528 	static char *function = "libewf_file_entry_read_random";
1529 	ssize_t read_count    = 0;
1530 
1531 	if( libewf_file_entry_seek_offset(
1532 	     file_entry,
1533 	     offset,
1534 	     SEEK_SET,
1535 	     error ) == -1 )
1536 	{
1537 		libcerror_error_set(
1538 		 error,
1539 		 LIBCERROR_ERROR_DOMAIN_IO,
1540 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
1541 		 "%s: unable to seek offset.",
1542 		 function );
1543 
1544 		return( -1 );
1545 	}
1546 	read_count = libewf_file_entry_read_buffer(
1547 	              file_entry,
1548 	              buffer,
1549 	              buffer_size,
1550 	              error );
1551 
1552 	if( read_count <= -1 )
1553 	{
1554 		libcerror_error_set(
1555 		 error,
1556 		 LIBCERROR_ERROR_DOMAIN_IO,
1557 		 LIBCERROR_IO_ERROR_READ_FAILED,
1558 		 "%s: unable to read buffer.",
1559 		 function );
1560 
1561 		return( -1 );
1562 	}
1563 	return( read_count );
1564 }
1565 
1566 /* Seeks a certain offset of the data
1567  * Returns the offset if seek is successful or -1 on error
1568  */
libewf_file_entry_seek_offset(libewf_file_entry_t * file_entry,off64_t offset,int whence,libcerror_error_t ** error)1569 off64_t libewf_file_entry_seek_offset(
1570          libewf_file_entry_t *file_entry,
1571          off64_t offset,
1572          int whence,
1573          libcerror_error_t **error )
1574 {
1575 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1576 	libewf_single_file_entry_t *single_file_entry     = NULL;
1577 	static char *function                             = "libewf_file_entry_seek_offset";
1578 	size64_t size                                     = 0;
1579 
1580 	if( file_entry == NULL )
1581 	{
1582 		libcerror_error_set(
1583 		 error,
1584 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1585 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1586 		 "%s: invalid file entry.",
1587 		 function );
1588 
1589 		return( -1 );
1590 	}
1591 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1592 
1593 	if( libcdata_tree_node_get_value(
1594 	     internal_file_entry->file_entry_tree_node,
1595 	     (intptr_t **) &single_file_entry,
1596 	     error ) != 1 )
1597 	{
1598 		libcerror_error_set(
1599 		 error,
1600 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1601 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1602 		 "%s: unable to retrieve value from file entry tree node.",
1603 		 function );
1604 
1605 		return( -1 );
1606 	}
1607 	if( libewf_single_file_entry_get_size(
1608 	     single_file_entry,
1609 	     &size,
1610 	     error ) != 1 )
1611 	{
1612 		libcerror_error_set(
1613 		 error,
1614 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1615 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1616 		 "%s: unable to retrieve size.",
1617 		 function );
1618 
1619 		return( -1 );
1620 	}
1621 	if( ( whence != SEEK_CUR )
1622 	 && ( whence != SEEK_END )
1623 	 && ( whence != SEEK_SET ) )
1624 	{
1625 		libcerror_error_set(
1626 		 error,
1627 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1628 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1629 		 "%s: unsupported whence.",
1630 		 function );
1631 
1632 		return( -1 );
1633 	}
1634 	if( whence == SEEK_CUR )
1635 	{
1636 		offset += internal_file_entry->offset;
1637 	}
1638 	else if( whence == SEEK_END )
1639 	{
1640 		offset += (off64_t) size;
1641 	}
1642 #if defined( HAVE_DEBUG_OUTPUT )
1643 	if( libcnotify_verbose != 0 )
1644 	{
1645 		libcnotify_printf(
1646 		 "%s: seeking offset: %" PRIi64 ".\n",
1647 		 function,
1648 		 offset );
1649 	}
1650 #endif
1651 	if( offset < 0 )
1652 	{
1653 		libcerror_error_set(
1654 		 error,
1655 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1656 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1657 		 "%s: invalid offset value out of bounds.",
1658 		 function );
1659 
1660 		return( -1 );
1661 	}
1662 	internal_file_entry->offset = offset;
1663 
1664 	return( offset );
1665 }
1666 
1667 /* Retrieves the current offset of the data
1668  * Returns the offset if successful or -1 on error
1669  */
libewf_file_entry_get_offset(libewf_file_entry_t * file_entry,off64_t * offset,libcerror_error_t ** error)1670 int libewf_file_entry_get_offset(
1671      libewf_file_entry_t *file_entry,
1672      off64_t *offset,
1673      libcerror_error_t **error )
1674 {
1675 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1676 	static char *function                             = "libewf_file_entry_get_offset";
1677 
1678 	if( file_entry == NULL )
1679 	{
1680 		libcerror_error_set(
1681 		 error,
1682 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1683 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1684 		 "%s: invalid file entry.",
1685 		 function );
1686 
1687 		return( -1 );
1688 	}
1689 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1690 
1691 	if( internal_file_entry->file_entry_tree_node == NULL )
1692 	{
1693 		libcerror_error_set(
1694 		 error,
1695 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1696 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1697 		 "%s: invalid file entry - missing file entry tree node.",
1698 		 function );
1699 
1700 		return( -1 );
1701 	}
1702 	if( offset == NULL )
1703 	{
1704 		libcerror_error_set(
1705 		 error,
1706 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1707 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1708 		 "%s: invalid offset.",
1709 		 function );
1710 
1711 		return( -1 );
1712 	}
1713 	*offset = internal_file_entry->offset;
1714 
1715 	return( 1 );
1716 }
1717 
1718 /* Retrieves the number of sub file entries
1719  * Returns 1 if successful or -1 on error
1720  */
libewf_file_entry_get_number_of_sub_file_entries(libewf_file_entry_t * file_entry,int * number_of_sub_file_entries,libcerror_error_t ** error)1721 int libewf_file_entry_get_number_of_sub_file_entries(
1722      libewf_file_entry_t *file_entry,
1723      int *number_of_sub_file_entries,
1724      libcerror_error_t **error )
1725 {
1726 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1727 	static char *function                             = "libewf_file_entry_get_number_of_sub_file_entries";
1728 
1729 	if( file_entry == NULL )
1730 	{
1731 		libcerror_error_set(
1732 		 error,
1733 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1734 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1735 		 "%s: invalid file entry.",
1736 		 function );
1737 
1738 		return( -1 );
1739 	}
1740 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1741 
1742 	if( libcdata_tree_node_get_number_of_sub_nodes(
1743 	     internal_file_entry->file_entry_tree_node,
1744 	     number_of_sub_file_entries,
1745 	     error ) != 1 )
1746 	{
1747 		libcerror_error_set(
1748 		 error,
1749 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1750 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1751 		 "%s: unable to retrieve number of sub file entries.",
1752 		 function );
1753 
1754 		return( -1 );
1755 	}
1756 	return( 1 );
1757 }
1758 
1759 /* Retrieves the sub file entry for the specific index
1760  * Returns 1 if successful or -1 on error
1761  */
libewf_file_entry_get_sub_file_entry(libewf_file_entry_t * file_entry,int sub_file_entry_index,libewf_file_entry_t ** sub_file_entry,libcerror_error_t ** error)1762 int libewf_file_entry_get_sub_file_entry(
1763      libewf_file_entry_t *file_entry,
1764      int sub_file_entry_index,
1765      libewf_file_entry_t **sub_file_entry,
1766      libcerror_error_t **error )
1767 {
1768 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1769 	libcdata_tree_node_t *sub_node                    = NULL;
1770 	static char *function                             = "libewf_file_entry_get_sub_file_entry";
1771 
1772 	if( file_entry == NULL )
1773 	{
1774 		libcerror_error_set(
1775 		 error,
1776 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1777 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1778 		 "%s: invalid file entry.",
1779 		 function );
1780 
1781 		return( -1 );
1782 	}
1783 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1784 
1785 	if( internal_file_entry->file_entry_tree_node == NULL )
1786 	{
1787 		libcerror_error_set(
1788 		 error,
1789 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1790 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1791 		 "%s: invalid file entry - missing file entry tree node.",
1792 		 function );
1793 
1794 		return( -1 );
1795 	}
1796 	if( sub_file_entry == NULL )
1797 	{
1798 		libcerror_error_set(
1799 		 error,
1800 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1801 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1802 		 "%s: invalid sub file entry.",
1803 		 function );
1804 
1805 		return( -1 );
1806 	}
1807 	if( *sub_file_entry != NULL )
1808 	{
1809 		libcerror_error_set(
1810 		 error,
1811 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1812 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1813 		 "%s: sub file entry already set.",
1814 		 function );
1815 
1816 		return( -1 );
1817 	}
1818 	if( libcdata_tree_node_get_sub_node_by_index(
1819 	     internal_file_entry->file_entry_tree_node,
1820              sub_file_entry_index,
1821              &sub_node,
1822 	     error ) != 1 )
1823 	{
1824 		libcerror_error_set(
1825 		 error,
1826 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1827 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1828 		 "%s: unable to retrieve sub file entry tree node.",
1829 		 function );
1830 
1831 		return( -1 );
1832 	}
1833 	if( sub_node == NULL )
1834 	{
1835 		libcerror_error_set(
1836 		 error,
1837 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1838 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1839 		 "%s: invalid sub node.",
1840 		 function );
1841 
1842 		return( -1 );
1843 	}
1844 	if( libewf_file_entry_initialize(
1845 	     sub_file_entry,
1846 	     internal_file_entry->internal_handle,
1847 	     sub_node,
1848 	     LIBEWF_ITEM_FLAGS_DEFAULT,
1849 	     error ) != 1 )
1850 	{
1851 		libcerror_error_set(
1852 		 error,
1853 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1854 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1855 		 "%s: unable to initialize sub file entry.",
1856 		 function );
1857 
1858 		return( -1 );
1859 	}
1860 	return( 1 );
1861 }
1862 
1863 /* Retrieves the sub file entry for the specific UTF-8 encoded name
1864  * Returns 1 if successful, 0 if no such sub file entry or -1 on error
1865  */
libewf_file_entry_get_sub_file_entry_by_utf8_name(libewf_file_entry_t * file_entry,const uint8_t * utf8_string,size_t utf8_string_length,libewf_file_entry_t ** sub_file_entry,libcerror_error_t ** error)1866 int libewf_file_entry_get_sub_file_entry_by_utf8_name(
1867      libewf_file_entry_t *file_entry,
1868      const uint8_t *utf8_string,
1869      size_t utf8_string_length,
1870      libewf_file_entry_t **sub_file_entry,
1871      libcerror_error_t **error )
1872 {
1873 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1874 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
1875 	libcdata_tree_node_t *sub_node                    = NULL;
1876 	static char *function                             = "libewf_file_entry_get_sub_file_entry_by_utf8_name";
1877 	int result                                        = 0;
1878 
1879 	if( file_entry == NULL )
1880 	{
1881 		libcerror_error_set(
1882 		 error,
1883 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1884 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1885 		 "%s: invalid file entry.",
1886 		 function );
1887 
1888 		return( -1 );
1889 	}
1890 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
1891 
1892 	if( internal_file_entry->file_entry_tree_node == NULL )
1893 	{
1894 		libcerror_error_set(
1895 		 error,
1896 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1897 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1898 		 "%s: invalid file entry - missing file entry tree node.",
1899 		 function );
1900 
1901 		return( -1 );
1902 	}
1903 	if( sub_file_entry == NULL )
1904 	{
1905 		libcerror_error_set(
1906 		 error,
1907 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1908 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1909 		 "%s: invalid sub file entry.",
1910 		 function );
1911 
1912 		return( -1 );
1913 	}
1914 	if( *sub_file_entry != NULL )
1915 	{
1916 		libcerror_error_set(
1917 		 error,
1918 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1919 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1920 		 "%s: sub file entry already set.",
1921 		 function );
1922 
1923 		return( -1 );
1924 	}
1925 	result = libewf_single_file_tree_get_sub_node_by_utf8_name(
1926 	          internal_file_entry->file_entry_tree_node,
1927 	          utf8_string,
1928 	          utf8_string_length,
1929 	          &sub_node,
1930 	          &sub_single_file_entry,
1931 	          error );
1932 
1933 	if( result == -1 )
1934 	{
1935 		libcerror_error_set(
1936 		 error,
1937 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1938 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1939 		 "%s: unable to retrieve sub file entry by UTF-8 name.",
1940 		 function );
1941 
1942 		return( -1 );
1943 	}
1944 	else if( result != 0 )
1945 	{
1946 		if( libewf_file_entry_initialize(
1947 		     sub_file_entry,
1948 		     internal_file_entry->internal_handle,
1949 		     sub_node,
1950 		     LIBEWF_ITEM_FLAGS_DEFAULT,
1951 		     error ) != 1 )
1952 		{
1953 			libcerror_error_set(
1954 			 error,
1955 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1956 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1957 			 "%s: unable to initialize sub file entry.",
1958 			 function );
1959 
1960 			return( -1 );
1961 		}
1962 	}
1963 	return( result );
1964 }
1965 
1966 /* Retrieves the sub file entry for the specific UTF-8 encoded path
1967  * The path separator is the \ character
1968  * Returns 1 if successful, 0 if no such file entry or -1 on error
1969  */
libewf_file_entry_get_sub_file_entry_by_utf8_path(libewf_file_entry_t * file_entry,const uint8_t * utf8_string,size_t utf8_string_length,libewf_file_entry_t ** sub_file_entry,libcerror_error_t ** error)1970 int libewf_file_entry_get_sub_file_entry_by_utf8_path(
1971      libewf_file_entry_t *file_entry,
1972      const uint8_t *utf8_string,
1973      size_t utf8_string_length,
1974      libewf_file_entry_t **sub_file_entry,
1975      libcerror_error_t **error )
1976 {
1977 	libewf_internal_file_entry_t *internal_file_entry = NULL;
1978 	libewf_single_file_entry_t *single_file_entry     = NULL;
1979 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
1980 	libcdata_tree_node_t *node                        = NULL;
1981 	libcdata_tree_node_t *sub_node                    = NULL;
1982 	uint8_t *utf8_string_segment                      = NULL;
1983 	static char *function                             = "libewf_file_entry_get_sub_file_entry_by_utf8_path";
1984 	size_t utf8_string_index                          = 0;
1985 	size_t utf8_string_segment_length                 = 0;
1986 	int result                                        = 0;
1987 
1988 	if( file_entry == NULL )
1989 	{
1990 		libcerror_error_set(
1991 		 error,
1992 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1993 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1994 		 "%s: invalid file entry.",
1995 		 function );
1996 
1997 		return( -1 );
1998 	}
1999 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
2000 
2001 	if( utf8_string == NULL )
2002 	{
2003 		libcerror_error_set(
2004 		 error,
2005 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2006 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2007 		 "%s: invalid UTF-8 string.",
2008 		 function );
2009 
2010 		return( -1 );
2011 	}
2012 	if( utf8_string_length > (size_t) SSIZE_MAX )
2013 	{
2014 		libcerror_error_set(
2015 		 error,
2016 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2017 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2018 		 "%s: invalid UTF-8 string length value exceeds maximum.",
2019 		 function );
2020 
2021 		return( -1 );
2022 	}
2023 	if( sub_file_entry == NULL )
2024 	{
2025 		libcerror_error_set(
2026 		 error,
2027 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2028 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2029 		 "%s: invalid sub file entry.",
2030 		 function );
2031 
2032 		return( -1 );
2033 	}
2034 	if( *sub_file_entry != NULL )
2035 	{
2036 		libcerror_error_set(
2037 		 error,
2038 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2039 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2040 		 "%s: sub file entry already set.",
2041 		 function );
2042 
2043 		return( -1 );
2044 	}
2045 	if( libcdata_tree_node_get_value(
2046 	     internal_file_entry->file_entry_tree_node,
2047 	     (intptr_t **) &single_file_entry,
2048 	     error ) != 1 )
2049 	{
2050 		libcerror_error_set(
2051 		 error,
2052 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2053 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2054 		 "%s: unable to retrieve value from file entry tree node.",
2055 		 function );
2056 
2057 		return( -1 );
2058 	}
2059 	if( single_file_entry == NULL )
2060 	{
2061 		libcerror_error_set(
2062 		 error,
2063 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2064 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2065 		 "%s: missing file entry values.",
2066 		 function );
2067 
2068 		return( -1 );
2069 	}
2070 	node = internal_file_entry->file_entry_tree_node;
2071 
2072 	if( utf8_string_length > 0 )
2073 	{
2074 		/* Ignore a leading separator
2075 		 */
2076 		if( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
2077 		{
2078 			utf8_string_index++;
2079 		}
2080 	}
2081 	if( ( utf8_string_length == 0 )
2082 	 || ( utf8_string_length == 1 ) )
2083 	{
2084 		result = 1;
2085 	}
2086 	while( utf8_string_index < utf8_string_length )
2087 	{
2088 		utf8_string_segment        = (uint8_t *) &( utf8_string[ utf8_string_index ] );
2089 		utf8_string_segment_length = 0;
2090 
2091 		while( utf8_string_index < utf8_string_length )
2092 		{
2093 			if( ( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
2094 			 || ( utf8_string[ utf8_string_index ] == (uint8_t) 0 ) )
2095 			{
2096 				utf8_string_index++;
2097 
2098 				break;
2099 			}
2100 			utf8_string_index++;
2101 
2102 			utf8_string_segment_length++;
2103 		}
2104 		if( utf8_string_segment_length == 0 )
2105 		{
2106 			libcerror_error_set(
2107 			 error,
2108 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2109 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2110 			 "%s: missing sub file entry name.",
2111 			 function );
2112 
2113 			return( -1 );
2114 		}
2115 		result = libewf_single_file_tree_get_sub_node_by_utf8_name(
2116 			  node,
2117 			  utf8_string_segment,
2118 			  utf8_string_segment_length,
2119 			  &sub_node,
2120 			  &sub_single_file_entry,
2121 			  error );
2122 
2123 		if( result == -1 )
2124 		{
2125 			libcerror_error_set(
2126 			 error,
2127 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2128 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2129 			 "%s: unable to retrieve sub node by name.",
2130 			 function );
2131 
2132 			return( -1 );
2133 		}
2134 		else if( result == 0 )
2135 		{
2136 			break;
2137 		}
2138 		node = sub_node;
2139 	}
2140 	if( result != 0 )
2141 	{
2142 		if( libewf_file_entry_initialize(
2143 		     sub_file_entry,
2144 		     internal_file_entry->internal_handle,
2145 		     sub_node,
2146 		     LIBEWF_ITEM_FLAGS_DEFAULT,
2147 		     error ) != 1 )
2148 		{
2149 			libcerror_error_set(
2150 			 error,
2151 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2152 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2153 			 "%s: unable to initialize sub file entry.",
2154 			 function );
2155 
2156 			return( -1 );
2157 		}
2158 	}
2159 	return( result );
2160 }
2161 
2162 /* Retrieves the sub file entry for the specific UTF-16 encoded name
2163  * Returns 1 if successful, 0 if no such sub file entry or -1 on error
2164  */
libewf_file_entry_get_sub_file_entry_by_utf16_name(libewf_file_entry_t * file_entry,const uint16_t * utf16_string,size_t utf16_string_length,libewf_file_entry_t ** sub_file_entry,libcerror_error_t ** error)2165 int libewf_file_entry_get_sub_file_entry_by_utf16_name(
2166      libewf_file_entry_t *file_entry,
2167      const uint16_t *utf16_string,
2168      size_t utf16_string_length,
2169      libewf_file_entry_t **sub_file_entry,
2170      libcerror_error_t **error )
2171 {
2172 	libewf_internal_file_entry_t *internal_file_entry = NULL;
2173 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
2174 	libcdata_tree_node_t *sub_node                    = NULL;
2175 	static char *function                             = "libewf_file_entry_get_sub_file_entry_by_utf16_name";
2176 	int result                                        = 0;
2177 
2178 	if( file_entry == NULL )
2179 	{
2180 		libcerror_error_set(
2181 		 error,
2182 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2183 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2184 		 "%s: invalid file entry.",
2185 		 function );
2186 
2187 		return( -1 );
2188 	}
2189 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
2190 
2191 	if( internal_file_entry->file_entry_tree_node == NULL )
2192 	{
2193 		libcerror_error_set(
2194 		 error,
2195 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2196 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2197 		 "%s: invalid file entry - missing file entry tree node.",
2198 		 function );
2199 
2200 		return( -1 );
2201 	}
2202 	if( sub_file_entry == NULL )
2203 	{
2204 		libcerror_error_set(
2205 		 error,
2206 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2207 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2208 		 "%s: invalid sub file entry.",
2209 		 function );
2210 
2211 		return( -1 );
2212 	}
2213 	if( *sub_file_entry != NULL )
2214 	{
2215 		libcerror_error_set(
2216 		 error,
2217 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2218 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2219 		 "%s: sub file entry already set.",
2220 		 function );
2221 
2222 		return( -1 );
2223 	}
2224 	result = libewf_single_file_tree_get_sub_node_by_utf16_name(
2225 	          internal_file_entry->file_entry_tree_node,
2226 	          utf16_string,
2227 	          utf16_string_length,
2228 	          &sub_node,
2229 	          &sub_single_file_entry,
2230 	          error );
2231 
2232 	if( result == -1 )
2233 	{
2234 		libcerror_error_set(
2235 		 error,
2236 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2237 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2238 		 "%s: unable to retrieve sub file entry by UTF-16 name.",
2239 		 function );
2240 
2241 		return( -1 );
2242 	}
2243 	else if( result != 0 )
2244 	{
2245 		if( libewf_file_entry_initialize(
2246 		     sub_file_entry,
2247 		     internal_file_entry->internal_handle,
2248 		     sub_node,
2249 		     LIBEWF_ITEM_FLAGS_DEFAULT,
2250 		     error ) != 1 )
2251 		{
2252 			libcerror_error_set(
2253 			 error,
2254 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2255 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2256 			 "%s: unable to initialize sub file entry.",
2257 			 function );
2258 
2259 			return( -1 );
2260 		}
2261 	}
2262 	return( result );
2263 }
2264 
2265 /* Retrieves the sub file entry for the specific UTF-16 encoded path
2266  * The path separator is the \ character
2267  * Returns 1 if successful, 0 if no such file entry or -1 on error
2268  */
libewf_file_entry_get_sub_file_entry_by_utf16_path(libewf_file_entry_t * file_entry,const uint16_t * utf16_string,size_t utf16_string_length,libewf_file_entry_t ** sub_file_entry,libcerror_error_t ** error)2269 int libewf_file_entry_get_sub_file_entry_by_utf16_path(
2270      libewf_file_entry_t *file_entry,
2271      const uint16_t *utf16_string,
2272      size_t utf16_string_length,
2273      libewf_file_entry_t **sub_file_entry,
2274      libcerror_error_t **error )
2275 {
2276 	libewf_internal_file_entry_t *internal_file_entry = NULL;
2277 	libewf_single_file_entry_t *single_file_entry     = NULL;
2278 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
2279 	libcdata_tree_node_t *node                        = NULL;
2280 	libcdata_tree_node_t *sub_node                    = NULL;
2281 	uint16_t *utf16_string_segment                    = NULL;
2282 	static char *function                             = "libewf_file_entry_get_sub_file_entry_by_utf16_path";
2283 	size_t utf16_string_index                         = 0;
2284 	size_t utf16_string_segment_length                = 0;
2285 	int result                                        = 0;
2286 
2287 	if( file_entry == NULL )
2288 	{
2289 		libcerror_error_set(
2290 		 error,
2291 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2292 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2293 		 "%s: invalid file entry.",
2294 		 function );
2295 
2296 		return( -1 );
2297 	}
2298 	internal_file_entry = (libewf_internal_file_entry_t *) file_entry;
2299 
2300 	if( utf16_string == NULL )
2301 	{
2302 		libcerror_error_set(
2303 		 error,
2304 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2305 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2306 		 "%s: invalid UTF-16 string.",
2307 		 function );
2308 
2309 		return( -1 );
2310 	}
2311 	if( utf16_string_length > (size_t) SSIZE_MAX )
2312 	{
2313 		libcerror_error_set(
2314 		 error,
2315 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2316 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
2317 		 "%s: invalid UTF-16 string length value exceeds maximum.",
2318 		 function );
2319 
2320 		return( -1 );
2321 	}
2322 	if( sub_file_entry == NULL )
2323 	{
2324 		libcerror_error_set(
2325 		 error,
2326 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2327 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2328 		 "%s: invalid sub file entry.",
2329 		 function );
2330 
2331 		return( -1 );
2332 	}
2333 	if( *sub_file_entry != NULL )
2334 	{
2335 		libcerror_error_set(
2336 		 error,
2337 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2338 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2339 		 "%s: sub file entry already set.",
2340 		 function );
2341 
2342 		return( -1 );
2343 	}
2344 	if( libcdata_tree_node_get_value(
2345 	     internal_file_entry->file_entry_tree_node,
2346 	     (intptr_t **) &single_file_entry,
2347 	     error ) != 1 )
2348 	{
2349 		libcerror_error_set(
2350 		 error,
2351 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2352 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2353 		 "%s: unable to retrieve value from file entry tree node.",
2354 		 function );
2355 
2356 		return( -1 );
2357 	}
2358 	if( single_file_entry == NULL )
2359 	{
2360 		libcerror_error_set(
2361 		 error,
2362 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2363 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2364 		 "%s: missing file entry values.",
2365 		 function );
2366 
2367 		return( -1 );
2368 	}
2369 	node = internal_file_entry->file_entry_tree_node;
2370 
2371 	if( utf16_string_length > 0 )
2372 	{
2373 		/* Ignore a leading separator
2374 		 */
2375 		if( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
2376 		{
2377 			utf16_string_index++;
2378 		}
2379 	}
2380 	if( ( utf16_string_length == 0 )
2381 	 || ( utf16_string_length == 1 ) )
2382 	{
2383 		result = 1;
2384 	}
2385 	while( utf16_string_index < utf16_string_length )
2386 	{
2387 		utf16_string_segment        = (uint16_t *) &( utf16_string[ utf16_string_index ] );
2388 		utf16_string_segment_length = 0;
2389 
2390 		while( utf16_string_index < utf16_string_length )
2391 		{
2392 			if( ( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
2393 			 || ( utf16_string[ utf16_string_index ] == (uint16_t) 0 ) )
2394 			{
2395 				utf16_string_index++;
2396 
2397 				break;
2398 			}
2399 			utf16_string_index++;
2400 
2401 			utf16_string_segment_length++;
2402 		}
2403 		if( utf16_string_segment_length == 0 )
2404 		{
2405 			libcerror_error_set(
2406 			 error,
2407 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2408 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2409 			 "%s: missing sub file entry name.",
2410 			 function );
2411 
2412 			return( -1 );
2413 		}
2414 		result = libewf_single_file_tree_get_sub_node_by_utf16_name(
2415 			  node,
2416 			  utf16_string_segment,
2417 			  utf16_string_segment_length,
2418 			  &sub_node,
2419 			  &sub_single_file_entry,
2420 			  error );
2421 
2422 		if( result == -1 )
2423 		{
2424 			libcerror_error_set(
2425 			 error,
2426 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2427 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2428 			 "%s: unable to retrieve sub node by name.",
2429 			 function );
2430 
2431 			return( -1 );
2432 		}
2433 		else if( result == 0 )
2434 		{
2435 			break;
2436 		}
2437 		node = sub_node;
2438 	}
2439 	if( result != 0 )
2440 	{
2441 		if( libewf_file_entry_initialize(
2442 		     sub_file_entry,
2443 		     internal_file_entry->internal_handle,
2444 		     sub_node,
2445 		     LIBEWF_ITEM_FLAGS_DEFAULT,
2446 		     error ) != 1 )
2447 		{
2448 			libcerror_error_set(
2449 			 error,
2450 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2451 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2452 			 "%s: unable to initialize sub file entry.",
2453 			 function );
2454 
2455 			return( -1 );
2456 		}
2457 	}
2458 	return( result );
2459 }
2460 
2461