从GUID获取USB音量路径 [英] Get usb volume path from guid
问题描述
我有一个程序,该程序可在插入和拔出时检测USB设备.在插入新的USB驱动器时,我得到插入驱动器的GUID,例如 \\?\ USBSTOR#Disk& Ven_JetFlash& Prod_Transcend_8GB& Rev_1100#546IYBDAPBE1075Q& 0#{53f56307-b6bf-11d0-94f2-00a0c .我想从GUID获取驱动器的驱动器路径(例如E:,F:).\
I have a program which detects usb devices on inserting and removing. On inserting a new usb drive, I get GUID of the inserted drive like this \\?\USBSTOR#Disk&Ven_JetFlash&Prod_Transcend_8GB&Rev_1100#546IYBDAPBE1075Q&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
. I want to get the the drive paths (example E:,F:) for the drive form the GUID.\
#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:
I call the RegisterListener()
method to start listening for usb change
How do I get the drive path from GUID? (drive path example e:, f:, g:) . Note: I will only be inserting and removing usb flash drives and not devices like printer, phone etc.
Edit: I do not want to get drive name/label. I want the path like drive e: or f:
推荐答案
" 我想要类似驱动器e:或f:"
"I want the path like drive e: or f:"
任何具有顶级窗口的应用程序都可以接收基本信息通过处理
WM_DEVICECHANGE
消息来通知.
DBT_DEVICEARRIVAL
和 DBT_DEVICEREMOVECOMPLETE
事件是自动广播到端口设备的所有顶级窗口.
The DBT_DEVICEARRIVAL
and DBT_DEVICEREMOVECOMPLETE
events are
automatically broadcast to all top-level windows for port devices.
音量通知也广播到顶级窗口,因此如果 dbch_devicetype
是 DBT_DEVTYP_VOLUME
,该函数将失败.
Volume notifications are also broadcast to top-level windows, so
the function fails if dbch_devicetype
is DBT_DEVTYP_VOLUME
.
仅消息窗口(指定 HWND_MESSAGE
)使您能够发送和接收消息.它是不可见的,没有z顺序,不能被枚举,不接收广播消息.窗户只需发送邮件即可.
A message-only window (specify the HWND_MESSAGE
) enables you to
send and receive messages. It is not visible, has no z-order, cannot
be enumerated, and does not receive broadcast messages. The window
simply dispatches messages.
请参考"RegisterDeviceNotification"; 和"仅限邮件的Windows" .
因此,仅消息窗口有一些限制.但是,对于一般的顶层窗口,很容易实现.请参阅演练:创建传统的Windows桌面应用程序(C ++)".有关如何创建顶级窗口的信息.
So there are some limitations to a message-only window. However, for a general top-level window, it is easy to achieve. Refer to "Walkthrough: Create a traditional Windows Desktop application (C++)" for how to create a top-level window.
以下是基于Visual Studio中Windows桌面应用程序模板的完整示例.
The following is complete sample based on Windows Desktop Application template in Visual Studio.
#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, ':', '\0'};
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;
}
这篇关于从GUID获取USB音量路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!