//--------------------------------------------------------------------------- // 获取优盘序列号的代码, by ccrun(老妖) // 参考: http://www.2ccc.com/article.asp?articleid=4167 // 以下代码在 C++Builder 6.0 和 VC 6.0 中编译通过 // 看帖请回帖, 转帖请留名. //--------------------------------------------------------------------------- #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(老妖) info@ccrun.com //--------------------------------------------------------------------------- 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); }
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END