xref: /reactos/dll/cpl/hotplug/eject.c (revision 11905780)
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