生活随笔
收集整理的這篇文章主要介紹了
Windows下使用C++(Win32SDK)编程无需提权读取硬盘序列号
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在需要對計算機進行標識的場景下,我們一般會選擇獲取一些硬件信息。然而CPU序列號可能有重復、網卡MAC地址和計算機名又能被輕易地修改,所以其中最可靠的應該就是硬盤序列號了。Windows下硬盤序列號的獲取本身并不復雜,而關鍵在于如何在無需權限提升的情況下獲取到硬盤序列號。為了解決這個問題,我也查了很多資料,基本上各大博客中貼出的都是需要權限提升的代碼。
最終,在DiskID32的源碼中,我找到了不提權獲取硬盤序列號的辦法。不過其源碼只能使用MBCS多字節字符集方式編譯,而無法使用Unicode字符集編譯,為此,我進行了一些修改,使之兼容兩種方式。下面將經過我修改、測試后的代碼貼出來,供大家參考。
其中,獲取硬盤序列號的函數命名為GetHDSerial,該函數依賴flipAndCodeBytes函數。前者使用說明如下:
#include <locale.h>
#include <tchar.h>
#include <windows.h>
#include <stdio.h>char * flipAndCodeBytes(const char * str,int pos,int flip,char * buf)
{int i;int j = 0;int k = 0;buf[0] = '\0';if (pos <= 0)return buf;if (!j){char p = 0;// First try to gather all characters representing hex digits only.j = 1;k = 0;buf[k] = 0;for (i = pos; j && str[i] != '\0'; ++i){char c = tolower(str[i]);if (isspace(c))c = '0';++p;buf[k] <<= 4;if (c >= '0' && c <= '9')buf[k] |= (unsigned char)(c - '0');else if (c >= 'a' && c <= 'f')buf[k] |= (unsigned char)(c - 'a' + 10);else{j = 0;break;}if (p == 2){if (buf[k] != '\0' && !isprint(buf[k])){j = 0;break;}++k;p = 0;buf[k] = 0;}}}if (!j){// There are non-digit characters, gather them as is.j = 1;k = 0;for (i = pos; j && str[i] != '\0'; ++i){char c = str[i];if (!isprint(c)){j = 0;break;}buf[k++] = c;}}if (!j){// The characters are not there or are not printable.k = 0;}buf[k] = '\0';if (flip)// Flip adjacent charactersfor (j = 0; j < k; j += 2){char t = buf[j];buf[j] = buf[j + 1];buf[j + 1] = t;}// Trim any beginning and end spacei = j = -1;for (k = 0; buf[k] != '\0'; ++k){if (!isspace(buf[k])){if (i < 0)i = k;j = k;}}if ((i >= 0) && (j >= 0)){for (k = i; (k <= j) && (buf[k] != '\0'); ++k)buf[k - i] = buf[k];buf[k - i] = '\0';}return buf;
}/************************************************************************
GetHDSerial:用于獲取指定編號的硬盤序列號,無需任何權限提升
參數:
PCHAR pszIDBuff:傳入的字符串緩沖區,用于接收硬盤序列號
int nBuffLen:傳入的字符串緩沖區大小,當硬盤序列號大于該值時,只復制nBuffLen長度
int nDriveID:要獲取的驅動器編號,從0開始,到15為止
返回值:
成功獲取到的硬盤序列號長度,為0表示獲取失敗
作者:
famous214(blog.csdn.net/LPWSTR)
源碼參考了diskid32(https://www.winsim.com/diskid32/diskid32.html)
版本歷史:
20171226 第一版,從diskid32源碼中提取
20171226 第二版,兼容Unicode編譯方式
20171230 重構后發布第三版
************************************************************************/
ULONG GetHDSerial(PCHAR pszIDBuff, int nBuffLen, int nDriveID)
{HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;ULONG ulSerialLen = 0;__try{// Try to get a handle to PhysicalDrive IOCTL, report failure// and exit if can't.TCHAR szDriveName[32];wsprintf(szDriveName, TEXT("\\\\.\\PhysicalDrive%d"), nDriveID);// Windows NT, Windows 2000, Windows XP - admin rights not requiredhPhysicalDrive = CreateFile(szDriveName, 0,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);if (hPhysicalDrive == INVALID_HANDLE_VALUE){__leave;}STORAGE_PROPERTY_QUERY query;DWORD cbBytesReturned = 0;static char local_buffer[10000];memset((void *)&query, 0, sizeof(query));query.PropertyId = StorageDeviceProperty;query.QueryType = PropertyStandardQuery;memset(local_buffer, 0, sizeof(local_buffer));if (DeviceIoControl(hPhysicalDrive, IOCTL_STORAGE_QUERY_PROPERTY,&query,sizeof(query),&local_buffer[0],sizeof(local_buffer),&cbBytesReturned, NULL)){STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *)& local_buffer;char serialNumber[1000];flipAndCodeBytes(local_buffer,descrip->SerialNumberOffset,1, serialNumber);if (isalnum(serialNumber[0])){ULONG ulSerialLenTemp = strnlen(serialNumber, nBuffLen - 1);memcpy(pszIDBuff, serialNumber, ulSerialLenTemp);pszIDBuff[ulSerialLenTemp] = NULL;ulSerialLen = ulSerialLenTemp;__leave;}}}__finally{if (hPhysicalDrive != INVALID_HANDLE_VALUE){CloseHandle(hPhysicalDrive);}return ulSerialLen;}
}void GetAllHDSerial(void)
{const int MAX_IDE_DRIVES = 16;static char szBuff[0x100];for (int nDriveNum = 0; nDriveNum < MAX_IDE_DRIVES; nDriveNum++){ULONG ulLen = GetHDSerial(szBuff, sizeof(szBuff), nDriveNum);if (ulLen > 0){_tprintf(TEXT("第%d塊硬盤的序列號為:%hs\n"), nDriveNum + 1, szBuff);}}
}int main()
{setlocale(LC_ALL, "chs");GetAllHDSerial();system("pause");return 0;
}
總結
以上是生活随笔為你收集整理的Windows下使用C++(Win32SDK)编程无需提权读取硬盘序列号的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。