Created
January 10, 2019 18:37
-
-
Save FRex/5ee5d6efd4910ad90b24a84a429dfe9b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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