有些时候,我们读取磁盘文件,会被hook.我们读到的可能并非实际的文件。

我们直接读取磁盘扇区获取数据。

实现磁盘数据的读写,不依赖WindowsAPI。

 

void CSectorEdit2000Dlg::OnView() 
{
	UpdateData(TRUE);
	if (m_uTo < m_uFrom)
		return;
	
	char cTemp[1];
	memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
	UINT uDiskID = cTemp[0] - 64;

	DWORD dwSectorNum = m_uTo - m_uFrom + 1;
	if (dwSectorNum > 100)
		return;

	unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
	
	if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
	{
		MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
		return;
	}
	
	char* cBuf = new char[dwSectorNum * 5120];
	memset(cBuf, 0, sizeof(cBuf));

	for (DWORD i = 0; i < dwSectorNum * 512; i++)
	{
		sprintf(cBuf, "%s%02X ", cBuf, bBuf[i]);

		if ((i % 512) == 511)
			sprintf(cBuf, "%s\r\n第%d扇区\r\n", cBuf, (int)(i / 512) + m_uFrom);
		if ((i % 16) == 15)
			sprintf(cBuf, "%s\r\n", cBuf);
		else if ((i % 16) == 7)
			sprintf(cBuf, "%s- ", cBuf);
	}
	SetDlgItemText(IDC_DATA, cBuf);
	delete[] bBuf;
	delete[] cBuf;
}

void CSectorEdit2000Dlg::OnCleardata() 
{
	UpdateData(TRUE);

	char cTemp[1];
	memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
	UINT uDiskID = cTemp[0] - 64;
	if (uDiskID > 2)
	{
		if (MessageBox("要清理的是硬盘分区,请确认是否继续?", "提示", MB_YESNO | MB_ICONWARNING) != 6)
			return;
		if (uDiskID == 3)
		{
			if (MessageBox("要清理的是系统分区,请再次确认是否继续?", "提示", MB_YESNO | MB_ICONWARNING) != 6)
				return;
		}
	}
	
	unsigned char bBuf[512];

	UINT i = 0;
	BOOL bRet = TRUE;
	while (m_bAllDisk)		
	{
		memset(bBuf, 0xFF, sizeof(bBuf));
		bRet = WriteSectors(uDiskID, i, 1, bBuf);
		memset(bBuf, 0, sizeof(bBuf));
		bRet = WriteSectors(uDiskID, i, 1, bBuf);
		
		if (bRet == FALSE)
		{
			if (i == 0)
				MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
			else
				MessageBox("磁盘数据擦除完毕!", "错误", MB_OK | MB_ICONERROR);
			return;
		}
		i++;
	}	

	if (m_bAllDisk == FALSE)
	{
		for (DWORD i = m_uFrom; i <= m_uTo; i++)
		{
			memset(bBuf, 0xFF, sizeof(bBuf));
			bRet = WriteSectors(uDiskID, i, 1, bBuf);
			memset(bBuf, 0, sizeof(bBuf));
			bRet = WriteSectors(uDiskID, i, 1, bBuf);
			if (bRet == FALSE)
			{
				if (i == 0)
					MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
				else
					MessageBox("磁盘数据擦除完毕!", "提示", MB_OK | MB_ICONINFORMATION);
				return;
			}
		}
	}
}


void CSectorEdit2000Dlg::OnBackup() 
{
	UpdateData(TRUE);
	if (m_uTo < m_uFrom)
		return;

	CFileDialog fileDlg(FALSE, "*.sec", "*.sec", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "磁盘扇区数据(*.sec)|*.sec||", NULL);
	CFile file;
	if (fileDlg.DoModal() != IDOK)
		return;
	
	file.Open(fileDlg.GetPathName(), CFile::modeCreate | CFile::modeReadWrite);
	char cTemp[1];
	memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
	UINT uDiskID = cTemp[0] - 64;

	DWORD dwSectorNum = m_uTo - m_uFrom + 1;
	unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
	
	if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
	{
		MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
		return;
	}

	file.Write(bBuf, dwSectorNum * 512);
	file.Close();

	delete[] bBuf;

	MessageBox("数据备份完毕!", "提示", MB_OK | MB_ICONINFORMATION);
}

void CSectorEdit2000Dlg::OnRestore() 
{
	UpdateData(TRUE);
	
	char cTemp[1];
	memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
	UINT uDiskID = cTemp[0] - 64;

	CFileDialog fileDlg(TRUE, "*.sec", "*.sec", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "磁盘扇区数据(*.sec)|*.sec||", NULL);
	CFile file;
	if (fileDlg.DoModal() != IDOK)
		return;

	file.Open(fileDlg.GetPathName(), CFile::modeReadWrite);
	DWORD dwSectorNum = file.GetLength();
	if (dwSectorNum % 512 != 0)
		return;
	dwSectorNum /= 512;

	unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
	file.Read(bBuf, dwSectorNum * 512);

	if (WriteSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
	{
		MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
		return;
	}

	file.Close();
	delete[] bBuf;

	MessageBox("数据恢复完毕!", "提示", MB_OK | MB_ICONINFORMATION);
}

BOOL CSectorEdit2000Dlg::WriteSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)
{
	if (bDrive == 0)
		return 0;

	char devName[] = "\\\\.\\A:";
	devName[4] ='A' + bDrive - 1;
	HANDLE hDev;
	if(m_bPhysicalDisk==false)
	{
		hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	}
	else
		hDev = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);


	if (hDev == INVALID_HANDLE_VALUE)
		return 0;

	SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

	DWORD dwCB;
	BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
	CloseHandle(hDev);
	return bRet;
}

BOOL CSectorEdit2000Dlg::ReadSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)
{
	if (bDrive == 0)
		return 0;

	char devName[] = "\\\\.\\A:";
	devName[4] ='A' + bDrive - 1;
	HANDLE hDev;
	if(m_bPhysicalDisk==false)
		hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	else
		hDev = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (hDev == INVALID_HANDLE_VALUE)
		return 0;

	SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

	DWORD dwCB;
	BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
	CloseHandle(hDev);
	return bRet;
}

void CSectorEdit2000Dlg::OnSelchangeComboDrive() 
{
	// TODO: Add your control notification handler code here
	int s;

	s = m_DrvListBox.GetCurSel();
	if( s != CB_ERR )
		m_DrvListBoxSResult = ( const char * )m_DrvListBox.GetItemDataPtr( m_DrvListBox.GetCurSel());

}

void CSectorEdit2000Dlg::OnCheck() 
{
	// TODO: Add your control notification handler code here
	m_bPhysicalDisk=!m_bPhysicalDisk;
	if(m_bPhysicalDisk==true)
	{
		GetDlgItem( IDC_COMBO_DRIVE)->EnableWindow( false );
	}
	if(m_bPhysicalDisk==false)
	{
		GetDlgItem( IDC_COMBO_DRIVE)->EnableWindow( true );
	}	
}