如何判断第一扇区的内容是MBR还是OBR? U盘和硬盘第一扇区都可以是MBR,也可以直接是OBR,那该怎么判断到底是MBR还是OBR呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 OBR是引导扇区的意思吗?还第1次见到这种名字。引导扇区和主引导扇区都必须是以0x55、0xaa两字节结尾才有效。引导扇区第3字节(基于0)出是文件系统ID,例如"NTFS"、"MSDOS"之类的字样,可以根据这个ID来判断。主引导扇区中0x1b8~0x1fd是分区表,可以根据分区表的有效性来判断。 其实就是DBR,不过似乎现在很多人都叫OBR,我觉得这个名称更合适一些就也这么叫了。分区表的有效性该怎么判断呢? 首先你要了解分区表结构,然后根据硬盘信息判断分区表的内容是否符合实际。分区表是4个分区项,每项占16字节,主要看最后8字节,最后8字节是两个DWORD值:前一个表示分区的开始扇区号,后一个表示分区的扇区总数。正常的分区表中各分区的开始和结束扇区都必须小于硬盘的扇区总数,并且各个分区之间不能有重叠。 分区表的解析没问题,现在唯一困扰我的就是判断是不是分区表,因为第一扇区可能是是MBR也可能就是DBR,如果判断方法过于简单的话存在误判的可能..... 判断方法我在1楼说了,一般情况判断文件系统ID就够了,如果要保险一点就再判断一下BPB和分区表。 首先各种文件系统的OEMName这个域不一致,总不能列出所有可能的值一个个比较吧?再次根据微软的白皮书,该域的值没有任何意义,即便你修改成其它字符也没关系,这样即便比较失败也不能说明这就不是DBR。而BPB结构则是各个文件系统都不一样吧? OEMName域主要是用于区分NTFS和FAT文件系统,如果是NTFS文件系统,这个位置一定是"NTFS",这个域只有在Win9X时才会乱写,因为9X只支持FAT文件系统,其BPB基本结构是一样的。你可以试一下,把一个U盘不分区,直接格式化为NTFS文件系统,然后再把NTFS的ID改成乱码,我估计Windows就没法认了。另外正常情况下BPB与分区表不会同时有效,假设真遇到这种情况就没法说U盘到底是有分区还是没分区了,你可以自己做出这种情况看操作系统按哪种来认,然后照着做就是了。 1、主引导区,在零磁道上,包括MBR(Main Boot Record)和分区表DPT(Disk Partition Table)。MBR位于硬盘的0磁道0柱面1扇区;DPT以80H或00H为开始标志,以55AAH结束。在总共512字节的硬盘主引导记录扇区中,446字节属于硬盘主引导程序,64字节属于硬盘分区表(DPT),两个字节(55 AA)属于分区结束标志。2、OBR(OS Boot Record)操作系统引导扇区,通常位于硬盘的0磁道1柱面1扇区,对于以多重引导方式启动的系统则位于相应的主分区/扩展分区的第一个扇区),是操作系统可直接访问的第一个扇区。 一般读写流程,需要进入ring0级:1)CreateFile(PChar('\\.\' + Driver),... 打开分区 2)DeviceIoControl(hDisk, 设备句柄 FSCTL_LOCK_VOLUME, 锁卷 3)ReadFile/WriteFile读写物理地址例如,读取MBR内容#include <winioctl.h> void WINAPI ReadMBR(BYTE* pMBR, UINT nLen) { HANDLE hDevice; TCHAR szDevicename[64]; LPTSTR szBuff; DISK_GEOMETRY Geometry; BOOL bRet; DWORD bytes,bread,count; int i; char *drive = "0"; wsprintf(szDevicename,"\\\\.\\PHYSICALDRIVE%c",*drive); hDevice = CreateFile( szDevicename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if (hDevice == INVALID_HANDLE_VALUE) { MessageBox(NULL,"打开设备出错",NULL,MB_OK); ExitProcess(0); } DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&count,NULL); DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL); szBuff = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector); if ( szBuff == NULL) { MessageBox(NULL,"分配内存出错",NULL,MB_OK); ExitProcess(0); } bytes = 512; bRet = ReadFile(hDevice, szBuff, bytes, &bread, NULL); if (bRet==FALSE || bread<512) { MessageBox(NULL,"读MBR出错",NULL,MB_OK); ExitProcess(0); } for(int n=0;n<512;n++){ pMBR[n] = szBuff[n]; } DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&count,NULL); CloseHandle(hDevice); } 关于MFC项目编码问题 网络通信问题 【求助】关于语音识别的一个小问题! 连接不上数据库,vs2005,mfc,谢谢大家了! 可以动态设置 Picture Control类型吗 如何打开后缀名为“.ocx”的文件 求C++和c中所有的位操作 怎样将十进制数转换成十六进制数? 如何改变CEdit控件中文字的字体??(20) 关于END_MESSAGE_MAP的嵌套定义问题 求制作3D Activex的方法. 弹出对话框时WM_GETDLGCODE消息死循环
引导扇区第3字节(基于0)出是文件系统ID,例如"NTFS"、"MSDOS"之类的字样,可以根据这个ID来判断。
主引导扇区中0x1b8~0x1fd是分区表,可以根据分区表的有效性来判断。
分区表是4个分区项,每项占16字节,主要看最后8字节,最后8字节是两个DWORD值:前一个表示分区的开始扇区号,后一个表示分区的扇区总数。正常的分区表中各分区的开始和结束扇区都必须小于硬盘的扇区总数,并且各个分区之间不能有重叠。
另外正常情况下BPB与分区表不会同时有效,假设真遇到这种情况就没法说U盘到底是有分区还是没分区了,你可以自己做出这种情况看操作系统按哪种来认,然后照着做就是了。
在总共512字节的硬盘主引导记录扇区中,446字节属于硬盘主引导程序,64字节属于硬盘分区表(DPT),两个字节(55 AA)属于分区结束标志。2、OBR(OS Boot Record)操作系统引导扇区,通常位于硬盘的0磁道1柱面1扇区,对于以多重引导方式启动的系统则位于相应的主分区/扩展分区的第一个扇区),是操作系统可直接访问的第一个扇区。
1)CreateFile(PChar('\\.\' + Driver),... 打开分区
2)DeviceIoControl(hDisk, 设备句柄
FSCTL_LOCK_VOLUME, 锁卷
3)ReadFile/WriteFile读写物理地址例如,读取MBR内容#include <winioctl.h>
void WINAPI ReadMBR(BYTE* pMBR, UINT nLen)
{
HANDLE hDevice;
TCHAR szDevicename[64];
LPTSTR szBuff;
DISK_GEOMETRY Geometry;
BOOL bRet;
DWORD bytes,bread,count;
int i;
char *drive = "0";
wsprintf(szDevicename,"\\\\.\\PHYSICALDRIVE%c",*drive);
hDevice = CreateFile( szDevicename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hDevice == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"打开设备出错",NULL,MB_OK);
ExitProcess(0);
}
DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&count,NULL); DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL);
szBuff = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector);
if ( szBuff == NULL)
{
MessageBox(NULL,"分配内存出错",NULL,MB_OK);
ExitProcess(0);
}
bytes = 512;
bRet = ReadFile(hDevice, szBuff, bytes, &bread, NULL);
if (bRet==FALSE || bread<512)
{
MessageBox(NULL,"读MBR出错",NULL,MB_OK);
ExitProcess(0);
}
for(int n=0;n<512;n++){
pMBR[n] = szBuff[n];
}
DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&count,NULL);
CloseHandle(hDevice);
}