[HOTPLUG] Display devices that are attached to a removable device
authorEric Kohl <eric.kohl@reactos.org>
Sat, 4 Apr 2020 16:13:03 +0000 (18:13 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 4 Apr 2020 16:13:03 +0000 (18:13 +0200)
dll/cpl/hotplug/hotplug.c
dll/cpl/hotplug/hotplug.h

index 17788fc..7e0d32a 100644 (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");
-
-            /* 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),
index 38beaac..8e11875 100644 (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>
 #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;