xref: /reactos/base/shell/rshell/misc.cpp (revision ea289516)
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 <CQuickLaunchBand.h>
54 
55 #include <wine/debug.h>
56 
57 extern "C"
58 {
59 extern HINSTANCE shell32_hInstance;
60 
61 HRESULT WINAPI RSHELL_CStartMenu_CreateInstance(REFIID riid, void **ppv);
62 HRESULT WINAPI RSHELL_CMenuDeskBar_CreateInstance(REFIID riid, LPVOID *ppv);
63 HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv);
64 HRESULT WINAPI RSHELL_CMenuBand_CreateInstance(REFIID riid, LPVOID *ppv);
65 HRESULT WINAPI RSHELL_CMergedFolder_CreateInstance(REFIID riid, LPVOID *ppv);
66 }
67 
68 DWORD WINAPI WinList_Init(void)
69 {
70     /* do something here (perhaps we may want to add our own implementation fo win8) */
71     return 0;
72 }
73 
74 class CRShellModule : public CComModule
75 {
76 public:
77 };
78 
79 CRShellModule gModule;
80 CAtlWinModule gWinModule;
81 
82 HINSTANCE shell32_hInstance = NULL;
83 
84 static LSTATUS inline _RegSetStringValueW(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpStringData)
85 {
86     DWORD dwStringDataLen = lstrlenW(lpStringData);
87 
88     return RegSetValueExW(hKey, lpValueName, 0, REG_SZ, (BYTE *) lpStringData, 2 * (dwStringDataLen + 1));
89 }
90 
91 static HRESULT RegisterComponent(REFGUID clsid, LPCWSTR szDisplayName)
92 {
93     WCHAR szFilename[MAX_PATH];
94     WCHAR szClsid[MAX_PATH];
95     WCHAR szRoot[MAX_PATH];
96 
97     if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
98         return E_FAIL;
99 
100     if (!GetModuleFileNameW(shell32_hInstance, szFilename, _countof(szFilename)))
101         return E_FAIL;
102 
103     HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
104     if (FAILED(hr))
105         return hr;
106 
107     DWORD dwDisposition;
108     HKEY hkRoot;
109     if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, NULL, 0, KEY_WRITE, 0, &hkRoot, &dwDisposition) != 0)
110         return E_FAIL;
111 
112     HKEY hkServer;
113 
114     _RegSetStringValueW(hkRoot, NULL, szDisplayName);
115 
116     if (RegCreateKeyExW(hkRoot, L"InprocServer32", 0, NULL, 0, KEY_SET_VALUE, 0, &hkServer, &dwDisposition) != 0)
117     {
118         RegCloseKey(hkRoot);
119         return E_FAIL;
120     }
121 
122     _RegSetStringValueW(hkServer, NULL, szFilename);
123     _RegSetStringValueW(hkServer, L"ThreadingModel", L"Both");
124 
125     RegCloseKey(hkServer);
126     RegCloseKey(hkRoot);
127     return S_OK;
128 }
129 
130 static HRESULT UnregisterComponent(REFGUID clsid)
131 {
132     WCHAR szClsid[MAX_PATH];
133     WCHAR szRoot[MAX_PATH];
134     HKEY hkRoot;
135 
136     if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
137         return E_FAIL;
138 
139     HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
140     if (FAILED(hr))
141         return hr;
142 
143     if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, KEY_WRITE, &hkRoot) != 0)
144         return E_FAIL;
145 
146     RegDeleteKeyW(hkRoot, L"InprocServer32");
147     RegCloseKey(hkRoot);
148 
149     RegDeleteKeyW(HKEY_CLASSES_ROOT, szRoot);
150 
151     return S_OK;
152 }
153 
154 STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
155 {
156     if (dwReason == DLL_PROCESS_ATTACH)
157     {
158         shell32_hInstance = hInstance;
159 
160         gModule.Init(NULL, hInstance, NULL);
161         DisableThreadLibraryCalls(hInstance);
162     }
163     else if (dwReason == DLL_PROCESS_DETACH)
164     {
165         shell32_hInstance = NULL;
166         gModule.Term();
167     }
168     return TRUE;
169 }
170 
171 HRESULT
172 WINAPI
173 DllCanUnloadNow(void)
174 {
175     gModule.DllCanUnloadNow();
176     return S_FALSE;
177 }
178 
179 STDAPI
180 DllRegisterServer(void)
181 {
182 #if 0
183     RegisterComponent(CLSID_StartMenu, L"Shell Start Menu");
184     RegisterComponent(CLSID_MenuDeskBar, L"Shell Menu Desk Bar");
185     RegisterComponent(CLSID_MenuBand, L"Shell Menu Band");
186     RegisterComponent(CLSID_MenuBandSite, L"Shell Menu Band Site");
187     RegisterComponent(CLSID_MergedFolder, L"Merged Shell Folder");
188     RegisterComponent(CLSID_RebarBandSite, L"Shell Rebar Band Site");
189 #endif
190     RegisterComponent(CLSID_QuickLaunchBand, L"Quick Launch");
191     RegisterComCat();
192     return S_OK;
193 }
194 
195 STDAPI
196 DllUnregisterServer(void)
197 {
198 #if 0
199     UnregisterComponent(CLSID_StartMenu);
200     UnregisterComponent(CLSID_MenuDeskBar);
201     UnregisterComponent(CLSID_MenuBand);
202     UnregisterComponent(CLSID_MenuBandSite);
203     UnregisterComponent(CLSID_MergedFolder);
204     UnregisterComponent(CLSID_RebarBandSite);
205 #endif
206     UnregisterComponent(CLSID_QuickLaunchBand);
207     UnregisterComCat();
208     return S_OK;
209 }
210 
211 class CRShellClassFactory :
212     public CComObjectRootEx<CComMultiThreadModelNoCS>,
213     public IClassFactory
214 {
215 private:
216     CLSID m_Clsid;
217 
218 public:
219     CRShellClassFactory() {}
220     virtual ~CRShellClassFactory() {}
221 
222     HRESULT Initialize(REFGUID clsid)
223     {
224         m_Clsid = clsid;
225         return S_OK;
226     }
227 
228     /* IClassFactory */
229     virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
230     {
231         *ppvObject = NULL;
232 
233         if (IsEqualCLSID(m_Clsid, CLSID_StartMenu))
234             return RSHELL_CStartMenu_CreateInstance(riid, ppvObject);
235 
236         if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
237             return RSHELL_CMenuDeskBar_CreateInstance(riid, ppvObject);
238 
239         if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
240             return RSHELL_CMenuBand_CreateInstance(riid, ppvObject);
241 
242         if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
243             return RSHELL_CMenuSite_CreateInstance(riid, ppvObject);
244 
245         if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
246             return RSHELL_CMergedFolder_CreateInstance(riid, ppvObject);
247 
248         if (IsEqualCLSID(m_Clsid, CLSID_QuickLaunchBand))
249             return ShellObjectCreator<CQuickLaunchBand>(riid, ppvObject);
250 
251         return E_NOINTERFACE;
252     }
253 
254     virtual HRESULT WINAPI LockServer(BOOL fLock)
255     {
256         return E_NOTIMPL;
257     }
258 
259     BEGIN_COM_MAP(CRShellClassFactory)
260         COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
261     END_COM_MAP()
262 };
263 
264 STDAPI
265 DllGetClassObject(
266 REFCLSID rclsid,
267 REFIID riid,
268 LPVOID *ppv)
269 {
270     if (!ppv)
271         return E_INVALIDARG;
272 
273     *ppv = NULL;
274 
275     return ShellObjectCreatorInit<CRShellClassFactory>(rclsid, riid, ppv);
276 }
277 
278 VOID WINAPI ShowFolderOptionsDialog(UINT Page, BOOL Async)
279 {
280     char buf[MAX_PATH];
281     wsprintfA(buf, "rundll32.exe shell32.dll,Options_RunDLL %u", Page);
282     WinExec(buf, SW_SHOW);
283 }
284 
285