Totala drifttiden av hårddisken i c++
Hej, jag skulle behöva lite hjälp med hur man får ut den totala drifttiden av hårddisken i c++. Detta är fullt möjligt om hårddisken stödjer S.M.A.R.T. Vad jag har förstått så skall man använda sig utav någon form av "DeviceIoControl".
Här är en kod i C som gör detta:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>
typedef struct _IDEREGS
{
UCHAR bFeaturesReg;
UCHAR bSectorCountReg;
UCHAR bSectorNumberReg;
UCHAR bCylLowReg;
UCHAR bCylHighReg;
UCHAR bDriveHeadReg;
UCHAR bCommandReg;
UCHAR bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
typedef struct _SENDCMDINPARAMS
{
ULONG cBufferSize;
IDEREGS irDriveRegs;
UCHAR bDriveNumber;
UCHAR bReserved[3];
ULONG dwReserved[4];
UCHAR bBuffer[1];
} _SENDCMDINPARAMS, *_PSENDCMDINPARAMS, *_LPSENDCMDINPARAMS;
typedef struct _GETVERSIONINPARAMS
{
UCHAR bVersion;
UCHAR bRevision;
UCHAR bReserved;
UCHAR bIDEDeviceMap;
ULONG fCapabilities;
ULONG dwReserved[4];
} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS;
#define READ_ATTRIBUTES 0xD0
#define IOCTL_DISK_BASE FILE_DEVICE_DISK
#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_SEND_DRIVE_COMMAND CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define ID_CMD 0xEC /* Returns ID sector for ATA*/
#define IDENTIFY_BUFFER_SIZE 512
#define SMART_CYL_LOW 0x4F
#define SMART_CYL_HI 0xC2
#define DRIVE_HEAD_REG 0xA0
#define SMART_CMD 0xB0
#define INDEX_ATTRIB_RAW 5
typedef struct
{
WORD wGenConfig;
WORD wNumCyls;
WORD wReserved;
WORD wNumHeads;
WORD wBytesPerTrack;
WORD wBytesPerSector;
WORD wSectorsPerTrack;
WORD wVendorUnique[3];
BYTE sSerialNumber[20];
WORD wBufferType;
WORD wBufferSize;
WORD wECCSize;
BYTE sFirmwareRev[8];
BYTE sModelNumber[39];
WORD wMoreVendorUnique;
WORD wDoubleWordIO;
WORD wCapabilities;
WORD wReserved1;
WORD wPIOTiming;
WORD wDMATiming;
WORD wBS;
WORD wNumCurrentCyls;
WORD wNumCurrentHeads;
WORD wNumCurrentSectorsPerTrack;
WORD ulCurrentSectorCapacity;
WORD wMultSectorStuff;
DWORD ulTotalAddressableSectors;
WORD wSingleWordDMA;
WORD wMultiWordDMA;
BYTE bReserved[127];
} ST_IDSECTOR;
typedef struct
{
BYTE m_ucAttribIndex;
DWORD m_dwAttribValue;
BYTE m_ucValue;
BYTE m_ucWorst;
DWORD m_dwThreshold;
} ST_SMART_INFO;
typedef struct
{
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[2];
DWORD dwReserved[2];
} ST_DRIVERSTAT;
typedef struct
{
DWORD cBufferSize;
ST_DRIVERSTAT DriverStatus;
BYTE bBuffer[1];
} ST_ATAOUTPARAM;
typedef struct
{
GETVERSIONINPARAMS m_stGVIP;
ST_IDSECTOR m_stInfo;
ST_SMART_INFO m_stSmartInfo[256];
BYTE m_ucSmartValues;
BYTE m_ucDriveIndex;
char m_csErrorString[MAX_PATH];
} ST_DRIVE_INFO;
void foo()
{
GETVERSIONINPARAMS GetVersionParams;
DWORD cbBytesReturned = 0;
memset (&GetVersionParams, 0, sizeof(GetVersionParams));
int drive = 0;
_SENDCMDINPARAMS cmd_send_params = {0};
BYTE szAttributes[sizeof(ST_ATAOUTPARAM) + 512 - 1];
for (drive = 0; drive < 20; drive++)
{
HANDLE hPhysicalDriveIOCTL = 0;
char driveName [256];
PBYTE pT1,pT3;
PDWORD pT2;
sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
/*GetVolumeInformationByHandle for Vista+*/
if ( 0!=DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION,
NULL,
0,
&GetVersionParams, sizeof (GETVERSIONINPARAMS),
&cbBytesReturned, NULL) )
{
cmd_send_params.bDriveNumber =drive;
cmd_send_params.irDriveRegs.bSectorCountReg = 1;
cmd_send_params.irDriveRegs.bSectorNumberReg = 1;
cmd_send_params.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
cmd_send_params.irDriveRegs.bCylHighReg = SMART_CYL_HI;
cmd_send_params.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
cmd_send_params.irDriveRegs.bCommandReg = SMART_CMD;
cmd_send_params.irDriveRegs.bFeaturesReg=READ_ATTRIBUTES;
cmd_send_params.cBufferSize=512;
if(0!=DeviceIoControl(hPhysicalDriveIOCTL,SMART_RCV_DRIVE_DATA,&cmd_send_params,sizeof(cmd_send_params),szAttributes,sizeof(ST_ATAOUTPARAM) + 512 - 1,&cbBytesReturned,NULL))
{
int ucT1;
pT1=(PBYTE)(((ST_ATAOUTPARAM*)szAttributes)->bBuffer);
for(ucT1=0; ucT1<30; ++ucT1)
{
pT2=(PDWORD)&pT1[2+ucT1*12+5];
pT3=&pT1[2+ucT1*12];
pT3[INDEX_ATTRIB_RAW+2]=pT3[INDEX_ATTRIB_RAW+3]=pT3[INDEX_ATTRIB_RAW+4]=pT3[INDEX_ATTRIB_RAW+5]=pT3[INDEX_ATTRIB_RAW+6]=0;
if ( 9 == pT3[0] )
printf("HOURS COUNT for %s %d\r\n",driveName, pT2[0]);
}
}
CloseHandle(hPhysicalDriveIOCTL);
}
}else if ( 2!=GetLastError()) printf("CreateFile() feailed %ld\r\n", GetLastError());
}
return;
}
int main()
{
foo();
return 0;
}
Denna koden kan dessvärre inte köras i vc++ 2010 (som jag behöver få koden att köras i), och jag har inte lyckats med att översätta koden så den fungerar i vc++ 2010.
Skulle vara mycket tacksam för vägledning och hjälp.