C/C++ 实现遍历当前设备
最近需要对一个加密狗进行检测,设备信息如下:
看到 HID#Vid_3689&Pid_8762
这一段,觉得可以先遍历所有的设备:
然后再筛选出里面所有的 HID 类型的设备:
最后判断这个设备的 Pid 和 Vid 是否和黑名单匹配。
下面是代码:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <string>
#include <mutex>
#include <atlbase.h>
#include <atlconv.h>
#include <SetupAPI.h>
extern "C"{
#include <hidsdi.h> // 无法解析的外部符号 HidD_GetAttributes、HidD_GetHidGuid
}
#pragma comment(lib,"hid.lib")
#pragma comment(lib,"Setupapi.lib")
using namespace std;
void EnumHIDDevice()
{
// 获取 HID 类型设备信息集句柄
GUID HidGuid;
HidD_GetHidGuid(&HidGuid);
HDEVINFO hdev = SetupDiGetClassDevs(
&HidGuid, // 只查找 HID 类型设备(查找所有则设置为NULL,并修改 Flag 参数)
NULL, // 枚举指定类型的设备
NULL, // 设备关联的顶级窗口句柄
DIGCF_DEVICEINTERFACE | // 指定设备接口
DIGCF_PRESENT // 只返回当前系统中存在的设备
);if(hdev == INVALID_HANDLE_VALUE){cout << "SetupDiGetClassDevs failed : " << GetLastError() << endl;}
// 遍历 HID 设备
int idev = 0;
while(TRUE){
// 初始化 SP_DEVICE_INTERFACE_DATA
SP_DEVICE_INTERFACE_DATA did = {0};
did.cbSize = sizeof(did);
if(!SetupDiEnumDeviceInterfaces(
hdev, // 设备信息集句柄
NULL, // 枚举所有设备接口(不限制类型)
&HidGuid, // 接收接口GUID
idev, // 下标
&did // [OUT] 指向 SP_DEVICE_INTERFACE_DATA 结构体的指针
)){cout << "SetupDiEnumDeviceInterfaces failed : " << GetLastError() << endl;break;}
// 初始化 SP_DEVICE_INTERFACE_DETAIL_DATA
DWORD buf_didd = 256;
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR,buf_didd);
pdidd->cbSize = sizeof(*pdidd);
if(!SetupDiGetDeviceInterfaceDetail(
hdev, // 设备信息集句柄
&did, // SP_DEVICE_INTERFACE_DATA 结构体的指针
pdidd, // [OUT] SP_DEVICE_INTERFACE_DETAIL_DATA
buf_didd, // SP_DEVICE_INTERFACE_DETAIL_DATA 对应的缓冲区大小
NULL, // [OUT] SP_DEVICE_INTERFACE_DATA 缓冲区大小
NULL
)){cout << "SetupDiGetDeviceInterfaceDetail failed : " << GetLastError() << endl;}
cout << "pdidd->DevicePath = " << pdidd->DevicePath << endl;
// 创建设备
HANDLE hDevHandle = CreateFile(
pdidd->DevicePath, // 设备名称
GENERIC_READ | GENERIC_WRITE, // 访问权限
FILE_SHARE_READ | FILE_SHARE_WRITE, // 分享权限
NULL, // 返回的句柄不能被继承
OPEN_EXISTING, // 仅当设备存在时打开
FILE_ATTRIBUTE_NORMAL, // 不设置其他属性
NULL // 不设置扩展属性
);if(INVALID_HANDLE_VALUE == hDevHandle){cout << "CreateFile failed : " << GetLastError() << endl;}
// 获取设备接口的 PID、VID
HIDD_ATTRIBUTES hidAttributes = {0};
hidAttributes.Size = sizeof(hidAttributes);
if (!HidD_GetAttributes(
hDevHandle, // 设备句柄
&hidAttributes // [OUT] HIDD_ATTRIBUTES 结构体指针
)){cout << "HidD_GetAttributes failed : " << GetLastError() << endl;}
// 判断域之天加密狗:USB\\VID_3689&PID_8762
cout << "hidAttributes.ProductID = " << hidAttributes.ProductID << endl;
cout << "hidAttributes.VendorID = " << hidAttributes.VendorID << endl;
if(hidAttributes.ProductID == 8762 && hidAttributes.VendorID == 3689){
cout << "发现域之天加密狗" << endl;
}
// 清理
CloseHandle(hDevHandle);
LocalFree(pdidd);
idev++;
cout << endl;
}
// 清理
SetupDiDestroyDeviceInfoList(hdev);
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumHIDDevice();
getchar();
return 0;
}
效果图:(我现在没有加密狗,自然检测不到咯 😕)
文章出处:https://www.cnblogs.com/LyShark/articles/15019601.html
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
标签:
Visual C++
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构