在机器视觉或者一些传统制造业行业里经常牵扯到软件加密算法,或者一些简单的加密,比如相机绑定,或者USB接口绑定之类的,那么针对这些硬件设备绑定加密方式,我这里简单的提供一个方法来实现:
方法很简单,从设备管理器里查找关心的USB设备,对比PID,VID和全球唯一标识GUID,当然被别人在驱动层挂了钩子修改注册表内容,这个方法就不适用了。以下是代码:
#pragma once
#include <afx.h>
#include <DShow.h>
#include <Windows.h>
#include <setupapi.h>
#include <vector>
#pragma comment(lib, "setupapi.lib")
/*
打开设备管理器里可以查看对应USB接口的详细信息
已配置设备 USB\VID_1E2F&PID_9801&MI_00\6&1a040c39&0&0000
VID 对应已配置信息的VID_1E2F
PID 对应已配置信息的PID_9801
类 GUID: {C166523C-FE0C-4A94-A586-F1A80CFBBF3E}
下面的GUID分别是16进制方式表示
GUID1 0xC166523C
GUID2 0xFE0C
GUID3 0x4A94
GUID4 0xA586
GUID5 0xF1A80CFBBF3E
返回值:
返回TRUE 表示验证成功
返回FALSE 表示验证失败
*/
class UsbSerialnumberBasicInfo {
public:
CString m_VID;
CString m_PID;
int m_GUID1;
int m_GUID2;
int m_GUID3;
int m_GUID4;
long long int m_GUID5;
UsbSerialnumberBasicInfo(CString VID, CString PID, int GUID1, int GUID2, int GUID3, int GUID4, long long int GUID5)
:m_VID(VID),m_PID(PID),m_GUID1(GUID1),m_GUID2(GUID2), m_GUID3(GUID3), m_GUID4(GUID4), m_GUID5(GUID5) {
}
};
BOOL CheckUSBSerialnumber(UsbSerialnumberBasicInfo& usbInfo);
BOOL CheckUSBSerialnumber(std::vector<UsbSerialnumberBasicInfo>& usbInfoVec);
#include "../include/encryption.h"
BOOL CheckUSBSerialnumber(UsbSerialnumberBasicInfo& usbInfo)
{
usbInfo.m_VID.MakeUpper();
usbInfo.m_PID.MakeUpper();
//VID: ZYZW 公司的生产商号
//const TCHAR NIKON_ID[] = _T("VID_1E2F");
TCHAR szDIS[MAX_PATH]; // Device Identification Strings,
DWORD nSize = 0;
// 获取当前系统所有使用的设备
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, (DIGCF_ALLCLASSES | DIGCF_PRESENT));
if (INVALID_HANDLE_VALUE == hDevInfo)
{
return FALSE;
}
// 准备遍历所有设备查找USB
SP_DEVINFO_DATA sDevInfoData;
sDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (int i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &sDevInfoData); i++)
{
nSize = 0;
if (!SetupDiGetDeviceInstanceId(hDevInfo, &sDevInfoData, szDIS, sizeof(szDIS), &nSize))
{
continue;
}
CString strDIS(szDIS);
strDIS.MakeUpper();
if (strDIS.Left(3) == _T("USB"))
{
int iVID_Pos = strDIS.Find(usbInfo.m_VID);
int iPID_Pos = strDIS.Find(usbInfo.m_PID);
if (iVID_Pos == 4 && iPID_Pos == 13)
{
char szClassBuf[MAX_PATH] = { 0 };
char szDescBuf[MAX_PATH] = { 0 };
// 获取类名
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &sDevInfoData, SPDRP_CLASS, NULL, (PBYTE)szClassBuf, MAX_PATH - 1, NULL))
continue;
CString cmpGuid4;
char str[10];
for (auto i = 0; i < 8; i++) {
sDevInfoData.ClassGuid.Data4[i];
_itoa_s((int)sDevInfoData.ClassGuid.Data4[i], str, 16);
if (strlen(str) < 2) {
cmpGuid4 += L"0";
}
cmpGuid4 += str;
}
cmpGuid4.MakeUpper();
CString strGuid4;
strGuid4.Format(_T("%x%llx"), usbInfo.m_GUID4, usbInfo.m_GUID5);
strGuid4.MakeUpper();
if (sDevInfoData.ClassGuid.Data1 == usbInfo.m_GUID1
&& sDevInfoData.ClassGuid.Data2 == usbInfo.m_GUID2
&& sDevInfoData.ClassGuid.Data3 == usbInfo.m_GUID3
&& cmpGuid4 == strGuid4) {
// 释放设备
SetupDiDestroyDeviceInfoList(hDevInfo);
return TRUE;
}
}
}
}
// 释放设备
SetupDiDestroyDeviceInfoList(hDevInfo);
return FALSE;
}
BOOL CheckUSBSerialnumber(std::vector<UsbSerialnumberBasicInfo>& usbInfoVec)
{
BOOL result = FALSE;
for (auto it = usbInfoVec.begin(); it != usbInfoVec.end(); it++) {
result = CheckUSBSerialnumber(*it);
if (result == FALSE) {
return FALSE;
}
}
return TRUE;
}