ReactOS 0.4.15-dev-7924-g5949c20
hotplug.cpp File Reference
#include "precomp.h"
#include <atlsimpcoll.h>
#include <dbt.h>
#include <cfgmgr32.h>
#include <shlwapi.h>
Include dependency graph for hotplug.cpp:

Go to the source code of this file.

Macros

#define DISPLAY_NAME_LEN   40
 

Functions

HRESULT EnumHotpluggedDevices (CSimpleArray< DEVINST > &devList)
 
HRESULT NotifyBalloon (CSysTray *pSysTray, LPCWSTR szTitle=NULL, LPCWSTR szInfo=NULL, UINT uId=ID_ICON_HOTPLUG)
 
HRESULT STDMETHODCALLTYPE Hotplug_Init (_In_ CSysTray *pSysTray)
 
HRESULT STDMETHODCALLTYPE Hotplug_Update (_In_ CSysTray *pSysTray)
 
HRESULT STDMETHODCALLTYPE Hotplug_Shutdown (_In_ CSysTray *pSysTray)
 
static void _RunHotplug (CSysTray *pSysTray)
 
static void _ShowContextMenu (CSysTray *pSysTray)
 
static void _ShowContextMenuR (CSysTray *pSysTray)
 
VOID HotplugDeviceTimer (_In_ CSysTray *pSysTray)
 
