Totala drifttiden av hårddisken i c++

Permalänk
Medlem

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; }

Dold text

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.

Permalänk
Hedersmedlem

Den här kan köras i alla fall (kanske är inte smart aktiverat på den här datorn...)

#include <stdio.h> #include <windows.h> #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; }

Dold text

(Ändra "Character Set" från "Use Unicode Character Set" i projektinställningarna)

Permalänk
Medlem

Får dessa error när jag försöker köra koden:

error LNK2001: unresolved external symbol _main C:\Visual Studio 2010\Projects\test\test\MSVCRT.lib(crtexe.obj)

error LNK1120: 1 unresolved externals C:\Visual Studio 2010\Projects\test\Release\test.exe

Permalänk
Hedersmedlem
Skrivet av scared:

Får dessa error när jag försöker köra koden:

error LNK2001: unresolved external symbol _main C:\Visual Studio 2010\Projects\test\test\MSVCRT.lib(crtexe.obj)

error LNK1120: 1 unresolved externals C:\Visual Studio 2010\Projects\test\Release\test.exe

Skapa till exempel ett nytt win32 console application-projekt och kör foo() från main-funktionen i den.

Permalänk
Medlem

Lyckades lösa det Tack för hjälpen.