[CSCRIPT][WSCRIPT] Sync with Wine Staging 3.17. CORE-15127
[reactos.git] / base / shell / explorer / shellservice.cpp
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 RegCloseKey(hkey);
119
120 /* Initialize */
121 DPA_EnumCallback(hdpa, InitializeAllCallback, &hr);
122 if (FAILED_UNEXPECTEDLY(hr))
123 goto cleanup;
124
125 *phdpa = hdpa;
126 return count > 0 ? S_OK : S_FALSE;
127
128 cleanup:
129 *phdpa = NULL;
130 ShutdownShellServices(hdpa);
131 return hr;
132 }
133
134 HRESULT ShutdownShellServices(HDPA hdpa)
135 {
136 DPA_EnumCallback(hdpa, ShutdownAllCallback, NULL);
137 DPA_EnumCallback(hdpa, DeleteAllEnumCallback, NULL);
138 DPA_Destroy(hdpa);
139 return S_OK;
140 }