注册 登录
编程论坛 QT论坛

Qt DiviceIoCtl

fds294512126 发布于 2018-01-15 14:07, 3548 次点击
在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,求高手指教。
0 回复
1