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