C/C++實現(xiàn)獲取硬盤序列號的示例代碼
獲取硬盤的序列號、型號和固件版本號,此類功能通常用于做硬盤綁定或硬件驗證操作,通過使用Windows API的DeviceIoControl函數(shù)與物理硬盤驅(qū)動程序進行通信,發(fā)送ATA命令來獲取硬盤的信息。
以下是該程序的主要功能和流程:
定義常量 IDE_ATAPI_IDENTIFY 和 IDE_ATA_IDENTIFY 分別表示讀取 ATAPI 設(shè)備和 ATA 設(shè)備信息的命令。
- 實現(xiàn)
Trim函數(shù),用于去除字符串首尾的空格。 - 實現(xiàn)
ConvertToString函數(shù),用于將DWORD數(shù)組轉(zhuǎn)換為字符串,并通過Trim函數(shù)去除首尾空格。 - 實現(xiàn)
DoIdentify函數(shù),該函數(shù)通過DeviceIoControl發(fā)送SMART命令,獲取硬盤的詳細信息。 - 實現(xiàn)
GetDiskInfo函數(shù),該函數(shù)打開物理硬盤設(shè)備,并調(diào)用DoIdentify獲取硬盤序列號、型號和固件版本號。
在 main 函數(shù)中,通過調(diào)用 GetDiskInfo 獲取硬盤信息,并輸出到控制臺。
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <winioctl.h>
#include <string>
const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 讀取ATAPI設(shè)備的命令
const WORD IDE_ATA_IDENTIFY = 0xEC; // 讀取ATA設(shè)備的命令
// 去除字符串首尾的空格
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ù)轉(zhuǎn)換
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);
// 打開設(shè)備
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ā)送控制代碼到指定設(shè)備驅(qū)動程序
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;
}
// 關(guān)閉設(shè)備
CloseHandle(hFile);
DWORD dwDiskData[256];
USHORT* pIDSector = NULL;
// 對應(yīng)結(jié)構(gòu)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;
}
輸出效果:

到此這篇關(guān)于C/C++實現(xiàn)獲取硬盤序列號的示例代碼的文章就介紹到這了,更多相關(guān)C++獲取硬盤序列號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

