diskwarez, 07-Oct-1998

Reading the MBR under Windows NT.

With Windows NT you just open a disk handle and just read. Simple eh?

Here is the .C source code, .TXT source code, and here is some output text from tests on my computer.

Here the <PRE></PRE> source code but some browsers can screw with such text so get the DISK.C file (or the DISK_C.TXT file) if that is the case with yourn.
 
 

/*
    File: DISK.C
    Desc: Read first sector of disk/drive (MBR or BOOT)
    Plat: Windows NT
    Auth: diskwarez
    Date: 07-Oct-1998

    Note: I totally dis-like Windows' C style (to put it mildly).
          Where ever I could I use normal C style. I loathe using
          Windows' typedefs like VOID and LPVOID etc. Anyhoo, this
          code works and is so damn simple. Who ever said you
          CAN'T read the MBR under Windows NT. (Writing the MBR
          may be a different story.)
*/

#include 
#include 
#include 

#if defined __STDC__ && defined _MSC_VER
#error Windows' SHIT is not ANSI compatable (use /Ze or /ze)
#endif
#if defined __WATCOMC__ && defined NO_EXT_KEYS
#error Windows' SHIT is not ANSI compatable (do not use -za)
#endif
#pragma warning(disable:4001)   /* single line comment */
#pragma warning(disable:4115)   /* named type definition in parentheses */
#pragma warning(disable:4201)   /* nameless struct/union */
#pragma warning(disable:4209)   /* benign typedef */
#pragma warning(disable:4214)   /* bit field types other than int */
#pragma warning(disable:4515)   /* unreferenced inline function */
#define WIN32_LEAN_AND_MEAN
#define NO_INLINE_SHIT
#include 
#include 

long winperror(char * message, ...);
void *secmalloc(DISK_GEOMETRY *Geometry);

int GetDiskGeometry(HANDLE hDisk, DISK_GEOMETRY *buf)
{
unsigned long count;

    return DeviceIoControl(hDisk,IOCTL_DISK_GET_DRIVE_GEOMETRY,
                           NULL,0,buf,sizeof(DISK_GEOMETRY),
                           &count,NULL);
}

int GetDiskPartitionInfo(HANDLE hDisk,PARTITION_INFORMATION *buf)
{
unsigned long count;

    return DeviceIoControl(hDisk,IOCTL_DISK_GET_PARTITION_INFO,
                           NULL,0,buf,sizeof(PARTITION_INFORMATION),
                           &count,NULL);
}

int LockVolume(HANDLE hDisk)
{
unsigned long count;

    return DeviceIoControl(hDisk,FSCTL_LOCK_VOLUME,
                           NULL,0,NULL,0,&count,NULL);
}

int UnlockVolume(HANDLE hDisk)
{
unsigned long count;

    return DeviceIoControl(hDisk,FSCTL_UNLOCK_VOLUME,
                           NULL,0,NULL,0,&count,NULL);
}

void PrintGeometry(char *DriveName,DISK_GEOMETRY *Geometry)
{
char *MediaType;

    if (DriveName)
        printf("Geometry for Drive %s\n",DriveName);

    switch (Geometry->MediaType)
    {
        case F5_1Pt2_512:  MediaType = "5.25, 1.2MB,  512 bytes/sector";break;
        case F3_1Pt44_512: MediaType = "3.5,  1.44MB, 512 bytes/sector";break;
        case F3_2Pt88_512: MediaType = "3.5,  2.88MB, 512 bytes/sector";break;
        case F3_20Pt8_512: MediaType = "3.5,  20.8MB, 512 bytes/sector";break;
        case F3_720_512:   MediaType = "3.5,  720KB,  512 bytes/sector";break;
        case F5_360_512:   MediaType = "5.25, 360KB,  512 bytes/sector";break;
        case F5_320_512:   MediaType = "5.25, 320KB,  512 bytes/sector";break;
        case F5_320_1024:  MediaType = "5.25, 320KB,  1024 bytes/sector";break;
        case F5_180_512:   MediaType = "5.25, 180KB,  512 bytes/sector";break;
        case F5_160_512:   MediaType = "5.25, 160KB,  512 bytes/sector";break;
        case RemovableMedia: MediaType = "Removable media other than floppy";break;
        case FixedMedia:   MediaType = "Fixed hard disk media";break;
        default:           MediaType = "Unknown";break;
    }
    printf("Media Type %s\n",MediaType);
    printf("Cylinders %d Tracks/Cylinder %d Sectors/Track %d\n",
            Geometry->Cylinders.LowPart,
            Geometry->TracksPerCylinder,
            Geometry->SectorsPerTrack);
}

