从 WM_DEVICECHANGE LParam 获取设备的友好名称
Get friendly name of a device from WM_DEVICECHANGE LParam
所以我正在为学校 PC 构建一个应用程序来跟踪所有插入的设备。
每当我插入或移除设备时,我设法使用 RegisterDeviceNotification()
在主线程中获得通知。
不过,我所能得到的只是 LParam
,一个设备唯一的指针。
我找不到任何有关如何使用该 LParam 获取设备的友好名称的信息。
我能找到的唯一资源是 2006 年的 this CodeProject(在 C++ 中)。
我在 pinvoke.net 上找不到任何东西,我唯一找到的东西(我不记得确切的位置)是使用 ManagementObjectSearcher
来获取此数据,但它找到了空数据. (这里是代码)
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Name from Win32_PnpEntity");
foreach (ManagementObject devices in searcher.Get())
{
foreach (var v in devices.Properties)
{
Console.WriteLine(v.Value);
}
}
searcher.Dispose();
谁能帮我弄清楚如何获取设备的友好名称?
您需要注册设备通知
RegisterDeviceNotificationW
static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE };
_hDevNot = RegisterDeviceNotificationW(hwnd, &dbd,
DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
因此您将收到 WM_DEVICECHANGE
消息
这里你需要检查 wParam for DBT_DEVICEARRIVAL
和
DBT_DEVICEREMOVECOMPLETE
事件
检查 dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE
在 DEV_BROADCAST_DEVICEINTERFACE_W.dbcc_name
你有
设备接口名称
你可以在里面用这个名字CM_Get_Device_Interface_PropertyW
启用 DEVPKEY_Device_InstanceId
功能
DBT_DEVICEARRIVAL
事件
-
在通话中使用它CM_Locate_DevNodeW
在调用 CM_Get_DevNode_PropertyW
中使用结果
DEVPKEY_NAME
or DEVPKEY_DeviceInterface_FriendlyName
on DBT_DEVICEREMOVECOMPLETE
- 你只能看自己
数据库(如果你在到达时创建它)这样的名字和友好
名字.
演示代码:
struct DeviceName : public LIST_ENTRY
{
ULONG InterfaceHash;
WCHAR Name[];
void* operator new(size_t cb, size_t len)
{
return LocalAlloc(0, cb + len);
}
void operator delete(void* pv)
{
LocalFree(pv);
}
};
volatile const UCHAR guz = 0;
CONFIGRET GetFriendlyNameByDevNode(DeviceName** pp, DEVINST dnDevInst)
{
CONFIGRET status;
ULONG cb = 32;
DEVPROPTYPE PropertyType;
do
{
if (DeviceName* p = new(cb) DeviceName)
{
status = CM_Get_DevNode_PropertyW(
dnDevInst, &DEVPKEY_DeviceInterface_FriendlyName, &PropertyType, (PBYTE)p->Name, &cb, 0);
if (status == CR_SUCCESS)
{
if (PropertyType == DEVPROP_TYPE_STRING)
{
*pp = p;
return CR_SUCCESS;
}
else
{
status = CR_WRONG_TYPE;
}
}
delete p;
}
else
{
status = CR_OUT_OF_MEMORY;
}
} while (CR_BUFFER_SMALL == status);
return status;
}
CONFIGRET GetFriendlyNameByInterface(DeviceName** pp, PCWSTR pszDeviceInterface)
{
// RTCu must be disabled !
ULONG cb = 0, rcb = 64;
PVOID stack = alloca(guz);
DEVPROPTYPE PropertyType;
CONFIGRET status;
union {
PVOID pv;
PWSTR DeviceID;
PBYTE pb;
};
do
{
if (cb < rcb)
{
rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
}
} while (CR_BUFFER_SMALL == (status = CM_Get_Device_Interface_PropertyW(
pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, pb, &rcb, 0)));
if (status == CR_SUCCESS)
{
if (PropertyType == DEVPROP_TYPE_STRING)
{
DEVINST dnDevInst;
status = CM_Locate_DevNodeW(&dnDevInst, DeviceID, CM_LOCATE_DEVNODE_NORMAL);
return status == CR_SUCCESS ? GetFriendlyNameByDevNode(pp, dnDevInst) : status;
}
else
{
status = CR_WRONG_TYPE;
}
}
return status;
}
case WM_DESTROY:
if (_hDevNot)
{
UnregisterDeviceNotification(_hDevNot);
PLIST_ENTRY head = &_DevListHead, entry = head->Flink;
while (entry != head)
{
DeviceName* p = static_cast<DeviceName*>(entry);
entry = entry->Flink;
delete p;
}
}
break;
case WM_DEVICECHANGE:
switch (wParam)
{
case DBT_DEVICEREMOVECOMPLETE:
case DBT_DEVICEARRIVAL:
if (reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
DeviceName* p;
ULONG InterfaceHash;
UNICODE_STRING dbcc_name;
RtlInitUnicodeString(&dbcc_name, reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_name);
RtlHashUnicodeString(&dbcc_name, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &InterfaceHash);
if (wParam == DBT_DEVICEARRIVAL)
{
if (CR_SUCCESS == GetFriendlyNameByInterface(&p, dbcc_name.Buffer))
{
p->InterfaceHash = InterfaceHash;
InsertHeadList(&_DevListHead, p);
DbgPrint("inserted %S ( %wZ )\n", p->Name, &dbcc_name);
}
}
else
{
PLIST_ENTRY head = &_DevListHead, entry = head;
while ((entry = entry->Flink) != head)
{
if (static_cast<DeviceName*>(entry)->InterfaceHash == InterfaceHash)
{
DbgPrint("removed %S ( %wZ )\n",
static_cast<DeviceName*>(entry)->Name, &dbcc_name);
RemoveEntryList(entry);
delete static_cast<DeviceName*>(entry);
break;
}
}
}
}
break;
}
return 0;
case WM_CREATE:
InitializeListHead(&_DevListHead);
static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE };
_hDevNot = RegisterDeviceNotificationW(hwnd, &dbd, DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
break;
所以我正在为学校 PC 构建一个应用程序来跟踪所有插入的设备。
每当我插入或移除设备时,我设法使用 RegisterDeviceNotification()
在主线程中获得通知。
不过,我所能得到的只是 LParam
,一个设备唯一的指针。
我找不到任何有关如何使用该 LParam 获取设备的友好名称的信息。 我能找到的唯一资源是 2006 年的 this CodeProject(在 C++ 中)。
我在 pinvoke.net 上找不到任何东西,我唯一找到的东西(我不记得确切的位置)是使用 ManagementObjectSearcher
来获取此数据,但它找到了空数据. (这里是代码)
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Name from Win32_PnpEntity");
foreach (ManagementObject devices in searcher.Get())
{
foreach (var v in devices.Properties)
{
Console.WriteLine(v.Value);
}
}
searcher.Dispose();
谁能帮我弄清楚如何获取设备的友好名称?
您需要注册设备通知
RegisterDeviceNotificationW
static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE }; _hDevNot = RegisterDeviceNotificationW(hwnd, &dbd, DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
因此您将收到
WM_DEVICECHANGE
消息这里你需要检查 wParam for
DBT_DEVICEARRIVAL
和DBT_DEVICEREMOVECOMPLETE
事件检查
dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE
在
DEV_BROADCAST_DEVICEINTERFACE_W.dbcc_name
你有 设备接口名称你可以在里面用这个名字
CM_Get_Device_Interface_PropertyW
启用DEVPKEY_Device_InstanceId
功能DBT_DEVICEARRIVAL
事件在通话中使用它
CM_Locate_DevNodeW
在调用
CM_Get_DevNode_PropertyW
中使用结果DEVPKEY_NAME
orDEVPKEY_DeviceInterface_FriendlyName
on
DBT_DEVICEREMOVECOMPLETE
- 你只能看自己 数据库(如果你在到达时创建它)这样的名字和友好 名字.
演示代码:
struct DeviceName : public LIST_ENTRY
{
ULONG InterfaceHash;
WCHAR Name[];
void* operator new(size_t cb, size_t len)
{
return LocalAlloc(0, cb + len);
}
void operator delete(void* pv)
{
LocalFree(pv);
}
};
volatile const UCHAR guz = 0;
CONFIGRET GetFriendlyNameByDevNode(DeviceName** pp, DEVINST dnDevInst)
{
CONFIGRET status;
ULONG cb = 32;
DEVPROPTYPE PropertyType;
do
{
if (DeviceName* p = new(cb) DeviceName)
{
status = CM_Get_DevNode_PropertyW(
dnDevInst, &DEVPKEY_DeviceInterface_FriendlyName, &PropertyType, (PBYTE)p->Name, &cb, 0);
if (status == CR_SUCCESS)
{
if (PropertyType == DEVPROP_TYPE_STRING)
{
*pp = p;
return CR_SUCCESS;
}
else
{
status = CR_WRONG_TYPE;
}
}
delete p;
}
else
{
status = CR_OUT_OF_MEMORY;
}
} while (CR_BUFFER_SMALL == status);
return status;
}
CONFIGRET GetFriendlyNameByInterface(DeviceName** pp, PCWSTR pszDeviceInterface)
{
// RTCu must be disabled !
ULONG cb = 0, rcb = 64;
PVOID stack = alloca(guz);
DEVPROPTYPE PropertyType;
CONFIGRET status;
union {
PVOID pv;
PWSTR DeviceID;
PBYTE pb;
};
do
{
if (cb < rcb)
{
rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
}
} while (CR_BUFFER_SMALL == (status = CM_Get_Device_Interface_PropertyW(
pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, pb, &rcb, 0)));
if (status == CR_SUCCESS)
{
if (PropertyType == DEVPROP_TYPE_STRING)
{
DEVINST dnDevInst;
status = CM_Locate_DevNodeW(&dnDevInst, DeviceID, CM_LOCATE_DEVNODE_NORMAL);
return status == CR_SUCCESS ? GetFriendlyNameByDevNode(pp, dnDevInst) : status;
}
else
{
status = CR_WRONG_TYPE;
}
}
return status;
}
case WM_DESTROY:
if (_hDevNot)
{
UnregisterDeviceNotification(_hDevNot);
PLIST_ENTRY head = &_DevListHead, entry = head->Flink;
while (entry != head)
{
DeviceName* p = static_cast<DeviceName*>(entry);
entry = entry->Flink;
delete p;
}
}
break;
case WM_DEVICECHANGE:
switch (wParam)
{
case DBT_DEVICEREMOVECOMPLETE:
case DBT_DEVICEARRIVAL:
if (reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
DeviceName* p;
ULONG InterfaceHash;
UNICODE_STRING dbcc_name;
RtlInitUnicodeString(&dbcc_name, reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_name);
RtlHashUnicodeString(&dbcc_name, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &InterfaceHash);
if (wParam == DBT_DEVICEARRIVAL)
{
if (CR_SUCCESS == GetFriendlyNameByInterface(&p, dbcc_name.Buffer))
{
p->InterfaceHash = InterfaceHash;
InsertHeadList(&_DevListHead, p);
DbgPrint("inserted %S ( %wZ )\n", p->Name, &dbcc_name);
}
}
else
{
PLIST_ENTRY head = &_DevListHead, entry = head;
while ((entry = entry->Flink) != head)
{
if (static_cast<DeviceName*>(entry)->InterfaceHash == InterfaceHash)
{
DbgPrint("removed %S ( %wZ )\n",
static_cast<DeviceName*>(entry)->Name, &dbcc_name);
RemoveEntryList(entry);
delete static_cast<DeviceName*>(entry);
break;
}
}
}
}
break;
}
return 0;
case WM_CREATE:
InitializeListHead(&_DevListHead);
static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE };
_hDevNot = RegisterDeviceNotificationW(hwnd, &dbd, DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
break;