Skip to content

Instantly share code, notes, and snippets.

@FRex
Created January 10, 2019 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FRex/5ee5d6efd4910ad90b24a84a429dfe9b to your computer and use it in GitHub Desktop.
Save FRex/5ee5d6efd4910ad90b24a84a429dfe9b to your computer and use it in GitHub Desktop.
#include <windows.h>
#include <stdio.h>
typedef unsigned __int64 u64;
typedef unsigned u32;
static int isDiskAvailable(char upperLetter)
{
if(!('A' <= upperLetter && upperLetter <= 'Z'))
return 0;
const DWORD d = GetLogicalDrives();
return (d >> (upperLetter - 'A')) & 1;
}
static HANDLE openDiskHandle(char disk)
{
char buff[10];
buff[0] = '\\';
buff[1] = '\\';
buff[2] = '.';
buff[3] = '\\';
buff[4] = disk;
buff[5] = ':';
buff[6] = '\0';
return CreateFileA(buff, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0x0, NULL);
}
static u64 getBytesPerSector(HANDLE disk)
{
DISK_GEOMETRY geo;
DWORD bytesgiven;
BOOL ok;
if(disk == INVALID_HANDLE_VALUE)
return 0u;
ok = DeviceIoControl(disk, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geo, sizeof(geo), &bytesgiven, NULL);
if(ok)
return (u64)geo.BytesPerSector;
return 0u;
}
static u64 littleu64(const char * buff)
{
const unsigned char * b = (const unsigned char*)buff;
u64 ret = 0u;
int i;
for(i = 7; i >= 0; --i)
ret = (ret << 8) + (u64)b[i];
return ret;
}
static u32 littleu32(const char * buff)
{
const unsigned char * b = (const unsigned char*)buff;
u32 ret = 0u;
int i;
for(i = 3; i >= 0; --i)
ret = (ret << 8) + (u32)b[i];
return ret;
}
static void askEnterToContinue(void)
{
char dummy[5];
printf("Press enter to continue\n");
fgets(dummy, 2, stdin);
}
static int readBuffer(HANDLE handle, void * buff, u64 size)
{
DWORD dummyreadsize;
return ReadFile(handle, buff, size, &dummyreadsize, NULL) != 0;
}
static int hasNtfsHeader(const char * buff)
{
const unsigned char * b = (const unsigned char*)buff;
if(b[0] != 0xeb) return 0;
if(b[1] != 0x52) return 0;
if(b[2] != 0x90) return 0;
if(b[3] != 'N') return 0;
if(b[4] != 'T') return 0;
if(b[5] != 'F') return 0;
if(b[6] != 'S') return 0;
if(b[7] != ' ') return 0;
if(b[8] != ' ') return 0;
if(b[9] != ' ') return 0;
if(b[10] != ' ') return 0;
return 1;
}
int main(int argc, char ** argv)
{
int i;
#define MYBUFF_SIZE 8192
char mybuff[MYBUFF_SIZE];
HANDLE diskhandle;
u64 bytespersector;
for(i = 'A'; i <= 'Z'; ++i)
{
if(!isDiskAvailable(i))
continue;
diskhandle = openDiskHandle(i);
if(diskhandle == INVALID_HANDLE_VALUE)
{
printf("Disk %c: INVALID_HANDLE_VALUE, GetLastError() == %u\n", i, (unsigned)GetLastError());
continue;
} /* if */
bytespersector = getBytesPerSector(diskhandle);
if(bytespersector <= MYBUFF_SIZE)
{
if(readBuffer(diskhandle, mybuff, bytespersector))
{
if(hasNtfsHeader(mybuff))
{
const u64 totalsectors = littleu64(mybuff + 0x28);
const u64 totalbytes = totalsectors * bytespersector;
const double gib = (totalbytes / (1024 * 1024)) / 1024.0;
const char * fmt = "Disk %c: %llu bytes per sector, %.4f GiB total\n";
printf(fmt, i, bytespersector, gib);
}
else
{
printf("Disk %c: no NTFS header\n", i);
}
}
else
{
printf("Disk %c: ReadFile() == 0, GetLastError() == %u\n", i, (unsigned)GetLastError());
}
}
else
{
const char * fmt = "Disk %c: %llu bytes per sector, MYBUFF_SIZE too small (%u) to read into\n";
printf(fmt, i, bytespersector, (unsigned)MYBUFF_SIZE);
}
if(!CloseHandle(diskhandle))
printf("CloseHandle failed, GetLastError() = %u\n", (unsigned)GetLastError());
} /* for */
askEnterToContinue();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment