[SHELL32] Sync CShellDispatch and family with wine.

Incorporates work from Ivan Rodionov.
CORE-12955
This commit is contained in:
Mark Jansen 2018-04-13 22:59:04 +02:00
parent fd87f0ad87
commit e8dcbcc61d
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
7 changed files with 261 additions and 186 deletions

View file

@ -1,21 +1,8 @@
/*
* Folder implementation
*
* Copyright 2015 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: Folder implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#include "precomp.h"
@ -31,9 +18,10 @@ CFolder::~CFolder()
{
}
void CFolder::Init(LPITEMIDLIST idlist)
HRESULT CFolder::Initialize(LPITEMIDLIST idlist)
{
m_idlist.Attach(idlist);
m_idlist.Attach(ILClone(idlist));
return CShellDispatch_Constructor(IID_PPV_ARG(IShellDispatch, &m_Application));
}
HRESULT CFolder::GetShellFolder(CComPtr<IShellFolder>& psfCurrent)
@ -65,35 +53,39 @@ HRESULT STDMETHODCALLTYPE CFolder::get_Title(BSTR *pbs)
HRESULT STDMETHODCALLTYPE CFolder::get_Application(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
return E_NOTIMPL;
if (!ppid)
return E_INVALIDARG;
*ppid = m_Application;
(*ppid)->AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CFolder::get_Parent(IDispatch **ppid)
{
TRACE("(%p %p)\n", this, ppid);
if (ppid)
*ppid = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFolder::get_ParentFolder(Folder **ppsf)
{
TRACE("(%p, %p)\n", this);
*ppsf = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFolder::Items(FolderItems **ppid)
{
CFolderItems* items = new CComObject<CFolderItems>();
items->AddRef();
HRESULT hr = items->Init(ILClone(m_idlist));
if (FAILED_UNEXPECTEDLY(hr))
{
items->Release();
return hr;
}
*ppid = items;
return S_OK;
/* FolderItems_Constructor */
return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), this, IID_PPV_ARG(FolderItems, ppid));
}
HRESULT STDMETHODCALLTYPE CFolder::ParseName(BSTR bName, FolderItem **ppid)
@ -113,11 +105,10 @@ HRESULT STDMETHODCALLTYPE CFolder::ParseName(BSTR bName, FolderItem **ppid)
if (!SUCCEEDED(hr))
return S_FALSE;
CFolderItem* item = new CComObject<CFolderItem>();
item->AddRef();
item->Init(ILCombine(m_idlist, relativePidl));
*ppid = item;
return S_OK;
CComHeapPtr<ITEMIDLIST> combined;
combined.Attach(ILCombine(m_idlist, relativePidl));
return ShellObjectCreatorInit<CFolderItem>(this, static_cast<LPITEMIDLIST>(combined), IID_PPV_ARG(FolderItem, ppid));
}
HRESULT STDMETHODCALLTYPE CFolder::NewFolder(BSTR bName, VARIANT vOptions)
@ -151,11 +142,8 @@ HRESULT STDMETHODCALLTYPE CFolder::get_Self(FolderItem **ppfi)
TRACE("(%p, %p)\n", this, ppfi);
if (!ppfi)
return E_POINTER;
CFolderItem* item = new CComObject<CFolderItem>();
item->AddRef();
item->Init(ILClone(m_idlist));
*ppfi = item;
return S_OK;
return ShellObjectCreatorInit<CFolderItem>(this, static_cast<LPITEMIDLIST>(m_idlist), IID_PPV_ARG(FolderItem, ppfi));
}
HRESULT STDMETHODCALLTYPE CFolder::get_OfflineStatus(LONG *pul)

View file

