程式設計方式讀取硬碟資訊
阿新 • • 發佈:2019-01-30
MBR結構,在資料庫恢復中,若要手工填寫分割槽表的話,只注意四個重要的地方,其它的可隨便填。
#pragma pack(1) //位元組對齊 typedef struct _PARTITION_ENTRY//分割槽表結構 { UCHAR active; //狀態(是否被啟用) 重要 UCHAR StartHead; //分割槽起始磁頭號 //UCHAR StartSector; //分割槽起始扇區和柱面號,高2位為柱面號的第 9,10 位, 高位元組為柱面號的低 8 位 //UCHAR StartCylinder; // 起始磁碟柱面 USHORT StartSecCyli; //與63相位與得出的是開始扇區,把它右移6位就是開始柱面 UCHAR PartitionType; // 分割槽型別 重要 UCHAR EndHead; //分割槽結束磁頭號 //UCHAR EndSector; //分割槽結束扇區 //UCHAR EndCylinder; // 結束柱面號 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()
擴充套件分割槽暫時未寫,程式碼基本上copy+理解,主要是學習並理解分割槽表
執行如圖
void _ReadMbrPartiton(CListBox *listbox) { TCHAR szDevicename[64]={0}; char *drive = "1"; MBR_SECTOR _ReadMbr; wsprintf(szDevicename,"\\\\.\\PHYSICALDRIVE%c",*drive); HANDLE hDevice=CreateFile(szDevicename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hDevice == INVALID_HANDLE_VALUE) { //MessageBox("開啟裝置出錯"); return; } memset(&_ReadMbr,0,sizeof(MBR_SECTOR)); DWORD leng = 512; DWORD count; DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&count,NULL); BOOL bcheck = ReadFile(hDevice,&_ReadMbr,512,&leng,NULL); if (bcheck==FALSE || leng<512) { //MessageBox("讀取MBR出錯!"); DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &count, NULL); CloseHandle(hDevice); return; } listbox->ResetContent();//清除 TCHAR * szTemp = new TCHAR[64]; //char * Temp = new char[64]; //for for (int i=0;i<4;i++) { if (_ReadMbr.Partition[i].PartitionType==0) { continue; } memset(szTemp,0,64); //memset(Temp,0,64); if (_ReadMbr.Partition[i].active == 128) { strcat(szTemp,"Active "); } else { strcat(szTemp,"NotActive "); } if (_ReadMbr.Partition[i].PartitionType==5 || _ReadMbr.Partition[i].PartitionType==15 ) { strcat(szTemp,"Extended "); } listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"80=active partition:%02X",_ReadMbr.Partition[i].active); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"Start head:%d",_ReadMbr.Partition[i].StartHead); listbox->AddString(szTemp); memset(szTemp,0,64); int temp = _ReadMbr.Partition[i].StartSecCyli; wsprintf(szTemp,"Start sector:%d",temp & 63); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"Start cylinder:%d",temp>>6); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"Partition type indicator (hex):%02d",_ReadMbr.Partition[i].PartitionType); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"End head:%d",_ReadMbr.Partition[i].EndHead); listbox->AddString(szTemp); memset(szTemp,0,64); temp = _ReadMbr.Partition[i].EndSecCyli; wsprintf(szTemp,"End sector:%d",temp & 63); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"End cylinder:%d",temp>>6); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"Sectors preceding partition 1:%d",_ReadMbr.Partition[i].StartLBA); listbox->AddString(szTemp); memset(szTemp,0,64); wsprintf(szTemp,"Sectors in partition 1:%d",_ReadMbr.Partition[i].TotalSector); listbox->AddString(szTemp); //若是擴充套件分割槽 if (_ReadMbr.Partition[i].PartitionType=15 || _ReadMbr.Partition[i].PartitionType==5) { BOOL bcon = TRUE; //第一次進來儲存 0扇區到擴充套件分割槽的絕對扇區 while (bcon) { //未完 } } } //for DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &count, NULL); CloseHandle(hDevice); }