//---------------------------------------------------------------------------
#include <setupapi.h>
#include <stdio.h>
#include <objbase.h>
#ifndef __BORLANDC__
#pragma comment(lib, "setupapi.lib")
#endif
//---------------------------------------------------------------------------
char g_strCrnVerify[] =
{
0xBB, 0xB6, 0xD3, 0xAD, 0xB9, 0xE2, 0xC1, 0xD9, 0x20, 0x43,
0x2B, 0x2B, 0x42, 0x75, 0x69, 0x6C, 0x64, 0x65, 0x72, 0xD1,
0xD0, 0xBE, 0xBF, 0x20, 0x2D, 0x20, 0x68, 0x74, 0x74, 0x70,
0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x63, 0x63, 0x72,
0x75, 0x6E, 0x2E, 0x63, 0x6F, 0x6D
};
//---------------------------------------------------------------------------
void CrnReplaceString(LPSTR lpBuf, char c1, char c2)
{
int nLen = strlen(lpBuf);
LPSTR lpTemp = new char[nLen];
memset(lpTemp, 0, nLen);
int j=0;
for(int i=0; i < nLen; i++)
{
if(lpBuf[i] == c1)
{
if(c2 != 0x00)
{
lpTemp[j] = c2;
j++;
}
}
else
{
lpTemp[j] = lpBuf[i];
j++;
}
}
//
memset(lpBuf, 0, nLen);
strncpy(lpBuf, lpTemp, nLen);
delete []lpTemp;
}
//---------------------------------------------------------------------------
// 獲取指定盤符的序列號(針對USB優盤有效)
// char cDiskID: 指定盤符,如 'L'
// LPSTR lpPID : 序列號存放的緩沖,如char szPID[32]
// by ccrun(老妖) [email protected]
//---------------------------------------------------------------------------
bool CrnGetUSBDiskID(char cDiskID, LPSTR lpPID)
{
char szDrv[4];
sprintf(szDrv, "%c:\\", cDiskID);
if(GetDriveType(szDrv) != DRIVE_REMOVABLE)
{
MessageBox(0, "指定的盤不是有效的優盤.",
"錯誤", MB_OK | MB_ICONWARNING);
return false;
}
char lpRegPath[512] = { 0 };
char lpRegValue[256] = { 0 };
sprintf(lpRegPath, "SYSTEM\\MountedDevices");
sprintf(lpRegValue, "\\DosDevices\\%c:", cDiskID);
//
DWORD dwDataSize(0);
DWORD dwRegType(REG_BINARY);
LPBYTE lpRegBinData(NULL);
LPSTR lpUSBKeyData(NULL);
// 查詢注冊表中映射驅動器的設備信息
HKEY hKey;
long lRet = ::RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // root key
lpRegPath, // 要訪問的鍵的位置
0, //
KEY_READ, // 以查詢的方式訪問注冊表
&hKey); // hKEY保存此函數所打開的鍵的句柄
if(lRet != ERROR_SUCCESS)
return false;
else
{
lRet = ::RegQueryValueEx(hKey, // 所打開的鍵的句柄
lpRegValue, // 要查詢的鍵值名
NULL,
&dwRegType, // 查詢數據的類型
lpRegBinData, // 保存所查詢的數據
&dwDataSize); // 預設置的數據長度
if(lRet != ERROR_SUCCESS)
{
::RegCloseKey(hKey);
return false;
}
else
{
lpRegBinData = new BYTE[dwDataSize];
lpUSBKeyData = new char[dwDataSize];
memset(lpUSBKeyData, 0, dwDataSize);
lRet = ::RegQueryValueEx(hKey,
lpRegValue,
NULL,
&dwRegType,
lpRegBinData,
&dwDataSize);
if(lRet != ERROR_SUCCESS)
{
delete []lpRegBinData;
delete []lpUSBKeyData;
::RegCloseKey(hKey);
return false;
}
}
}
::RegCloseKey(hKey);
// 過濾二進制串中的無用信息(將0x0字符去除)
int j = 0;
for(DWORD i=0; i<dwDataSize; i++)
{
if(lpRegBinData[i] != 0x0)
{
lpUSBKeyData[j] = lpRegBinData[i];
j++;
}
}
delete []lpRegBinData;
// I'm sorry: You can remove under line in your Code.
MessageBox(0, g_strCrnVerify, "CrnGetUSBDiskID", 0);
// I'm sorry: Only for [Zhuan Tie Bu Liu Ming]. - -#
// 截取lpUSBKeyData中的有用信息, 例: 7&100a16f&0
// \??\STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
// 63 63 72 75 6E 2E 63 6F 6D
LPSTR lpPos1 = strstr(lpUSBKeyData, "#RemovableMedia#") + 16;
LPSTR lpPos2 = strstr(lpUSBKeyData, "RM");
strncpy(lpUSBKeyData, lpPos1, int(lpPos2) - int(lpPos1));
lpUSBKeyData[int(lpPos2) - int(lpPos1) - 1] = 0x0;
strcpy(lpUSBKeyData, strupr(lpUSBKeyData));
// Disk Device(磁盤設備)的GUID
GUID guidUSB;
CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", &guidUSB);
//
HDEVINFO hUSB = SetupDiGetClassDevs(
&guidUSB, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if(hUSB == INVALID_HANDLE_VALUE)
{
delete []lpUSBKeyData;
return false;
}
//
int nDevIndex = 0;
bool bSuccess;
SP_DEVINFO_DATA DevData;
SP_DEVICE_INTERFACE_DATA DevIntData;
PSP_DEVICE_INTERFACE_DETAIL_DATA lpDevIntDetailData;
DWORD dwBytesReturned;
// 遍歷磁盤設備
do
{
DevIntData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
bSuccess = SetupDiEnumDeviceInterfaces(hUSB, NULL, &guidUSB,
nDevIndex, &DevIntData) > 0;
// 本文轉自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1021&d=fgp83l
if(bSuccess)
{
// 獲取接口詳細信息
DevData.cbSize = sizeof(SP_DEVINFO_DATA);
dwBytesReturned = 0;
SetupDiGetDeviceInterfaceDetailA(hUSB, &DevIntData,
NULL, 0, &dwBytesReturned, &DevData);
if(dwBytesReturned != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
lpDevIntDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
GlobalAlloc(GMEM_FIXED, dwBytesReturned);
lpDevIntDetailData->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if(SetupDiGetDeviceInterfaceDetailA(hUSB, &DevIntData,
lpDevIntDetailData, dwBytesReturned, &dwBytesReturned, &DevData))
{
// 取得設備接口詳細信息並根據轉化後的路徑在注冊表中查詢
LPSTR lpPathTemp = new char[strlen(lpDevIntDetailData->DevicePath) + 256];
strcpy(lpRegPath, "SYSTEM\\CurrentControlSet\\Enum\\");
strcpy(lpPathTemp, lpDevIntDetailData->DevicePath);
lpPos1 = LPSTR(int(lpPathTemp) + 4);
lpPos2 = LPSTR(int(strstr(lpPathTemp, "{")) - 1);
strncpy(lpPathTemp, lpPos1, int(lpPos2) - int(lpPos1));
lpPathTemp[int(lpPos2) - int(lpPos1)] = 0x0;
CrnReplaceString(lpPathTemp, '#', '\\');
strcat(lpRegPath, lpPathTemp);
//
if(RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
lpRegPath,
0,
KEY_READ,
&hKey) == ERROR_SUCCESS)
{
dwRegType = REG_SZ;
LPSTR lpRegSzData = NULL;
dwDataSize = 0;
lRet = ::RegQueryValueEx(hKey,
"ParentIdPrefix",
NULL,
&dwRegType,
(LPBYTE)lpRegSzData,
&dwDataSize);
if(lRet == ERROR_SUCCESS)
{
lpRegSzData = new char[dwDataSize];
lRet = ::RegQueryValueEx(hKey,
"ParentIdPrefix",
NULL,
&dwRegType,
(LPBYTE)lpRegSzData,
&dwDataSize);
if(lRet == ERROR_SUCCESS)
{
strcpy(lpRegSzData, strupr(lpRegSzData));
if(!strcmp(lpUSBKeyData, lpRegSzData))
{
// 經比對,找到要查詢的磁盤設備
strcpy(lpPathTemp, LPSTR(int(strstr(
lpDevIntDetailData->DevicePath, "#")) + 1));
lpPos1 = LPSTR(int(strstr(lpPathTemp, "#")) + 1);
lpPos2 = LPSTR(int(strstr(lpPathTemp, "#{")));
strncpy(lpPathTemp, lpPos1, int(lpPos2) - int(lpPos1));
lpPathTemp[int(lpPos2) - int(lpPos1)] = 0x0;
// 獲取最終的磁盤序列號
CrnReplaceString(lpPathTemp, '&', 0x00);
if(lpPID)
strncpy(lpPID, strupr(lpPathTemp), 32);
//
delete []lpRegSzData;
delete []lpPathTemp;
GlobalFree(lpDevIntDetailData);
::RegCloseKey(hKey);
break;
}
}
delete []lpRegSzData;
}
::RegCloseKey(hKey);
}
delete []lpPathTemp;
nDevIndex++;
}
GlobalFree(lpDevIntDetailData);
}
}
}while(bSuccess);
SetupDiDestroyDeviceInfoList(hUSB);
delete []lpUSBKeyData;
return true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char lpPID[32];
if(CrnGetUSBDiskID('L', lpPID))
ShowMessage(lpPID);
}