/***************************************************************************** Sector-level disk I/O code for Windows NT. This code is public domain (no copyright). You can do whatever you want with it. EXPORTS: int read_sector(disk_t *disk, unsigned long lba, unsigned char *buf); int open_disk(disk_t *disk, unsigned drive_num); int is_fat_bootsector(unsigned char *buf); Tim Robinson helped with this code. (Bugs are due to Giese :) *****************************************************************************/ #include <windows.h> /* FILE, fopen(), setvbuf(), fseek(), fread(), fclose(), printf(), sprintf() */ #include <stdio.h> #include "diskio.h" /***************************************************************************** *****************************************************************************/ static FILE *do_open(unsigned drive_num) { char dev_name[64]; FILE *f; /* form internal drive name */ if(drive_num < 0x80) sprintf(dev_name, "\\\\.\\%c:", drive_num + 'A'); else sprintf(dev_name, "\\\\.\\PhysicalDrive%u", drive_num - 0x80); /* open the drive */ f = fopen(dev_name, "r+b"); if(f == NULL) printf("do_open(): drive 0x%02X (%s) does not exist\n", drive_num, dev_name); return f; } /***************************************************************************** *****************************************************************************/ int read_sector(disk_t *disk, unsigned long lba, unsigned char *buf) { unsigned err; FILE *f; lba += disk->partition_start; f = do_open(disk->drive_num); if(f == NULL) return -1; /* seek, read, close */ setvbuf(f, NULL, _IOFBF, BPS); fseek(f, lba * BPS, SEEK_SET); err = fread(buf, 1, BPS, f); fclose(f); return (err == BPS) ? 0 : -1; } /***************************************************************************** *****************************************************************************/ int open_disk(disk_t *disk, unsigned drive_num) { OSVERSIONINFO win_version; unsigned char buf[BPS]; unsigned err = 0; FILE *f; /* check for NT */ win_version.dwOSVersionInfoSize = sizeof(win_version); GetVersionEx(&win_version); if(win_version.dwPlatformId != VER_PLATFORM_WIN32_NT) { printf("Sorry, Windows NT required\n" "Windows 9x users should use the " "DOS version of this program\n\n"); return -1; } disk->drive_num = drive_num; disk->partition_start = 0; /* assume floppy */ disk->use_lba = 0; /* assume CHS */ /* open the drive, to make sure it exists */ f = do_open(disk->drive_num); if(f == NULL) return -1; fclose(f); /* no CHS geometry - NT uses LBA for everything */ return 0; } /***************************************************************************** is_fat_bootsector() is not used in this file, but still used in DEMO.C *****************************************************************************/ int is_fat_bootsector(unsigned char *buf) { int temp, ok = 1; DEBUG(printf("check_if_fat_bootsector:\n");) /* must start with 16-bit JMP or 8-bit JMP plus NOP */ if(buf[0] == 0xE9) /* OK */; else if(buf[0] == 0xEB && buf[2] == 0x90) /* OK */; else { DEBUG(printf("\tMissing JMP/NOP\n");) ok = 0; } temp = buf[13]; if(temp == 0 || ((temp - 1) & temp) != 0) { DEBUG(printf("\tSectors per cluster (%u) " "is not a power of 2\n", temp);) ok = 0; } temp = buf[16]; temp = LE16(buf + 24); if(temp == 0 || temp > 63) { DEBUG(printf("\tInvalid number of sectors (%u)\n", temp);) ok = 0; } temp = LE16(buf + 26); if(temp == 0 || temp > 255) { DEBUG(printf("\tInvalid number of heads (%u)\n", temp);) ok = 0; } return ok; }