https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cbdf649f2cb6ee27b8333…
commit cbdf649f2cb6ee27b8333860b916a05037e9d211
Author:     Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Mon Mar 30 23:11:44 2020 +0200
Commit:     Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Mon Mar 30 23:11:44 2020 +0200
    [HOTPLUG] Show removable devices and update the list on arrival and removal.
---
 dll/cpl/hotplug/hotplug.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++
 dll/cpl/hotplug/hotplug.h |   4 ++
 2 files changed, 115 insertions(+)
diff --git a/dll/cpl/hotplug/hotplug.c b/dll/cpl/hotplug/hotplug.c
index c67d0d80376..7152e487075 100644
--- a/dll/cpl/hotplug/hotplug.c
+++ b/dll/cpl/hotplug/hotplug.c
@@ -21,6 +21,93 @@ APPLET Applets[NUM_APPLETS] =
 };
+static
+VOID
+EnumHotpluggedDevices(HWND hwndDeviceTree)
+{
+    WCHAR szDisplayName[40];
+    SP_DEVINFO_DATA did = { 0 };
+    HDEVINFO hdev;
+    int idev;
+    DWORD dwCapabilities, dwSize;
+    ULONG ulStatus, ulProblem;
+    TVINSERTSTRUCTW tvItem;
+    CONFIGRET cr;
+
+    TreeView_DeleteAllItems(hwndDeviceTree);
+
+    hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
+    if (hdev == INVALID_HANDLE_VALUE)
+        return;
+
+    did.cbSize = sizeof(did);
+
+    /* Enumerate all the attached devices */
+    for (idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++)
+    {
+        ulStatus = 0;
+        ulProblem = 0;
+
+        cr = CM_Get_DevNode_Status(&ulStatus,
+                                   &ulProblem,
+                                   did.DevInst,
+                                   0);
+        if (cr != CR_SUCCESS)
+            continue;
+
+        dwCapabilities = 0,
+        dwSize = sizeof(dwCapabilities);
+        cr = CM_Get_DevNode_Registry_Property(did.DevInst,
+                                              CM_DRP_CAPABILITIES,
+                                              NULL,
+                                              &dwCapabilities,
+                                              &dwSize,
+                                              0);
+        if (cr != CR_SUCCESS)
+            continue;
+
+        /* Add devices that require safe removal to the device tree */
+        if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) &&
+            !(dwCapabilities & CM_DEVCAP_DOCKDEVICE) &&
+            !(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) &&
+            ((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");
+
+            /* 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 = IMAGE_SOUND_SECTION;
+//            tvItem.item.iSelectedImage = IMAGE_SOUND_SECTION;
+            tvItem.item.lParam = (LPARAM)NULL;
+
+            /*hTreeItem = */ TreeView_InsertItem(hwndDeviceTree, &tvItem);
+
+
+
+        }
+    }
+
+    SetupDiDestroyDeviceInfoList(hdev);
+}
+
+
 INT_PTR
 CALLBACK
 SafeRemovalDlgProc(
@@ -34,17 +121,41 @@ SafeRemovalDlgProc(
     switch (uMsg)
     {
         case WM_INITDIALOG:
+            EnumHotpluggedDevices(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE));
             return TRUE;
         case WM_COMMAND:
             switch (LOWORD(wParam))
             {
                 case IDCLOSE:
+                    KillTimer(hwndDlg, 1);
                     EndDialog(hwndDlg, TRUE);
                     break;
             }
             break;
+
+        case WM_DEVICECHANGE:
+            switch (wParam)
+            {
+                case DBT_DEVNODES_CHANGED:
+                    SetTimer(hwndDlg, 1, 500, NULL);
+                    break;
+            }
+            break;
+
+        case WM_TIMER:
+            if (wParam == 1)
+            {
+                KillTimer(hwndDlg, 1);
+                EnumHotpluggedDevices(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE));
+            }
+            break;
+
+        case WM_CLOSE:
+            KillTimer(hwndDlg, 1);
+            EndDialog(hwndDlg, TRUE);
+            break;
     }
     return FALSE;
diff --git a/dll/cpl/hotplug/hotplug.h b/dll/cpl/hotplug/hotplug.h
index b21d59a0235..38beaac69c3 100644
--- a/dll/cpl/hotplug/hotplug.h
+++ b/dll/cpl/hotplug/hotplug.h
@@ -7,10 +7,14 @@
 #include <wingdi.h>
 #include <winuser.h>
 #include <wincon.h>
+#include <winreg.h>
 #include <commctrl.h>
 #include <cpl.h>
 #include <tchar.h>
 #include <limits.h>
+#include <setupapi.h>
+#include <cfgmgr32.h>
+#include <dbt.h>
 #include "resource.h"