1 /*
2  * Debug functions
3  *
4  * Copyright (C) 2011-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 <narrow_string.h>
25 #include <system_string.h>
26 #include <types.h>
27 #include <wide_string.h>
28 
29 #include "libscca_debug.h"
30 #include "libscca_definitions.h"
31 #include "libscca_libbfio.h"
32 #include "libscca_libcerror.h"
33 #include "libscca_libcnotify.h"
34 #include "libscca_libfdatetime.h"
35 #include "libscca_libuna.h"
36 
37 #if defined( HAVE_DEBUG_OUTPUT )
38 
39 /* Prints a FILETIME value
40  * Returns 1 if successful or -1 on error
41  */
libscca_debug_print_filetime_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,uint32_t string_format_flags,libcerror_error_t ** error)42 int libscca_debug_print_filetime_value(
43      const char *function_name,
44      const char *value_name,
45      const uint8_t *byte_stream,
46      size_t byte_stream_size,
47      int byte_order,
48      uint32_t string_format_flags,
49      libcerror_error_t **error )
50 {
51 	char date_time_string[ 32 ];
52 
53 	libfdatetime_filetime_t *filetime = NULL;
54 	static char *function             = "libscca_debug_print_filetime_value";
55 
56 	if( libfdatetime_filetime_initialize(
57 	     &filetime,
58 	     error ) != 1 )
59 	{
60 		libcerror_error_set(
61 		 error,
62 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
63 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
64 		 "%s: unable to create filetime.",
65 		 function );
66 
67 		goto on_error;
68 	}
69 	if( libfdatetime_filetime_copy_from_byte_stream(
70 	     filetime,
71 	     byte_stream,
72 	     byte_stream_size,
73 	     byte_order,
74 	     error ) != 1 )
75 	{
76 		libcerror_error_set(
77 		 error,
78 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
79 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
80 		 "%s: unable to copy byte stream to filetime.",
81 		 function );
82 
83 		goto on_error;
84 	}
85 	if( libfdatetime_filetime_copy_to_utf8_string(
86 	     filetime,
87 	     (uint8_t *) date_time_string,
88 	     32,
89 	     string_format_flags,
90 	     error ) != 1 )
91 	{
92 		libcerror_error_set(
93 		 error,
94 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
95 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
96 		 "%s: unable to copy filetime to string.",
97 		 function );
98 
99 		goto on_error;
100 	}
101 	libcnotify_printf(
102 	 "%s: %s: %s UTC\n",
103 	 function_name,
104 	 value_name,
105 	 date_time_string );
106 
107 	if( libfdatetime_filetime_free(
108 	     &filetime,
109 	     error ) != 1 )
110 	{
111 		libcerror_error_set(
112 		 error,
113 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
114 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
115 		 "%s: unable to free filetime.",
116 		 function );
117 
118 		goto on_error;
119 	}
120 	return( 1 );
121 
122 on_error:
123 	if( filetime != NULL )
124 	{
125 		libfdatetime_filetime_free(
126 		 &filetime,
127 		 NULL );
128 	}
129 	return( -1 );
130 }
131 
132 /* Prints an UTF-16 string value
133  * Returns 1 if successful or -1 on error
134  */
libscca_debug_print_utf16_string_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)135 int libscca_debug_print_utf16_string_value(
136      const char *function_name,
137      const char *value_name,
138      const uint8_t *byte_stream,
139      size_t byte_stream_size,
140      int byte_order,
141      libcerror_error_t **error )
142 {
143 	system_character_t *string = NULL;
144 	static char *function      = "libscca_debug_print_utf16_string_value";
145 	size_t string_size         = 0;
146 	int result                 = 0;
147 
148 	if( ( byte_stream == NULL )
149 	 || ( byte_stream_size == 0 ) )
150 	{
151 		libcnotify_printf(
152 		 "%s: %s:\n",
153 		 function_name,
154 		 value_name );
155 
156 		return( 1 );
157 	}
158 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
159 	result = libuna_utf16_string_size_from_utf16_stream(
160 	          byte_stream,
161 	          byte_stream_size,
162 	          byte_order,
163 	          &string_size,
164 	          error );
165 #else
166 	result = libuna_utf8_string_size_from_utf16_stream(
167 	          byte_stream,
168 	          byte_stream_size,
169 	          byte_order,
170 	          &string_size,
171 	          error );
172 #endif
173 	if( result != 1 )
174 	{
175 		libcerror_error_set(
176 		 error,
177 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
178 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
179 		 "%s: unable to determine size of string.",
180 		 function );
181 
182 		goto on_error;
183 	}
184 	if( string_size > ( (size_t) SSIZE_MAX / sizeof( system_character_t ) ) )
185 	{
186 		libcerror_error_set(
187 		 error,
188 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
189 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
190 		 "%s: invalid string size value exceeds maximum.",
191 		 function );
192 
193 		goto on_error;
194 	}
195 	libcnotify_printf(
196 	 "%s: %s:",
197 	 function_name,
198 	 value_name );
199 
200 	if( string_size > 0 )
201 	{
202 		string = system_string_allocate(
203 		          string_size );
204 
205 		if( string == NULL )
206 		{
207 			libcerror_error_set(
208 			 error,
209 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
210 			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
211 			 "%s: unable to create string.",
212 			 function );
213 
214 			goto on_error;
215 		}
216 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
217 		result = libuna_utf16_string_copy_from_utf16_stream(
218 		          (libuna_utf16_character_t *) string,
219 		          string_size,
220 		          byte_stream,
221 		          byte_stream_size,
222 		          byte_order,
223 		          error );
224 #else
225 		result = libuna_utf8_string_copy_from_utf16_stream(
226 		          (libuna_utf8_character_t *) string,
227 		          string_size,
228 		          byte_stream,
229 		          byte_stream_size,
230 		          byte_order,
231 		          error );
232 #endif
233 		if( result != 1 )
234 		{
235 			libcerror_error_set(
236 			 error,
237 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
238 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
239 			 "%s: unable to set string.",
240 			 function );
241 
242 			goto on_error;
243 		}
244 		libcnotify_printf(
245 		 " %s",
246 		 string );
247 
248 		memory_free(
249 		 string );
250 	}
251 	libcnotify_printf(
252 	 "\n" );
253 
254 	return( 1 );
255 
256 on_error:
257 	if( string != NULL )
258 	{
259 		memory_free(
260 		 string );
261 	}
262 	return( -1 );
263 }
264 
265 /* Prints the read offsets
266  * Returns 1 if successful or -1 on error
267  */
libscca_debug_print_read_offsets(libbfio_handle_t * file_io_handle,libcerror_error_t ** error)268 int libscca_debug_print_read_offsets(
269      libbfio_handle_t *file_io_handle,
270      libcerror_error_t **error )
271 {
272 	static char *function = "libscca_debug_print_read_offsets";
273 	off64_t offset        = 0;
274 	size64_t size         = 0;
275 	int number_of_offsets = 0;
276 	int offset_iterator   = 0;
277 
278 	if( file_io_handle == NULL )
279 	{
280 		libcerror_error_set(
281 		 error,
282 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
284 		 "%s: invalid file io handle.",
285 		 function );
286 
287 		return( -1 );
288 	}
289 	if( libbfio_handle_get_number_of_offsets_read(
290 	     file_io_handle,
291 	     &number_of_offsets,
292 	     error ) != 1 )
293 	{
294 		libcerror_error_set(
295 		 error,
296 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
297 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
298 		 "%s: unable to retrieve number of offsets read.",
299 		 function );
300 
301 		return( -1 );
302 	}
303 	libcnotify_printf(
304 	 "Offsets read:\n" );
305 
306 	for( offset_iterator = 0;
307 	     offset_iterator < number_of_offsets;
308 	     offset_iterator++ )
309 	{
310 		if( libbfio_handle_get_offset_read(
311 		     file_io_handle,
312 		     offset_iterator,
313 		     &offset,
314 		     &size,
315 		     error ) != 1 )
316 		{
317 			libcerror_error_set(
318 			 error,
319 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
320 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
321 			 "%s: unable to retrieve offset: %d.",
322 			 function,
323 			 ( offset_iterator + 1 ) );
324 
325 			return( -1 );
326 		}
327 		libcnotify_printf(
328 		 "%08" PRIi64 " ( 0x%08" PRIx64 " ) - %08" PRIi64 " ( 0x%08" PRIx64 " ) size: %" PRIu64 "\n",
329 		 offset,
330 		 offset,
331 		 offset + size,
332 		 offset + size,
333 		 size );
334 	}
335 	libcnotify_printf(
336 	 "\n" );
337 
338 	return( 1 );
339 }
340 
341 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
342 
343