I've seen some file restoration programs out there and am curious how one goes about doing an absolute disk read and how one would determine where files begin, end, etc on the disk? With my primitive debugging skills I've noticed the file restoration program I'm observing appears to simply be using ReadFile() and when CreateFileA() is called the path is specified as "\\.\C:". Normally I'd go ahead and try to see if that would work, but the last thing I want to do is screw up my hard drive at the moment. :) Has anyone ever done this before or is aware of any source I could study? Thanks!
Yes, you can do that. Well, if you're still unsure, try it on a diskette first.
the \\.\disk stuff is just documented in win32.hlp:
The lpFileName string should be of the form \\.\PHYSICALDRIVEx to open the hard disk x. Hard disk numbers start at zero. For example:
String Meaning
\\.\PHYSICALDRIVE2 Obtains a handle to the third physical drive on the user's computer.
? The lpFileName string should be \\.\x: to open a floppy drive x or a partition x on a hard disk. For example:
String Meaning
\\.\A: Obtains a handle to drive A on the user's computer.
\\.\C: Obtains a handle to drive C on the user's computer.
...if you just want to play around without trashing anything, don't specify WRITE access :-)
Thanks for the help everyone, but I'm still not having much success with this. I read in about 1 MB of data from the C: drive and my buffer is completely NULL. Also, how should I determine where a file starts, begins, and ends? Does Windows 2000 use FAT32 or something else? I suppose I'll need to research that as well. Here's the code that is only reading in NULLs apparently (Sorry, I'm using C++ as a scratchpad here):
#include <windows.h>
#include <iostream>
int main()
{
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
DWORD read;
HANDLE hdFile = CreateFile("\\\\.\\C:", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hdFile == INVALID_HANDLE_VALUE)
{
std::cout<<"Error opening file"<<std::endl;
return 0;
}
for(int x=0; x<1000; x++)
{
if(!ReadFile(hdFile, buffer, 1023, &read, NULL))
{
std::cout<<buffer<< std::endl;
}
else
std::cout<<"There was a problem reading the file!"<<std::endl;
}
return 0;
}
MSDN: A file system may or may not require buffer alignment even though the data is noncached.
So, use VirtualAlloc to allocate your buffer, and make all reads a multiple of sectorsize bytes. Forget about parsing filesystems, FAT is doable but NTFS is proprietary.
Also, remembar that readfile returns 0 on error, anything else on success. Oh, and raw ASCII dump of data is not much use, do a hexdump :)
Win2000 can do either FAT32 or NTFS on the hard drive.
The Properties of the disk will tell you which one is being used.
The Properties of the disk will tell you which one is being used.
Depends on how it's setup. If you bought your computer with say XP already on it, then I would imagine the default is NTFS. This link may be useful to you. It has low level info on NTFS.
http://www.ntfs.com/#ntfs%20basics
http://www.ntfs.com/#ntfs%20basics
Also, std::cout << buffer is NOT going to display what you read in a displayable form, because the data is not readable text, and will probably show data only up to the first zero byte.