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 //BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle); 197fbc5f42SShriraj Sawant 207fbc5f42SShriraj Sawant CSimpleArray<DEVINST> g_devList; 217fbc5f42SShriraj Sawant /*static HDEVNOTIFY g_hDevNotify = NULL;*/ 22c2c66affSColin Finck static HICON g_hIconHotplug = NULL; 237fbc5f42SShriraj Sawant static LPCWSTR g_strTooltip = L"Safely Remove Hardware and Eject Media"; 247fbc5f42SShriraj Sawant static WCHAR g_strMenuSel[DISPLAY_NAME_LEN]; 257fbc5f42SShriraj Sawant static BOOL g_IsRemoving = FALSE; 26c2c66affSColin Finck 277fbc5f42SShriraj Sawant /*++ 287fbc5f42SShriraj Sawant * @name EnumHotpluggedDevices 297fbc5f42SShriraj Sawant * 307fbc5f42SShriraj Sawant * Enumerates the connected safely removable devices. 317fbc5f42SShriraj Sawant * 327fbc5f42SShriraj Sawant * @param devList 337fbc5f42SShriraj Sawant * List of device instances, representing the currently attached devices. 347fbc5f42SShriraj Sawant * 357fbc5f42SShriraj Sawant * @return The error code. 367fbc5f42SShriraj Sawant * 377fbc5f42SShriraj Sawant *--*/ 387fbc5f42SShriraj Sawant HRESULT EnumHotpluggedDevices(CSimpleArray<DEVINST> &devList) 397fbc5f42SShriraj Sawant { 407fbc5f42SShriraj Sawant devList.RemoveAll(); // Clear current devList 417fbc5f42SShriraj Sawant HDEVINFO hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT); 427fbc5f42SShriraj Sawant if (INVALID_HANDLE_VALUE == hdev) 437fbc5f42SShriraj Sawant return E_HANDLE; 447fbc5f42SShriraj Sawant SP_DEVINFO_DATA did = { 0 }; 457fbc5f42SShriraj Sawant did.cbSize = sizeof(did); 467fbc5f42SShriraj Sawant 477fbc5f42SShriraj Sawant // Enumerate all the attached devices. 487fbc5f42SShriraj Sawant for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++) 497fbc5f42SShriraj Sawant { 507fbc5f42SShriraj Sawant DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities); 517fbc5f42SShriraj Sawant WCHAR dispName[DISPLAY_NAME_LEN]; 527fbc5f42SShriraj Sawant ULONG ulStatus = 0, ulPnum = 0, ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR); 537fbc5f42SShriraj Sawant CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulPnum, did.DevInst, 0); 547fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 557fbc5f42SShriraj Sawant continue; 567fbc5f42SShriraj Sawant cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0); 577fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 587fbc5f42SShriraj Sawant continue; 597fbc5f42SShriraj Sawant cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_CAPABILITIES, NULL, &dwCapabilities, &dwSize, 0); 607fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 617fbc5f42SShriraj Sawant continue; 627fbc5f42SShriraj Sawant 637fbc5f42SShriraj Sawant // Filter and make list of only the appropriate safely removable devices. 647fbc5f42SShriraj Sawant if ( (dwCapabilities & CM_DEVCAP_REMOVABLE) && 657fbc5f42SShriraj Sawant !(dwCapabilities & CM_DEVCAP_DOCKDEVICE) && 667fbc5f42SShriraj Sawant !(dwCapabilities & CM_DEVCAP_SURPRISEREMOVALOK) && 677fbc5f42SShriraj Sawant ((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) && 687fbc5f42SShriraj Sawant !ulPnum) 697fbc5f42SShriraj Sawant { 707fbc5f42SShriraj Sawant devList.Add(did.DevInst); 717fbc5f42SShriraj Sawant } 727fbc5f42SShriraj Sawant } 737fbc5f42SShriraj Sawant SetupDiDestroyDeviceInfoList(hdev); 747fbc5f42SShriraj Sawant 757fbc5f42SShriraj Sawant if (NO_ERROR != GetLastError() && ERROR_NO_MORE_ITEMS != GetLastError()) 767fbc5f42SShriraj Sawant { 777fbc5f42SShriraj Sawant return E_UNEXPECTED; 787fbc5f42SShriraj Sawant } 797fbc5f42SShriraj Sawant 807fbc5f42SShriraj Sawant return S_OK; 817fbc5f42SShriraj Sawant } 827fbc5f42SShriraj Sawant 837fbc5f42SShriraj Sawant /*++ 847fbc5f42SShriraj Sawant * @name NotifyBalloon 857fbc5f42SShriraj Sawant * 867fbc5f42SShriraj Sawant * Pops the balloon notification of the given notification icon. 877fbc5f42SShriraj Sawant * 887fbc5f42SShriraj Sawant * @param pSysTray 897fbc5f42SShriraj Sawant * Provides interface for acquiring CSysTray information as required. 907fbc5f42SShriraj Sawant * @param szTitle 917fbc5f42SShriraj Sawant * Title for the balloon notification. 927fbc5f42SShriraj Sawant * @param szInfo 937fbc5f42SShriraj Sawant * Main content for the balloon notification. 947fbc5f42SShriraj Sawant * @param uId 957fbc5f42SShriraj Sawant * Represents the particular notification icon. 967fbc5f42SShriraj Sawant * 977fbc5f42SShriraj Sawant * @return The error code. 987fbc5f42SShriraj Sawant * 997fbc5f42SShriraj Sawant *--*/ 1007fbc5f42SShriraj Sawant HRESULT NotifyBalloon(CSysTray* pSysTray, LPCWSTR szTitle = NULL, LPCWSTR szInfo = NULL, UINT uId = ID_ICON_HOTPLUG) 1017fbc5f42SShriraj Sawant { 1025de33ab0SHermès Bélusca-Maïto NOTIFYICONDATA nim = { 0 }; 10342073979SHermès Bélusca-Maïto 10442073979SHermès Bélusca-Maïto nim.cbSize = sizeof(nim); 1057fbc5f42SShriraj Sawant nim.uID = uId; 1067fbc5f42SShriraj Sawant nim.hWnd = pSysTray->GetHWnd(); 1077fbc5f42SShriraj Sawant 1087fbc5f42SShriraj Sawant nim.uFlags = NIF_INFO; 1097fbc5f42SShriraj Sawant nim.uTimeout = 10; 1107fbc5f42SShriraj Sawant nim.dwInfoFlags = NIIF_INFO; 1117fbc5f42SShriraj Sawant 1127fbc5f42SShriraj Sawant StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), szTitle); 1137fbc5f42SShriraj Sawant StringCchCopy(nim.szInfo, _countof(nim.szInfo), szInfo); 1147fbc5f42SShriraj Sawant BOOL ret = Shell_NotifyIcon(NIM_MODIFY, &nim); 1157fbc5f42SShriraj Sawant 1167fbc5f42SShriraj Sawant Sleep(10000); /* As per windows, the balloon notification remains visible for atleast 10 sec. 1177fbc5f42SShriraj Sawant This timer maintains the same condition. 1187fbc5f42SShriraj Sawant Also it is required so that the icon doesn't hide instantly after last device is removed, 1197fbc5f42SShriraj Sawant as that will prevent popping of notification. 1207fbc5f42SShriraj Sawant */ 1217fbc5f42SShriraj Sawant StringCchCopy(nim.szInfoTitle, _countof(nim.szInfoTitle), L""); 1227fbc5f42SShriraj Sawant StringCchCopy(nim.szInfo, _countof(nim.szInfo), L""); 1237fbc5f42SShriraj Sawant ret = Shell_NotifyIcon(NIM_MODIFY, &nim); 1247fbc5f42SShriraj Sawant g_IsRemoving = FALSE; /* This flag is used to prevent instant icon hiding after last device is removed. 1257fbc5f42SShriraj Sawant The above timer maintains the required state for the same. 1267fbc5f42SShriraj Sawant */ 1277fbc5f42SShriraj Sawant return ret ? S_OK : E_FAIL; 1287fbc5f42SShriraj Sawant } 129c2c66affSColin Finck 130c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray) 131c2c66affSColin Finck { 132c2c66affSColin Finck TRACE("Hotplug_Init\n"); 1337fbc5f42SShriraj Sawant g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_HOTPLUG_OK)); 1347fbc5f42SShriraj Sawant EnumHotpluggedDevices(g_devList); 135c2c66affSColin Finck 1367fbc5f42SShriraj Sawant return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN); 137c2c66affSColin Finck } 138c2c66affSColin Finck 139c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray) 140c2c66affSColin Finck { 141c2c66affSColin Finck TRACE("Hotplug_Update\n"); 1427fbc5f42SShriraj Sawant 1437fbc5f42SShriraj Sawant if(g_devList.GetSize() || g_IsRemoving) 1447fbc5f42SShriraj Sawant return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip); 1457fbc5f42SShriraj Sawant else 1467fbc5f42SShriraj Sawant return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN); 147c2c66affSColin Finck } 148c2c66affSColin Finck 149c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray) 150c2c66affSColin Finck { 151c2c66affSColin Finck TRACE("Hotplug_Shutdown\n"); 152c2c66affSColin Finck 153c2c66affSColin Finck return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL); 154c2c66affSColin Finck } 155c2c66affSColin Finck 1567fbc5f42SShriraj Sawant static void _RunHotplug(CSysTray * pSysTray) 157c2c66affSColin Finck { 1587fbc5f42SShriraj Sawant ShellExecuteW(pSysTray->GetHWnd(), L"open", L"rundll32.exe shell32.dll,Control_RunDLL hotplug.dll", NULL, NULL, SW_SHOWNORMAL); 159c2c66affSColin Finck } 160c2c66affSColin Finck 1617fbc5f42SShriraj Sawant static void _ShowContextMenu(CSysTray * pSysTray) 162c2c66affSColin Finck { 1637fbc5f42SShriraj Sawant HMENU hPopup = CreatePopupMenu(); 1647fbc5f42SShriraj Sawant ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR); 165c2c66affSColin Finck 1667fbc5f42SShriraj Sawant for (INT index = 0; index < g_devList.GetSize(); index++) 1677fbc5f42SShriraj Sawant { 1687fbc5f42SShriraj Sawant WCHAR dispName[DISPLAY_NAME_LEN], menuName[DISPLAY_NAME_LEN + 10]; 1697fbc5f42SShriraj Sawant CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[index], CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0); 1707fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 1717fbc5f42SShriraj Sawant StrCpyW(dispName, L"Unknown Device"); 172c2c66affSColin Finck 1737fbc5f42SShriraj Sawant swprintf(menuName, L"Eject %wS", dispName); 1747fbc5f42SShriraj Sawant AppendMenuW(hPopup, MF_STRING, index+1, menuName); 1757fbc5f42SShriraj Sawant } 176c2c66affSColin Finck 177c2c66affSColin Finck SetForegroundWindow(pSysTray->GetHWnd()); 1787fbc5f42SShriraj Sawant DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; 1797fbc5f42SShriraj Sawant POINT pt; 1807fbc5f42SShriraj Sawant GetCursorPos(&pt); 181c2c66affSColin Finck 1827fbc5f42SShriraj Sawant DWORD id = TrackPopupMenuEx(hPopup, flags, 1837fbc5f42SShriraj Sawant pt.x, pt.y, 1847fbc5f42SShriraj Sawant pSysTray->GetHWnd(), NULL); 185c2c66affSColin Finck 1867fbc5f42SShriraj Sawant if (id > 0) 1877fbc5f42SShriraj Sawant { 1887fbc5f42SShriraj Sawant id--; // since array indices starts from zero. 1897fbc5f42SShriraj Sawant CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[id], CM_DRP_DEVICEDESC, NULL, g_strMenuSel, &ulLength, 0); 1907fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 1917fbc5f42SShriraj Sawant StrCpyW(g_strMenuSel, L"Unknown Device"); 1927fbc5f42SShriraj Sawant 1937fbc5f42SShriraj Sawant cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0); 1947fbc5f42SShriraj Sawant if (cr != CR_SUCCESS) 1957fbc5f42SShriraj Sawant { 1967fbc5f42SShriraj Sawant WCHAR strInfo[128]; 1977fbc5f42SShriraj Sawant swprintf(strInfo, L"Problem Ejecting %wS", g_strMenuSel); 1987fbc5f42SShriraj Sawant MessageBox(0, L"The device cannot be stopped right now! Try stopping it again later!", strInfo, MB_OKCANCEL | MB_ICONEXCLAMATION); 1997fbc5f42SShriraj Sawant } 2007fbc5f42SShriraj Sawant else 2017fbc5f42SShriraj Sawant { 2027fbc5f42SShriraj Sawant //MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OKCANCEL | MB_ICONINFORMATION); 2037fbc5f42SShriraj Sawant g_IsRemoving = TRUE; 2047fbc5f42SShriraj Sawant g_devList.RemoveAt(id); /* thing is.. even after removing id at this point, the devnode_change occurs after some seconds of sucessful removal 2057fbc5f42SShriraj Sawant and since pendrive is still plugged in it gets enumerated, if problem number is not filtered. 2067fbc5f42SShriraj Sawant */ 2077fbc5f42SShriraj Sawant } 208c2c66affSColin Finck } 209c2c66affSColin Finck 2107fbc5f42SShriraj Sawant DestroyMenu(hPopup); 2117fbc5f42SShriraj Sawant } 212c2c66affSColin Finck 2137fbc5f42SShriraj Sawant static void _ShowContextMenuR(CSysTray * pSysTray) 2147fbc5f42SShriraj Sawant { 2157fbc5f42SShriraj Sawant CString strMenu((LPWSTR)IDS_HOTPLUG_REMOVE_2); 216c2c66affSColin Finck HMENU hPopup = CreatePopupMenu(); 2177fbc5f42SShriraj Sawant AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu); 218754a35b2SEric Kohl SetMenuDefaultItem(hPopup, IDS_HOTPLUG_REMOVE_2, FALSE); 219c2c66affSColin Finck 2207fbc5f42SShriraj Sawant SetForegroundWindow(pSysTray->GetHWnd()); 2217fbc5f42SShriraj Sawant DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; 2227fbc5f42SShriraj Sawant POINT pt; 2237fbc5f42SShriraj Sawant GetCursorPos(&pt); 224c2c66affSColin Finck 2257fbc5f42SShriraj Sawant DWORD id = TrackPopupMenuEx(hPopup, flags, 2267fbc5f42SShriraj Sawant pt.x, pt.y, 2277fbc5f42SShriraj Sawant pSysTray->GetHWnd(), NULL); 228c2c66affSColin Finck 2297fbc5f42SShriraj Sawant if (id == IDS_HOTPLUG_REMOVE_2) 2307fbc5f42SShriraj Sawant { 2317fbc5f42SShriraj Sawant _RunHotplug(pSysTray); 2327fbc5f42SShriraj Sawant } 233c2c66affSColin Finck 234c2c66affSColin Finck DestroyMenu(hPopup); 235c2c66affSColin Finck } 236c2c66affSColin Finck 237c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) 238c2c66affSColin Finck { 2397fbc5f42SShriraj Sawant HRESULT hr = E_FAIL; 240c2c66affSColin Finck TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam); 241c2c66affSColin Finck 242c2c66affSColin Finck switch (uMsg) 243c2c66affSColin Finck { 2447fbc5f42SShriraj Sawant /*case WM_CREATE: 2457fbc5f42SShriraj Sawant TRACE("Hotplug_Message: WM_CREATE\n"); 2467fbc5f42SShriraj Sawant DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; 2477fbc5f42SShriraj Sawant 2487fbc5f42SShriraj Sawant ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); 2497fbc5f42SShriraj Sawant NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); 2507fbc5f42SShriraj Sawant NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 2517fbc5f42SShriraj Sawant 2527fbc5f42SShriraj Sawant g_hDevNotify = RegisterDeviceNotification(pSysTray->GetHWnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); 2537fbc5f42SShriraj Sawant if (g_hDevNotify != NULL) 2547fbc5f42SShriraj Sawant { 2557fbc5f42SShriraj Sawant lResult = true; 2567fbc5f42SShriraj Sawant return S_OK; 2577fbc5f42SShriraj Sawant } 2587fbc5f42SShriraj Sawant return S_FALSE;*/ 2597fbc5f42SShriraj Sawant 260c2c66affSColin Finck case WM_USER + 220: 261c2c66affSColin Finck TRACE("Hotplug_Message: WM_USER+220\n"); 262*8c30fdabSEric Kohl if (wParam == HOTPLUG_SERVICE_FLAG) 263c2c66affSColin Finck { 264*8c30fdabSEric Kohl if (lParam) 265*8c30fdabSEric Kohl { 266*8c30fdabSEric Kohl pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, TRUE); 267c2c66affSColin Finck return Hotplug_Init(pSysTray); 268*8c30fdabSEric Kohl } 269c2c66affSColin Finck else 270*8c30fdabSEric Kohl { 271*8c30fdabSEric Kohl pSysTray->EnableService(HOTPLUG_SERVICE_FLAG, FALSE); 272c2c66affSColin Finck return Hotplug_Shutdown(pSysTray); 273c2c66affSColin Finck } 274*8c30fdabSEric Kohl } 275c2c66affSColin Finck return S_FALSE; 276c2c66affSColin Finck 277c2c66affSColin Finck case WM_USER + 221: 278c2c66affSColin Finck TRACE("Hotplug_Message: WM_USER+221\n"); 279*8c30fdabSEric Kohl if (wParam == HOTPLUG_SERVICE_FLAG) 280c2c66affSColin Finck { 281*8c30fdabSEric Kohl lResult = (LRESULT)pSysTray->IsServiceEnabled(HOTPLUG_SERVICE_FLAG); 282c2c66affSColin Finck return S_OK; 283c2c66affSColin Finck } 284c2c66affSColin Finck return S_FALSE; 285c2c66affSColin Finck 2862baafa61SEric Kohl case WM_TIMER: 2872baafa61SEric Kohl if (wParam == HOTPLUG_TIMER_ID) 2882baafa61SEric Kohl { 2892baafa61SEric Kohl KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID); 2902baafa61SEric Kohl _ShowContextMenu(pSysTray); 2912baafa61SEric Kohl } 2922baafa61SEric Kohl break; 2932baafa61SEric Kohl 294c2c66affSColin Finck case ID_ICON_HOTPLUG: 295c2c66affSColin Finck Hotplug_Update(pSysTray); 296c2c66affSColin Finck 297c2c66affSColin Finck switch (lParam) 298c2c66affSColin Finck { 299c2c66affSColin Finck case WM_LBUTTONDOWN: 300282b4397SEric Kohl SetTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID, GetDoubleClickTime(), NULL); 301c2c66affSColin Finck break; 302c2c66affSColin Finck 303c2c66affSColin Finck case WM_LBUTTONUP: 304c2c66affSColin Finck break; 305c2c66affSColin Finck 306c2c66affSColin Finck case WM_LBUTTONDBLCLK: 3072baafa61SEric Kohl KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID); 3087fbc5f42SShriraj Sawant _RunHotplug(pSysTray); 309c2c66affSColin Finck break; 310c2c66affSColin Finck 311c2c66affSColin Finck case WM_RBUTTONDOWN: 312c2c66affSColin Finck break; 313c2c66affSColin Finck 314c2c66affSColin Finck case WM_RBUTTONUP: 3157fbc5f42SShriraj Sawant _ShowContextMenuR(pSysTray); 316c2c66affSColin Finck break; 317c2c66affSColin Finck 318c2c66affSColin Finck case WM_RBUTTONDBLCLK: 319c2c66affSColin Finck break; 320c2c66affSColin Finck 321c2c66affSColin Finck case WM_MOUSEMOVE: 322c2c66affSColin Finck break; 323c2c66affSColin Finck } 324c2c66affSColin Finck return S_OK; 325c2c66affSColin Finck 3267fbc5f42SShriraj Sawant case WM_DEVICECHANGE: 3277fbc5f42SShriraj Sawant switch (wParam) 3287fbc5f42SShriraj Sawant { 3297fbc5f42SShriraj Sawant case DBT_DEVNODES_CHANGED: 3307fbc5f42SShriraj Sawant hr = EnumHotpluggedDevices(g_devList); 3317fbc5f42SShriraj Sawant if (FAILED(hr)) 3327fbc5f42SShriraj Sawant return hr; 3337fbc5f42SShriraj Sawant 3347fbc5f42SShriraj Sawant lResult = true; 3357fbc5f42SShriraj Sawant break; 3367fbc5f42SShriraj Sawant case DBT_DEVICEARRIVAL: 3377fbc5f42SShriraj Sawant break; 3387fbc5f42SShriraj Sawant case DBT_DEVICEQUERYREMOVE: 3397fbc5f42SShriraj Sawant break; 3407fbc5f42SShriraj Sawant case DBT_DEVICEQUERYREMOVEFAILED: 3417fbc5f42SShriraj Sawant break; 3427fbc5f42SShriraj Sawant case DBT_DEVICEREMOVECOMPLETE: 3437fbc5f42SShriraj Sawant WCHAR strInfo[128]; 3447fbc5f42SShriraj Sawant swprintf(strInfo, L"The %wS can now be safely removed from the system.", g_strMenuSel); 3457fbc5f42SShriraj Sawant NotifyBalloon(pSysTray, L"Safe to Remove Hardware", strInfo); 3467fbc5f42SShriraj Sawant 3477fbc5f42SShriraj Sawant lResult = true; 3487fbc5f42SShriraj Sawant break; 3497fbc5f42SShriraj Sawant case DBT_DEVICEREMOVEPENDING: 3507fbc5f42SShriraj Sawant break; 3517fbc5f42SShriraj Sawant } 3527fbc5f42SShriraj Sawant return S_OK; 3537fbc5f42SShriraj Sawant 3547fbc5f42SShriraj Sawant /*case WM_CLOSE: 3557fbc5f42SShriraj Sawant if (!UnregisterDeviceNotification(hDeviceNotify)) 3567fbc5f42SShriraj Sawant { 3577fbc5f42SShriraj Sawant return S_FALSE; 3587fbc5f42SShriraj Sawant } 3597fbc5f42SShriraj Sawant return S_OK;*/ 3607fbc5f42SShriraj Sawant 361c2c66affSColin Finck default: 362c2c66affSColin Finck TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n"); 363c2c66affSColin Finck return S_FALSE; 364c2c66affSColin Finck } 365c2c66affSColin Finck 366c2c66affSColin Finck return S_FALSE; 367c2c66affSColin Finck } 368