mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[bb] fix bad blocks check for 64 bit
* 32 bit bad blocks check is too limited for large drives and result in erroneous computations * 32 bit also means that 2TB would be absolute limit, which may be too low in case for USB HDD checks * This fix makes bad blocks check and related calls 64 bit compliant * also improve on bad block reports
This commit is contained in:
		
							parent
							
								
									3721b0a570
								
							
						
					
					
						commit
						a9c47a4922
					
				
					 6 changed files with 194 additions and 161 deletions
				
			
		
							
								
								
									
										152
									
								
								src/badblocks.c
									
										
									
									
									
								
							
							
						
						
									
										152
									
								
								src/badblocks.c
									
										
									
									
									
								
							|  | @ -39,6 +39,7 @@ | |||
| #include <time.h> | ||||
| #include <setjmp.h> | ||||
| #include <windows.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "badblocks.h" | ||||
|  | @ -47,6 +48,7 @@ | |||
| 
 | ||||
| FILE* log_fd = NULL; | ||||
| static const char* abort_msg = "Too many bad blocks, aborting test\n"; | ||||
| static const char* bb_prefix = "Bad Blocks: "; | ||||
| 
 | ||||
| /*
 | ||||
|  *From e2fsprogs/lib/ext2fs/badblocks.c | ||||
|  | @ -55,35 +57,35 @@ static const char* abort_msg = "Too many bad blocks, aborting test\n"; | |||
| /*
 | ||||
|  * Badblocks list | ||||
|  */ | ||||
| struct ext2_struct_u32_list { | ||||
| struct bb_struct_u64_list { | ||||
| 	int   magic; | ||||
| 	int   num; | ||||
| 	int   size; | ||||
| 	__u32 *list; | ||||
| 	uint64_t *list; | ||||
| 	int   badblocks_flags; | ||||
| }; | ||||
| 
 | ||||
| struct ext2_struct_u32_iterate { | ||||
| struct bb_struct_u64_iterate { | ||||
| 	int         magic; | ||||
| 	ext2_u32_list bb; | ||||
| 	bb_u64_list bb; | ||||
| 	int         ptr; | ||||
| }; | ||||
| 
 | ||||
| static errcode_t make_u32_list(int size, int num, __u32 *list, ext2_u32_list *ret) | ||||
| static errcode_t make_u64_list(int size, int num, uint64_t *list, bb_u64_list *ret) | ||||
| { | ||||
| 	ext2_u32_list	bb; | ||||
| 	bb_u64_list bb; | ||||
| 
 | ||||
| 	bb = calloc(1, sizeof(struct ext2_struct_u32_list)); | ||||
| 	bb = calloc(1, sizeof(struct bb_struct_u64_list)); | ||||
| 	if (bb == NULL) | ||||
| 		return EXT2_ET_NO_MEMORY; | ||||
| 	bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST; | ||||
| 		return BB_ET_NO_MEMORY; | ||||
| 	bb->magic = BB_ET_MAGIC_BADBLOCKS_LIST; | ||||
| 	bb->size = size ? size : 10; | ||||
| 	bb->num = num; | ||||
| 	bb->list = malloc(sizeof(blk_t) * bb->size); | ||||
| 	if (bb->list == NULL) { | ||||
| 		free(bb); | ||||
| 		bb = NULL; | ||||
| 		return EXT2_ET_NO_MEMORY; | ||||
| 		return BB_ET_NO_MEMORY; | ||||
| 	} | ||||
| 	if (list) | ||||
| 		memcpy(bb->list, list, bb->size * sizeof(blk_t)); | ||||
|  | @ -96,28 +98,28 @@ static errcode_t make_u32_list(int size, int num, __u32 *list, ext2_u32_list *re | |||
| /*
 | ||||
|  * This procedure creates an empty badblocks list. | ||||
|  */ | ||||
| static errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size) | ||||
| static errcode_t bb_badblocks_list_create(bb_badblocks_list *ret, int size) | ||||
| { | ||||
| 	return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret); | ||||
| 	return make_u64_list(size, 0, 0, (bb_badblocks_list *) ret); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This procedure adds a block to a badblocks list. | ||||
|  */ | ||||
| static errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk) | ||||
| static errcode_t bb_u64_list_add(bb_u64_list bb, uint64_t blk) | ||||
| { | ||||
| 	int		i, j; | ||||
| 	__u32* old_bb_list = bb->list; | ||||
| 	uint64_t* old_bb_list = bb->list; | ||||
| 
 | ||||
| 	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST); | ||||
| 	BB_CHECK_MAGIC(bb, BB_ET_MAGIC_BADBLOCKS_LIST); | ||||
| 
 | ||||
| 	if (bb->num >= bb->size) { | ||||
| 		bb->size += 100; | ||||
| 		bb->list = realloc(bb->list, bb->size * sizeof(__u32)); | ||||
| 		bb->list = realloc(bb->list, bb->size * sizeof(uint64_t)); | ||||
| 		if (bb->list == NULL) { | ||||
| 			bb->list = old_bb_list; | ||||
| 			bb->size -= 100; | ||||
| 			return EXT2_ET_NO_MEMORY; | ||||
| 			return BB_ET_NO_MEMORY; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -148,20 +150,20 @@ static errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk) | ||||
| static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk_t blk) | ||||
| { | ||||
| 	return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk); | ||||
| 	return bb_u64_list_add((bb_u64_list) bb, blk); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This procedure finds a particular block is on a badblocks | ||||
|  * list. | ||||
|  */ | ||||
| static int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk) | ||||
| static int bb_u64_list_find(bb_u64_list bb, uint64_t blk) | ||||
| { | ||||
| 	int	low, high, mid; | ||||
| 
 | ||||
| 	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) | ||||
| 	if (bb->magic != BB_ET_MAGIC_BADBLOCKS_LIST) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	if (bb->num == 0) | ||||
|  | @ -192,29 +194,29 @@ static int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk) | |||
|  * This procedure tests to see if a particular block is on a badblocks | ||||
|  * list. | ||||
|  */ | ||||
| static int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk) | ||||
| static int bb_u64_list_test(bb_u64_list bb, uint64_t blk) | ||||
| { | ||||
| 	if (ext2fs_u32_list_find(bb, blk) < 0) | ||||
| 	if (bb_u64_list_find(bb, blk) < 0) | ||||
| 		return 0; | ||||
| 	else | ||||
| 		return 1; | ||||
| } | ||||
| 
 | ||||