HRESULT STDMETHODCALLTYPE Hotplug_Message (_In_ CSysTray *pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
 

Variables

CSimpleArray< DEVINSTg_devList
 
CString g_strHotplugTooltip
 
static HICON g_hIconHotplug = NULL
 
static WCHAR g_strMenuSel [DISPLAY_NAME_LEN]
 
static BOOL g_IsRemoving = FALSE
 

Macro Definition Documentation

◆ DISPLAY_NAME_LEN

#define DISPLAY_NAME_LEN   40

Definition at line 16 of file hotplug.cpp.

Function Documentation

◆ _RunHotplug()

static void _RunHotplug ( CSysTray pSysTray)
static

Definition at line 155 of file hotplug.cpp.

156{
157 ShellExecuteW(pSysTray->GetHWnd(),
158 L"open",
159 L"rundll32.exe",
160 L"shell32.dll,Control_RunDLL hotplug.dll",
161 NULL,
163}
HWND GetHWnd()
Definition: csystray.h:54
#define NULL
Definition: types.h:112
#define L(x)
Definition: ntvdm.h:50
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2402
#define SW_SHOWNORMAL
Definition: winuser.h:770

Referenced by _ShowContextMenuR(), and Hotplug_Message().

◆ _ShowContextMenu()

static void _ShowContextMenu ( CSysTray pSysTray)
static

Definition at line 165 of file hotplug.cpp.

166{
167 HMENU hPopup = CreatePopupMenu();
168 ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
169
170 for (INT index = 0; index < g_devList.GetSize(); index++)
171 {
172 WCHAR dispName[DISPLAY_NAME_LEN];
173 CString menuName;
175 if (cr != CR_SUCCESS)
176 StrCpyW(dispName, L"Unknown Device");
177
178 menuName.Format(IDS_HOTPLUG_REMOVE_3, dispName);
179 AppendMenuW(hPopup, MF_STRING, index+1, menuName);
180 }
181
182 SetForegroundWindow(pSysTray->GetHWnd());
184 POINT pt;
186
187 DWORD id = TrackPopupMenuEx(hPopup, flags,
188 pt.x, pt.y,
189 pSysTray->GetHWnd(), NULL);
190
191 if (id > 0)
192 {
193 id--; // since array indices starts from zero.
195 if (cr != CR_SUCCESS)
196 StrCpyW(g_strMenuSel, L"Unknown Device");
197
198 cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0);
199 if (cr != CR_SUCCESS)
200 {
201 WCHAR strInfo[128];
202 swprintf(strInfo, L"Problem Ejecting %wS", g_strMenuSel);
203 MessageBox(0, L"The device cannot be stopped right now! Try stopping it again later!", strInfo, MB_OK | MB_ICONEXCLAMATION);
204 }
205 else
206 {
207 //MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OK | MB_ICONINFORMATION);
209 g_devList.RemoveAt(id); /* thing is.. even after removing id at this point, the devnode_change occurs after some seconds of sucessful removal
210 and since pendrive is still plugged in it gets enumerated, if problem number is not filtered.
211 */
212 }
213 }
214
215 DestroyMenu(hPopup);
216}
#define CM_DRP_DEVICEDESC
Definition: cfgmgr32.h:676
#define CM_Get_DevNode_Registry_Property
Definition: cfgmgr32.h:1733
#define CM_Request_Device_Eject_Ex
Definition: cfgmgr32.h:2878
RETURN_TYPE CONFIGRET
Definition: cfgmgr32.h:74
#define CR_SUCCESS
Definition: cfgmgr32.h:842
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
#define TRUE
Definition: types.h:120
#define IDS_HOTPLUG_REMOVE_3
Definition: resource.h:20
LPWSTR WINAPI StrCpyW(LPWSTR lpszStr, LPCWSTR lpszSrc)
Definition: string.c:514
#define swprintf
Definition: precomp.h:40
#define pt(x, y)
Definition: drawing.c:79
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
#define DISPLAY_NAME_LEN
Definition: hotplug.cpp:16
static BOOL g_IsRemoving
Definition: hotplug.cpp:22
static WCHAR g_strMenuSel[DISPLAY_NAME_LEN]
Definition: hotplug.cpp:21
CSimpleArray< DEVINST > g_devList
Definition: hotplug.cpp:18
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define TPM_BOTTOMALIGN
Definition: winuser.h:2385
#define MF_STRING
Definition: winuser.h:138
BOOL WINAPI SetForegroundWindow(_In_ HWND)
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define TPM_RIGHTALIGN
Definition: winuser.h:2378
#define TPM_NONOTIFY
Definition: winuser.h:2386
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
#define MB_ICONEXCLAMATION
Definition: winuser.h:785
#define MB_OK
Definition: winuser.h:790
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MessageBox
Definition: winuser.h:5822
#define TPM_RETURNCMD
Definition: winuser.h:2387
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by Hotplug_Message().

◆ _ShowContextMenuR()

static void _ShowContextMenuR ( CSysTray pSysTray)
static

Definition at line 218 of file hotplug.cpp.

219{
221 HMENU hPopup = CreatePopupMenu();
222 AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu);
224
225 SetForegroundWindow(pSysTray->GetHWnd());
227 POINT pt;
229
230 DWORD id = TrackPopupMenuEx(hPopup, flags,
231 pt.x, pt.y,
232 pSysTray->GetHWnd(), NULL);
233
234 if (id == IDS_HOTPLUG_REMOVE_2)
235 {
236 _RunHotplug(pSysTray);
237 }
238
239 DestroyMenu(hPopup);
240}
#define FALSE
Definition: types.h:117
#define IDS_HOTPLUG_REMOVE_2
Definition: resource.h:19
static void _RunHotplug(CSysTray *pSysTray)
Definition: hotplug.cpp:155
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by Hotplug_Message().

◆ EnumHotpluggedDevices()

HRESULT EnumHotpluggedDevices ( CSimpleArray< DEVINST > &  devList)

Definition at line 35 of file hotplug.cpp.

36{
37 devList.RemoveAll(); // Clear current devList
40 return E_HANDLE;
41 SP_DEVINFO_DATA did = { 0 };
42 did.cbSize = sizeof(did);
43
44 // Enumerate all the attached devices.
45 for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++)
46 {
47 DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities);
48 ULONG ulStatus = 0, ulProblem = 0;
49 CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulProblem, did.DevInst, 0);
50 if (cr != CR_SUCCESS)
51 continue;
52
54 if (cr != CR_SUCCESS)
55 continue;
56
57 // Filter and make list of only the appropriate safely removable devices.
58 if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) &&
59 !(dwCapabilities & CM_DEVCAP_DOCKDEVICE) &&
60 !(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) &&
61 ((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
62 !ulProblem)
63 {
64 devList.Add(did.DevInst);
65 }
66 }
68
70 {
71 return E_UNEXPECTED;
72 }
73
74 return S_OK;
75}
#define DN_DISABLEABLE
Definition: cfg.h:131
#define CM_DEVCAP_EJECTSUPPORTED
Definition: cfgmgr32.h:736
#define CM_DRP_CAPABILITIES
Definition: cfgmgr32.h:691
#define CM_DEVCAP_SURPRISEREMOVALOK
Definition: cfgmgr32.h:742
#define CM_DEVCAP_DOCKDEVICE
Definition: cfgmgr32.h:738
#define CM_DEVCAP_REMOVABLE
Definition: cfgmgr32.h:737
CONFIGRET WINAPI CM_Get_DevNode_Status(_Out_ PULONG pulStatus, _Out_ PULONG pulProblemNumber, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags)
Definition: cfgmgr.c:3572
#define NO_ERROR
Definition: dderror.h:5
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
BOOL WINAPI SetupDiEnumDeviceInfo(HDEVINFO devinfo, DWORD index, PSP_DEVINFO_DATA info)
Definition: devinst.c:1787
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2893
#define S_OK
Definition: intsafe.h:52
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define DIGCF_ALLCLASSES
Definition: setupapi.h:172
#define SetupDiGetClassDevs
Definition: setupapi.h:2593
#define DIGCF_PRESENT
Definition: setupapi.h:171
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ HDEV hdev
Definition: winddi.h:3449
#define E_HANDLE
Definition: winerror.h:2850
#define E_UNEXPECTED
Definition: winerror.h:2456

Referenced by Hotplug_Init(), and HotplugDeviceTimer().

◆ Hotplug_Init()

HRESULT STDMETHODCALLTYPE Hotplug_Init ( _In_ CSysTray pSysTray)

Definition at line 124 of file hotplug.cpp.

125{
126 TRACE("Hotplug_Init\n");
127
130
132
133 if (g_devList.GetSize() > 0)
134 return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip);
135 else
136 return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip, NIS_HIDDEN);
137}
HINSTANCE g_hInstance
Definition: MainWindow.cpp:18
#define ID_ICON_HOTPLUG
Definition: precomp.h:34
#define IDS_HOTPLUG_REMOVE_1
Definition: resource.h:18
#define IDI_HOTPLUG_OK
Definition: resource.h:57
HRESULT EnumHotpluggedDevices(CSimpleArray< DEVINST > &devList)
Definition: hotplug.cpp:35
static HICON g_hIconHotplug
Definition: hotplug.cpp:20
CString g_strHotplugTooltip
Definition: hotplug.cpp:19
#define NIM_ADD
Definition: shellapi.h:94
#define TRACE(s)
Definition: solgame.cpp:4
#define LoadIcon
Definition: winuser.h:5813
#define MAKEINTRESOURCE
Definition: winuser.h:591

Referenced by Hotplug_Message().

◆ Hotplug_Message()

HRESULT STDMETHODCALLTYPE Hotplug_Message ( _In_ CSysTray pSysTray,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam,
LRESULT lResult 
)

Definition at line 258 of file hotplug.cpp.

259{
260 TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
261
262 switch (uMsg)
263 {
264 case WM_USER + 220:
265 TRACE("Hotplug_Message: WM_USER+220\n");
267 {
268 if (lParam)
269 {
270 pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, TRUE);
271 return Hotplug_Init(pSysTray);
272 }
273 else
274 {
275 pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, FALSE);
276 return Hotplug_Shutdown(pSysTray);
277 }
278 }
279 return S_FALSE;
280
281 case WM_USER + 221:
282 TRACE("Hotplug_Message: WM_USER+221\n");
284 {
285 lResult = (LRESULT)pSysTray->IsServiceEnabled(HOTPLUG_SERVICE_FLAG);
286 return S_OK;
287 }
288 return S_FALSE;
289
290 case WM_TIMER:
292 {
293 KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID);
294 _ShowContextMenu(pSysTray);
295 }
297 {
298 KillTimer(pSysTray->GetHWnd(), HOTPLUG_DEVICE_TIMER_ID);
299 HotplugDeviceTimer(pSysTray);
300 }
301 break;
302
303 case ID_ICON_HOTPLUG:
304 switch (lParam)
305 {
306 case WM_LBUTTONDOWN:
307 SetTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID, GetDoubleClickTime(), NULL);
308 break;
309
310 case WM_LBUTTONUP:
311 break;
312
313 case WM_LBUTTONDBLCLK:
314 KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID);
315 _RunHotplug(pSysTray);
316 break;
317
318 case WM_RBUTTONDOWN:
319 break;
320
321 case WM_RBUTTONUP:
322 _ShowContextMenuR(pSysTray);
323 break;
324
325 case WM_RBUTTONDBLCLK:
326 break;
327
328 case WM_MOUSEMOVE:
329 break;
330 }
331 return S_OK;
332
333 case WM_DEVICECHANGE:
334 switch (wParam)
335 {
337 TRACE("WM_DEVICECHANGE : DBT_DEVNODES_CHANGED\n");
338 SetTimer(pSysTray->GetHWnd(), HOTPLUG_DEVICE_TIMER_ID, 100, NULL);
339 lResult = true;
340 break;
341
343 break;
345 break;
347 break;
349 WCHAR strInfo[128];
350 swprintf(strInfo, L"The %wS can now be safely removed from the system.", g_strMenuSel);
351 NotifyBalloon(pSysTray, L"Safe to Remove Hardware", strInfo);
352
353 lResult = true;
354 break;
356 break;
357 }
358 return S_OK;
359
360 default:
361 TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
362 return S_FALSE;
363 }
364
365 return S_FALSE;
366}
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define DBT_DEVICEREMOVEPENDING
Definition: dbt.h:15
#define DBT_DEVNODES_CHANGED
Definition: dbt.h:28
#define DBT_DEVICEQUERYREMOVE
Definition: dbt.h:13
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
#define DBT_DEVICEQUERYREMOVEFAILED
Definition: dbt.h:14
#define HOTPLUG_TIMER_ID
Definition: precomp.h:85
#define HOTPLUG_SERVICE_FLAG
Definition: precomp.h:39
#define HOTPLUG_DEVICE_TIMER_ID
Definition: precomp.h:86
HRESULT NotifyBalloon(CSysTray *pSysTray, LPCWSTR szTitle=NULL, LPCWSTR szInfo=NULL, UINT uId=ID_ICON_HOTPLUG)
Definition: hotplug.cpp:94
HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray *pSysTray)
Definition: hotplug.cpp:124
HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray *pSysTray)
Definition: hotplug.cpp:145
VOID HotplugDeviceTimer(_In_ CSysTray *pSysTray)
Definition: hotplug.cpp:244
static void _ShowContextMenuR(CSysTray *pSysTray)
Definition: hotplug.cpp:218
static void _ShowContextMenu(CSysTray *pSysTray)
Definition: hotplug.cpp:165
#define LRESULT
Definition: ole.h:14
#define S_FALSE
Definition: winerror.h:2357
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1778
#define WM_RBUTTONUP
Definition: winuser.h:1780
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1781
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
#define WM_DEVICECHANGE
Definition: winuser.h:1811
UINT WINAPI GetDoubleClickTime(void)
Definition: ntwrapper.h:314
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
#define WM_TIMER
Definition: winuser.h:1742
#define WM_LBUTTONUP
Definition: winuser.h:1777
#define WM_USER
Definition: winuser.h:1895
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)

◆ Hotplug_Shutdown()

HRESULT STDMETHODCALLTYPE Hotplug_Shutdown ( _In_ CSysTray pSysTray)

Definition at line 145 of file hotplug.cpp.

146{
147 TRACE("Hotplug_Shutdown\n");
148
151
152 return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL);
153}
#define NIM_DELETE
Definition: shellapi.h:96
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2053

Referenced by Hotplug_Message().

◆ Hotplug_Update()

HRESULT STDMETHODCALLTYPE Hotplug_Update ( _In_ CSysTray pSysTray)

Definition at line 139 of file hotplug.cpp.

140{
141 TRACE("Hotplug_Update\n");
142 return S_OK;
143}

◆ HotplugDeviceTimer()

VOID HotplugDeviceTimer ( _In_ CSysTray pSysTray)

Definition at line 244 of file hotplug.cpp.

246{
247 TRACE("HotplugDeviceTimer()\n");
248
250
251 if (g_devList.GetSize() > 0)
253 else
254 pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip, NIS_HIDDEN);
255}
#define NIM_MODIFY
Definition: shellapi.h:95

Referenced by Hotplug_Message().

◆ NotifyBalloon()

HRESULT NotifyBalloon ( CSysTray pSysTray,
LPCWSTR  szTitle = NULL,
LPCWSTR  szInfo = NULL,
UINT  uId = ID_ICON_HOTPLUG 
)

Definition at line 94 of file hotplug.cpp.

95{
96 NOTIFYICONDATA nim = { 0 };
97
98 nim.cbSize = sizeof(nim);
99 nim.uID = uId;
100 nim.hWnd = pSysTray->GetHWnd();
101
102 nim.uFlags = NIF_INFO;
103 nim.uTimeout = 10;
104 nim.dwInfoFlags = NIIF_INFO;
105
107 StringCchCopy(nim.szInfo, _countof(nim.szInfo), szInfo);
109
110 Sleep(10000); /* As per windows, the balloon notification remains visible for atleast 10 sec.
111 This timer maintains the same condition.
112 Also it is required so that the icon doesn't hide instantly after last device is removed,
113 as that will prevent popping of notification.
114 */
116 StringCchCopy(nim.szInfo, _countof(nim.szInfo), L"");
118 g_IsRemoving = FALSE; /* This flag is used to prevent instant icon hiding after last device is removed.
119 The above timer maintains the required state for the same.
120 */
121 return ret ? S_OK : E_FAIL;
122}
#define E_FAIL
Definition: ddrawi.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define Shell_NotifyIcon
Definition: shellapi.h:691
#define _countof(array)
Definition: sndvol32.h:68
#define StringCchCopy
Definition: strsafe.h:139
CHAR szInfoTitle[64]
Definition: shellapi.h:245
CHAR szInfo[256]
Definition: shellapi.h:240
DWORD dwInfoFlags
Definition: shellapi.h:246
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
int ret

Referenced by Hotplug_Message().

Variable Documentation

◆ g_devList

CSimpleArray<DEVINST> g_devList

Definition at line 18 of file hotplug.cpp.

Referenced by _ShowContextMenu(), Hotplug_Init(), and HotplugDeviceTimer().

◆ g_hIconHotplug

HICON g_hIconHotplug = NULL
static

Definition at line 20 of file hotplug.cpp.

Referenced by Hotplug_Init(), Hotplug_Shutdown(), and HotplugDeviceTimer().

◆ g_IsRemoving

BOOL g_IsRemoving = FALSE
static

Definition at line 22 of file hotplug.cpp.

Referenced by _ShowContextMenu(), and NotifyBalloon().

◆ g_strHotplugTooltip

CString g_strHotplugTooltip

Definition at line 19 of file hotplug.cpp.

Referenced by Hotplug_Init(), and HotplugDeviceTimer().

◆ g_strMenuSel

WCHAR g_strMenuSel[DISPLAY_NAME_LEN]
static

Definition at line 21 of file hotplug.cpp.

Referenced by _ShowContextMenu(), and Hotplug_Message().