当我尝试打印所有USB设备(WinAPI)时,我只能看到一个USB字符串



每当新的USB设备连接到我的电脑时,我都会尝试打印一条消息,但我不想创建一个只捕捉和处理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;
}

CM_Get_Device_Interface_ListA用于返回项列表的格式是双null终止列表(另请参阅为什么双null终止字符串而不是指向字符串的指针数组?以了解基本原理(。这在文档中没有明确说明,但可以从Buffer:PZZSTR的参数类型中推断出来。

它在winnt.h中声明如下:

typedef _NullNull_terminated_ CHAR *PZZSTR;

这实际上只是一个char*,但带有_NullNull_terminated_SAL注释。它允许静态代码分析器了解PZZSTR的附加语义,并为开发人员提供提示。

有问题的代码只打印第一个NUL字符之前的字符,即它最多显示列表中的一个项目。要显示所有项目,您必须遍历字符串,直到找到一个空字符串:

char const* current{ buffer };
while (*current != '') {
std::cout << current << std::endl;
current += strlen(current) + 1;
}

这解决了眼前的问题。要使代码真正工作,您必须修复潜在的内存损坏错误。在对CM_Get_Device_Interface_ListA的调用中,您告诉APIbuffer指向length字节的内存,但您分配了MAX字节。

BufferBufferLen的自变量必须与实际分配相匹配。说到这里,你从来没有真正清理过那段记忆。使用std::vector解决了两个问题:

std::vector<char> buffer(length);
auto eroare2 = CM_Get_Device_Interface_ListA(
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
buffer.data(),
buffer.size(),
CM_GET_DEVICE_INTERFACE_LIST_PRESENT
);
// ...
char const* current{ buffer.data() };
// ...

相关内容

  • 没有找到相关文章

最新更新