当我尝试打印所有USB设备(Winapi)时,我只能看到一个USB字符串
每当将新的USB设备连接到我的PC时,我都会尝试打印一条消息,但我不想创建一个应用程序,该应用程序只能捕获和处理Windows内核触发的事件。因此,我使用了一些特定功能来打印活动的USB设备,然后,每当插入新设备时,信号就会产生某些东西(弹出窗口或类似的东西)。因此,首先,我试图枚举所有USB设备,但是只要我只收到一行文本,该线路代表特定的USB设备,而不是所有已连接的USB设备。这是代码
#pragma comment(lib, "Cfgmgr32")
#include <iostream>
#include <Windows.h>
#include <cfgmgr32.h>
#include <initguid.h>
#include <Usbiodef.h>
#define MAX 1024
int main()
{
ULONG length;
auto eroare1 = CM_Get_Device_Interface_List_SizeA(
&length,
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT
);
if (eroare1 != CR_SUCCESS)
{
std::cout << "eroare 1";
}
PSZ buffer;
buffer = new char[MAX];
auto eroare2 = CM_Get_Device_Interface_ListA(
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
buffer
length,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT
);
if (eroare2 != CR_SUCCESS)
{
std::cout << "eroare";
}
std::cout << buffer << std::endl;
}
I try to print a message whenever a new USB device is connected to my PC, but I don't want to create an application which just catches and treats the events triggered by the windows' kernel. So I used some specific functions in order to print the active USB devices and then, whenever a new device is plugged in, a signal produces something (a pop-up or something like that). Thus, firstly, I tried to enumerate all the USB devices, but I had no success as long as I receive only one line of text which represents a specific USB device, not all the USB devices connected. Here is the code
#pragma comment(lib, "Cfgmgr32")
#include <iostream>
#include <Windows.h>
#include <cfgmgr32.h>
#include <initguid.h>
#include <Usbiodef.h>
#define MAX 1024
int main()
{
ULONG length;
auto eroare1 = CM_Get_Device_Interface_List_SizeA(
&length,
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT
);
if (eroare1 != CR_SUCCESS)
{
std::cout << "eroare 1";
}
PSZ buffer;
buffer = new char[MAX];
auto eroare2 = CM_Get_Device_Interface_ListA(
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
buffer
length,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT
);
if (eroare2 != CR_SUCCESS)
{
std::cout << "eroare";
}
std::cout << buffer << std::endl;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
CM_Get_Device_Interface_ListA
返回项目列表是 双 null 终止列表(另请参阅为什么双空终止字符串而不是指向字符串的指针数组? 的基本原理)。文档中没有明确说明这一点,但可以从
Buffer
的参数类型推断:PZZSTR
。它在 winnt.h 中声明如下:
这实际上只是一个
char*
但带有_NullNull_termminate_
SAL 注释。它允许静态代码分析器了解PZZSTR
的附加语义,并为开发人员提供提示。相关代码仅打印第一个 NUL 字符之前的字符,即它最多显示列表中的一项。要显示所有项目,您必须迭代字符串,直到找到空字符串:
这解决了眼前的问题。为了使代码真正工作,您必须修复潜在的内存损坏错误。在对
CM_Get_Device_Interface_ListA
的调用中,您告诉 APIbuffer
指向length
字节的内存,但您分配了MAX< /代码> 字节。
Buffer
和BufferLen
的参数必须与实际分配匹配。说到这里,你实际上并没有清理过那段记忆。使用std::vector
解决了这两个问题:The format used by
CM_Get_Device_Interface_ListA
to return a list of items is a double-null-terminated list (see also Why double-null-terminated strings instead of an array of pointers to strings? for rationale). This isn't explicitly spelled out in the documentation, but can be inferred from the argument type ofBuffer
:PZZSTR
.It is declared in winnt.h like this:
This is really just a
char*
but with the_NullNull_terminated_
SAL annotation. It allows static code analyzers to know about the additional semantics ofPZZSTR
, and serves as a hint to developers.The code in question only prints characters up to the first NUL character, i.e. it displays at most one item from the list. To display all items, you'll have to iterate over the strings until you find an empty string:
That fixes the immediate issue. To make the code actually work, you'll have to fix the potential memory corruption bug. In the call to
CM_Get_Device_Interface_ListA
you're telling the API thatbuffer
is pointing tolength
bytes of memory, but you allocatedMAX
bytes.The arguments of
Buffer
andBufferLen
must match the actual allocation. Speaking of which, you never actually clean up that memory. Using astd::vector
solves both issues: