从 GUID 获取 USB 卷路径

Get usb volume path from guid

本文关键字:路径 USB 获取 GUID      更新时间:2023-10-16

我有一个程序可以检测插入和移除的USB设备。插入新的 USB 驱动器时,我得到插入驱动器的 GUID,如下所示\?USBSTOR#Disk&Ven_JetFlash&Prod_Transcend_8GB&Rev_1100#546IYBDAPBE1075Q&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}。我想从 GUID 中获取驱动器的驱动器路径(示例 E:,F:(。

#define HID_CLASSGUID { 0x53f5630d, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b }}
static const GUID GuidDevInterfaceList[] = {    
{ 0x53f5630d, 0xb6bf, 0x11d0,{ 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } }
};
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;
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...   
std::cout << "Hell" << std::endl;
}
}
}
break;
case WM_DEVICECHANGE:
{

PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lparam;
PDEV_BROADCAST_DEVICEINTERFACE_W lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE_W)lpdb;        
std::wstring path;

if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{

switch (wparam)
{

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

std::wcout << L"New device connected:n";
path = std::wstring(lpdbv->dbcc_name);//Gives the GUID of inserted drive
break;
}
case DBT_DEVICEREMOVECOMPLETE:{

std::wstring pathexit;

pathexit = std::wstring(lpdbv->dbcc_name);//Gives the GUID of removed drive

break;
}
}
break;
}
}
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);
}   
}

我调用RegisterListener()方法开始侦听 USB 更改 如何从 GUID 获取驱动器路径?(驱动器路径示例 e:, f:, g:( 。注意:我只会插入和移除USB闪存驱动器,而不是打印机,手机等设备。 编辑:我不想获取驱动器名称/标签。我想要像驱动器 e: 或 f 这样的路径:

">我想要像驱动器 e: 或 f: 这样的路径">

任何具有顶级窗口的应用程序都可以接收基本 通过处理WM_DEVICECHANGE消息进行通知。

DBT_DEVICEARRIVALDBT_DEVICEREMOVECOMPLETE事件是 自动广播到端口设备的所有顶级窗口。

卷通知也会广播到顶级窗口,因此 如果dbch_devicetypeDBT_DEVTYP_VOLUME,则该函数将失败。

仅消息窗口(指定HWND_MESSAGE(使您能够 发送和接收消息。它不可见,没有 z 顺序,不能 被枚举,并且不接收广播消息。窗口 只是发送消息。

请参阅"注册设备通知"和"仅消息窗口"。

因此,仅消息窗口存在一些限制。但是,对于一般的顶级窗口,很容易实现。有关如何创建顶级窗口,请参阅"演练:创建传统的 Windows 桌面应用程序 (C++("。

以下是基于 Visual Studio 中的 Windows 桌面应用程序模板的完整示例。

#include <windows.h>
#include <Dbt.h>
#include <string>
#include <strsafe.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void Main_OnDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam);
char FirstDriveFromMask(ULONG unitmask);  //prototype
/*------------------------------------------------------------------
Main_OnDeviceChange( hwnd, wParam, lParam )
Description
Handles WM_DEVICECHANGE messages sent to the application's
top-level window.
--------------------------------------------------------------------*/
void Main_OnDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
TCHAR szMsg[80];
switch (wParam)
{
case DBT_DEVICEARRIVAL:
if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
StringCchPrintf(szMsg, sizeof(szMsg) / sizeof(szMsg[0]),
TEXT("Drive %c: has arrived.n"),
FirstDriveFromMask(lpdbv->dbcv_unitmask));
MessageBox(NULL, szMsg, L"", MB_OK);
}
break;
case DBT_DEVICEREMOVECOMPLETE:
if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
StringCchPrintf(szMsg, sizeof(szMsg) / sizeof(szMsg[0]),
TEXT("Drive %c: has been removed.n"),
FirstDriveFromMask(lpdbv->dbcv_unitmask));
MessageBox(NULL, szMsg, L"", MB_OK);
}
break;
}
}
char FirstDriveFromMask(ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
i += 'A';
char name[] = {'n', i, ':', ''};
OutputDebugStringA(name);
return i;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR    lpCmdLine,
_In_ int       nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_SO20200709, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SO20200709));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SO20200709));
wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_SO20200709);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DEVICECHANGE:
{
Main_OnDeviceChange(hWnd, wParam, lParam);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}