[英]Get dos_name of usb on inserting or removal
我設計了一個程序來檢測何時連接或移除 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}
獲取連接的邏輯驅動器的名稱或無論如何它的名稱。 我的代碼是:
#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 的新手,所以請耐心等待代碼,
在開始時,您需要打開安裝管理器並將其保存在與您的 window 關聯的 class 中,因為不能多次打開/關閉它,僅位一次
#include <mountmgr.h>
HANDLE hMountMgr = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0, 0, 0, OPEN_EXISTING, 0, 0);
對於類似名稱的查詢(如果存在!),您需要首先通過IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
獲取設備名稱,該名稱需要發送到設備,您擁有哪個接口名稱。 所以你需要先打開它。
然后你可以將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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.