summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/locks.h2
-rw-r--r--src/main.c4
-rw-r--r--src/misc.c32
-rw-r--r--src/scrounge.c99
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;
}