[SHELLUTILS.H]
[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
22 #include <stdio.h>
23 #include <tchar.h>
24
25 #define WIN32_NO_STATUS
26 #define _INC_WINDOWS
27 #define COM_NO_WINDOWS_H
28
29 #define COBJMACROS
30
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winreg.h>
34 #include <wingdi.h>
35 #include <winnls.h>
36 #include <wincon.h>
37 #include <shellapi.h>
38 #include <shlobj.h>
39 #include <shlobj_undoc.h>
40 #include <shlwapi.h>
41 #include <shlguid_undoc.h>
42 #include <uxtheme.h>
43 #include <strsafe.h>
44
45 #include <atlbase.h>
46 #include <atlcom.h>
47 #include <atlwin.h>
48 #include <undocshell.h>
49 #include <undocuser.h>
50
51 #include <shellutils.h>
52
53 #include <wine/debug.h>
54
55 extern "C"
56 {
57 extern HINSTANCE shell32_hInstance;
58
59 HRESULT WINAPI CStartMenu_Constructor(REFIID riid, void **ppv);
60 HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv);
61 HRESULT WINAPI CMenuSite_Constructor(REFIID riid, LPVOID *ppv);
62 HRESULT WINAPI CMenuBand_Constructor(REFIID riid, LPVOID *ppv);
63 HRESULT WINAPI CMergedFolder_Constructor(REFIID riid, LPVOID *ppv);
64 }
65
66 DWORD WINAPI WinList_Init(void)
67 {
68 /* do something here (perhaps we may want to add our own implementation fo win8) */
69 return 0;
70 }
71
72 void *operator new (size_t, void *buf)
73 {
74 return buf;
75 }
76
77 class CRShellModule : public CComModule
78 {
79 public:
80 };
81
82 CRShellModule gModule;
83 CAtlWinModule gWinModule;
84
85 HINSTANCE shell32_hInstance = NULL;
86
87 static LSTATUS inline _RegSetStringValueW(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpStringData)
88 {
89 DWORD dwStringDataLen = lstrlenW(lpStringData);
90
91 return RegSetValueExW(hKey, lpValueName, 0, REG_SZ, (BYTE *) lpStringData, 2 * (dwStringDataLen + 1));
92 }
93
94 static HRESULT RegisterComponent(REFGUID clsid, LPCWSTR szDisplayName)
95 {
96 WCHAR szFilename[MAX_PATH];
97 WCHAR szClsid[MAX_PATH];
98 WCHAR szRoot[MAX_PATH];
99
100 if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
101 return E_FAIL;
102
103 if (!GetModuleFileNameW(shell32_hInstance, szFilename, _countof(szFilename)))
104 return E_FAIL;
105
106 HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
107 if (FAILED(hr))
108 return hr;
109
110 DWORD dwDisposition;
111 HKEY hkRoot;
112 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, NULL, 0, KEY_WRITE, 0, &hkRoot, &dwDisposition) != 0)
113 return E_FAIL;
114
115 HKEY hkServer;
116
117 _RegSetStringValueW(hkRoot, NULL, szDisplayName);
118
119 if (RegCreateKeyExW(hkRoot, L"InprocServer32", 0, NULL, 0, KEY_SET_VALUE, 0, &hkServer, &dwDisposition) != 0)
120 {
121 RegCloseKey(hkRoot);
122 return E_FAIL;
123 }
124
125 _RegSetStringValueW(hkServer, NULL, szFilename);
126 _RegSetStringValueW(hkServer, L"ThreadingModel", L"Both");
127
128 RegCloseKey(hkServer);
129 RegCloseKey(hkRoot);
130 return S_OK;
131 }
132
133 static HRESULT UnregisterComponent(REFGUID clsid)
134 {
135 WCHAR szClsid[MAX_PATH];
136 WCHAR szRoot[MAX_PATH];
137 HKEY hkRoot;
138
139 if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
140 return E_FAIL;
141
142 HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
143 if (FAILED(hr))
144 return hr;
145
146 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, KEY_WRITE, &hkRoot) != 0)
147 return E_FAIL;
148
149 RegDeleteKeyW(hkRoot, L"InprocServer32");
150 RegCloseKey(hkRoot);
151
152 RegDeleteKeyW(HKEY_CLASSES_ROOT, szRoot);
153
154 return S_OK;
155 }
156
157 STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
158 {
159 if (dwReason == DLL_PROCESS_ATTACH)
160 {
161 shell32_hInstance = hInstance;
162
163 gModule.Init(NULL, hInstance, NULL);
164 DisableThreadLibraryCalls(hInstance);
165 }
166 else if (dwReason == DLL_PROCESS_DETACH)
167 {
168 shell32_hInstance = NULL;
169 gModule.Term();
170 }
171 return TRUE;
172 }
173
174 HRESULT
175 WINAPI
176 DllCanUnloadNow(void)
177 {
178 gModule.DllCanUnloadNow();
179 return S_FALSE;
180 }
181
182 STDAPI
183 DllRegisterServer(void)
184 {
185 RegisterComponent(CLSID_StartMenu, L"Shell Start Menu");
186 RegisterComponent(CLSID_MenuDeskBar, L"Shell Menu Desk Bar");
187 RegisterComponent(CLSID_MenuBand, L"Shell Menu Band");
188 RegisterComponent(CLSID_MenuBandSite, L"Shell Menu Band Site");
189 RegisterComponent(CLSID_MergedFolder, L"Merged Shell Folder");
190 RegisterComponent(CLSID_RebarBandSite, L"Shell Rebar Band Site");
191 return S_OK;
192 }
193
194 STDAPI
195 DllUnregisterServer(void)
196 {
197 UnregisterComponent(CLSID_StartMenu);
198 UnregisterComponent(CLSID_MenuDeskBar);
199 UnregisterComponent(CLSID_MenuBand);
200 UnregisterComponent(CLSID_MenuBandSite);
201 UnregisterComponent(CLSID_MergedFolder);
202 UnregisterComponent(CLSID_RebarBandSite);
203 return S_OK;
204 }
205
206 class CRShellClassFactory :
207 public CComObjectRootEx<CComMultiThreadModelNoCS>,
208 public IClassFactory
209 {
210 private:
211 CLSID m_Clsid;
212
213 public:
214 CRShellClassFactory() {}
215 virtual ~CRShellClassFactory() {}
216
217 HRESULT Initialize(REFGUID clsid)
218 {
219 m_Clsid = clsid;
220 return S_OK;
221 }
222
223 /* IClassFactory */
224 virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
225 {
226 *ppvObject = NULL;
227
228 if (IsEqualCLSID(m_Clsid, CLSID_StartMenu))
229 return CStartMenu_Constructor(riid, ppvObject);
230
231 if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
232 return CMenuDeskBar_Constructor(riid, ppvObject);
233
234 if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
235 return CMenuBand_Constructor(riid, ppvObject);
236
237 if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
238 return CMenuSite_Constructor(riid, ppvObject);
239
240 if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
241 return CMergedFolder_Constructor(riid, ppvObject);
242
243 return E_NOINTERFACE;
244 }
245
246 virtual HRESULT WINAPI LockServer(BOOL fLock)
247 {
248 return E_NOTIMPL;
249 }
250
251 BEGIN_COM_MAP(CRShellClassFactory)
252 COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
253 END_COM_MAP()
254 };
255
256 STDAPI
257 DllGetClassObject(
258 REFCLSID rclsid,
259 REFIID riid,
260 LPVOID *ppv)
261 {
262 if (!ppv)
263 return E_INVALIDARG;
264
265 *ppv = NULL;
266
267 return ShellObjectCreatorInit<CRShellClassFactory>(rclsid, riid, ppv);
268 }