📄 do_diskdlg.cpp
字号:
// Do_DiskDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Do_Disk.h"
#include "Do_DiskDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString MakeIdeInfo(int nDrive, int nType, IDINFO *pIdInfo)
{
CString strInfo;
CString strTmp;
if(nType == 0) // Use ATA/ATAPI directly
{
strInfo.Format("Physical drive %d ----\r\n", nDrive);
}
else // Use SCSI driver instead of IDE driver
{
if(nType/2 == 0) strInfo = "Primary ";
else strInfo = "Secondary ";
if(nType%2 == 0) strInfo = " master drive ----\r\n";
else strInfo += " master drive ---- \r\n";
}
strTmp = pIdInfo->sModelNumber;
strInfo += " Model number: " + strTmp.Left(40) + "\r\n";
strTmp = pIdInfo->sSerialNumber;
strInfo += " Serial number: " + strTmp.Left(20) + "\r\n";
strTmp = pIdInfo->sFirmwareRev;
strInfo += " Firmware reversion: " + strTmp.Left(8) + "\r\n";
if(*(WORD*)&pIdInfo->wMajorVersion != 0 && *(WORD*)&pIdInfo->wMajorVersion != 0xffff)
{
strTmp.Empty();
if(pIdInfo->wMajorVersion.ATA1)
{
strTmp += "ATA-1";
}
if(pIdInfo->wMajorVersion.ATA2)
{
strTmp += ", ATA-2";
}
if(pIdInfo->wMajorVersion.ATA3)
{
strTmp += ", ATA-3";
}
if(pIdInfo->wMajorVersion.ATA4)
{
strTmp += ", ATA/ATAPI-4";
}
if(pIdInfo->wMajorVersion.ATA5)
{
strTmp += ", ATA/ATAPI-5";
}
if(pIdInfo->wMajorVersion.ATA6)
{
strTmp += ", ATA/ATAPI-6";
}
strInfo += " ATA/ATAPI versions supported: " + strTmp + "\r\n";
}
strTmp.Format("%u", pIdInfo->wBufferSize * 512);
strInfo += " Buffer size on drive: " + strTmp + " bytes\r\n";
strTmp.Format("%u", pIdInfo->wNumCyls);
strInfo += " Cylinders: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->wNumHeads);
strInfo += " Heads: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->wNumSectorsPerTrack);
strInfo += " Sectors per track: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->dwTotalSectors);
strInfo += " Total sectors: " + strTmp + "\r\n";
strTmp.Format("%I64d", (ULONGLONG)pIdInfo->dwTotalSectors * 512);
strInfo += " Total size: " + strTmp + " bytes\r\n";
if(pIdInfo->wFieldValidity.CHSNumber)
{
strTmp.Format("%u", pIdInfo->wNumCurCyls);
strInfo += " Addressable cylinders in CHS translation: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->wNumCurHeads);
strInfo += " Addressable heads in CHS translation: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->wNumCurSectorsPerTrack);
strInfo += " Addressable sectors per track in CHS translation: " + strTmp + "\r\n";
strTmp.Format("%u", pIdInfo->wCurSectorsLow + pIdInfo->wCurSectorsHigh * 65536);
strInfo += " Addressable sectors in CHS translation: " + strTmp + "\r\n";
strTmp.Format("%I64d", (ULONGLONG)(pIdInfo->wCurSectorsLow + pIdInfo->wCurSectorsHigh * 65536) * 512);
strInfo += " Addressable size in CHS translation: " + strTmp + " bytes\r\n";
}
strTmp.Format("%d", pIdInfo->wPIOCapacity.AdvPOIModes);
strInfo += " Advanced PIO modes supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.DMA ? "Yes" : "No";
strInfo += " DMA supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.LBA ? "Yes" : "No";
strInfo += " LBA supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.IORDY ? "Yes" : "No";
strInfo += " IORDY supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.DisIORDY ? "Yes" : "No";
strInfo += " IORDY may be disabled: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.Overlap ? "Yes" : "No";
strInfo += " Overlap operation supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.Queue ? "Yes" : "No";
strInfo += " Command queuing supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wCapabilities.InlDMA ? "Yes" : "No";
strInfo += " Interleaved DMA supported: " + strTmp + "\r\n";
if(pIdInfo->wFieldValidity.UnltraDMA)
{
strTmp = pIdInfo->wUltraDMA.Mode0 ? "Yes" : "No";
strInfo += " Ultra DMA mode 0 (16.7Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode1 ? "Yes" : "No";
strInfo += " Ultra DMA mode 1 (25Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode2 ? "Yes" : "No";
strInfo += " Ultra DMA mode 2 (33Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode3 ? "Yes" : "No";
strInfo += " Ultra DMA mode 3 (44Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode4 ? "Yes" : "No";
strInfo += " Ultra DMA mode 4 (66Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode5 ? "Yes" : "No";
strInfo += " Ultra DMA mode 5 (100Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode6 ? "Yes" : "No";
strInfo += " Ultra DMA mode 6 (133Mb/s) supported: " + strTmp + "\r\n";
strTmp = pIdInfo->wUltraDMA.Mode7 ? "Yes" : "No";
strInfo += " Ultra DMA mode 7 (166Mb/s) supported: " + strTmp + "\r\n";
if(pIdInfo->wUltraDMA.Mode0Sel)
{
strInfo += " Ultra DMA mode currently selected: 0\r\n";
}
if(pIdInfo->wUltraDMA.Mode1Sel)
{
strInfo += " Ultra DMA mode currently selected: 1\r\n";
}
if(pIdInfo->wUltraDMA.Mode2Sel)
{
strInfo += " Ultra DMA mode currently selected: 2\r\n";
}
if(pIdInfo->wUltraDMA.Mode3Sel)
{
strInfo += " Ultra DMA mode currently selected: 3\r\n";
}
if(pIdInfo->wUltraDMA.Mode4Sel)
{
strInfo += " Ultra DMA mode currently selected: 4\r\n";
}
if(pIdInfo->wUltraDMA.Mode5Sel)
{
strInfo += " Ultra DMA mode currently selected: 5\r\n";
}
if(pIdInfo->wUltraDMA.Mode6Sel)
{
strInfo += " Ultra DMA mode currently selected: 6\r\n";
}
if(pIdInfo->wUltraDMA.Mode7Sel)
{
strInfo += " Ultra DMA mode currently selected: 7\r\n";
}
}
return strInfo;
}
HANDLE OpenDevice(LPCTSTR filename)
{
HANDLE hDevice;
// 打开设备
hDevice= ::CreateFile(filename, // 文件名
GENERIC_READ | GENERIC_WRITE, // 读写方式
FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享方式
NULL, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
NULL); // 不需参照模板文件
return hDevice;
}
// 向驱动发“IDENTIFY DEVICE”命令,获得设备信息
// hDevice: 设备句柄
// pIdInfo: 设备信息结构指针
BOOL IdentifyDevice(HANDLE hDevice, PIDINFO pIdInfo)
{
PSENDCMDINPARAMS pSCIP; // 输入数据结构指针
PSENDCMDOUTPARAMS pSCOP; // 输出数据结构指针
DWORD dwOutBytes; // IOCTL输出数据长度
BOOL bResult; // IOCTL返回值
// 申请输入/输出数据结构空间
pSCIP = (PSENDCMDINPARAMS)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SENDCMDINPARAMS)-1);
pSCOP = (PSENDCMDOUTPARAMS)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SENDCMDOUTPARAMS)+sizeof(IDINFO)-1);
// 指定ATA/ATAPI命令的寄存器值
// pSCIP->irDriveRegs.bFeaturesReg = 0;
// pSCIP->irDriveRegs.bSectorCountReg = 0;
// pSCIP->irDriveRegs.bSectorNumberReg = 0;
// pSCIP->irDriveRegs.bCylLowReg = 0;
// pSCIP->irDriveRegs.bCylHighReg = 0;
// pSCIP->irDriveRegs.bDriveHeadReg = 0;
pSCIP->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
// 指定输入/输出数据缓冲区大小
pSCIP->cBufferSize = 0;
pSCOP->cBufferSize = sizeof(IDINFO);
// IDENTIFY DEVICE
bResult = ::DeviceIoControl(hDevice, // 设备句柄
DFP_RECEIVE_DRIVE_DATA, // 指定IOCTL
pSCIP, sizeof(SENDCMDINPARAMS) - 1, // 输入数据缓冲区
pSCOP, sizeof(SENDCMDOUTPARAMS) + sizeof(IDINFO) - 1, // 输出数据缓冲区
&dwOutBytes, // 输出数据长度
(LPOVERLAPPED)NULL); // 用同步I/O
// 复制设备参数结构
::memcpy(pIdInfo, pSCOP->bBuffer, sizeof(IDINFO));
// 释放输入/输出数据空间
::GlobalFree(pSCOP);
::GlobalFree(pSCIP);
return bResult;
}
// 向SCSI MINI-PORT驱动发“IDENTIFY PACKET DEVICE”命令,获得设备信息
// hDevice: 设备句柄
// pIdInfo: 设备信息结构指针
BOOL IdentifyDeviceAsScsi(HANDLE hDevice, int nDrive, PIDINFO pIdInfo)
{
PSENDCMDINPARAMS pSCIP; // 输入数据结构指针
PSENDCMDOUTPARAMS pSCOP; // 输出数据结构指针
PSRB_IO_CONTROL pSRBIO; // SCSI输入输出数据结构指针
DWORD dwOutBytes; // IOCTL输出数据长度
BOOL bResult; // IOCTL返回值
// 申请输入/输出数据结构空间
pSRBIO = (PSRB_IO_CONTROL)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDOUTPARAMS)+sizeof(IDINFO)-1);
pSCIP = (PSENDCMDINPARAMS)((char *)pSRBIO+sizeof(SRB_IO_CONTROL));
pSCOP = (PSENDCMDOUTPARAMS)((char *)pSRBIO+sizeof(SRB_IO_CONTROL));
// 填充输入/输出数据
pSRBIO->HeaderLength = sizeof(SRB_IO_CONTROL);
pSRBIO->Timeout = 10000;
pSRBIO->Length = sizeof(SENDCMDOUTPARAMS)+sizeof(IDINFO)-1;
pSRBIO->ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
::strncpy ((char *)pSRBIO->Signature, "SCSIDISK", 8);
// 指定ATA/ATAPI命令的寄存器值
// pSCIP->irDriveRegs.bFeaturesReg = 0;
// pSCIP->irDriveRegs.bSectorCountReg = 0;
// pSCIP->irDriveRegs.bSectorNumberReg = 0;
// pSCIP->irDriveRegs.bCylLowReg = 0;
// pSCIP->irDriveRegs.bCylHighReg = 0;
// pSCIP->irDriveRegs.bDriveHeadReg = 0;
pSCIP->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
pSCIP->bDriveNumber = nDrive;
// IDENTIFY DEVICE
bResult = ::DeviceIoControl(hDevice, // 设备句柄
IOCTL_SCSI_MINIPORT, // 指定IOCTL
pSRBIO, sizeof(SRB_IO_CONTROL) +sizeof(SENDCMDINPARAMS) - 1, // 输入数据缓冲区
pSRBIO, sizeof(SRB_IO_CONTROL) +sizeof(SENDCMDOUTPARAMS) + sizeof(IDINFO) - 1, // 输出数据缓冲区
&dwOutBytes, // 输出数据长度
(LPOVERLAPPED)NULL); // 用同步I/O
// 复制设备参数结构
::memcpy(pIdInfo, pSCOP->bBuffer, sizeof(IDINFO));
// 释放输入/输出数据空间
::GlobalFree(pSRBIO);
return bResult;
}
// 将串中的字符两两颠倒
// 原因是ATA/ATAPI中的WORD,与Windows采用的字节顺序相反
// 驱动程序中已经将收到的数据全部反过来,我们来个负负得正
void AdjustString(char* str, int len)
{
char ch;
int i;
// 两两颠倒
for(i=0;i<len;i+=2)
{
ch = str[i];
str[i] = str[i+1];
str[i+1] = ch;
}
// 若是右对齐的,调整为左对齐 (去掉左边的空格)
i=0;
while(i<len && str[i]==' ') i++;
::memmove(str, &str[i], len-i);
// 去掉右边的空格
i = len - 1;
while(i>=0 && str[i]==' ')
{
str[i] = '\0';
i--;
}
}
// 读取IDE硬盘的设备信息,必须有足够权限
// nDrive: 驱动器号(0=第一个硬盘,1=0=第二个硬盘,......)
// pIdInfo: 设备信息结构指针
BOOL GetPhysicalDriveInfoInNT(int nDrive, PIDINFO pIdInfo)
{
HANDLE hDevice; // 设备句柄
BOOL bResult; // 返回结果
char szFileName[40]; // 文件名
::sprintf(szFileName,"\\\\.\\PhysicalDrive%d", nDrive);
hDevice = ::OpenDevice(szFileName);
if(hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}
// IDENTIFY DEVICE
bResult = ::IdentifyDevice(hDevice, pIdInfo);
if(bResult)
{
// 调整字符串
::AdjustString(pIdInfo->sSerialNumber, 20);
::AdjustString(pIdInfo->sModelNumber, 40);
::AdjustString(pIdInfo->sFirmwareRev, 8);
}
::CloseHandle (hDevice);
return bResult;
}
// 用SCSI驱动读取IDE硬盘的设备信息,不受权限制约
// nDrive: 驱动器号(0=Primary Master, 1=Promary Slave, 2=Secondary master, 3=Secondary slave)
// pIdInfo: 设备信息结构指针
BOOL GetIdeDriveAsScsiInfoInNT(int nDrive, PIDINFO pIdInfo)
{
HANDLE hDevice; // 设备句柄
BOOL bResult; // 返回结果
char szFileName[20]; // 文件名
::sprintf(szFileName,"\\\\.\\Scsi%d:", nDrive/2);
hDevice = ::OpenDevice(szFileName);
if(hDevice == INVALID_HANDLE_VALUE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -