写了一个类型,用于读取硬盘物理参数。基本测试通过,容量计算上好象有些问题
/****************************************************
Module: DiskType.h
Notices: Copyright (c) 2008 WangYu
*****************************************************/
#ifndef __DISKTYPE
#define __DISKTYPE
#include <iostream>
#include <string>
#include <sstream>
#include <windows.h>
using namespace std;
typedef struct _GETVERSIONOUTPARAMS {
BYTE bVersion;
BYTE bRevision;
BYTE bReserved;
BYTE bIDEDeviceMap;
DWORD fCapabilities;
DWORD dwReserved[4];
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
typedef struct _IDEREGS {
BYTE bFeaturesReg;
BYTE bSectorCountReg;
BYTE bSectorNumberReg;
BYTE bCylLowReg;
BYTE bCylHighReg;
BYTE bDriveHeadReg;
BYTE bCommandReg;
BYTE bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
typedef struct _SENDCMDINPARAMS {
DWORD cBufferSize;
IDEREGS irDriveRegs;
BYTE bDriveNumber;
BYTE bReserved[3];
DWORD dwReserved[4];
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
typedef struct _DRIVERSTATUS {
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[2];
DWORD dwReserved[2];
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
typedef struct _SENDCMDOUTPARAMS {
DWORD cBufferSize;
DRIVERSTATUS DriverStatus;
BYTE bBuffer[512];
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
typedef struct _IDSECTOR {
USHORT wGenConfig;
USHORT wNumCyls;
USHORT wReserved;
USHORT wNumHeads;
USHORT wBytesPerTrack;
USHORT wBytesPerSector;
USHORT wSectorsPerTrack;
USHORT wVendorUnique[3];
CHAR sSerialNumber[20];
USHORT wBufferType;
USHORT wBufferSize;
USHORT wECCSize;
CHAR sFirmwareRev[8];
CHAR sModelNumber[40];
USHORT wMoreVendorUnique;
USHORT wDoubleWordIO;
USHORT wCapabilities;
USHORT wReserved1;
USHORT wPIOTiming;
USHORT wDMATiming;
USHORT wBS;
USHORT wNumCurrentCyls;
USHORT wNumCurrentHeads;
USHORT wNumCurrentSectorsPerTrack;
ULONG ulCurrentSectorCapacity;
USHORT wMultSectorStuff;
ULONG ulTotalAddressableSectors;
USHORT wSingleWordDMA;
USHORT wMultiWordDMA;
BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;
const DWORD DFP_GET_VERSION = 0x00074080;
const DWORD DFP_SEND_DRIVE_COMMAND = 0x0007c084;
const DWORD DFP_RECEIVE_DRIVE_DATA = 0x0007c088;
class DiskType{
friend ostream& operator<<(ostream& , const DiskType&);
public:
DiskType(int theDisk = 0)
{
j = theDisk;
GetDiskInfo();
}
ostringstream errmsg;
protected:
void ChangeByteOrder(PCHAR, USHORT);
void GetDiskInfo(void);
private:
GETVERSIONOUTPARAMS vers;
SENDCMDINPARAMS in;
SENDCMDOUTPARAMS out;
HANDLE h;
DWORD i;
BYTE j;
char hd[80];
PIDSECTOR phdinfo;
char s[41];
string Module, Firmware, Serial;
ostringstream Capacity;
};
#endif
/******************************************************
Module: DiskType.cpp
Notices: Copyright (c) 2008 WangYu
******************************************************/
#include "DiskType.h"
inline void DiskType::GetDiskInfo()
{
ZeroMemory(&vers,sizeof(vers));
sprintf(hd,"\\\\.\\PhysicalDrive%d",j);
h=CreateFile(hd, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if(!DeviceIoControl(h, DFP_GET_VERSION, 0, 0, &vers, sizeof(vers), &i, 0))
CloseHandle(h);
//If IDE identify command not supported, fails
if(!(vers.fCapabilities & 1))
{
errmsg << "Error: IDE identify command not supported." << endl;
CloseHandle(h);
return;
}
//Identify the IDE drives
ZeroMemory(&in,sizeof(in));
ZeroMemory(&out,sizeof(out));
if(j&1)
in.irDriveRegs.bDriveHeadReg=0xb0;
else
in.irDriveRegs.bDriveHeadReg=0xa0;
if(vers.fCapabilities & (16>>j) )
{
//We don't detect a ATAPI device.
errmsg << "Drive "<< (int)(j+1) << " is a ATAPI device, we don't detect it" << endl;
}else
in.irDriveRegs.bCommandReg=0xec;
in.bDriveNumber=j;
in.irDriveRegs.bSectorCountReg=1;
in.irDriveRegs.bSectorNumberReg=1;
in.cBufferSize=512;
if(!DeviceIoControl(h, DFP_RECEIVE_DRIVE_DATA, &in, sizeof(in), &out, sizeof(out), &i, 0))
{
errmsg << "DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA" << endl;
CloseHandle(h);
return;
}
phdinfo=(PIDSECTOR)out.bBuffer;
memcpy(s,phdinfo->sModelNumber,40);
s[40]=0;
ChangeByteOrder(s,40);
Module = s;
memcpy(s,phdinfo->sFirmwareRev,8);
s[8]=0;
ChangeByteOrder(s,8);
Firmware = s;
memcpy(s,phdinfo->sSerialNumber,20);
s[20]=0;
ChangeByteOrder(s,20);
Serial = s;
Capacity << phdinfo->ulTotalAddressableSectors/2/1024<< "M" << endl;
CloseHandle(h);
}
inline void DiskType::ChangeByteOrder(PCHAR szString,USHORT uscStrSize)
{
USHORT i;
CHAR temp;
for(i = 0; i < uscStrSize; i += 2)
{
temp = szString[i];
szString[i] = szString[i+1];
szString[i+1] = temp;
}
}
inline ostream& operator<<(ostream& os, const DiskType& dt)
{
os << "Module Number: "
<< dt.Module << endl
<< "Firmware rev: "
<< dt.Firmware << endl
<< "Serial Number: "
<< dt.Serial << endl
<< "Capacity: "
<< dt.Capacity.str() << endl
<< "other message ---- " << endl
<< dt.errmsg.str();
return os;
}
int main()
{
DiskType dt;
cout << dt;
return 0;
}