Reactos
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
23static 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
32static 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
40static 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
48HRESULT 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
128cleanup:
129 RegCloseKey(hkey);
130 *phdpa = NULL;
131 ShutdownShellServices(hdpa);
132 return hr;
133}
134
135HRESULT 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}