生活随笔
收集整理的這篇文章主要介紹了
读取硬盘序列号
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在需要對計算機進行標識的場景下,我們一般會選擇獲取一些硬件信息。然而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;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){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){k =
0;}buf[k] =
'\0';
if (flip)
for (j =
0; j < k; j +=
2){
char t = buf[j];buf[j] = buf[j +
1];buf[j +
1] = t;}i = 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;
}
ULONG GetHDSerial(PCHAR pszIDBuff,
int nBuffLen,
int nDriveID)
{HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;ULONG ulSerialLen =
0;__try{TCHAR szDriveName[
32];wsprintf(szDriveName, TEXT(
"\\\\.\\PhysicalDrive%d"), nDriveID);hPhysicalDrive = 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;
}
總結
以上是生活随笔為你收集整理的读取硬盘序列号的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。