mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-29 05:55:30 -04:00
[ext2fs] initial ext2fs support
This commit is contained in:
parent
f4d70345af
commit
cda716c1ff
87 changed files with 29093 additions and 130 deletions
|
@ -1,36 +1,19 @@
|
|||
/*
|
||||
* badblocks.c - Bad blocks checker
|
||||
* badblocks.c - Bad blocks checker
|
||||
*
|
||||
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
|
||||
* Laboratoire MASI, Institut Blaise Pascal
|
||||
* Universite Pierre et Marie Curie (Paris VI)
|
||||
*
|
||||
* Copyright 1995, 1996, 1997, 1998, 1999 by Theodore Ts'o
|
||||
* Copyright 1999 by David Beattie
|
||||
* Copyright 2011-2018 by Pete Batard
|
||||
* Copyright 1992-1994 Remy Card <card@masi.ibp.fr>
|
||||
* Copyright 1995-1999 Theodore Ts'o
|
||||
* Copyright 1999 David Beattie
|
||||
* Copyright 2011-2019 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* This file is based on the minix file system programs fsck and mkfs
|
||||
* written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi>
|
||||
*
|
||||
* %Begin-Header%
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
* This file may be redistributed under the terms of the GNU Public License.
|
||||
* %End-Header%
|
||||
*/
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/05/26 - Creation from e2fsck
|
||||
* 94/02/27 - Made a separate bad blocks checker
|
||||
* 99/06/30...99/07/26 - Added non-destructive write-testing,
|
||||
* configurable blocks-at-once parameter,
|
||||
* loading of badblocks list to avoid testing
|
||||
* blocks known to be bad, multiple passes to
|
||||
* make sure that no new blocks are added to the
|
||||
* list. (Work done by David Beattie)
|
||||
* 11/12/04 - Windows/Rufus integration (Pete Batard)
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -84,16 +67,16 @@ static errcode_t make_u64_list(int size, int num, uint64_t *list, bb_u64_list *r
|
|||
bb->magic = BB_ET_MAGIC_BADBLOCKS_LIST;
|
||||
bb->size = size ? size : 10;
|
||||
bb->num = num;
|
||||
bb->list = malloc(sizeof(blk_t) * bb->size);
|
||||
bb->list = malloc(sizeof(blk64_t) * bb->size);
|
||||
if (bb->list == NULL) {
|
||||
free(bb);
|
||||
bb = NULL;
|
||||
return BB_ET_NO_MEMORY;
|
||||
}
|
||||
if (list)
|
||||
memcpy(bb->list, list, bb->size * sizeof(blk_t));
|
||||
memcpy(bb->list, list, bb->size * sizeof(blk64_t));
|
||||
else
|
||||
memset(bb->list, 0, bb->size * sizeof(blk_t));
|
||||
memset(bb->list, 0, bb->size * sizeof(blk64_t));
|
||||
*ret = bb;
|
||||
return 0;
|
||||
}
|
||||
|
@ -155,7 +138,7 @@ static errcode_t bb_u64_list_add(bb_u64_list bb, uint64_t blk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk_t blk)
|
||||
static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk64_t blk)
|
||||
{
|
||||
return bb_u64_list_add((bb_u64_list) bb, blk);
|
||||
}
|
||||
|
@ -164,7 +147,7 @@ static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk_t blk)
|
|||
* This procedure finds a particular block is on a badblocks
|
||||
* list.
|
||||
*/
|
||||
static int bb_u64_list_find(bb_u64_list bb, uint64_t blk)
|
||||
static int bb_u64_list_find(bb_u64_list bb, blk64_t blk)
|
||||
{
|
||||
int low, high, mid;
|
||||
|
||||
|
@ -199,7 +182,7 @@ static int bb_u64_list_find(bb_u64_list bb, uint64_t blk)
|
|||
* This procedure tests to see if a particular block is on a badblocks
|
||||
* list.
|
||||
*/
|
||||
static int bb_u64_list_test(bb_u64_list bb, uint64_t blk)
|
||||
static int bb_u64_list_test(bb_u64_list bb, blk64_t blk)
|
||||
{
|
||||
if (bb_u64_list_find(bb, blk) < 0)
|
||||
return 0;
|
||||
|
@ -207,12 +190,12 @@ static int bb_u64_list_test(bb_u64_list bb, uint64_t blk)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int bb_badblocks_list_test(bb_badblocks_list bb, blk_t blk)
|
||||
static int bb_badblocks_list_test(bb_badblocks_list bb, blk64_t blk)
|
||||
{
|
||||
return bb_u64_list_test((bb_u64_list) bb, blk);
|
||||
}
|
||||
|
||||
static int bb_u64_list_iterate(bb_u64_iterate iter, uint64_t *blk)
|
||||
static int bb_u64_list_iterate(bb_u64_iterate iter, blk64_t *blk)
|
||||
{
|
||||
bb_u64_list bb;
|
||||
|
||||
|
@ -232,7 +215,7 @@ static int bb_u64_list_iterate(bb_u64_iterate iter, uint64_t *blk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bb_badblocks_list_iterate(bb_badblocks_iterate iter, blk_t *blk)
|
||||
static int bb_badblocks_list_iterate(bb_badblocks_iterate iter, blk64_t *blk)
|
||||
{
|
||||
return bb_u64_list_iterate((bb_u64_iterate) iter, blk);
|
||||
}
|
||||
|
@ -247,13 +230,13 @@ 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 = BB_BAD_BLOCKS_THRESHOLD;
|
||||
static blk_t currently_testing = 0;
|
||||
static blk_t num_blocks = 0;
|
||||
static blk64_t currently_testing = 0;
|
||||
static blk64_t num_blocks = 0;
|
||||
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 blk64_t next_bad = 0;
|
||||
static bb_badblocks_iterate bb_iter = NULL;
|
||||
|
||||
static __inline void *allocate_buffer(size_t size) {
|
||||
|
@ -268,7 +251,7 @@ static __inline void free_buffer(void* p) {
|
|||
* This routine reports a new bad block. If the bad block has already
|
||||
* been seen before, then it returns 0; otherwise it returns 1.
|
||||
*/
|
||||
static int bb_output (blk_t bad, enum error_types error_type)
|
||||
static int bb_output (blk64_t bad, enum error_types error_type)
|
||||
{
|
||||
errcode_t error_code;
|
||||
|
||||
|
@ -381,8 +364,8 @@ 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 int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size,
|
||||
blk_t current_block)
|
||||
static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
|
||||
uint64_t block_size, blk64_t current_block)
|
||||
{
|
||||
int64_t got;
|
||||
|
||||
|
@ -403,8 +386,8 @@ static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
|
|||
* Perform a write of a sequence of blocks; return the number of blocks
|
||||
* successfully sequentially written.
|
||||
*/
|
||||
static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size,
|
||||
blk_t current_block)
|
||||
static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
|
||||
uint64_t block_size, blk64_t current_block)
|
||||
{
|
||||
int64_t got;
|
||||
|
||||
|
@ -421,15 +404,15 @@ static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
|
|||
return got;
|
||||
}
|
||||
|
||||
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 pattern_type, int nb_passes)
|
||||
static unsigned int test_rw(HANDLE hDrive, blk64_t last_block, size_t block_size, blk64_t first_block,
|
||||
size_t blocks_at_once, int pattern_type, int nb_passes)
|
||||
{
|
||||
const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] =
|
||||
{ BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC };
|
||||
unsigned char *buffer = NULL, *read_buffer;
|
||||
int i, pat_idx;
|
||||
unsigned int bb_count = 0;
|
||||
blk_t got, tryout, recover_block = ~0, *blk_id;
|
||||
blk64_t got, tryout, recover_block = ~0, *blk_id;
|
||||
size_t id_offset = 0;
|
||||
|
||||
if ((pattern_type < 0) || (pattern_type >= BADLOCKS_PATTERN_TYPES)) {
|
||||
|
@ -463,7 +446,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
|
|||
goto out;
|
||||
if (detect_fakes && (pat_idx == 0)) {
|
||||
srand((unsigned int)GetTickCount64());
|
||||
id_offset = rand() * (block_size - sizeof(blk_t)) / RAND_MAX;
|
||||
id_offset = rand() * (block_size - sizeof(blk64_t)) / RAND_MAX;
|
||||
uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset);
|
||||
}
|
||||
// coverity[dont_call]
|
||||
|
@ -492,8 +475,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
|
|||
/* Add the block number at a fixed (random) offset during each pass to
|
||||
allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */
|
||||
for (i=0; i<(int)blocks_at_once; i++) {
|
||||
blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
|
||||
*blk_id = (blk_t)(currently_testing + i);
|
||||
blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
|
||||
*blk_id = (blk64_t)(currently_testing + i);
|
||||
}
|
||||
}
|
||||
got = do_write(hDrive, buffer, tryout, block_size, currently_testing);
|
||||
|
@ -538,8 +521,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
|
|||
tryout = last_block - currently_testing;
|
||||
if (detect_fakes && (pat_idx == 0)) {
|
||||
for (i=0; i<(int)blocks_at_once; i++) {
|
||||
blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
|
||||
*blk_id = (blk_t)(currently_testing + i);
|
||||
blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
|
||||
*blk_id = (blk64_t)(currently_testing + i);
|
||||
}
|
||||
}
|
||||
got = do_read(hDrive, read_buffer, tryout, block_size,
|
||||
|
@ -575,10 +558,10 @@ out:
|
|||
}
|
||||
|
||||
BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int nb_passes,
|
||||
int flash_type, badblocks_report *report, FILE* fd)
|
||||
int flash_type, badblocks_report *report, FILE* fd)
|
||||
{
|
||||
errcode_t error_code;
|
||||
blk_t last_block = disk_size / BADBLOCK_BLOCK_SIZE;
|
||||
blk64_t last_block = disk_size / BADBLOCK_BLOCK_SIZE;
|
||||
|
||||
if (report == NULL) return FALSE;
|
||||
num_read_errors = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue