1 /*
2  * Library file type test program
3  *
4  * Copyright (C) 2010-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 <file_stream.h>
24 #include <narrow_string.h>
25 #include <system_string.h>
26 #include <types.h>
27 #include <wide_string.h>
28 
29 #if defined( HAVE_STDLIB_H ) || defined( WINAPI )
30 #include <stdlib.h>
31 #endif
32 
33 #if defined( TIME_WITH_SYS_TIME )
34 #include <sys/time.h>
35 #include <time.h>
36 #elif defined( HAVE_SYS_TIME_H )
37 #include <sys/time.h>
38 #else
39 #include <time.h>
40 #endif
41 
42 #include "qcow_test_functions.h"
43 #include "qcow_test_getopt.h"
44 #include "qcow_test_libbfio.h"
45 #include "qcow_test_libcerror.h"
46 #include "qcow_test_libcpath.h"
47 #include "qcow_test_libqcow.h"
48 #include "qcow_test_macros.h"
49 #include "qcow_test_memory.h"
50 #include "qcow_test_rwlock.h"
51 
52 #include "../libqcow/libqcow_file.h"
53 
54 #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) && SIZEOF_WCHAR_T != 2 && SIZEOF_WCHAR_T != 4
55 #error Unsupported size of wchar_t
56 #endif
57 
58 /* Define to make qcow_test_file generate verbose output
59 #define QCOW_TEST_FILE_VERBOSE
60  */
61 
62 #define QCOW_TEST_FILE_READ_BUFFER_SIZE	4096
63 
64 #if !defined( LIBQCOW_HAVE_BFIO )
65 
66 LIBQCOW_EXTERN \
67 int libqcow_check_file_signature_file_io_handle(
68      libbfio_handle_t *file_io_handle,
69      libcerror_error_t **error );
70 
71 LIBQCOW_EXTERN \
72 int libqcow_file_open_file_io_handle(
73      libqcow_file_t *file,
74      libbfio_handle_t *file_io_handle,
75      int access_flags,
76      libqcow_error_t **error );
77 
78 #endif /* !defined( LIBQCOW_HAVE_BFIO ) */
79 
80 /* Creates and opens a source file
81  * Returns 1 if successful or -1 on error
82  */
qcow_test_file_open_source(libqcow_file_t ** file,libbfio_handle_t * file_io_handle,const system_character_t * password,libcerror_error_t ** error)83 int qcow_test_file_open_source(
84      libqcow_file_t **file,
85      libbfio_handle_t *file_io_handle,
86      const system_character_t *password,
87      libcerror_error_t **error )
88 {
89 	static char *function = "qcow_test_file_open_source";
90 	size_t string_length  = 0;
91 	int result            = 0;
92 
93 	if( file == NULL )
94 	{
95 		libcerror_error_set(
96 		 error,
97 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99 		 "%s: invalid file.",
100 		 function );
101 
102 		return( -1 );
103 	}
104 	if( file_io_handle == NULL )
105 	{
106 		libcerror_error_set(
107 		 error,
108 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
109 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
110 		 "%s: invalid file IO handle.",
111 		 function );
112 
113 		return( -1 );
114 	}
115 	if( libqcow_file_initialize(
116 	     file,
117 	     error ) != 1 )
118 	{
119 		libcerror_error_set(
120 		 error,
121 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
122 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
123 		 "%s: unable to initialize file.",
124 		 function );
125 
126 		goto on_error;
127 	}
128 	if( password != NULL )
129 	{
130 		string_length = system_string_length(
131 		                 password );
132 
133 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
134 		result = libqcow_file_set_utf16_password(
135 		          *file,
136 		          (uint16_t *) password,
137 		          string_length,
138 		          error );
139 #else
140 		result = libqcow_file_set_utf8_password(
141 		          *file,
142 		          (uint8_t *) password,
143 		          string_length,
144 		          error );
145 #endif
146 		if( result != 1 )
147 		{
148 			libcerror_error_set(
149 			 error,
150 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
151 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
152 			 "%s: unable to set password.",
153 			 function );
154 
155 			goto on_error;
156 		}
157 	}
158 	result = libqcow_file_open_file_io_handle(
159 	          *file,
160 	          file_io_handle,
161 	          LIBQCOW_OPEN_READ,
162 	          error );
163 
164 	if( result != 1 )
165 	{
166 		libcerror_error_set(
167 		 error,
168 		 LIBCERROR_ERROR_DOMAIN_IO,
169 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
170 		 "%s: unable to open file.",
171 		 function );
172 
173 		goto on_error;
174 	}
175 	return( 1 );
176 
177 on_error:
178 	if( *file != NULL )
179 	{
180 		libqcow_file_free(
181 		 file,
182 		 NULL );
183 	}
184 	return( -1 );
185 }
186 
187 /* Opens the parent input file
188  * Returns 1 if successful, 0 if no parent file or -1 on error
189  */
qcow_test_file_open_parent_file(libqcow_file_t ** parent_file,const system_character_t * source,libqcow_file_t * file,libcerror_error_t ** error)190 int qcow_test_file_open_parent_file(
191      libqcow_file_t **parent_file,
192      const system_character_t *source,
193      libqcow_file_t *file,
194      libcerror_error_t **error )
195 {
196 	system_character_t *backing_file_path = NULL;
197 	system_character_t *backing_filename  = NULL;
198 	system_character_t *basename_end      = NULL;
199 	static char *function                 = "qcow_test_file_open_parent_file";
200 	size_t backing_basename_length        = 0;
201 	size_t backing_file_path_size         = 0;
202 	size_t backing_filename_size          = 0;
203 	size_t basename_length                = 0;
204 	size_t source_length                  = 0;
205 	int result                            = 0;
206 
207 	if( parent_file == NULL )
208 	{
209 		libcerror_error_set(
210 		 error,
211 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
212 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
213 		 "%s: invalid parent file.",
214 		 function );
215 
216 		return( -1 );
217 	}
218 	if( source == NULL )
219 	{
220 		libcerror_error_set(
221 		 error,
222 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224 		 "%s: invalid source.",
225 		 function );
226 
227 		return( -1 );
228 	}
229 	source_length = system_string_length(
230 	                 source );
231 
232 	basename_end = system_string_search_character_reverse(
233 	                source,
234 	                (system_character_t) LIBCPATH_SEPARATOR,
235 	                source_length + 1 );
236 
237 	if( basename_end != NULL )
238 	{
239 		basename_length = (size_t) ( basename_end - source );
240 	}
241 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
242 	result = libqcow_file_get_utf16_backing_filename_size(
243 		  file,
244 		  &backing_filename_size,
245 		  error );
246 #else
247 	result = libqcow_file_get_utf8_backing_filename_size(
248 		  file,
249 		  &backing_filename_size,
250 		  error );
251 #endif
252 	if( result == -1 )
253 	{
254 		libcerror_error_set(
255 		 error,
256 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
257 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
258 		 "%s: unable to retrieve backing filename size.",
259 		 function );
260 
261 		goto on_error;
262 	}
263 	else if( result == 0 )
264 	{
265 		return( 0 );
266 	}
267 	if( backing_filename_size == 0 )
268 	{
269 		libcerror_error_set(
270 		 error,
271 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
272 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
273 		 "%s: missing backing filename.",
274 		 function );
275 
276 		goto on_error;
277 	}
278 	if( backing_filename_size > (size_t) ( SSIZE_MAX / sizeof( system_character_t ) ) )
279 	{
280 		libcerror_error_set(
281 		 error,
282 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
283 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
284 		 "%s: invalid backing filename size value exceeds maximum.",
285 		 function );
286 
287 		goto on_error;
288 	}
289 	backing_filename = system_string_allocate(
290 	                    backing_filename_size );
291 
292 	if( backing_filename == NULL )
293 	{
294 		libcerror_error_set(
295 		 error,
296 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
297 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
298 		 "%s: unable to create backing filename string.",
299 		 function );
300 
301 		goto on_error;
302 	}
303 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
304 	result = libqcow_file_get_utf16_backing_filename(
305 		  file,
306 		  (uint16_t *) backing_filename,
307 		  backing_filename_size,
308 		  error );
309 #else
310 	result = libqcow_file_get_utf8_backing_filename(
311 		  file,
312 		  (uint8_t *) backing_filename,
313 		  backing_filename_size,
314 		  error );
315 #endif
316 	if( result != 1 )
317 	{
318 		libcerror_error_set(
319 		 error,
320 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
321 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
322 		 "%s: unable to retrieve backing filename.",
323 		 function );
324 
325 		goto on_error;
326 	}
327 	if( basename_length == 0 )
328 	{
329 		backing_file_path      = &( backing_filename[ backing_basename_length ] );
330 		backing_file_path_size = backing_filename_size - ( backing_basename_length + 1 );
331 	}
332 	else
333 	{
334 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
335 		if( libcpath_path_join_wide(
336 		     &backing_file_path,
337 		     &backing_file_path_size,
338 		     source,
339 		     basename_length,
340 		     &( backing_filename[ backing_basename_length ] ),
341 		     backing_filename_size - ( backing_basename_length + 1 ),
342 		     error ) != 1 )
343 #else
344 		if( libcpath_path_join(
345 		     &backing_file_path,
346 		     &backing_file_path_size,
347 		     source,
348 		     basename_length,
349 		     &( backing_filename[ backing_basename_length ] ),
350 		     backing_filename_size - ( backing_basename_length + 1 ),
351 		     error ) != 1 )
352 #endif
353 		{
354 			libcerror_error_set(
355 			 error,
356 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
357 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
358 			 "%s: unable to create backing file path.",
359 			 function );
360 
361 			goto on_error;
362 		}
363 	}
364 	if( libqcow_file_initialize(
365 	     parent_file,
366 	     error ) != 1 )
367 	{
368 		libcerror_error_set(
369 		 error,
370 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
371 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
372 		 "%s: unable to initialize parent input file.",
373 		 function );
374 
375 		goto on_error;
376 	}
377 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
378 	if( libqcow_file_open_wide(
379 	     *parent_file,
380 	     backing_file_path,
381 	     LIBQCOW_OPEN_READ,
382 	     error ) != 1 )
383 #else
384 	if( libqcow_file_open(
385 	     *parent_file,
386 	     backing_file_path,
387 	     LIBQCOW_OPEN_READ,
388 	     error ) != 1 )
389 #endif
390 	{
391 		libcerror_error_set(
392 		 error,
393 		 LIBCERROR_ERROR_DOMAIN_IO,
394 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
395 		 "%s: unable to open parent input file: %" PRIs_SYSTEM ".",
396 		 function,
397 		 backing_file_path );
398 
399 		goto on_error;
400 	}
401 	if( libqcow_file_set_parent_file(
402 	     file,
403 	     *parent_file,
404 	     error ) != 1 )
405 	{
406 		libcerror_error_set(
407 		 error,
408 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
409 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
410 		 "%s: unable to set parent input file.",
411 		 function );
412 
413 		goto on_error;
414 	}
415 	if( ( basename_length != 0 )
416 	 && ( backing_file_path != NULL ) )
417 	{
418 		memory_free(
419 		 backing_file_path );
420 
421 		backing_file_path = NULL;
422 	}
423 	if( backing_filename != NULL )
424 	{
425 		memory_free(
426 		 backing_filename );
427 
428 		backing_filename = NULL;
429 	}
430 	return( 1 );
431 
432 on_error:
433 	if( *parent_file != NULL )
434 	{
435 		libqcow_file_free(
436 		 parent_file,
437 		 NULL );
438 	}
439 	if( ( basename_length != 0 )
440 	 && ( backing_file_path != NULL ) )
441 	{
442 		memory_free(
443 		 backing_file_path );
444 	}
445 	if( backing_filename != NULL )
446 	{
447 		memory_free(
448 		 backing_filename );
449 	}
450 	return( -1 );
451 }
452 
453 /* Closes and frees a source file
454  * Returns 1 if successful or -1 on error
455  */
qcow_test_file_close_source(libqcow_file_t ** file,libcerror_error_t ** error)456 int qcow_test_file_close_source(
457      libqcow_file_t **file,
458      libcerror_error_t **error )
459 {
460 	static char *function = "qcow_test_file_close_source";
461 	int result            = 0;
462 
463 	if( file == NULL )
464 	{
465 		libcerror_error_set(
466 		 error,
467 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
468 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
469 		 "%s: invalid file.",
470 		 function );
471 
472 		return( -1 );
473 	}
474 	if( libqcow_file_close(
475 	     *file,
476 	     error ) != 0 )
477 	{
478 		libcerror_error_set(
479 		 error,
480 		 LIBCERROR_ERROR_DOMAIN_IO,
481 		 LIBCERROR_IO_ERROR_CLOSE_FAILED,
482 		 "%s: unable to close file.",
483 		 function );
484 
485 		result = -1;
486 	}
487 	if( libqcow_file_free(
488 	     file,
489 	     error ) != 1 )
490 	{
491 		libcerror_error_set(
492 		 error,
493 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
494 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
495 		 "%s: unable to free file.",
496 		 function );
497 
498 		result = -1;
499 	}
500 	return( result );
501 }
502 
503 /* Tests the libqcow_file_initialize function
504  * Returns 1 if successful or 0 if not
505  */
qcow_test_file_initialize(void)506 int qcow_test_file_initialize(
507      void )
508 {
509 	libcerror_error_t *error        = NULL;
510 	libqcow_file_t *file            = NULL;
511 	int result                      = 0;
512 
513 #if defined( HAVE_QCOW_TEST_MEMORY )
514 	int number_of_malloc_fail_tests = 1;
515 	int number_of_memset_fail_tests = 1;
516 	int test_number                 = 0;
517 #endif
518 
519 	/* Test regular cases
520 	 */
521 	result = libqcow_file_initialize(
522 	          &file,
523 	          &error );
524 
525 	QCOW_TEST_ASSERT_EQUAL_INT(
526 	 "result",
527 	 result,
528 	 1 );
529 
530 	QCOW_TEST_ASSERT_IS_NOT_NULL(
531 	 "file",
532 	 file );
533 
534 	QCOW_TEST_ASSERT_IS_NULL(
535 	 "error",
536 	 error );
537 
538 	result = libqcow_file_free(
539 	          &file,
540 	          &error );
541 
542 	QCOW_TEST_ASSERT_EQUAL_INT(
543 	 "result",
544 	 result,
545 	 1 );
546 
547 	QCOW_TEST_ASSERT_IS_NULL(
548 	 "file",
549 	 file );
550 
551 	QCOW_TEST_ASSERT_IS_NULL(
552 	 "error",
553 	 error );
554 
555 	/* Test error cases
556 	 */
557 	result = libqcow_file_initialize(
558 	          NULL,
559 	          &error );
560 
561 	QCOW_TEST_ASSERT_EQUAL_INT(
562 	 "result",
563 	 result,
564 	 -1 );
565 
566 	QCOW_TEST_ASSERT_IS_NOT_NULL(
567 	 "error",
568 	 error );
569 
570 	libcerror_error_free(
571 	 &error );
572 
573 	file = (libqcow_file_t *) 0x12345678UL;
574 
575 	result = libqcow_file_initialize(
576 	          &file,
577 	          &error );
578 
579 	file = NULL;
580 
581 	QCOW_TEST_ASSERT_EQUAL_INT(
582 	 "result",
583 	 result,
584 	 -1 );
585 
586 	QCOW_TEST_ASSERT_IS_NOT_NULL(
587 	 "error",
588 	 error );
589 
590 	libcerror_error_free(
591 	 &error );
592 
593 #if defined( HAVE_QCOW_TEST_MEMORY )
594 
595 	for( test_number = 0;
596 	     test_number < number_of_malloc_fail_tests;
597 	     test_number++ )
598 	{
599 		/* Test libqcow_file_initialize with malloc failing
600 		 */
601 		qcow_test_malloc_attempts_before_fail = test_number;
602 
603 		result = libqcow_file_initialize(
604 		          &file,
605 		          &error );
606 
607 		if( qcow_test_malloc_attempts_before_fail != -1 )
608 		{
609 			qcow_test_malloc_attempts_before_fail = -1;
610 
611 			if( file != NULL )
612 			{
613 				libqcow_file_free(
614 				 &file,
615 				 NULL );
616 			}
617 		}
618 		else
619 		{
620 			QCOW_TEST_ASSERT_EQUAL_INT(
621 			 "result",
622 			 result,
623 			 -1 );
624 
625 			QCOW_TEST_ASSERT_IS_NULL(
626 			 "file",
627 			 file );
628 
629 			QCOW_TEST_ASSERT_IS_NOT_NULL(
630 			 "error",
631 			 error );
632 
633 			libcerror_error_free(
634 			 &error );
635 		}
636 	}
637 	for( test_number = 0;
638 	     test_number < number_of_memset_fail_tests;
639 	     test_number++ )
640 	{
641 		/* Test libqcow_file_initialize with memset failing
642 		 */
643 		qcow_test_memset_attempts_before_fail = test_number;
644 
645 		result = libqcow_file_initialize(
646 		          &file,
647 		          &error );
648 
649 		if( qcow_test_memset_attempts_before_fail != -1 )
650 		{
651 			qcow_test_memset_attempts_before_fail = -1;
652 
653 			if( file != NULL )
654 			{
655 				libqcow_file_free(
656 				 &file,
657 				 NULL );
658 			}
659 		}
660 		else
661 		{
662 			QCOW_TEST_ASSERT_EQUAL_INT(
663 			 "result",
664 			 result,
665 			 -1 );
666 
667 			QCOW_TEST_ASSERT_IS_NULL(
668 			 "file",
669 			 file );
670 
671 			QCOW_TEST_ASSERT_IS_NOT_NULL(
672 			 "error",
673 			 error );
674 
675 			libcerror_error_free(
676 			 &error );
677 		}
678 	}
679 #endif /* defined( HAVE_QCOW_TEST_MEMORY ) */
680 
681 	return( 1 );
682 
683 on_error:
684 	if( error != NULL )
685 	{
686 		libcerror_error_free(
687 		 &error );
688 	}
689 	if( file != NULL )
690 	{
691 		libqcow_file_free(
692 		 &file,
693 		 NULL );
694 	}
695 	return( 0 );
696 }
697 
698 /* Tests the libqcow_file_free function
699  * Returns 1 if successful or 0 if not
700  */
qcow_test_file_free(void)701 int qcow_test_file_free(
702      void )
703 {
704 	libcerror_error_t *error = NULL;
705 	int result               = 0;
706 
707 	/* Test error cases
708 	 */
709 	result = libqcow_file_free(
710 	          NULL,
711 	          &error );
712 
713 	QCOW_TEST_ASSERT_EQUAL_INT(
714 	 "result",
715 	 result,
716 	 -1 );
717 
718 	QCOW_TEST_ASSERT_IS_NOT_NULL(
719 	 "error",
720 	 error );
721 
722 	libcerror_error_free(
723 	 &error );
724 
725 	return( 1 );
726 
727 on_error:
728 	if( error != NULL )
729 	{
730 		libcerror_error_free(
731 		 &error );
732 	}
733 	return( 0 );
734 }
735 
736 /* Tests the libqcow_file_open function
737  * Returns 1 if successful or 0 if not
738  */
qcow_test_file_open(const system_character_t * source,const system_character_t * password)739 int qcow_test_file_open(
740      const system_character_t *source,
741      const system_character_t *password )
742 {
743 	char narrow_source[ 256 ];
744 
745 	libcerror_error_t *error = NULL;
746 	libqcow_file_t *file     = NULL;
747 	size_t string_length     = 0;
748 	int result               = 0;
749 
750 	/* Initialize test
751 	 */
752 	result = qcow_test_get_narrow_source(
753 	          source,
754 	          narrow_source,
755 	          256,
756 	          &error );
757 
758 	QCOW_TEST_ASSERT_EQUAL_INT(
759 	 "result",
760 	 result,
761 	 1 );
762 
763 	QCOW_TEST_ASSERT_IS_NULL(
764 	 "error",
765 	 error );
766 
767 	result = libqcow_file_initialize(
768 	          &file,
769 	          &error );
770 
771 	QCOW_TEST_ASSERT_EQUAL_INT(
772 	 "result",
773 	 result,
774 	 1 );
775 
776 	QCOW_TEST_ASSERT_IS_NOT_NULL(
777 	 "file",
778 	 file );
779 
780 	QCOW_TEST_ASSERT_IS_NULL(
781 	 "error",
782 	 error );
783 
784 	if( password != NULL )
785 	{
786 		string_length = system_string_length(
787 		                 password );
788 
789 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
790 		result = libqcow_file_set_utf16_password(
791 		          file,
792 		          (uint16_t *) password,
793 		          string_length,
794 		          &error );
795 #else
796 		result = libqcow_file_set_utf8_password(
797 		          file,
798 		          (uint8_t *) password,
799 		          string_length,
800 		          &error );
801 #endif
802 		QCOW_TEST_ASSERT_EQUAL_INT(
803 		 "result",
804 		 result,
805 		 1 );
806 
807 	        QCOW_TEST_ASSERT_IS_NULL(
808 	         "error",
809 		 error );
810 	}
811 	/* Test open
812 	 */
813 	result = libqcow_file_open(
814 	          file,
815 	          narrow_source,
816 	          LIBQCOW_OPEN_READ,
817 	          &error );
818 
819 	QCOW_TEST_ASSERT_EQUAL_INT(
820 	 "result",
821 	 result,
822 	 1 );
823 
824 	QCOW_TEST_ASSERT_IS_NULL(
825 	 "error",
826 	 error );
827 
828 	/* Test error cases
829 	 */
830 	result = libqcow_file_open(
831 	          NULL,
832 	          narrow_source,
833 	          LIBQCOW_OPEN_READ,
834 	          &error );
835 
836 	QCOW_TEST_ASSERT_EQUAL_INT(
837 	 "result",
838 	 result,
839 	 -1 );
840 
841 	QCOW_TEST_ASSERT_IS_NOT_NULL(
842 	 "error",
843 	 error );
844 
845 	libcerror_error_free(
846 	 &error );
847 
848 	result = libqcow_file_open(
849 	          file,
850 	          NULL,
851 	          LIBQCOW_OPEN_READ,
852 	          &error );
853 
854 	QCOW_TEST_ASSERT_EQUAL_INT(
855 	 "result",
856 	 result,
857 	 -1 );
858 
859 	QCOW_TEST_ASSERT_IS_NOT_NULL(
860 	 "error",
861 	 error );
862 
863 	libcerror_error_free(
864 	 &error );
865 
866 	result = libqcow_file_open(
867 	          file,
868 	          narrow_source,
869 	          -1,
870 	          &error );
871 
872 	QCOW_TEST_ASSERT_EQUAL_INT(
873 	 "result",
874 	 result,
875 	 -1 );
876 
877 	QCOW_TEST_ASSERT_IS_NOT_NULL(
878 	 "error",
879 	 error );
880 
881 	libcerror_error_free(
882 	 &error );
883 
884 	/* Test open when already opened
885 	 */
886 	result = libqcow_file_open(
887 	          file,
888 	          narrow_source,
889 	          LIBQCOW_OPEN_READ,
890 	          &error );
891 
892 	QCOW_TEST_ASSERT_EQUAL_INT(
893 	 "result",
894 	 result,
895 	 -1 );
896 
897 	QCOW_TEST_ASSERT_IS_NOT_NULL(
898 	 "error",
899 	 error );
900 
901 	libcerror_error_free(
902 	 &error );
903 
904 	/* Clean up
905 	 */
906 	result = libqcow_file_free(
907 	          &file,
908 	          &error );
909 
910 	QCOW_TEST_ASSERT_EQUAL_INT(
911 	 "result",
912 	 result,
913 	 1 );
914 
915 	QCOW_TEST_ASSERT_IS_NULL(
916 	 "file",
917 	 file );
918 
919 	QCOW_TEST_ASSERT_IS_NULL(
920 	 "error",
921 	 error );
922 
923 	return( 1 );
924 
925 on_error:
926 	if( error != NULL )
927 	{
928 		libcerror_error_free(
929 		 &error );
930 	}
931 	if( file != NULL )
932 	{
933 		libqcow_file_free(
934 		 &file,
935 		 NULL );
936 	}
937 	return( 0 );
938 }
939 
940 #if defined( HAVE_WIDE_CHARACTER_TYPE )
941 
942 /* Tests the libqcow_file_open_wide function
943  * Returns 1 if successful or 0 if not
944  */
qcow_test_file_open_wide(const system_character_t * source,const system_character_t * password)945 int qcow_test_file_open_wide(
946      const system_character_t *source,
947      const system_character_t *password )
948 {
949 	wchar_t wide_source[ 256 ];
950 
951 	libcerror_error_t *error = NULL;
952 	libqcow_file_t *file     = NULL;
953 	size_t string_length     = 0;
954 	int result               = 0;
955 
956 	/* Initialize test
957 	 */
958 	result = qcow_test_get_wide_source(
959 	          source,
960 	          wide_source,
961 	          256,
962 	          &error );
963 
964 	QCOW_TEST_ASSERT_EQUAL_INT(
965 	 "result",
966 	 result,
967 	 1 );
968 
969 	QCOW_TEST_ASSERT_IS_NULL(
970 	 "error",
971 	 error );
972 
973 	result = libqcow_file_initialize(
974 	          &file,
975 	          &error );
976 
977 	QCOW_TEST_ASSERT_EQUAL_INT(
978 	 "result",
979 	 result,
980 	 1 );
981 
982 	QCOW_TEST_ASSERT_IS_NOT_NULL(
983 	 "file",
984 	 file );
985 
986 	QCOW_TEST_ASSERT_IS_NULL(
987 	 "error",
988 	 error );
989 
990 	if( password != NULL )
991 	{
992 		string_length = system_string_length(
993 		                 password );
994 
995 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
996 		result = libqcow_file_set_utf16_password(
997 		          file,
998 		          (uint16_t *) password,
999 		          string_length,
1000 		          &error );
1001 #else
1002 		result = libqcow_file_set_utf8_password(
1003 		          file,
1004 		          (uint8_t *) password,
1005 		          string_length,
1006 		          &error );
1007 #endif
1008 		QCOW_TEST_ASSERT_EQUAL_INT(
1009 		 "result",
1010 		 result,
1011 		 1 );
1012 
1013 	        QCOW_TEST_ASSERT_IS_NULL(
1014 	         "error",
1015 		 error );
1016 	}
1017 	/* Test open
1018 	 */
1019 	result = libqcow_file_open_wide(
1020 	          file,
1021 	          wide_source,
1022 	          LIBQCOW_OPEN_READ,
1023 	          &error );
1024 
1025 	QCOW_TEST_ASSERT_EQUAL_INT(
1026 	 "result",
1027 	 result,
1028 	 1 );
1029 
1030 	QCOW_TEST_ASSERT_IS_NULL(
1031 	 "error",
1032 	 error );
1033 
1034 	/* Test error cases
1035 	 */
1036 	result = libqcow_file_open_wide(
1037 	          NULL,
1038 	          wide_source,
1039 	          LIBQCOW_OPEN_READ,
1040 	          &error );
1041 
1042 	QCOW_TEST_ASSERT_EQUAL_INT(
1043 	 "result",
1044 	 result,
1045 	 -1 );
1046 
1047 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1048 	 "error",
1049 	 error );
1050 
1051 	libcerror_error_free(
1052 	 &error );
1053 
1054 	result = libqcow_file_open_wide(
1055 	          file,
1056 	          NULL,
1057 	          LIBQCOW_OPEN_READ,
1058 	          &error );
1059 
1060 	QCOW_TEST_ASSERT_EQUAL_INT(
1061 	 "result",
1062 	 result,
1063 	 -1 );
1064 
1065 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1066 	 "error",
1067 	 error );
1068 
1069 	libcerror_error_free(
1070 	 &error );
1071 
1072 	result = libqcow_file_open_wide(
1073 	          file,
1074 	          wide_source,
1075 	          -1,
1076 	          &error );
1077 
1078 	QCOW_TEST_ASSERT_EQUAL_INT(
1079 	 "result",
1080 	 result,
1081 	 -1 );
1082 
1083 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1084 	 "error",
1085 	 error );
1086 
1087 	libcerror_error_free(
1088 	 &error );
1089 
1090 	/* Test open when already opened
1091 	 */
1092 	result = libqcow_file_open_wide(
1093 	          file,
1094 	          wide_source,
1095 	          LIBQCOW_OPEN_READ,
1096 	          &error );
1097 
1098 	QCOW_TEST_ASSERT_EQUAL_INT(
1099 	 "result",
1100 	 result,
1101 	 -1 );
1102 
1103 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1104 	 "error",
1105 	 error );
1106 
1107 	libcerror_error_free(
1108 	 &error );
1109 
1110 	/* Clean up
1111 	 */
1112 	result = libqcow_file_free(
1113 	          &file,
1114 	          &error );
1115 
1116 	QCOW_TEST_ASSERT_EQUAL_INT(
1117 	 "result",
1118 	 result,
1119 	 1 );
1120 
1121 	QCOW_TEST_ASSERT_IS_NULL(
1122 	 "file",
1123 	 file );
1124 
1125 	QCOW_TEST_ASSERT_IS_NULL(
1126 	 "error",
1127 	 error );
1128 
1129 	return( 1 );
1130 
1131 on_error:
1132 	if( error != NULL )
1133 	{
1134 		libcerror_error_free(
1135 		 &error );
1136 	}
1137 	if( file != NULL )
1138 	{
1139 		libqcow_file_free(
1140 		 &file,
1141 		 NULL );
1142 	}
1143 	return( 0 );
1144 }
1145 
1146 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1147 
1148 /* Tests the libqcow_file_open_file_io_handle function
1149  * Returns 1 if successful or 0 if not
1150  */
qcow_test_file_open_file_io_handle(const system_character_t * source,const system_character_t * password)1151 int qcow_test_file_open_file_io_handle(
1152      const system_character_t *source,
1153      const system_character_t *password )
1154 {
1155 	libbfio_handle_t *file_io_handle = NULL;
1156 	libcerror_error_t *error         = NULL;
1157 	libqcow_file_t *file             = NULL;
1158 	size_t string_length             = 0;
1159 	int result                       = 0;
1160 
1161 	/* Initialize test
1162 	 */
1163 	result = libbfio_file_initialize(
1164 	          &file_io_handle,
1165 	          &error );
1166 
1167 	QCOW_TEST_ASSERT_EQUAL_INT(
1168 	 "result",
1169 	 result,
1170 	 1 );
1171 
1172 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1173 	 "file_io_handle",
1174 	 file_io_handle );
1175 
1176 	QCOW_TEST_ASSERT_IS_NULL(
1177 	 "error",
1178 	 error );
1179 
1180 	string_length = system_string_length(
1181 	                 source );
1182 
1183 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1184 	result = libbfio_file_set_name_wide(
1185 	          file_io_handle,
1186 	          source,
1187 	          string_length,
1188 	          &error );
1189 #else
1190 	result = libbfio_file_set_name(
1191 	          file_io_handle,
1192 	          source,
1193 	          string_length,
1194 	          &error );
1195 #endif
1196 	QCOW_TEST_ASSERT_EQUAL_INT(
1197 	 "result",
1198 	 result,
1199 	 1 );
1200 
1201 	QCOW_TEST_ASSERT_IS_NULL(
1202 	 "error",
1203 	 error );
1204 
1205 	result = libqcow_file_initialize(
1206 	          &file,
1207 	          &error );
1208 
1209 	QCOW_TEST_ASSERT_EQUAL_INT(
1210 	 "result",
1211 	 result,
1212 	 1 );
1213 
1214 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1215 	 "file",
1216 	 file );
1217 
1218 	QCOW_TEST_ASSERT_IS_NULL(
1219 	 "error",
1220 	 error );
1221 
1222 	if( password != NULL )
1223 	{
1224 		string_length = system_string_length(
1225 		                 password );
1226 
1227 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1228 		result = libqcow_file_set_utf16_password(
1229 		          file,
1230 		          (uint16_t *) password,
1231 		          string_length,
1232 		          &error );
1233 #else
1234 		result = libqcow_file_set_utf8_password(
1235 		          file,
1236 		          (uint8_t *) password,
1237 		          string_length,
1238 		          &error );
1239 #endif
1240 		QCOW_TEST_ASSERT_EQUAL_INT(
1241 		 "result",
1242 		 result,
1243 		 1 );
1244 
1245 	        QCOW_TEST_ASSERT_IS_NULL(
1246 	         "error",
1247 		 error );
1248 	}
1249 	/* Test open
1250 	 */
1251 	result = libqcow_file_open_file_io_handle(
1252 	          file,
1253 	          file_io_handle,
1254 	          LIBQCOW_OPEN_READ,
1255 	          &error );
1256 
1257 	QCOW_TEST_ASSERT_EQUAL_INT(
1258 	 "result",
1259 	 result,
1260 	 1 );
1261 
1262 	QCOW_TEST_ASSERT_IS_NULL(
1263 	 "error",
1264 	 error );
1265 
1266 	/* Test error cases
1267 	 */
1268 	result = libqcow_file_open_file_io_handle(
1269 	          NULL,
1270 	          file_io_handle,
1271 	          LIBQCOW_OPEN_READ,
1272 	          &error );
1273 
1274 	QCOW_TEST_ASSERT_EQUAL_INT(
1275 	 "result",
1276 	 result,
1277 	 -1 );
1278 
1279 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1280 	 "error",
1281 	 error );
1282 
1283 	libcerror_error_free(
1284 	 &error );
1285 
1286 	result = libqcow_file_open_file_io_handle(
1287 	          file,
1288 	          NULL,
1289 	          LIBQCOW_OPEN_READ,
1290 	          &error );
1291 
1292 	QCOW_TEST_ASSERT_EQUAL_INT(
1293 	 "result",
1294 	 result,
1295 	 -1 );
1296 
1297 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1298 	 "error",
1299 	 error );
1300 
1301 	libcerror_error_free(
1302 	 &error );
1303 
1304 	result = libqcow_file_open_file_io_handle(
1305 	          file,
1306 	          file_io_handle,
1307 	          -1,
1308 	          &error );
1309 
1310 	QCOW_TEST_ASSERT_EQUAL_INT(
1311 	 "result",
1312 	 result,
1313 	 -1 );
1314 
1315 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1316 	 "error",
1317 	 error );
1318 
1319 	libcerror_error_free(
1320 	 &error );
1321 
1322 	/* Test open when already opened
1323 	 */
1324 	result = libqcow_file_open_file_io_handle(
1325 	          file,
1326 	          file_io_handle,
1327 	          LIBQCOW_OPEN_READ,
1328 	          &error );
1329 
1330 	QCOW_TEST_ASSERT_EQUAL_INT(
1331 	 "result",
1332 	 result,
1333 	 -1 );
1334 
1335 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1336 	 "error",
1337 	 error );
1338 
1339 	libcerror_error_free(
1340 	 &error );
1341 
1342 	/* Clean up
1343 	 */
1344 	result = libqcow_file_free(
1345 	          &file,
1346 	          &error );
1347 
1348 	QCOW_TEST_ASSERT_EQUAL_INT(
1349 	 "result",
1350 	 result,
1351 	 1 );
1352 
1353 	QCOW_TEST_ASSERT_IS_NULL(
1354 	 "file",
1355 	 file );
1356 
1357 	QCOW_TEST_ASSERT_IS_NULL(
1358 	 "error",
1359 	 error );
1360 
1361 	result = libbfio_handle_free(
1362 	          &file_io_handle,
1363 	          &error );
1364 
1365 	QCOW_TEST_ASSERT_EQUAL_INT(
1366 	 "result",
1367 	 result,
1368 	 1 );
1369 
1370 	QCOW_TEST_ASSERT_IS_NULL(
1371 	 "file_io_handle",
1372 	 file_io_handle );
1373 
1374 	QCOW_TEST_ASSERT_IS_NULL(
1375 	 "error",
1376 	 error );
1377 
1378 	return( 1 );
1379 
1380 on_error:
1381 	if( error != NULL )
1382 	{
1383 		libcerror_error_free(
1384 		 &error );
1385 	}
1386 	if( file != NULL )
1387 	{
1388 		libqcow_file_free(
1389 		 &file,
1390 		 NULL );
1391 	}
1392 	if( file_io_handle != NULL )
1393 	{
1394 		libbfio_handle_free(
1395 		 &file_io_handle,
1396 		 NULL );
1397 	}
1398 	return( 0 );
1399 }
1400 
1401 /* Tests the libqcow_file_close function
1402  * Returns 1 if successful or 0 if not
1403  */
qcow_test_file_close(void)1404 int qcow_test_file_close(
1405      void )
1406 {
1407 	libcerror_error_t *error = NULL;
1408 	int result               = 0;
1409 
1410 	/* Test error cases
1411 	 */
1412 	result = libqcow_file_close(
1413 	          NULL,
1414 	          &error );
1415 
1416 	QCOW_TEST_ASSERT_EQUAL_INT(
1417 	 "result",
1418 	 result,
1419 	 -1 );
1420 
1421 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1422 	 "error",
1423 	 error );
1424 
1425 	libcerror_error_free(
1426 	 &error );
1427 
1428 	return( 1 );
1429 
1430 on_error:
1431 	if( error != NULL )
1432 	{
1433 		libcerror_error_free(
1434 		 &error );
1435 	}
1436 	return( 0 );
1437 }
1438 
1439 /* Tests the libqcow_file_open and libqcow_file_close functions
1440  * Returns 1 if successful or 0 if not
1441  */
qcow_test_file_open_close(const system_character_t * source,const system_character_t * password)1442 int qcow_test_file_open_close(
1443      const system_character_t *source,
1444      const system_character_t *password )
1445 {
1446 	libcerror_error_t *error = NULL;
1447 	libqcow_file_t *file     = NULL;
1448 	size_t string_length     = 0;
1449 	int result               = 0;
1450 
1451 	/* Initialize test
1452 	 */
1453 	result = libqcow_file_initialize(
1454 	          &file,
1455 	          &error );
1456 
1457 	QCOW_TEST_ASSERT_EQUAL_INT(
1458 	 "result",
1459 	 result,
1460 	 1 );
1461 
1462 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1463 	 "file",
1464 	 file );
1465 
1466 	QCOW_TEST_ASSERT_IS_NULL(
1467 	 "error",
1468 	 error );
1469 
1470 	if( password != NULL )
1471 	{
1472 		string_length = system_string_length(
1473 		                 password );
1474 
1475 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1476 		result = libqcow_file_set_utf16_password(
1477 		          file,
1478 		          (uint16_t *) password,
1479 		          string_length,
1480 		          &error );
1481 #else
1482 		result = libqcow_file_set_utf8_password(
1483 		          file,
1484 		          (uint8_t *) password,
1485 		          string_length,
1486 		          &error );
1487 #endif
1488 		QCOW_TEST_ASSERT_EQUAL_INT(
1489 		 "result",
1490 		 result,
1491 		 1 );
1492 
1493 	        QCOW_TEST_ASSERT_IS_NULL(
1494 	         "error",
1495 		 error );
1496 	}
1497 	/* Test open and close
1498 	 */
1499 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1500 	result = libqcow_file_open_wide(
1501 	          file,
1502 	          source,
1503 	          LIBQCOW_OPEN_READ,
1504 	          &error );
1505 #else
1506 	result = libqcow_file_open(
1507 	          file,
1508 	          source,
1509 	          LIBQCOW_OPEN_READ,
1510 	          &error );
1511 #endif
1512 
1513 	QCOW_TEST_ASSERT_EQUAL_INT(
1514 	 "result",
1515 	 result,
1516 	 1 );
1517 
1518 	QCOW_TEST_ASSERT_IS_NULL(
1519 	 "error",
1520 	 error );
1521 
1522 	result = libqcow_file_close(
1523 	          file,
1524 	          &error );
1525 
1526 	QCOW_TEST_ASSERT_EQUAL_INT(
1527 	 "result",
1528 	 result,
1529 	 0 );
1530 
1531 	QCOW_TEST_ASSERT_IS_NULL(
1532 	 "error",
1533 	 error );
1534 
1535 	/* Test open and close a second time to validate clean up on close
1536 	 */
1537 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1538 	result = libqcow_file_open_wide(
1539 	          file,
1540 	          source,
1541 	          LIBQCOW_OPEN_READ,
1542 	          &error );
1543 #else
1544 	result = libqcow_file_open(
1545 	          file,
1546 	          source,
1547 	          LIBQCOW_OPEN_READ,
1548 	          &error );
1549 #endif
1550 
1551 	QCOW_TEST_ASSERT_EQUAL_INT(
1552 	 "result",
1553 	 result,
1554 	 1 );
1555 
1556 	QCOW_TEST_ASSERT_IS_NULL(
1557 	 "error",
1558 	 error );
1559 
1560 	result = libqcow_file_close(
1561 	          file,
1562 	          &error );
1563 
1564 	QCOW_TEST_ASSERT_EQUAL_INT(
1565 	 "result",
1566 	 result,
1567 	 0 );
1568 
1569 	QCOW_TEST_ASSERT_IS_NULL(
1570 	 "error",
1571 	 error );
1572 
1573 	/* Clean up
1574 	 */
1575 	result = libqcow_file_free(
1576 	          &file,
1577 	          &error );
1578 
1579 	QCOW_TEST_ASSERT_EQUAL_INT(
1580 	 "result",
1581 	 result,
1582 	 1 );
1583 
1584 	QCOW_TEST_ASSERT_IS_NULL(
1585 	 "file",
1586 	 file );
1587 
1588 	QCOW_TEST_ASSERT_IS_NULL(
1589 	 "error",
1590 	 error );
1591 
1592 	return( 1 );
1593 
1594 on_error:
1595 	if( error != NULL )
1596 	{
1597 		libcerror_error_free(
1598 		 &error );
1599 	}
1600 	if( file != NULL )
1601 	{
1602 		libqcow_file_free(
1603 		 &file,
1604 		 NULL );
1605 	}
1606 	return( 0 );
1607 }
1608 
1609 /* Tests the libqcow_file_signal_abort function
1610  * Returns 1 if successful or 0 if not
1611  */
qcow_test_file_signal_abort(libqcow_file_t * file)1612 int qcow_test_file_signal_abort(
1613      libqcow_file_t *file )
1614 {
1615 	libcerror_error_t *error = NULL;
1616 	int result               = 0;
1617 
1618 	/* Test regular cases
1619 	 */
1620 	result = libqcow_file_signal_abort(
1621 	          file,
1622 	          &error );
1623 
1624 	QCOW_TEST_ASSERT_EQUAL_INT(
1625 	 "result",
1626 	 result,
1627 	 1 );
1628 
1629 	QCOW_TEST_ASSERT_IS_NULL(
1630 	 "error",
1631 	 error );
1632 
1633 	/* Test error cases
1634 	 */
1635 	result = libqcow_file_signal_abort(
1636 	          NULL,
1637 	          &error );
1638 
1639 	QCOW_TEST_ASSERT_EQUAL_INT(
1640 	 "result",
1641 	 result,
1642 	 -1 );
1643 
1644 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1645 	 "error",
1646 	 error );
1647 
1648 	libcerror_error_free(
1649 	 &error );
1650 
1651 	return( 1 );
1652 
1653 on_error:
1654 	if( error != NULL )
1655 	{
1656 		libcerror_error_free(
1657 		 &error );
1658 	}
1659 	return( 0 );
1660 }
1661 
1662 /* Tests the libqcow_file_is_locked function
1663  * Returns 1 if successful or 0 if not
1664  */
qcow_test_file_is_locked(libqcow_file_t * file)1665 int qcow_test_file_is_locked(
1666      libqcow_file_t *file )
1667 {
1668 	libcerror_error_t *error = NULL;
1669 	int result               = 0;
1670 
1671 	/* Test regular cases
1672 	 */
1673 	result = libqcow_file_is_locked(
1674 	          file,
1675 	          &error );
1676 
1677 	QCOW_TEST_ASSERT_NOT_EQUAL_INT(
1678 	 "result",
1679 	 result,
1680 	 -1 );
1681 
1682 	QCOW_TEST_ASSERT_IS_NULL(
1683 	 "error",
1684 	 error );
1685 
1686 	/* Test error cases
1687 	 */
1688 	result = libqcow_file_is_locked(
1689 	          NULL,
1690 	          &error );
1691 
1692 	QCOW_TEST_ASSERT_EQUAL_INT(
1693 	 "result",
1694 	 result,
1695 	 -1 );
1696 
1697 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1698 	 "error",
1699 	 error );
1700 
1701 	libcerror_error_free(
1702 	 &error );
1703 
1704 	return( 1 );
1705 
1706 on_error:
1707 	if( error != NULL )
1708 	{
1709 		libcerror_error_free(
1710 		 &error );
1711 	}
1712 	return( 0 );
1713 }
1714 
1715 #if defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT )
1716 
1717 /* Tests the libqcow_internal_file_read_buffer_from_file_io_handle function
1718  * Returns 1 if successful or 0 if not
1719  */
qcow_test_internal_file_read_buffer_from_file_io_handle(libqcow_file_t * file)1720 int qcow_test_internal_file_read_buffer_from_file_io_handle(
1721      libqcow_file_t *file )
1722 {
1723 	uint8_t buffer[ QCOW_TEST_FILE_READ_BUFFER_SIZE ];
1724 
1725 	libcerror_error_t *error      = NULL;
1726 	time_t timestamp              = 0;
1727 	size64_t media_size           = 0;
1728 	size64_t remaining_media_size = 0;
1729 	size_t read_size              = 0;
1730 	ssize_t read_count            = 0;
1731 	off64_t offset                = 0;
1732 	off64_t read_offset           = 0;
1733 	int number_of_tests           = 1024;
1734 	int random_number             = 0;
1735 	int result                    = 0;
1736 	int test_number               = 0;
1737 
1738 	/* Determine size
1739 	 */
1740 	result = libqcow_file_get_media_size(
1741 	          file,
1742 	          &media_size,
1743 	          &error );
1744 
1745 	QCOW_TEST_ASSERT_EQUAL_INT(
1746 	 "result",
1747 	 result,
1748 	 1 );
1749 
1750 	QCOW_TEST_ASSERT_IS_NULL(
1751 	 "error",
1752 	 error );
1753 
1754 	/* Reset offset to 0
1755 	 */
1756 	offset = libqcow_file_seek_offset(
1757 	          file,
1758 	          0,
1759 	          SEEK_SET,
1760 	          &error );
1761 
1762 	QCOW_TEST_ASSERT_EQUAL_INT64(
1763 	 "offset",
1764 	 offset,
1765 	 (int64_t) 0 );
1766 
1767 	QCOW_TEST_ASSERT_IS_NULL(
1768 	 "error",
1769 	 error );
1770 
1771 	/* Test regular cases
1772 	 */
1773 	read_size = QCOW_TEST_FILE_READ_BUFFER_SIZE;
1774 
1775 	if( media_size < QCOW_TEST_FILE_READ_BUFFER_SIZE )
1776 	{
1777 		read_size = (size_t) media_size;
1778 	}
1779 	read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
1780 	              (libqcow_internal_file_t *) file,
1781 	              ( (libqcow_internal_file_t *) file )->file_io_handle,
1782 	              buffer,
1783 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
1784 	              &error );
1785 
1786 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
1787 	 "read_count",
1788 	 read_count,
1789 	 (ssize_t) read_size );
1790 
1791 	QCOW_TEST_ASSERT_IS_NULL(
1792 	 "error",
1793 	 error );
1794 
1795 	if( media_size > 8 )
1796 	{
1797 		/* Set offset to media_size - 8
1798 		 */
1799 		offset = libqcow_file_seek_offset(
1800 		          file,
1801 		          -8,
1802 		          SEEK_END,
1803 		          &error );
1804 
1805 		QCOW_TEST_ASSERT_EQUAL_INT64(
1806 		 "offset",
1807 		 offset,
1808 		 (int64_t) media_size - 8 );
1809 
1810 		QCOW_TEST_ASSERT_IS_NULL(
1811 		 "error",
1812 		 error );
1813 
1814 		/* Read buffer on media_size boundary
1815 		 */
1816 		read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
1817 		              (libqcow_internal_file_t *) file,
1818 		              ( (libqcow_internal_file_t *) file )->file_io_handle,
1819 		              buffer,
1820 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
1821 		              &error );
1822 
1823 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
1824 		 "read_count",
1825 		 read_count,
1826 		 (ssize_t) 8 );
1827 
1828 		QCOW_TEST_ASSERT_IS_NULL(
1829 		 "error",
1830 		 error );
1831 
1832 		/* Read buffer beyond media_size boundary
1833 		 */
1834 		read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
1835 		              (libqcow_internal_file_t *) file,
1836 		              ( (libqcow_internal_file_t *) file )->file_io_handle,
1837 		              buffer,
1838 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
1839 		              &error );
1840 
1841 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
1842 		 "read_count",
1843 		 read_count,
1844 		 (ssize_t) 0 );
1845 
1846 		QCOW_TEST_ASSERT_IS_NULL(
1847 		 "error",
1848 		 error );
1849 	}
1850 	/* Stress test read buffer
1851 	 */
1852 	timestamp = time(
1853 	             NULL );
1854 
1855 	srand(
1856 	 (unsigned int) timestamp );
1857 
1858 	offset = libqcow_file_seek_offset(
1859 	          file,
1860 	          0,
1861 	          SEEK_SET,
1862 	          &error );
1863 
1864 	QCOW_TEST_ASSERT_EQUAL_INT64(
1865 	 "offset",
1866 	 offset,
1867 	 (int64_t) 0 );
1868 
1869 	QCOW_TEST_ASSERT_IS_NULL(
1870 	 "error",
1871 	 error );
1872 
1873 	remaining_media_size = media_size;
1874 
1875 	for( test_number = 0;
1876 	     test_number < number_of_tests;
1877 	     test_number++ )
1878 	{
1879 		random_number = rand();
1880 
1881 		QCOW_TEST_ASSERT_GREATER_THAN_INT(
1882 		 "random_number",
1883 		 random_number,
1884 		 -1 );
1885 
1886 		read_size = (size_t) random_number % QCOW_TEST_FILE_READ_BUFFER_SIZE;
1887 
1888 #if defined( QCOW_TEST_FILE_VERBOSE )
1889 		fprintf(
1890 		 stdout,
1891 		 "libqcow_file_read_buffer: at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIzd "\n",
1892 		 read_offset,
1893 		 read_offset,
1894 		 read_size );
1895 #endif
1896 		read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
1897 		              (libqcow_internal_file_t *) file,
1898 		              ( (libqcow_internal_file_t *) file )->file_io_handle,
1899 		              buffer,
1900 		              read_size,
1901 		              &error );
1902 
1903 		if( read_size > remaining_media_size )
1904 		{
1905 			read_size = (size_t) remaining_media_size;
1906 		}
1907 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
1908 		 "read_count",
1909 		 read_count,
1910 		 (ssize_t) read_size );
1911 
1912 		QCOW_TEST_ASSERT_IS_NULL(
1913 		 "error",
1914 		 error );
1915 
1916 		read_offset += read_count;
1917 
1918 		result = libqcow_file_get_offset(
1919 		          file,
1920 		          &offset,
1921 		          &error );
1922 
1923 		QCOW_TEST_ASSERT_EQUAL_INT(
1924 		 "result",
1925 		 result,
1926 		 1 );
1927 
1928 		QCOW_TEST_ASSERT_EQUAL_INT64(
1929 		 "offset",
1930 		 offset,
1931 		 read_offset );
1932 
1933 		QCOW_TEST_ASSERT_IS_NULL(
1934 		 "error",
1935 		 error );
1936 
1937 		remaining_media_size -= read_count;
1938 
1939 		if( remaining_media_size == 0 )
1940 		{
1941 			offset = libqcow_file_seek_offset(
1942 			          file,
1943 			          0,
1944 			          SEEK_SET,
1945 			          &error );
1946 
1947 			QCOW_TEST_ASSERT_EQUAL_INT64(
1948 			 "offset",
1949 			 offset,
1950 			 (int64_t) 0 );
1951 
1952 			QCOW_TEST_ASSERT_IS_NULL(
1953 			 "error",
1954 			 error );
1955 
1956 			read_offset = 0;
1957 
1958 			remaining_media_size = media_size;
1959 		}
1960 	}
1961 	/* Reset offset to 0
1962 	 */
1963 	offset = libqcow_file_seek_offset(
1964 	          file,
1965 	          0,
1966 	          SEEK_SET,
1967 	          &error );
1968 
1969 	QCOW_TEST_ASSERT_EQUAL_INT64(
1970 	 "offset",
1971 	 offset,
1972 	 (int64_t) 0 );
1973 
1974 	QCOW_TEST_ASSERT_IS_NULL(
1975 	 "error",
1976 	 error );
1977 
1978 	/* Test error cases
1979 	 */
1980 	read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
1981 	              NULL,
1982 	              ( (libqcow_internal_file_t *) file )->file_io_handle,
1983 	              buffer,
1984 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
1985 	              &error );
1986 
1987 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
1988 	 "read_count",
1989 	 read_count,
1990 	 (ssize_t) -1 );
1991 
1992 	QCOW_TEST_ASSERT_IS_NOT_NULL(
1993 	 "error",
1994 	 error );
1995 
1996 	libcerror_error_free(
1997 	 &error );
1998 
1999 	read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
2000 	              (libqcow_internal_file_t *) file,
2001 	              ( (libqcow_internal_file_t *) file )->file_io_handle,
2002 	              NULL,
2003 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2004 	              &error );
2005 
2006 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2007 	 "read_count",
2008 	 read_count,
2009 	 (ssize_t) -1 );
2010 
2011 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2012 	 "error",
2013 	 error );
2014 
2015 	libcerror_error_free(
2016 	 &error );
2017 
2018 	read_count = libqcow_internal_file_read_buffer_from_file_io_handle(
2019 	              (libqcow_internal_file_t *) file,
2020 	              ( (libqcow_internal_file_t *) file )->file_io_handle,
2021 	              buffer,
2022 	              (size_t) SSIZE_MAX + 1,
2023 	              &error );
2024 
2025 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2026 	 "read_count",
2027 	 read_count,
2028 	 (ssize_t) -1 );
2029 
2030 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2031 	 "error",
2032 	 error );
2033 
2034 	libcerror_error_free(
2035 	 &error );
2036 
2037 	return( 1 );
2038 
2039 on_error:
2040 	if( error != NULL )
2041 	{
2042 		libcerror_error_free(
2043 		 &error );
2044 	}
2045 	return( 0 );
2046 }
2047 
2048 #endif /* defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT ) */
2049 
2050 /* Tests the libqcow_file_read_buffer function
2051  * Returns 1 if successful or 0 if not
2052  */
qcow_test_file_read_buffer(libqcow_file_t * file)2053 int qcow_test_file_read_buffer(
2054      libqcow_file_t *file )
2055 {
2056 	uint8_t buffer[ QCOW_TEST_FILE_READ_BUFFER_SIZE ];
2057 
2058 	libcerror_error_t *error      = NULL;
2059 	time_t timestamp              = 0;
2060 	size64_t media_size           = 0;
2061 	size64_t remaining_media_size = 0;
2062 	size_t read_size              = 0;
2063 	ssize_t read_count            = 0;
2064 	off64_t offset                = 0;
2065 	off64_t read_offset           = 0;
2066 	int number_of_tests           = 1024;
2067 	int random_number             = 0;
2068 	int result                    = 0;
2069 	int test_number               = 0;
2070 
2071 	/* Determine size
2072 	 */
2073 	result = libqcow_file_get_media_size(
2074 	          file,
2075 	          &media_size,
2076 	          &error );
2077 
2078 	QCOW_TEST_ASSERT_EQUAL_INT(
2079 	 "result",
2080 	 result,
2081 	 1 );
2082 
2083 	QCOW_TEST_ASSERT_IS_NULL(
2084 	 "error",
2085 	 error );
2086 
2087 	/* Reset offset to 0
2088 	 */
2089 	offset = libqcow_file_seek_offset(
2090 	          file,
2091 	          0,
2092 	          SEEK_SET,
2093 	          &error );
2094 
2095 	QCOW_TEST_ASSERT_EQUAL_INT64(
2096 	 "offset",
2097 	 offset,
2098 	 (int64_t) 0 );
2099 
2100 	QCOW_TEST_ASSERT_IS_NULL(
2101 	 "error",
2102 	 error );
2103 
2104 	/* Test regular cases
2105 	 */
2106 	read_size = QCOW_TEST_FILE_READ_BUFFER_SIZE;
2107 
2108 	if( media_size < QCOW_TEST_FILE_READ_BUFFER_SIZE )
2109 	{
2110 		read_size = (size_t) media_size;
2111 	}
2112 	read_count = libqcow_file_read_buffer(
2113 	              file,
2114 	              buffer,
2115 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2116 	              &error );
2117 
2118 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2119 	 "read_count",
2120 	 read_count,
2121 	 (ssize_t) read_size );
2122 
2123 	QCOW_TEST_ASSERT_IS_NULL(
2124 	 "error",
2125 	 error );
2126 
2127 	if( media_size > 8 )
2128 	{
2129 		/* Set offset to media_size - 8
2130 		 */
2131 		offset = libqcow_file_seek_offset(
2132 		          file,
2133 		          -8,
2134 		          SEEK_END,
2135 		          &error );
2136 
2137 		QCOW_TEST_ASSERT_EQUAL_INT64(
2138 		 "offset",
2139 		 offset,
2140 		 (int64_t) media_size - 8 );
2141 
2142 		QCOW_TEST_ASSERT_IS_NULL(
2143 		 "error",
2144 		 error );
2145 
2146 		/* Read buffer on media_size boundary
2147 		 */
2148 		read_count = libqcow_file_read_buffer(
2149 		              file,
2150 		              buffer,
2151 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2152 		              &error );
2153 
2154 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2155 		 "read_count",
2156 		 read_count,
2157 		 (ssize_t) 8 );
2158 
2159 		QCOW_TEST_ASSERT_IS_NULL(
2160 		 "error",
2161 		 error );
2162 
2163 		/* Read buffer beyond media_size boundary
2164 		 */
2165 		read_count = libqcow_file_read_buffer(
2166 		              file,
2167 		              buffer,
2168 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2169 		              &error );
2170 
2171 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2172 		 "read_count",
2173 		 read_count,
2174 		 (ssize_t) 0 );
2175 
2176 		QCOW_TEST_ASSERT_IS_NULL(
2177 		 "error",
2178 		 error );
2179 	}
2180 	/* Stress test read buffer
2181 	 */
2182 	timestamp = time(
2183 	             NULL );
2184 
2185 	srand(
2186 	 (unsigned int) timestamp );
2187 
2188 	offset = libqcow_file_seek_offset(
2189 	          file,
2190 	          0,
2191 	          SEEK_SET,
2192 	          &error );
2193 
2194 	QCOW_TEST_ASSERT_EQUAL_INT64(
2195 	 "offset",
2196 	 offset,
2197 	 (int64_t) 0 );
2198 
2199 	QCOW_TEST_ASSERT_IS_NULL(
2200 	 "error",
2201 	 error );
2202 
2203 	remaining_media_size = media_size;
2204 
2205 	for( test_number = 0;
2206 	     test_number < number_of_tests;
2207 	     test_number++ )
2208 	{
2209 		random_number = rand();
2210 
2211 		QCOW_TEST_ASSERT_GREATER_THAN_INT(
2212 		 "random_number",
2213 		 random_number,
2214 		 -1 );
2215 
2216 		read_size = (size_t) random_number % QCOW_TEST_FILE_READ_BUFFER_SIZE;
2217 
2218 #if defined( QCOW_TEST_FILE_VERBOSE )
2219 		fprintf(
2220 		 stdout,
2221 		 "libqcow_file_read_buffer: at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIzd "\n",
2222 		 read_offset,
2223 		 read_offset,
2224 		 read_size );
2225 #endif
2226 		read_count = libqcow_file_read_buffer(
2227 		              file,
2228 		              buffer,
2229 		              read_size,
2230 		              &error );
2231 
2232 		if( read_size > remaining_media_size )
2233 		{
2234 			read_size = (size_t) remaining_media_size;
2235 		}
2236 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2237 		 "read_count",
2238 		 read_count,
2239 		 (ssize_t) read_size );
2240 
2241 		QCOW_TEST_ASSERT_IS_NULL(
2242 		 "error",
2243 		 error );
2244 
2245 		read_offset += read_count;
2246 
2247 		result = libqcow_file_get_offset(
2248 		          file,
2249 		          &offset,
2250 		          &error );
2251 
2252 		QCOW_TEST_ASSERT_EQUAL_INT(
2253 		 "result",
2254 		 result,
2255 		 1 );
2256 
2257 		QCOW_TEST_ASSERT_EQUAL_INT64(
2258 		 "offset",
2259 		 offset,
2260 		 read_offset );
2261 
2262 		QCOW_TEST_ASSERT_IS_NULL(
2263 		 "error",
2264 		 error );
2265 
2266 		remaining_media_size -= read_count;
2267 
2268 		if( remaining_media_size == 0 )
2269 		{
2270 			offset = libqcow_file_seek_offset(
2271 			          file,
2272 			          0,
2273 			          SEEK_SET,
2274 			          &error );
2275 
2276 			QCOW_TEST_ASSERT_EQUAL_INT64(
2277 			 "offset",
2278 			 offset,
2279 			 (int64_t) 0 );
2280 
2281 			QCOW_TEST_ASSERT_IS_NULL(
2282 			 "error",
2283 			 error );
2284 
2285 			read_offset = 0;
2286 
2287 			remaining_media_size = media_size;
2288 		}
2289 	}
2290 	/* Reset offset to 0
2291 	 */
2292 	offset = libqcow_file_seek_offset(
2293 	          file,
2294 	          0,
2295 	          SEEK_SET,
2296 	          &error );
2297 
2298 	QCOW_TEST_ASSERT_EQUAL_INT64(
2299 	 "offset",
2300 	 offset,
2301 	 (int64_t) 0 );
2302 
2303 	QCOW_TEST_ASSERT_IS_NULL(
2304 	 "error",
2305 	 error );
2306 
2307 	/* Test error cases
2308 	 */
2309 	read_count = libqcow_file_read_buffer(
2310 	              NULL,
2311 	              buffer,
2312 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2313 	              &error );
2314 
2315 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2316 	 "read_count",
2317 	 read_count,
2318 	 (ssize_t) -1 );
2319 
2320 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2321 	 "error",
2322 	 error );
2323 
2324 	libcerror_error_free(
2325 	 &error );
2326 
2327 	read_count = libqcow_file_read_buffer(
2328 	              file,
2329 	              NULL,
2330 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2331 	              &error );
2332 
2333 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2334 	 "read_count",
2335 	 read_count,
2336 	 (ssize_t) -1 );
2337 
2338 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2339 	 "error",
2340 	 error );
2341 
2342 	libcerror_error_free(
2343 	 &error );
2344 
2345 	read_count = libqcow_file_read_buffer(
2346 	              file,
2347 	              buffer,
2348 	              (size_t) SSIZE_MAX + 1,
2349 	              &error );
2350 
2351 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2352 	 "read_count",
2353 	 read_count,
2354 	 (ssize_t) -1 );
2355 
2356 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2357 	 "error",
2358 	 error );
2359 
2360 	libcerror_error_free(
2361 	 &error );
2362 
2363 #if defined( HAVE_QCOW_TEST_RWLOCK )
2364 
2365 	/* Test libqcow_file_read_buffer with pthread_rwlock_wrlock failing in libcthreads_read_write_lock_grab_for_write
2366 	 */
2367 	qcow_test_pthread_rwlock_wrlock_attempts_before_fail = 0;
2368 
2369 	read_count = libqcow_file_read_buffer(
2370 	              file,
2371 	              buffer,
2372 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2373 	              &error );
2374 
2375 	if( qcow_test_pthread_rwlock_wrlock_attempts_before_fail != -1 )
2376 	{
2377 		qcow_test_pthread_rwlock_wrlock_attempts_before_fail = -1;
2378 	}
2379 	else
2380 	{
2381 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2382 		 "read_count",
2383 		 read_count,
2384 		 (ssize_t) -1 );
2385 
2386 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2387 		 "error",
2388 		 error );
2389 
2390 		libcerror_error_free(
2391 		 &error );
2392 	}
2393 	/* Test libqcow_file_read_buffer with pthread_rwlock_unlock failing in libcthreads_read_write_lock_release_for_write
2394 	 */
2395 	qcow_test_pthread_rwlock_unlock_attempts_before_fail = 0;
2396 
2397 	read_count = libqcow_file_read_buffer(
2398 	              file,
2399 	              buffer,
2400 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2401 	              &error );
2402 
2403 	if( qcow_test_pthread_rwlock_unlock_attempts_before_fail != -1 )
2404 	{
2405 		qcow_test_pthread_rwlock_unlock_attempts_before_fail = -1;
2406 	}
2407 	else
2408 	{
2409 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2410 		 "read_count",
2411 		 read_count,
2412 		 (ssize_t) -1 );
2413 
2414 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2415 		 "error",
2416 		 error );
2417 
2418 		libcerror_error_free(
2419 		 &error );
2420 	}
2421 #endif /* defined( HAVE_QCOW_TEST_RWLOCK ) */
2422 
2423 	return( 1 );
2424 
2425 on_error:
2426 	if( error != NULL )
2427 	{
2428 		libcerror_error_free(
2429 		 &error );
2430 	}
2431 	return( 0 );
2432 }
2433 
2434 /* Tests the libqcow_file_read_buffer_at_offset function
2435  * Returns 1 if successful or 0 if not
2436  */
qcow_test_file_read_buffer_at_offset(libqcow_file_t * file)2437 int qcow_test_file_read_buffer_at_offset(
2438      libqcow_file_t *file )
2439 {
2440 	uint8_t buffer[ QCOW_TEST_FILE_READ_BUFFER_SIZE ];
2441 
2442 	libcerror_error_t *error      = NULL;
2443 	time_t timestamp              = 0;
2444 	size64_t media_size           = 0;
2445 	size64_t remaining_media_size = 0;
2446 	size_t read_size              = 0;
2447 	ssize_t read_count            = 0;
2448 	off64_t offset                = 0;
2449 	off64_t read_offset           = 0;
2450 	int number_of_tests           = 1024;
2451 	int random_number             = 0;
2452 	int result                    = 0;
2453 	int test_number               = 0;
2454 
2455 	/* Determine size
2456 	 */
2457 	result = libqcow_file_get_media_size(
2458 	          file,
2459 	          &media_size,
2460 	          &error );
2461 
2462 	QCOW_TEST_ASSERT_EQUAL_INT(
2463 	 "result",
2464 	 result,
2465 	 1 );
2466 
2467 	QCOW_TEST_ASSERT_IS_NULL(
2468 	 "error",
2469 	 error );
2470 
2471 	/* Test regular cases
2472 	 */
2473 	read_size = QCOW_TEST_FILE_READ_BUFFER_SIZE;
2474 
2475 	if( media_size < QCOW_TEST_FILE_READ_BUFFER_SIZE )
2476 	{
2477 		read_size = (size_t) media_size;
2478 	}
2479 	read_count = libqcow_file_read_buffer_at_offset(
2480 	              file,
2481 	              buffer,
2482 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2483 	              0,
2484 	              &error );
2485 
2486 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2487 	 "read_count",
2488 	 read_count,
2489 	 (ssize_t) read_size );
2490 
2491 	QCOW_TEST_ASSERT_IS_NULL(
2492 	 "error",
2493 	 error );
2494 
2495 	if( media_size > 8 )
2496 	{
2497 		/* Read buffer on media_size boundary
2498 		 */
2499 		read_count = libqcow_file_read_buffer_at_offset(
2500 		              file,
2501 		              buffer,
2502 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2503 		              media_size - 8,
2504 		              &error );
2505 
2506 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2507 		 "read_count",
2508 		 read_count,
2509 		 (ssize_t) 8 );
2510 
2511 		QCOW_TEST_ASSERT_IS_NULL(
2512 		 "error",
2513 		 error );
2514 
2515 		/* Read buffer beyond media_size boundary
2516 		 */
2517 		read_count = libqcow_file_read_buffer_at_offset(
2518 		              file,
2519 		              buffer,
2520 		              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2521 		              media_size + 8,
2522 		              &error );
2523 
2524 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2525 		 "read_count",
2526 		 read_count,
2527 		 (ssize_t) 0 );
2528 
2529 		QCOW_TEST_ASSERT_IS_NULL(
2530 		 "error",
2531 		 error );
2532 	}
2533 	/* Stress test read buffer
2534 	 */
2535 	timestamp = time(
2536 	             NULL );
2537 
2538 	srand(
2539 	 (unsigned int) timestamp );
2540 
2541 	for( test_number = 0;
2542 	     test_number < number_of_tests;
2543 	     test_number++ )
2544 	{
2545 		random_number = rand();
2546 
2547 		QCOW_TEST_ASSERT_GREATER_THAN_INT(
2548 		 "random_number",
2549 		 random_number,
2550 		 -1 );
2551 
2552 		if( media_size > 0 )
2553 		{
2554 			read_offset = (off64_t) random_number % media_size;
2555 		}
2556 		read_size = (size_t) random_number % QCOW_TEST_FILE_READ_BUFFER_SIZE;
2557 
2558 #if defined( QCOW_TEST_FILE_VERBOSE )
2559 		fprintf(
2560 		 stdout,
2561 		 "libqcow_file_read_buffer_at_offset: at offset: %" PRIi64 " (0x%08" PRIx64 ") of size: %" PRIzd "\n",
2562 		 read_offset,
2563 		 read_offset,
2564 		 read_size );
2565 #endif
2566 		read_count = libqcow_file_read_buffer_at_offset(
2567 		              file,
2568 		              buffer,
2569 		              read_size,
2570 		              read_offset,
2571 		              &error );
2572 
2573 		remaining_media_size = media_size - read_offset;
2574 
2575 		if( read_size > remaining_media_size )
2576 		{
2577 			read_size = (size_t) remaining_media_size;
2578 		}
2579 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2580 		 "read_count",
2581 		 read_count,
2582 		 (ssize_t) read_size );
2583 
2584 		QCOW_TEST_ASSERT_IS_NULL(
2585 		 "error",
2586 		 error );
2587 
2588 		read_offset += read_count;
2589 
2590 		result = libqcow_file_get_offset(
2591 		          file,
2592 		          &offset,
2593 		          &error );
2594 
2595 		QCOW_TEST_ASSERT_EQUAL_INT(
2596 		 "result",
2597 		 result,
2598 		 1 );
2599 
2600 		QCOW_TEST_ASSERT_EQUAL_INT64(
2601 		 "offset",
2602 		 offset,
2603 		 read_offset );
2604 
2605 		QCOW_TEST_ASSERT_IS_NULL(
2606 		 "error",
2607 		 error );
2608 	}
2609 	/* Test error cases
2610 	 */
2611 	read_count = libqcow_file_read_buffer_at_offset(
2612 	              NULL,
2613 	              buffer,
2614 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2615 	              0,
2616 	              &error );
2617 
2618 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2619 	 "read_count",
2620 	 read_count,
2621 	 (ssize_t) -1 );
2622 
2623 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2624 	 "error",
2625 	 error );
2626 
2627 	libcerror_error_free(
2628 	 &error );
2629 
2630 	read_count = libqcow_file_read_buffer_at_offset(
2631 	              file,
2632 	              NULL,
2633 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2634 	              0,
2635 	              &error );
2636 
2637 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2638 	 "read_count",
2639 	 read_count,
2640 	 (ssize_t) -1 );
2641 
2642 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2643 	 "error",
2644 	 error );
2645 
2646 	libcerror_error_free(
2647 	 &error );
2648 
2649 	read_count = libqcow_file_read_buffer_at_offset(
2650 	              file,
2651 	              buffer,
2652 	              (size_t) SSIZE_MAX + 1,
2653 	              0,
2654 	              &error );
2655 
2656 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2657 	 "read_count",
2658 	 read_count,
2659 	 (ssize_t) -1 );
2660 
2661 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2662 	 "error",
2663 	 error );
2664 
2665 	libcerror_error_free(
2666 	 &error );
2667 
2668 	read_count = libqcow_file_read_buffer_at_offset(
2669 	              file,
2670 	              buffer,
2671 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2672 	              -1,
2673 	              &error );
2674 
2675 	QCOW_TEST_ASSERT_EQUAL_SSIZE(
2676 	 "read_count",
2677 	 read_count,
2678 	 (ssize_t) -1 );
2679 
2680 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2681 	 "error",
2682 	 error );
2683 
2684 	libcerror_error_free(
2685 	 &error );
2686 
2687 #if defined( HAVE_QCOW_TEST_RWLOCK )
2688 
2689 	/* Test libqcow_file_read_buffer_at_offset with pthread_rwlock_wrlock failing in libcthreads_read_write_lock_grab_for_write
2690 	 */
2691 	qcow_test_pthread_rwlock_wrlock_attempts_before_fail = 0;
2692 
2693 	read_count = libqcow_file_read_buffer_at_offset(
2694 	              file,
2695 	              buffer,
2696 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2697 	              0,
2698 	              &error );
2699 
2700 	if( qcow_test_pthread_rwlock_wrlock_attempts_before_fail != -1 )
2701 	{
2702 		qcow_test_pthread_rwlock_wrlock_attempts_before_fail = -1;
2703 	}
2704 	else
2705 	{
2706 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2707 		 "read_count",
2708 		 read_count,
2709 		 (ssize_t) -1 );
2710 
2711 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2712 		 "error",
2713 		 error );
2714 
2715 		libcerror_error_free(
2716 		 &error );
2717 	}
2718 	/* Test libqcow_file_read_buffer_at_offset with pthread_rwlock_unlock failing in libcthreads_read_write_lock_release_for_write
2719 	 */
2720 	qcow_test_pthread_rwlock_unlock_attempts_before_fail = 0;
2721 
2722 	read_count = libqcow_file_read_buffer_at_offset(
2723 	              file,
2724 	              buffer,
2725 	              QCOW_TEST_FILE_READ_BUFFER_SIZE,
2726 	              0,
2727 	              &error );
2728 
2729 	if( qcow_test_pthread_rwlock_unlock_attempts_before_fail != -1 )
2730 	{
2731 		qcow_test_pthread_rwlock_unlock_attempts_before_fail = -1;
2732 	}
2733 	else
2734 	{
2735 		QCOW_TEST_ASSERT_EQUAL_SSIZE(
2736 		 "read_count",
2737 		 read_count,
2738 		 (ssize_t) -1 );
2739 
2740 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2741 		 "error",
2742 		 error );
2743 
2744 		libcerror_error_free(
2745 		 &error );
2746 	}
2747 #endif /* defined( HAVE_QCOW_TEST_RWLOCK ) */
2748 
2749 	return( 1 );
2750 
2751 on_error:
2752 	if( error != NULL )
2753 	{
2754 		libcerror_error_free(
2755 		 &error );
2756 	}
2757 	return( 0 );
2758 }
2759 
2760 /* Tests the libqcow_file_seek_offset function
2761  * Returns 1 if successful or 0 if not
2762  */
qcow_test_file_seek_offset(libqcow_file_t * file)2763 int qcow_test_file_seek_offset(
2764      libqcow_file_t *file )
2765 {
2766 	libcerror_error_t *error = NULL;
2767 	size64_t size            = 0;
2768 	off64_t offset           = 0;
2769 
2770 	/* Test regular cases
2771 	 */
2772 	offset = libqcow_file_seek_offset(
2773 	          file,
2774 	          0,
2775 	          SEEK_END,
2776 	          &error );
2777 
2778 	QCOW_TEST_ASSERT_NOT_EQUAL_INT64(
2779 	 "offset",
2780 	 offset,
2781 	 (int64_t) -1 );
2782 
2783 	QCOW_TEST_ASSERT_IS_NULL(
2784 	 "error",
2785 	 error );
2786 
2787 	size = (size64_t) offset;
2788 
2789 	offset = libqcow_file_seek_offset(
2790 	          file,
2791 	          1024,
2792 	          SEEK_SET,
2793 	          &error );
2794 
2795 	QCOW_TEST_ASSERT_EQUAL_INT64(
2796 	 "offset",
2797 	 offset,
2798 	 (int64_t) 1024 );
2799 
2800 	QCOW_TEST_ASSERT_IS_NULL(
2801 	 "error",
2802 	 error );
2803 
2804 	offset = libqcow_file_seek_offset(
2805 	          file,
2806 	          -512,
2807 	          SEEK_CUR,
2808 	          &error );
2809 
2810 	QCOW_TEST_ASSERT_EQUAL_INT64(
2811 	 "offset",
2812 	 offset,
2813 	 (int64_t) 512 );
2814 
2815 	QCOW_TEST_ASSERT_IS_NULL(
2816 	 "error",
2817 	 error );
2818 
2819 	offset = libqcow_file_seek_offset(
2820 	          file,
2821 	          (off64_t) ( size + 512 ),
2822 	          SEEK_SET,
2823 	          &error );
2824 
2825 	QCOW_TEST_ASSERT_EQUAL_INT64(
2826 	 "offset",
2827 	 offset,
2828 	 (int64_t) ( size + 512 ) );
2829 
2830 	QCOW_TEST_ASSERT_IS_NULL(
2831 	 "error",
2832 	 error );
2833 
2834 	/* Reset offset to 0
2835 	 */
2836 	offset = libqcow_file_seek_offset(
2837 	          file,
2838 	          0,
2839 	          SEEK_SET,
2840 	          &error );
2841 
2842 	QCOW_TEST_ASSERT_EQUAL_INT64(
2843 	 "offset",
2844 	 offset,
2845 	 (int64_t) 0 );
2846 
2847 	QCOW_TEST_ASSERT_IS_NULL(
2848 	 "error",
2849 	 error );
2850 
2851 	/* Test error cases
2852 	 */
2853 	offset = libqcow_file_seek_offset(
2854 	          NULL,
2855 	          0,
2856 	          SEEK_SET,
2857 	          &error );
2858 
2859 	QCOW_TEST_ASSERT_EQUAL_INT64(
2860 	 "offset",
2861 	 offset,
2862 	 (int64_t) -1 );
2863 
2864 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2865 	 "error",
2866 	 error );
2867 
2868 	libcerror_error_free(
2869 	 &error );
2870 
2871 	offset = libqcow_file_seek_offset(
2872 	          file,
2873 	          -1,
2874 	          SEEK_SET,
2875 	          &error );
2876 
2877 	QCOW_TEST_ASSERT_EQUAL_INT64(
2878 	 "offset",
2879 	 offset,
2880 	 (int64_t) -1 );
2881 
2882 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2883 	 "error",
2884 	 error );
2885 
2886 	libcerror_error_free(
2887 	 &error );
2888 
2889 	offset = libqcow_file_seek_offset(
2890 	          file,
2891 	          -1,
2892 	          SEEK_CUR,
2893 	          &error );
2894 
2895 	QCOW_TEST_ASSERT_EQUAL_INT64(
2896 	 "offset",
2897 	 offset,
2898 	 (int64_t) -1 );
2899 
2900 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2901 	 "error",
2902 	 error );
2903 
2904 	offset = libqcow_file_seek_offset(
2905 	          file,
2906 	          (off64_t) ( -1 * ( size + 1 ) ),
2907 	          SEEK_END,
2908 	          &error );
2909 
2910 	QCOW_TEST_ASSERT_EQUAL_INT64(
2911 	 "offset",
2912 	 offset,
2913 	 (int64_t) -1 );
2914 
2915 	QCOW_TEST_ASSERT_IS_NOT_NULL(
2916 	 "error",
2917 	 error );
2918 
2919 	libcerror_error_free(
2920 	 &error );
2921 
2922 #if defined( HAVE_QCOW_TEST_RWLOCK )
2923 
2924 	/* Test libqcow_file_seek_offset with pthread_rwlock_wrlock failing in libcthreads_read_write_lock_grab_for_write
2925 	 */
2926 	qcow_test_pthread_rwlock_wrlock_attempts_before_fail = 0;
2927 
2928 	offset = libqcow_file_seek_offset(
2929 	          file,
2930 	          0,
2931 	          SEEK_SET,
2932 	          &error );
2933 
2934 	if( qcow_test_pthread_rwlock_wrlock_attempts_before_fail != -1 )
2935 	{
2936 		qcow_test_pthread_rwlock_wrlock_attempts_before_fail = -1;
2937 	}
2938 	else
2939 	{
2940 		QCOW_TEST_ASSERT_EQUAL_INT64(
2941 		 "offset",
2942 		 (int64_t) offset,
2943 		 (int64_t) -1 );
2944 
2945 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2946 		 "error",
2947 		 error );
2948 
2949 		libcerror_error_free(
2950 		 &error );
2951 	}
2952 	/* Test libqcow_file_seek_offset with pthread_rwlock_unlock failing in libcthreads_read_write_lock_release_for_write
2953 	 */
2954 	qcow_test_pthread_rwlock_unlock_attempts_before_fail = 0;
2955 
2956 	offset = libqcow_file_seek_offset(
2957 	          file,
2958 	          0,
2959 	          SEEK_SET,
2960 	          &error );
2961 
2962 	if( qcow_test_pthread_rwlock_unlock_attempts_before_fail != -1 )
2963 	{
2964 		qcow_test_pthread_rwlock_unlock_attempts_before_fail = -1;
2965 	}
2966 	else
2967 	{
2968 		QCOW_TEST_ASSERT_EQUAL_INT64(
2969 		 "offset",
2970 		 (int64_t) offset,
2971 		 (int64_t) -1 );
2972 
2973 		QCOW_TEST_ASSERT_IS_NOT_NULL(
2974 		 "error",
2975 		 error );
2976 
2977 		libcerror_error_free(
2978 		 &error );
2979 	}
2980 #endif /* defined( HAVE_QCOW_TEST_RWLOCK ) */
2981 
2982 	return( 1 );
2983 
2984 on_error:
2985 	if( error != NULL )
2986 	{
2987 		libcerror_error_free(
2988 		 &error );
2989 	}
2990 	return( 0 );
2991 }
2992 
2993 /* Tests the libqcow_file_get_offset function
2994  * Returns 1 if successful or 0 if not
2995  */
qcow_test_file_get_offset(libqcow_file_t * file)2996 int qcow_test_file_get_offset(
2997      libqcow_file_t *file )
2998 {
2999 	libcerror_error_t *error = NULL;
3000 	off64_t offset           = 0;
3001 	int result               = 0;
3002 
3003 	/* Test regular cases
3004 	 */
3005 	result = libqcow_file_get_offset(
3006 	          file,
3007 	          &offset,
3008 	          &error );
3009 
3010 	QCOW_TEST_ASSERT_EQUAL_INT(
3011 	 "result",
3012 	 result,
3013 	 1 );
3014 
3015 	QCOW_TEST_ASSERT_IS_NULL(
3016 	 "error",
3017 	 error );
3018 
3019 	/* Test error cases
3020 	 */
3021 	result = libqcow_file_get_offset(
3022 	          NULL,
3023 	          &offset,
3024 	          &error );
3025 
3026 	QCOW_TEST_ASSERT_EQUAL_INT(
3027 	 "result",
3028 	 result,
3029 	 -1 );
3030 
3031 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3032 	 "error",
3033 	 error );
3034 
3035 	libcerror_error_free(
3036 	 &error );
3037 
3038 	result = libqcow_file_get_offset(
3039 	          file,
3040 	          NULL,
3041 	          &error );
3042 
3043 	QCOW_TEST_ASSERT_EQUAL_INT(
3044 	 "result",
3045 	 result,
3046 	 -1 );
3047 
3048 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3049 	 "error",
3050 	 error );
3051 
3052 	libcerror_error_free(
3053 	 &error );
3054 
3055 #if defined( HAVE_QCOW_TEST_RWLOCK )
3056 
3057 	/* Test libqcow_file_get_offset with pthread_rwlock_rdlock failing in libcthreads_read_write_lock_grab_for_read
3058 	 */
3059 	qcow_test_pthread_rwlock_rdlock_attempts_before_fail = 0;
3060 
3061 	result = libqcow_file_get_offset(
3062 	          file,
3063 	          &offset,
3064 	          &error );
3065 
3066 	if( qcow_test_pthread_rwlock_rdlock_attempts_before_fail != -1 )
3067 	{
3068 		qcow_test_pthread_rwlock_rdlock_attempts_before_fail = -1;
3069 	}
3070 	else
3071 	{
3072 		QCOW_TEST_ASSERT_EQUAL_INT(
3073 		 "result",
3074 		 result,
3075 		 -1 );
3076 
3077 		QCOW_TEST_ASSERT_IS_NOT_NULL(
3078 		 "error",
3079 		 error );
3080 
3081 		libcerror_error_free(
3082 		 &error );
3083 	}
3084 	/* Test libqcow_file_get_offset with pthread_rwlock_unlock failing in libcthreads_read_write_lock_release_for_read
3085 	 */
3086 	qcow_test_pthread_rwlock_unlock_attempts_before_fail = 0;
3087 
3088 	result = libqcow_file_get_offset(
3089 	          file,
3090 	          &offset,
3091 	          &error );
3092 
3093 	if( qcow_test_pthread_rwlock_unlock_attempts_before_fail != -1 )
3094 	{
3095 		qcow_test_pthread_rwlock_unlock_attempts_before_fail = -1;
3096 	}
3097 	else
3098 	{
3099 		QCOW_TEST_ASSERT_EQUAL_INT(
3100 		 "result",
3101 		 result,
3102 		 -1 );
3103 
3104 		QCOW_TEST_ASSERT_IS_NOT_NULL(
3105 		 "error",
3106 		 error );
3107 
3108 		libcerror_error_free(
3109 		 &error );
3110 	}
3111 #endif /* defined( HAVE_QCOW_TEST_RWLOCK ) */
3112 
3113 	return( 1 );
3114 
3115 on_error:
3116 	if( error != NULL )
3117 	{
3118 		libcerror_error_free(
3119 		 &error );
3120 	}
3121 	return( 0 );
3122 }
3123 
3124 /* Tests the libqcow_file_get_media_size function
3125  * Returns 1 if successful or 0 if not
3126  */
qcow_test_file_get_media_size(libqcow_file_t * file)3127 int qcow_test_file_get_media_size(
3128      libqcow_file_t *file )
3129 {
3130 	libcerror_error_t *error = NULL;
3131 	size64_t media_size      = 0;
3132 	int result               = 0;
3133 
3134 	/* Test regular cases
3135 	 */
3136 	result = libqcow_file_get_media_size(
3137 	          file,
3138 	          &media_size,
3139 	          &error );
3140 
3141 	QCOW_TEST_ASSERT_EQUAL_INT(
3142 	 "result",
3143 	 result,
3144 	 1 );
3145 
3146 	QCOW_TEST_ASSERT_IS_NULL(
3147 	 "error",
3148 	 error );
3149 
3150 	/* Test error cases
3151 	 */
3152 	result = libqcow_file_get_media_size(
3153 	          NULL,
3154 	          &media_size,
3155 	          &error );
3156 
3157 	QCOW_TEST_ASSERT_EQUAL_INT(
3158 	 "result",
3159 	 result,
3160 	 -1 );
3161 
3162 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3163 	 "error",
3164 	 error );
3165 
3166 	libcerror_error_free(
3167 	 &error );
3168 
3169 	result = libqcow_file_get_media_size(
3170 	          file,
3171 	          NULL,
3172 	          &error );
3173 
3174 	QCOW_TEST_ASSERT_EQUAL_INT(
3175 	 "result",
3176 	 result,
3177 	 -1 );
3178 
3179 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3180 	 "error",
3181 	 error );
3182 
3183 	libcerror_error_free(
3184 	 &error );
3185 
3186 #if defined( HAVE_QCOW_TEST_RWLOCK )
3187 
3188 	/* Test libqcow_file_get_media_size with pthread_rwlock_rdlock failing in libcthreads_read_write_lock_grab_for_read
3189 	 */
3190 	qcow_test_pthread_rwlock_rdlock_attempts_before_fail = 0;
3191 
3192 	result = libqcow_file_get_media_size(
3193 	          file,
3194 	          &media_size,
3195 	          &error );
3196 
3197 	if( qcow_test_pthread_rwlock_rdlock_attempts_before_fail != -1 )
3198 	{
3199 		qcow_test_pthread_rwlock_rdlock_attempts_before_fail = -1;
3200 	}
3201 	else
3202 	{
3203 		QCOW_TEST_ASSERT_EQUAL_INT(
3204 		 "result",
3205 		 result,
3206 		 -1 );
3207 
3208 		QCOW_TEST_ASSERT_IS_NOT_NULL(
3209 		 "error",
3210 		 error );
3211 
3212 		libcerror_error_free(
3213 		 &error );
3214 	}
3215 	/* Test libqcow_file_get_media_size with pthread_rwlock_unlock failing in libcthreads_read_write_lock_release_for_read
3216 	 */
3217 	qcow_test_pthread_rwlock_unlock_attempts_before_fail = 0;
3218 
3219 	result = libqcow_file_get_media_size(
3220 	          file,
3221 	          &media_size,
3222 	          &error );
3223 
3224 	if( qcow_test_pthread_rwlock_unlock_attempts_before_fail != -1 )
3225 	{
3226 		qcow_test_pthread_rwlock_unlock_attempts_before_fail = -1;
3227 	}
3228 	else
3229 	{
3230 		QCOW_TEST_ASSERT_EQUAL_INT(
3231 		 "result",
3232 		 result,
3233 		 -1 );
3234 
3235 		QCOW_TEST_ASSERT_IS_NOT_NULL(
3236 		 "error",
3237 		 error );
3238 
3239 		libcerror_error_free(
3240 		 &error );
3241 	}
3242 #endif /* defined( HAVE_QCOW_TEST_RWLOCK ) */
3243 
3244 	return( 1 );
3245 
3246 on_error:
3247 	if( error != NULL )
3248 	{
3249 		libcerror_error_free(
3250 		 &error );
3251 	}
3252 	return( 0 );
3253 }
3254 
3255 /* Tests the libqcow_file_get_format_version function
3256  * Returns 1 if successful or 0 if not
3257  */
qcow_test_file_get_format_version(libqcow_file_t * file)3258 int qcow_test_file_get_format_version(
3259      libqcow_file_t *file )
3260 {
3261 	libcerror_error_t *error = NULL;
3262 	uint32_t format_version  = 0;
3263 	int result               = 0;
3264 
3265 	/* Test regular cases
3266 	 */
3267 	result = libqcow_file_get_format_version(
3268 	          file,
3269 	          &format_version,
3270 	          &error );
3271 
3272 	QCOW_TEST_ASSERT_EQUAL_INT(
3273 	 "result",
3274 	 result,
3275 	 1 );
3276 
3277 	QCOW_TEST_ASSERT_IS_NULL(
3278 	 "error",
3279 	 error );
3280 
3281 	/* Test error cases
3282 	 */
3283 	result = libqcow_file_get_format_version(
3284 	          NULL,
3285 	          &format_version,
3286 	          &error );
3287 
3288 	QCOW_TEST_ASSERT_EQUAL_INT(
3289 	 "result",
3290 	 result,
3291 	 -1 );
3292 
3293 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3294 	 "error",
3295 	 error );
3296 
3297 	libcerror_error_free(
3298 	 &error );
3299 
3300 	result = libqcow_file_get_format_version(
3301 	          file,
3302 	          NULL,
3303 	          &error );
3304 
3305 	QCOW_TEST_ASSERT_EQUAL_INT(
3306 	 "result",
3307 	 result,
3308 	 -1 );
3309 
3310 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3311 	 "error",
3312 	 error );
3313 
3314 	libcerror_error_free(
3315 	 &error );
3316 
3317 	return( 1 );
3318 
3319 on_error:
3320 	if( error != NULL )
3321 	{
3322 		libcerror_error_free(
3323 		 &error );
3324 	}
3325 	return( 0 );
3326 }
3327 
3328 /* Tests the libqcow_file_get_encryption_method function
3329  * Returns 1 if successful or 0 if not
3330  */
qcow_test_file_get_encryption_method(libqcow_file_t * file)3331 int qcow_test_file_get_encryption_method(
3332      libqcow_file_t *file )
3333 {
3334 	libcerror_error_t *error   = NULL;
3335 	uint32_t encryption_method = 0;
3336 	int result                 = 0;
3337 
3338 	/* Test regular cases
3339 	 */
3340 	result = libqcow_file_get_encryption_method(
3341 	          file,
3342 	          &encryption_method,
3343 	          &error );
3344 
3345 	QCOW_TEST_ASSERT_EQUAL_INT(
3346 	 "result",
3347 	 result,
3348 	 1 );
3349 
3350 	QCOW_TEST_ASSERT_IS_NULL(
3351 	 "error",
3352 	 error );
3353 
3354 	/* Test error cases
3355 	 */
3356 	result = libqcow_file_get_encryption_method(
3357 	          NULL,
3358 	          &encryption_method,
3359 	          &error );
3360 
3361 	QCOW_TEST_ASSERT_EQUAL_INT(
3362 	 "result",
3363 	 result,
3364 	 -1 );
3365 
3366 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3367 	 "error",
3368 	 error );
3369 
3370 	libcerror_error_free(
3371 	 &error );
3372 
3373 	result = libqcow_file_get_encryption_method(
3374 	          file,
3375 	          NULL,
3376 	          &error );
3377 
3378 	QCOW_TEST_ASSERT_EQUAL_INT(
3379 	 "result",
3380 	 result,
3381 	 -1 );
3382 
3383 	QCOW_TEST_ASSERT_IS_NOT_NULL(
3384 	 "error",
3385 	 error );
3386 
3387 	libcerror_error_free(
3388 	 &error );
3389 
3390 	return( 1 );
3391 
3392 on_error:
3393 	if( error != NULL )
3394 	{
3395 		libcerror_error_free(
3396 		 &error );
3397 	}
3398 	return( 0 );
3399 }
3400 
3401 /* The main program
3402  */
3403 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
wmain(int argc,wchar_t * const argv[])3404 int wmain(
3405      int argc,
3406      wchar_t * const argv[] )
3407 #else
3408 int main(
3409      int argc,
3410      char * const argv[] )
3411 #endif
3412 {
3413 	libbfio_handle_t *file_io_handle    = NULL;
3414 	libcerror_error_t *error            = NULL;
3415 	libqcow_file_t *parent_file        = NULL;
3416 	libqcow_file_t *file                = NULL;
3417 	system_character_t *option_password = NULL;
3418 	system_character_t *source          = NULL;
3419 	system_integer_t option             = 0;
3420 	size_t string_length                = 0;
3421 	int result                          = 0;
3422 
3423 	while( ( option = qcow_test_getopt(
3424 	                   argc,
3425 	                   argv,
3426 	                   _SYSTEM_STRING( "p:" ) ) ) != (system_integer_t) -1 )
3427 	{
3428 		switch( option )
3429 		{
3430 			case (system_integer_t) '?':
3431 			default:
3432 				fprintf(
3433 				 stderr,
3434 				 "Invalid argument: %" PRIs_SYSTEM ".\n",
3435 				 argv[ optind - 1 ] );
3436 
3437 				return( EXIT_FAILURE );
3438 
3439 			case (system_integer_t) 'p':
3440 				option_password = optarg;
3441 
3442 				break;
3443 		}
3444 	}
3445 	if( optind < argc )
3446 	{
3447 		source = argv[ optind ];
3448 	}
3449 #if defined( HAVE_DEBUG_OUTPUT ) && defined( QCOW_TEST_FILE_VERBOSE )
3450 	libqcow_notify_set_verbose(
3451 	 1 );
3452 	libqcow_notify_set_stream(
3453 	 stderr,
3454 	 NULL );
3455 #endif
3456 
3457 	QCOW_TEST_RUN(
3458 	 "libqcow_file_initialize",
3459 	 qcow_test_file_initialize );
3460 
3461 	QCOW_TEST_RUN(
3462 	 "libqcow_file_free",
3463 	 qcow_test_file_free );
3464 
3465 #if !defined( __BORLANDC__ ) || ( __BORLANDC__ >= 0x0560 )
3466 	if( source != NULL )
3467 	{
3468 		result = libbfio_file_initialize(
3469 		          &file_io_handle,
3470 		          &error );
3471 
3472 		QCOW_TEST_ASSERT_EQUAL_INT(
3473 		 "result",
3474 		 result,
3475 		 1 );
3476 
3477 	        QCOW_TEST_ASSERT_IS_NOT_NULL(
3478 	         "file_io_handle",
3479 	         file_io_handle );
3480 
3481 	        QCOW_TEST_ASSERT_IS_NULL(
3482 	         "error",
3483 	         error );
3484 
3485 		string_length = system_string_length(
3486 		                 source );
3487 
3488 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
3489 		result = libbfio_file_set_name_wide(
3490 		          file_io_handle,
3491 		          source,
3492 		          string_length,
3493 		          &error );
3494 #else
3495 		result = libbfio_file_set_name(
3496 		          file_io_handle,
3497 		          source,
3498 		          string_length,
3499 		          &error );
3500 #endif
3501 		QCOW_TEST_ASSERT_EQUAL_INT(
3502 		 "result",
3503 		 result,
3504 		 1 );
3505 
3506 	        QCOW_TEST_ASSERT_IS_NULL(
3507 	         "error",
3508 	         error );
3509 
3510 		result = libqcow_check_file_signature_file_io_handle(
3511 		          file_io_handle,
3512 		          &error );
3513 
3514 		QCOW_TEST_ASSERT_NOT_EQUAL_INT(
3515 		 "result",
3516 		 result,
3517 		 -1 );
3518 
3519 		QCOW_TEST_ASSERT_IS_NULL(
3520 		 "error",
3521 		 error );
3522 	}
3523 	if( result != 0 )
3524 	{
3525 		QCOW_TEST_RUN_WITH_ARGS(
3526 		 "libqcow_file_open",
3527 		 qcow_test_file_open,
3528 		 source,
3529 		 option_password );
3530 
3531 #if defined( HAVE_WIDE_CHARACTER_TYPE )
3532 
3533 		QCOW_TEST_RUN_WITH_ARGS(
3534 		 "libqcow_file_open_wide",
3535 		 qcow_test_file_open_wide,
3536 		 source,
3537 		 option_password );
3538 
3539 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
3540 
3541 		QCOW_TEST_RUN_WITH_ARGS(
3542 		 "libqcow_file_open_file_io_handle",
3543 		 qcow_test_file_open_file_io_handle,
3544 		 source,
3545 		 option_password );
3546 
3547 		QCOW_TEST_RUN(
3548 		 "libqcow_file_close",
3549 		 qcow_test_file_close );
3550 
3551 		QCOW_TEST_RUN_WITH_ARGS(
3552 		 "libqcow_file_open_close",
3553 		 qcow_test_file_open_close,
3554 		 source,
3555 		 option_password );
3556 
3557 		/* Initialize file for tests
3558 		 */
3559 		result = qcow_test_file_open_source(
3560 		          &file,
3561 		          file_io_handle,
3562 		          option_password,
3563 		          &error );
3564 
3565 		QCOW_TEST_ASSERT_EQUAL_INT(
3566 		 "result",
3567 		 result,
3568 		 1 );
3569 
3570 		QCOW_TEST_ASSERT_IS_NOT_NULL(
3571 		 "file",
3572 		 file );
3573 
3574 		QCOW_TEST_ASSERT_IS_NULL(
3575 		 "error",
3576 		 error );
3577 
3578 		result = qcow_test_file_open_parent_file(
3579 		          &parent_file,
3580 		          source,
3581 		          file,
3582 		          &error );
3583 
3584 		QCOW_TEST_ASSERT_NOT_EQUAL_INT(
3585 		 "result",
3586 		 result,
3587 		 -1 );
3588 
3589 	        QCOW_TEST_ASSERT_IS_NULL(
3590 	         "error",
3591 	         error );
3592 
3593 		QCOW_TEST_RUN_WITH_ARGS(
3594 		 "libqcow_file_signal_abort",
3595 		 qcow_test_file_signal_abort,
3596 		 file );
3597 
3598 #if defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT )
3599 
3600 		/* TODO: add tests for libqcow_internal_file_open_read */
3601 
3602 #endif /* defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT ) */
3603 
3604 		QCOW_TEST_RUN_WITH_ARGS(
3605 		 "libqcow_file_is_locked",
3606 		 qcow_test_file_is_locked,
3607 		 file );
3608 
3609 #if defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT )
3610 
3611 		QCOW_TEST_RUN_WITH_ARGS(
3612 		 "libqcow_internal_file_read_buffer_from_file_io_handle",
3613 		 qcow_test_internal_file_read_buffer_from_file_io_handle,
3614 		 file );
3615 
3616 #endif /* defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT ) */
3617 
3618 		QCOW_TEST_RUN_WITH_ARGS(
3619 		 "libqcow_file_read_buffer",
3620 		 qcow_test_file_read_buffer,
3621 		 file );
3622 
3623 		QCOW_TEST_RUN_WITH_ARGS(
3624 		 "libqcow_file_read_buffer_at_offset",
3625 		 qcow_test_file_read_buffer_at_offset,
3626 		 file );
3627 
3628 #if defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT )
3629 
3630 		/* TODO: add tests for libqcow_internal_file_write_buffer_to_file_io_handle */
3631 
3632 #endif /* defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT ) */
3633 
3634 		/* TODO: add tests for libqcow_file_write_buffer */
3635 
3636 		/* TODO: add tests for libqcow_file_write_buffer_at_offset */
3637 
3638 #if defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT )
3639 
3640 		/* TODO: add tests for libqcow_internal_file_seek_offset */
3641 
3642 #endif /* defined( __GNUC__ ) && !defined( LIBQCOW_DLL_IMPORT ) */
3643 
3644 		QCOW_TEST_RUN_WITH_ARGS(
3645 		 "libqcow_file_seek_offset",
3646 		 qcow_test_file_seek_offset,
3647 		 file );
3648 
3649 		QCOW_TEST_RUN_WITH_ARGS(
3650 		 "libqcow_file_get_offset",
3651 		 qcow_test_file_get_offset,
3652 		 file );
3653 
3654 		/* TODO: add tests for libqcow_file_set_keys */
3655 
3656 		/* TODO: add tests for libqcow_file_set_utf8_password */
3657 
3658 		/* TODO: add tests for libqcow_file_set_utf16_password */
3659 
3660 		QCOW_TEST_RUN_WITH_ARGS(
3661 		 "libqcow_file_get_media_size",
3662 		 qcow_test_file_get_media_size,
3663 		 file );
3664 
3665 		QCOW_TEST_RUN_WITH_ARGS(
3666 		 "libqcow_file_get_format_version",
3667 		 qcow_test_file_get_format_version,
3668 		 file );
3669 
3670 		QCOW_TEST_RUN_WITH_ARGS(
3671 		 "libqcow_file_get_encryption_method",
3672 		 qcow_test_file_get_encryption_method,
3673 		 file );
3674 
3675 		/* Clean up
3676 		 */
3677 		result = qcow_test_file_close_source(
3678 		          &file,
3679 		          &error );
3680 
3681 		QCOW_TEST_ASSERT_EQUAL_INT(
3682 		 "result",
3683 		 result,
3684 		 0 );
3685 
3686 		QCOW_TEST_ASSERT_IS_NULL(
3687 		 "file",
3688 		 file );
3689 
3690 		QCOW_TEST_ASSERT_IS_NULL(
3691 		 "error",
3692 		 error );
3693 
3694 		if( parent_file != NULL )
3695 		{
3696 			result = qcow_test_file_close_source(
3697 			          &parent_file,
3698 			          &error );
3699 
3700 			QCOW_TEST_ASSERT_EQUAL_INT(
3701 			 "result",
3702 			 result,
3703 			 0 );
3704 
3705 		        QCOW_TEST_ASSERT_IS_NULL(
3706 		         "error",
3707 		         error );
3708 		}
3709 	}
3710 	if( file_io_handle != NULL )
3711 	{
3712 		result = libbfio_handle_free(
3713 		          &file_io_handle,
3714 		          &error );
3715 
3716 		QCOW_TEST_ASSERT_EQUAL_INT(
3717 		 "result",
3718 		 result,
3719 		 1 );
3720 
3721 		QCOW_TEST_ASSERT_IS_NULL(
3722 	         "file_io_handle",
3723 	         file_io_handle );
3724 
3725 	        QCOW_TEST_ASSERT_IS_NULL(
3726 	         "error",
3727 	         error );
3728 	}
3729 #endif /* !defined( __BORLANDC__ ) || ( __BORLANDC__ >= 0x0560 ) */
3730 
3731 	return( EXIT_SUCCESS );
3732 
3733 on_error:
3734 	if( error != NULL )
3735 	{
3736 		libcerror_error_free(
3737 		 &error );
3738 	}
3739 	if( file != NULL )
3740 	{
3741 		libqcow_file_free(
3742 		 &file,
3743 		 NULL );
3744 	}
3745 	if( file_io_handle != NULL )
3746 	{
3747 		libbfio_handle_free(
3748 		 &file_io_handle,
3749 		 NULL );
3750 	}
3751 	if( parent_file != NULL )
3752 	{
3753 		qcow_test_file_close_source(
3754 		 &parent_file,
3755 		 NULL );
3756 	}
3757 	return( EXIT_FAILURE );
3758 }
3759 
3760