前段时间在安装黑苹果时,发现一个问题,电脑在启动时,会找激活分区,如果没有找到,那就启动不起来。
那能否写个小程序读取一下MBR信息,把激活分区换成其它,搞点恶作剧呢,于是就有了这篇读取MBR信息的文章,但是没写入,不敢尝试。
通过动手学习,对硬盘MBR信息有了更好的了解。
1、我的硬盘主引导记录信息及分析
80 01 01 00 07 FE FF FF 3F 00 00 00 0D F0 BF 03(主分区)
偏移00H---80---激活标志---表示可引导
偏移01H---01---表示分区开始的磁头号为1
偏移02H---01---转换为二进制后为8位,0-5位表示该分区的起始扇区号---此处为1
偏移03H---00---02H的6-7位与03H的全部8位,共10位,组成起始磁柱号---此处为0
偏移04H---07---表示文件系统类型NTFS。
偏移05H---FE---转换为十进制254,表示分区结束的磁头号为254
偏移06H---FF---转换为二进制1111 1111,0-5位即3F,十进制下的63---该分区的结束扇区号为63。
偏移07H---FF---与06H的6-7位10合起来为3FF,即十进制下的1023---该分区的结束磁柱号为1023。
偏移08H、09H、0AH,0BH---3F 00 00 00---为分区起始相对扇区号63
偏移0CH、0DH、0EH,0FH---0D F0 BF 03---为分区总的扇区数3BFF00D,转换为十进制为62910477。
00 FE FF FF 05 FE FF FF 4C F0 BF 03 75 E6 82 21(扩展分区)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00(没有使用)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00(没有使用)
55 AA(MBR的结束标志位)
从上面可以看出MBR开分区结构最多只能识别4个主要分区,但是为什么我们的电脑上可以分4个以上的盘呢?
这是因为一般电脑上是一个主分区,一个扩展分区,在扩展分区中又分的逻辑分区(扩展分区中可以有多个逻辑分区)
2、获取相关信息的代码(Win7下,请以管理员身份运行)
//基于http://www.cnblogs.com/onepc/archive/2011/12/01/2270468.html来修改的。
//在此感谢此博友
//2012.10.10
#include <iostream>
#include <windows.h>
using namespace std;
#pragma pack(1) //字节对齐
typedef struct _PARTITION_ENTRY//分区表结构
{
UCHAR active; //状态(是否被激活) 重要
UCHAR StartHead; //分区起始磁头号
USHORT StartSecCyli; //与63相位与得出的是开始扇区,把它右移6位就是开始柱面
UCHAR PartitionType; // 分区类型 重要
UCHAR EndHead; //分区结束磁头号
USHORT EndSecCyli; //与63相位与得出的就是结束扇区,把它右移6位就是结束柱面
ULONG StartLBA; // 扇区起始逻辑地址(相对扇区号) 重要
ULONG TotalSector; // 分区大小 重要
} PARTITION_ENTRY, *PPARTITION_ENTRY;
//引导区512BYTE结构
typedef struct _MBR_SECTOR
{
UCHAR BootCode[440];//启动记录440 Byte
ULONG DiskSignature;//磁盘签名
USHORT NoneDisk;//二个字节
PARTITION_ENTRY Partition[4];//分区表结构64 Byte
USHORT Signature;//结束标志2 Byte 55 AA
} MBR_SECTOR, *PMBR_SECTOR;
#pragma pack()
int main()
{
TCHAR szDevicename[64]={0};
MBR_SECTOR _ReadMbr;
wsprintf(szDevicename,L"\\\\.\\PHYSICALDRIVE0");
HANDLE hDevice=CreateFile(szDevicename,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hDevice==INVALID_HANDLE_VALUE)
{
cout<<"打开设备出错"<<endl;
return -1;
}
memset(&_ReadMbr,0,sizeof(MBR_SECTOR));
DWORD leng=512;
DWORD count;
DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&count,NULL);
UCHAR sz[512]={0};
//ReadFile(hDevice,sz,512,&leng,NULL);
BOOL bcheck=ReadFile(hDevice,&_ReadMbr,512,&leng,NULL);
memcpy(sz,&_ReadMbr,512);
for(int i=0;i<66;i++)
{
printf("%02X ",sz[446+i]);
if((i+1)%16==0)
printf("\n");
}
printf("\n");
if(bcheck==FALSE && leng<512)
{
cout<<"读取MBR出错!"<<endl;
DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&count,NULL);
CloseHandle(hDevice);
return -1;
}
char *szTemp=new char[64];
for(int i=0;i<4;i++)
{
if(_ReadMbr.Partition[i].PartitionType==0)
{
continue;
}
memset(szTemp,0,64);
if(_ReadMbr.Partition[i].active==128)
{
cout<<"激活分区"<<endl;
}else
cout<<"非激活分区"<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"激活分区标志位:%02X",_ReadMbr.Partition[i].active);
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区起始磁头号:%d",_ReadMbr.Partition[i].StartHead);
cout<<szTemp<<endl;
memset(szTemp,0,64);
int temp = _ReadMbr.Partition[i].StartSecCyli;
sprintf(szTemp,"分区起始扇区号:%d",temp & 63);//63转为二进制111111,做&运算,只取低6位
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区起始磁柱号:%d",temp>>6);//取高10位
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区文件类型标识:%02d",_ReadMbr.Partition[i].PartitionType);
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区结束磁头号:%d",_ReadMbr.Partition[i].EndHead);
cout<<szTemp<<endl;
memset(szTemp,0,64);
temp = _ReadMbr.Partition[i].EndSecCyli;
sprintf(szTemp,"分区结束扇区号:%d",temp & 63);
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区结束磁柱号:%d",temp>>6);
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区起始相对扇区号:%d",_ReadMbr.Partition[i].StartLBA);
cout<<szTemp<<endl;
memset(szTemp,0,64);
sprintf(szTemp,"分区总的扇区数:%d",_ReadMbr.Partition[i].TotalSector);
cout<<szTemp<<endl;
}
DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &count, NULL);
CloseHandle(hDevice);
system("pause");
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)