21ac77978261764b5e756aaa082d6892dc701b2b
[reactos.git] / base / shell / explorer-new / shellservice.c
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 extern HRESULT InitShellServices(HDPA * phdpa);
24 extern HRESULT ShutdownShellServices(HDPA hdpa);
25
26 static int CALLBACK InitializeAllCallback(void* pItem, void* pData)
27 {
28 IOleCommandTarget * pOct = pItem;
29 HRESULT * phr = pData;
30 DbgPrint("Initializing SSO %p\n", pOct);
31 *phr = IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
32 return SUCCEEDED(*phr);
33 }
34
35 static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
36 {
37 IOleCommandTarget * pOct = pItem;
38 DbgPrint("Shutting down SSO %p\n", pOct);
39 IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
40 return TRUE;
41 }
42
43 static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData)
44 {
45 IOleCommandTarget * pOct = pItem;
46 DbgPrint("Releasing SSO %p\n", pOct);
47 IUnknown_Release(pOct);
48 return TRUE;
49 }
50
51 HRESULT InitShellServices(HDPA * phdpa)
52 {
53 IOleCommandTarget * pOct;
54 HKEY hkey;
55 CLSID clsid;
56 WCHAR name[MAX_PATH];
57 WCHAR value[MAX_PATH];
58 DWORD type;
59 LONG ret;
60 HDPA hdpa;
61 HRESULT hr = S_OK;
62 int count = 0;
63
64 hdpa = DPA_Create(5);
65
66 DbgPrint("Enumerating Shell Service Ojbect GUIDs...\n");
67
68 if (RegOpenKey(HKEY_LOCAL_MACHINE,
69 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad",
70 &hkey))
71 {
72 DbgPrint("ERROR: RegOpenKey failed.\n");
73 return HRESULT_FROM_WIN32(GetLastError());
74 }
75
76 /* Enumerate */
77 do
78 {
79 DWORD name_len = MAX_PATH;
80 DWORD value_len = sizeof(value); /* byte count! */
81
82 ret = RegEnumValueW(hkey, count, name, &name_len, 0, &type, (LPBYTE) &value, &value_len);
83 if (ret)
84 break;
85
86 if (type != REG_SZ)
87 {
88 DbgPrint("WARNING: Value type was not REG_SZ.\n");
89 continue;
90 }
91
92 hr = CLSIDFromString(value, &clsid);
93 if (FAILED(hr))
94 {
95 DbgPrint("ERROR: CLSIDFromString failed %08x.\n", hr);
96 goto cleanup;
97 }
98
99 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (VOID**) &pOct);
100 if (FAILED(hr))
101 {
102 DbgPrint("ERROR: CoCreateInstance failed %08x.\n", hr);
103 goto cleanup;
104 }
105
106 DPA_AppendPtr(hdpa, pOct);
107
108 count++;
109 }
110 while (1);
111
112 if (ret != ERROR_NO_MORE_ITEMS)
113 {
114 DbgPrint("ERROR: RegEnumValueW failed %08x.\n", ret);
115 hr = HRESULT_FROM_WIN32(GetLastError());
116 goto cleanup;
117 }
118
119 RegCloseKey(hkey);
120
121 /* Initialize */
122 DPA_EnumCallback(hdpa, InitializeAllCallback, &hr);
123 if (FAILED(hr))
124 goto cleanup;
125
126 *phdpa = hdpa;
127 return count > 0 ? S_OK : S_FALSE;
128
129 cleanup:
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 }