[STOBJECT]
[reactos.git] / dll / win32 / stobject / stobject.cpp
1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll\win32\stobject\stobject.cpp
5 * PURPOSE: COM registration services for STobject.dll
6 * PROGRAMMERS: Robert Naumann
7 David Quintana <gigaherz@gmail.com>
8 */
9
10 #include "precomp.h"
11
12 #include <olectl.h>
13 #include <atlwin.h>
14
15 WINE_DEFAULT_DEBUG_CHANNEL(stobject);
16
17 BEGIN_OBJECT_MAP(ObjectMap)
18 OBJECT_ENTRY(CLSID_SysTray, CSysTray)
19 END_OBJECT_MAP()
20
21 class CShellTrayModule : public CComModule
22 {
23 public:
24 };
25
26 HINSTANCE g_hInstance;
27 CShellTrayModule g_Module;
28 SysTrayIconHandlers_t g_IconHandlers [] = {
29 { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }
30 };
31 const int g_NumIcons = _countof(g_IconHandlers);
32
33 void *operator new (size_t, void *buf)
34 {
35 return buf;
36 }
37
38 BOOL
39 WINAPI
40 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
41 {
42 if (fdwReason == DLL_PROCESS_ATTACH)
43 {
44 g_hInstance = hinstDLL;
45 DisableThreadLibraryCalls(g_hInstance);
46
47 /* HACK - the global constructors don't run, so I placement new them here */
48 new (&g_Module) CShellTrayModule;
49 new (&_AtlWinModule) CAtlWinModule;
50 new (&_AtlBaseModule) CAtlBaseModule;
51 new (&_AtlComModule) CAtlComModule;
52
53 g_Module.Init(ObjectMap, g_hInstance, NULL);
54 }
55 else if (fdwReason == DLL_PROCESS_DETACH)
56 {
57 g_hInstance = NULL;
58 g_Module.Term();
59 }
60 return TRUE;
61 }
62
63 static
64 HRESULT
65 RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister)
66 {
67 const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad";
68
69 HRESULT hr = E_FAIL;
70
71 OLECHAR strGuid[128];
72
73 HKEY hKey = 0;
74
75 if (!StringFromGUID2(guidClass, strGuid, _countof(strGuid)))
76 {
77 DbgPrint("StringFromGUID2 failed\n");
78 goto cleanup;
79 }
80
81 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey))
82 {
83 DbgPrint("RegOpenKeyExW failed\n");
84 goto cleanup;
85 }
86
87 if (bRegister)
88 {
89 LONG cbGuid = (lstrlenW(strGuid) + 1) * 2;
90 if (RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid))
91 {
92 DbgPrint("RegSetValueExW failed\n");
93 goto cleanup;
94 }
95 }
96 else
97 {
98 if (RegDeleteValueW(hKey, lpName))
99 {
100 DbgPrint("RegDeleteValueW failed\n");
101 goto cleanup;
102 }
103 }
104
105 hr = S_OK;
106
107 cleanup:
108 if (hKey)
109 RegCloseKey(hKey);
110
111 return hr;
112 }
113
114 STDAPI
115 DllRegisterServer(void)
116 {
117 HRESULT hr;
118
119 hr = g_Module.DllRegisterServer(FALSE);
120 if (FAILED_UNEXPECTEDLY(hr))
121 return hr;
122
123 hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE);
124 if (FAILED_UNEXPECTEDLY(hr))
125 return hr;
126
127 return S_OK;
128 }
129
130 STDAPI
131 DllUnregisterServer(void)
132 {
133 HRESULT hr;
134
135 hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE);
136 if (FAILED_UNEXPECTEDLY(hr))
137 return hr;
138
139 hr = g_Module.DllUnregisterServer(FALSE);
140 if (FAILED_UNEXPECTEDLY(hr))
141 return hr;
142
143 return S_OK;
144 }
145
146 STDAPI
147 DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
148 {
149 HRESULT hr;
150
151 hr = g_Module.DllGetClassObject(rclsid, riid, ppv);
152 if (FAILED_UNEXPECTEDLY(hr))
153 return hr;
154
155 return S_OK;
156 }
157
158 HRESULT
159 WINAPI
160 DllCanUnloadNow(void)
161 {
162 return g_Module.DllCanUnloadNow();
163 }