#ifndef MBR_DATA_H
#define MBR_DATA_H 0x2009
#include<vector>
using namespace std;
#define GetCylinder(l ,h)   ((((WORD)h) << 2) | (l & 0xB0))   //获取柱面号
#define GetSector(x)    (x & 0x3F) // 获取扇区号              
#define IsActiveDPT(x)  x == 0x80 ? 1 : 0  //判断是否是活动分区 
#define IsNTFSDPT(x)    x == 0x07 ? 1 : 0 //判断是否是NTFS分区
 #pragma pack(1)
typedef struct DPT
{
 BYTE BootFlag;  //启动标志,是否为活动分区 0x80表示活动分区
 BYTE StartSide; //分区其实磁头号 
 BYTE StartCylinder; //分区起始柱面号 10 bit
 BYTE StartSector; //分区起始扇区号 6 bit
 BYTE SystemIndicator; //分区文件系统类型 0x0B fat32 0x0C <==> 0x0b 0x0E<==>0x06 0x0F<==>0x05
 //0x05 扩展分区 , 0x06 FAT , 0x07 IFS(HPFS | NTFS)
 BYTE EndSide;  //分区结束磁头号
 BYTE EndCylinder; //分区结束柱面号 10 bit
 BYTE EndSector; //分区结束扇区号  6 bit
 DWORD RelativeSector; //4byte 表示从分区表开头到分区开始处的偏移量 ,按扇区计数.
 DWORD NumofSector; //4byte 分区中的扇区数
}DPT;
#pragma pack()
typedef struct MBR
{
 BYTE MBR_S[446];   //MBR
 DPT  dpt[4];   //分区表
 WORD EndFlag;  //结束标志 
}MBR;
typedef vector<MBR> vecMBRInfo;
 #endif
//读取DBR
BOOL CDiskMBRDlg::ReadMBR(void)
{
 m_hFileOpenRead = ::CreateFile(_T("\\\\.\\PHYSICALDRIVE0"),
  GENERIC_READ,
  FILE_SHARE_READ | FILE_SHARE_WRITE ,
  NULL,
  OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL ,
  NULL);  //打开物理扇区  0 0 1
 if(m_hFileOpenRead != INVALID_HANDLE_VALUE)
 {
  MBR mbrRead;
  memset(&mbrRead,0,sizeof(MBR));
  DWORD dwNumBytesOfRead = 0;
  BOOL bRet = FALSE;
  LARGE_INTEGER nOffset;
  memset(&nOffset,0,sizeof(nOffset));
  size_t size =sizeof(MBR);
  bRet = ::ReadFile(m_hFileOpenRead,&mbrRead,sizeof(MBR),&dwNumBytesOfRead,NULL); //读取MBR
  m_MBRInfo.push_back(mbrRead);
  DWORD dwErr = ::GetLastError();
  if(bRet && dwNumBytesOfRead == 512 && mbrRead.EndFlag == 0xAA55)  //确保数据正确无误
  {
   while(!IsEndOfDPT(mbrRead) && dwNumBytesOfRead == 512 && mbrRead.EndFlag == 0xAA55)
   {
    nOffset = CacNextDiskAddr(mbrRead);   //计算偏移
    memset(&mbrRead,0,sizeof(mbrRead));  //重新初始化初始化
    ::SetFilePointerEx(m_hFileOpenRead,nOffset,NULL,FILE_BEGIN);
    bRet = ::ReadFile(m_hFileOpenRead,&mbrRead,sizeof(MBR),&dwNumBytesOfRead,NULL);
    if(bRet == FALSE)
     return FALSE;
    m_MBRInfo.push_back(mbrRead);
    DWORD dwFlag = mbrRead.EndFlag;
   }
   ShowMBRInfo();
 
  }
 }
 return 0;
}
//通过前一次读取的DBR数据来确定下一个分区的地址
LARGE_INTEGER CDiskMBRDlg::CacNextDiskAddr(MBR& mbrPrev)
{
 LARGE_INTEGER nOffset;
 DWORD dwBytesOfSector = 0;
 ::GetDiskFreeSpace(NULL,NULL,&dwBytesOfSector,NULL,NULL);  //获取扇区大小
 nOffset.QuadPart = m_nPrevDPTAddr + ((LONGLONG)(mbrPrev.dpt[0].RelativeSector + mbrPrev.dpt[0].NumofSector)) * dwBytesOfSector;
 m_nPrevDPTAddr = nOffset.QuadPart;
 return nOffset;
}
//判断是否到达最后以个分区
BOOL CDiskMBRDlg::IsEndOfDPT(MBR& mbrCurr)
{
 BYTE bBuff[16] = {0};
 if(memcmp(bBuff,&(mbrCurr.dpt[1]),16) == 0)
 {
  return TRUE;
 }
 else
 {
  return FALSE;
 }
}