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
156
src/badblocks.c
156
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 {
|
||||
int magic;
|
||||
ext2_u32_list bb;
|
||||
int ptr;
|
||||
struct bb_struct_u64_iterate {
|
||||
int magic;
|
||||
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 DWORD errcode_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,
|
||||
const void *pBuf)
|
||||
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,
|
||||
void *pBuf)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
if(Len > 0xFFFFFFFFUL)
|
||||
{
|
||||
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,
|
||||
const void *pBuf);
|
||||
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,
|
||||
void *pBuf);
|
||||
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…
Reference in a new issue