1 /* 2 * ReactOS Explorer 3 * 4 * Copyright 2014 - David Quintana 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 "precomp.h" 22 23 static int CALLBACK InitializeAllCallback(void* pItem, void* pData) 24 { 25 IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem); 26 HRESULT * phr = reinterpret_cast<HRESULT *>(pData); 27 TRACE("Initializing SSO %p\n", pOct); 28 *phr = pOct->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL); 29 return SUCCEEDED(*phr); 30 } 31 32 static int CALLBACK ShutdownAllCallback(void* pItem, void* pData) 33 { 34 IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem); 35 TRACE("Shutting down SSO %p\n", pOct); 36 pOct->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL); 37 return TRUE; 38 } 39 40 static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData) 41 { 42 IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem); 43 TRACE("Releasing SSO %p\n", pOct); 44 pOct->Release(); 45 return TRUE; 46 } 47 48 HRESULT InitShellServices(HDPA * phdpa) 49 { 50 IOleCommandTarget * pOct; 51 HKEY hkey; 52 CLSID clsid; 53 WCHAR name[MAX_PATH]; 54 WCHAR value[MAX_PATH]; 55 DWORD type; 56 LONG ret; 57 HDPA hdpa; 58 HRESULT hr = S_OK; 59 int count = 0; 60 61 *phdpa = NULL; 62 63 TRACE("Enumerating Shell Service Object GUIDs...\n"); 64 65 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, 66 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad", 67 &hkey)) 68 { 69 ERR("RegOpenKeyW failed.\n"); 70 return HRESULT_FROM_WIN32(GetLastError()); 71 } 72 73 hdpa = DPA_Create(5); 74 75 /* Enumerate */ 76 do 77 { 78 DWORD name_len = MAX_PATH; 79 DWORD value_len = sizeof(value); /* byte count! */ 80 81 ret = RegEnumValueW(hkey, count, name, &name_len, 0, &type, (LPBYTE) &value, &value_len); 82 if (ret) 83 break; 84 85 if (type != REG_SZ) 86 { 87 WARN("Value type was not REG_SZ.\n"); 88 continue; 89 } 90 91 hr = CLSIDFromString(value, &clsid); 92 if (FAILED_UNEXPECTEDLY(hr)) 93 { 94 ERR("CLSIDFromString failed %08x.\n", hr); 95 goto cleanup; 96 } 97 98 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &pOct)); 99 if (FAILED_UNEXPECTEDLY(hr)) 100 { 101 ERR("CoCreateInstance failed %08x.\n", hr); 102 goto cleanup; 103 } 104 105 DPA_AppendPtr(hdpa, pOct); 106 107 count++; 108 } 109 while (1); 110 111 if (ret != ERROR_NO_MORE_ITEMS) 112 { 113 ERR("RegEnumValueW failed %08x.\n", ret); 114 hr = HRESULT_FROM_WIN32(GetLastError()); 115 goto cleanup; 116 } 117 118 /* Initialize */ 119 DPA_EnumCallback(hdpa, InitializeAllCallback, &hr); 120 if (FAILED_UNEXPECTEDLY(hr)) 121 goto cleanup; 122 123 RegCloseKey(hkey); 124 125 *phdpa = hdpa; 126 return count > 0 ? S_OK : S_FALSE; 127 128 cleanup: 129 RegCloseKey(hkey); 130 *phdpa = NULL; 131 ShutdownShellServices(hdpa); 132 return hr; 133 } 134 135 HRESULT ShutdownShellServices(HDPA hdpa) 136 { 137 DPA_EnumCallback(hdpa, ShutdownAllCallback, NULL); 138 DPA_EnumCallback(hdpa, DeleteAllEnumCallback, NULL); 139 DPA_Destroy(hdpa); 140 return S_OK; 141 } 142