xref: /reactos/dll/shellext/stobject/hotplug.cpp (revision 7fbc5f42)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     ReactOS system libraries
3c2c66affSColin Finck  * LICENSE:     GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:        dll/shellext/stobject/hotplug.cpp
5*7fbc5f42SShriraj Sawant  * PURPOSE:     Removable devices notification icon handler
6*7fbc5f42SShriraj Sawant  * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
7c2c66affSColin Finck  */
8*7fbc5f42SShriraj Sawant #include <windows.h>
9c2c66affSColin Finck #include "precomp.h"
10*7fbc5f42SShriraj Sawant #include <mmsystem.h>
11*7fbc5f42SShriraj Sawant #include <mmddk.h>
12*7fbc5f42SShriraj Sawant #include <atlstr.h>
13*7fbc5f42SShriraj Sawant #include <atlsimpcoll.h>
14*7fbc5f42SShriraj Sawant #include <dbt.h>
15*7fbc5f42SShriraj Sawant #include <setupapi.h>
16*7fbc5f42SShriraj Sawant #include <cfgmgr32.h>
17c2c66affSColin Finck 
18c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(stobject);
19*7fbc5f42SShriraj Sawant #define DISPLAY_NAME_LEN 40
20c2c66affSColin Finck 
21*7fbc5f42SShriraj Sawant //BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle);
22*7fbc5f42SShriraj Sawant 
23*7fbc5f42SShriraj Sawant CSimpleArray<DEVINST> g_devList;
24*7fbc5f42SShriraj Sawant /*static HDEVNOTIFY g_hDevNotify = NULL;*/
25c2c66affSColin Finck static HICON g_hIconHotplug = NULL;
26*7fbc5f42SShriraj Sawant static LPCWSTR g_strTooltip = L"Safely Remove Hardware and Eject Media";
27*7fbc5f42SShriraj Sawant static WCHAR g_strMenuSel[DISPLAY_NAME_LEN];
28c2c66affSColin Finck static BOOL g_IsRunning = FALSE;
29*7fbc5f42SShriraj Sawant static BOOL g_IsRemoving = FALSE;
30c2c66affSColin Finck 
31*7fbc5f42SShriraj Sawant /*++
32*7fbc5f42SShriraj Sawant * @name EnumHotpluggedDevices
33*7fbc5f42SShriraj Sawant *
34*7fbc5f42SShriraj Sawant * Enumerates the connected safely removable devices.
35*7fbc5f42SShriraj Sawant *
36*7fbc5f42SShriraj Sawant * @param devList
37*7fbc5f42SShriraj Sawant *        List of device instances, representing the currently attached devices.
38*7fbc5f42SShriraj Sawant *
39*7fbc5f42SShriraj Sawant * @return The error code.
40*7fbc5f42SShriraj Sawant *
41*7fbc5f42SShriraj Sawant *--*/
42*7fbc5f42SShriraj Sawant HRESULT EnumHotpluggedDevices(CSimpleArray<DEVINST> &devList)
43*7fbc5f42SShriraj Sawant {
44*7fbc5f42SShriraj Sawant     devList.RemoveAll(); // Clear current devList
45*7fbc5f42SShriraj Sawant     HDEVINFO hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
46*7fbc5f42SShriraj Sawant     if (INVALID_HANDLE_VALUE == hdev)
47*7fbc5f42SShriraj Sawant         return E_HANDLE;
48*7fbc5f42SShriraj Sawant     SP_DEVINFO_DATA did = { 0 };
49*7fbc5f42SShriraj Sawant     did.cbSize = sizeof(did);
50*7fbc5f42SShriraj Sawant 
51*7fbc5f42SShriraj Sawant     // Enumerate all the attached devices.
52*7fbc5f42SShriraj Sawant     for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++)
53*7fbc5f42SShriraj Sawant     {
54*7fbc5f42SShriraj Sawant         DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities);
55*7fbc5f42SShriraj Sawant         WCHAR dispName[DISPLAY_NAME_LEN];
56*7fbc5f42SShriraj Sawant         ULONG ulStatus = 0, ulPnum = 0, ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
57*7fbc5f42SShriraj Sawant         CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulPnum, did.DevInst, 0);
58*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
59*7fbc5f42SShriraj Sawant             continue;
60*7fbc5f42SShriraj Sawant         cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0);
61*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
62*7fbc5f42SShriraj Sawant             continue;
63*7fbc5f42SShriraj Sawant         cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_CAPABILITIES, NULL, &dwCapabilities, &dwSize, 0);
64*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
65*7fbc5f42SShriraj Sawant             continue;
66*7fbc5f42SShriraj Sawant 
67*7fbc5f42SShriraj Sawant         // Filter and make list of only the appropriate safely removable devices.
68*7fbc5f42SShriraj Sawant         if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) &&
69*7fbc5f42SShriraj Sawant             !(dwCapabilities & CM_DEVCAP_DOCKDEVICE) &&
70*7fbc5f42SShriraj Sawant             !(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) &&
71*7fbc5f42SShriraj Sawant             ((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
72*7fbc5f42SShriraj Sawant             !ulPnum)
73*7fbc5f42SShriraj Sawant         {
74*7fbc5f42SShriraj Sawant             devList.Add(did.DevInst);
75*7fbc5f42SShriraj Sawant         }
76*7fbc5f42SShriraj Sawant     }
77*7fbc5f42SShriraj Sawant     SetupDiDestroyDeviceInfoList(hdev);
78*7fbc5f42SShriraj Sawant 
79*7fbc5f42SShriraj Sawant     if (NO_ERROR != GetLastError() && ERROR_NO_MORE_ITEMS != GetLastError())
80*7fbc5f42SShriraj Sawant     {
81*7fbc5f42SShriraj Sawant         return E_UNEXPECTED;
82*7fbc5f42SShriraj Sawant     }
83*7fbc5f42SShriraj Sawant 
84*7fbc5f42SShriraj Sawant     return S_OK;
85*7fbc5f42SShriraj Sawant }
86*7fbc5f42SShriraj Sawant 
87*7fbc5f42SShriraj Sawant /*++
88*7fbc5f42SShriraj Sawant * @name NotifyBalloon
89*7fbc5f42SShriraj Sawant *
90*7fbc5f42SShriraj Sawant * Pops the balloon notification of the given notification icon.
91*7fbc5f42SShriraj Sawant *
92*7fbc5f42SShriraj Sawant * @param pSysTray
93*7fbc5f42SShriraj Sawant *        Provides interface for acquiring CSysTray information as required.
94*7fbc5f42SShriraj Sawant * @param szTitle
95*7fbc5f42SShriraj Sawant *        Title for the balloon notification.
96*7fbc5f42SShriraj Sawant * @param szInfo
97*7fbc5f42SShriraj Sawant *        Main content for the balloon notification.
98*7fbc5f42SShriraj Sawant * @param uId
99*7fbc5f42SShriraj Sawant *        Represents the particular notification icon.
100*7fbc5f42SShriraj Sawant *
101*7fbc5f42SShriraj Sawant * @return The error code.
102*7fbc5f42SShriraj Sawant *
103*7fbc5f42SShriraj Sawant *--*/
104*7fbc5f42SShriraj Sawant HRESULT NotifyBalloon(CSysTray* pSysTray, LPCWSTR szTitle = NULL, LPCWSTR szInfo = NULL, UINT uId = ID_ICON_HOTPLUG)
105*7fbc5f42SShriraj Sawant {
106*7fbc5f42SShriraj Sawant     NOTIFYICONDATA nim = { 0 };
107*7fbc5f42SShriraj Sawant     nim.cbSize = sizeof(NOTIFYICONDATA);
108*7fbc5f42SShriraj Sawant     nim.uID = uId;
109*7fbc5f42SShriraj Sawant     nim.hWnd = pSysTray->GetHWnd();
110*7fbc5f42SShriraj Sawant 
111*7fbc5f42SShriraj Sawant     nim.uFlags = NIF_INFO;
112*7fbc5f42SShriraj Sawant     nim.uTimeout = 10;
113*7fbc5f42SShriraj Sawant     nim.dwInfoFlags = NIIF_INFO;
114*7fbc5f42SShriraj Sawant 
115*7fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), szTitle);
116*7fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfo, _countof(nim.szInfo), szInfo);
117*7fbc5f42SShriraj Sawant     BOOL ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
118*7fbc5f42SShriraj Sawant 
119*7fbc5f42SShriraj Sawant     Sleep(10000); /* As per windows, the balloon notification remains visible for atleast 10 sec.
120*7fbc5f42SShriraj Sawant                      This timer maintains the same condition.
121*7fbc5f42SShriraj Sawant                      Also it is required so that the icon doesn't hide instantly after last device is removed,
122*7fbc5f42SShriraj Sawant                      as that will prevent popping of notification.
123*7fbc5f42SShriraj Sawant                   */
124*7fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), L"");
125*7fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfo, _countof(nim.szInfo), L"");
126*7fbc5f42SShriraj Sawant     ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
127*7fbc5f42SShriraj Sawant     g_IsRemoving = FALSE; /* This flag is used to prevent instant icon hiding after last device is removed.
128*7fbc5f42SShriraj Sawant                              The above timer maintains the required state for the same.
129*7fbc5f42SShriraj Sawant                           */
130*7fbc5f42SShriraj Sawant     return ret ? S_OK : E_FAIL;
131*7fbc5f42SShriraj Sawant }
132c2c66affSColin Finck 
133c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray)
134c2c66affSColin Finck {
135c2c66affSColin Finck     TRACE("Hotplug_Init\n");
136*7fbc5f42SShriraj Sawant     g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_HOTPLUG_OK));
137c2c66affSColin Finck     g_IsRunning = TRUE;
138*7fbc5f42SShriraj Sawant     EnumHotpluggedDevices(g_devList);
139c2c66affSColin Finck 
140*7fbc5f42SShriraj Sawant     return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN);
141c2c66affSColin Finck }
142c2c66affSColin Finck 
143c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray)
144c2c66affSColin Finck {
145c2c66affSColin Finck     TRACE("Hotplug_Update\n");
146*7fbc5f42SShriraj Sawant 
147*7fbc5f42SShriraj Sawant     if(g_devList.GetSize() || g_IsRemoving)
148*7fbc5f42SShriraj Sawant         return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip);
149*7fbc5f42SShriraj Sawant     else
150*7fbc5f42SShriraj Sawant         return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN);
151c2c66affSColin Finck }
152c2c66affSColin Finck 
153c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray)
154c2c66affSColin Finck {
155c2c66affSColin Finck     TRACE("Hotplug_Shutdown\n");
156c2c66affSColin Finck 
157c2c66affSColin Finck     g_IsRunning = FALSE;
158c2c66affSColin Finck 
159c2c66affSColin Finck     return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL);
160c2c66affSColin Finck }
161c2c66affSColin Finck 
162*7fbc5f42SShriraj Sawant static void _RunHotplug(CSysTray * pSysTray)
163c2c66affSColin Finck {
164*7fbc5f42SShriraj Sawant     ShellExecuteW(pSysTray->GetHWnd(), L"open", L"rundll32.exe shell32.dll,Control_RunDLL hotplug.dll", NULL, NULL, SW_SHOWNORMAL);
165c2c66affSColin Finck }
166c2c66affSColin Finck 
167*7fbc5f42SShriraj Sawant static void _ShowContextMenu(CSysTray * pSysTray)
168c2c66affSColin Finck {
169*7fbc5f42SShriraj Sawant     HMENU hPopup = CreatePopupMenu();
170*7fbc5f42SShriraj Sawant     ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
171c2c66affSColin Finck 
172*7fbc5f42SShriraj Sawant     for (INT index = 0; index < g_devList.GetSize(); index++)
173*7fbc5f42SShriraj Sawant     {
174*7fbc5f42SShriraj Sawant         WCHAR dispName[DISPLAY_NAME_LEN], menuName[DISPLAY_NAME_LEN + 10];
175*7fbc5f42SShriraj Sawant         CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[index], CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0);
176*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
177*7fbc5f42SShriraj Sawant             StrCpyW(dispName, L"Unknown Device");
178c2c66affSColin Finck 
179*7fbc5f42SShriraj Sawant         swprintf(menuName, L"Eject %wS", dispName);
180*7fbc5f42SShriraj Sawant         AppendMenuW(hPopup, MF_STRING, index+1, menuName);
181*7fbc5f42SShriraj Sawant     }
182c2c66affSColin Finck 
183c2c66affSColin Finck     SetForegroundWindow(pSysTray->GetHWnd());
184*7fbc5f42SShriraj Sawant     DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
185*7fbc5f42SShriraj Sawant     POINT pt;
186*7fbc5f42SShriraj Sawant     GetCursorPos(&pt);
187c2c66affSColin Finck 
188*7fbc5f42SShriraj Sawant     DWORD id = TrackPopupMenuEx(hPopup, flags,
189*7fbc5f42SShriraj Sawant         pt.x, pt.y,
190*7fbc5f42SShriraj Sawant         pSysTray->GetHWnd(), NULL);
191c2c66affSColin Finck 
192*7fbc5f42SShriraj Sawant     if (id > 0)
193*7fbc5f42SShriraj Sawant     {
194*7fbc5f42SShriraj Sawant         id--; // since array indices starts from zero.
195*7fbc5f42SShriraj Sawant         CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[id], CM_DRP_DEVICEDESC, NULL, g_strMenuSel, &ulLength, 0);
196*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
197*7fbc5f42SShriraj Sawant             StrCpyW(g_strMenuSel, L"Unknown Device");
198*7fbc5f42SShriraj Sawant 
199*7fbc5f42SShriraj Sawant         cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0);
200*7fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
201*7fbc5f42SShriraj Sawant         {
202*7fbc5f42SShriraj Sawant             WCHAR strInfo[128];
203*7fbc5f42SShriraj Sawant             swprintf(strInfo, L"Problem Ejecting %wS", g_strMenuSel);
204*7fbc5f42SShriraj Sawant             MessageBox(0, L"The device cannot be stopped right now! Try stopping it again later!", strInfo, MB_OKCANCEL | MB_ICONEXCLAMATION);
205*7fbc5f42SShriraj Sawant         }
206*7fbc5f42SShriraj Sawant         else
207*7fbc5f42SShriraj Sawant         {
208*7fbc5f42SShriraj Sawant             //MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OKCANCEL | MB_ICONINFORMATION);
209*7fbc5f42SShriraj Sawant             g_IsRemoving = TRUE;
210*7fbc5f42SShriraj Sawant             g_devList.RemoveAt(id); /* thing is.. even after removing id at this point, the devnode_change occurs after some seconds of sucessful removal
211*7fbc5f42SShriraj Sawant                                        and since pendrive is still plugged in it gets enumerated, if problem number is not filtered.
212*7fbc5f42SShriraj Sawant                                     */
213*7fbc5f42SShriraj Sawant         }
214c2c66affSColin Finck     }
215c2c66affSColin Finck 
216*7fbc5f42SShriraj Sawant     DestroyMenu(hPopup);
217*7fbc5f42SShriraj Sawant }
218c2c66affSColin Finck 
219*7fbc5f42SShriraj Sawant static void _ShowContextMenuR(CSysTray * pSysTray)
220*7fbc5f42SShriraj Sawant {
221*7fbc5f42SShriraj Sawant     CString strMenu((LPWSTR)IDS_HOTPLUG_REMOVE_2);
222c2c66affSColin Finck     HMENU hPopup = CreatePopupMenu();
223*7fbc5f42SShriraj Sawant     AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu);
224c2c66affSColin Finck 
225*7fbc5f42SShriraj Sawant     SetForegroundWindow(pSysTray->GetHWnd());
226*7fbc5f42SShriraj Sawant     DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
227*7fbc5f42SShriraj Sawant     POINT pt;
228*7fbc5f42SShriraj Sawant     GetCursorPos(&pt);
229c2c66affSColin Finck 
230*7fbc5f42SShriraj Sawant     DWORD id = TrackPopupMenuEx(hPopup, flags,
231*7fbc5f42SShriraj Sawant         pt.x, pt.y,
232*7fbc5f42SShriraj Sawant         pSysTray->GetHWnd(), NULL);
233c2c66affSColin Finck 
234*7fbc5f42SShriraj Sawant     if (id == IDS_HOTPLUG_REMOVE_2)
235*7fbc5f42SShriraj Sawant     {
236*7fbc5f42SShriraj Sawant         _RunHotplug(pSysTray);
237*7fbc5f42SShriraj Sawant     }
238c2c66affSColin Finck 
239c2c66affSColin Finck     DestroyMenu(hPopup);
240c2c66affSColin Finck }
241c2c66affSColin Finck 
242c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
243c2c66affSColin Finck {
244*7fbc5f42SShriraj Sawant     HRESULT hr = E_FAIL;
245c2c66affSColin Finck     TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
246c2c66affSColin Finck 
247c2c66affSColin Finck     switch (uMsg)
248c2c66affSColin Finck     {
249*7fbc5f42SShriraj Sawant         /*case WM_CREATE:
250*7fbc5f42SShriraj Sawant             TRACE("Hotplug_Message: WM_CREATE\n");
251*7fbc5f42SShriraj Sawant             DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
252*7fbc5f42SShriraj Sawant 
253*7fbc5f42SShriraj Sawant             ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
254*7fbc5f42SShriraj Sawant             NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
255*7fbc5f42SShriraj Sawant             NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
256*7fbc5f42SShriraj Sawant 
257*7fbc5f42SShriraj Sawant             g_hDevNotify = RegisterDeviceNotification(pSysTray->GetHWnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
258*7fbc5f42SShriraj Sawant             if (g_hDevNotify != NULL)
259*7fbc5f42SShriraj Sawant             {
260*7fbc5f42SShriraj Sawant                 lResult = true;
261*7fbc5f42SShriraj Sawant                 return S_OK;
262*7fbc5f42SShriraj Sawant             }
263*7fbc5f42SShriraj Sawant             return S_FALSE;*/
264*7fbc5f42SShriraj Sawant 
265c2c66affSColin Finck         case WM_USER + 220:
266c2c66affSColin Finck             TRACE("Hotplug_Message: WM_USER+220\n");
267*7fbc5f42SShriraj Sawant             if (wParam == 1)
268c2c66affSColin Finck             {
269c2c66affSColin Finck                 if (lParam == FALSE)
270c2c66affSColin Finck                     return Hotplug_Init(pSysTray);
271c2c66affSColin Finck                 else
272c2c66affSColin Finck                     return Hotplug_Shutdown(pSysTray);
273c2c66affSColin Finck             }
274c2c66affSColin Finck             return S_FALSE;
275c2c66affSColin Finck 
276c2c66affSColin Finck         case WM_USER + 221:
277c2c66affSColin Finck             TRACE("Hotplug_Message: WM_USER+221\n");
278*7fbc5f42SShriraj Sawant             if (wParam == 1)
279c2c66affSColin Finck             {
280c2c66affSColin Finck                 lResult = (LRESULT)g_IsRunning;
281c2c66affSColin Finck                 return S_OK;
282c2c66affSColin Finck             }
283c2c66affSColin Finck             return S_FALSE;
284c2c66affSColin Finck 
285c2c66affSColin Finck         case ID_ICON_HOTPLUG:
286c2c66affSColin Finck             Hotplug_Update(pSysTray);
287c2c66affSColin Finck 
288c2c66affSColin Finck             switch (lParam)
289c2c66affSColin Finck             {
290c2c66affSColin Finck                 case WM_LBUTTONDOWN:
291c2c66affSColin Finck                     break;
292c2c66affSColin Finck 
293c2c66affSColin Finck                 case WM_LBUTTONUP:
294*7fbc5f42SShriraj Sawant                     _ShowContextMenu(pSysTray);
295c2c66affSColin Finck                     break;
296c2c66affSColin Finck 
297c2c66affSColin Finck                 case WM_LBUTTONDBLCLK:
298*7fbc5f42SShriraj Sawant                     _RunHotplug(pSysTray);
299c2c66affSColin Finck                     break;
300c2c66affSColin Finck 
301c2c66affSColin Finck                 case WM_RBUTTONDOWN:
302c2c66affSColin Finck                     break;
303c2c66affSColin Finck 
304c2c66affSColin Finck                 case WM_RBUTTONUP:
305*7fbc5f42SShriraj Sawant                     _ShowContextMenuR(pSysTray);
306c2c66affSColin Finck                     break;
307c2c66affSColin Finck 
308c2c66affSColin Finck                 case WM_RBUTTONDBLCLK:
309c2c66affSColin Finck                     break;
310c2c66affSColin Finck 
311c2c66affSColin Finck                 case WM_MOUSEMOVE:
312c2c66affSColin Finck                     break;
313c2c66affSColin Finck             }
314c2c66affSColin Finck             return S_OK;
315c2c66affSColin Finck 
316*7fbc5f42SShriraj Sawant         case WM_DEVICECHANGE:
317*7fbc5f42SShriraj Sawant             switch (wParam)
318*7fbc5f42SShriraj Sawant             {
319*7fbc5f42SShriraj Sawant                 case DBT_DEVNODES_CHANGED:
320*7fbc5f42SShriraj Sawant                     hr = EnumHotpluggedDevices(g_devList);
321*7fbc5f42SShriraj Sawant                     if (FAILED(hr))
322*7fbc5f42SShriraj Sawant                         return hr;
323*7fbc5f42SShriraj Sawant 
324*7fbc5f42SShriraj Sawant                     lResult = true;
325*7fbc5f42SShriraj Sawant                     break;
326*7fbc5f42SShriraj Sawant                 case DBT_DEVICEARRIVAL:
327*7fbc5f42SShriraj Sawant                     break;
328*7fbc5f42SShriraj Sawant                 case DBT_DEVICEQUERYREMOVE:
329*7fbc5f42SShriraj Sawant                     break;
330*7fbc5f42SShriraj Sawant                 case DBT_DEVICEQUERYREMOVEFAILED:
331*7fbc5f42SShriraj Sawant                     break;
332*7fbc5f42SShriraj Sawant                 case DBT_DEVICEREMOVECOMPLETE:
333*7fbc5f42SShriraj Sawant                     WCHAR strInfo[128];
334*7fbc5f42SShriraj Sawant                     swprintf(strInfo, L"The %wS can now be safely removed from the system.", g_strMenuSel);
335*7fbc5f42SShriraj Sawant                     NotifyBalloon(pSysTray, L"Safe to Remove Hardware", strInfo);
336*7fbc5f42SShriraj Sawant 
337*7fbc5f42SShriraj Sawant                     lResult = true;
338*7fbc5f42SShriraj Sawant                     break;
339*7fbc5f42SShriraj Sawant                 case DBT_DEVICEREMOVEPENDING:
340*7fbc5f42SShriraj Sawant                     break;
341*7fbc5f42SShriraj Sawant             }
342*7fbc5f42SShriraj Sawant             return S_OK;
343*7fbc5f42SShriraj Sawant 
344*7fbc5f42SShriraj Sawant         /*case WM_CLOSE:
345*7fbc5f42SShriraj Sawant             if (!UnregisterDeviceNotification(hDeviceNotify))
346*7fbc5f42SShriraj Sawant             {
347*7fbc5f42SShriraj Sawant                 return S_FALSE;
348*7fbc5f42SShriraj Sawant             }
349*7fbc5f42SShriraj Sawant             return S_OK;*/
350*7fbc5f42SShriraj Sawant 
351c2c66affSColin Finck         default:
352c2c66affSColin Finck             TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
353c2c66affSColin Finck             return S_FALSE;
354c2c66affSColin Finck     }
355c2c66affSColin Finck 
356c2c66affSColin Finck     return S_FALSE;
357c2c66affSColin Finck }
358