https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e8dcbcc61d52df02fd6bb…
commit e8dcbcc61d52df02fd6bb4abb9af947851df8cd3
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Fri Apr 13 22:59:04 2018 +0200
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sat Apr 14 15:47:13 2018 +0200
[SHELL32] Sync CShellDispatch and family with wine.
Incorporates work from Ivan Rodionov.
CORE-12955
---
dll/win32/shell32/CFolder.cpp | 72 ++++++---------
dll/win32/shell32/CFolder.h | 24 ++---
dll/win32/shell32/CFolderItemVerbs.cpp | 15 ++-
dll/win32/shell32/CFolderItems.cpp | 118 ++++++++++++++----------
dll/win32/shell32/CFolderItems.h | 28 ++----
dll/win32/shell32/CShellDispatch.cpp | 161 ++++++++++++++++++++++++++-------
dll/win32/shell32/CShellDispatch.h | 21 +----
7 files changed, 257 insertions(+), 182 deletions(-)
diff --git a/dll/win32/shell32/CFolder.cpp b/dll/win32/shell32/CFolder.cpp
index 26eea6cfba..3421ecbcc1 100644
--- a/dll/win32/shell32/CFolder.cpp
+++ b/dll/win32/shell32/CFolder.cpp
@@ -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(a)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)
diff --git a/dll/win32/shell32/CFolder.h b/dll/win32/shell32/CFolder.h
index bfd5c9d08d..df0d482b43 100644
--- a/dll/win32/shell32/CFolder.h
+++ b/dll/win32/shell32/CFolder.h
@@ -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(a)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);
diff --git a/dll/win32/shell32/CFolderItemVerbs.cpp
b/dll/win32/shell32/CFolderItemVerbs.cpp
index 87866fa786..0397f724f8 100644
--- a/dll/win32/shell32/CFolderItemVerbs.cpp
+++ b/dll/win32/shell32/CFolderItemVerbs.cpp
@@ -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 };
diff --git a/dll/win32/shell32/CFolderItems.cpp b/dll/win32/shell32/CFolderItems.cpp
index 614ead2e8b..9d2e27090b 100644
--- a/dll/win32/shell32/CFolderItems.cpp
+++ b/dll/win32/shell32/CFolderItems.cpp
@@ -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(a)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);
+ if (V_VT(&index) == VT_I4)
+ {
+ ULONG count = V_UI4(&index);
- HRESULT hr = m_EnumIDList->Reset();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
+ HRESULT hr = m_EnumIDList->Reset();
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- hr = m_EnumIDList->Skip(count);
+ hr = m_EnumIDList->Skip(count);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- CComHeapPtr<ITEMIDLIST> spPidl;
- hr = m_EnumIDList->Next(1, &spPidl, 0);
- if (hr == S_OK)
+ 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)
{
- CFolderItem* item = new CComObject<CFolderItem>();
- item->AddRef();
- item->Init(spPidl.Detach());
- *ppid = item;
- return S_OK;
+ 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));
}
diff --git a/dll/win32/shell32/CFolderItems.h b/dll/win32/shell32/CFolderItems.h
index ddb62c87e8..ce339646db 100644
--- a/dll/win32/shell32/CFolderItems.h
+++ b/dll/win32/shell32/CFolderItems.h
@@ -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(a)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);
diff --git a/dll/win32/shell32/CShellDispatch.cpp b/dll/win32/shell32/CShellDispatch.cpp
index 7c98b4ae52..259b891997 100644
--- a/dll/win32/shell32/CShellDispatch.cpp
+++ b/dll/win32/shell32/CShellDispatch.cpp
@@ -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(a)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)
diff --git a/dll/win32/shell32/CShellDispatch.h b/dll/win32/shell32/CShellDispatch.h
index 539f3cfd29..6c32ecf667 100644
--- a/dll/win32/shell32/CShellDispatch.h
+++ b/dll/win32/shell32/CShellDispatch.h
@@ -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(a)reactos.org)
*/
#ifndef _SHELLDISPATCH_H_