reactos/base/shell/explorer/shellservice.cpp
2020-09-08 21:55:45 +02:00

141 lines
3.8 KiB
C++

/*
* ReactOS Explorer
*
* Copyright 2014 - David Quintana
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
static int CALLBACK InitializeAllCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
HRESULT * phr = reinterpret_cast<HRESULT *>(pData);
TRACE("Initializing SSO %p\n", pOct);
*phr = pOct->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
return SUCCEEDED(*phr);
}
static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
TRACE("Shutting down SSO %p\n", pOct);
pOct->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
return TRUE;
}
static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
TRACE("Releasing SSO %p\n", pOct);
pOct->Release();
return TRUE;
}
HRESULT InitShellServices(HDPA * phdpa)
{
IOleCommandTarget * pOct;
HKEY hkey;
CLSID clsid;
WCHAR name[MAX_PATH];
WCHAR value[MAX_PATH];
DWORD type;
LONG ret;
HDPA hdpa;
HRESULT hr = S_OK;
int count = 0;
*phdpa = NULL;
TRACE("Enumerating Shell Service Object GUIDs...\n");
if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad",
&hkey))
{
ERR("RegOpenKeyW failed.\n");
return HRESULT_FROM_WIN32(GetLastError());
}
hdpa = DPA_Create(5);
/* Enumerate */
do
{
DWORD name_len = MAX_PATH;
DWORD value_len = sizeof(value); /* byte count! */
ret = RegEnumValueW(hkey, count, name, &name_len, 0, &type, (LPBYTE) &value, &value_len);
if (ret)
break;
if (type != REG_SZ)
{
WARN("Value type was not REG_SZ.\n");
continue;
}
hr = CLSIDFromString(value, &clsid);
if (FAILED_UNEXPECTEDLY(hr))
{
ERR("CLSIDFromString failed %08x.\n", hr);
goto cleanup;
}
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &pOct));
if (FAILED_UNEXPECTEDLY(hr))
{
ERR("CoCreateInstance failed %08x.\n", hr);
goto cleanup;
}
DPA_AppendPtr(hdpa, pOct);
count++;
}
while (1);
if (ret != ERROR_NO_MORE_ITEMS)
{
ERR("RegEnumValueW failed %08x.\n", ret);
hr = HRESULT_FROM_WIN32(GetLastError());
goto cleanup;
}
/* Initialize */
DPA_EnumCallback(hdpa, InitializeAllCallback, &hr);
if (FAILED_UNEXPECTEDLY(hr))
goto cleanup;
RegCloseKey(hkey);
*phdpa = hdpa;
return count > 0 ? S_OK : S_FALSE;
cleanup:
RegCloseKey(hkey);
*phdpa = NULL;
ShutdownShellServices(hdpa);
return hr;
}
HRESULT ShutdownShellServices(HDPA hdpa)
{
DPA_EnumCallback(hdpa, ShutdownAllCallback, NULL);
DPA_EnumCallback(hdpa, DeleteAllEnumCallback, NULL);
DPA_Destroy(hdpa);
return S_OK;
}