HANDLE opendrive(char *drive)
{
char devname[64];

    if (isalpha(*drive))
       sprintf(devname,"\\\\.\\%c:",*drive);
    else
        sprintf(devname,"\\\\.\\PHYSICALDRIVE%c",*drive);

    return CreateFile(devname,GENERIC_READ | GENERIC_WRITE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                      NULL,OPEN_EXISTING,0,NULL);
}


int main()
{
int i;
HANDLE dev;
unsigned char *buf;
unsigned long bytes,bread;
DISK_GEOMETRY Geometry;
PARTITION_INFORMATION partinfo;

char *drive = "0";                  /* change this for other drives */

    printf("Drive: %s\n",drive);

    dev = opendrive(drive);

    if ( dev == INVALID_HANDLE_VALUE )
        return (int)winperror("CreateFile");

    LockVolume(dev);
    winperror("Lock");

    GetDiskPartitionInfo(dev,&partinfo);
    winperror("GetDiskPartitionInfo");

    GetDiskGeometry(dev,&Geometry);
    winperror("GetDIskGeometry");

    PrintGeometry(drive,&Geometry);

    buf = secmalloc(&Geometry);
    if (buf == NULL)
        abort();

    bytes = 512;

    ReadFile(dev, buf, bytes, &bread, NULL);
    winperror("ReadFile");

    /* print first 16 bytes */

    for (i = 0; i < 16; i++)
        printf("%02x ",(unsigned)buf[i]);
    for (i = 0; i < 16; i++)
        printf("%c",isprint(buf[i]) ? buf[i] : '.');

    /* print last 16 bytes */

    printf("\n");
    for (i = 512-16; i < 512; i++)
        printf("%02x ",(unsigned)buf[i]);
    for (i = 512-16; i < 512; i++)
        printf("%c",isprint(buf[i]) ? buf[i] : '.');

    printf("\n");

    /* hey, lets try the next sector... */

    ReadFile(dev, buf, bytes, &bread, NULL);
    winperror("ReadFile");

    for (i = 0; i < 16; i++)
        printf("%02x ",(unsigned)buf[i]);
    for (i = 0; i < 16; i++)
        printf("%c",isprint(buf[i]) ? buf[i] : '.');
    printf("\n");
    for (i = 512-16; i < 512; i++)
        printf("%02x ",(unsigned)buf[i]);
    for (i = 512-16; i < 512; i++)
        printf("%c",isprint(buf[i]) ? buf[i] : '.');

    /* simple eh? Looking into overlapped i/o for Seeking... */

    UnlockVolume(dev);

    return 0;
}

void *secmalloc(DISK_GEOMETRY *Geometry)
{
long NumBufs;
long VirtBufSize;
LPVOID IoBuffer;

    NumBufs = Geometry->Cylinders.LowPart;
    /*
    VirtBufSize =  Geometry->TracksPerCylinder *
                   Geometry->SectorsPerTrack *
    */
    VirtBufSize = Geometry->BytesPerSector;

    IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);

    return IoBuffer;
}

long winperror(char * message, ...)
{
char *buf;
va_list ap;
long error;

    error = GetLastError();
    SetLastError(0);

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
                  NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
                  (LPTSTR)&buf,0,NULL);

    va_start(ap,message);
    vprintf(message,ap);
    va_end(ap);

    printf(" : ");
    if (error)
        printf("error = %lu, ",error);
    printf("%s",buf);

    LocalFree(buf);

    return error;
}