xref: /reactos/dll/shellext/stobject/hotplug.cpp (revision 9393fc32)
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
57fbc5f42SShriraj Sawant  * PURPOSE:     Removable devices notification icon handler
67fbc5f42SShriraj Sawant  * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
7c2c66affSColin Finck  */
8e15874b4SAmine Khaldi 
9c2c66affSColin Finck #include "precomp.h"
10e15874b4SAmine Khaldi 
117fbc5f42SShriraj Sawant #include <atlsimpcoll.h>
127fbc5f42SShriraj Sawant #include <dbt.h>
137fbc5f42SShriraj Sawant #include <cfgmgr32.h>
14e15874b4SAmine Khaldi #include <shlwapi.h>
15c2c66affSColin Finck 
167fbc5f42SShriraj Sawant #define DISPLAY_NAME_LEN 40
17c2c66affSColin Finck 
187fbc5f42SShriraj Sawant CSimpleArray<DEVINST> g_devList;
1901fd69dfSEric Kohl CString g_strHotplugTooltip;
20c2c66affSColin Finck static HICON g_hIconHotplug = NULL;
217fbc5f42SShriraj Sawant static WCHAR g_strMenuSel[DISPLAY_NAME_LEN];
227fbc5f42SShriraj Sawant static BOOL g_IsRemoving = FALSE;
23c2c66affSColin Finck 
247fbc5f42SShriraj Sawant /*++
257fbc5f42SShriraj Sawant * @name EnumHotpluggedDevices
267fbc5f42SShriraj Sawant *
277fbc5f42SShriraj Sawant * Enumerates the connected safely removable devices.
287fbc5f42SShriraj Sawant *
297fbc5f42SShriraj Sawant * @param devList
307fbc5f42SShriraj Sawant *        List of device instances, representing the currently attached devices.
317fbc5f42SShriraj Sawant *
327fbc5f42SShriraj Sawant * @return The error code.
337fbc5f42SShriraj Sawant *
347fbc5f42SShriraj Sawant *--*/
EnumHotpluggedDevices(CSimpleArray<DEVINST> & devList)357fbc5f42SShriraj Sawant HRESULT EnumHotpluggedDevices(CSimpleArray<DEVINST> &devList)
367fbc5f42SShriraj Sawant {
377fbc5f42SShriraj Sawant     devList.RemoveAll(); // Clear current devList
387fbc5f42SShriraj Sawant     HDEVINFO hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
397fbc5f42SShriraj Sawant     if (INVALID_HANDLE_VALUE == hdev)
407fbc5f42SShriraj Sawant         return E_HANDLE;
417fbc5f42SShriraj Sawant     SP_DEVINFO_DATA did = { 0 };
427fbc5f42SShriraj Sawant     did.cbSize = sizeof(did);
437fbc5f42SShriraj Sawant 
447fbc5f42SShriraj Sawant     // Enumerate all the attached devices.
457fbc5f42SShriraj Sawant     for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++)
467fbc5f42SShriraj Sawant     {
477fbc5f42SShriraj Sawant         DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities);
4801fd69dfSEric Kohl         ULONG ulStatus = 0, ulProblem = 0;
4901fd69dfSEric Kohl         CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulProblem, did.DevInst, 0);
507fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
517fbc5f42SShriraj Sawant             continue;
5201fd69dfSEric Kohl 
537fbc5f42SShriraj Sawant         cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_CAPABILITIES, NULL, &dwCapabilities, &dwSize, 0);
547fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
557fbc5f42SShriraj Sawant             continue;
567fbc5f42SShriraj Sawant 
577fbc5f42SShriraj Sawant         // Filter and make list of only the appropriate safely removable devices.
587fbc5f42SShriraj Sawant         if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) &&
597fbc5f42SShriraj Sawant             !(dwCapabilities & CM_DEVCAP_DOCKDEVICE) &&
607fbc5f42SShriraj Sawant             !(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) &&
617fbc5f42SShriraj Sawant             ((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
6201fd69dfSEric Kohl             !ulProblem)
637fbc5f42SShriraj Sawant         {
647fbc5f42SShriraj Sawant             devList.Add(did.DevInst);
657fbc5f42SShriraj Sawant         }
667fbc5f42SShriraj Sawant     }
677fbc5f42SShriraj Sawant     SetupDiDestroyDeviceInfoList(hdev);
687fbc5f42SShriraj Sawant 
697fbc5f42SShriraj Sawant     if (NO_ERROR != GetLastError() && ERROR_NO_MORE_ITEMS != GetLastError())
707fbc5f42SShriraj Sawant     {
717fbc5f42SShriraj Sawant         return E_UNEXPECTED;
727fbc5f42SShriraj Sawant     }
737fbc5f42SShriraj Sawant 
747fbc5f42SShriraj Sawant     return S_OK;
757fbc5f42SShriraj Sawant }
767fbc5f42SShriraj Sawant 
777fbc5f42SShriraj Sawant /*++
787fbc5f42SShriraj Sawant * @name NotifyBalloon
797fbc5f42SShriraj Sawant *
807fbc5f42SShriraj Sawant * Pops the balloon notification of the given notification icon.
817fbc5f42SShriraj Sawant *
827fbc5f42SShriraj Sawant * @param pSysTray
837fbc5f42SShriraj Sawant *        Provides interface for acquiring CSysTray information as required.
847fbc5f42SShriraj Sawant * @param szTitle
857fbc5f42SShriraj Sawant *        Title for the balloon notification.
867fbc5f42SShriraj Sawant * @param szInfo
877fbc5f42SShriraj Sawant *        Main content for the balloon notification.
887fbc5f42SShriraj Sawant * @param uId
897fbc5f42SShriraj Sawant *        Represents the particular notification icon.
907fbc5f42SShriraj Sawant *
917fbc5f42SShriraj Sawant * @return The error code.
927fbc5f42SShriraj Sawant *
937fbc5f42SShriraj Sawant *--*/
NotifyBalloon(CSysTray * pSysTray,LPCWSTR szTitle=NULL,LPCWSTR szInfo=NULL,UINT uId=ID_ICON_HOTPLUG)947fbc5f42SShriraj Sawant HRESULT NotifyBalloon(CSysTray* pSysTray, LPCWSTR szTitle = NULL, LPCWSTR szInfo = NULL, UINT uId = ID_ICON_HOTPLUG)
957fbc5f42SShriraj Sawant {
965de33ab0SHermès Bélusca-Maïto     NOTIFYICONDATA nim = { 0 };
9742073979SHermès Bélusca-Maïto 
9842073979SHermès Bélusca-Maïto     nim.cbSize = sizeof(nim);
997fbc5f42SShriraj Sawant     nim.uID = uId;
1007fbc5f42SShriraj Sawant     nim.hWnd = pSysTray->GetHWnd();
1017fbc5f42SShriraj Sawant 
1027fbc5f42SShriraj Sawant     nim.uFlags = NIF_INFO;
1037fbc5f42SShriraj Sawant     nim.uTimeout = 10;
1047fbc5f42SShriraj Sawant     nim.dwInfoFlags = NIIF_INFO;
1057fbc5f42SShriraj Sawant 
1067fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), szTitle);
1077fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfo, _countof(nim.szInfo), szInfo);
1087fbc5f42SShriraj Sawant     BOOL ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
1097fbc5f42SShriraj Sawant 
1107fbc5f42SShriraj Sawant     Sleep(10000); /* As per windows, the balloon notification remains visible for atleast 10 sec.
1117fbc5f42SShriraj Sawant                      This timer maintains the same condition.
1127fbc5f42SShriraj Sawant                      Also it is required so that the icon doesn't hide instantly after last device is removed,
1137fbc5f42SShriraj Sawant                      as that will prevent popping of notification.
1147fbc5f42SShriraj Sawant                   */
1157fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), L"");
1167fbc5f42SShriraj Sawant     StringCchCopy(nim.szInfo, _countof(nim.szInfo), L"");
1177fbc5f42SShriraj Sawant     ret = Shell_NotifyIcon(NIM_MODIFY, &nim);
1187fbc5f42SShriraj Sawant     g_IsRemoving = FALSE; /* This flag is used to prevent instant icon hiding after last device is removed.
1197fbc5f42SShriraj Sawant                              The above timer maintains the required state for the same.
1207fbc5f42SShriraj Sawant                           */
1217fbc5f42SShriraj Sawant     return ret ? S_OK : E_FAIL;
1227fbc5f42SShriraj Sawant }
123c2c66affSColin Finck 
Hotplug_Init(_In_ CSysTray * pSysTray)124c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray)
125c2c66affSColin Finck {
126c2c66affSColin Finck     TRACE("Hotplug_Init\n");
127fc999e18SEric Kohl 
1287fbc5f42SShriraj Sawant     g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_HOTPLUG_OK));
12901fd69dfSEric Kohl     g_strHotplugTooltip.LoadStringW(IDS_HOTPLUG_REMOVE_1);
130fc999e18SEric Kohl 
1317fbc5f42SShriraj Sawant     EnumHotpluggedDevices(g_devList);
132c2c66affSColin Finck 
133fc999e18SEric Kohl     if (g_devList.GetSize() > 0)
13401fd69dfSEric Kohl         return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip);
135fc999e18SEric Kohl     else
13601fd69dfSEric Kohl         return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip, NIS_HIDDEN);
137c2c66affSColin Finck }
138c2c66affSColin Finck 
Hotplug_Update(_In_ CSysTray * pSysTray)139c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray)
140c2c66affSColin Finck {
141c2c66affSColin Finck     TRACE("Hotplug_Update\n");
142fc999e18SEric Kohl     return S_OK;
143c2c66affSColin Finck }
144c2c66affSColin Finck 
Hotplug_Shutdown(_In_ CSysTray * pSysTray)145c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray)
146c2c66affSColin Finck {
147c2c66affSColin Finck     TRACE("Hotplug_Shutdown\n");
148c2c66affSColin Finck 
149fc999e18SEric Kohl     DestroyIcon(g_hIconHotplug);
150fc999e18SEric Kohl     g_hIconHotplug = NULL;
151fc999e18SEric Kohl 
152c2c66affSColin Finck     return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL);
153c2c66affSColin Finck }
154c2c66affSColin Finck 
_RunHotplug(CSysTray * pSysTray)1557fbc5f42SShriraj Sawant static void _RunHotplug(CSysTray * pSysTray)
156c2c66affSColin Finck {
157cb77f170SSerge Gautherie     ShellExecuteW(pSysTray->GetHWnd(),
158cb77f170SSerge Gautherie                   L"open",
159cb77f170SSerge Gautherie                   L"rundll32.exe",
160cb77f170SSerge Gautherie                   L"shell32.dll,Control_RunDLL hotplug.dll",
161cb77f170SSerge Gautherie                   NULL,
162cb77f170SSerge Gautherie                   SW_SHOWNORMAL);
163c2c66affSColin Finck }
164c2c66affSColin Finck 
_ShowContextMenu(CSysTray * pSysTray)1657fbc5f42SShriraj Sawant static void _ShowContextMenu(CSysTray * pSysTray)
166c2c66affSColin Finck {
1677fbc5f42SShriraj Sawant     HMENU hPopup = CreatePopupMenu();
1687fbc5f42SShriraj Sawant     ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR);
169c2c66affSColin Finck 
1707fbc5f42SShriraj Sawant     for (INT index = 0; index < g_devList.GetSize(); index++)
1717fbc5f42SShriraj Sawant     {
17201fd69dfSEric Kohl         WCHAR dispName[DISPLAY_NAME_LEN];
17301fd69dfSEric Kohl         CString menuName;
1747fbc5f42SShriraj Sawant         CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[index], CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0);
1757fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
1767fbc5f42SShriraj Sawant             StrCpyW(dispName, L"Unknown Device");
177c2c66affSColin Finck 
17801fd69dfSEric Kohl         menuName.Format(IDS_HOTPLUG_REMOVE_3, dispName);
1797fbc5f42SShriraj Sawant         AppendMenuW(hPopup, MF_STRING, index+1, menuName);
1807fbc5f42SShriraj Sawant     }
181c2c66affSColin Finck 
182c2c66affSColin Finck     SetForegroundWindow(pSysTray->GetHWnd());
1837fbc5f42SShriraj Sawant     DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
1847fbc5f42SShriraj Sawant     POINT pt;
1857fbc5f42SShriraj Sawant     GetCursorPos(&pt);
186c2c66affSColin Finck 
1877fbc5f42SShriraj Sawant     DWORD id = TrackPopupMenuEx(hPopup, flags,
1887fbc5f42SShriraj Sawant         pt.x, pt.y,
1897fbc5f42SShriraj Sawant         pSysTray->GetHWnd(), NULL);
190c2c66affSColin Finck 
1917fbc5f42SShriraj Sawant     if (id > 0)
1927fbc5f42SShriraj Sawant     {
1937fbc5f42SShriraj Sawant         id--; // since array indices starts from zero.
1947fbc5f42SShriraj Sawant         CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[id], CM_DRP_DEVICEDESC, NULL, g_strMenuSel, &ulLength, 0);
1957fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
1967fbc5f42SShriraj Sawant             StrCpyW(g_strMenuSel, L"Unknown Device");
1977fbc5f42SShriraj Sawant 
1987fbc5f42SShriraj Sawant         cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0);
1997fbc5f42SShriraj Sawant         if (cr != CR_SUCCESS)
2007fbc5f42SShriraj Sawant         {
2017fbc5f42SShriraj Sawant             WCHAR strInfo[128];
2027fbc5f42SShriraj Sawant             swprintf(strInfo, L"Problem Ejecting %wS", g_strMenuSel);
203*a5a725aeSJared Smudde             MessageBox(0, L"The device cannot be stopped right now! Try stopping it again later!", strInfo, MB_OK | MB_ICONEXCLAMATION);
2047fbc5f42SShriraj Sawant         }
2057fbc5f42SShriraj Sawant         else
2067fbc5f42SShriraj Sawant         {
207*a5a725aeSJared Smudde             //MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OK | MB_ICONINFORMATION);
2087fbc5f42SShriraj Sawant             g_IsRemoving = TRUE;
2097fbc5f42SShriraj Sawant             g_devList.RemoveAt(id); /* thing is.. even after removing id at this point, the devnode_change occurs after some seconds of sucessful removal
2107fbc5f42SShriraj Sawant                                        and since pendrive is still plugged in it gets enumerated, if problem number is not filtered.
2117fbc5f42SShriraj Sawant                                     */
2127fbc5f42SShriraj Sawant         }
213c2c66affSColin Finck     }
214c2c66affSColin Finck 
2157fbc5f42SShriraj Sawant     DestroyMenu(hPopup);
2167fbc5f42SShriraj Sawant }
217c2c66affSColin Finck 
_ShowContextMenuR(CSysTray * pSysTray)2187fbc5f42SShriraj Sawant static void _ShowContextMenuR(CSysTray * pSysTray)
2197fbc5f42SShriraj Sawant {
2207fbc5f42SShriraj Sawant     CString strMenu((LPWSTR)IDS_HOTPLUG_REMOVE_2);
221c2c66affSColin Finck     HMENU hPopup = CreatePopupMenu();
2227fbc5f42SShriraj Sawant     AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu);
223754a35b2SEric Kohl     SetMenuDefaultItem(hPopup, IDS_HOTPLUG_REMOVE_2, FALSE);
224c2c66affSColin Finck 
2257fbc5f42SShriraj Sawant     SetForegroundWindow(pSysTray->GetHWnd());
2267fbc5f42SShriraj Sawant     DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
2277fbc5f42SShriraj Sawant     POINT pt;
2287fbc5f42SShriraj Sawant     GetCursorPos(&pt);
229c2c66affSColin Finck 
2307fbc5f42SShriraj Sawant     DWORD id = TrackPopupMenuEx(hPopup, flags,
2317fbc5f42SShriraj Sawant         pt.x, pt.y,
2327fbc5f42SShriraj Sawant         pSysTray->GetHWnd(), NULL);
233c2c66affSColin Finck 
2347fbc5f42SShriraj Sawant     if (id == IDS_HOTPLUG_REMOVE_2)
2357fbc5f42SShriraj Sawant     {
2367fbc5f42SShriraj Sawant         _RunHotplug(pSysTray);
2377fbc5f42SShriraj Sawant     }
238c2c66affSColin Finck 
239c2c66affSColin Finck     DestroyMenu(hPopup);
240c2c66affSColin Finck }
241c2c66affSColin Finck 
242fc999e18SEric Kohl 
243fc999e18SEric Kohl VOID
HotplugDeviceTimer(_In_ CSysTray * pSysTray)244fc999e18SEric Kohl HotplugDeviceTimer(
245fc999e18SEric Kohl     _In_ CSysTray *pSysTray)
246fc999e18SEric Kohl {
247fc999e18SEric Kohl     TRACE("HotplugDeviceTimer()\n");
248fc999e18SEric Kohl 
249fc999e18SEric Kohl     EnumHotpluggedDevices(g_devList);
250fc999e18SEric Kohl 
251fc999e18SEric Kohl     if (g_devList.GetSize() > 0)
25201fd69dfSEric Kohl         pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip);
253fc999e18SEric Kohl     else
25401fd69dfSEric Kohl         pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strHotplugTooltip, NIS_HIDDEN);
255fc999e18SEric Kohl }
256fc999e18SEric Kohl 
257fc999e18SEric Kohl 
Hotplug_Message(_In_ CSysTray * pSysTray,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT & lResult)258c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
259c2c66affSColin Finck {
260c2c66affSColin Finck     TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
261c2c66affSColin Finck 
262c2c66affSColin Finck     switch (uMsg)
263c2c66affSColin Finck     {
264c2c66affSColin Finck         case WM_USER + 220:
265c2c66affSColin Finck             TRACE("Hotplug_Message: WM_USER+220\n");
2668c30fdabSEric Kohl             if (wParam == HOTPLUG_SERVICE_FLAG)
267c2c66affSColin Finck             {
2688c30fdabSEric Kohl                 if (lParam)
2698c30fdabSEric Kohl                 {
2708c30fdabSEric Kohl                     pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, TRUE);
271c2c66affSColin Finck                     return Hotplug_Init(pSysTray);
2728c30fdabSEric Kohl                 }
273c2c66affSColin Finck                 else
2748c30fdabSEric Kohl                 {
2758c30fdabSEric Kohl                     pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, FALSE);
276c2c66affSColin Finck                     return Hotplug_Shutdown(pSysTray);
277c2c66affSColin Finck                 }
2788c30fdabSEric Kohl             }
279c2c66affSColin Finck             return S_FALSE;
280c2c66affSColin Finck 
281c2c66affSColin Finck         case WM_USER + 221:
282c2c66affSColin Finck             TRACE("Hotplug_Message: WM_USER+221\n");
2838c30fdabSEric Kohl             if (wParam == HOTPLUG_SERVICE_FLAG)
284c2c66affSColin Finck             {
2858c30fdabSEric Kohl                 lResult = (LRESULT)pSysTray->IsServiceEnabled(HOTPLUG_SERVICE_FLAG);
286c2c66affSColin Finck                 return S_OK;
287c2c66affSColin Finck             }
288c2c66affSColin Finck             return S_FALSE;
289c2c66affSColin Finck 
2902baafa61SEric Kohl         case WM_TIMER:
2912baafa61SEric Kohl             if (wParam == HOTPLUG_TIMER_ID)
2922baafa61SEric Kohl             {
2932baafa61SEric Kohl                 KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID);
2942baafa61SEric Kohl                 _ShowContextMenu(pSysTray);
2952baafa61SEric Kohl             }
296fc999e18SEric Kohl             else if (wParam == HOTPLUG_DEVICE_TIMER_ID)
297fc999e18SEric Kohl             {
298fc999e18SEric Kohl                 KillTimer(pSysTray->GetHWnd(), HOTPLUG_DEVICE_TIMER_ID);
299fc999e18SEric Kohl                 HotplugDeviceTimer(pSysTray);
300fc999e18SEric Kohl             }
3012baafa61SEric Kohl             break;
3022baafa61SEric Kohl 
303c2c66affSColin Finck         case ID_ICON_HOTPLUG:
304c2c66affSColin Finck             switch (lParam)
305c2c66affSColin Finck             {
306c2c66affSColin Finck                 case WM_LBUTTONDOWN:
307282b4397SEric Kohl                     SetTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID, GetDoubleClickTime(), NULL);
308c2c66affSColin Finck                     break;
309c2c66affSColin Finck 
310c2c66affSColin Finck                 case WM_LBUTTONUP:
311c2c66affSColin Finck                     break;
312c2c66affSColin Finck 
313c2c66affSColin Finck                 case WM_LBUTTONDBLCLK:
3142baafa61SEric Kohl                     KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID);
3157fbc5f42SShriraj Sawant                     _RunHotplug(pSysTray);
316c2c66affSColin Finck                     break;
317c2c66affSColin Finck 
318c2c66affSColin Finck                 case WM_RBUTTONDOWN:
319c2c66affSColin Finck                     break;
320c2c66affSColin Finck 
321c2c66affSColin Finck                 case WM_RBUTTONUP:
3227fbc5f42SShriraj Sawant                     _ShowContextMenuR(pSysTray);
323c2c66affSColin Finck                     break;
324c2c66affSColin Finck 
325c2c66affSColin Finck                 case WM_RBUTTONDBLCLK:
326c2c66affSColin Finck                     break;
327c2c66affSColin Finck 
328c2c66affSColin Finck                 case WM_MOUSEMOVE:
329c2c66affSColin Finck                     break;
330c2c66affSColin Finck             }
331c2c66affSColin Finck             return S_OK;
332c2c66affSColin Finck 
3337fbc5f42SShriraj Sawant         case WM_DEVICECHANGE:
3347fbc5f42SShriraj Sawant             switch (wParam)
3357fbc5f42SShriraj Sawant             {
3367fbc5f42SShriraj Sawant                 case DBT_DEVNODES_CHANGED:
337fc999e18SEric Kohl                     TRACE("WM_DEVICECHANGE : DBT_DEVNODES_CHANGED\n");
338fc999e18SEric Kohl                     SetTimer(pSysTray->GetHWnd(), HOTPLUG_DEVICE_TIMER_ID, 100, NULL);
3397fbc5f42SShriraj Sawant                     lResult = true;
3407fbc5f42SShriraj Sawant                     break;
341fc999e18SEric Kohl 
3427fbc5f42SShriraj Sawant                 case DBT_DEVICEARRIVAL:
3437fbc5f42SShriraj Sawant                     break;
3447fbc5f42SShriraj Sawant                 case DBT_DEVICEQUERYREMOVE:
3457fbc5f42SShriraj Sawant                     break;
3467fbc5f42SShriraj Sawant                 case DBT_DEVICEQUERYREMOVEFAILED:
3477fbc5f42SShriraj Sawant                     break;
3487fbc5f42SShriraj Sawant                 case DBT_DEVICEREMOVECOMPLETE:
3497fbc5f42SShriraj Sawant                     WCHAR strInfo[128];
3507fbc5f42SShriraj Sawant                     swprintf(strInfo, L"The %wS can now be safely removed from the system.", g_strMenuSel);
3517fbc5f42SShriraj Sawant                     NotifyBalloon(pSysTray, L"Safe to Remove Hardware", strInfo);
3527fbc5f42SShriraj Sawant 
3537fbc5f42SShriraj Sawant                     lResult = true;
3547fbc5f42SShriraj Sawant                     break;
3557fbc5f42SShriraj Sawant                 case DBT_DEVICEREMOVEPENDING:
3567fbc5f42SShriraj Sawant                     break;
3577fbc5f42SShriraj Sawant             }
3587fbc5f42SShriraj Sawant             return S_OK;
3597fbc5f42SShriraj Sawant 
360c2c66affSColin Finck         default:
361c2c66affSColin Finck             TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
362c2c66affSColin Finck             return S_FALSE;
363c2c66affSColin Finck     }
364c2c66affSColin Finck 
365c2c66affSColin Finck     return S_FALSE;
366c2c66affSColin Finck }
367