| static int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk) | ||||
| static int bb_badblocks_list_test(bb_badblocks_list bb, blk_t blk) | ||||
| { | ||||
| 	return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk); | ||||
| 	return bb_u64_list_test((bb_u64_list) bb, blk); | ||||
| } | ||||
| 
 | ||||
| static int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk) | ||||
| static int bb_u64_list_iterate(bb_u64_iterate iter, uint64_t *blk) | ||||
| { | ||||
| 	ext2_u32_list	bb; | ||||
| 	bb_u64_list bb; | ||||
| 
 | ||||
| 	if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE) | ||||
| 	if (iter->magic != BB_ET_MAGIC_BADBLOCKS_ITERATE) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	bb = iter->bb; | ||||
| 
 | ||||
| 	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) | ||||
| 	if (bb->magic != BB_ET_MAGIC_BADBLOCKS_LIST) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (iter->ptr < bb->num) { | ||||
|  | @ -225,10 +227,9 @@ static int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk) | ||||
| static int bb_badblocks_list_iterate(bb_badblocks_iterate iter, blk_t *blk) | ||||
| { | ||||
| 	return ext2fs_u32_list_iterate((ext2_u32_iterate) iter, | ||||
| 				       (__u32 *) blk); | ||||
| 	return bb_u64_list_iterate((bb_u64_iterate) iter, blk); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -240,21 +241,21 @@ static int cancel_ops = 0;				/* abort current operation */ | |||
| static int cur_pattern, nr_pattern; | ||||
| static int cur_op; | ||||
| /* Abort test if more than this number of bad blocks has been encountered */ | ||||
| static unsigned int max_bb = EXT2_BAD_BLOCKS_THRESHOLD; | ||||
| static unsigned int max_bb = BB_BAD_BLOCKS_THRESHOLD; | ||||
| static blk_t currently_testing = 0; | ||||
| static blk_t num_blocks = 0; | ||||
| static blk_t num_read_errors = 0; | ||||
| static blk_t num_write_errors = 0; | ||||
| static blk_t num_corruption_errors = 0; | ||||
| static ext2_badblocks_list bb_list = NULL; | ||||
| static uint32_t num_read_errors = 0; | ||||
| static uint32_t num_write_errors = 0; | ||||
| static uint32_t num_corruption_errors = 0; | ||||
| static bb_badblocks_list bb_list = NULL; | ||||
| static blk_t next_bad = 0; | ||||
| static ext2_badblocks_iterate bb_iter = NULL; | ||||
| static bb_badblocks_iterate bb_iter = NULL; | ||||
| 
 | ||||
| static __inline void *allocate_buffer(size_t size) { | ||||
| #ifdef __MINGW32__ | ||||
| 	return __mingw_aligned_malloc(size, EXT2_SYS_PAGE_SIZE); | ||||
| 	return __mingw_aligned_malloc(size, BB_SYS_PAGE_SIZE); | ||||
| #else  | ||||
| 	return _aligned_malloc(size, EXT2_SYS_PAGE_SIZE); | ||||
| 	return _aligned_malloc(size, BB_SYS_PAGE_SIZE); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -274,17 +275,17 @@ static int bb_output (blk_t bad, enum error_types error_type) | |||
| { | ||||
| 	errcode_t error_code; | ||||
| 
 | ||||
| 	if (ext2fs_badblocks_list_test(bb_list, bad)) | ||||
| 	if (bb_badblocks_list_test(bb_list, bad)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	uprintf("%lu\n", (unsigned long) bad); | ||||
| 	uprintf("%s%lu\n", bb_prefix, (unsigned long)bad); | ||||
| 	fprintf(log_fd, "Block %lu: %s error\n", (unsigned long)bad, (error_type==READ_ERROR)?"read": | ||||
| 		((error_type == WRITE_ERROR)?"write":"corruption")); | ||||
| 	fflush(log_fd); | ||||
| 
 | ||||
| 	error_code = ext2fs_badblocks_list_add(bb_list, bad); | ||||
| 	error_code = bb_badblocks_list_add(bb_list, bad); | ||||
| 	if (error_code) { | ||||
| 		uprintf("Error %d adding to in-memory bad block list", error_code); | ||||
| 		uprintf("%sError %d adding to in-memory bad block list", bb_prefix, error_code); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -293,7 +294,7 @@ static int bb_output (blk_t bad, enum error_types error_type) | |||
| 	   an element was just added before the current iteration | ||||
| 	   position.  This should not cause next_bad to change. */ | ||||
| 	if (bb_iter && bad < next_bad) | ||||
| 		ext2fs_badblocks_list_iterate (bb_iter, &next_bad); | ||||
| 		bb_badblocks_list_iterate (bb_iter, &next_bad); | ||||
| 
 | ||||
| 	if (error_type == READ_ERROR) { | ||||
| 	  num_read_errors++; | ||||
|  | @ -338,7 +339,7 @@ static void CALLBACK alarm_intr(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dw | |||
| 	if (!num_blocks) | ||||
| 		return; | ||||
| 	if (FormatStatus) { | ||||
| 		uprintf("Interrupting at block %llu\n",  | ||||
| 		uprintf("%sInterrupting at block %llu\n", bb_prefix, | ||||
| 			(unsigned long long) currently_testing); | ||||
| 		cancel_ops = -1; | ||||
| 	} | ||||
|  | @ -355,7 +356,7 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, | |||
| 		for (ptr = buffer; ptr < buffer + n; ptr++) { | ||||
| 			(*ptr) = rand() % (1 << (8 * sizeof(char))); | ||||
| 		} | ||||
| 		PrintStatus(3500, TRUE, "Bad Blocks: Testing with random pattern."); | ||||
| 		PrintStatus(3500, FALSE, "Bad Blocks: Testing with random pattern."); | ||||
| 	} else { | ||||
| 		bpattern[0] = 0; | ||||
| 		for (i = 0; i < sizeof(bpattern); i++) { | ||||
|  | @ -372,7 +373,7 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, | |||
| 			else | ||||
| 				i--; | ||||
| 		} | ||||
| 		PrintStatus(3500, TRUE, "Bad Blocks: Testing with pattern 0x%02X.", bpattern[i]); | ||||
| 		PrintStatus(3500, FALSE, "Bad Blocks: Testing with pattern 0x%02X.", bpattern[i]); | ||||
| 		cur_pattern++; | ||||
| 	} | ||||
| } | ||||
|  | @ -381,10 +382,10 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, | |||
|  * Perform a read of a sequence of blocks; return the number of blocks | ||||
|  *    successfully sequentially read. | ||||
|  */ | ||||
| static int do_read (HANDLE hDrive, unsigned char * buffer, int tryout, int block_size, | ||||
| static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size, | ||||
| 		    blk_t current_block) | ||||
| { | ||||
| 	long got; | ||||
| 	int64_t got; | ||||
| 
 | ||||
| 	if (v_flag > 1) | ||||
| 		print_status(); | ||||
|  | @ -394,7 +395,7 @@ static int do_read (HANDLE hDrive, unsigned char * buffer, int tryout, int block | |||
| 	if (got < 0) | ||||
| 		got = 0; | ||||
| 	if (got & 511) | ||||
| 		uprintf("Weird value (%ld) in do_read\n", got); | ||||
| 		uprintf("%sWeird value (%ld) in do_read\n", bb_prefix, got); | ||||
| 	got /= block_size; | ||||
| 	return got; | ||||
| } | ||||
|  | @ -403,10 +404,10 @@ static int do_read (HANDLE hDrive, unsigned char * buffer, int tryout, int block | |||
|  * Perform a write of a sequence of blocks; return the number of blocks | ||||
|  *    successfully sequentially written. | ||||
|  */ | ||||
| static int do_write(HANDLE hDrive, unsigned char * buffer, int tryout, int block_size, | ||||
| 		    unsigned long current_block) | ||||
| static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size, | ||||
| 		    blk_t current_block) | ||||
| { | ||||
| 	long got; | ||||
| 	int64_t got; | ||||
| 
 | ||||
| 	if (v_flag > 1) | ||||
| 		print_status(); | ||||
|  | @ -416,23 +417,23 @@ static int do_write(HANDLE hDrive, unsigned char * buffer, int tryout, int block | |||
| 	if (got < 0) | ||||
| 		got = 0; | ||||
| 	if (got & 511) | ||||
| 		uprintf("Weird value (%ld) in do_write\n", got); | ||||
| 		uprintf("%sWeird value (%ld) in do_write\n", bb_prefix, got); | ||||
| 	got /= block_size; | ||||
| 	return got; | ||||
| } | ||||
| 
 | ||||
| static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk_t first_block, | ||||
| 	unsigned int blocks_at_once, int nb_passes) | ||||
| static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block, | ||||
| 	size_t blocks_at_once, int nb_passes) | ||||
| { | ||||
| 	unsigned char *buffer = NULL, *read_buffer; | ||||
| 	const unsigned int pattern[] = {0xaa, 0x55, 0xff, 0x00}; | ||||
| 	int i, tryout, got, pat_idx; | ||||
| 	int i, pat_idx; | ||||
| 	unsigned int bb_count = 0; | ||||
| 	blk_t recover_block = ~0, *blk_id; | ||||
| 	blk_t got, tryout, recover_block = ~0, *blk_id; | ||||
| 	size_t id_offset; | ||||
| 
 | ||||
| 	if ((nb_passes < 1) || (nb_passes > 4)) { | ||||
| 		uprintf("Invalid number of passes\n"); | ||||
| 		uprintf("%sInvalid number of passes\n", bb_prefix); | ||||
| 		cancel_ops = -1; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | @ -441,13 +442,13 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 	read_buffer = buffer + blocks_at_once * block_size; | ||||
| 
 | ||||
| 	if (!buffer) { | ||||
| 		uprintf("Error while allocating buffers\n"); | ||||
| 		uprintf("%sError while allocating buffers\n", bb_prefix); | ||||
| 		cancel_ops = -1; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("Checking for bad blocks in read-write mode\n"); | ||||
| 	uprintf("From block %lu to %lu\n", (unsigned long) first_block, (unsigned long) last_block - 1); | ||||
| 	uprintf("%sChecking from block %lu to %lu\n", bb_prefix, | ||||
| 		(unsigned long) first_block, (unsigned long) last_block - 1); | ||||
| 	nr_pattern = nb_passes; | ||||
| 	cur_pattern = 0; | ||||
| 
 | ||||
|  | @ -456,14 +457,15 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 		srand((unsigned int)GetTickCount()); | ||||
| 		id_offset = rand()* (block_size-sizeof(blk_t)) / RAND_MAX; | ||||
| 		pattern_fill(buffer, pattern[pat_idx], blocks_at_once * block_size); | ||||
| 		uprintf("Block ID at offset: %d\n", id_offset); | ||||
| 		uprintf("%sBlock ID at offset: %d\n", bb_prefix, id_offset); | ||||
| 		num_blocks = last_block - 1; | ||||
| 		currently_testing = first_block; | ||||
| 		if (s_flag | v_flag) | ||||
| 			uprintf("Writing\n"); | ||||
| 			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pat_idx]); | ||||
| 		cur_op = OP_WRITE; | ||||
| 		tryout = blocks_at_once; | ||||
| 		while (currently_testing < last_block) { | ||||
| 			if (cancel_ops) goto out; | ||||
| 			if (max_bb && bb_count >= max_bb) { | ||||
| 				if (s_flag || v_flag) { | ||||
| 					uprintf(abort_msg); | ||||
|  | @ -471,9 +473,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 					fflush(log_fd); | ||||
| 				} | ||||
| 				cancel_ops = -1; | ||||
| 				break; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			if (cancel_ops) goto out; | ||||
| 			if (currently_testing + tryout > last_block) | ||||
| 				tryout = last_block - currently_testing; | ||||
| 			/* Add the block number at a fixed (random) offset during each pass to
 | ||||
|  | @ -503,7 +504,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 
 | ||||
| 		num_blocks = 0; | ||||
| 		if (s_flag | v_flag) | ||||
| 			uprintf("Reading and comparing\n"); | ||||
| 			uprintf("%sReading and comparing\n", bb_prefix); | ||||
| 		cur_op = OP_READ; | ||||
| 		num_blocks = last_block; | ||||
| 		currently_testing = first_block; | ||||
|  | @ -517,7 +518,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 					fprintf(log_fd, abort_msg); | ||||
| 					fflush(log_fd); | ||||
| 				} | ||||
| 				break; | ||||
| 				cancel_ops = -1; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			if (currently_testing + tryout > last_block) | ||||
| 				tryout = last_block - currently_testing; | ||||
|  | @ -544,7 +546,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk | |||
| 				if (memcmp(read_buffer + i * block_size, | ||||
| 					   buffer + i * block_size, | ||||
| 					   block_size)) | ||||
| 					bb_count += bb_output(currently_testing+i, CORRUPTION_ERROR); | ||||
| 					bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR); | ||||
| 			} | ||||
| 			if (v_flag > 1) | ||||
| 				print_status(); | ||||
|  | @ -557,11 +559,11 @@ out: | |||
| 	return bb_count; | ||||
| } | ||||
| 
 | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, size_t block_size, | ||||
| 	int nb_passes, badblocks_report *report, FILE* fd) | ||||
| { | ||||
| 	errcode_t error_code; | ||||
| 	blk_t first_block = 0, last_block = (blk_t)disk_size/block_size; | ||||
| 	blk_t first_block = 0, last_block = disk_size/block_size; | ||||
| 
 | ||||
| 	if (report == NULL) return FALSE; | ||||
| 	report->bb_count = 0; | ||||
|  | @ -571,16 +573,16 @@ BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, | |||
| 		log_fd = freopen(NULL, "w", stderr); | ||||
| 	} | ||||
| 
 | ||||
| 	error_code = ext2fs_badblocks_list_create(&bb_list, 0); | ||||
| 	error_code = bb_badblocks_list_create(&bb_list, 0); | ||||
| 	if (error_code) { | ||||
| 		uprintf("Error %d while creating in-memory bad blocks list", error_code); | ||||
| 		uprintf("%sError %d while creating in-memory bad blocks list", bb_prefix, error_code); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 
 | ||||
| 	cancel_ops = 0; | ||||
| 	/* use a timer to update status every second */ | ||||
| 	SetTimer(hMainDialog, TID_BADBLOCKS_UPDATE, 1000, alarm_intr); | ||||
| 	report->bb_count = test_rw(hPhysicalDrive, last_block, block_size, first_block, EXT2_BLOCKS_AT_ONCE, nb_passes); | ||||
| 	report->bb_count = test_rw(hPhysicalDrive, last_block, block_size, first_block, BB_BLOCKS_AT_ONCE, nb_passes); | ||||
| 	KillTimer(hMainDialog, TID_BADBLOCKS_UPDATE); | ||||
| 	free(bb_list->list); | ||||
| 	free(bb_list); | ||||
|  |  | |||
|  | @ -19,27 +19,25 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <windows.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #ifndef __u32 | ||||
| #define __u32  UINT32 | ||||
| #endif | ||||
| typedef UINT32 blk_t; | ||||
| typedef uint64_t blk_t; | ||||
| typedef DWORD    errcode_t; | ||||
| 
 | ||||
| typedef struct ext2_struct_u32_list         *ext2_badblocks_list; | ||||
| typedef struct ext2_struct_u32_iterate      *ext2_badblocks_iterate; | ||||
| typedef struct ext2_struct_u32_list         *ext2_u32_list; | ||||
| typedef struct ext2_struct_u32_iterate      *ext2_u32_iterate; | ||||
| typedef struct bb_struct_u64_list         *bb_badblocks_list; | ||||
| typedef struct bb_struct_u64_iterate      *bb_badblocks_iterate; | ||||
| typedef struct bb_struct_u64_list         *bb_u64_list; | ||||
| typedef struct bb_struct_u64_iterate      *bb_u64_iterate; | ||||
| 
 | ||||
| #define EXT2_ET_NO_MEMORY                   (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY) | ||||
| #define EXT2_ET_MAGIC_BADBLOCKS_LIST        (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OBJECT_IN_LIST) | ||||
| #define EXT2_ET_MAGIC_BADBLOCKS_ITERATE     (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_BLOCK) | ||||
| #define BB_ET_NO_MEMORY                   (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY) | ||||
| #define BB_ET_MAGIC_BADBLOCKS_LIST        (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OBJECT_IN_LIST) | ||||
| #define BB_ET_MAGIC_BADBLOCKS_ITERATE     (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_BLOCK) | ||||
| 
 | ||||
| #define EXT2_CHECK_MAGIC(struct, code) \ | ||||
| #define BB_CHECK_MAGIC(struct, code) \ | ||||
| 	if ((struct)->magic != (code)) return (code) | ||||
| #define EXT2_BAD_BLOCKS_THRESHOLD           256 | ||||
| #define EXT2_BLOCKS_AT_ONCE                 64 | ||||
| #define EXT2_SYS_PAGE_SIZE                  4096 | ||||
| #define BB_BAD_BLOCKS_THRESHOLD           256 | ||||
| #define BB_BLOCKS_AT_ONCE                 64 | ||||
| #define BB_SYS_PAGE_SIZE                  4096 | ||||
| 
 | ||||
| enum error_types { READ_ERROR, WRITE_ERROR, CORRUPTION_ERROR }; | ||||
| enum op_type { OP_READ, OP_WRITE }; | ||||
|  | @ -48,14 +46,14 @@ enum op_type { OP_READ, OP_WRITE }; | |||
|  * Badblocks report | ||||
|  */ | ||||
| typedef struct { | ||||
| 	blk_t bb_count; | ||||
| 	blk_t num_read_errors; | ||||
| 	blk_t num_write_errors; | ||||
| 	blk_t num_corruption_errors; | ||||
| 	uint32_t bb_count; | ||||
| 	uint32_t num_read_errors; | ||||
| 	uint32_t num_write_errors; | ||||
| 	uint32_t num_corruption_errors; | ||||
| } badblocks_report; | ||||
| 
 | ||||
| /*
 | ||||
|  * Shared prototypes | ||||
|  */ | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, | ||||
| BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, size_t block_size, | ||||
| 	int test_type, badblocks_report *report, FILE* fd); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -529,14 +529,16 @@ DWORD WINAPI FormatThread(LPVOID param) | |||
| 
 | ||||
| 			if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, | ||||
| 				SelectedDrive.Geometry.BytesPerSector, ComboBox_GetCurSel(hNBPasses)+1, &report, log_fd)) { | ||||
| 				uprintf("Bad blocks check failed.\n"); | ||||
| 				uprintf("Bad blocks: Check failed.\n"); | ||||
| 				if (!FormatStatus) | ||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)| | ||||
| 						APPERR(ERROR_BADBLOCKS_FAILURE); | ||||
| 				ClearMBR(hPhysicalDrive); | ||||
| 				fclose(log_fd); | ||||
| 				_unlink(logfile); | ||||
| 				goto out; | ||||
| 			} | ||||
| 			uprintf("Check completed, %u bad block%s found. (%d/%d/%d errors)\n", | ||||
| 			uprintf("Bad Blocks: Check completed, %u bad block%s found. (%d/%d/%d errors)\n", | ||||
| 				report.bb_count, (report.bb_count==1)?"":"s", | ||||
| 				report.num_read_errors, report.num_write_errors, report.num_corruption_errors); | ||||
| 			r = IDOK; | ||||
|  | @ -547,13 +549,15 @@ DWORD WINAPI FormatThread(LPVOID param) | |||
| 					report.num_read_errors, report.num_write_errors,  | ||||
| 					report.num_corruption_errors); | ||||
| 				fprintf(log_fd, "%s", bb_msg); | ||||
| 				GetLocalTime(<); | ||||
| 				fprintf(log_fd, "Rufus bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d\n", | ||||
| 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | ||||
| 				fclose(log_fd); | ||||
| 				safe_sprintf(&bb_msg[strlen(bb_msg)], sizeof(bb_msg)-strlen(bb_msg)-1, | ||||
| 					"\nA more detailed report can be found in:\n%s\n", logfile); | ||||
| 				r = MessageBoxU(hMainDialog, bb_msg, "Bad blocks found", MB_ABORTRETRYIGNORE|MB_ICONWARNING); | ||||
| 			} else { | ||||
| 				// We didn't get any errors => delete the log file
 | ||||
| 				// NB: the log doesn't get deleted on abort
 | ||||
| 				fclose(log_fd); | ||||
| 				_unlink(logfile); | ||||
| 			} | ||||
|  |  | |||
|  | @ -18,17 +18,25 @@ | |||
| ******************************************************************/ | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "../rufus.h" | ||||
| #include "file.h" | ||||
| 
 | ||||
| /* Returns the number of bytes written or -1 on error */ | ||||
| int write_sectors(HANDLE hDrive, size_t SectorSize, | ||||
|                   size_t StartSector, size_t nSectors, | ||||
| int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize, | ||||
|                       uint64_t StartSector, uint64_t nSectors, | ||||
|                       const void *pBuf) | ||||
| { | ||||
|    LARGE_INTEGER ptr; | ||||
|    DWORD Size = (DWORD)(nSectors*SectorSize); | ||||
|    DWORD Size; | ||||
| 
 | ||||
|    if((nSectors*SectorSize) > 0xFFFFFFFFUL) | ||||
|    { | ||||
|       uprintf("write_sectors: nSectors x SectorSize is too big\n"); | ||||
|       return -1; | ||||
|    } | ||||
|    Size = (DWORD)(nSectors*SectorSize); | ||||
| 
 | ||||
|    ptr.QuadPart = StartSector*SectorSize; | ||||
|    if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN)) | ||||
|  | @ -44,16 +52,23 @@ int write_sectors(HANDLE hDrive, size_t SectorSize, | |||
|       return Size; | ||||
|    } | ||||
| 
 | ||||
|    return Size; | ||||
|    return (int64_t)Size; | ||||
| } | ||||
| 
 | ||||
| /* Returns the number of bytes read or -1 on error */ | ||||
| int read_sectors(HANDLE hDrive, size_t SectorSize, | ||||
|                  size_t StartSector, size_t nSectors, | ||||
| int64_t read_sectors(HANDLE hDrive, uint64_t SectorSize, | ||||
|                      uint64_t StartSector, uint64_t nSectors, | ||||
|                      void *pBuf) | ||||
| { | ||||
|    LARGE_INTEGER ptr; | ||||
|    DWORD Size = (DWORD)(nSectors*SectorSize); | ||||
|    DWORD Size; | ||||
| 
 | ||||
|    if((nSectors*SectorSize) > 0xFFFFFFFFUL) | ||||
|    { | ||||
|       uprintf("read_sectors: nSectors x SectorSize is too big\n"); | ||||
|       return -1; | ||||
|    } | ||||
|    Size = (DWORD)(nSectors*SectorSize); | ||||
| 
 | ||||
|    ptr.QuadPart = StartSector*SectorSize; | ||||
|    if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN)) | ||||
|  | @ -68,7 +83,7 @@ int read_sectors(HANDLE hDrive, size_t SectorSize, | |||
|       uprintf("  StartSector:%0X, nSectors:%0X, SectorSize:%0X\n", StartSector, nSectors, SectorSize); | ||||
|    } | ||||
| 
 | ||||
|    return Size; | ||||
|    return (int64_t)Size; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -77,14 +92,49 @@ int read_sectors(HANDLE hDrive, size_t SectorSize, | |||
|  * fp->_bufsiz: the sector size | ||||
|  * fp->_cnt: a file offset | ||||
|  */ | ||||
| int contains_data(FILE *fp, size_t Position, | ||||
|                   const void *pData, size_t Len) | ||||
| int contains_data(FILE *fp, uint64_t Position, | ||||
|                   const void *pData, uint64_t Len) | ||||
| { | ||||
|    unsigned char aucBuf[MAX_DATA_LEN]; | ||||
|    HANDLE hDrive = (HANDLE)fp->_ptr; | ||||
|    size_t SectorSize = (size_t)fp->_bufsiz; | ||||
|    size_t StartSector, EndSector, NumSectors; | ||||
|    Position += (size_t)fp->_cnt; | ||||
|    uint64_t SectorSize = (uint64_t)fp->_bufsiz; | ||||
|    uint64_t StartSector, EndSector, NumSectors; | ||||
|    Position += (uint64_t)fp->_cnt; | ||||
| 
 | ||||
|    StartSector = Position/SectorSize; | ||||
|    EndSector   = (Position+Len+SectorSize-1)/SectorSize; | ||||
|    NumSectors  = (size_t)(EndSector - StartSector); | ||||
| 
 | ||||
|    if((NumSectors*SectorSize) > MAX_DATA_LEN) | ||||
|    { | ||||
|       uprintf("contains_data: please increase MAX_DATA_LEN in file.h\n"); | ||||
|       return 0; | ||||
|    } | ||||
| 
 | ||||
|    if(Len > 0xFFFFFFFFUL) | ||||
|    { | ||||
|       uprintf("contains_data: Len is too big\n"); | ||||
|       return 0; | ||||
|    } | ||||
| 
 | ||||
|    if(read_sectors(hDrive, SectorSize, StartSector, | ||||
|                      NumSectors, aucBuf) <= 0) | ||||
|       return 0; | ||||
| 
 | ||||
|    if(memcmp(pData, &aucBuf[Position - StartSector*SectorSize], (size_t)Len)) | ||||
|       return 0; | ||||
|    return 1; | ||||
| } /* contains_data */ | ||||
| 
 | ||||
| /* May read/write the same sector many times, but compatible with existing ms-sys */ | ||||
| int write_data(FILE *fp, uint64_t Position, | ||||
|                const void *pData, uint64_t Len) | ||||
| { | ||||
|    unsigned char aucBuf[MAX_DATA_LEN]; | ||||
|    HANDLE hDrive = (HANDLE)fp->_ptr; | ||||
|    uint64_t SectorSize = (uint64_t)fp->_bufsiz; | ||||
|    uint64_t StartSector, EndSector, NumSectors; | ||||
|    Position += (uint64_t)fp->_cnt; | ||||
| 
 | ||||
|    StartSector = Position/SectorSize; | ||||
|    EndSector   = (Position+Len+SectorSize-1)/SectorSize; | ||||
|  | @ -96,32 +146,9 @@ int contains_data(FILE *fp, size_t Position, | |||
|       return 0; | ||||
|    } | ||||
| 
 | ||||
|    if(read_sectors(hDrive, SectorSize, StartSector, | ||||
|                      NumSectors, aucBuf) <= 0) | ||||
|       return 0; | ||||
| 
 | ||||
|    if(memcmp(pData, &aucBuf[Position - StartSector*SectorSize], Len)) | ||||
|       return 0; | ||||
|    return 1; | ||||
| } /* contains_data */ | ||||
| 
 | ||||
| /* May read/write the same sector many times, but compatible with existing ms-sys */ | ||||
| int write_data(FILE *fp, size_t Position, | ||||
|                const void *pData, size_t Len) | ||||
|    if(Len > 0xFFFFFFFFUL) | ||||
|    { | ||||
|    unsigned char aucBuf[MAX_DATA_LEN]; | ||||
|    HANDLE hDrive = (HANDLE)fp->_ptr; | ||||
|    size_t SectorSize = (size_t)fp->_bufsiz; | ||||
|    size_t StartSector, EndSector, NumSectors; | ||||
|    Position += (size_t)fp->_cnt; | ||||
| 
 | ||||
|    StartSector = Position/SectorSize; | ||||
|    EndSector   = (Position+Len+SectorSize-1)/SectorSize; | ||||
|    NumSectors  = EndSector - StartSector; | ||||
| 
 | ||||
|    if((NumSectors*SectorSize) > MAX_DATA_LEN) | ||||
|    { | ||||
|       uprintf("Please increase MAX_DATA_LEN in file.h\n"); | ||||
|       uprintf("write_data: Len is too big\n"); | ||||
|       return 0; | ||||
|    } | ||||
| 
 | ||||
|  | @ -130,7 +157,7 @@ int write_data(FILE *fp, size_t Position, | |||
|                      NumSectors, aucBuf) <= 0) | ||||
|       return 0; | ||||
| 
 | ||||
|    if(!memcpy(&aucBuf[Position - StartSector*SectorSize], pData, Len)) | ||||
|    if(!memcpy(&aucBuf[Position - StartSector*SectorSize], pData, (size_t)Len)) | ||||
|       return 0; | ||||
| 
 | ||||
|    if(write_sectors(hDrive, SectorSize, StartSector, | ||||
|  |  | |||
|  | @ -1,27 +1,29 @@ | |||
| #ifndef FILE_H | ||||
| #define FILE_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| /* Max valid value of uiLen for contains_data */ | ||||
| #define MAX_DATA_LEN 8192 | ||||
| 
 | ||||
| /* Checks if a file contains a data pattern of length uiLen at position
 | ||||
|    ulPositoin. The file pointer will change when calling this function! */ | ||||
| int contains_data(FILE *fp, size_t ulPosition, | ||||
|                   const void *pData, size_t uiLen); | ||||
| /* Checks if a file contains a data pattern of length Len at position
 | ||||
|    Position. The file pointer will change when calling this function! */ | ||||
| int contains_data(FILE *fp, uint64_t Position, | ||||
|                   const void *pData, uint64_t Len); | ||||
| 
 | ||||
| /* Writes a data pattern of length uiLen at position ulPositoin.
 | ||||
| /* Writes a data pattern of length Len at position Position.
 | ||||
|    The file pointer will change when calling this function! */ | ||||
| int write_data(FILE *fp, size_t ulPosition, | ||||
|                const void *pData, size_t uiLen); | ||||
| int write_data(FILE *fp, uint64_t Position, | ||||
|                const void *pData, uint64_t Len); | ||||
| 
 | ||||
| /* Writes nSectors of size SectorSize starting at sector StartSector */ | ||||
| int write_sectors(void *hDrive, size_t SectorSize, | ||||
|                   size_t StartSector, size_t nSectors, | ||||
| int64_t write_sectors(void *hDrive, uint64_t SectorSize, | ||||
|                       uint64_t StartSector, uint64_t nSectors, | ||||
|                       const void *pBuf); | ||||
| 
 | ||||
| /* Reads nSectors of size SectorSize starting at sector StartSector */ | ||||
| int read_sectors(void *hDrive, size_t SectorSize, | ||||
|                  size_t StartSector, size_t nSectors, | ||||
| int64_t read_sectors(void *hDrive, uint64_t SectorSize, | ||||
|                      uint64_t StartSector, uint64_t nSectors, | ||||
|                      void *pBuf); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 206, 289 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_APPWINDOW | ||||
| CAPTION "Rufus v1.1.4.148" | ||||
| CAPTION "Rufus v1.1.4.149" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,248,50,14 | ||||
|  | @ -73,7 +73,7 @@ BEGIN | |||
|     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP | ||||
|     CONTROL         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, | ||||
|                     "SysLink",WS_TABSTOP,46,47,114,9 | ||||
|     LTEXT           "Version 1.1.4 (Build 148)",IDC_STATIC,46,19,78,8 | ||||
|     LTEXT           "Version 1.1.4 (Build 149)",IDC_STATIC,46,19,78,8 | ||||
|     PUSHBUTTON      "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP | ||||
|     EDITTEXT        IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL | ||||
|     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 | ||||
|  | @ -223,8 +223,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 1,1,4,148 | ||||
|  PRODUCTVERSION 1,1,4,148 | ||||
|  FILEVERSION 1,1,4,149 | ||||
|  PRODUCTVERSION 1,1,4,149 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -241,13 +241,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "akeo.ie" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "1.1.4.148" | ||||
|             VALUE "FileVersion", "1.1.4.149" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "1.1.4.148" | ||||
|             VALUE "ProductVersion", "1.1.4.149" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue