日期:2014-05-16 浏览次数:20939 次
在 GPT分区表 一文中,讲解了MBR分区表的一些概念。本文进一步给出了Windows系统上读取MBR的示例代码,以及MBR的具体数据,可进一步加深对MBR的理解。
在参考网上一些文章&代码的基础上,本文给出了下面的展示MBR的示例代码;同时最后针对几个典型问题,给出了一些解释和参考文档。
下面是代码:
/** * ref: http://noyesno.net/page/it/20100701-172 * */ #include <stdio.h> #include <windows.h> struct CHS { unsigned int header; unsigned int sector; unsigned int cylinder; }; struct partition_record { unsigned char boot_indicator; unsigned char os_type; struct CHS starting_chs; struct CHS ending_chs; unsigned int starting_LBA; unsigned int size_in_LBA; }; void dump_partition_record(const partition_record& record) { const double DISK_SECTOR_SIZE = 512.0; const size_t GB = 1024 * 1024 * 1024; printf( "\tboot indicator: 0x%02x\n" "\tOS Type: 0x%02x\n" "\tStarting CHS: (%d, %d, %d)\n" "\tEnding_CHS: (%d, %d, %d)\n" "\tSize in LBA: %d\n" "\tSize:%.2f\n\n", record.boot_indicator, record.os_type, record.starting_chs.cylinder, record.starting_chs.header, record.starting_chs.sector, record.ending_chs.cylinder, record.ending_chs.header, record.ending_chs.sector, record.size_in_LBA, record.size_in_LBA * DISK_SECTOR_SIZE / GB); } // transform the 16-bytes buffer to partition record void get_partition_record(unsigned char buffer[], partition_record& record) { record.boot_indicator = buffer[0]; record.starting_chs.header = buffer[1]; record.starting_chs.sector = buffer[2] & 0x3f; record.starting_chs.cylinder = (((buffer[2] & 0xff) >> 6) << 8) + buffer[3]; record.os_type = buffer[4]; record.ending_chs.header = buffer[5]; record.ending_chs.sector = buffer[6] & 0x3f; record.ending_chs.cylinder = (((buffer[6] & 0xff) >> 6) << 8) + buffer[7]; record.size_in_LBA = *(unsigned int*)(buffer + 12); } void read_mbr(const char *devname){ HANDLE hDevice = CreateFile(devname, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE){ printf("Open %s failed, the error code is %d.\n", devname, GetLastError()); return; } DWORD dwRead = 0; const size_t DISK_SECTOR_SIZE = 512; unsigned char buffer[DISK_SECTOR_SIZE]; BOOL bSuccess = ReadFile(hDevice, buffer, DISK_SECTOR_SIZE, &dwRead, NULL); CloseHandle(hDevice); if ( !bSuccess || DISK_SECTOR_SIZE != dwRead) { printf("Error: read error! Read size = %d\n", dwRead); return; } size_t i, j; printf("%10s 0 1 2 3 4 5 6 7 8 9 A B C D E F \n", " "); for (i = 0; i < 32; i++) { printf("%.8XH: ", i); for (j = 0; j < 16; j++) { printf("%.2X ", buffer[i * 16 + j] & 0xFF); } printf("\n"); } printf("====MBR Partition Entries====\n"); partition_record record = {0}; for(i = 0x01be; i < 0x01FE; i += 16){ get_partition_record(buffer + i, record); dump_partition_record(record); } } int main(int argc, char *argv[]){ const char* LOG_FILE = "./log.txt"; freopen(LOG_FILE, "a", stdout); setbuf(stdout, NULL); read_mbr("\\\\.\\PhysicalDrive0"); return 0; }
0 1 2 3 4 5 6 7 8 9