在win7下用qt 4.8.3的库做硬盘SMART(Self_Minotoring And Reporting Technology)信息读取,代码如下:
const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 读取ATAPI设备的命令
const WORD IDE_ATA_IDENTIFY = 0xEC;
#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
typedef struct _IDEREGS {
BYTE bFeaturesReg; // Used for specifying SMART "commands".
BYTE bSectorCountReg; // IDE sector count register
BYTE bSectorNumberReg; // IDE sector number register
BYTE bCylLowReg; // IDE low order cylinder value
BYTE bCylHighReg; // IDE high order cylinder value
BYTE bDriveHeadReg; // IDE drive/head register
BYTE bCommandReg; // Actual IDE command.
BYTE bReserved; // reserved for future use. Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;
typedef struct _SENDCMDOUTPARAMS {
DWORD cBufferSize; // Size of bBuffer in bytes
DRIVERSTATUS DriverStatus; // Driver status structure.
BYTE bBuffer[1]; // Buffer of arbitrary length in which to store the data read from the // drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
typedef struct _SENDCMDINPARAMS {
DWORD cBufferSize; // Buffer size in bytes
IDEREGS irDriveRegs; // Structure with drive register values.
BYTE bDriveNumber; // Physical drive number to send
// command to (0,1,2,3).
BYTE bReserved[3]; // Reserved for future expansion.
DWORD dwReserved[4]; // For future use.
BYTE bBuffer[1]; // Input buffer.
}SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
typedef struct _GETVERSIONINPARAMS {
BYTE bVersion; // Binary driver version.
BYTE bRevision; // Binary driver revision.
BYTE bReserved; // Not used.
BYTE bIDEDeviceMap; // Bit map of IDE devices.
DWORD fCapabilities; // Bit mask of driver capabilities.
DWORD dwReserved[4]; // For future use.
} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS;
DWORD GetDiskModelNumber(DWORD driver, CHAR *modelNumber)
{
CHAR sFilePath[DISK_PATH_LEN];
BOOL result; // results flag
DWORD readed; // discard results
HANDLE hDevice;
WORD i;
sprintf(sFilePath, "\\\\.\\PHYSICALDRIVE%d", driver);
hDevice = CreateFile( sFilePath,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
return (DWORD)-1;
}
GETVERSIONINPARAMS gvopVersionParams;
result = DeviceIoControl( hDevice, SMART_GET_VERSION, NULL,0,&gvopVersionParams,sizeof(gvopVersionParams), &readed,NULL);
if (!result) //fail
{
fprintf(stderr, "SMART_GET_VERSION Error: %ld\n", GetLastError());
(void)CloseHandle(hDevice);
return (DWORD)-1;
}
if(0 == gvopVersionParams.bIDEDeviceMap)
{
return (DWORD)-1;
}
// IDE or ATAPI IDENTIFY cmd
BYTE btIDCmd;
SENDCMDINPARAMS inParams;
BYTE nDrive =0;
btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
// output structure
BYTE outParams[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; // + 512 - 1
//fill in the input buffer
inParams.cBufferSize = 0; //or IDENTIFY_BUFFER_SIZE ?
inParams.irDriveRegs.bFeaturesReg = READ_ATTRIBUTES;
inParams.irDriveRegs.bSectorCountReg = 1;
inParams.irDriveRegs.bSectorNumberReg = 1;
inParams.irDriveRegs.bCylLowReg = 0;
inParams.irDriveRegs.bCylHighReg = 0;
inParams.irDriveRegs.bDriveHeadReg = (nDrive & 1) ? 0xB0 : 0xA0;
inParams.irDriveRegs.bCommandReg = btIDCmd;
//inParams.bDriveNumber = nDrive;
//get the attributes
result = DeviceIoControl(hDevice,SMART_RCV_DRIVE_DATA, &inParams, sizeof(SENDCMDINPARAMS) - 1,outParams,sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,&readed, NULL);
if (!result) //fail
{
fprintf(stderr, "SMART_RCV_DRIVE_DATA Error: %ld\n", GetLastError());
(void)CloseHandle(hDevice);
return (DWORD)-1;
}
(void)CloseHandle(hDevice);
}
执行过程中gvopVersionParams.bIDEDeviceMap ==0,求高手指教。