https://git.reactos.org/?p=reactos.git;a=commitdiff;h=68b6639ade4a2570ca8c5…
commit 68b6639ade4a2570ca8c52b360babdbc8e08f1b5
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Apr 4 18:13:03 2020 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sat Apr 4 18:13:03 2020 +0200
[HOTPLUG] Display devices that are attached to a removable device
---
dll/cpl/hotplug/hotplug.c | 290 +++++++++++++++++++++++++++++++++++++---------
dll/cpl/hotplug/hotplug.h | 5 +
2 files changed, 239 insertions(+), 56 deletions(-)
diff --git a/dll/cpl/hotplug/hotplug.c b/dll/cpl/hotplug/hotplug.c
index 17788fc8212..7e0d32a80d4 100644
--- a/dll/cpl/hotplug/hotplug.c
+++ b/dll/cpl/hotplug/hotplug.c
@@ -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");
-
- /* 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)
- {
- pSetupGuidFromString(szGuidString, &ClassGuid);
- }
- else
+ hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
+ TVI_ROOT,
+ did.DevInst,
+ pHotplugData);
+
+ if ((hTreeItem != NULL) && (pHotplugData->dwFlags &
HOTPLUG_DISPLAY_DEVICE_COMPONENTS))
{
-// memcpy(&ClassGuid, GUID_DEVCLASS_UNKNOWN, sizeof(GUID));
+ RecursiveInsertSubDevices(hwndDeviceTree,
+ hTreeItem,
+ did.DevInst,
+ pHotplugData);
}
-
- /* 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),
diff --git a/dll/cpl/hotplug/hotplug.h b/dll/cpl/hotplug/hotplug.h
index 38beaac69c3..8e11875c613 100644
--- a/dll/cpl/hotplug/hotplug.h
+++ b/dll/cpl/hotplug/hotplug.h
@@ -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;