@ -1,21 +1,8 @@
/*
* Folder implementation
*
* Copyright 2015 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: Folder implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#ifndef _FOLDER_H_
@ -31,12 +18,13 @@ private:
HRESULT GetShellFolder(CComPtr<IShellFolder>& psfCurrent);
CComHeapPtr<ITEMIDLIST> m_idlist;
CComPtr<IShellDispatch> m_Application;
public:
CFolder();
~CFolder();
void Init(LPITEMIDLIST idlist);
HRESULT Initialize(LPITEMIDLIST idlist);
// *** Folder methods ***
virtual HRESULT STDMETHODCALLTYPE get_Title(BSTR *pbs);

View file

@ -107,7 +107,7 @@ HRESULT CFolderItemVerbs::Init(LPITEMIDLIST idlist)
HRESULT STDMETHODCALLTYPE CFolderItemVerbs::get_Count(LONG *plCount)
{
if (!plCount)
return E_POINTER;
return E_INVALIDARG;
*plCount = m_count;
return S_OK;
}
@ -115,12 +115,20 @@ HRESULT STDMETHODCALLTYPE CFolderItemVerbs::get_Count(LONG *plCount)
HRESULT STDMETHODCALLTYPE CFolderItemVerbs::get_Application(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
if (ppid)
*ppid = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFolderItemVerbs::get_Parent(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
if (ppid)
*ppid = NULL;
return E_NOTIMPL;
}
@ -130,9 +138,8 @@ HRESULT STDMETHODCALLTYPE CFolderItemVerbs::Item(VARIANT indexVar, FolderItemVer
return E_POINTER;
CComVariant var;
VariantCopyInd(&var, &indexVar);
HRESULT hr = VariantChangeType(&var, &var, 0, VT_I4);
HRESULT hr = VariantChangeType(&var, &indexVar, 0, VT_I4);
if (FAILED_UNEXPECTEDLY(hr))
return E_INVALIDARG;
@ -144,7 +151,9 @@ HRESULT STDMETHODCALLTYPE CFolderItemVerbs::Item(VARIANT indexVar, FolderItemVer
BSTR name = NULL;
if(index == m_count)
{
name = SysAllocStringLen(NULL, 0);
}
else
{
MENUITEMINFOW info = { sizeof(info), 0 };

View file

@ -1,21 +1,8 @@
/*
* FolderItem(s) implementation
*
* Copyright 2015,2016 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: FolderItem(s) implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#include "precomp.h"
@ -31,28 +18,49 @@ CFolderItem::~CFolderItem()
{
}
void CFolderItem::Init(LPITEMIDLIST idlist)
HRESULT CFolderItem::Initialize(Folder* folder, LPITEMIDLIST idlist)
{
m_idlist.Attach(idlist);
m_idlist.Attach(ILClone(idlist));
m_Folder = folder;
return S_OK;
}
// *** FolderItem methods ***
HRESULT STDMETHODCALLTYPE CFolderItem::get_Application(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
return E_NOTIMPL;
return m_Folder->get_Application(ppid);
}
HRESULT STDMETHODCALLTYPE CFolderItem::get_Parent(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
if (ppid)
{
*ppid = m_Folder;
m_Folder->AddRef();
}
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFolderItem::get_Name(BSTR *pbs)
{
TRACE("(%p, %p)\n", this, pbs);
return E_NOTIMPL;
*pbs = NULL;
CComPtr<IShellFolder2> Parent;
LPCITEMIDLIST last_part;
HRESULT hr = SHBindToParent(m_idlist, IID_PPV_ARG(IShellFolder2, &Parent), &last_part);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
STRRET strret;
hr = Parent->GetDisplayNameOf(last_part, SHGDN_INFOLDER, &strret);
if (!FAILED_UNEXPECTEDLY(hr))
hr = StrRetToBSTR(&strret, last_part, pbs);
return hr;
}
HRESULT STDMETHODCALLTYPE CFolderItem::put_Name(BSTR bs)
@ -170,11 +178,11 @@ CFolderItems::~CFolderItems()
{
}
HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
HRESULT CFolderItems::Initialize(LPITEMIDLIST idlist, Folder* parent)
{
CComPtr<IShellFolder> psfDesktop, psfTarget;
m_idlist.Attach(idlist);
m_idlist.Attach(ILClone(idlist));
HRESULT hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED_UNEXPECTEDLY(hr))
@ -189,6 +197,7 @@ HRESULT CFolderItems::Init(LPITEMIDLIST idlist)
if (FAILED_UNEXPECTEDLY(hr))
return hr;
m_Folder = parent;
return S_OK;
}
@ -210,8 +219,7 @@ HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
return hr;
CComHeapPtr<ITEMIDLIST> Pidl;
hr = m_EnumIDList->Next(1, &Pidl, 0);
while (hr != S_FALSE)
while ((hr = m_EnumIDList->Next(1, &Pidl, 0)) != S_FALSE)
{
count++;
Pidl.Free();
@ -226,12 +234,16 @@ HRESULT STDMETHODCALLTYPE CFolderItems::get_Count(long *plCount)
HRESULT STDMETHODCALLTYPE CFolderItems::get_Application(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
return E_NOTIMPL;
return m_Folder->get_Application(ppid);
}
HRESULT STDMETHODCALLTYPE CFolderItems::get_Parent(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
if (ppid)
*ppid = NULL;
return E_NOTIMPL;
}
@ -240,40 +252,48 @@ HRESULT STDMETHODCALLTYPE CFolderItems::Item(VARIANT index, FolderItem **ppid)
if (!m_EnumIDList)
return E_FAIL;
if (V_VT(&index) != VT_I4 && V_VT(&index) != VT_UI4)
return E_INVALIDARG;
if (V_VT(&index) == VT_I2)
VariantChangeType(&index, &index, 0, VT_I4);
ULONG count = V_UI4(&index);
HRESULT hr = m_EnumIDList->Reset();
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_EnumIDList->Skip(count);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CComHeapPtr<ITEMIDLIST> spPidl;
hr = m_EnumIDList->Next(1, &spPidl, 0);
if (hr == S_OK)
if (V_VT(&index) == VT_I4)
{
CFolderItem* item = new CComObject<CFolderItem>();
item->AddRef();
item->Init(spPidl.Detach());
*ppid = item;
return S_OK;
ULONG count = V_UI4(&index);
HRESULT hr = m_EnumIDList->Reset();
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_EnumIDList->Skip(count);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CComHeapPtr<ITEMIDLIST> spPidl;
hr = m_EnumIDList->Next(1, &spPidl, 0);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = ShellObjectCreatorInit<CFolderItem>(m_Folder, static_cast<LPITEMIDLIST>(spPidl), IID_PPV_ARG(FolderItem, ppid));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return hr;
}
else if (V_VT(&index) == VT_BSTR)
{
if (!V_BSTR(&index))
return S_FALSE;
HRESULT hr = m_Folder->ParseName(V_BSTR(&index), ppid);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return hr;
}
return hr;
FIXME("Index type %d not handled.\n", V_VT(&index));
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CFolderItems::_NewEnum(IUnknown **ppunk)
{
CFolderItems* items = new CComObject<CFolderItems>();
items->AddRef();
items->Init(ILClone(m_idlist));
*ppunk = items;
return S_OK;
return ShellObjectCreatorInit<CFolderItems>(static_cast<LPITEMIDLIST>(m_idlist), m_Folder, IID_FolderItems, reinterpret_cast<void**>(ppunk));
}

View file

@ -1,21 +1,8 @@
/*
* FolderItem(s) implementation
*
* Copyright 2015 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: FolderItem(s) implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#ifndef _FOLDERITEM_H_
@ -29,13 +16,13 @@ class CFolderItem:
{
private:
CComHeapPtr<ITEMIDLIST> m_idlist;
CComPtr<Folder> m_Folder;
public:
CFolderItem();
~CFolderItem();
// Please note: CFolderItem takes ownership of idlist.
void Init(LPITEMIDLIST idlist);
HRESULT Initialize(Folder* folder, LPITEMIDLIST idlist);
// *** FolderItem methods ***
@ -75,6 +62,7 @@ class CFolderItems:
private:
CComHeapPtr<ITEMIDLIST> m_idlist;
CComPtr<IEnumIDList> m_EnumIDList;
CComPtr<Folder> m_Folder;
long m_Count;
public:
@ -82,7 +70,7 @@ public:
~CFolderItems();
// Please note: CFolderItems takes ownership of idlist.
HRESULT Init(LPITEMIDLIST idlist);
HRESULT Initialize(LPITEMIDLIST idlist, Folder* parent);
// *** FolderItems methods ***
virtual HRESULT STDMETHODCALLTYPE get_Count(long *plCount);

View file

@ -1,24 +1,12 @@
/*
* IShellDispatch implementation
*
* Copyright 2015 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: IShellDispatch implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#include "precomp.h"
#include "winsvc.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@ -40,13 +28,27 @@ HRESULT CShellDispatch::Initialize()
HRESULT STDMETHODCALLTYPE CShellDispatch::get_Application(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
return E_NOTIMPL;
if (!ppid)
return E_INVALIDARG;
*ppid = this;
AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::get_Parent(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
return E_NOTIMPL;
if (ppid)
{
*ppid = static_cast<IDispatch*>(this);
AddRef();
}
return S_OK;
}
HRESULT VariantToIdlist(VARIANT* var, LPITEMIDLIST* idlist)
@ -69,26 +71,56 @@ HRESULT STDMETHODCALLTYPE CShellDispatch::NameSpace(VARIANT vDir, Folder **ppsdf
if (!ppsdf)
return E_POINTER;
*ppsdf = NULL;
LPITEMIDLIST idlist = NULL;
HRESULT hr = VariantToIdlist(&vDir, &idlist);
HRESULT hr;
if (V_VT(&vDir) == VT_I2)
{
hr = VariantChangeType(&vDir, &vDir, 0, VT_I4);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
CComHeapPtr<ITEMIDLIST> idlist;
hr = VariantToIdlist(&vDir, &idlist);
if (!SUCCEEDED(hr) || !idlist)
return S_FALSE;
CFolder* fld = new CComObject<CFolder>();
fld->Init(idlist);
*ppsdf = fld;
fld->AddRef();
return hr;
return ShellObjectCreatorInit<CFolder>(static_cast<LPITEMIDLIST>(idlist), IID_PPV_ARG(Folder, ppsdf));
}
static BOOL is_optional_argument(const VARIANT *arg)
{
return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::BrowseForFolder(LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
{
TRACE("(%p, %lu, %ls, %lu, %s, %p)\n", this, Hwnd, Title, Options, debugstr_variant(&RootFolder), ppsdf);
return E_NOTIMPL;
*ppsdf = NULL;
if (!is_optional_argument(&RootFolder))
FIXME("root folder is ignored\n");
BROWSEINFOW bi = { 0 };
bi.hwndOwner = reinterpret_cast<HWND>(LongToHandle(Hwnd));
bi.lpszTitle = Title;
bi.ulFlags = Options;
CComHeapPtr<ITEMIDLIST> selection;
selection.Attach(SHBrowseForFolderW(&bi));
if (!selection)
return S_FALSE;
return ShellObjectCreatorInit<CFolder>(static_cast<LPITEMIDLIST>(selection), IID_PPV_ARG(Folder, ppsdf));
}
HRESULT STDMETHODCALLTYPE CShellDispatch::Windows(IDispatch **ppid)
{
TRACE("(%p, %p)\n", this, ppid);
*ppid = NULL;
return E_NOTIMPL;
}
@ -208,10 +240,35 @@ HRESULT STDMETHODCALLTYPE CShellDispatch::IsRestricted(BSTR group, BSTR restrict
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::ShellExecute(BSTR file, VARIANT args, VARIANT dir, VARIANT op, VARIANT show)
HRESULT STDMETHODCALLTYPE CShellDispatch::ShellExecute(BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
{
TRACE("(%p, %ls, %s, %s, %s, %s)\n", this, file, debugstr_variant(&args), debugstr_variant(&dir), debugstr_variant(&op), debugstr_variant(&show));
return E_NOTIMPL;
CComVariant args_str, dir_str, op_str, show_int;
WCHAR *args = NULL, *dir = NULL, *op = NULL;
INT show = 0;
HINSTANCE ret;
TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));
args_str.ChangeType(VT_BSTR, &v_args);
if (V_VT(&args_str) == VT_BSTR)
args = V_BSTR(&args_str);
dir_str.ChangeType(VT_BSTR, &v_dir);
if (V_VT(&dir_str) == VT_BSTR)
dir = V_BSTR(&dir_str);
op_str.ChangeType(VT_BSTR, &v_op);
if (V_VT(&op_str) == VT_BSTR)
op = V_BSTR(&op_str);
show_int.ChangeType(VT_I4, &v_show);
if (V_VT(&show_int) == VT_I4)
show = V_I4(&show_int);
ret = ShellExecuteW(NULL, op, file, args, dir, show);
return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::FindPrinter(BSTR name, BSTR location, BSTR model)
@ -238,10 +295,48 @@ HRESULT STDMETHODCALLTYPE CShellDispatch::ServiceStop(BSTR service, VARIANT pers
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::IsServiceRunning(BSTR service, VARIANT *running)
HRESULT STDMETHODCALLTYPE CShellDispatch::IsServiceRunning(BSTR name, VARIANT *running)
{
TRACE("(%p, %ls, %p)\n", this, service, running);
return E_NOTIMPL;
SERVICE_STATUS_PROCESS status;
SC_HANDLE scm, service;
DWORD dummy;
TRACE("(%s, %p)\n", debugstr_w(name), running);
V_VT(running) = VT_BOOL;
V_BOOL(running) = VARIANT_FALSE;
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
if (!scm)
{
ERR("failed to connect to service manager\n");
return S_OK;
}
service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
if (!service)
{
ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
CloseServiceHandle(scm);
return S_OK;
}
if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
sizeof(SERVICE_STATUS_PROCESS), &dummy))
{
TRACE("failed to query service status (%u)\n", GetLastError());
CloseServiceHandle(service);
CloseServiceHandle(scm);
return S_OK;
}
if (status.dwCurrentState == SERVICE_RUNNING)
V_BOOL(running) = VARIANT_TRUE;
CloseServiceHandle(service);
CloseServiceHandle(scm);
return S_OK;
}
HRESULT STDMETHODCALLTYPE CShellDispatch::CanStartStopService(BSTR service, VARIANT *ret)

View file

@ -1,21 +1,8 @@
/*
* IShellDispatch implementation
*
* Copyright 2015 Mark Jansen
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: IShellDispatch implementation
* COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
*/
#ifndef _SHELLDISPATCH_H_