1 /*
2 * Catalog functions
3 *
4 * Copyright (C) 2009-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 "libesedb_data_definition.h"
27 #include "libesedb_debug.h"
28 #include "libesedb_definitions.h"
29 #include "libesedb_catalog.h"
30 #include "libesedb_catalog_definition.h"
31 #include "libesedb_libbfio.h"
32 #include "libesedb_libcdata.h"
33 #include "libesedb_libcerror.h"
34 #include "libesedb_libcnotify.h"
35 #include "libesedb_libfcache.h"
36 #include "libesedb_libfdata.h"
37 #include "libesedb_libuna.h"
38 #include "libesedb_page_tree.h"
39 #include "libesedb_table_definition.h"
40
41 /* Creates a catalog
42 * Make sure the value catalog is referencing, is set to NULL
43 * Returns 1 if successful or -1 on error
44 */
libesedb_catalog_initialize(libesedb_catalog_t ** catalog,libesedb_io_handle_t * io_handle,uint32_t root_page_number,libfdata_vector_t * pages_vector,libfcache_cache_t * pages_cache,libcerror_error_t ** error)45 int libesedb_catalog_initialize(
46 libesedb_catalog_t **catalog,
47 libesedb_io_handle_t *io_handle,
48 uint32_t root_page_number,
49 libfdata_vector_t *pages_vector,
50 libfcache_cache_t *pages_cache,
51 libcerror_error_t **error )
52 {
53 static char *function = "libesedb_catalog_initialize";
54
55 if( catalog == NULL )
56 {
57 libcerror_error_set(
58 error,
59 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61 "%s: invalid catalog.",
62 function );
63
64 return( -1 );
65 }
66 if( *catalog != NULL )
67 {
68 libcerror_error_set(
69 error,
70 LIBCERROR_ERROR_DOMAIN_RUNTIME,
71 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72 "%s: invalid catalog value already set.",
73 function );
74
75 return( -1 );
76 }
77 *catalog = memory_allocate_structure(
78 libesedb_catalog_t );
79
80 if( *catalog == NULL )
81 {
82 libcerror_error_set(
83 error,
84 LIBCERROR_ERROR_DOMAIN_MEMORY,
85 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86 "%s: unable to create catalog.",
87 function );
88
89 goto on_error;
90 }
91 if( memory_set(
92 *catalog,
93 0,
94 sizeof( libesedb_catalog_t ) ) == NULL )
95 {
96 libcerror_error_set(
97 error,
98 LIBCERROR_ERROR_DOMAIN_MEMORY,
99 LIBCERROR_MEMORY_ERROR_SET_FAILED,
100 "%s: unable to clear catalog.",
101 function );
102
103 memory_free(
104 *catalog );
105
106 *catalog = NULL;
107
108 return( -1 );
109 }
110 if( libesedb_page_tree_initialize(
111 &( ( *catalog )->page_tree ),
112 io_handle,
113 pages_vector,
114 pages_cache,
115 LIBESEDB_FDP_OBJECT_IDENTIFIER_CATALOG,
116 root_page_number,
117 NULL,
118 NULL,
119 error ) != 1 )
120 {
121 libcerror_error_set(
122 error,
123 LIBCERROR_ERROR_DOMAIN_RUNTIME,
124 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
125 "%s: unable to create page tree.",
126 function );
127
128 goto on_error;
129 }
130 if( libcdata_array_initialize(
131 &( ( *catalog )->table_definition_array ),
132 0,
133 error ) != 1 )
134 {
135 libcerror_error_set(
136 error,
137 LIBCERROR_ERROR_DOMAIN_RUNTIME,
138 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
139 "%s: unable to create table definition array.",
140 function );
141
142 goto on_error;
143 }
144 return( 1 );
145
146 on_error:
147 if( *catalog != NULL )
148 {
149 if( ( *catalog )->page_tree != NULL )
150 {
151 libesedb_page_tree_free(
152 &( ( *catalog )->page_tree ),
153 NULL );
154 }
155 memory_free(
156 *catalog );
157
158 *catalog = NULL;
159 }
160 return( -1 );
161 }
162
163 /* Frees a catalog
164 * Returns 1 if successful or -1 on error
165 */
libesedb_catalog_free(libesedb_catalog_t ** catalog,libcerror_error_t ** error)166 int libesedb_catalog_free(
167 libesedb_catalog_t **catalog,
168 libcerror_error_t **error )
169 {
170 static char *function = "libesedb_catalog_free";
171 int result = 1;
172
173 if( catalog == NULL )
174 {
175 libcerror_error_set(
176 error,
177 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
178 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
179 "%s: invalid catalog.",
180 function );
181
182 return( -1 );
183 }
184 if( *catalog != NULL )
185 {
186 if( libesedb_page_tree_free(
187 &( ( *catalog )->page_tree ),
188 error ) != 1 )
189 {
190 libcerror_error_set(
191 error,
192 LIBCERROR_ERROR_DOMAIN_RUNTIME,
193 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
194 "%s: unable to free catalog page tree.",
195 function );
196
197 result = -1;
198 }
199 if( libcdata_array_free(
200 &( ( *catalog )->table_definition_array ),
201 (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_table_definition_free,
202 error ) != 1 )
203 {
204 libcerror_error_set(
205 error,
206 LIBCERROR_ERROR_DOMAIN_RUNTIME,
207 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
208 "%s: unable to free table definition array.",
209 function );
210
211 result = -1;
212 }
213 memory_free(
214 *catalog );
215
216 *catalog = NULL;
217 }
218 return( result );
219 }
220
221 /* Reads a catalog value
222 * Returns 1 if successful or -1 on error
223 */
libesedb_catalog_read_value_data(libesedb_catalog_t * catalog,const uint8_t * data,size_t data_size,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)224 int libesedb_catalog_read_value_data(
225 libesedb_catalog_t *catalog,
226 const uint8_t *data,
227 size_t data_size,
228 libesedb_table_definition_t **table_definition,
229 libcerror_error_t **error )
230 {
231 libesedb_catalog_definition_t *catalog_definition = NULL;
232 static char *function = "libesedb_catalog_read_value_data";
233 int entry_index = 0;
234
235 if( catalog == NULL )
236 {
237 libcerror_error_set(
238 error,
239 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
240 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
241 "%s: invalid catalog.",
242 function );
243
244 return( -1 );
245 }
246 if( catalog->page_tree == NULL )
247 {
248 libcerror_error_set(
249 error,
250 LIBCERROR_ERROR_DOMAIN_RUNTIME,
251 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
252 "%s: invalid catalog - missing page tree.",
253 function );
254
255 return( -1 );
256 }
257 if( catalog->page_tree->io_handle == NULL )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
262 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
263 "%s: invalid catalog - invalid page tree - missing IO handle.",
264 function );
265
266 return( -1 );
267 }
268 if( table_definition == NULL )
269 {
270 libcerror_error_set(
271 error,
272 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
273 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
274 "%s: invalid table definition.",
275 function );
276
277 return( -1 );
278 }
279 if( libesedb_catalog_definition_initialize(
280 &catalog_definition,
281 error ) != 1 )
282 {
283 libcerror_error_set(
284 error,
285 LIBCERROR_ERROR_DOMAIN_RUNTIME,
286 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
287 "%s: unable to create catalog definition.",
288 function );
289
290 goto on_error;
291 }
292 if( libesedb_catalog_definition_read_data(
293 catalog_definition,
294 data,
295 data_size,
296 catalog->page_tree->io_handle->ascii_codepage,
297 error ) != 1 )
298 {
299 libcerror_error_set(
300 error,
301 LIBCERROR_ERROR_DOMAIN_IO,
302 LIBCERROR_IO_ERROR_READ_FAILED,
303 "%s: unable to read catalog definition.",
304 function );
305
306 goto on_error;
307 }
308 if( ( catalog_definition->type != LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE )
309 && ( *table_definition == NULL ) )
310 {
311 /* TODO add build-in table 1 support */
312 #if defined( HAVE_DEBUG_OUTPUT )
313 if( libcnotify_verbose != 0 )
314 {
315 libcnotify_printf(
316 "%s: missing table definition for catalog definition type: %" PRIu16 ".\n",
317 function,
318 catalog_definition->type );
319 }
320 #endif
321 if( libesedb_catalog_definition_free(
322 &catalog_definition,
323 error ) != 1 )
324 {
325 libcerror_error_set(
326 error,
327 LIBCERROR_ERROR_DOMAIN_RUNTIME,
328 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
329 "%s: unable to free catalog definition.",
330 function );
331
332 goto on_error;
333 }
334 catalog_definition = NULL;
335 }
336 else switch( catalog_definition->type )
337 {
338 case LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE:
339 *table_definition = NULL;
340
341 if( libesedb_table_definition_initialize(
342 table_definition,
343 catalog_definition,
344 error ) != 1 )
345 {
346 libcerror_error_set(
347 error,
348 LIBCERROR_ERROR_DOMAIN_RUNTIME,
349 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
350 "%s: unable to create table definition.",
351 function );
352
353 libesedb_table_definition_free(
354 table_definition,
355 NULL );
356
357 goto on_error;
358 }
359 catalog_definition = NULL;
360
361 if( libcdata_array_append_entry(
362 catalog->table_definition_array,
363 &entry_index,
364 (intptr_t *) *table_definition,
365 error ) != 1 )
366 {
367 libcerror_error_set(
368 error,
369 LIBCERROR_ERROR_DOMAIN_RUNTIME,
370 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
371 "%s: unable to append table definition to table definition array.",
372 function );
373
374 libesedb_table_definition_free(
375 table_definition,
376 NULL );
377
378 goto on_error;
379 }
380 break;
381
382 case LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN:
383 if( libesedb_table_definition_append_column_catalog_definition(
384 *table_definition,
385 catalog_definition,
386 error ) != 1 )
387 {
388 libcerror_error_set(
389 error,
390 LIBCERROR_ERROR_DOMAIN_RUNTIME,
391 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
392 "%s: unable to append column catalog definition to table definition.",
393 function );
394
395 goto on_error;
396 }
397 catalog_definition = NULL;
398
399 break;
400
401 case LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX:
402 if( libesedb_table_definition_append_index_catalog_definition(
403 *table_definition,
404 catalog_definition,
405 error ) != 1 )
406 {
407 libcerror_error_set(
408 error,
409 LIBCERROR_ERROR_DOMAIN_RUNTIME,
410 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
411 "%s: unable to append index catalog definition to table definition.",
412 function );
413
414 goto on_error;
415 }
416 catalog_definition = NULL;
417
418 break;
419
420 case LIBESEDB_CATALOG_DEFINITION_TYPE_LONG_VALUE:
421 if( libesedb_table_definition_set_long_value_catalog_definition(
422 *table_definition,
423 catalog_definition,
424 error ) != 1 )
425 {
426 libcerror_error_set(
427 error,
428 LIBCERROR_ERROR_DOMAIN_RUNTIME,
429 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
430 "%s: unable to set long value catalog definition in table definition.",
431 function );
432
433 goto on_error;
434 }
435 catalog_definition = NULL;
436
437 break;
438
439 case LIBESEDB_CATALOG_DEFINITION_TYPE_CALLBACK:
440 if( libesedb_table_definition_set_callback_catalog_definition(
441 *table_definition,
442 catalog_definition,
443 error ) != 1 )
444 {
445 libcerror_error_set(
446 error,
447 LIBCERROR_ERROR_DOMAIN_RUNTIME,
448 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
449 "%s: unable to set callback catalog definition in table definition.",
450 function );
451
452 goto on_error;
453 }
454 catalog_definition = NULL;
455
456 break;
457
458 default:
459 #if defined( HAVE_DEBUG_OUTPUT )
460 if( libcnotify_verbose != 0 )
461 {
462 libcnotify_printf(
463 "%s: unsupported catalog definition type: %" PRIu16 ".\n",
464 function,
465 catalog_definition->type );
466 }
467 #endif
468 if( libesedb_catalog_definition_free(
469 &catalog_definition,
470 error ) != 1 )
471 {
472 libcerror_error_set(
473 error,
474 LIBCERROR_ERROR_DOMAIN_RUNTIME,
475 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
476 "%s: unable to free catalog definition.",
477 function );
478
479 goto on_error;
480 }
481 catalog_definition = NULL;
482
483 break;
484 }
485 return( 1 );
486
487 on_error:
488 if( catalog_definition != NULL )
489 {
490 libesedb_catalog_definition_free(
491 &catalog_definition,
492 NULL );
493 }
494 return( -1 );
495 }
496
497 /* Reads the catalog values from a leaf page
498 * Returns 1 if successful or -1 on error
499 */
libesedb_catalog_read_values_from_leaf_page(libesedb_catalog_t * catalog,libesedb_page_t * page,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)500 int libesedb_catalog_read_values_from_leaf_page(
501 libesedb_catalog_t *catalog,
502 libesedb_page_t *page,
503 libesedb_table_definition_t **table_definition,
504 libcerror_error_t **error )
505 {
506 libesedb_page_tree_value_t *page_tree_value = NULL;
507 libesedb_page_value_t *page_value = NULL;
508 static char *function = "libesedb_catalog_read_values_from_leaf_page";
509 uint32_t page_flags = 0;
510 uint16_t number_of_page_values = 0;
511 uint16_t page_value_index = 0;
512
513 if( catalog == NULL )
514 {
515 libcerror_error_set(
516 error,
517 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
518 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
519 "%s: invalid catalog.",
520 function );
521
522 return( -1 );
523 }
524 if( libesedb_page_get_flags(
525 page,
526 &page_flags,
527 error ) != 1 )
528 {
529 libcerror_error_set(
530 error,
531 LIBCERROR_ERROR_DOMAIN_RUNTIME,
532 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
533 "%s: unable to retrieve page flags.",
534 function );
535
536 goto on_error;
537 }
538 if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_LEAF ) == 0 )
539 {
540 libcerror_error_set(
541 error,
542 LIBCERROR_ERROR_DOMAIN_RUNTIME,
543 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
544 "%s: unsupported page - not a leaf page.",
545 function );
546
547 goto on_error;
548 }
549 if( libesedb_page_get_number_of_values(
550 page,
551 &number_of_page_values,
552 error ) != 1 )
553 {
554 libcerror_error_set(
555 error,
556 LIBCERROR_ERROR_DOMAIN_RUNTIME,
557 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
558 "%s: unable to retrieve number of page values.",
559 function );
560
561 goto on_error;
562 }
563 for( page_value_index = 1;
564 page_value_index < number_of_page_values;
565 page_value_index++ )
566 {
567 if( libesedb_page_get_value_by_index(
568 page,
569 page_value_index,
570 &page_value,
571 error ) != 1 )
572 {
573 libcerror_error_set(
574 error,
575 LIBCERROR_ERROR_DOMAIN_RUNTIME,
576 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
577 "%s: unable to retrieve page value: %" PRIu16 ".",
578 function,
579 page_value_index );
580
581 goto on_error;
582 }
583 if( page_value == NULL )
584 {
585 libcerror_error_set(
586 error,
587 LIBCERROR_ERROR_DOMAIN_RUNTIME,
588 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
589 "%s: missing page value: %" PRIu16 ".",
590 function,
591 page_value_index );
592
593 goto on_error;
594 }
595 #if defined( HAVE_DEBUG_OUTPUT )
596 if( libcnotify_verbose != 0 )
597 {
598 libcnotify_printf(
599 "%s: page value: %03" PRIu16 " page tag flags\t\t: 0x%02" PRIx8 "",
600 function,
601 page_value_index,
602 page_value->flags );
603 libesedb_debug_print_page_tag_flags(
604 page_value->flags );
605 libcnotify_printf(
606 "\n" );
607 }
608 #endif
609 if( ( page_value->flags & LIBESEDB_PAGE_TAG_FLAG_IS_DEFUNCT ) != 0 )
610 {
611 continue;
612 }
613 if( libesedb_page_tree_value_initialize(
614 &page_tree_value,
615 error ) != 1 )
616 {
617 libcerror_error_set(
618 error,
619 LIBCERROR_ERROR_DOMAIN_RUNTIME,
620 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
621 "%s: unable to create page tree value.",
622 function );
623
624 goto on_error;
625 }
626 if( libesedb_page_tree_value_read_data(
627 page_tree_value,
628 page_value->data,
629 (size_t) page_value->size,
630 page_value->flags,
631 error ) != 1 )
632 {
633 libcerror_error_set(
634 error,
635 LIBCERROR_ERROR_DOMAIN_IO,
636 LIBCERROR_IO_ERROR_READ_FAILED,
637 "%s: unable to read page tree value: %" PRIu16 ".",
638 function,
639 page_value_index );
640
641 goto on_error;
642 }
643 if( libesedb_catalog_read_value_data(
644 catalog,
645 page_tree_value->data,
646 page_tree_value->data_size,
647 table_definition,
648 error ) != 1 )
649 {
650 libcerror_error_set(
651 error,
652 LIBCERROR_ERROR_DOMAIN_IO,
653 LIBCERROR_IO_ERROR_READ_FAILED,
654 "%s: unable to read catalog value.",
655 function );
656
657 goto on_error;
658 }
659 if( libesedb_page_tree_value_free(
660 &page_tree_value,
661 error ) != 1 )
662 {
663 libcerror_error_set(
664 error,
665 LIBCERROR_ERROR_DOMAIN_RUNTIME,
666 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
667 "%s: unable to free page tree value.",
668 function );
669
670 goto on_error;
671 }
672 }
673 return( 1 );
674
675 on_error:
676 if( page_tree_value != NULL )
677 {
678 libesedb_page_tree_value_free(
679 &page_tree_value,
680 NULL );
681 }
682 return( -1 );
683 }
684
685 /* Reads the catalog
686 * Returns 1 if successful or -1 on error
687 */
libesedb_catalog_read_file_io_handle(libesedb_catalog_t * catalog,libbfio_handle_t * file_io_handle,libcerror_error_t ** error)688 int libesedb_catalog_read_file_io_handle(
689 libesedb_catalog_t *catalog,
690 libbfio_handle_t *file_io_handle,
691 libcerror_error_t **error )
692 {
693 libesedb_page_t *page = NULL;
694 libesedb_table_definition_t *table_definition = NULL;
695 static char *function = "libesedb_catalog_read_file_io_handle";
696 uint32_t leaf_page_number = 0;
697 int recursion_depth = 0;
698
699 if( catalog == NULL )
700 {
701 libcerror_error_set(
702 error,
703 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
704 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
705 "%s: invalid catalog.",
706 function );
707
708 return( -1 );
709 }
710 if( catalog->page_tree == NULL )
711 {
712 libcerror_error_set(
713 error,
714 LIBCERROR_ERROR_DOMAIN_RUNTIME,
715 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
716 "%s: invalid catalog - missing page tree.",
717 function );
718
719 return( -1 );
720 }
721 if( libesedb_page_tree_get_get_first_leaf_page_number(
722 catalog->page_tree,
723 file_io_handle,
724 &leaf_page_number,
725 error ) != 1 )
726 {
727 libcerror_error_set(
728 error,
729 LIBCERROR_ERROR_DOMAIN_RUNTIME,
730 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
731 "%s: unable to retrieve first leaf page number from page tree.",
732 function );
733
734 return( -1 );
735 }
736 while( leaf_page_number != 0 )
737 {
738 if( recursion_depth > LIBESEDB_MAXIMUM_LEAF_PAGE_RECURSION_DEPTH )
739 {
740 libcerror_error_set(
741 error,
742 LIBCERROR_ERROR_DOMAIN_RUNTIME,
743 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
744 "%s: invalid recursion depth value out of bounds.",
745 function );
746
747 return( -1 );
748 }
749 #if ( SIZEOF_INT <= 4 )
750 if( leaf_page_number > (uint32_t) INT_MAX )
751 #else
752 if( leaf_page_number > (unsigned int) INT_MAX )
753 #endif
754 {
755 libcerror_error_set(
756 error,
757 LIBCERROR_ERROR_DOMAIN_RUNTIME,
758 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
759 "%s: invalid leaf page number value out of bounds.",
760 function );
761
762 return( -1 );
763 }
764 if( libfdata_vector_get_element_value_by_index(
765 catalog->page_tree->pages_vector,
766 (intptr_t *) file_io_handle,
767 (libfdata_cache_t *) catalog->page_tree->pages_cache,
768 (int) leaf_page_number - 1,
769 (intptr_t **) &page,
770 0,
771 error ) != 1 )
772 {
773 libcerror_error_set(
774 error,
775 LIBCERROR_ERROR_DOMAIN_RUNTIME,
776 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
777 "%s: unable to retrieve page: %" PRIu32 ".",
778 function,
779 leaf_page_number );
780
781 return( -1 );
782 }
783 if( libesedb_catalog_read_values_from_leaf_page(
784 catalog,
785 page,
786 &table_definition,
787 error ) != 1 )
788 {
789 libcerror_error_set(
790 error,
791 LIBCERROR_ERROR_DOMAIN_RUNTIME,
792 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
793 "%s: unable to read values from page: %" PRIu32 ".",
794 function,
795 leaf_page_number );
796
797 return( -1 );
798 }
799 if( libesedb_page_get_next_page_number(
800 page,
801 &leaf_page_number,
802 error ) != 1 )
803 {
804 libcerror_error_set(
805 error,
806 LIBCERROR_ERROR_DOMAIN_RUNTIME,
807 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
808 "%s: unable to retrieve next page number from page: %" PRIu32 ".",
809 function,
810 leaf_page_number );
811
812 return( -1 );
813 }
814 recursion_depth++;
815 }
816 return( 1 );
817 }
818
819 /* Retrieves the number of table definitions
820 * Returns 1 if successful or -1 on error
821 */
libesedb_catalog_get_number_of_table_definitions(libesedb_catalog_t * catalog,int * number_of_table_definitions,libcerror_error_t ** error)822 int libesedb_catalog_get_number_of_table_definitions(
823 libesedb_catalog_t *catalog,
824 int *number_of_table_definitions,
825 libcerror_error_t **error )
826 {
827 static char *function = "libesedb_catalog_get_number_of_table_definitions";
828
829 if( catalog == NULL )
830 {
831 libcerror_error_set(
832 error,
833 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
834 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
835 "%s: invalid catalog.",
836 function );
837
838 return( -1 );
839 }
840 if( libcdata_array_get_number_of_entries(
841 catalog->table_definition_array,
842 number_of_table_definitions,
843 error ) != 1 )
844 {
845 libcerror_error_set(
846 error,
847 LIBCERROR_ERROR_DOMAIN_RUNTIME,
848 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
849 "%s: unable to retrieve number of entries from table definition array.",
850 function );
851
852 return( -1 );
853 }
854 return( 1 );
855 }
856
857 /* Retrieves the table definition for the specific index
858 * Returns 1 if successful or -1 on error
859 */
libesedb_catalog_get_table_definition_by_index(libesedb_catalog_t * catalog,int table_definition_index,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)860 int libesedb_catalog_get_table_definition_by_index(
861 libesedb_catalog_t *catalog,
862 int table_definition_index,
863 libesedb_table_definition_t **table_definition,
864 libcerror_error_t **error )
865 {
866 static char *function = "libesedb_catalog_get_table_definition_by_index";
867
868 if( catalog == NULL )
869 {
870 libcerror_error_set(
871 error,
872 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
873 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
874 "%s: invalid catalog.",
875 function );
876
877 return( -1 );
878 }
879 if( libcdata_array_get_entry_by_index(
880 catalog->table_definition_array,
881 table_definition_index,
882 (intptr_t **) table_definition,
883 error ) != 1 )
884 {
885 libcerror_error_set(
886 error,
887 LIBCERROR_ERROR_DOMAIN_RUNTIME,
888 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
889 "%s: unable to retrieve entry: %d from table definition array.",
890 function,
891 table_definition_index );
892
893 return( -1 );
894 }
895 return( 1 );
896 }
897
898 /* Retrieves the table definition for the specific name
899 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
900 */
libesedb_catalog_get_table_definition_by_name(libesedb_catalog_t * catalog,const uint8_t * table_name,size_t table_name_size,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)901 int libesedb_catalog_get_table_definition_by_name(
902 libesedb_catalog_t *catalog,
903 const uint8_t *table_name,
904 size_t table_name_size,
905 libesedb_table_definition_t **table_definition,
906 libcerror_error_t **error )
907 {
908 libesedb_table_definition_t *safe_table_definition = NULL;
909 static char *function = "libesedb_catalog_get_table_definition_by_name";
910 int entry_index = 0;
911 int number_of_entries = 0;
912 int result = 0;
913
914 if( catalog == NULL )
915 {
916 libcerror_error_set(
917 error,
918 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
919 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
920 "%s: invalid catalog.",
921 function );
922
923 return( -1 );
924 }
925 if( table_name == NULL )
926 {
927 libcerror_error_set(
928 error,
929 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
930 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
931 "%s: invalid table name.",
932 function );
933
934 return( -1 );
935 }
936 if( ( table_name_size == 0 )
937 || ( table_name_size > (size_t) SSIZE_MAX ) )
938 {
939 libcerror_error_set(
940 error,
941 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
942 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
943 "%s: invalid table name size value exceeds maximum.",
944 function );
945
946 return( -1 );
947 }
948 if( table_definition == NULL )
949 {
950 libcerror_error_set(
951 error,
952 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
953 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
954 "%s: invalid table definition.",
955 function );
956
957 return( -1 );
958 }
959 *table_definition = NULL;
960
961 if( libcdata_array_get_number_of_entries(
962 catalog->table_definition_array,
963 &number_of_entries,
964 error ) != 1 )
965 {
966 libcerror_error_set(
967 error,
968 LIBCERROR_ERROR_DOMAIN_RUNTIME,
969 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
970 "%s: unable to retrieve number of entries in table definition array.",
971 function );
972
973 return( -1 );
974 }
975 for( entry_index = 0;
976 entry_index < number_of_entries;
977 entry_index++ )
978 {
979 if( libcdata_array_get_entry_by_index(
980 catalog->table_definition_array,
981 entry_index,
982 (intptr_t **) &safe_table_definition,
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 entry: %d from table definition array.",
990 function,
991 entry_index );
992
993 return( -1 );
994 }
995 if( safe_table_definition == NULL )
996 {
997 libcerror_error_set(
998 error,
999 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1000 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1001 "%s: missing table definition: %d.",
1002 function,
1003 entry_index );
1004
1005 return( -1 );
1006 }
1007 result = libesedb_catalog_definition_compare_name(
1008 safe_table_definition->table_catalog_definition,
1009 table_name,
1010 table_name_size,
1011 error );
1012
1013 if( result == -1 )
1014 {
1015 libcerror_error_set(
1016 error,
1017 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1018 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1019 "%s: unable to compare table name with table catalog definition: %d name.",
1020 function,
1021 entry_index );
1022
1023 return( -1 );
1024 }
1025 else if( result == 1 )
1026 {
1027 break;
1028 }
1029 }
1030 if( result != 0 )
1031 {
1032 *table_definition = safe_table_definition;
1033 }
1034 return( result );
1035 }
1036
1037 /* Retrieves the table definition for the specific UTF-8 encoded name
1038 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
1039 */
libesedb_catalog_get_table_definition_by_utf8_name(libesedb_catalog_t * catalog,const uint8_t * utf8_string,size_t utf8_string_length,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)1040 int libesedb_catalog_get_table_definition_by_utf8_name(
1041 libesedb_catalog_t *catalog,
1042 const uint8_t *utf8_string,
1043 size_t utf8_string_length,
1044 libesedb_table_definition_t **table_definition,
1045 libcerror_error_t **error )
1046 {
1047 libesedb_table_definition_t *safe_table_definition = NULL;
1048 static char *function = "libesedb_catalog_get_table_definition_by_utf8_name";
1049 int entry_index = 0;
1050 int number_of_entries = 0;
1051 int result = 0;
1052
1053 if( catalog == NULL )
1054 {
1055 libcerror_error_set(
1056 error,
1057 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1058 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1059 "%s: invalid catalog.",
1060 function );
1061
1062 return( -1 );
1063 }
1064 if( utf8_string == NULL )
1065 {
1066 libcerror_error_set(
1067 error,
1068 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1069 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1070 "%s: invalid UTF-8 string.",
1071 function );
1072
1073 return( -1 );
1074 }
1075 if( ( utf8_string_length == 0 )
1076 || ( utf8_string_length > (size_t) SSIZE_MAX ) )
1077 {
1078 libcerror_error_set(
1079 error,
1080 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1081 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1082 "%s: invalid UTF-8 string length value exceeds maximum.",
1083 function );
1084
1085 return( -1 );
1086 }
1087 if( table_definition == NULL )
1088 {
1089 libcerror_error_set(
1090 error,
1091 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1092 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1093 "%s: invalid table definition.",
1094 function );
1095
1096 return( -1 );
1097 }
1098 *table_definition = NULL;
1099
1100 if( libcdata_array_get_number_of_entries(
1101 catalog->table_definition_array,
1102 &number_of_entries,
1103 error ) != 1 )
1104 {
1105 libcerror_error_set(
1106 error,
1107 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1108 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1109 "%s: unable to retrieve number of entries in table definition array.",
1110 function );
1111
1112 return( -1 );
1113 }
1114 for( entry_index = 0;
1115 entry_index < number_of_entries;
1116 entry_index++ )
1117 {
1118 if( libcdata_array_get_entry_by_index(
1119 catalog->table_definition_array,
1120 entry_index,
1121 (intptr_t **) &safe_table_definition,
1122 error ) != 1 )
1123 {
1124 libcerror_error_set(
1125 error,
1126 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1127 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1128 "%s: unable to retrieve entry: %d from table definition array.",
1129 function,
1130 entry_index );
1131
1132 return( -1 );
1133 }
1134 if( safe_table_definition == NULL )
1135 {
1136 libcerror_error_set(
1137 error,
1138 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1139 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1140 "%s: missing table definition: %d.",
1141 function,
1142 entry_index );
1143
1144 return( -1 );
1145 }
1146 result = libesedb_catalog_definition_compare_name_with_utf8_string(
1147 safe_table_definition->table_catalog_definition,
1148 utf8_string,
1149 utf8_string_length,
1150 error );
1151
1152 if( result == -1 )
1153 {
1154 libcerror_error_set(
1155 error,
1156 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1157 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1158 "%s: unable to compare UTF-8 string with table catalog definition: %d name.",
1159 function,
1160 entry_index );
1161
1162 return( -1 );
1163 }
1164 else if( result == LIBUNA_COMPARE_EQUAL )
1165 {
1166 result = 1;
1167
1168 break;
1169 }
1170 }
1171 if( result != 0 )
1172 {
1173 *table_definition = safe_table_definition;
1174 }
1175 return( result );
1176 }
1177
1178 /* Retrieves the table definition for the specific UTF-16 encoded name
1179 * Returns 1 if successful, 0 if no corresponding table definition was found or -1 on error
1180 */
libesedb_catalog_get_table_definition_by_utf16_name(libesedb_catalog_t * catalog,const uint16_t * utf16_string,size_t utf16_string_length,libesedb_table_definition_t ** table_definition,libcerror_error_t ** error)1181 int libesedb_catalog_get_table_definition_by_utf16_name(
1182 libesedb_catalog_t *catalog,
1183 const uint16_t *utf16_string,
1184 size_t utf16_string_length,
1185 libesedb_table_definition_t **table_definition,
1186 libcerror_error_t **error )
1187 {
1188 libesedb_table_definition_t *safe_table_definition = NULL;
1189 static char *function = "libesedb_catalog_get_table_definition_by_utf16_name";
1190 int entry_index = 0;
1191 int number_of_entries = 0;
1192 int result = 0;
1193
1194 if( catalog == NULL )
1195 {
1196 libcerror_error_set(
1197 error,
1198 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1199 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1200 "%s: invalid catalog.",
1201 function );
1202
1203 return( -1 );
1204 }
1205 if( utf16_string == NULL )
1206 {
1207 libcerror_error_set(
1208 error,
1209 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1210 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1211 "%s: invalid UTF-16 string.",
1212 function );
1213
1214 return( -1 );
1215 }
1216 if( ( utf16_string_length == 0 )
1217 || ( utf16_string_length > (size_t) SSIZE_MAX ) )
1218 {
1219 libcerror_error_set(
1220 error,
1221 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1222 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1223 "%s: invalid UTF-16 string length value exceeds maximum.",
1224 function );
1225
1226 return( -1 );
1227 }
1228 if( table_definition == NULL )
1229 {
1230 libcerror_error_set(
1231 error,
1232 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1233 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1234 "%s: invalid table definition.",
1235 function );
1236
1237 return( -1 );
1238 }
1239 *table_definition = NULL;
1240
1241 if( libcdata_array_get_number_of_entries(
1242 catalog->table_definition_array,
1243 &number_of_entries,
1244 error ) != 1 )
1245 {
1246 libcerror_error_set(
1247 error,
1248 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1249 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1250 "%s: unable to retrieve number of entries in table definition array.",
1251 function );
1252
1253 return( -1 );
1254 }
1255 for( entry_index = 0;
1256 entry_index < number_of_entries;
1257 entry_index++ )
1258 {
1259 if( libcdata_array_get_entry_by_index(
1260 catalog->table_definition_array,
1261 entry_index,
1262 (intptr_t **) &safe_table_definition,
1263 error ) != 1 )
1264 {
1265 libcerror_error_set(
1266 error,
1267 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1268 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1269 "%s: unable to retrieve entry: %d from table definition array.",
1270 function,
1271 entry_index );
1272
1273 return( -1 );
1274 }
1275 if( safe_table_definition == NULL )
1276 {
1277 libcerror_error_set(
1278 error,
1279 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1280 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1281 "%s: missing table definition: %d.",
1282 function,
1283 entry_index );
1284
1285 return( -1 );
1286 }
1287 result = libesedb_catalog_definition_compare_name_with_utf16_string(
1288 safe_table_definition->table_catalog_definition,
1289 utf16_string,
1290 utf16_string_length,
1291 error );
1292
1293 if( result == -1 )
1294 {
1295 libcerror_error_set(
1296 error,
1297 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1298 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1299 "%s: unable to compare UTF-16 string with table catalog definition: %d name.",
1300 function,
1301 entry_index );
1302
1303 return( -1 );
1304 }
1305 else if( result == LIBUNA_COMPARE_EQUAL )
1306 {
1307 result = 1;
1308
1309 break;
1310 }
1311 }
1312 if( result != 0 )
1313 {
1314 *table_definition = safe_table_definition;
1315 }
1316 return( result );
1317 }
1318
1319