[STOBJECT]

* Improve code organization. 
* Add some debug prints.
* Fix some nits.

svn path=/branches/shell-experiments/; revision=63787
This commit is contained in:
David Quintana 2014-07-30 22:08:05 +00:00
parent 149d0f17d3
commit cd1e4d2911
7 changed files with 411 additions and 331 deletions

View file

@ -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;
}

View file

@ -15,6 +15,7 @@ include_directories(
spec2def(stobject.dll stobject.spec)
add_library(stobject SHARED
csystray.cpp
stobject.cpp
stobject.rc
volume.cpp

View file

@ -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 <gigaherz@gmail.com>
*/
#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;
}

View file

@ -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 <gigaherz@gmail.com>
*/
#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<CSysTray, &CLSID_SysTray>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public CWindowImpl<CSysTray, CWindow, CMessageWndClass>,
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()
};

View file

@ -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<CSysTray, &CLSID_SysTray>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public CWindowImpl<CSysTray, CWindow, CMessageWndClass>,
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);

View file

@ -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 <gigaherz@gmail.com>
*/
@ -14,253 +14,21 @@
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);
struct SysTrayIconHandlers_t
{
PFNSTINIT pfnInit;
PFNSTSHUTDOWN pfnShutdown;
PFNSTUPDATE pfnUpdate;
PFNSTMESSAGE pfnMessage;
};
SysTrayIconHandlers_t g_IconHandlers [] = {
{ Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }
};
const int g_NumIcons = _countof(g_IconHandlers);
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;
}
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)
{
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;
}
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SysTray, CSysTray)
END_OBJECT_MAP()
class CShellTrayModule : public CComModule
{
public:
};
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))
{
if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey))
{
if (bRegister)
{
LONG cbGuid = (lstrlenW(strGuid) + 1) * 2;
ret = RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid);
}
else
{
ret = RegDeleteValueW(hKey, lpName);
}
}
}
if (hKey)
RegCloseKey(hKey);
return /*HRESULT_FROM_NT*/(ret); // regsvr32 considers anything != S_OK to be an error
}
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);
void *operator new (size_t, void *buf)
{
@ -273,55 +41,123 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hinstDLL;
DisableThreadLibraryCalls(g_hInstance);
/* HACK - the global constructors don't run, so I placement new them here */
new (&gModule) CShellTrayModule;
new (&g_Module) CShellTrayModule;
new (&_AtlWinModule) CAtlWinModule;
new (&_AtlBaseModule) CAtlBaseModule;
new (&_AtlComModule) CAtlComModule;
g_hInstance = hinstDLL;
DisableThreadLibraryCalls(g_hInstance);
gModule.Init(ObjectMap, g_hInstance, NULL);
g_Module.Init(ObjectMap, g_hInstance, NULL);
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
g_hInstance = NULL;
gModule.Term();
g_Module.Term();
}
return TRUE;
}
static
HRESULT
RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister)
{
const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad";
HRESULT hr = E_FAIL;
OLECHAR strGuid[128];
HKEY hKey = 0;
if (!StringFromGUID2(guidClass, strGuid, _countof(strGuid)))
{
DbgPrint("StringFromGUID2 failed\n");
goto cleanup;
}
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey))
{
DbgPrint("RegOpenKeyExW failed\n");
goto cleanup;
}
if (bRegister)
{
LONG cbGuid = (lstrlenW(strGuid) + 1) * 2;
if (RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid))
{
DbgPrint("RegSetValueExW failed\n");
goto cleanup;
}
}
else
{
if (RegDeleteValueW(hKey, lpName))
{
DbgPrint("RegDeleteValueW failed\n");
goto cleanup;
}
}
hr = S_OK;
cleanup:
if (hKey)
RegCloseKey(hKey);
return hr;
}
STDAPI
DllRegisterServer(void)
{
HRESULT hr;
hr = g_Module.DllRegisterServer(FALSE);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return S_OK;
}
STDAPI
DllUnregisterServer(void)
{
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 S_OK;
}
STDAPI
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
HRESULT hr;
hr = g_Module.DllGetClassObject(rclsid, riid, ppv);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return S_OK;
}
HRESULT
WINAPI
DllCanUnloadNow(void)
{
return gModule.DllCanUnloadNow();
}
STDAPI
DllRegisterServer(void)
{
HRESULT hr = gModule.DllRegisterServer(FALSE);
if (FAILED(hr))
return hr;
return RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE);
}
STDAPI
DllUnregisterServer(void)
{
RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE);
return gModule.DllUnregisterServer(FALSE);
}
STDAPI
DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID *ppv)
{
return gModule.DllGetClassObject(rclsid, riid, ppv);
return g_Module.DllCanUnloadNow();
}

View file

@ -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 <gigaherz@gmail.com>
* PURPOSE: Volume notification icon handler
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
*/
#include "precomp.h"
@ -12,6 +11,8 @@
#include <mmsystem.h>
#include <mmddk.h>
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) &param2);
result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &waveOutId, (DWORD_PTR) &param2);
if (result)
return E_FAIL;