日期:2014-05-16 浏览次数:21157 次
在 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