From cd1e4d2911c56c1777bd6d31ddbb6e8392619ddc Mon Sep 17 00:00:00 2001 From: David Quintana Date: Wed, 30 Jul 2014 22:08:05 +0000 Subject: [PATCH] [STOBJECT] * Improve code organization. * Add some debug prints. * Fix some nits. svn path=/branches/shell-experiments/; revision=63787 --- base/shell/explorer-new/shellservice.c | 16 ++ dll/win32/stobject/CMakeLists.txt | 1 + dll/win32/stobject/csystray.cpp | 200 +++++++++++++++ dll/win32/stobject/csystray.h | 66 +++++ dll/win32/stobject/precomp.h | 66 +---- dll/win32/stobject/stobject.cpp | 340 +++++++------------------ dll/win32/stobject/volume.cpp | 9 +- 7 files changed, 389 insertions(+), 309 deletions(-) create mode 100644 dll/win32/stobject/csystray.cpp create mode 100644 dll/win32/stobject/csystray.h diff --git a/base/shell/explorer-new/shellservice.c b/base/shell/explorer-new/shellservice.c index 5f3f4405e92..21ac7797826 100644 --- a/base/shell/explorer-new/shellservice.c +++ b/base/shell/explorer-new/shellservice.c @@ -27,6 +27,7 @@ static int CALLBACK InitializeAllCallback(void* pItem, void* pData) { IOleCommandTarget * pOct = pItem; HRESULT * phr = pData; + DbgPrint("Initializing SSO %p\n", pOct); *phr = IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL); return SUCCEEDED(*phr); } @@ -34,6 +35,7 @@ static int CALLBACK InitializeAllCallback(void* pItem, void* pData) static int CALLBACK ShutdownAllCallback(void* pItem, void* pData) { IOleCommandTarget * pOct = pItem; + DbgPrint("Shutting down SSO %p\n", pOct); IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL); return TRUE; } @@ -41,6 +43,7 @@ static int CALLBACK ShutdownAllCallback(void* pItem, void* pData) static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData) { IOleCommandTarget * pOct = pItem; + DbgPrint("Releasing SSO %p\n", pOct); IUnknown_Release(pOct); return TRUE; } @@ -60,10 +63,13 @@ HRESULT InitShellServices(HDPA * phdpa) hdpa = DPA_Create(5); + DbgPrint("Enumerating Shell Service Ojbect GUIDs...\n"); + if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad", &hkey)) { + DbgPrint("ERROR: RegOpenKey failed.\n"); return HRESULT_FROM_WIN32(GetLastError()); } @@ -78,15 +84,24 @@ HRESULT InitShellServices(HDPA * phdpa) break; if (type != REG_SZ) + { + DbgPrint("WARNING: Value type was not REG_SZ.\n"); continue; + } hr = CLSIDFromString(value, &clsid); if (FAILED(hr)) + { + DbgPrint("ERROR: CLSIDFromString failed %08x.\n", hr); goto cleanup; + } hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (VOID**) &pOct); if (FAILED(hr)) + { + DbgPrint("ERROR: CoCreateInstance failed %08x.\n", hr); goto cleanup; + } DPA_AppendPtr(hdpa, pOct); @@ -96,6 +111,7 @@ HRESULT InitShellServices(HDPA * phdpa) if (ret != ERROR_NO_MORE_ITEMS) { + DbgPrint("ERROR: RegEnumValueW failed %08x.\n", ret); hr = HRESULT_FROM_WIN32(GetLastError()); goto cleanup; } diff --git a/dll/win32/stobject/CMakeLists.txt b/dll/win32/stobject/CMakeLists.txt index 773cbddf81e..d718d3bface 100644 --- a/dll/win32/stobject/CMakeLists.txt +++ b/dll/win32/stobject/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories( spec2def(stobject.dll stobject.spec) add_library(stobject SHARED + csystray.cpp stobject.cpp stobject.rc volume.cpp diff --git a/dll/win32/stobject/csystray.cpp b/dll/win32/stobject/csystray.cpp new file mode 100644 index 00000000000..66bcd4d87a9 --- /dev/null +++ b/dll/win32/stobject/csystray.cpp @@ -0,0 +1,200 @@ +/* +* PROJECT: ReactOS system libraries +* LICENSE: GPL - See COPYING in the top level directory +* FILE: dll\win32\stobject\csystray.cpp +* PURPOSE: Systray shell service object implementation +* PROGRAMMERS: David Quintana +*/ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(stobject); + +const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } }; + +CSysTray::CSysTray() {} +CSysTray::~CSysTray() {} + +HRESULT CSysTray::InitIcons() +{ + for (int i = 0; i < g_NumIcons; i++) + { + HRESULT hr = g_IconHandlers[i].pfnInit(this); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +HRESULT CSysTray::ShutdownIcons() +{ + for (int i = 0; i < g_NumIcons; i++) + { + HRESULT hr = g_IconHandlers[i].pfnShutdown(this); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +HRESULT CSysTray::UpdateIcons() +{ + for (int i = 0; i < g_NumIcons; i++) + { + HRESULT hr = g_IconHandlers[i].pfnUpdate(this); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + for (int i = 0; i < g_NumIcons; i++) + { + HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam); + if (FAILED(hr)) + return hr; + + if (hr != S_FALSE) + return hr; + } + + return S_OK; +} + +HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip) +{ + NOTIFYICONDATA nim; + nim.cbSize = sizeof(NOTIFYICONDATA); + nim.uFlags = NIF_ICON | NIF_STATE | NIF_TIP; + nim.hIcon = hIcon; + nim.uID = uId; + nim.uCallbackMessage = uId; + nim.dwState = 0; + nim.dwStateMask = 0; + nim.hWnd = m_hWnd; + nim.uVersion = NOTIFYICON_VERSION; + if (szTip) + StringCchCopy(nim.szTip, _countof(nim.szTip), szTip); + else + nim.szTip[0] = 0; + BOOL ret = Shell_NotifyIcon(code, &nim); + return ret ? S_OK : E_FAIL; +} + +DWORD WINAPI CSysTray::s_SysTrayThreadProc(PVOID param) +{ + CSysTray * st = (CSysTray*) param; + return st->SysTrayThreadProc(); +} + +HRESULT CSysTray::SysTrayMessageLoop() +{ + BOOL ret; + MSG msg; + + while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) + { + if (ret < 0) + break; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return S_OK; +} + +HRESULT CSysTray::SysTrayThreadProc() +{ + WCHAR strFileName[MAX_PATH]; + GetModuleFileNameW(g_hInstance, strFileName, MAX_PATH); + HMODULE hLib = LoadLibraryW(strFileName); + + CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED); + + Create(NULL); + + HRESULT ret = SysTrayMessageLoop(); + + CoUninitialize(); + + FreeLibraryAndExitThread(hLib, ret); +} + +HRESULT CSysTray::CreateSysTrayThread() +{ + DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n"); + + HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL); + + CloseHandle(hThread); + + return S_OK; +} + +HRESULT CSysTray::DestroySysTrayWindow() +{ + DestroyWindow(); + hwndSysTray = NULL; + return S_OK; +} + +// *** IOleCommandTarget methods *** +HRESULT STDMETHODCALLTYPE CSysTray::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) +{ + UNIMPLEMENTED; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CSysTray::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) +{ + if (!IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject)) + return E_FAIL; + + switch (nCmdID) + { + case OLECMDID_NEW: // init + return CreateSysTrayThread(); + case OLECMDID_SAVE: // shutdown + return DestroySysTrayWindow(); + } + return S_OK; +} + +BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID) +{ + HRESULT hr; + + if (hWnd != m_hWnd) + return FALSE; + + switch (uMsg) + { + case WM_CREATE: + InitIcons(); + SetTimer(1, 2000, NULL); + return TRUE; + case WM_TIMER: + UpdateIcons(); + return TRUE; + case WM_DESTROY: + ShutdownIcons(); + return TRUE; + } + + DbgPrint("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam); + + hr = ProcessIconMessage(uMsg, wParam, lParam); + if (FAILED(hr)) + return FALSE; + + if (hr == S_FALSE) + return FALSE; + + return TRUE; +} diff --git a/dll/win32/stobject/csystray.h b/dll/win32/stobject/csystray.h new file mode 100644 index 00000000000..1bf474e6b85 --- /dev/null +++ b/dll/win32/stobject/csystray.h @@ -0,0 +1,66 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll\win32\stobject\stobject.cpp + * PURPOSE: Systray shell service object + * PROGRAMMERS: Robert Naumann + David Quintana + */ +#pragma once + +extern const GUID CLSID_SysTray; + + +typedef CWinTraits < + WS_POPUP | WS_DLGFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_PALETTEWINDOW +> CMessageWndClass; + +class CSysTray : + public CComCoClass, + public CComObjectRootEx, + public CWindowImpl, + public IOleCommandTarget +{ + // TODO: keep icon handlers here + + HWND hwndSysTray; + + static DWORD WINAPI s_SysTrayThreadProc(PVOID param); + HRESULT SysTrayMessageLoop(); + HRESULT SysTrayThreadProc(); + HRESULT CreateSysTrayThread(); + HRESULT DestroySysTrayWindow(); + + HRESULT InitIcons(); + HRESULT ShutdownIcons(); + HRESULT UpdateIcons(); + HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + +public: + HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip); + + HWND GetHWnd() { return m_hWnd; } + +protected: + BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID = 0); + +public: + CSysTray(); + virtual ~CSysTray(); + + // *** IOleCommandTarget methods *** + virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText); + virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); + + DECLARE_WND_CLASS_EX(_T("SystemTray_Main"), CS_GLOBALCLASS, COLOR_3DFACE) + + DECLARE_REGISTRY_RESOURCEID(IDR_SYSTRAY) + DECLARE_NOT_AGGREGATABLE(CSysTray) + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(CSysTray) + COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) + END_COM_MAP() + +}; \ No newline at end of file diff --git a/dll/win32/stobject/precomp.h b/dll/win32/stobject/precomp.h index c42e8d5bc81..e74b9880fea 100644 --- a/dll/win32/stobject/precomp.h +++ b/dll/win32/stobject/precomp.h @@ -34,68 +34,28 @@ #include "resource.h" -extern const GUID CLSID_SysTray; - extern HINSTANCE g_hInstance; #define ID_ICON_VOLUME 0x4CB -/* --------------- CSysTray callbacks ------------------------------ */ +#include "csystray.h" -typedef CWinTraits < - WS_POPUP | WS_DLGFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_PALETTEWINDOW -> CMessageWndClass; +typedef HRESULT(STDMETHODCALLTYPE * PFNSTINIT) (_In_ CSysTray * pSysTray); +typedef HRESULT(STDMETHODCALLTYPE * PFNSTSHUTDOWN) (_In_ CSysTray * pSysTray); +typedef HRESULT(STDMETHODCALLTYPE * PFNSTUPDATE) (_In_ CSysTray * pSysTray); +typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam); -class CSysTray : - public CComCoClass, - public CComObjectRootEx, - public CWindowImpl, - public IOleCommandTarget +struct SysTrayIconHandlers_t { - // TODO: keep icon handlers here - - HWND hwndSysTray; - - static DWORD WINAPI s_SysTrayThreadProc(PVOID param); - HRESULT SysTrayMessageLoop(); - HRESULT SysTrayThreadProc(); - HRESULT CreateSysTrayThread(); - HRESULT DestroySysTrayWindow(); - - HRESULT InitIcons(); - HRESULT ShutdownIcons(); - HRESULT UpdateIcons(); - HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); - -public: - HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip); - - HWND GetHWnd() { return m_hWnd; } - -protected: - BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID = 0); - -public: - CSysTray(); - virtual ~CSysTray(); - - // *** IOleCommandTarget methods *** - virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText); - virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); - - DECLARE_WND_CLASS_EX(_T("SystemTray_Main"), CS_GLOBALCLASS, COLOR_3DFACE) - - DECLARE_REGISTRY_RESOURCEID(IDR_SYSTRAY) - DECLARE_NOT_AGGREGATABLE(CSysTray) - DECLARE_PROTECT_FINAL_CONSTRUCT() - - BEGIN_COM_MAP(CSysTray) - COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) - END_COM_MAP() - + PFNSTINIT pfnInit; + PFNSTSHUTDOWN pfnShutdown; + PFNSTUPDATE pfnUpdate; + PFNSTMESSAGE pfnMessage; }; +extern SysTrayIconHandlers_t g_IconHandlers[]; +extern const int g_NumIcons; + /* --------------- Icon callbacks ------------------------------ */ extern HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray); diff --git a/dll/win32/stobject/stobject.cpp b/dll/win32/stobject/stobject.cpp index 69e122a1182..6d597881eee 100644 --- a/dll/win32/stobject/stobject.cpp +++ b/dll/win32/stobject/stobject.cpp @@ -2,7 +2,7 @@ * PROJECT: ReactOS system libraries * LICENSE: GPL - See COPYING in the top level directory * FILE: dll\win32\stobject\stobject.cpp - * PURPOSE: Systray shell service object + * PURPOSE: COM registration services for STobject.dll * PROGRAMMERS: Robert Naumann David Quintana */ @@ -14,314 +14,150 @@ WINE_DEFAULT_DEBUG_CHANNEL(stobject); -const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } }; - -HINSTANCE g_hInstance; - -typedef HRESULT(STDMETHODCALLTYPE * PFNSTINIT) (_In_ CSysTray * pSysTray); -typedef HRESULT(STDMETHODCALLTYPE * PFNSTSHUTDOWN) (_In_ CSysTray * pSysTray); -typedef HRESULT(STDMETHODCALLTYPE * PFNSTUPDATE) (_In_ CSysTray * pSysTray); -typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam); +BEGIN_OBJECT_MAP(ObjectMap) + OBJECT_ENTRY(CLSID_SysTray, CSysTray) +END_OBJECT_MAP() -struct SysTrayIconHandlers_t +class CShellTrayModule : public CComModule { - PFNSTINIT pfnInit; - PFNSTSHUTDOWN pfnShutdown; - PFNSTUPDATE pfnUpdate; - PFNSTMESSAGE pfnMessage; +public: }; +HINSTANCE g_hInstance; +CShellTrayModule g_Module; SysTrayIconHandlers_t g_IconHandlers [] = { { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message } }; -const int g_NumIcons = _countof(g_IconHandlers); +const int g_NumIcons = _countof(g_IconHandlers); -HRESULT CSysTray::InitIcons() +void *operator new (size_t, void *buf) { - for (int i = 0; i < g_NumIcons; i++) - { - HRESULT hr = g_IconHandlers[i].pfnInit(this); - if (FAILED(hr)) - return hr; - } - - return S_OK; + return buf; } -HRESULT CSysTray::ShutdownIcons() +BOOL +WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { - for (int i = 0; i < g_NumIcons; i++) + if (fdwReason == DLL_PROCESS_ATTACH) { - HRESULT hr = g_IconHandlers[i].pfnShutdown(this); - if (FAILED(hr)) - return hr; - } + g_hInstance = hinstDLL; + DisableThreadLibraryCalls(g_hInstance); - return S_OK; -} + /* HACK - the global constructors don't run, so I placement new them here */ + new (&g_Module) CShellTrayModule; + new (&_AtlWinModule) CAtlWinModule; + new (&_AtlBaseModule) CAtlBaseModule; + new (&_AtlComModule) CAtlComModule; -HRESULT CSysTray::UpdateIcons() -{ - for (int i = 0; i < g_NumIcons; i++) - { - HRESULT hr = g_IconHandlers[i].pfnUpdate(this); - if (FAILED(hr)) - return hr; + g_Module.Init(ObjectMap, g_hInstance, NULL); } - - return S_OK; -} - -HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - for (int i = 0; i < g_NumIcons; i++) + else if (fdwReason == DLL_PROCESS_DETACH) { - HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam); - if (FAILED(hr)) - return hr; - - if (hr != S_FALSE) - return hr; + g_hInstance = NULL; + g_Module.Term(); } - - return S_OK; + return TRUE; } -HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip) +static +HRESULT +RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister) { - NOTIFYICONDATA nim; - nim.cbSize = sizeof(NOTIFYICONDATA); - nim.uFlags = NIF_ICON | NIF_STATE | NIF_TIP; - nim.hIcon = hIcon; - nim.uID = uId; - nim.uCallbackMessage = uId; - nim.dwState = 0; - nim.dwStateMask = 0; - nim.hWnd = m_hWnd; - nim.uVersion = NOTIFYICON_VERSION; - if (szTip) - StringCchCopy(nim.szTip, _countof(nim.szTip), szTip); - else - nim.szTip[0] = 0; - BOOL ret = Shell_NotifyIcon(code, &nim); - return ret ? S_OK : E_FAIL; -} + const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad"; -DWORD WINAPI CSysTray::s_SysTrayThreadProc(PVOID param) -{ - CSysTray * st = (CSysTray*) param; - return st->SysTrayThreadProc(); -} + HRESULT hr = E_FAIL; -HRESULT CSysTray::SysTrayMessageLoop() -{ - BOOL ret; - MSG msg; + OLECHAR strGuid[128]; - while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) - { - if (ret < 0) - break; + HKEY hKey = 0; - TranslateMessage(&msg); - DispatchMessage(&msg); + if (!StringFromGUID2(guidClass, strGuid, _countof(strGuid))) + { + DbgPrint("StringFromGUID2 failed\n"); + goto cleanup; } - return S_OK; -} - -HRESULT CSysTray::SysTrayThreadProc() -{ - WCHAR strFileName[MAX_PATH]; - GetModuleFileNameW(g_hInstance, strFileName, MAX_PATH); - HMODULE hLib = LoadLibraryW(strFileName); - - CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED); - - Create(NULL); - - HRESULT ret = SysTrayMessageLoop(); - - CoUninitialize(); - - FreeLibraryAndExitThread(hLib, ret); -} - -HRESULT CSysTray::CreateSysTrayThread() -{ - DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n"); - - HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL); - - CloseHandle(hThread); - - return S_OK; -} - -HRESULT CSysTray::DestroySysTrayWindow() -{ - DestroyWindow(); - hwndSysTray = NULL; - return S_OK; -} - -CSysTray::CSysTray() {} -CSysTray::~CSysTray() {} - -// *** IOleCommandTarget methods *** -HRESULT STDMETHODCALLTYPE CSysTray::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) -{ - UNIMPLEMENTED; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CSysTray::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) -{ - if (!IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject)) - return E_FAIL; - - switch (nCmdID) + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey)) { - case OLECMDID_NEW: // init - return CreateSysTrayThread(); - case OLECMDID_SAVE: // shutdown - return DestroySysTrayWindow(); + DbgPrint("RegOpenKeyExW failed\n"); + goto cleanup; } - return S_OK; -} -BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID) -{ - HRESULT hr; - - if (hWnd != m_hWnd) - return FALSE; - - switch (uMsg) + if (bRegister) { - case WM_CREATE: - InitIcons(); - SetTimer(1, 2000, NULL); - return TRUE; - case WM_TIMER: - UpdateIcons(); - return TRUE; - case WM_DESTROY: - ShutdownIcons(); - return TRUE; + LONG cbGuid = (lstrlenW(strGuid) + 1) * 2; + if (RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid)) + { + DbgPrint("RegSetValueExW failed\n"); + goto cleanup; + } } - - DbgPrint("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam); - - hr = ProcessIconMessage(uMsg, wParam, lParam); - if (FAILED(hr)) - return FALSE; - - if (hr == S_FALSE) - return FALSE; - - return TRUE; -} - -BEGIN_OBJECT_MAP(ObjectMap) - OBJECT_ENTRY(CLSID_SysTray, CSysTray) -END_OBJECT_MAP() - -class CShellTrayModule : public CComModule -{ -}; - -CShellTrayModule gModule; - - -HRESULT RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister) -{ - const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad"; - - OLECHAR strGuid[128]; // shouldn't need so much! - LSTATUS ret = 0; - HKEY hKey = 0; - if (StringFromGUID2(guidClass, strGuid, 128)) + else { - if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey)) + if (RegDeleteValueW(hKey, lpName)) { - if (bRegister) - { - LONG cbGuid = (lstrlenW(strGuid) + 1) * 2; - ret = RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid); - } - else - { - ret = RegDeleteValueW(hKey, lpName); - } + DbgPrint("RegDeleteValueW failed\n"); + goto cleanup; } } + + hr = S_OK; + +cleanup: if (hKey) RegCloseKey(hKey); - return /*HRESULT_FROM_NT*/(ret); // regsvr32 considers anything != S_OK to be an error + return hr; } -void *operator new (size_t, void *buf) -{ - return buf; -} - -BOOL -WINAPI -DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) +STDAPI +DllRegisterServer(void) { - if (fdwReason == DLL_PROCESS_ATTACH) - { - /* HACK - the global constructors don't run, so I placement new them here */ - new (&gModule) CShellTrayModule; - new (&_AtlWinModule) CAtlWinModule; - new (&_AtlBaseModule) CAtlBaseModule; - new (&_AtlComModule) CAtlComModule; + HRESULT hr; - g_hInstance = hinstDLL; - DisableThreadLibraryCalls(g_hInstance); + hr = g_Module.DllRegisterServer(FALSE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - gModule.Init(ObjectMap, g_hInstance, NULL); - } - else if (fdwReason == DLL_PROCESS_DETACH) - { - g_hInstance = NULL; - gModule.Term(); - } - return TRUE; -} + hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; -HRESULT -WINAPI -DllCanUnloadNow(void) -{ - return gModule.DllCanUnloadNow(); + return S_OK; } STDAPI -DllRegisterServer(void) +DllUnregisterServer(void) { - HRESULT hr = gModule.DllRegisterServer(FALSE); - if (FAILED(hr)) + HRESULT hr; + + hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = g_Module.DllUnregisterServer(FALSE); + if (FAILED_UNEXPECTEDLY(hr)) return hr; - return RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE); + return S_OK; } STDAPI -DllUnregisterServer(void) +DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE); + HRESULT hr; + + hr = g_Module.DllGetClassObject(rclsid, riid, ppv); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - return gModule.DllUnregisterServer(FALSE); + return S_OK; } -STDAPI -DllGetClassObject( -REFCLSID rclsid, -REFIID riid, -LPVOID *ppv) +HRESULT +WINAPI +DllCanUnloadNow(void) { - return gModule.DllGetClassObject(rclsid, riid, ppv); + return g_Module.DllCanUnloadNow(); } diff --git a/dll/win32/stobject/volume.cpp b/dll/win32/stobject/volume.cpp index 133809a48a6..2a925f10529 100644 --- a/dll/win32/stobject/volume.cpp +++ b/dll/win32/stobject/volume.cpp @@ -2,9 +2,8 @@ * PROJECT: ReactOS system libraries * LICENSE: GPL - See COPYING in the top level directory * FILE: dll\win32\stobject\volume.cpp - * PURPOSE: Systray shell service object - * PROGRAMMERS: Robert Naumann - David Quintana + * PURPOSE: Volume notification icon handler + * PROGRAMMERS: David Quintana */ #include "precomp.h" @@ -12,6 +11,8 @@ #include #include +WINE_DEFAULT_DEBUG_CHANNEL(stobject); + HICON g_hIconVolume; HICON g_hIconMute; @@ -33,7 +34,7 @@ static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray) DbgPrint("Volume_FindDefaultMixerID\n"); - result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD) &waveOutId, (DWORD) ¶m2); + result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &waveOutId, (DWORD_PTR) ¶m2); if (result) return E_FAIL; -- 2.17.1