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;
}
The format used by
CM_Get_Device_Interface_ListAto 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_ListAyou're telling the API thatbufferis pointing tolengthbytes of memory, but you allocatedMAXbytes.The arguments of
BufferandBufferLenmust match the actual allocation. Speaking of which, you never actually clean up that memory. Using astd::vectorsolves both issues: