Author: ssawant Date: Sun Aug 6 16:33:27 2017 New Revision: 75497
URL: http://svn.reactos.org/svn/reactos?rev=75497&view=rev Log: [STOBJECT] -Added new battery icons and hotplug icons, thanks to Pi_User5. -Modified resources for the same. -Modified CSysTray to support icon hiding feature. -Modified hotplug.cpp by adding experimental enumeration to test icon behavior. -Icon behavior successfully tested. -Added code to eject device, works fine. -Fixed a bug which didn't showed attached devices after reloading. (like after system restart or explorer restart.) -Now at least pen-drives are safely removable. (Still experimental though, use at your own risk ;P) -Tested in winxp vm, needs further testing.
Added: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/0.ico (with props) branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/1.ico (with props) Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.cpp branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.h branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/hotplug.cpp branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resource.h branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/0.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/1.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/2.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/3.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/4.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/5.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging0.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging1.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging2.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging3.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging4.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/error.ico branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/stobject.rc
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.cpp URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== --- branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.cpp [iso-8859-1] (original) +++ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.cpp [iso-8859-1] Sun Aug 6 16:33:27 2017 @@ -4,6 +4,7 @@ * FILE: dll/shellext/stobject/csystray.cpp * PURPOSE: Systray shell service object implementation * PROGRAMMERS: David Quintana gigaherz@gmail.com +* Shriraj Sawant a.k.a SR13 sr.official@hotmail.com */
#include "precomp.h" @@ -97,7 +98,7 @@ return S_FALSE; }
-HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip) +HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip, DWORD dwstate) { NOTIFYICONDATA nim = { 0 };
@@ -108,8 +109,8 @@ nim.hIcon = hIcon; nim.uID = uId; nim.uCallbackMessage = uId; - nim.dwState = 0; - nim.dwStateMask = 0; + nim.dwState = dwstate; + nim.dwStateMask = NIS_HIDDEN; nim.hWnd = m_hWnd; nim.uVersion = NOTIFYICON_VERSION; if (szTip)
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== --- branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.h [iso-8859-1] (original) +++ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/csystray.h [iso-8859-1] Sun Aug 6 16:33:27 2017 @@ -5,6 +5,7 @@ * PURPOSE: Systray shell service object * PROGRAMMERS: Robert Naumann * David Quintana gigaherz@gmail.com + * Shriraj Sawant a.k.a SR13 sr.official@hotmail.com */ #pragma once
@@ -43,7 +44,7 @@ HRESULT ShutdownNetShell();
public: - HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip); + HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip, DWORD dwstate = 0);
HWND GetHWnd() { return m_hWnd; }
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/hotplug.cpp URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== --- branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/hotplug.cpp [iso-8859-1] (original) +++ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/hotplug.cpp [iso-8859-1] Sun Aug 6 16:33:27 2017 @@ -5,33 +5,87 @@ * PURPOSE: Removable devices notification icon handler * PROGRAMMERS: Shriraj Sawant a.k.a SR13 sr.official@hotmail.com */ - +#include <windows.h> #include "precomp.h" #include <mmsystem.h> #include <mmddk.h> #include <atlstr.h> +#include <atlsimpcoll.h> +#include <dbt.h> +#include <setupapi.h> +#include <cfgmgr32.h>
WINE_DEFAULT_DEBUG_CHANNEL(stobject); - +#define DISPLAY_NAME_LEN 40 + +//BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle); + +CSimpleArray<DEVINST> g_devList; +static HDEVNOTIFY g_hDevNotify = NULL; static HICON g_hIconHotplug = NULL; static LPWSTR g_strTooltip = L"Safely Remove Hardware and Eject Media"; static BOOL g_IsRunning = FALSE; +static BOOL g_IsRemoved = FALSE; + +// Enumerate the connected removable devices +// TODO: Require proper enumeration and filters. +HRESULT EnumHotpluggedDevices(CSimpleArray<DEVINST> &devList) +{ + devList.RemoveAll(); // Clear current devList + HDEVINFO hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT); + if (INVALID_HANDLE_VALUE == hdev) + return E_HANDLE; + SP_DEVINFO_DATA did = { 0 }; + did.cbSize = sizeof(did); + + for (int idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); idev++) + { + DWORD dwCapabilities = 0, dwSize = sizeof(dwCapabilities); + WCHAR dispName[DISPLAY_NAME_LEN]; + ULONG ulStatus = 0, ulPnum = 0, ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR); + CONFIGRET cr = CM_Get_DevNode_Status(&ulStatus, &ulPnum, did.DevInst, 0); + if (cr != CR_SUCCESS) + continue; + cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0); + if (cr != CR_SUCCESS) + continue; + cr = CM_Get_DevNode_Registry_Property(did.DevInst, CM_DRP_CAPABILITIES, NULL, &dwCapabilities, &dwSize, 0); + if (cr != CR_SUCCESS) + continue; + + if ((dwCapabilities & CM_DEVCAP_REMOVABLE) && (dwCapabilities & CM_DEVCAP_UNIQUEID)) + { + devList.Add(did.DevInst); + } + } + SetupDiDestroyDeviceInfoList(hdev); + + if (NO_ERROR != GetLastError() && ERROR_NO_MORE_ITEMS != GetLastError()) + { + return E_UNEXPECTED; + } + + return S_OK; +}
HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray) { TRACE("Hotplug_Init\n"); - g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_EXTRACT)); + g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_HOTPLUG_OK)); g_IsRunning = TRUE; - - return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip); + EnumHotpluggedDevices(g_devList); + + return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN); }
HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray) { TRACE("Hotplug_Update\n"); - //g_hIconHotplug = DynamicLoadIcon(g_hInstance); - - return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip); + + if(g_devList.GetSize()) + return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip); + else + return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_HOTPLUG, g_hIconHotplug, g_strTooltip, NIS_HIDDEN); }
HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray) @@ -42,16 +96,26 @@ return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL); }
-static void _RunHotplug() -{ - ShellExecuteW(NULL, NULL, L"hotplug.cpl", NULL, NULL, SW_SHOWNORMAL); +static void _RunHotplug(CSysTray * pSysTray) +{ + ShellExecuteW(pSysTray->GetHWnd(), L"open", L"rundll32.exe shell32.dll,Control_RunDLL hotplug.dll", NULL, NULL, SW_SHOWNORMAL); }
static void _ShowContextMenu(CSysTray * pSysTray) -{ - CString strOpen((LPCSTR)IDS_HOTPLUG_REMOVE_2); - HMENU hPopup = CreatePopupMenu(); - AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strOpen); +{ + HMENU hPopup = CreatePopupMenu(); + + for (UINT index = 0; index < g_devList.GetSize(); index++) + { + WCHAR dispName[DISPLAY_NAME_LEN], menuName[DISPLAY_NAME_LEN + 10]; + ULONG ulLength = DISPLAY_NAME_LEN * sizeof(WCHAR); + CONFIGRET cr = CM_Get_DevNode_Registry_Property(g_devList[index], CM_DRP_DEVICEDESC, NULL, dispName, &ulLength, 0); + if (cr != CR_SUCCESS) + StrCpyW(dispName, L"Unknown Device"); + + swprintf(menuName, L"Eject %wS", dispName); + AppendMenuW(hPopup, MF_STRING, index+1, menuName); + }
SetForegroundWindow(pSysTray->GetHWnd()); DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; @@ -60,23 +124,69 @@
DWORD id = TrackPopupMenuEx(hPopup, flags, pt.x, pt.y, - pSysTray->GetHWnd(), NULL); - - switch (id) - { - case IDS_HOTPLUG_REMOVE_2: - _RunHotplug(); - break; - } + pSysTray->GetHWnd(), NULL); + + if (id > 0) + { + id--; // since array indices starts from zero. + CONFIGRET cr = CM_Request_Device_Eject_Ex(g_devList[id], 0, 0, 0, 0, 0); + if (cr != CR_SUCCESS) + MessageBox(0, L"Device ejection failed!! Please try again after closing any open programs on device!", L"Safely Remove Hardware", MB_OKCANCEL | MB_ICONEXCLAMATION); + else + { + MessageBox(0, L"Device ejected successfully!! You can safely remove the device now!", L"Safely Remove Hardware", MB_OKCANCEL | MB_ICONINFORMATION); + g_devList.RemoveAt(id); + } + } + DestroyMenu(hPopup); }
+static void _ShowContextMenuR(CSysTray * pSysTray) +{ + CString strMenu((LPWSTR)IDS_HOTPLUG_REMOVE_2); + HMENU hPopup = CreatePopupMenu(); + AppendMenuW(hPopup, MF_STRING, IDS_HOTPLUG_REMOVE_2, strMenu); + + SetForegroundWindow(pSysTray->GetHWnd()); + DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; + POINT pt; + GetCursorPos(&pt); + + DWORD id = TrackPopupMenuEx(hPopup, flags, + pt.x, pt.y, + pSysTray->GetHWnd(), NULL); + + if (id == IDS_HOTPLUG_REMOVE_2) + { + _RunHotplug(pSysTray); + } + + DestroyMenu(hPopup); +} + HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) { - TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam); + TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
switch (uMsg) { + /*case WM_CREATE: + TRACE("Hotplug_Message: WM_CREATE\n"); + DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; + + ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); + NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + + g_hDevNotify = RegisterDeviceNotification(pSysTray->GetHWnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); + if (g_hDevNotify != NULL) + { + lResult = true; + return S_OK; + } + return S_FALSE;*/ + case WM_USER + 220: TRACE("Hotplug_Message: WM_USER+220\n"); if (wParam == 1) @@ -106,18 +216,18 @@ break;
case WM_LBUTTONUP: - MessageBox(0, L"Safely Remove Hardware", L"Test", MB_OKCANCEL | MB_ICONINFORMATION); + _ShowContextMenu(pSysTray); break;
case WM_LBUTTONDBLCLK: - _RunHotplug(); + _RunHotplug(pSysTray); break;
case WM_RBUTTONDOWN: break;
case WM_RBUTTONUP: - _ShowContextMenu(pSysTray); + _ShowContextMenuR(pSysTray); break;
case WM_RBUTTONDBLCLK: @@ -127,6 +237,25 @@ break; } return S_OK; + + case WM_DEVICECHANGE: + switch (wParam) + { + case DBT_DEVNODES_CHANGED: + HRESULT hr = EnumHotpluggedDevices(g_devList); + if (FAILED(hr)) + return hr; + } + + lResult = true; + return S_OK; + + /*case WM_CLOSE: + if (!UnregisterDeviceNotification(hDeviceNotify)) + { + return S_FALSE; + } + return S_OK;*/
default: TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resource.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== --- branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resource.h [iso-8859-1] (original) +++ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resource.h [iso-8859-1] Sun Aug 6 16:33:27 2017 @@ -39,17 +39,20 @@ #define IDS_KEYS_MOUSE 331 #define IDS_KEYS_FILTER 332
-#define IDI_BATTCAP0 400 -#define IDI_BATTCAP1 401 -#define IDI_BATTCAP2 402 -#define IDI_BATTCAP3 403 -#define IDI_BATTCAP4 404 -#define IDI_BATTCAP5 405 -#define IDI_BATTCHA0 406 -#define IDI_BATTCHA1 407 -#define IDI_BATTCHA2 408 -#define IDI_BATTCHA3 409 -#define IDI_BATTCHA4 410 -#define IDI_BATTCAP_ERR 412 +#define IDI_BATTCAP0 400 +#define IDI_BATTCAP1 401 +#define IDI_BATTCAP2 402 +#define IDI_BATTCAP3 403 +#define IDI_BATTCAP4 404 +#define IDI_BATTCAP5 405 +#define IDI_BATTCHA0 406 +#define IDI_BATTCHA1 407 +#define IDI_BATTCHA2 408 +#define IDI_BATTCHA3 409 +#define IDI_BATTCHA4 410 +#define IDI_BATTCAP_ERR 412 + +#define IDI_HOTPLUG_ERR 420 +#define IDI_HOTPLUG_OK 421
#define IDR_SYSTRAY 11001
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/0.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/1.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/2.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/3.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/4.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/5.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging0.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging1.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging2.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging3.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/charging4.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/battery/error.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary files - no diff available.
Added: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/0.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary file - no diff available.
Propchange: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/0.ico ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream
Added: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/1.ico URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== Binary file - no diff available.
Propchange: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/resources/hotplug/1.ico ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream
Modified: branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/stobject.rc URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/reactos/dll/s... ============================================================================== --- branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/stobject.rc [iso-8859-1] (original) +++ branches/GSoC_2017/shellext/reactos/dll/shellext/stobject/stobject.rc [iso-8859-1] Sun Aug 6 16:33:27 2017 @@ -25,6 +25,10 @@ IDI_BATTCHA4 ICON "resources/battery/charging4.ico"
IDI_BATTCAP_ERR ICON "resources/battery/error.ico" + +IDI_HOTPLUG_ERR ICON "resources/hotplug/0.ico" +IDI_HOTPLUG_OK ICON "resources/hotplug/1.ico" +
IDR_SYSTRAY REGISTRY "resources/rgs/systray.rgs"