gpt4 book ai didi

c++ - 在插入或移除时获取 USB 的 dos_name

转载 作者:行者123 更新时间:2023-12-02 10:12:57 25 4
gpt4 key购买 nike

我设计了一个程序来检测何时连接或移除 USB 设备。我想知道dos path连接的设备或这样的 Guid \\?\Volume{17ee3574-7082-4881-aeae-07893db4e957}\而是 dbcc_name给我\\?\STORAGE#Volume#_??_USBSTOR#Disk&Ven_JetFlash&Prod_Transcend_8GB&Rev_1100#546IYBDAPBE1075Q&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}无论如何要获得连接的逻辑驱动器的guid或其dos名称。我的代码是:

#define CLS_NAME L"USB_LISTENER_CLASS"
#define HID_CLASSGUID {0x4d1e55b2, 0xf16f, 0x11cf,{ 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}}
LRESULT message_handler(HWND__* hwnd, UINT uint, WPARAM wparam, LPARAM lparam)
{

switch (uint)
{
case WM_NCCREATE: // before window creation
return true;
break;

case WM_CREATE: // the actual creation of the window
{
// you can get your creation params here..like GUID..
LPCREATESTRUCT params = (LPCREATESTRUCT)lparam;
GUID InterfaceClassGuid = *((GUID*)params->lpCreateParams);
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_VOLUME;

HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (dev_notify == NULL)
{
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;
switch (wparam)
{

case DBT_DEVICEARRIVAL: //A device or piece of media has been inserted and is now available.

std::cout << "Device Arrived" << std::endl;
std::cout << "GUID od inserted device: " << lpdbv->dbcc_name;
break;

case DBT_DEVICEREMOVECOMPLETE:
std::cout << "Device Removed" << std::endl;
break;
}

}

}
return 0L;
}
void UsbListener::RegisterListener()
{
HWND hWnd = NULL;
WNDCLASSEXW wx;
ZeroMemory(&wx, sizeof(wx));
wx.cbSize = sizeof(WNDCLASSEX);
wx.lpfnWndProc = reinterpret_cast<WNDPROC>(message_handler);
wx.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
wx.style = CS_HREDRAW | CS_VREDRAW;
wx.hInstance = GetModuleHandle(0);
wx.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wx.lpszClassName = CLS_NAME;
GUID guid = HID_CLASSGUID;
if (RegisterClassExW(&wx))
{
hWnd = CreateWindowW(
CLS_NAME, L"DeviceNotificationWindow", WS_ICONIC, 0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), (void*)&guid
);
}
if (hWnd == NULL)
{
throw std::runtime_error("Could not create message window!");
}
std::cout <<std::endl<< "Listening..." << std::endl;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
我想知道插入或删除的确切驱动器的 Dos 名称,以便 UI 可以显示。我是winapi的新手,所以请耐心等待代码,

最佳答案

一开始你需要打开Mount Manager并将它的句柄保存在与您的窗口关联的类中,因为不会多次打开/关闭它,仅位一次

#include <mountmgr.h>

HANDLE hMountMgr = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0, 0, 0, OPEN_EXISTING, 0, 0);
对于类似名称的查询(如果存在!),您需要先获取 device name通过 IOCTL_MOUNTDEV_QUERY_DEVICE_NAME 哪个需要发送到设备,你有哪个接口(interface)名称。所以你需要先打开它。
那么你可以发送 IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH到 Mount Manager 并得到你想要的
volatile UCHAR guz;

ULONG GetDosVolumePath(HANDLE hMountMgr, PCWSTR InterfaceLink, PWSTR* ppszDosPath)
{
*ppszDosPath = 0;

HANDLE hFile = CreateFileW(InterfaceLink, 0, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);

if (hFile == INVALID_HANDLE_VALUE) return GetLastError();

union {
PVOID buf;
PMOUNTDEV_NAME pmdn;
};

ULONG dwError;

PVOID stack = alloca(guz);
ULONG cb = 0, rcb, InputBufferLength = sizeof(MOUNTDEV_NAME) + 0x40;

do
{
if (cb < InputBufferLength)
{
cb = RtlPointerToOffset(buf = alloca(InputBufferLength - cb), stack);
}

dwError = BOOL_TO_ERROR(DeviceIoControl(hFile, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, 0, 0, pmdn, cb, &rcb, 0));

InputBufferLength = FIELD_OFFSET(MOUNTDEV_NAME, Name) + pmdn->NameLength;

} while ( dwError == ERROR_MORE_DATA);

CloseHandle(hFile);

if (dwError == NOERROR)
{
union {
PVOID pv;
PMOUNTMGR_VOLUME_PATHS pmvp;
};

cb = 0, rcb = sizeof(MOUNTMGR_VOLUME_PATHS) + 8;

do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(pv = alloca(rcb - cb), pmdn);
}

dwError = BOOL_TO_ERROR(DeviceIoControl(hMountMgr,
IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
pmdn, InputBufferLength, pmvp, cb, &rcb, 0));

if (dwError == NOERROR)
{
*ppszDosPath = _wcsdup(pmvp->MultiSz);
}

rcb = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + pmvp->MultiSzLength;

} while (dwError == ERROR_MORE_DATA);
}

return dwError;
}

关于c++ - 在插入或移除时获取 USB 的 dos_name,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62853331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com