From 0ce28cbfed5d711405dbfd85f7321b824842e47a Mon Sep 17 00:00:00 2001 From: Stef Date: Sat, 27 Nov 2010 15:50:58 +0000 Subject: Redo raw scrounge so that it's faster. --- src/locks.h | 2 +- src/main.c | 4 +-- src/misc.c | 32 ++++++++++--------- src/scrounge.c | 99 +++++++++++++++++++++++++++++++++++++--------------------- 4 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/locks.h b/src/locks.h index 028225a..3d35b39 100644 --- a/src/locks.h +++ b/src/locks.h @@ -32,7 +32,7 @@ typedef struct _drivelocks drivelocks; void addLocationLock(drivelocks* locks, uint64 beg, uint64 end); -bool checkLocationLock(drivelocks* locks, uint64 sec); +uint64 checkLocationLock(drivelocks* locks, uint64 sec); #ifdef _DEBUG void dumpLocationLocks(drivelocks* locks); diff --git a/src/main.c b/src/main.c index 12eb85e..b0cd31b 100644 --- a/src/main.c +++ b/src/main.c @@ -91,9 +91,9 @@ int main(int argc, char* argv[]) pi.cluster = 8; #ifdef _WIN32 - while((ch = getopt(argc, argv, "c:d:hlm:o:sv")) != -1) + while((ch = getopt(argc, argv, "c:d:hk:lm:o:sv")) != -1) #else - while((ch = getopt(argc, argv, "c:hlm:o:sv")) != -1) + while((ch = getopt(argc, argv, "c:hk:lm:o:sv")) != -1) #endif { switch(ch) diff --git a/src/misc.c b/src/misc.c index 255533f..4163348 100644 --- a/src/misc.c +++ b/src/misc.c @@ -60,25 +60,27 @@ void addLocationLock(drivelocks* locks, uint64 beg, uint64 end) } } -bool checkLocationLock(drivelocks* locks, uint64 sec) +uint64 checkLocationLock(drivelocks* locks, uint64 sec) { - uint32 i; + uint64 locked; + uint32 i; - if(locks->_locks) - { - /* Go through and check for a lock */ - for(i = 0; i < locks->_current; i++) - { - if(sec >= locks->_locks[i].beg && - sec < locks->_locks[i].end) - { - sec = locks->_locks[i].end; - return true; - } - } + if(locks->_locks) + { + /* Go through and check for a lock */ + for(i = 0; i < locks->_current; i++) + { + if(sec >= locks->_locks[i].beg && + sec < locks->_locks[i].end) + { + locked = locks->_locks[i].end - sec; + assert(locked != 0); + return locked; + } + } } - return false; + return 0; } #ifdef _DEBUG diff --git a/src/scrounge.c b/src/scrounge.c index ad340b0..a5670d7 100644 --- a/src/scrounge.c +++ b/src/scrounge.c @@ -611,57 +611,86 @@ void scroungeUsingMFT(partitioninfo* pi) void scroungeUsingRaw(partitioninfo* pi, uint64 skip) { - byte buffSec[kSectorSize]; - fchar_t dir[MAX_PATH + 1]; - uint64 sec; - drivelocks locks; - int64 pos; - size_t sz; - uint32 magic = kNTFS_RecMagic; - - fprintf(stderr, "[Scrounging raw records...]\n"); + byte *buffer; + size_t length; + byte *bufsec; + fchar_t dir[MAX_PATH + 1]; + uint64 sec; + drivelocks locks; + int64 pos; + uint64 locked; + size_t sz; + uint32 magic = kNTFS_RecMagic; + + fprintf(stderr, "[Scrounging raw records...]\n"); /* Save current directory away */ fc_getcwd(dir, MAX_PATH); - /* Get the locks ready */ - memset(&locks, 0, sizeof(locks)); - pi->locks = &locks; + /* Get the locks ready */ + memset(&locks, 0, sizeof(locks)); + pi->locks = &locks; + + /* The memory buffer */ + length = kSectorSize * 2048; + buffer = malloc(length); + if(!buffer) + errx(1, "out of memory"); /* Loop through sectors */ - for(sec = pi->first + skip; sec < pi->end; sec++) + sec = pi->first + skip; + while(sec < pi->end) { - if(checkLocationLock(&locks, sec)) - continue; - #ifdef _WIN32 - fprintf(stderr, "sector: %I64u\r", sec); + fprintf(stderr, "sector: %I64u\r", sec); #else - fprintf(stderr, "sector: %llu\r", (unsigned long long)sec); + fprintf(stderr, "sector: %llu\r", (unsigned long long)sec); #endif - /* Read the record */ - pos = SECTOR_TO_BYTES(sec); - if(lseek64(pi->device, pos, SEEK_SET) == -1) - errx(1, "can't seek device to sector"); + /* Skip any locked sectors, already read */ + locked = checkLocationLock(&locks, sec); + if(locked > 0) + { + sec += locked; + continue; + } - sz = read(pi->device, buffSec, kSectorSize); - if(sz == -1 || sz != kSectorSize) - { - warn("can't read drive sector"); - continue; - } + /* Read a buffer size at this point */ + pos = SECTOR_TO_BYTES(sec); + if(lseek64(pi->device, pos, SEEK_SET) == -1) + errx(1, "can't seek device to sector"); - /* Check beginning of sector for the magic signature */ - if(!memcmp(&magic, &buffSec, sizeof(magic))) + sz = read(pi->device, buffer, length); + if(sz == -1 || sz < kSectorSize) { - /* Process the record */ - processMFTRecord(pi, sec, 0); + warn("can't read drive sector"); + + /* Try again and go much slower */ + if(length != kSectorSize) + length = kSectorSize; + + /* Already going slow, skip sector */ + else + ++sec; + + continue; } - /* Move to right output directory */ - fc_chdir(dir); + /* Now go through the read data */ + for(bufsec = buffer; bufsec < buffer + sz; + bufsec += kSectorSize, ++sec) + { + /* Check beginning of sector for the magic signature */ + if(!memcmp(&magic, bufsec, sizeof(magic))) + { + /* Process the record */ + processMFTRecord(pi, sec, 0); + } + + /* Move to right output directory */ + fc_chdir(dir); + } } - pi->locks = NULL; + pi->locks = NULL; } -- cgit v1.2.3