C/C++實現(xiàn)獲取硬盤序列號的示例代碼
更新時間:2023年11月17日 08:59:27 作者:lyshark
獲取硬盤的序列號、型號和固件版本號,此類功能通常用于做硬盤綁定或硬件驗證操作,下面我們就來學習一下如何使用C/C++實現(xiàn)獲取硬盤序列號吧
獲取硬盤的序列號、型號和固件版本號,此類功能通常用于做硬盤綁定或硬件驗證操作,通過使用Windows API
的DeviceIoControl
函數(shù)與物理硬盤驅動程序進行通信,發(fā)送ATA
命令來獲取硬盤的信息。
以下是該程序的主要功能和流程:
定義常量 IDE_ATAPI_IDENTIFY
和 IDE_ATA_IDENTIFY
分別表示讀取 ATAPI
設備和 ATA
設備信息的命令。
- 實現(xiàn)
Trim
函數(shù),用于去除字符串首尾的空格。 - 實現(xiàn)
ConvertToString
函數(shù),用于將DWORD
數(shù)組轉換為字符串,并通過Trim
函數(shù)去除首尾空格。 - 實現(xiàn)
DoIdentify
函數(shù),該函數(shù)通過DeviceIoControl
發(fā)送SMART
命令,獲取硬盤的詳細信息。 - 實現(xiàn)
GetDiskInfo
函數(shù),該函數(shù)打開物理硬盤設備,并調用DoIdentify
獲取硬盤序列號、型號和固件版本號。
在 main
函數(shù)中,通過調用 GetDiskInfo
獲取硬盤信息,并輸出到控制臺。
#define _CRT_SECURE_NO_WARNINGS #include <windows.h> #include <iostream> #include <winioctl.h> #include <string> const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 讀取ATAPI設備的命令 const WORD IDE_ATA_IDENTIFY = 0xEC; // 讀取ATA設備的命令 // 去除字符串首尾的空格 BOOL Trim(char* szStr) { int i = 0, j = 0, iFirst = -1, iLast = -1; int iLen = strlen(szStr); char szTemp[256] = { 0 }; // 從前往后遍歷,獲取第一個不為 空格 的下標 for (i = 0; i < iLen; i++) { if (' ' != szStr[i]) { iFirst = i; break; } } // 從后往前遍歷,獲取第一個不為 空格 的下標 for (i = (iLen - 1); 0 <= i; i--) { if (' ' != szStr[i]) { iLast = i; break; } } // 字符串全為 空格 if (-1 == iFirst || -1 == iLast) { return FALSE; } // 獲取去除 空格 部分 for (i = iFirst; i <= iLast; i++) { szTemp[j] = szStr[i]; j++; } szTemp[j] = '\0'; strcpy(szStr, szTemp); return TRUE; } // 數(shù)據(jù)轉換 char* __fastcall ConvertToString(DWORD dwDiskData[256],int iFirstIndex,int iLastIndex) { static char szResBuf[256]; int iIndex = 0; int iPosition = 0; for (iIndex = iFirstIndex; iIndex <= iLastIndex; iIndex++) { szResBuf[iPosition] = (char)(dwDiskData[iIndex] / 256); iPosition++; // Get low BYTE for 2nd character szResBuf[iPosition] = (char)(dwDiskData[iIndex] % 256); iPosition++; } szResBuf[iPosition] = '\0'; // 刪除首尾的空格 Trim(szResBuf); return szResBuf; } BOOL __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL,PSENDCMDINPARAMS pSCIP,PSENDCMDOUTPARAMS pSCOP,BYTE btIDCmd,BYTE btDriveNum,PDWORD pdwBytesReturned) { pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE; pSCIP->irDriveRegs.bFeaturesReg = 0; pSCIP->irDriveRegs.bSectorCountReg = 1; pSCIP->irDriveRegs.bSectorNumberReg = 1; pSCIP->irDriveRegs.bCylLowReg = 0; pSCIP->irDriveRegs.bCylHighReg = 0; pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0; pSCIP->irDriveRegs.bCommandReg = btIDCmd; pSCIP->bDriveNumber = btDriveNum; return DeviceIoControl(hPhysicalDriveIOCTL,SMART_RCV_DRIVE_DATA,(LPVOID)pSCIP,sizeof(SENDCMDINPARAMS) - 1, (LPVOID)pSCOP,sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,pdwBytesReturned,NULL); return FALSE; } int GetDiskInfo(int iDriver, char* szSerialNumber, char* szModelNumber, char* szFirmwareNumber) { char szFilePath[64] = { 0 }; sprintf(szFilePath, "\\\\.\\PHYSICALDRIVE%d", iDriver); // 打開設備 HANDLE hFile = CreateFileA(szFilePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) { return -1; } // 發(fā)送控制代碼到指定設備驅動程序 DWORD dwBytesReturned = 0; GETVERSIONINPARAMS gvopVersionParam; DeviceIoControl(hFile,SMART_GET_VERSION,NULL,0,&gvopVersionParam,sizeof(gvopVersionParam),&dwBytesReturned,NULL); if (0 >= gvopVersionParam.bIDEDeviceMap) { return -2; } // IDE or ATAPI IDENTIFY cmd unsigned int uiIDCmd = 0; SENDCMDINPARAMS InParams; unsigned int uiDrive = 0; uiIDCmd = (gvopVersionParam.bIDEDeviceMap >> uiDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; // 輸出參數(shù) BYTE btOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; if (FALSE == DoIdentify(hFile,&InParams,(SENDCMDOUTPARAMS*)btOutCmd,(BYTE)uiIDCmd,(BYTE)uiDrive,&dwBytesReturned)) { return -3; } // 關閉設備 CloseHandle(hFile); DWORD dwDiskData[256]; USHORT* pIDSector = NULL; // 對應結構IDSECTOR 見頭文件 pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btOutCmd)->bBuffer; for (int i = 0; i < 256; i++) { dwDiskData[i] = pIDSector[i]; } // 獲取序列號 strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19)); // 獲取型號 strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46)); // 獲取固件版本號 strcpy(szFirmwareNumber, ConvertToString(dwDiskData, 23, 26)); return 0; } int main(int argc,char *argv[]) { char SerialNumber[64]; // 硬盤序列號 char ModelNumber[64]; // 硬盤型號 char FirmwareNumber[64]; // 硬盤固件版本號 if (0 == GetDiskInfo(0, SerialNumber, ModelNumber, FirmwareNumber)) { std::cout << "序列號: " << SerialNumber << std::endl; std::cout << "硬盤型號: " << ModelNumber << std::endl; std::cout << "固件版本:" << FirmwareNumber << std::endl; } system("pause"); return 0; }
輸出效果:
到此這篇關于C/C++實現(xiàn)獲取硬盤序列號的示例代碼的文章就介紹到這了,更多相關C++獲取硬盤序列號內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!