a08eded842e5afee502524dfab340ddccc32ed53
[reactos.git] / reactos / base / shell / rshell / misc.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2014 Giannis Adamopoulos
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "shellmenu.h"
22
23 DWORD WINAPI WinList_Init(void)
24 {
25 /* do something here (perhaps we may want to add our own implementation fo win8) */
26 return 0;
27 }
28
29 void *operator new (size_t, void *buf)
30 {
31 return buf;
32 }
33
34 class CRShellModule : public CComModule
35 {
36 public:
37 };
38
39 CRShellModule gModule;
40 CAtlWinModule gWinModule;
41
42 HINSTANCE g_hRShell;
43
44 static LSTATUS inline _RegSetStringValueW(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpStringData)
45 {
46 DWORD dwStringDataLen = lstrlenW(lpStringData);
47
48 return RegSetValueExW(hKey, lpValueName, 0, REG_SZ, (BYTE *) lpStringData, 2 * (dwStringDataLen + 1));
49 }
50
51 static HRESULT RegisterComponent(REFGUID clsid, LPCWSTR szDisplayName)
52 {
53 WCHAR szFilename[MAX_PATH];
54 WCHAR szClsid[MAX_PATH];
55 WCHAR szRoot[MAX_PATH];
56
57 if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
58 return E_FAIL;
59
60 if (!GetModuleFileNameW(g_hRShell, szFilename, _countof(szFilename)))
61 return E_FAIL;
62
63 HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
64 if (FAILED(hr))
65 return hr;
66
67 DWORD dwDisposition;
68 HKEY hkRoot;
69 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, NULL, 0, KEY_WRITE, 0, &hkRoot, &dwDisposition) != 0)
70 return E_FAIL;
71
72 HKEY hkServer;
73
74 _RegSetStringValueW(hkRoot, NULL, szDisplayName);
75
76 if (RegCreateKeyExW(hkRoot, L"InprocServer32", 0, NULL, 0, KEY_SET_VALUE, 0, &hkServer, &dwDisposition) != 0)
77 {
78 RegCloseKey(hkRoot);
79 return E_FAIL;
80 }
81
82 _RegSetStringValueW(hkServer, NULL, szFilename);
83 _RegSetStringValueW(hkServer, L"ThreadingModel", L"Both");
84
85 RegCloseKey(hkServer);
86 RegCloseKey(hkRoot);
87 return S_OK;
88 }
89
90 static HRESULT UnregisterComponent(REFGUID clsid)
91 {
92 WCHAR szClsid[MAX_PATH];
93 WCHAR szRoot[MAX_PATH];
94 HKEY hkRoot;
95
96 if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
97 return E_FAIL;
98
99 HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
100 if (FAILED(hr))
101 return hr;
102
103 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, KEY_WRITE, &hkRoot) != 0)
104 return E_FAIL;
105
106 RegDeleteKeyW(hkRoot, L"InprocServer32");
107 RegCloseKey(hkRoot);
108
109 RegDeleteKeyW(HKEY_CLASSES_ROOT, szRoot);
110
111 return S_OK;
112 }
113
114 STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
115 {
116 if (dwReason == DLL_PROCESS_ATTACH)
117 {
118 g_hRShell = hInstance;
119
120 /* HACK - the global constructors don't run, so I placement new them here */
121 new (&gModule) CRShellModule;
122 new (&gWinModule) CAtlWinModule;
123 new (&_AtlBaseModule) CAtlBaseModule;
124 new (&_AtlComModule) CAtlComModule;
125
126 gModule.Init(NULL, hInstance, NULL);
127 DisableThreadLibraryCalls(hInstance);
128 }
129 else if (dwReason == DLL_PROCESS_DETACH)
130 {
131 gModule.Term();
132 }
133 return TRUE;
134 }
135
136 HRESULT
137 WINAPI
138 DllCanUnloadNow(void)
139 {
140 gModule.DllCanUnloadNow();
141 return S_FALSE;
142 }
143
144 STDAPI
145 DllRegisterServer(void)
146 {
147 RegisterComponent(CLSID_StartMenu, L"Shell Start Menu");
148 RegisterComponent(CLSID_MenuDeskBar, L"Shell Menu Desk Bar");
149 RegisterComponent(CLSID_MenuBand, L"Shell Menu Band");
150 RegisterComponent(CLSID_MenuBandSite, L"Shell Menu Band Site");
151 RegisterComponent(CLSID_MergedFolder, L"Merged Shell Folder");
152 RegisterComponent(CLSID_RebarBandSite, L"Shell Rebar Band Site");
153 return S_OK;
154 }
155
156 STDAPI
157 DllUnregisterServer(void)
158 {
159 UnregisterComponent(CLSID_StartMenu);
160 UnregisterComponent(CLSID_MenuDeskBar);
161 UnregisterComponent(CLSID_MenuBand);
162 UnregisterComponent(CLSID_MenuBandSite);
163 UnregisterComponent(CLSID_MergedFolder);
164 UnregisterComponent(CLSID_RebarBandSite);
165 return S_OK;
166 }
167
168 class CRShellClassFactory :
169 public CComObjectRootEx<CComMultiThreadModelNoCS>,
170 public IClassFactory
171 {
172 private:
173 CLSID m_Clsid;
174
175 public:
176 CRShellClassFactory() {}
177 virtual ~CRShellClassFactory() {}
178
179 HRESULT Initialize(REFGUID clsid)
180 {
181 m_Clsid = clsid;
182 return S_OK;
183 }
184
185 /* IClassFactory */
186 virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
187 {
188 *ppvObject = NULL;
189
190 if (IsEqualCLSID(m_Clsid, CLSID_StartMenu))
191 return CStartMenu_Constructor(riid, ppvObject);
192
193 if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
194 return CMenuDeskBar_Constructor(riid, ppvObject);
195
196 if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
197 return CMenuBand_Constructor(riid, ppvObject);
198
199 if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
200 return CMenuSite_Constructor(riid, ppvObject);
201
202 if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
203 return CMergedFolder_Constructor(riid, ppvObject);
204
205 if (IsEqualCLSID(m_Clsid, CLSID_RebarBandSite))
206 return CBandSite_Constructor(riid, ppvObject);
207
208 return E_NOINTERFACE;
209 }
210
211 virtual HRESULT WINAPI LockServer(BOOL fLock)
212 {
213 return E_NOTIMPL;
214 }
215
216 BEGIN_COM_MAP(CRShellClassFactory)
217 COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
218 END_COM_MAP()
219 };
220
221 STDAPI
222 DllGetClassObject(
223 REFCLSID rclsid,
224 REFIID riid,
225 LPVOID *ppv)
226 {
227 if (!ppv)
228 return E_INVALIDARG;
229
230 *ppv = NULL;
231
232 return ShellObjectCreatorInit<CRShellClassFactory>(rclsid, riid, ppv);
233 }