diff --git a/base/shell/rshell/CStartMenu.cpp b/base/shell/rshell/CStartMenu.cpp index 649086beb33..dfefa3fad52 100644 --- a/base/shell/rshell/CStartMenu.cpp +++ b/base/shell/rshell/CStartMenu.cpp @@ -412,6 +412,8 @@ CStartMenu_Constructor(REFIID riid, void **ppv) return hr; hr = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidlProgramsAbsolute); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; pidlPrograms = ILClone(ILFindLastID(pidlProgramsAbsolute)); ILFree(pidlProgramsAbsolute); diff --git a/dll/win32/CMakeLists.txt b/dll/win32/CMakeLists.txt index 3355a269c2d..ade507f12f4 100644 --- a/dll/win32/CMakeLists.txt +++ b/dll/win32/CMakeLists.txt @@ -193,6 +193,7 @@ add_subdirectory(srclient) add_subdirectory(stdole2.tlb) add_subdirectory(stdole32.tlb) add_subdirectory(sti) +add_subdirectory(stobject) add_subdirectory(sxs) add_subdirectory(syssetup) add_subdirectory(t2embed) diff --git a/dll/win32/stobject/CMakeLists.txt b/dll/win32/stobject/CMakeLists.txt new file mode 100644 index 00000000000..5b0f24b0734 --- /dev/null +++ b/dll/win32/stobject/CMakeLists.txt @@ -0,0 +1,36 @@ + +project(SHELL) + +set_cpp(WITH_RUNTIME) + +if(NOT MSVC) + # HACK: this should be enabled globally! + add_compile_flags_language("-std=c++11" "CXX") +endif() + +include_directories( + ${REACTOS_SOURCE_DIR}/lib/atl + ${REACTOS_SOURCE_DIR}) + +spec2def(stobject.dll stobject.spec) + +add_library(stobject SHARED + stobject.cpp + stobject.rc + ${CMAKE_CURRENT_BINARY_DIR}/stobject.def) + +set_module_type(stobject win32dll UNICODE) +target_link_libraries(stobject uuid wine atlnew) + +add_importlibs(stobject + advapi32 + ole32 + gdi32 + user32 + comctl32 + shlwapi + msvcrt + kernel32 + ntdll) + +add_cd_file(TARGET stobject DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/stobject/lang/de-DE.rc b/dll/win32/stobject/lang/de-DE.rc new file mode 100644 index 00000000000..0e573487217 --- /dev/null +++ b/dll/win32/stobject/lang/de-DE.rc @@ -0,0 +1,2 @@ +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL + diff --git a/dll/win32/stobject/lang/en-US.rc b/dll/win32/stobject/lang/en-US.rc new file mode 100644 index 00000000000..53b8ea9b4de --- /dev/null +++ b/dll/win32/stobject/lang/en-US.rc @@ -0,0 +1 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/dll/win32/stobject/precomp.h b/dll/win32/stobject/precomp.h new file mode 100644 index 00000000000..3f14fd1eb0e --- /dev/null +++ b/dll/win32/stobject/precomp.h @@ -0,0 +1,75 @@ +#pragma once + +#define WIN32_NO_STATUS +#include +#include + +#define COBJMACROS +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H +#define NTOS_MODE_USER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern const GUID CLSID_SysTray; + +#include "resource.h" + +static __inline ULONG +Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...) +{ + char szMsg[512]; + char *szMsgStart; + const char *fname; + va_list vl; + ULONG uRet; + + fname = strrchr(filename, '\\'); + if (fname == NULL) + { + fname = strrchr(filename, '/'); + } + + if (fname == NULL) + fname = filename; + else + fname++; + + szMsgStart = szMsg + sprintf(szMsg, "[%10lu] %s:%d: ", GetTickCount(), fname, line); + + va_start(vl, lpFormat); + uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl); + va_end(vl); + + OutputDebugStringA(szMsg); + + return uRet; +} + +#define DbgPrint(fmt, ...) \ + Win32DbgPrint(__FILE__, __LINE__, fmt, ##__VA_ARGS__) + +#if 1 +#define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (DbgPrint("Unexpected failure %08x.\n", hr), TRUE)) +#else +#define FAILED_UNEXPECTEDLY(hr) FAILED(hr) +#endif + diff --git a/dll/win32/stobject/resource.h b/dll/win32/stobject/resource.h new file mode 100644 index 00000000000..242929678c7 --- /dev/null +++ b/dll/win32/stobject/resource.h @@ -0,0 +1,8 @@ +#pragma once + +#define IDI_ICON1 200 +#define IDI_ICON2 210 +#define IDI_ICON3 230 +#define IDI_ICON4 231 + +#define IDR_SYSTRAY 11001 diff --git a/dll/win32/stobject/resources/1.ico b/dll/win32/stobject/resources/1.ico new file mode 100644 index 00000000000..9f051006742 Binary files /dev/null and b/dll/win32/stobject/resources/1.ico differ diff --git a/dll/win32/stobject/resources/2.ico b/dll/win32/stobject/resources/2.ico new file mode 100644 index 00000000000..d2c4f857187 Binary files /dev/null and b/dll/win32/stobject/resources/2.ico differ diff --git a/dll/win32/stobject/resources/3.ico b/dll/win32/stobject/resources/3.ico new file mode 100644 index 00000000000..3aba11dfd88 Binary files /dev/null and b/dll/win32/stobject/resources/3.ico differ diff --git a/dll/win32/stobject/resources/4.ico b/dll/win32/stobject/resources/4.ico new file mode 100644 index 00000000000..fdde85a086b Binary files /dev/null and b/dll/win32/stobject/resources/4.ico differ diff --git a/dll/win32/stobject/resources/rgs/systray.rgs b/dll/win32/stobject/resources/rgs/systray.rgs new file mode 100644 index 00000000000..2b70f2e2bc7 --- /dev/null +++ b/dll/win32/stobject/resources/rgs/systray.rgs @@ -0,0 +1,13 @@ +HKCR +{ + NoRemove CLSID + { + ForceRemove {35CEC8A3-2BE6-11D2-8773-92E220524153} = s 'SysTray' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Both' + } + } + } +} diff --git a/dll/win32/stobject/stobject.cpp b/dll/win32/stobject/stobject.cpp new file mode 100644 index 00000000000..5453652e6e3 --- /dev/null +++ b/dll/win32/stobject/stobject.cpp @@ -0,0 +1,165 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll\win32\stobject\stobject.c + * PURPOSE: Systray shell service object + * PROGRAMMERS: Copyright 2014 Robert Naumann + */ + +#include "precomp.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(stobject); + +const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } }; + +class CShellTrayModule : public CComModule +{ +public: +}; + +class CSysTray : + public CComCoClass, + public CComObjectRootEx, + public IOleCommandTarget +{ + // TODO: keep icon handlers here + +public: + CSysTray() {} + virtual ~CSysTray() {} + + // *** IOleCommandTarget methods *** + virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) + { + UNIMPLEMENTED; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE 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 + DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n"); + break; + case OLECMDID_SAVE: // shutdown + DbgPrint("CSysTray Shutdown TODO: Shutdown.\n"); + break; + } + return S_OK; + } + + 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() +}; + + +BEGIN_OBJECT_MAP(ObjectMap) + OBJECT_ENTRY(CLSID_SysTray, CSysTray) +END_OBJECT_MAP() + +CShellTrayModule gModule; + +HINSTANCE g_hInstance; + +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 + +} + +void *operator new (size_t, void *buf) +{ + return buf; +} + +BOOL +WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) +{ + 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; + + g_hInstance = hinstDLL; + DisableThreadLibraryCalls(g_hInstance); + + gModule.Init(ObjectMap, g_hInstance, NULL); + } + else if (fdwReason == DLL_PROCESS_DETACH) + { + g_hInstance = NULL; + gModule.Term(); + } + return TRUE; +} + +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); +} diff --git a/dll/win32/stobject/stobject.rc b/dll/win32/stobject/stobject.rc new file mode 100644 index 00000000000..e47b00063dd --- /dev/null +++ b/dll/win32/stobject/stobject.rc @@ -0,0 +1,26 @@ +#include +#include +#include + +#include "resource.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +IDI_ICON1 ICON "resources/1.ico" +IDI_ICON2 ICON "resources/2.ico" +IDI_ICON3 ICON "resources/3.ico" +IDI_ICON4 ICON "resources/4.ico" + +IDR_SYSTRAY REGISTRY "resources/rgs/systray.rgs" + +/* UTF-8 */ +#pragma code_page(65001) + +#if 0 +#ifdef LANGUAGE_DE_DE + #include "lang/de-DE.rc" +#endif +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif +#endif diff --git a/dll/win32/stobject/stobject.spec b/dll/win32/stobject/stobject.spec new file mode 100644 index 00000000000..069be116271 --- /dev/null +++ b/dll/win32/stobject/stobject.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() \ No newline at end of file