[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:
Pete Batard 2012-03-03 22:59:58 +00:00
parent 3721b0a570
commit a9c47a4922
6 changed files with 194 additions and 161 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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(&lt);
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);
}

View File

@ -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,

View File

@ -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

View File

@ -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"