Files
reactos/dll/win32/shell32/CShellItemArray.cpp
T
095860df57 [SDK][SHELL32] A big bundle of NT6+ shell32 implementations and stubs (#8834)
Split off CShellitemArray
stub out CShellLibrary
stub out CUserEventTimer
rewrite some vista shellitem APIs
Misc stubs for vista
AddITaskbarList3/ITaskbarList4

---------

Co-authored-by: Oleb Dubinskiy <[email protected]>
Co-authored-by: Mikhail Tyukin <[email protected]>
2026-07-21 12:11:29 -07:00

354 lines
8.0 KiB
C++

#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/***********************************************************************
* CShellItemArray
*/
CShellItemArray::CShellItemArray() : m_pHIDA(NULL)
{
}
CShellItemArray::~CShellItemArray()
{
delete m_pHIDA;
}
HRESULT
CShellItemArray::Initialize(_In_ IDataObject *pdo)
{
m_pHIDA = new CDataObjectHIDA(pdo);
if (!m_pHIDA)
return E_OUTOFMEMORY;
HRESULT hr = m_pHIDA->hr();
if (FAILED(hr))
{
delete m_pHIDA;
m_pHIDA = NULL;
}
return hr;
}
UINT
CShellItemArray::ItemCount() const
{
return m_pHIDA ? (*m_pHIDA)->cidl : 0;
}
STDMETHODIMP
CShellItemArray::BindToHandler(_In_opt_ IBindCtx *pbc, _In_ REFGUID rbhid, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CShellItemArray::GetPropertyStore(_In_ GETPROPERTYSTOREFLAGS flags, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CShellItemArray::GetPropertyDescriptionList(_In_ REFPROPERTYKEY keyType, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CShellItemArray::GetAttributes(_In_ SIATTRIBFLAGS dwAttribFlags, _In_ SFGAOF sfgaoMask, _Out_ SFGAOF *psfgaoAttribs)
{
UNIMPLEMENTED;
*psfgaoAttribs = 0;
return E_NOTIMPL;
}
STDMETHODIMP
CShellItemArray::GetCount(_Out_ DWORD *pCount)
{
if (!pCount)
return E_INVALIDARG;
*pCount = ItemCount();
return S_OK;
}
STDMETHODIMP
CShellItemArray::GetItemAt(_In_ DWORD nIndex, _Out_ IShellItem **ppItem)
{
if (!ppItem)
return E_INVALIDARG;
*ppItem = NULL;
if (!m_pHIDA)
return E_UNEXPECTED;
if (nIndex >= ItemCount())
return E_FAIL;
return SHCreateShellItem(HIDA_GetPIDLFolder(*m_pHIDA), NULL,
HIDA_GetPIDLItem(*m_pHIDA, nIndex), ppItem);
}
STDMETHODIMP
CShellItemArray::EnumItems(_Out_ IEnumShellItems **ppESI)
{
UNIMPLEMENTED;
*ppESI = NULL;
return E_NOTIMPL;
}
/***********************************************************************
* CSimpleShellItemArray
*/
HRESULT
CSimpleShellItemArray::Initialize(_In_reads_(count) IShellItem **pitems, _In_ UINT count)
{
if (!m_items.SetCount(0))
return E_OUTOFMEMORY;
for (UINT i = 0; i < count; ++i)
{
CComPtr<IShellItem> ptr = pitems[i];
if (!ptr)
return E_INVALIDARG;
m_items.Add(ptr);
}
return S_OK;
}
STDMETHODIMP
CSimpleShellItemArray::BindToHandler(_In_opt_ IBindCtx *pbc, _In_ REFGUID rbhid, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CSimpleShellItemArray::GetPropertyStore(_In_ GETPROPERTYSTOREFLAGS flags, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CSimpleShellItemArray::GetPropertyDescriptionList(_In_ REFPROPERTYKEY keyType, _In_ REFIID riid, _Out_ void **ppv)
{
UNIMPLEMENTED;
*ppv = NULL;
return E_NOTIMPL;
}
STDMETHODIMP
CSimpleShellItemArray::GetAttributes(_In_ SIATTRIBFLAGS dwAttribFlags, _In_ SFGAOF sfgaoMask, _Out_ SFGAOF *psfgaoAttribs)
{
HRESULT hr = S_OK;
SFGAOF attr;
if (!psfgaoAttribs)
return E_POINTER;
if (dwAttribFlags & ~(SIATTRIBFLAGS_AND | SIATTRIBFLAGS_OR))
FIXME("%08x contains unsupported attribution flags\n", dwAttribFlags);
for (size_t i = 0; i < m_items.GetCount(); ++i)
{
hr = m_items[i]->GetAttributes(sfgaoMask, &attr);
if (FAILED_UNEXPECTEDLY(hr))
break;
if (i == 0)
{
*psfgaoAttribs = attr;
continue;
}
if ((dwAttribFlags & SIATTRIBFLAGS_MASK) == SIATTRIBFLAGS_AND)
*psfgaoAttribs &= attr;
else
*psfgaoAttribs |= attr;
}
if (SUCCEEDED(hr))
{
if (*psfgaoAttribs == sfgaoMask)
return S_OK;
return S_FALSE;
}
return hr;
}
STDMETHODIMP
CSimpleShellItemArray::GetCount(_Out_ DWORD *pdwNumItems)
{
if (!pdwNumItems)
return E_INVALIDARG;
*pdwNumItems = static_cast<DWORD>(m_items.GetCount());
return S_OK;
}
STDMETHODIMP
CSimpleShellItemArray::GetItemAt(_In_ DWORD dwIndex, _Out_ IShellItem **ppsi)
{
if (!ppsi)
return E_INVALIDARG;
*ppsi = NULL;
if (dwIndex >= m_items.GetCount())
return E_FAIL;
*ppsi = m_items[dwIndex];
(*ppsi)->AddRef();
return S_OK;
}
STDMETHODIMP
CSimpleShellItemArray::EnumItems(_Out_ IEnumShellItems **ppenumShellItems)
{
UNIMPLEMENTED;
*ppenumShellItems = NULL;
return E_NOTIMPL;
}
HRESULT
CreateShellItemArrayFromItems(_In_reads_(cidl) IShellItem **items, _In_ UINT cidl, _In_ REFIID riid, _Out_ void **ppv)
{
return ShellObjectCreatorInit<CSimpleShellItemArray>(items, cidl, riid, ppv);
}
/***********************************************************************
* SHCreateShellItemArray [SHELL32.@]
*/
EXTERN_C HRESULT WINAPI
SHCreateShellItemArray(
_In_opt_ PCIDLIST_ABSOLUTE pidlParent,
_In_opt_ IShellFolder *psf,
_In_ UINT cidl,
_In_reads_opt_(cidl) PCUITEMID_CHILD_ARRAY ppidl,
_Out_ IShellItemArray **ppsiItemArray)
{
CComHeapPtr<IShellItem *> array;
HRESULT hr = E_FAIL;
TRACE("(%p,%p,%u,%p,%p)\n", pidlParent, psf, cidl, ppidl, ppsiItemArray);
if (!ppsiItemArray)
return E_POINTER;
*ppsiItemArray = NULL;
if (!pidlParent && !psf)
return E_POINTER;
if (!ppidl)
return E_INVALIDARG;
array.Allocate(cidl);
if (!array)
return E_OUTOFMEMORY;
for (UINT i = 0; i < cidl; ++i)
array[i] = NULL;
for (UINT i = 0; i < cidl; ++i)
{
hr = SHCreateShellItem(pidlParent, psf, ppidl[i], &array[i]);
if (FAILED_UNEXPECTEDLY(hr))
break;
}
if (SUCCEEDED(hr))
{
hr = CreateShellItemArrayFromItems(array, cidl, IID_PPV_ARG(IShellItemArray, ppsiItemArray));
}
for (UINT i = 0; i < cidl; ++i)
{
if (array[i])
array[i]->Release();
}
return hr;
}
/***********************************************************************
* SHCreateShellItemArrayFromIDLists [SHELL32.@]
*/
EXTERN_C HRESULT WINAPI
SHCreateShellItemArrayFromIDLists(
_In_ UINT cidl,
_In_reads_(cidl) PCIDLIST_ABSOLUTE_ARRAY pidlArray,
_Out_ IShellItemArray **ppsiItemArray)
{
CComHeapPtr<IShellItem *> array;
HRESULT hr;
TRACE("(%u,%p,%p)\n", cidl, pidlArray, ppsiItemArray);
if (!ppsiItemArray)
return E_POINTER;
*ppsiItemArray = NULL;
if (cidl == 0 || !pidlArray)
return E_INVALIDARG;
array.Allocate(cidl);
if (!array)
return E_OUTOFMEMORY;
for (UINT i = 0; i < cidl; ++i)
array[i] = NULL;
for (UINT i = 0; i < cidl; ++i)
{
hr = SHCreateShellItem(NULL, NULL, pidlArray[i], &array[i]);
if (FAILED_UNEXPECTEDLY(hr))
break;
}
if (SUCCEEDED(hr))
{
hr = CreateShellItemArrayFromItems(array, cidl, IID_PPV_ARG(IShellItemArray, ppsiItemArray));
}
for (UINT i = 0; i < cidl; ++i)
{
if (array[i])
array[i]->Release();
}
return hr;
}
/***********************************************************************
* SHCreateShellItemArrayFromShellItem [SHELL32.@]
*/
EXTERN_C HRESULT WINAPI
SHCreateShellItemArrayFromShellItem(_In_ IShellItem *psi, _In_ REFIID riid, _Out_ void **ppv)
{
IShellItem *items[1] = { psi };
TRACE("(%p,%s,%p)\n", psi, debugstr_guid(&riid), ppv);
if (!ppv)
return E_POINTER;
*ppv = NULL;
if (!psi)
return E_INVALIDARG;
return CreateShellItemArrayFromItems(items, 1, riid, ppv);
}
/***********************************************************************
* SHCreateShellItemArrayFromDataObject [SHELL32.@]
*/
EXTERN_C HRESULT WINAPI
SHCreateShellItemArrayFromDataObject(_In_ IDataObject *pdo, _In_ REFIID riid, _Out_ void **ppv)
{
return ShellObjectCreatorInit<CShellItemArray>(pdo, riid, ppv);
}