Я создал программу, которая обнаруживает, когда USB-устройство вставляется или удаляется. Если я вызываю метод RegisterListener()
из main (), программа начинает прослушивать изменения USB. Проблема в том, что если я вставляю USB-накопитель с одним или несколькими томами (например, e :, f :, et c.), dbch_devicetype
всегда определяется как DBT_DEVTYP_DEVICEINTERFACE
(т.е. 5) и никогда DBT_DEVTYP_VOLUME
(т.е. 2). Как я могу получить уведомление DBT_DEVTYP_VOLUME
, чтобы я мог извлечь идентификатор тома и использовать его для извлечения буквы (букв) диска (пример: e :, f:).
#include "OstorUSBLib.h"
#include<iostream>
#include <Dbt.h>
#define CLS_NAME L"USB_LISTENER_CLASS"
#define HWND_MESSAGE ((HWND)-3)
#define HID_CLASSGUID { 0x53f5630d, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b }} //volume
//#define HID_CLASSGUID { 0x53f56307, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b }} //disk
static const GUID GuidDevInterfaceList[] = {
{ 0xa5dcbf10, 0x6530, 0x11d2,{ 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } },//GUID_DEVINTERFACE_USB_DEVICE
{ 0x53f5630d, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },//GUID_DEVINTERFACE_VOLUME
{ 0x53f56307, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },//GUID_DEVINTERFACE_DISK
{ 0xad498944, 0x762f, 0x11d0,{ 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } }//GUID_NDIS_LAN_CLASS
};
LRESULT OstorUSBLib::message_handler(HWND__ * hwnd, UINT uint, WPARAM wparam, LPARAM lparam)
{
switch (uint)
{
case WM_NCCREATE: // before window creation
return true;
break;
case WM_CREATE:
{
//works. Receives broadcast disk information
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = {0};
NotificationFilter.dbcc_size = sizeof(PDEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
LPCREATESTRUCT params = (LPCREATESTRUCT)lparam;
GUID InterfaceClassGuid = *((GUID*)params->lpCreateParams);
for (int i = 0; i < sizeof(GuidDevInterfaceList); i++) {
NotificationFilter.dbcc_classguid = GuidDevInterfaceList[i];
HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (dev_notify == NULL) { // Handle the error by returning correct error in LRESULT format and remove throw...
throw std::runtime_error("Could not register for device Notifications!");
}
}
}
break;
case WM_DEVICECHANGE:
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lparam;
PDEV_BROADCAST_DEVICEINTERFACE_W lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE_W)lpdb;
std::cout << lpdb->dbch_devicetype<<std::endl;
}
}
return LRESULT();
}
void OstorUSBLib::RegisterListener()
{
HWND hWnd = NULL;
WNDCLASSEXW wx = {0};
wx.cbSize = sizeof(WNDCLASSEXW);
wx.lpfnWndProc = reinterpret_cast<WNDPROC>(message_handler);
wx.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
wx.style = CS_HREDRAW || CS_VREDRAW;
wx.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wx.lpszClassName = CLS_NAME;
if(RegisterClassExW(&wx))
{
GUID guid = HID_CLASSGUID;
hWnd = CreateWindowW(
CLS_NAME, L"DevNotifWnd", WS_ICONIC, 0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE,
NULL, GetModuleHandle(0), (void*)&guid
);
}
else
{
throw std::runtime_error("Could not create message window!");
}
std::cout << "waiting for new devices.\n";
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}