From 571cfed8d7a58d5d9f576d426092ff3bd871382c Mon Sep 17 00:00:00 2001 From: Thamatip Chitpong Date: Sat, 28 Oct 2023 06:22:23 +0700 Subject: [PATCH] [HOTPLUG] **WIP** Implement confirm devices list --- dll/cpl/hotplug/eject.c | 122 +++++++++++++++++++++++++++++++++++++- dll/cpl/hotplug/hotplug.c | 28 ++++----- dll/cpl/hotplug/hotplug.h | 9 +++ 3 files changed, 138 insertions(+), 21 deletions(-) diff --git a/dll/cpl/hotplug/eject.c b/dll/cpl/hotplug/eject.c index 2de314ba50e11..14184818a8070 100644 --- a/dll/cpl/hotplug/eject.c +++ b/dll/cpl/hotplug/eject.c @@ -7,6 +7,105 @@ #include "hotplug.h" +static +HTREEITEM +GetTopLevelItemOfSelectedDevice( + _In_ HWND hwndDeviceTree) +{ + HTREEITEM hTreeItem; + + hTreeItem = TreeView_GetSelection(hwndDeviceTree); + if (!hTreeItem) + return NULL; + + while (TreeView_GetParent(hwndDeviceTree, hTreeItem)) + { + hTreeItem = TreeView_GetParent(hwndDeviceTree, hTreeItem); + } + + return hTreeItem; +} + +static +VOID +InsertConfirmDeviceListItem( + _In_ HWND hwndDeviceTree, + _In_ HWND hwndCfmDeviceList, + _In_ HTREEITEM hDevTreeItem) +{ + TVITEMW tvItem; + WCHAR szDisplayName[40]; + LVITEMW lvItem; + + /* Retrieve data from the source tree-view item */ + ZeroMemory(&tvItem, sizeof(tvItem)); + tvItem.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM; + tvItem.hItem = hDevTreeItem; + tvItem.pszText = szDisplayName; + tvItem.cchTextMax = ARRAYSIZE(szDisplayName); + TreeView_GetItem(hwndDeviceTree, &tvItem); + + /* Copy data to the new list-view item */ + ZeroMemory(&lvItem, sizeof(lvItem)); + lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + lvItem.iItem = ListView_GetItemCount(hwndCfmDeviceList); + lvItem.pszText = szDisplayName; + lvItem.iImage = tvItem.iImage; + lvItem.lParam = tvItem.lParam; + ListView_InsertItem(hwndCfmDeviceList, &lvItem); +} + +static +VOID +FillConfirmDeviceList( + _In_ HWND hwndDeviceTree, + _In_ HWND hwndCfmDeviceList) +{ + HTREEITEM hTreeItem; + LVCOLUMNW lvColumn; + + hTreeItem = GetTopLevelItemOfSelectedDevice(hwndDeviceTree); + if (!hTreeItem) + return; + + ZeroMemory(&lvColumn, sizeof(lvColumn)); + lvColumn.mask = LVCF_FMT | LVCF_ORDER; + + lvColumn.fmt = LVCFMT_IMAGE; + lvColumn.iOrder = 0; + ListView_InsertColumn(hwndCfmDeviceList, 0, &lvColumn); + + lvColumn.fmt = LVCFMT_LEFT; + lvColumn.iOrder = 1; + ListView_InsertColumn(hwndCfmDeviceList, 1, &lvColumn); + + InsertConfirmDeviceListItem(hwndDeviceTree, hwndCfmDeviceList, hTreeItem); + + ListView_SetColumnWidth(hwndCfmDeviceList, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndCfmDeviceList, 1, LVSCW_AUTOSIZE_USEHEADER); +} + +static +DEVINST +GetDeviceInstForRemoval( + _In_ HWND hwndDeviceTree) +{ + HTREEITEM hTreeItem; + TVITEMW item; + + hTreeItem = GetTopLevelItemOfSelectedDevice(hwndDeviceTree); + if (!hTreeItem) + return 0; + + ZeroMemory(&item, sizeof(item)); + item.mask = TVIF_PARAM; + item.hItem = hTreeItem; + + TreeView_GetItem(hwndDeviceTree, &item); + + return item.lParam; +} + static VOID SafeRemoveDevice( @@ -32,20 +131,33 @@ ConfirmRemovalDlgProc( WPARAM wParam, LPARAM lParam) { - static DEVINST selectedDev; + PHOTPLUG_DATA pHotplugData; + + pHotplugData = (PHOTPLUG_DATA)GetWindowLongPtrW(hwndDlg, DWLP_USER); switch (uMsg) { case WM_INITDIALOG: - selectedDev = lParam; + { + pHotplugData = (PHOTPLUG_DATA)lParam; + SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)pHotplugData); + + ListView_SetImageList(GetDlgItem(hwndDlg, IDC_CONFIRM_STOP_DEVICE_LIST), + pHotplugData->ImageListData.ImageList, + LVSIL_NORMAL); + + FillConfirmDeviceList(pHotplugData->hwndDeviceTree, + GetDlgItem(hwndDlg, IDC_CONFIRM_STOP_DEVICE_LIST)); + return TRUE; + } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: - SafeRemoveDevice(selectedDev); + SafeRemoveDevice(GetDeviceInstForRemoval(pHotplugData->hwndDeviceTree)); EndDialog(hwndDlg, TRUE); break; @@ -56,6 +168,10 @@ ConfirmRemovalDlgProc( break; } + + case WM_DESTROY: + SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)NULL); + break; } return FALSE; diff --git a/dll/cpl/hotplug/hotplug.c b/dll/cpl/hotplug/hotplug.c index a74728abf99a0..58c570fb6bd9c 100644 --- a/dll/cpl/hotplug/hotplug.c +++ b/dll/cpl/hotplug/hotplug.c @@ -14,17 +14,6 @@ #define NDEBUG #include - -typedef struct _HOTPLUG_DATA -{ - HICON hIcon; - HICON hIconSm; - SP_CLASSIMAGELIST_DATA ImageListData; - HMENU hPopupMenu; - DWORD dwFlags; -} HOTPLUG_DATA, *PHOTPLUG_DATA; - - // globals HINSTANCE hApplet = 0; @@ -456,7 +445,7 @@ SafeRemovalDlgProc( SetupDiGetClassImageList(&pHotplugData->ImageListData); pHotplugData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_DEVICE_TREE)); - + pHotplugData->hwndDeviceTree = GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE); pHotplugData->dwFlags = GetHotPlugFlags(); if (pHotplugData->dwFlags & HOTPLUG_DISPLAY_DEVICE_COMPONENTS) @@ -509,12 +498,15 @@ SafeRemovalDlgProc( case IDC_SAFE_REMOVE_STOP: case IDM_STOP: { - HWND hwndDevTree = GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE); - DialogBoxParamW(hApplet, - MAKEINTRESOURCEW(IDD_CONFIRM_STOP_HARDWARE_DIALOG), - hwndDlg, - ConfirmRemovalDlgProc, - (LPARAM)GetSelectedDeviceInst(hwndDevTree)); + if (pHotplugData != NULL) + { + DialogBoxParamW(hApplet, + MAKEINTRESOURCEW(IDD_CONFIRM_STOP_HARDWARE_DIALOG), + hwndDlg, + ConfirmRemovalDlgProc, + (LPARAM)pHotplugData); + } + break; } } diff --git a/dll/cpl/hotplug/hotplug.h b/dll/cpl/hotplug/hotplug.h index 47cf851b93a9a..66e8dccb9f9d2 100644 --- a/dll/cpl/hotplug/hotplug.h +++ b/dll/cpl/hotplug/hotplug.h @@ -38,6 +38,15 @@ typedef struct APPLET_PROC AppletProc; }APPLET, *PAPPLET; +typedef struct _HOTPLUG_DATA +{ + HICON hIcon; + HICON hIconSm; + SP_CLASSIMAGELIST_DATA ImageListData; + HMENU hPopupMenu; + HWND hwndDeviceTree; + DWORD dwFlags; +} HOTPLUG_DATA, *PHOTPLUG_DATA; // eject.c INT_PTR