mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[SHELL32] Sync CShellDispatch and family with wine.
Incorporates work from Ivan Rodionov. CORE-12955
This commit is contained in:
parent
fd87f0ad87
commit
e8dcbcc61d
7 changed files with 261 additions and 186 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in a new issue