1*11905780SThamatip Chitpong /*
2*11905780SThamatip Chitpong * PROJECT: Safely Remove Hardware Applet
3*11905780SThamatip Chitpong * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4*11905780SThamatip Chitpong * PURPOSE: Device removal support
5*11905780SThamatip Chitpong * COPYRIGHT: Copyright 2023 Thamatip Chitpong <thamatip.chitpong@reactos.org>
6*11905780SThamatip Chitpong */
7*11905780SThamatip Chitpong
8*11905780SThamatip Chitpong #include "hotplug.h"
9*11905780SThamatip Chitpong
10*11905780SThamatip Chitpong #include <strsafe.h>
11*11905780SThamatip Chitpong
12*11905780SThamatip Chitpong DEVINST
GetDeviceInstForRemoval(_In_ PHOTPLUG_DATA pHotplugData)13*11905780SThamatip Chitpong GetDeviceInstForRemoval(
14*11905780SThamatip Chitpong _In_ PHOTPLUG_DATA pHotplugData)
15*11905780SThamatip Chitpong {
16*11905780SThamatip Chitpong HTREEITEM hItem, hParentItem;
17*11905780SThamatip Chitpong TVITEMW tvItem;
18*11905780SThamatip Chitpong
19*11905780SThamatip Chitpong hItem = TreeView_GetSelection(pHotplugData->hwndDeviceTree);
20*11905780SThamatip Chitpong if (!hItem)
21*11905780SThamatip Chitpong return 0;
22*11905780SThamatip Chitpong
23*11905780SThamatip Chitpong /* Find root item */
24*11905780SThamatip Chitpong hParentItem = TreeView_GetParent(pHotplugData->hwndDeviceTree, hItem);
25*11905780SThamatip Chitpong while (hParentItem)
26*11905780SThamatip Chitpong {
27*11905780SThamatip Chitpong hItem = hParentItem;
28*11905780SThamatip Chitpong hParentItem = TreeView_GetParent(pHotplugData->hwndDeviceTree, hItem);
29*11905780SThamatip Chitpong }
30*11905780SThamatip Chitpong
31*11905780SThamatip Chitpong ZeroMemory(&tvItem, sizeof(tvItem));
32*11905780SThamatip Chitpong tvItem.mask = TVIF_PARAM;
33*11905780SThamatip Chitpong tvItem.hItem = hItem;
34*11905780SThamatip Chitpong
35*11905780SThamatip Chitpong TreeView_GetItem(pHotplugData->hwndDeviceTree, &tvItem);
36*11905780SThamatip Chitpong
37*11905780SThamatip Chitpong return tvItem.lParam;
38*11905780SThamatip Chitpong }
39*11905780SThamatip Chitpong
40*11905780SThamatip Chitpong static
41*11905780SThamatip Chitpong VOID
FillConfirmDeviceList(_In_ HWND hwndCfmDeviceList,_In_ PHOTPLUG_DATA pHotplugData)42*11905780SThamatip Chitpong FillConfirmDeviceList(
43*11905780SThamatip Chitpong _In_ HWND hwndCfmDeviceList,
44*11905780SThamatip Chitpong _In_ PHOTPLUG_DATA pHotplugData)
45*11905780SThamatip Chitpong {
46*11905780SThamatip Chitpong LVCOLUMNW lvColumn;
47*11905780SThamatip Chitpong
48*11905780SThamatip Chitpong ZeroMemory(&lvColumn, sizeof(lvColumn));
49*11905780SThamatip Chitpong lvColumn.mask = LVCF_FMT;
50*11905780SThamatip Chitpong lvColumn.fmt = LVCFMT_LEFT | LVCFMT_IMAGE;
51*11905780SThamatip Chitpong ListView_InsertColumn(hwndCfmDeviceList, 0, &lvColumn);
52*11905780SThamatip Chitpong
53*11905780SThamatip Chitpong CfmListEnumDevices(hwndCfmDeviceList, pHotplugData);
54*11905780SThamatip Chitpong
55*11905780SThamatip Chitpong ListView_SetColumnWidth(hwndCfmDeviceList, 0, LVSCW_AUTOSIZE_USEHEADER);
56*11905780SThamatip Chitpong }
57*11905780SThamatip Chitpong
58*11905780SThamatip Chitpong static
59*11905780SThamatip Chitpong VOID
SafeRemoveDevice(_In_ DEVINST DevInst,_In_opt_ HWND hwndDlg)60*11905780SThamatip Chitpong SafeRemoveDevice(
61*11905780SThamatip Chitpong _In_ DEVINST DevInst,
62*11905780SThamatip Chitpong _In_opt_ HWND hwndDlg)
63*11905780SThamatip Chitpong {
64*11905780SThamatip Chitpong PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
65*11905780SThamatip Chitpong CONFIGRET cr;
66*11905780SThamatip Chitpong
67*11905780SThamatip Chitpong cr = CM_Request_Device_EjectW(DevInst, &VetoType, NULL, 0, 0);
68*11905780SThamatip Chitpong if (cr != CR_SUCCESS && VetoType == PNP_VetoTypeUnknown)
69*11905780SThamatip Chitpong {
70*11905780SThamatip Chitpong LPCWSTR pszFormat = L"";
71*11905780SThamatip Chitpong WCHAR szError[64];
72*11905780SThamatip Chitpong
73*11905780SThamatip Chitpong /* NOTES: IDS_EJECT_ERROR_FORMAT resource has to be explicitly NULL-terminated
74*11905780SThamatip Chitpong * so we can use the string directly without having to make a copy of it. */
75*11905780SThamatip Chitpong LoadStringW(hApplet, IDS_EJECT_ERROR_FORMAT, (LPWSTR)&pszFormat, 0);
76*11905780SThamatip Chitpong StringCbPrintfW(szError, sizeof(szError), pszFormat, cr);
77*11905780SThamatip Chitpong
78*11905780SThamatip Chitpong MessageBoxW(hwndDlg, szError, NULL, MB_ICONEXCLAMATION | MB_OK);
79*11905780SThamatip Chitpong }
80*11905780SThamatip Chitpong }
81*11905780SThamatip Chitpong
82*11905780SThamatip Chitpong INT_PTR
83*11905780SThamatip Chitpong CALLBACK
ConfirmRemovalDlgProc(_In_ HWND hwndDlg,_In_ UINT uMsg,_In_ WPARAM wParam,_In_ LPARAM lParam)84*11905780SThamatip Chitpong ConfirmRemovalDlgProc(
85*11905780SThamatip Chitpong _In_ HWND hwndDlg,
86*11905780SThamatip Chitpong _In_ UINT uMsg,
87*11905780SThamatip Chitpong _In_ WPARAM wParam,
88*11905780SThamatip Chitpong _In_ LPARAM lParam)
89*11905780SThamatip Chitpong {
90*11905780SThamatip Chitpong PHOTPLUG_DATA pHotplugData;
91*11905780SThamatip Chitpong
92*11905780SThamatip Chitpong pHotplugData = (PHOTPLUG_DATA)GetWindowLongPtrW(hwndDlg, DWLP_USER);
93*11905780SThamatip Chitpong
94*11905780SThamatip Chitpong switch (uMsg)
95*11905780SThamatip Chitpong {
96*11905780SThamatip Chitpong case WM_INITDIALOG:
97*11905780SThamatip Chitpong {
98*11905780SThamatip Chitpong HWND hwndDevList;
99*11905780SThamatip Chitpong
100*11905780SThamatip Chitpong pHotplugData = (PHOTPLUG_DATA)lParam;
101*11905780SThamatip Chitpong SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)pHotplugData);
102*11905780SThamatip Chitpong
103*11905780SThamatip Chitpong hwndDevList = GetDlgItem(hwndDlg, IDC_CONFIRM_STOP_DEVICE_LIST);
104*11905780SThamatip Chitpong
105*11905780SThamatip Chitpong ListView_SetImageList(hwndDevList,
106*11905780SThamatip Chitpong pHotplugData->ImageListData.ImageList,
107*11905780SThamatip Chitpong LVSIL_SMALL);
108*11905780SThamatip Chitpong
109*11905780SThamatip Chitpong FillConfirmDeviceList(hwndDevList, pHotplugData);
110*11905780SThamatip Chitpong
111*11905780SThamatip Chitpong return TRUE;
112*11905780SThamatip Chitpong }
113*11905780SThamatip Chitpong
114*11905780SThamatip Chitpong case WM_COMMAND:
115*11905780SThamatip Chitpong {
116*11905780SThamatip Chitpong switch (LOWORD(wParam))
117*11905780SThamatip Chitpong {
118*11905780SThamatip Chitpong case IDOK:
119*11905780SThamatip Chitpong SafeRemoveDevice(GetDeviceInstForRemoval(pHotplugData), hwndDlg);
120*11905780SThamatip Chitpong EndDialog(hwndDlg, LOWORD(wParam));
121*11905780SThamatip Chitpong break;
122*11905780SThamatip Chitpong
123*11905780SThamatip Chitpong case IDCANCEL:
124*11905780SThamatip Chitpong EndDialog(hwndDlg, LOWORD(wParam));
125*11905780SThamatip Chitpong break;
126*11905780SThamatip Chitpong }
127*11905780SThamatip Chitpong
128*11905780SThamatip Chitpong break;
129*11905780SThamatip Chitpong }
130*11905780SThamatip Chitpong
131*11905780SThamatip Chitpong case WM_DESTROY:
132*11905780SThamatip Chitpong SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
133*11905780SThamatip Chitpong break;
134*11905780SThamatip Chitpong }
135*11905780SThamatip Chitpong
136*11905780SThamatip Chitpong return FALSE;
137*11905780SThamatip Chitpong }
138