1 /*
2  * Catalog definition 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 <byte_stream.h>
24 #include <memory.h>
25 #include <narrow_string.h>
26 #include <system_string.h>
27 #include <types.h>
28 #include <wide_string.h>
29 
30 #include "libesedb_catalog_definition.h"
31 #include "libesedb_codepage.h"
32 #include "libesedb_column_type.h"
33 #include "libesedb_debug.h"
34 #include "libesedb_definitions.h"
35 #include "libesedb_lcid.h"
36 #include "libesedb_libcerror.h"
37 #include "libesedb_libcnotify.h"
38 #include "libesedb_libuna.h"
39 #include "libesedb_unused.h"
40 
41 #include "esedb_page_values.h"
42 
43 #if !defined( LIBESEDB_ATTRIBUTE_FALLTHROUGH )
44 #if defined( __GNUC__ ) && __GNUC__ >= 7
45 #define LIBESEDB_ATTRIBUTE_FALLTHROUGH	__attribute__ ((fallthrough))
46 #else
47 #define LIBESEDB_ATTRIBUTE_FALLTHROUGH
48 #endif
49 #endif
50 
51 /* Creates a catalog definition
52  * Make sure the value catalog_definition is referencing, is set to NULL
53  * Returns 1 if successful or -1 on error
54  */
libesedb_catalog_definition_initialize(libesedb_catalog_definition_t ** catalog_definition,libcerror_error_t ** error)55 int libesedb_catalog_definition_initialize(
56      libesedb_catalog_definition_t **catalog_definition,
57      libcerror_error_t **error )
58 {
59 	static char *function = "libesedb_catalog_definition_initialize";
60 
61 	if( catalog_definition == NULL )
62 	{
63 		libcerror_error_set(
64 		 error,
65 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
66 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
67 		 "%s: invalid catalog definition.",
68 		 function );
69 
70 		return( -1 );
71 	}
72 	if( *catalog_definition != NULL )
73 	{
74 		libcerror_error_set(
75 		 error,
76 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
77 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
78 		 "%s: invalid catalog definition value already set.",
79 		 function );
80 
81 		return( -1 );
82 	}
83 	*catalog_definition = memory_allocate_structure(
84 	                       libesedb_catalog_definition_t );
85 
86 	if( *catalog_definition == NULL )
87 	{
88 		libcerror_error_set(
89 		 error,
90 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
91 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
92 		 "%s: unable to create catalog definition.",
93 		 function );
94 
95 		goto on_error;
96 	}
97 	if( memory_set(
98 	     *catalog_definition,
99 	     0,
100 	     sizeof( libesedb_catalog_definition_t ) ) == NULL )
101 	{
102 		libcerror_error_set(
103 		 error,
104 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
105 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
106 		 "%s: unable to clear catalog definition.",
107 		 function );
108 
109 		goto on_error;
110 	}
111 	return( 1 );
112 
113 on_error:
114 	if( *catalog_definition != NULL )
115 	{
116 		memory_free(
117 		 *catalog_definition );
118 
119 		*catalog_definition = NULL;
120 	}
121 	return( -1 );
122 }
123 
124 /* Frees a catalog definition
125  * Returns 1 if successful or -1 on error
126  */
libesedb_catalog_definition_free(libesedb_catalog_definition_t ** catalog_definition,libcerror_error_t ** error)127 int libesedb_catalog_definition_free(
128      libesedb_catalog_definition_t **catalog_definition,
129      libcerror_error_t **error )
130 {
131 	static char *function = "libesedb_catalog_definition_free";
132 
133 	if( catalog_definition == NULL )
134 	{
135 		libcerror_error_set(
136 		 error,
137 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
138 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
139 		 "%s: invalid catalog definition.",
140 		 function );
141 
142 		return( -1 );
143 	}
144 	if( *catalog_definition != NULL )
145 	{
146 		if( ( *catalog_definition )->name != NULL )
147 		{
148 			memory_free(
149 			 ( *catalog_definition )->name );
150 		}
151 #if defined( HAVE_DEBUG_OUTPUT )
152 		if( ( *catalog_definition )->name_string != NULL )
153 		{
154 			memory_free(
155 			 ( *catalog_definition )->name_string );
156 		}
157 #endif
158 		if( ( *catalog_definition )->template_name != NULL )
159 		{
160 			memory_free(
161 			 ( *catalog_definition )->template_name );
162 		}
163 		if( ( *catalog_definition )->default_value != NULL )
164 		{
165 			memory_free(
166 			 ( *catalog_definition )->default_value );
167 		}
168 		memory_free(
169 		 *catalog_definition );
170 
171 		*catalog_definition = NULL;
172 	}
173 	return( 1 );
174 }
175 
176 /* Reads the catalog definition
177  * Returns 1 if successful or -1 on error
178  */
libesedb_catalog_definition_read_data(libesedb_catalog_definition_t * catalog_definition,const uint8_t * data,size_t data_size,int ascii_codepage LIBESEDB_ATTRIBUTE_UNUSED,libcerror_error_t ** error)179 int libesedb_catalog_definition_read_data(
180      libesedb_catalog_definition_t *catalog_definition,
181      const uint8_t *data,
182      size_t data_size,
183      int ascii_codepage LIBESEDB_ATTRIBUTE_UNUSED,
184      libcerror_error_t **error )
185 {
186 	const uint8_t *fixed_size_data_type_value_data      = NULL;
187 	const uint8_t *variable_size_data_type_value_data   = NULL;
188 	static char *function                               = "libesedb_catalog_definition_read_data";
189 	size_t remaining_data_size                          = 0;
190 	size_t variable_size_data_type_value_data_offset    = 0;
191 	uint16_t calculated_variable_size_data_types_offset = 0;
192 	uint16_t data_type_number                           = 0;
193 	uint16_t data_type_size                             = 0;
194 	uint16_t previous_variable_size_data_type_size      = 0;
195 	uint16_t variable_size_data_type_size               = 0;
196 	uint16_t variable_size_data_types_offset            = 0;
197 	uint8_t last_fixed_size_data_type                   = 0;
198 	uint8_t last_variable_size_data_type                = 0;
199 	uint8_t number_of_variable_size_data_types          = 0;
200 	uint8_t variable_size_data_type_iterator            = 0;
201 
202 #if defined( HAVE_DEBUG_OUTPUT )
203 	system_character_t *value_string                    = 0;
204 	size_t value_string_size                            = 0;
205 	uint32_t value_32bit                                = 0;
206 	uint16_t record_offset                              = 0;
207 	uint16_t value_16bit                                = 0;
208 	int result                                          = 0;
209 #endif
210 
211 	LIBESEDB_UNREFERENCED_PARAMETER( ascii_codepage )
212 
213 	if( catalog_definition == NULL )
214 	{
215 		libcerror_error_set(
216 		 error,
217 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
218 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
219 		 "%s: invalid catalog definition.",
220 		 function );
221 
222 		return( -1 );
223 	}
224 	if( data == NULL )
225 	{
226 		libcerror_error_set(
227 		 error,
228 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
229 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
230 		 "%s: invalid data.",
231 		 function );
232 
233 		return( -1 );
234 	}
235 	if( data_size > (size_t) SSIZE_MAX )
236 	{
237 		libcerror_error_set(
238 		 error,
239 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
240 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
241 		 "%s: invalid data size value exceeds maximum.",
242 		 function );
243 
244 		return( -1 );
245 	}
246 	if( data_size < sizeof( esedb_data_definition_header_t ) )
247 	{
248 		libcerror_error_set(
249 		 error,
250 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
251 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
252 		 "%s: data too small.",
253 		 function );
254 
255 		return( -1 );
256 	}
257 #if defined( HAVE_DEBUG_OUTPUT )
258 	if( libcnotify_verbose != 0 )
259 	{
260 		libcnotify_printf(
261 		 "%s: data definition:\n",
262 		 function );
263 		libcnotify_print_data(
264 		 data,
265 		 data_size,
266 		 0 );
267 	}
268 #endif
269 	last_fixed_size_data_type    = ( (esedb_data_definition_header_t *) data )->last_fixed_size_data_type;
270 	last_variable_size_data_type = ( (esedb_data_definition_header_t *) data )->last_variable_size_data_type;
271 
272 	byte_stream_copy_to_uint16_little_endian(
273 	 ( (esedb_data_definition_header_t *) data )->variable_size_data_types_offset,
274 	 variable_size_data_types_offset );
275 
276 #if defined( HAVE_DEBUG_OUTPUT )
277 	if( libcnotify_verbose != 0 )
278 	{
279 		libcnotify_printf(
280 		 "%s: last fixed size data type\t\t\t: %" PRIu8 "\n",
281 		 function,
282 		 last_fixed_size_data_type );
283 
284 		libcnotify_printf(
285 		 "%s: last variable size data type\t\t\t: %" PRIu8 "\n",
286 		 function,
287 		 last_variable_size_data_type );
288 
289 		libcnotify_printf(
290 		 "%s: variable size data types offset\t\t\t: %" PRIu16 "\n",
291 		 function,
292 		 variable_size_data_types_offset );
293 	}
294 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
295 
296 	/* As far as the documentation states
297 	 * the column data FIELD structure is 16 bytes of size
298 	 */
299 	if( last_fixed_size_data_type < 5 )
300 	{
301 		libcerror_error_set(
302 		 error,
303 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
304 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
305 		 "%s: last fixed size data type too small.",
306 		 function );
307 
308 		return( -1 );
309 	}
310 	if( last_fixed_size_data_type > 12 )
311 	{
312 		libcerror_error_set(
313 		 error,
314 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
315 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
316 		 "%s: unsupported last fixed size data type: %" PRIu8 ".",
317 		 function,
318 		 last_fixed_size_data_type );
319 
320 		return( -1 );
321 	}
322 	if( last_variable_size_data_type > 127 )
323 	{
324 		number_of_variable_size_data_types = last_variable_size_data_type - 127;
325 	}
326 	calculated_variable_size_data_types_offset += sizeof( esedb_data_definition_header_t );
327 
328 	/* Use a fall through to determine the size of the fixed size data types
329 	 */
330 	switch( last_fixed_size_data_type )
331 	{
332 		case 12:
333 			calculated_variable_size_data_types_offset += 4;
334 
335 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
336 		case 11:
337 			calculated_variable_size_data_types_offset += 2;
338 
339 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
340 		case 10:
341 			calculated_variable_size_data_types_offset += 4;
342 
343 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
344 		case 9:
345 			calculated_variable_size_data_types_offset += 2;
346 
347 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
348 		case 8:
349 			if( last_variable_size_data_type > 127 )
350 			{
351 				calculated_variable_size_data_types_offset += 1 * number_of_variable_size_data_types;
352 			}
353 
354 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
355 		case 7:
356 			calculated_variable_size_data_types_offset += 4;
357 
358 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
359 		case 6:
360 			calculated_variable_size_data_types_offset += 4;
361 
362 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
363 		case 5:
364 			calculated_variable_size_data_types_offset += 4;
365 
366 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
367 		case 4:
368 			calculated_variable_size_data_types_offset += 4;
369 
370 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
371 		case 3:
372 			calculated_variable_size_data_types_offset += 4;
373 
374 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
375 		case 2:
376 			calculated_variable_size_data_types_offset += 2;
377 
378 		LIBESEDB_ATTRIBUTE_FALLTHROUGH;
379 		case 1:
380 			calculated_variable_size_data_types_offset += 4;
381 			break;
382 	}
383 	if( ( variable_size_data_types_offset < sizeof( esedb_data_definition_header_t ) )
384 	 || ( variable_size_data_types_offset > data_size ) )
385 	{
386 		libcerror_error_set(
387 		 error,
388 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
389 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
390 		 "%s: variable size data types offset value out of bounds.",
391 		 function );
392 
393 		return( -1 );
394 	}
395 	fixed_size_data_type_value_data = &( data[ sizeof( esedb_data_definition_header_t ) ] );
396 
397 	byte_stream_copy_to_uint32_little_endian(
398 	 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->father_data_page_object_identifier,
399 	 catalog_definition->father_data_page_object_identifier );
400 
401 	byte_stream_copy_to_uint16_little_endian(
402 	 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->type,
403 	 catalog_definition->type );
404 
405 	byte_stream_copy_to_uint32_little_endian(
406 	 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->identifier,
407 	 catalog_definition->identifier );
408 
409 	if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
410 	{
411 		byte_stream_copy_to_uint32_little_endian(
412 		 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->column_type,
413 		 catalog_definition->column_type );
414 	}
415 	else
416 	{
417 		byte_stream_copy_to_uint32_little_endian(
418 		 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->father_data_page_number,
419 		 catalog_definition->father_data_page_number );
420 	}
421 	byte_stream_copy_to_uint32_little_endian(
422 	 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->space_usage,
423 	 catalog_definition->size );
424 
425 	if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
426 	{
427 		byte_stream_copy_to_uint32_little_endian(
428 		 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->codepage,
429 		 catalog_definition->codepage );
430 	}
431 	if( last_fixed_size_data_type >= 10 )
432 	{
433 		byte_stream_copy_to_uint32_little_endian(
434 		 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->lc_map_flags,
435 		 catalog_definition->lcmap_flags );
436 	}
437 #if defined( HAVE_DEBUG_OUTPUT )
438 	if( libcnotify_verbose != 0 )
439 	{
440 		data_type_number = 1;
441 
442 		libcnotify_printf(
443 		 "%s: (%03" PRIu16 ") father data page (FDP) object identifier\t: %" PRIu32 "\n",
444 		 function,
445 		 data_type_number++,
446 		 catalog_definition->father_data_page_object_identifier );
447 
448 		libcnotify_printf(
449 		 "%s: (%03" PRIu16 ") type\t\t\t\t\t: 0x%04" PRIx16 " ",
450 		 function,
451 		 data_type_number++,
452 		 catalog_definition->type );
453 		libesedb_debug_print_page_value_definition_type(
454 		 catalog_definition->type );
455 		libcnotify_printf(
456 		 "\n" );
457 
458 		libcnotify_printf(
459 		 "%s: (%03" PRIu16 ") identifier\t\t\t\t\t: %" PRIu32 "\n",
460 		 function,
461 		 data_type_number++,
462 		 catalog_definition->identifier );
463 
464 		if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
465 		{
466 			libcnotify_printf(
467 			 "%s: (%03" PRIu16 ") column type\t\t\t\t: %" PRIu32 " (%s) %s\n",
468 			 function,
469 			 data_type_number++,
470 			 catalog_definition->column_type,
471 			 libesedb_column_type_get_identifier(
472 			  catalog_definition->column_type ),
473 			 libesedb_column_type_get_description(
474 			  catalog_definition->column_type ) );
475 		}
476 		else
477 		{
478 			libcnotify_printf(
479 			 "%s: (%03" PRIu16 ") father data page (FDP) number\t\t: %" PRIu32 "\n",
480 			 function,
481 			 data_type_number++,
482 			 catalog_definition->father_data_page_number );
483 		}
484 		libcnotify_printf(
485 		 "%s: (%03" PRIu16 ") space usage\t\t\t\t: %" PRIu32 "\n",
486 		 function,
487 		 data_type_number++,
488 		 catalog_definition->size );
489 
490 		byte_stream_copy_to_uint32_little_endian(
491 		 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->flags,
492 		 value_32bit );
493 
494 		if( last_fixed_size_data_type >= 6 )
495 		{
496 			if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
497 			{
498 				libcnotify_printf(
499 				 "%s: (%03" PRIu16 ") flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
500 				 function,
501 				 data_type_number++,
502 				 value_32bit );
503 				libesedb_debug_print_column_group_of_bits(
504 				 value_32bit );
505 				libcnotify_printf(
506 				 "\n" );
507 			}
508 			else if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX )
509 			{
510 				libcnotify_printf(
511 				 "%s: (%03" PRIu16 ") flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
512 				 function,
513 				 data_type_number++,
514 				 value_32bit );
515 				libesedb_debug_print_index_group_of_bits(
516 				 value_32bit );
517 				libcnotify_printf(
518 				 "\n" );
519 			}
520 			else
521 			{
522 				libcnotify_printf(
523 				 "%s: (%03" PRIu16 ") flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
524 				 function,
525 				 data_type_number++,
526 				 value_32bit );
527 			}
528 		}
529 		if( last_fixed_size_data_type >= 7 )
530 		{
531 			if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN )
532 			{
533 				libcnotify_printf(
534 				 "%s: (%03" PRIu16 ") codepage\t\t\t\t\t: %" PRIu32 "",
535 				 function,
536 				 data_type_number++,
537 				 catalog_definition->codepage );
538 
539 				if( catalog_definition->codepage != 0 )
540 				{
541 					libcnotify_printf(
542 					 " (%s) %s",
543 					 libesedb_codepage_get_identifier(
544 					  catalog_definition->codepage ),
545 					 libesedb_codepage_get_description(
546 					  catalog_definition->codepage ) );
547 				}
548 				libcnotify_printf(
549 				 "\n" );
550 			}
551 			else if( catalog_definition->type == LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX )
552 			{
553 				byte_stream_copy_to_uint32_little_endian(
554 				 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->locale_identifier,
555 				 value_32bit );
556 
557 				libcnotify_printf(
558 				 "%s: (%03" PRIu16 ") locale identifier\t\t\t\t: 0x%08" PRIx32 " (%s)\n",
559 				 function,
560 				 data_type_number++,
561 				 value_32bit,
562 				 libesedb_lcid_language_tag_get_identifier(
563 				  (uint16_t) value_32bit ),
564 				 libesedb_lcid_language_tag_get_description(
565 				  (uint16_t) value_32bit ) );
566 			}
567 			else
568 			{
569 				byte_stream_copy_to_uint32_little_endian(
570 				 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->number_of_pages,
571 				 value_32bit );
572 
573 				libcnotify_printf(
574 				 "%s: (%03" PRIu16 ") number of pages\t\t\t\t: %" PRIu32 "\n",
575 				 function,
576 				 data_type_number++,
577 				 value_32bit );
578 			}
579 		}
580 		if( last_fixed_size_data_type >= 8 )
581 		{
582 			libcnotify_printf(
583 			 "%s: (%03" PRIu16 ") root flag\t\t\t\t\t: 0x%02" PRIx8 "\n",
584 			 function,
585 			 data_type_number++,
586 			 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->root_flag );
587 		}
588 		if( last_fixed_size_data_type >= 9 )
589 		{
590 			byte_stream_copy_to_uint16_little_endian(
591 			 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->record_offset,
592 			 record_offset );
593 
594 			libcnotify_printf(
595 			 "%s: (%03" PRIu16 ") record offset\t\t\t\t: %" PRIu16 "\n",
596 			 function,
597 			 data_type_number++,
598 			 record_offset );
599 		}
600 		if( last_fixed_size_data_type >= 10 )
601 		{
602 			libcnotify_printf(
603 			 "%s: (%03" PRIu16 ") locale map (LCMAP) flags\t\t\t: 0x%08" PRIx32 "\n",
604 			 function,
605 			 data_type_number++,
606 			 catalog_definition->lcmap_flags );
607 			libesedb_debug_print_lcmap_flags(
608 			 catalog_definition->lcmap_flags );
609 		}
610 		if( last_fixed_size_data_type >= 11 )
611 		{
612 			byte_stream_copy_to_uint16_little_endian(
613 			 ( (esedb_data_definition_t *) fixed_size_data_type_value_data )->key_most,
614 			 value_16bit );
615 
616 			libcnotify_printf(
617 			 "%s: (%03" PRIu16 ") key most\t\t\t\t: 0x04%" PRIx16 "\n",
618 			 function,
619 			 data_type_number++,
620 			 value_16bit );
621 		}
622 		libcnotify_printf(
623 		 "\n" );
624 	}
625 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
626 
627 #if defined( HAVE_DEBUG_OUTPUT )
628 	if( libcnotify_verbose != 0 )
629 	{
630 		if( variable_size_data_types_offset > calculated_variable_size_data_types_offset )
631 		{
632 			libcnotify_printf(
633 			 "%s: fixed size data types trailing data:\n",
634 			 function );
635 			libcnotify_print_data(
636 			 &( data[ calculated_variable_size_data_types_offset ] ),
637 			 variable_size_data_types_offset - calculated_variable_size_data_types_offset,
638 			 0 );
639 		}
640 	}
641 #endif
642 	if( number_of_variable_size_data_types > 0 )
643 	{
644 		variable_size_data_type_value_data_offset = variable_size_data_types_offset + ( number_of_variable_size_data_types * 2 );
645 
646 		if( variable_size_data_type_value_data_offset > data_size )
647 		{
648 			libcerror_error_set(
649 			 error,
650 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
651 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
652 			 "%s: variable size data type value data offset exceeds data.",
653 			 function );
654 
655 			return( -1 );
656 		}
657 		variable_size_data_type_value_data = &( data[ variable_size_data_type_value_data_offset ] );
658 		remaining_data_size                = data_size - variable_size_data_type_value_data_offset;
659 
660 		data_type_number = 128;
661 
662 		for( variable_size_data_type_iterator = 0;
663 		     variable_size_data_type_iterator < number_of_variable_size_data_types;
664 		     variable_size_data_type_iterator++ )
665 		{
666 			if( variable_size_data_types_offset > ( data_size - 2 ) )
667 			{
668 				libcerror_error_set(
669 				 error,
670 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
671 				 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
672 				 "%s: variable size data types offset value out of bounds.",
673 				 function );
674 
675 				return( -1 );
676 			}
677 			byte_stream_copy_to_uint16_little_endian(
678 			 &( data[ variable_size_data_types_offset ] ),
679 			 variable_size_data_type_size );
680 
681 			variable_size_data_types_offset += 2;
682 
683 #if defined( HAVE_DEBUG_OUTPUT )
684 			if( libcnotify_verbose != 0 )
685 			{
686 				libcnotify_printf(
687 				 "%s: (%03" PRIu16 ") variable size data type size\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n",
688 				 function,
689 				 data_type_number,
690 				 variable_size_data_type_size,
691 				 ( ( variable_size_data_type_size & 0x8000 ) != 0 ) ? 0 : ( variable_size_data_type_size & 0x7fff ) - previous_variable_size_data_type_size );
692 			}
693 #endif
694 			/* The MSB signifies that the variable size data type is empty
695 			 */
696 			if( ( variable_size_data_type_size & 0x8000 ) != 0 )
697 			{
698 				data_type_size = 0;
699 			}
700 			else
701 			{
702 				data_type_size = variable_size_data_type_size - previous_variable_size_data_type_size;
703 
704 				if( ( previous_variable_size_data_type_size > remaining_data_size )
705 				 || ( data_type_size > ( remaining_data_size - previous_variable_size_data_type_size ) ) )
706 				{
707 					libcerror_error_set(
708 					 error,
709 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
710 					 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
711 					 "%s: invalid data type size value out of bounds.",
712 					 function );
713 
714 					return( -1 );
715 				}
716 			}
717 			switch( data_type_number )
718 			{
719 				case 128:
720 					if( data_type_size > 0 )
721 					{
722 						catalog_definition->name = (uint8_t *) memory_allocate(
723 										        sizeof( uint8_t ) * data_type_size );
724 
725 						if( catalog_definition->name == NULL )
726 						{
727 							libcerror_error_set(
728 							 error,
729 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
730 							 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
731 							 "%s: unable to create name.",
732 							 function );
733 
734 							return( -1 );
735 						}
736 						catalog_definition->name_size = (size_t) data_type_size;
737 
738 						if( memory_copy(
739 						     catalog_definition->name,
740 						     &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
741 						     catalog_definition->name_size ) == NULL )
742 						{
743 							libcerror_error_set(
744 							 error,
745 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
746 							 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
747 							 "%s: unable to set name.",
748 							 function );
749 
750 							memory_free(
751 							 catalog_definition->name );
752 
753 							catalog_definition->name      = NULL;
754 							catalog_definition->name_size = 0;
755 
756 							return( -1 );
757 						}
758 #if defined( HAVE_DEBUG_OUTPUT )
759 						if( libcnotify_verbose != 0 )
760 						{
761 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
762 							result = libuna_utf16_string_size_from_byte_stream(
763 							          catalog_definition->name,
764 							          catalog_definition->name_size,
765 							          ascii_codepage,
766 							          &value_string_size,
767 							          error );
768 #else
769 							result = libuna_utf8_string_size_from_byte_stream(
770 							          catalog_definition->name,
771 							          catalog_definition->name_size,
772 							          ascii_codepage,
773 							          &value_string_size,
774 							          error );
775 #endif
776 
777 							if( result != 1 )
778 							{
779 								libcerror_error_set(
780 								 error,
781 								 LIBCERROR_ERROR_DOMAIN_RUNTIME,
782 								 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
783 								 "%s: unable to determine size of name string.",
784 								 function );
785 
786 								return( -1 );
787 							}
788 							catalog_definition->name_string = system_string_allocate(
789 							                                   value_string_size );
790 
791 							if( catalog_definition->name_string == NULL )
792 							{
793 								libcerror_error_set(
794 								 error,
795 								 LIBCERROR_ERROR_DOMAIN_MEMORY,
796 								 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
797 								 "%s: unable to create name string.",
798 								 function );
799 
800 								return( -1 );
801 							}
802 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
803 							result = libuna_utf16_string_copy_from_byte_stream(
804 							          (libuna_utf16_character_t *) catalog_definition->name_string,
805 							          value_string_size,
806 							          catalog_definition->name,
807 							          catalog_definition->name_size,
808 							          ascii_codepage,
809 							          error );
810 #else
811 							result = libuna_utf8_string_copy_from_byte_stream(
812 							          (libuna_utf8_character_t *) catalog_definition->name_string,
813 							          value_string_size,
814 							          catalog_definition->name,
815 							          catalog_definition->name_size,
816 							          ascii_codepage,
817 							          error );
818 #endif
819 
820 							if( result != 1 )
821 							{
822 								libcerror_error_set(
823 								 error,
824 								 LIBCERROR_ERROR_DOMAIN_CONVERSION,
825 								 LIBCERROR_CONVERSION_ERROR_GENERIC,
826 								 "%s: unable to set name string.",
827 								 function );
828 
829 								memory_free(
830 								 catalog_definition->name_string );
831 
832 								catalog_definition->name_string = NULL;
833 
834 								return( -1 );
835 							}
836 							libcnotify_printf(
837 							 "%s: (%03" PRIu8 ") name\t\t\t\t\t: %" PRIs_SYSTEM "\n",
838 							 function,
839 							 data_type_number,
840 							 catalog_definition->name_string );
841 						}
842 #endif
843 					}
844 #if defined( HAVE_DEBUG_OUTPUT )
845 					else if( libcnotify_verbose != 0 )
846 					{
847 						libcnotify_printf(
848 						 "%s: (%03" PRIu8 ") name\t\t\t\t\t: <NULL>\n",
849 						 function,
850 						 data_type_number );
851 					}
852 #endif
853 					break;
854 
855 #if defined( HAVE_DEBUG_OUTPUT )
856 				case 129:
857 					if( libcnotify_verbose != 0 )
858 					{
859 						if( data_type_size > 0 )
860 						{
861 							libcnotify_printf(
862 							 "%s: (%03" PRIu8 ") stats:\n",
863 							 function,
864 							 data_type_number );
865 							libcnotify_print_data(
866 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
867 							 data_type_size,
868 							 0 );
869 						}
870 						else
871 						{
872 							libcnotify_printf(
873 							 "%s: (%03" PRIu8 ") stats\t\t\t\t\t: <NULL>\n",
874 							 function,
875 							 data_type_number );
876 						}
877 					}
878 					break;
879 #endif
880 
881 				case 130:
882 					if( data_type_size > 0 )
883 					{
884 						catalog_definition->template_name = (uint8_t *) memory_allocate(
885 						                                                 sizeof( uint8_t ) * data_type_size );
886 
887 						if( catalog_definition->template_name == NULL )
888 						{
889 							libcerror_error_set(
890 							 error,
891 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
892 							 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
893 							 "%s: unable to create template name.",
894 							 function );
895 
896 							return( -1 );
897 						}
898 						catalog_definition->template_name_size = (size_t) data_type_size;
899 
900 						if( memory_copy(
901 						     catalog_definition->template_name,
902 						     &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
903 						     catalog_definition->template_name_size ) == NULL )
904 						{
905 							libcerror_error_set(
906 							 error,
907 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
908 							 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
909 							 "%s: unable to set template name.",
910 							 function );
911 
912 							memory_free(
913 							 catalog_definition->template_name );
914 
915 							catalog_definition->template_name      = NULL;
916 							catalog_definition->template_name_size = 0;
917 
918 							return( -1 );
919 						}
920 #if defined( HAVE_DEBUG_OUTPUT )
921 						if( libcnotify_verbose != 0 )
922 						{
923 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
924 							result = libuna_utf16_string_size_from_byte_stream(
925 							          catalog_definition->template_name,
926 							          catalog_definition->template_name_size,
927 							          ascii_codepage,
928 							          &value_string_size,
929 							          error );
930 #else
931 							result = libuna_utf8_string_size_from_byte_stream(
932 							          catalog_definition->template_name,
933 							          catalog_definition->template_name_size,
934 							          ascii_codepage,
935 							          &value_string_size,
936 							          error );
937 #endif
938 
939 							if( result != 1 )
940 							{
941 								libcerror_error_set(
942 								 error,
943 								 LIBCERROR_ERROR_DOMAIN_RUNTIME,
944 								 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
945 								 "%s: unable to determine size of template name string.",
946 								 function );
947 
948 								return( -1 );
949 							}
950 							value_string = system_string_allocate(
951 							                value_string_size );
952 
953 							if( value_string == NULL )
954 							{
955 								libcerror_error_set(
956 								 error,
957 								 LIBCERROR_ERROR_DOMAIN_MEMORY,
958 								 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
959 								 "%s: unable to create template name string.",
960 								 function );
961 
962 								return( -1 );
963 							}
964 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
965 							result = libuna_utf16_string_copy_from_byte_stream(
966 							          (libuna_utf16_character_t *) value_string,
967 							          value_string_size,
968 							          catalog_definition->template_name,
969 							          catalog_definition->template_name_size,
970 							          ascii_codepage,
971 							          error );
972 #else
973 							result = libuna_utf8_string_copy_from_byte_stream(
974 							          (libuna_utf8_character_t *) value_string,
975 							          value_string_size,
976 							          catalog_definition->template_name,
977 							          catalog_definition->template_name_size,
978 							          ascii_codepage,
979 							          error );
980 #endif
981 
982 							if( result != 1 )
983 							{
984 								libcerror_error_set(
985 								 error,
986 								 LIBCERROR_ERROR_DOMAIN_CONVERSION,
987 								 LIBCERROR_CONVERSION_ERROR_GENERIC,
988 								 "%s: unable to set template name string.",
989 								 function );
990 
991 								memory_free(
992 								 value_string );
993 
994 								return( -1 );
995 							}
996 							libcnotify_printf(
997 							 "%s: (%03" PRIu8 ") template name\t\t\t\t: %" PRIs_SYSTEM "\n",
998 							 function,
999 							 data_type_number,
1000 							 value_string );
1001 
1002 							memory_free(
1003 							 value_string );
1004 						}
1005 #endif
1006 					}
1007 #if defined( HAVE_DEBUG_OUTPUT )
1008 					else if( libcnotify_verbose != 0 )
1009 					{
1010 						libcnotify_printf(
1011 						 "%s: (%03" PRIu8 ") template name\t\t\t\t: <NULL>\n",
1012 						 function,
1013 						 data_type_number );
1014 					}
1015 #endif
1016 					break;
1017 
1018 				case 131:
1019 					if( data_type_size > 0 )
1020 					{
1021 						catalog_definition->default_value = (uint8_t *) memory_allocate(
1022 												 sizeof( uint8_t ) * data_type_size );
1023 
1024 						if( catalog_definition->default_value == NULL )
1025 						{
1026 							libcerror_error_set(
1027 							 error,
1028 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
1029 							 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1030 							 "%s: unable to create default value.",
1031 							 function );
1032 
1033 							return( -1 );
1034 						}
1035 						catalog_definition->default_value_size = (size_t) data_type_size;
1036 
1037 						if( memory_copy(
1038 						     catalog_definition->default_value,
1039 						     &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1040 						     catalog_definition->default_value_size ) == NULL )
1041 						{
1042 							libcerror_error_set(
1043 							 error,
1044 							 LIBCERROR_ERROR_DOMAIN_MEMORY,
1045 							 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1046 							 "%s: unable to set default value.",
1047 							 function );
1048 
1049 							memory_free(
1050 							 catalog_definition->default_value );
1051 
1052 							catalog_definition->default_value      = NULL;
1053 							catalog_definition->default_value_size = 0;
1054 
1055 							return( -1 );
1056 						}
1057 #if defined( HAVE_DEBUG_OUTPUT )
1058 						if( libcnotify_verbose != 0 )
1059 						{
1060 							libcnotify_printf(
1061 							 "%s: (%03" PRIu8 ") default value:\n",
1062 							 function,
1063 							 data_type_number );
1064 							libcnotify_print_data(
1065 							 catalog_definition->default_value,
1066 							 catalog_definition->default_value_size,
1067 							 0 );
1068 						}
1069 #endif
1070 					}
1071 #if defined( HAVE_DEBUG_OUTPUT )
1072 					else if( libcnotify_verbose != 0 )
1073 					{
1074 						libcnotify_printf(
1075 						 "%s: (%03" PRIu8 ") default value\t\t\t\t: <NULL>\n",
1076 						 function,
1077 						 data_type_number );
1078 					}
1079 #endif
1080 					break;
1081 
1082 #if defined( HAVE_DEBUG_OUTPUT )
1083 				case 132:
1084 					if( libcnotify_verbose != 0 )
1085 					{
1086 						if( data_type_size > 0 )
1087 						{
1088 							libcnotify_printf(
1089 							 "%s: (%03" PRIu8 ") KeyFldIDs:\n",
1090 							 function,
1091 							 data_type_number );
1092 							libcnotify_print_data(
1093 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1094 							 data_type_size,
1095 							 0 );
1096 						}
1097 						else
1098 						{
1099 							libcnotify_printf(
1100 							 "%s: (%03" PRIu8 ") KeyFldIDs\t\t\t\t: <NULL>\n",
1101 							 function,
1102 							 data_type_number );
1103 						}
1104 					}
1105 					break;
1106 
1107 				case 133:
1108 					if( libcnotify_verbose != 0 )
1109 					{
1110 						if( data_type_size > 0 )
1111 						{
1112 							libcnotify_printf(
1113 							 "%s: (%03" PRIu8 ") VarSegMac:\n",
1114 							 function,
1115 							 data_type_number );
1116 							libcnotify_print_data(
1117 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1118 							 data_type_size,
1119 							 0 );
1120 						}
1121 						else
1122 						{
1123 							libcnotify_printf(
1124 							 "%s: (%03" PRIu8 ") VarSegMac\t\t\t\t\t: <NULL>\n",
1125 							 function,
1126 							 data_type_number );
1127 						}
1128 					}
1129 					break;
1130 
1131 				case 134:
1132 					if( libcnotify_verbose != 0 )
1133 					{
1134 						if( data_type_size > 0 )
1135 						{
1136 							libcnotify_printf(
1137 							 "%s: (%03" PRIu8 ") ConditionalColumns:\n",
1138 							 function,
1139 							 data_type_number );
1140 							libcnotify_print_data(
1141 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1142 							 data_type_size,
1143 							 0 );
1144 						}
1145 						else
1146 						{
1147 							libcnotify_printf(
1148 							 "%s: (%03" PRIu8 ") ConditionalColumns\t\t\t\t: <NULL>\n",
1149 							 function,
1150 							 data_type_number );
1151 						}
1152 					}
1153 					break;
1154 
1155 				case 135:
1156 					if( libcnotify_verbose != 0 )
1157 					{
1158 						if( data_type_size > 0 )
1159 						{
1160 							libcnotify_printf(
1161 							 "%s: (%03" PRIu8 ") TupleLimits:\n",
1162 							 function,
1163 							 data_type_number );
1164 							libcnotify_print_data(
1165 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1166 							 data_type_size,
1167 							 0 );
1168 						}
1169 						else
1170 						{
1171 							libcnotify_printf(
1172 							 "%s: (%03" PRIu8 ") TupleLimits\t\t\t\t: <NULL>\n",
1173 							 function,
1174 							 data_type_number );
1175 						}
1176 					}
1177 					break;
1178 
1179 				case 136:
1180 					if( libcnotify_verbose != 0 )
1181 					{
1182 						if( data_type_size > 0 )
1183 						{
1184 							libcnotify_printf(
1185 							 "%s: (%03" PRIu8 ") Version:\n",
1186 							 function,
1187 							 data_type_number );
1188 							libcnotify_print_data(
1189 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1190 							 data_type_size,
1191 							 0 );
1192 						}
1193 						else
1194 						{
1195 							libcnotify_printf(
1196 							 "%s: (%03" PRIu8 ") Version\t\t\t\t: <NULL>\n",
1197 							 function,
1198 							 data_type_number );
1199 						}
1200 					}
1201 					break;
1202 #endif
1203 
1204 				default:
1205 #if defined( HAVE_DEBUG_OUTPUT )
1206 					if( libcnotify_verbose != 0 )
1207 					{
1208 						if( data_type_size > 0 )
1209 						{
1210 							libcnotify_printf(
1211 							 "%s: (%03" PRIu16 ") variable size data type:\n",
1212 							 function,
1213 							 data_type_number );
1214 							libcnotify_print_data(
1215 							 &( variable_size_data_type_value_data[ previous_variable_size_data_type_size ] ),
1216 							 data_type_size,
1217 							 0 );
1218 						}
1219 						else
1220 						{
1221 							libcnotify_printf(
1222 							 "%s: (%03" PRIu16 ") variable size data type\t\t: <NULL>\n",
1223 							 function,
1224 							 data_type_number );
1225 						}
1226 					}
1227 #endif
1228 					break;
1229 			}
1230 			if( data_type_size > 0 )
1231 			{
1232 				previous_variable_size_data_type_size = variable_size_data_type_size;
1233 			}
1234 			data_type_number++;
1235 		}
1236 	}
1237 #if defined( HAVE_DEBUG_OUTPUT )
1238 	if( libcnotify_verbose != 0 )
1239 	{
1240 		libcnotify_printf(
1241 		 "\n" );
1242 	}
1243 #endif
1244 	return( 1 );
1245 }
1246 
1247 /* Retrieves the catalog definition identifier
1248  * Returns 1 if successful or -1 on error
1249  */
libesedb_catalog_definition_get_identifier(libesedb_catalog_definition_t * catalog_definition,uint32_t * identifier,libcerror_error_t ** error)1250 int libesedb_catalog_definition_get_identifier(
1251      libesedb_catalog_definition_t *catalog_definition,
1252      uint32_t *identifier,
1253      libcerror_error_t **error )
1254 {
1255 	static char *function = "libesedb_catalog_definition_get_identifier";
1256 
1257 	if( catalog_definition == NULL )
1258 	{
1259 		libcerror_error_set(
1260 		 error,
1261 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1262 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1263 		 "%s: invalid catalog definition.",
1264 		 function );
1265 
1266 		return( -1 );
1267 	}
1268 	if( identifier == NULL )
1269 	{
1270 		libcerror_error_set(
1271 		 error,
1272 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1273 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1274 		 "%s: invalid identifier.",
1275 		 function );
1276 
1277 		return( -1 );
1278 	}
1279 	*identifier = catalog_definition->identifier;
1280 
1281 	return( 1 );
1282 }
1283 
1284 /* Retrieves the catalog definition column type
1285  * Returns 1 if successful or -1 on error
1286  */
libesedb_catalog_definition_get_column_type(libesedb_catalog_definition_t * catalog_definition,uint32_t * column_type,libcerror_error_t ** error)1287 int libesedb_catalog_definition_get_column_type(
1288      libesedb_catalog_definition_t *catalog_definition,
1289      uint32_t *column_type,
1290      libcerror_error_t **error )
1291 {
1292 	static char *function = "libesedb_catalog_definition_get_column_type";
1293 
1294 	if( catalog_definition == NULL )
1295 	{
1296 		libcerror_error_set(
1297 		 error,
1298 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1299 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1300 		 "%s: invalid catalog definition.",
1301 		 function );
1302 
1303 		return( -1 );
1304 	}
1305 	if( column_type == NULL )
1306 	{
1307 		libcerror_error_set(
1308 		 error,
1309 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1310 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1311 		 "%s: invalid column type.",
1312 		 function );
1313 
1314 		return( -1 );
1315 	}
1316 	*column_type = catalog_definition->column_type;
1317 
1318 	return( 1 );
1319 }
1320 
1321 /* Retrieves the size of the UTF-8 encoded string string of the catalog definition name
1322  * The returned size includes the end of string character
1323  * Returns 1 if successful or -1 on error
1324  */
libesedb_catalog_definition_get_utf8_name_size(libesedb_catalog_definition_t * catalog_definition,size_t * utf8_string_size,int ascii_codepage,libcerror_error_t ** error)1325 int libesedb_catalog_definition_get_utf8_name_size(
1326      libesedb_catalog_definition_t *catalog_definition,
1327      size_t *utf8_string_size,
1328      int ascii_codepage,
1329      libcerror_error_t **error )
1330 {
1331 	static char *function = "libesedb_catalog_definition_get_utf8_name_size";
1332 
1333 	if( catalog_definition == NULL )
1334 	{
1335 		libcerror_error_set(
1336 		 error,
1337 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1338 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1339 		 "%s: invalid catalog definition.",
1340 		 function );
1341 
1342 		return( -1 );
1343 	}
1344 	if( libuna_utf8_string_size_from_byte_stream(
1345 	     catalog_definition->name,
1346 	     catalog_definition->name_size,
1347 	     ascii_codepage,
1348 	     utf8_string_size,
1349 	     error ) != 1 )
1350 	{
1351 		libcerror_error_set(
1352 		 error,
1353 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1354 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1355 		 "%s: unable to retrieve UTF-8 string size.",
1356 		 function );
1357 
1358 		return( -1 );
1359 	}
1360 	return( 1 );
1361 }
1362 
1363 /* Retrieves the UTF-8 encoded string of the catalog definition name
1364  * The size should include the end of string character
1365  * Returns 1 if successful or -1 on error
1366  */
libesedb_catalog_definition_get_utf8_name(libesedb_catalog_definition_t * catalog_definition,uint8_t * utf8_string,size_t utf8_string_size,int ascii_codepage,libcerror_error_t ** error)1367 int libesedb_catalog_definition_get_utf8_name(
1368      libesedb_catalog_definition_t *catalog_definition,
1369      uint8_t *utf8_string,
1370      size_t utf8_string_size,
1371      int ascii_codepage,
1372      libcerror_error_t **error )
1373 {
1374 	static char *function = "libesedb_catalog_definition_get_utf8_name";
1375 
1376 	if( catalog_definition == NULL )
1377 	{
1378 		libcerror_error_set(
1379 		 error,
1380 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1381 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1382 		 "%s: invalid catalog definition.",
1383 		 function );
1384 
1385 		return( -1 );
1386 	}
1387 	if( libuna_utf8_string_copy_from_byte_stream(
1388 	     utf8_string,
1389 	     utf8_string_size,
1390 	     catalog_definition->name,
1391 	     catalog_definition->name_size,
1392 	     ascii_codepage,
1393 	     error ) != 1 )
1394 	{
1395 		libcerror_error_set(
1396 		 error,
1397 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1398 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1399 		 "%s: unable to set UTF-8 string.",
1400 		 function );
1401 
1402 		return( -1 );
1403 	}
1404 	return( 1 );
1405 }
1406 
1407 /* Retrieves the size of the UTF-16 encoded string of the catalog definition name
1408  * The returned size includes the end of string character
1409  * Returns 1 if successful or -1 on error
1410  */
libesedb_catalog_definition_get_utf16_name_size(libesedb_catalog_definition_t * catalog_definition,size_t * utf16_string_size,int ascii_codepage,libcerror_error_t ** error)1411 int libesedb_catalog_definition_get_utf16_name_size(
1412      libesedb_catalog_definition_t *catalog_definition,
1413      size_t *utf16_string_size,
1414      int ascii_codepage,
1415      libcerror_error_t **error )
1416 {
1417 	static char *function = "libesedb_catalog_definition_get_utf16_name_size";
1418 
1419 	if( catalog_definition == NULL )
1420 	{
1421 		libcerror_error_set(
1422 		 error,
1423 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1424 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1425 		 "%s: invalid catalog definition.",
1426 		 function );
1427 
1428 		return( -1 );
1429 	}
1430 	if( libuna_utf16_string_size_from_byte_stream(
1431 	     catalog_definition->name,
1432 	     catalog_definition->name_size,
1433 	     ascii_codepage,
1434 	     utf16_string_size,
1435 	     error ) != 1 )
1436 	{
1437 		libcerror_error_set(
1438 		 error,
1439 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1440 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1441 		 "%s: unable to retrieve UTF-16 string size.",
1442 		 function );
1443 
1444 		return( -1 );
1445 	}
1446 	return( 1 );
1447 }
1448 
1449 /* Retrieves the UTF-16 encoded string of the catalog definition name
1450  * The size should include the end of string character
1451  * Returns 1 if successful or -1 on error
1452  */
libesedb_catalog_definition_get_utf16_name(libesedb_catalog_definition_t * catalog_definition,uint16_t * utf16_string,size_t utf16_string_size,int ascii_codepage,libcerror_error_t ** error)1453 int libesedb_catalog_definition_get_utf16_name(
1454      libesedb_catalog_definition_t *catalog_definition,
1455      uint16_t *utf16_string,
1456      size_t utf16_string_size,
1457      int ascii_codepage,
1458      libcerror_error_t **error )
1459 {
1460 	static char *function = "libesedb_catalog_definition_get_utf16_name";
1461 
1462 	if( catalog_definition == NULL )
1463 	{
1464 		libcerror_error_set(
1465 		 error,
1466 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1467 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1468 		 "%s: invalid catalog definition.",
1469 		 function );
1470 
1471 		return( -1 );
1472 	}
1473 	if( libuna_utf16_string_copy_from_byte_stream(
1474 	     utf16_string,
1475 	     utf16_string_size,
1476 	     catalog_definition->name,
1477 	     catalog_definition->name_size,
1478 	     ascii_codepage,
1479 	     error ) != 1 )
1480 	{
1481 		libcerror_error_set(
1482 		 error,
1483 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1484 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1485 		 "%s: unable to set UTF-16 string.",
1486 		 function );
1487 
1488 		return( -1 );
1489 	}
1490 	return( 1 );
1491 }
1492 
1493 /* Retrieves the size of the UTF-8 encoded string string of the catalog definition template name
1494  * The returned size includes the end of string character
1495  * Returns 1 if successful or -1 on error
1496  */
libesedb_catalog_definition_get_utf8_template_name_size(libesedb_catalog_definition_t * catalog_definition,size_t * utf8_string_size,int ascii_codepage,libcerror_error_t ** error)1497 int libesedb_catalog_definition_get_utf8_template_name_size(
1498      libesedb_catalog_definition_t *catalog_definition,
1499      size_t *utf8_string_size,
1500      int ascii_codepage,
1501      libcerror_error_t **error )
1502 {
1503 	static char *function = "libesedb_catalog_definition_get_utf8_template_name_size";
1504 
1505 	if( catalog_definition == NULL )
1506 	{
1507 		libcerror_error_set(
1508 		 error,
1509 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1510 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1511 		 "%s: invalid catalog definition.",
1512 		 function );
1513 
1514 		return( -1 );
1515 	}
1516 	if( catalog_definition->template_name == NULL )
1517 	{
1518 		if( utf8_string_size == NULL )
1519 		{
1520 			libcerror_error_set(
1521 			 error,
1522 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1523 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1524 			 "%s: invalid UTF-8 string size.",
1525 			 function );
1526 
1527 			return( -1 );
1528 		}
1529 		*utf8_string_size = 0;
1530 	}
1531 	else
1532 	{
1533 		if( libuna_utf8_string_size_from_byte_stream(
1534 		     catalog_definition->template_name,
1535 		     catalog_definition->template_name_size,
1536 		     ascii_codepage,
1537 		     utf8_string_size,
1538 		     error ) != 1 )
1539 		{
1540 			libcerror_error_set(
1541 			 error,
1542 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1543 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1544 			 "%s: unable to retrieve UTF-8 string size.",
1545 			 function );
1546 
1547 			return( -1 );
1548 		}
1549 	}
1550 	return( 1 );
1551 }
1552 
1553 /* Retrieves the UTF-8 encoded string of the catalog definition template name
1554  * The size should include the end of string character
1555  * Returns 1 if successful or -1 on error
1556  */
libesedb_catalog_definition_get_utf8_template_name(libesedb_catalog_definition_t * catalog_definition,uint8_t * utf8_string,size_t utf8_string_size,int ascii_codepage,libcerror_error_t ** error)1557 int libesedb_catalog_definition_get_utf8_template_name(
1558      libesedb_catalog_definition_t *catalog_definition,
1559      uint8_t *utf8_string,
1560      size_t utf8_string_size,
1561      int ascii_codepage,
1562      libcerror_error_t **error )
1563 {
1564 	static char *function = "libesedb_catalog_definition_get_utf8_template_name";
1565 
1566 	if( catalog_definition == NULL )
1567 	{
1568 		libcerror_error_set(
1569 		 error,
1570 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1571 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1572 		 "%s: invalid catalog definition.",
1573 		 function );
1574 
1575 		return( -1 );
1576 	}
1577 	if( catalog_definition->template_name != NULL )
1578 	{
1579 		if( libuna_utf8_string_copy_from_byte_stream(
1580 		     utf8_string,
1581 		     utf8_string_size,
1582 		     catalog_definition->template_name,
1583 		     catalog_definition->template_name_size,
1584 		     ascii_codepage,
1585 		     error ) != 1 )
1586 		{
1587 			libcerror_error_set(
1588 			 error,
1589 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1590 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1591 			 "%s: unable to set UTF-8 string.",
1592 			 function );
1593 
1594 			return( -1 );
1595 		}
1596 	}
1597 	return( 1 );
1598 }
1599 
1600 /* Retrieves the size of the UTF-16 encoded string of the catalog definition template name
1601  * The returned size includes the end of string character
1602  * Returns 1 if successful or -1 on error
1603  */
libesedb_catalog_definition_get_utf16_template_name_size(libesedb_catalog_definition_t * catalog_definition,size_t * utf16_string_size,int ascii_codepage,libcerror_error_t ** error)1604 int libesedb_catalog_definition_get_utf16_template_name_size(
1605      libesedb_catalog_definition_t *catalog_definition,
1606      size_t *utf16_string_size,
1607      int ascii_codepage,
1608      libcerror_error_t **error )
1609 {
1610 	static char *function = "libesedb_catalog_definition_get_utf16_template_name_size";
1611 
1612 	if( catalog_definition == NULL )
1613 	{
1614 		libcerror_error_set(
1615 		 error,
1616 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1617 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1618 		 "%s: invalid catalog definition.",
1619 		 function );
1620 
1621 		return( -1 );
1622 	}
1623 	if( catalog_definition->template_name == NULL )
1624 	{
1625 		if( utf16_string_size == NULL )
1626 		{
1627 			libcerror_error_set(
1628 			 error,
1629 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1630 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1631 			 "%s: invalid UTF-16 string size.",
1632 			 function );
1633 
1634 			return( -1 );
1635 		}
1636 		*utf16_string_size = 0;
1637 	}
1638 	else
1639 	{
1640 		if( libuna_utf16_string_size_from_byte_stream(
1641 		     catalog_definition->template_name,
1642 		     catalog_definition->template_name_size,
1643 		     ascii_codepage,
1644 		     utf16_string_size,
1645 		     error ) != 1 )
1646 		{
1647 			libcerror_error_set(
1648 			 error,
1649 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1650 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1651 			 "%s: unable to retrieve UTF-16 string size.",
1652 			 function );
1653 
1654 			return( -1 );
1655 		}
1656 	}
1657 	return( 1 );
1658 }
1659 
1660 /* Retrieves the UTF-16 encoded string of the catalog definition template name
1661  * The size should include the end of string character
1662  * Returns 1 if successful or -1 on error
1663  */
libesedb_catalog_definition_get_utf16_template_name(libesedb_catalog_definition_t * catalog_definition,uint16_t * utf16_string,size_t utf16_string_size,int ascii_codepage,libcerror_error_t ** error)1664 int libesedb_catalog_definition_get_utf16_template_name(
1665      libesedb_catalog_definition_t *catalog_definition,
1666      uint16_t *utf16_string,
1667      size_t utf16_string_size,
1668      int ascii_codepage,
1669      libcerror_error_t **error )
1670 {
1671 	static char *function = "libesedb_catalog_definition_get_utf16_template_name";
1672 
1673 	if( catalog_definition == NULL )
1674 	{
1675 		libcerror_error_set(
1676 		 error,
1677 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1678 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1679 		 "%s: invalid catalog definition.",
1680 		 function );
1681 
1682 		return( -1 );
1683 	}
1684 	if( catalog_definition->template_name != NULL )
1685 	{
1686 		if( libuna_utf16_string_copy_from_byte_stream(
1687 		     utf16_string,
1688 		     utf16_string_size,
1689 		     catalog_definition->template_name,
1690 		     catalog_definition->template_name_size,
1691 		     ascii_codepage,
1692 		     error ) != 1 )
1693 		{
1694 			libcerror_error_set(
1695 			 error,
1696 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1697 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1698 			 "%s: unable to set UTF-16 string.",
1699 			 function );
1700 
1701 			return( -1 );
1702 		}
1703 	}
1704 	return( 1 );
1705 }
1706 
1707 /* Compares the name of the table definition with a name
1708  * Returns 1 if equal, 0 if not or -1 on error
1709  */
libesedb_catalog_definition_compare_name(libesedb_catalog_definition_t * catalog_definition,const uint8_t * name,size_t name_size,libcerror_error_t ** error)1710 int libesedb_catalog_definition_compare_name(
1711      libesedb_catalog_definition_t *catalog_definition,
1712      const uint8_t *name,
1713      size_t name_size,
1714      libcerror_error_t **error )
1715 {
1716 	static char *function = "libesedb_catalog_definition_compare_name";
1717 
1718 	if( catalog_definition == NULL )
1719 	{
1720 		libcerror_error_set(
1721 		 error,
1722 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1723 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1724 		 "%s: invalid catalog definition.",
1725 		 function );
1726 
1727 		return( -1 );
1728 	}
1729 	if( catalog_definition->name == NULL )
1730 	{
1731 		libcerror_error_set(
1732 		 error,
1733 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1734 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1735 		 "%s: invalid catalog definition - missing name.",
1736 		 function );
1737 
1738 		return( -1 );
1739 	}
1740 	if( name == NULL )
1741 	{
1742 		libcerror_error_set(
1743 		 error,
1744 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1745 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1746 		 "%s: invalid name.",
1747 		 function );
1748 
1749 		return( -1 );
1750 	}
1751 	if( ( name_size == 0 )
1752 	 || ( name_size > (size_t) SSIZE_MAX ) )
1753 	{
1754 		libcerror_error_set(
1755 		 error,
1756 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1757 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1758 		 "%s: invalid name size value exceeds maximum.",
1759 		 function );
1760 
1761 		return( -1 );
1762 	}
1763 	if( name_size == catalog_definition->name_size )
1764 	{
1765 		if( memory_compare(
1766 		     catalog_definition->name,
1767 		     name,
1768 		     name_size ) == 0 )
1769 		{
1770 			return( 1 );
1771 		}
1772 	}
1773 	return( 0 );
1774 }
1775 
1776 /* Compares the name of the table definition with an UTF-8 encoded string
1777  * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
1778  */
libesedb_catalog_definition_compare_name_with_utf8_string(libesedb_catalog_definition_t * catalog_definition,const uint8_t * utf8_string,size_t utf8_string_length,libcerror_error_t ** error)1779 int libesedb_catalog_definition_compare_name_with_utf8_string(
1780      libesedb_catalog_definition_t *catalog_definition,
1781      const uint8_t *utf8_string,
1782      size_t utf8_string_length,
1783      libcerror_error_t **error )
1784 {
1785 	static char *function = "libesedb_catalog_definition_compare_name_with_utf8_string";
1786 	int result            = 0;
1787 
1788 	if( catalog_definition == NULL )
1789 	{
1790 		libcerror_error_set(
1791 		 error,
1792 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1793 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1794 		 "%s: invalid catalog definition.",
1795 		 function );
1796 
1797 		return( -1 );
1798 	}
1799 	if( catalog_definition->name == NULL )
1800 	{
1801 		libcerror_error_set(
1802 		 error,
1803 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1804 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1805 		 "%s: invalid catalog definition - missing name.",
1806 		 function );
1807 
1808 		return( -1 );
1809 	}
1810 /* TODO use ascii codepage */
1811 	result = libuna_utf8_string_compare_with_byte_stream(
1812 		  utf8_string,
1813 		  utf8_string_length,
1814 		  catalog_definition->name,
1815 		  catalog_definition->name_size,
1816 		  LIBUNA_CODEPAGE_WINDOWS_1252,
1817 		  error );
1818 
1819 	if( result == -1 )
1820 	{
1821 		libcerror_error_set(
1822 		 error,
1823 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1825 		 "%s: unable to compare UTF-8 string with catalog definition name.",
1826 		 function );
1827 
1828 		return( -1 );
1829 	}
1830 	return( result );
1831 }
1832 
1833 /* Compares the name of the table definition with an UTF-16 encoded string
1834  * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
1835  */
libesedb_catalog_definition_compare_name_with_utf16_string(libesedb_catalog_definition_t * catalog_definition,const uint16_t * utf16_string,size_t utf16_string_length,libcerror_error_t ** error)1836 int libesedb_catalog_definition_compare_name_with_utf16_string(
1837      libesedb_catalog_definition_t *catalog_definition,
1838      const uint16_t *utf16_string,
1839      size_t utf16_string_length,
1840      libcerror_error_t **error )
1841 {
1842 	static char *function = "libesedb_catalog_definition_compare_name_with_utf16_string";
1843 	int result            = 0;
1844 
1845 	if( catalog_definition == NULL )
1846 	{
1847 		libcerror_error_set(
1848 		 error,
1849 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1850 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1851 		 "%s: invalid catalog definition.",
1852 		 function );
1853 
1854 		return( -1 );
1855 	}
1856 	if( catalog_definition->name == NULL )
1857 	{
1858 		libcerror_error_set(
1859 		 error,
1860 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1861 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1862 		 "%s: invalid catalog definition - missing name.",
1863 		 function );
1864 
1865 		return( -1 );
1866 	}
1867 /* TODO use ascii codepage */
1868 	result = libuna_utf16_string_compare_with_byte_stream(
1869 		  utf16_string,
1870 		  utf16_string_length,
1871 		  catalog_definition->name,
1872 		  catalog_definition->name_size,
1873 		  LIBUNA_CODEPAGE_WINDOWS_1252,
1874 		  error );
1875 
1876 	if( result == -1 )
1877 	{
1878 		libcerror_error_set(
1879 		 error,
1880 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1881 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1882 		 "%s: unable to compare UTF-16 string with catalog definition name.",
1883 		 function );
1884 
1885 		return( -1 );
1886 	}
1887 	return( result );
1888 }
1889 
1890