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