[HOTPLUG] Display devices that are attached to a removable device

This commit is contained in:
Eric Kohl 2020-04-04 18:13:03 +02:00
parent 7db342f8a1
commit 68b6639ade
2 changed files with 238 additions and 55 deletions

View file

@ -8,12 +8,17 @@
#include "hotplug.h"
#include <initguid.h>
#include <devguid.h>
#define NDEBUG
#include <debug.h>
typedef struct _HOTPLUG_DATA
{
SP_CLASSIMAGELIST_DATA ImageListData;
DWORD dwFlags;
} HOTPLUG_DATA, *PHOTPLUG_DATA;
@ -26,6 +31,197 @@ APPLET Applets[NUM_APPLETS] =
{IDI_HOTPLUG, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet}
};
static
DWORD
GetHotPlugFlags(VOID)
{
HKEY hKey = NULL;
DWORD dwFlags = 0;
DWORD dwSize, dwError;
dwError = RegOpenKeyExW(HKEY_CURRENT_USER,
REGSTR_PATH_SYSTRAY,
0,
KEY_READ,
&hKey);
if (dwError != ERROR_SUCCESS)
goto done;
dwSize = sizeof(dwFlags);
dwError = RegQueryValueExW(hKey,
L"HotPlugFlags",
NULL,
NULL,
(LPBYTE)&dwFlags,
&dwSize);
if (dwError != ERROR_SUCCESS)
dwFlags = 0;
done:
if (hKey != NULL)
RegCloseKey(hKey);
return dwFlags;
}
static
DWORD
SetHotPlugFlags(
_In_ DWORD dwFlags)
{
HKEY hKey = NULL;
DWORD dwError;
dwError = RegCreateKeyExW(HKEY_CURRENT_USER,
REGSTR_PATH_SYSTRAY,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
NULL);
if (dwError != ERROR_SUCCESS)
goto done;
dwError = RegSetValueExW(hKey,
L"HotPlugFlags",
0,
REG_DWORD,
(LPBYTE)&dwFlags,
sizeof(dwFlags));
done:
if (hKey != NULL)
RegCloseKey(hKey);
return dwError;
}
static
HTREEITEM
InsertDeviceTreeItem(
_In_ HWND hwndDeviceTree,
_In_ HTREEITEM hParent,
_In_ DWORD DevInst,
_In_ PHOTPLUG_DATA pHotplugData)
{
WCHAR szDisplayName[40];
WCHAR szGuidString[MAX_GUID_STRING_LEN];
TVINSERTSTRUCTW tvItem;
GUID ClassGuid;
INT nClassImage;
DWORD dwSize;
CONFIGRET cr;
/* Get the device description */
dwSize = sizeof(szDisplayName);
cr = CM_Get_DevNode_Registry_Property(DevInst,
CM_DRP_DEVICEDESC,
NULL,
szDisplayName,
&dwSize,
0);
if (cr != CR_SUCCESS)
wcscpy(szDisplayName, L"Unknown Device");
/* Get the class GUID */
dwSize = sizeof(szGuidString);
cr = CM_Get_DevNode_Registry_Property(DevInst,
CM_DRP_CLASSGUID,
NULL,
szGuidString,
&dwSize,
0);
if (cr == CR_SUCCESS)
{
pSetupGuidFromString(szGuidString, &ClassGuid);
}
else
{
memcpy(&ClassGuid, &GUID_DEVCLASS_UNKNOWN, sizeof(GUID));
}
/* Get the image for the class this device is in */
SetupDiGetClassImageIndex(&pHotplugData->ImageListData,
&ClassGuid,
&nClassImage);
/* Add it to the device tree */
ZeroMemory(&tvItem, sizeof(tvItem));
tvItem.hParent = hParent;
tvItem.hInsertAfter = TVI_LAST;
tvItem.item.mask = TVIF_STATE | TVIF_TEXT /*| TVIF_PARAM*/ | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvItem.item.state = TVIS_EXPANDED;
tvItem.item.stateMask = TVIS_EXPANDED;
tvItem.item.pszText = szDisplayName;
tvItem.item.iImage = nClassImage;
tvItem.item.iSelectedImage = nClassImage;
tvItem.item.lParam = (LPARAM)NULL;
return TreeView_InsertItem(hwndDeviceTree, &tvItem);
}
static
VOID
RecursiveInsertSubDevices(
_In_ HWND hwndDeviceTree,
_In_ HTREEITEM hParentItem,
_In_ DWORD ParentDevInst,
_In_ PHOTPLUG_DATA pHotplugData)
{
HTREEITEM hTreeItem;
DEVINST ChildDevInst;
CONFIGRET cr;
DPRINT("RecursiveInsertSubDevices()\n");
cr = CM_Get_Child(&ChildDevInst, ParentDevInst, 0);
if (cr != CR_SUCCESS)
{
DPRINT("No child! %lu\n", cr);
return;
}
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
hParentItem,
ChildDevInst,
pHotplugData);
if (hTreeItem != NULL)
{
RecursiveInsertSubDevices(hwndDeviceTree,
hTreeItem,
ChildDevInst,
pHotplugData);
}
for (;;)
{
cr = CM_Get_Sibling(&ChildDevInst, ChildDevInst, 0);
if (cr != CR_SUCCESS)
{
DPRINT("No sibling! %lu\n", cr);
return;
}
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
hParentItem,
ChildDevInst,
pHotplugData);
if (hTreeItem != NULL)
{
RecursiveInsertSubDevices(hwndDeviceTree,
hTreeItem,
ChildDevInst,
pHotplugData);
}
}
}
static
VOID
@ -33,19 +229,18 @@ EnumHotpluggedDevices(
HWND hwndDeviceTree,
PHOTPLUG_DATA pHotplugData)
{
WCHAR szDisplayName[40];
SP_DEVINFO_DATA did = { 0 };
HDEVINFO hdev;
int idev;
DWORD dwCapabilities, dwSize;
ULONG ulStatus, ulProblem;
TVINSERTSTRUCTW tvItem;
// HTREEITEM hTreeItem;
WCHAR szGuidString[MAX_GUID_STRING_LEN];
GUID ClassGuid;
INT nClassImage;
HTREEITEM hTreeItem;
CONFIGRET cr;
DPRINT1("EnumHotpluggedDevices()\n");
TreeView_DeleteAllItems(hwndDeviceTree);
hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
@ -85,56 +280,18 @@ EnumHotpluggedDevices(
((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
ulProblem == 0)
{
/* Get the device description */
dwSize = sizeof(szDisplayName);
cr = CM_Get_DevNode_Registry_Property(did.DevInst,
CM_DRP_DEVICEDESC,
NULL,
szDisplayName,
&dwSize,
0);
if (cr != CR_SUCCESS)
wcscpy(szDisplayName, L"Unknown Device");
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
TVI_ROOT,
did.DevInst,
pHotplugData);
/* Get the class GUID */
dwSize = sizeof(szGuidString);
cr = CM_Get_DevNode_Registry_Property(did.DevInst,
CM_DRP_CLASSGUID,
NULL,
szGuidString,
&dwSize,
0);
if (cr == CR_SUCCESS)
if ((hTreeItem != NULL) && (pHotplugData->dwFlags & HOTPLUG_DISPLAY_DEVICE_COMPONENTS))
{
pSetupGuidFromString(szGuidString, &ClassGuid);
RecursiveInsertSubDevices(hwndDeviceTree,
hTreeItem,
did.DevInst,
pHotplugData);
}
else
{
// memcpy(&ClassGuid, GUID_DEVCLASS_UNKNOWN, sizeof(GUID));
}
/* Get the image for the class this device is in */
SetupDiGetClassImageIndex(&pHotplugData->ImageListData,
&ClassGuid,
&nClassImage);
/* Add it to the device tree */
ZeroMemory(&tvItem, sizeof(tvItem));
tvItem.hParent = TVI_ROOT;
tvItem.hInsertAfter = TVI_FIRST;
tvItem.item.mask = TVIF_STATE | TVIF_TEXT /*| TVIF_PARAM*/ | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvItem.item.state = TVIS_EXPANDED;
tvItem.item.stateMask = TVIS_EXPANDED;
tvItem.item.pszText = szDisplayName;
tvItem.item.iImage = nClassImage;
tvItem.item.iSelectedImage = nClassImage;
tvItem.item.lParam = (LPARAM)NULL;
/*hTreeItem =*/ TreeView_InsertItem(hwndDeviceTree, &tvItem);
}
}
@ -154,7 +311,6 @@ SafeRemovalDlgProc(
UNREFERENCED_PARAMETER(lParam);
pHotplugData = (PHOTPLUG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
@ -168,6 +324,11 @@ SafeRemovalDlgProc(
pHotplugData->ImageListData.cbSize = sizeof(pHotplugData->ImageListData);
SetupDiGetClassImageList(&pHotplugData->ImageListData);
pHotplugData->dwFlags = GetHotPlugFlags();
if (pHotplugData->dwFlags & HOTPLUG_DISPLAY_DEVICE_COMPONENTS)
Button_SetCheck(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DISPLAY_COMPONENTS), BST_CHECKED);
TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE),
pHotplugData->ImageListData.ImageList,
TVSIL_NORMAL);
@ -185,6 +346,23 @@ SafeRemovalDlgProc(
EndDialog(hwndDlg, TRUE);
break;
case IDC_SAFE_REMOVE_DISPLAY_COMPONENTS:
if (HIWORD(wParam) == BN_CLICKED)
{
if (pHotplugData != NULL)
{
if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DISPLAY_COMPONENTS)) == BST_CHECKED)
pHotplugData->dwFlags |= HOTPLUG_DISPLAY_DEVICE_COMPONENTS;
else
pHotplugData->dwFlags &= ~HOTPLUG_DISPLAY_DEVICE_COMPONENTS;
SetHotPlugFlags(pHotplugData->dwFlags);
EnumHotpluggedDevices(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE),
pHotplugData);
}
}
break;
}
break;
@ -238,7 +416,7 @@ InitApplet(
LPARAM wParam,
LPARAM lParam)
{
DPRINT1("InitApplet()\n");
DPRINT("InitApplet()\n");
DialogBox(hApplet,
MAKEINTRESOURCE(IDD_SAFE_REMOVE_HARDWARE_DIALOG),

View file

@ -8,6 +8,7 @@
#include <winuser.h>
#include <wincon.h>
#include <winreg.h>
#include <windowsx.h>
#include <commctrl.h>
#include <cpl.h>
#include <tchar.h>
@ -15,9 +16,13 @@
#include <setupapi.h>
#include <cfgmgr32.h>
#include <dbt.h>
#include <regstr.h>
#include "resource.h"
/* Hotplug Flags */
#define HOTPLUG_DISPLAY_DEVICE_COMPONENTS 0x00000002
// Globals
extern HINSTANCE hApplet;