From: Kevin Martinez 137180189+kevinrmartinez@users.noreply.github.com
--- dlls/shell32/Makefile.in | 1 + dlls/shell32/enumobjects.c | 195 +++++++++++++++++++++++++++++++ dlls/shell32/shell32_classes.idl | 5 + dlls/shell32/shell32_main.h | 2 + dlls/shell32/shellole.c | 1 + include/shobjidl.idl | 23 ++++ 6 files changed, 227 insertions(+) create mode 100644 dlls/shell32/enumobjects.c
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in index 4a906ac59db..c2df32b62ec 100644 --- a/dlls/shell32/Makefile.in +++ b/dlls/shell32/Makefile.in @@ -21,6 +21,7 @@ SOURCES = \ dragdrophelper.c \ ebrowser.c \ enumidlist.c \ + enumobjects.c \ folders.c \ iconcache.c \ new_menu.c \ diff --git a/dlls/shell32/enumobjects.c b/dlls/shell32/enumobjects.c new file mode 100644 index 00000000000..b4933304cdb --- /dev/null +++ b/dlls/shell32/enumobjects.c @@ -0,0 +1,195 @@ +/* + * IEnumObjects + * + * Copyright 2024 Kevin Martinez + * + * 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 + */ + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#define COBJMACROS + +#include "wine/debug.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "shell32_main.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +typedef struct +{ + IEnumObjects IEnumObjects_iface; + LONG ref; + struct list objls; + struct list *current; +} IEnumObjectsImpl; + +static inline IEnumObjectsImpl *impl_from_IEnumObjects(IEnumObjects *iface) +{ + return CONTAINING_RECORD(iface, IEnumObjectsImpl, IEnumObjects_iface); +} + +/************************************************************************** + * IEnumObjects_fnQueryInterface + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI IEnumObjects_fnQueryInterface(IEnumObjects *iface, REFIID riid, void **obj) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IEnumObjects, riid)) + { + *obj = &This->IEnumObjects_iface; + } + else + { + WARN("no interface for %s\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*obj); + return S_OK; +} + +/************************************************************************** + * IEnumObjects_fnAddRef + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI IEnumObjects_fnAddRef(IEnumObjects *iface) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(%lu)\n", This, refCount - 1); + + return refCount; +} + +/************************************************************************** + * IEnumObjects_fnRelease + * + * See IUnknown_Release. + */ + static ULONG WINAPI IEnumObjects_fnRelease(IEnumObjects *iface) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(%lu)\n", This, refCount + 1); + + if (!refCount) + { + list_remove(&This->objls); + free(This); + } + + return refCount; +} + +/************************************************************************** + * IEnumIDList::Next + */ +static HRESULT WINAPI IEnumObjects_fnNext(IEnumObjects *iface, ULONG celt, REFIID riid, void **rgelt, ULONG *celtFetched) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + + FIXME("%p (%ld, %p, %p, %ln ): stud!\n", This, celt, debugstr_guid(riid), rgelt, celtFetched); + + return E_NOTIMPL; +} + +/************************************************************************** + * IEnumObjects::Skip + */ +static HRESULT WINAPI IEnumObjects_fnSkip(IEnumObjects *iface, ULONG celt) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + + FIXME("(%p)->(%ld): stud!\n", This, celt); + + return E_NOTIMPL; +} + +/************************************************************************** + * IEnumObjects::Reset + */ +static HRESULT WINAPI IEnumObjects_fnReset(IEnumObjects *iface) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + + FIXME("(%p)->() semi-stub\n", This); + + This->current = list_head(&This->objls); + return S_OK; +} + +/************************************************************************** + * IEnumObjects::Clone + */ +static HRESULT WINAPI IEnumObjects_fnClone(IEnumObjects *iface, IEnumObjects **ppenum) +{ + IEnumObjectsImpl *This = impl_from_IEnumObjects(iface); + + WARN("(%p)->(%p): Not implemented.\n",This, ppenum); + + return E_NOTIMPL; +} + +static const IEnumObjectsVtbl eobjlvt = +{ + IEnumObjects_fnQueryInterface, + IEnumObjects_fnAddRef, + IEnumObjects_fnRelease, + IEnumObjects_fnNext, + IEnumObjects_fnSkip, + IEnumObjects_fnReset, + IEnumObjects_fnClone, +}; + +HRESULT WINAPI IEnumObjects_Constructor(IUnknown *outer, REFIID iid, void **obj) +{ + IEnumObjectsImpl *This; + HRESULT hr = S_OK; + + TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj); + + if (outer) + return CLASS_E_NOAGGREGATION; + + if (!(This = heap_alloc(sizeof(*This)))) + return E_OUTOFMEMORY; + + This->IEnumObjects_iface.lpVtbl = &eobjlvt; + This->ref = 1; + list_init(&This->objls); + This->current = NULL; + + + hr = IEnumObjects_fnQueryInterface(&This->IEnumObjects_iface, iid, obj); + IEnumObjects_fnRelease(&This->IEnumObjects_iface); + return hr; +} diff --git a/dlls/shell32/shell32_classes.idl b/dlls/shell32/shell32_classes.idl index 135ef52f7b0..872ecb31630 100644 --- a/dlls/shell32/shell32_classes.idl +++ b/dlls/shell32/shell32_classes.idl @@ -189,3 +189,8 @@ coclass KnownFolderManager { interface IKnownFolderManager; } uuid(d969a300-e7ff-11d0-a93b-00a0c90f2719) ] coclass NewMenu {} + +[ + threading(apartment), + uuid(2d3468c1-36a7-43b6-ac24-d3f02fd9607a) +] coclass EnumerableObjectCollection { interface IEnumObjects; } diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index 6b5575c6879..65250b09bd2 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -123,6 +123,8 @@ LPEXTRACTICONW IExtractIconW_Constructor(LPCITEMIDLIST);
HRESULT WINAPI CustomDestinationList_Constructor(IUnknown *outer, REFIID riid, void **obj);
+HRESULT WINAPI IEnumObjects_Constructor(IUnknown *outer, REFIID riid, void **obj); + /* initialisation for FORMATETC */ #define InitFormatEtc(fe, cf, med) \ {\ diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c index aa9bd3e0f3e..4cc73e4ef24 100644 --- a/dlls/shell32/shellole.c +++ b/dlls/shell32/shellole.c @@ -87,6 +87,7 @@ static const struct { {&CLSID_ShellImageDataFactory, ShellImageDataFactory_Constructor}, {&CLSID_FileOperation, IFileOperation_Constructor}, {&CLSID_ActiveDesktop, ActiveDesktop_Constructor}, + {&CLSID_EnumerableObjectCollection, IEnumObjects_Constructor}, {NULL, NULL} };
diff --git a/include/shobjidl.idl b/include/shobjidl.idl index 886cff89ef9..23ea0b57153 100644 --- a/include/shobjidl.idl +++ b/include/shobjidl.idl @@ -4126,3 +4126,26 @@ interface IFileOperation : IUnknown HRESULT PerformOperations(); HRESULT GetAnyOperationsAborted([out] BOOL *aborted); } + +/***************************************************************************** + * IEnumObjects interface + */ +[ + object, + uuid(5632b1a4-e38a-400a-928a-d4cd63230295), + pointer_default(unique) +] +interface IEnumObjects : IUnknown +{ + //fixme: typedef IEnumObjects *?; + + HRESULT Next( + [in] ULONG celt, + [in] REFIID riid, + [out, iid_is(riid)] void **rgelt, + [out, optional] ULONG *pceltFetched ); + + HRESULT Skip( [in] ULONG celt ); + HRESULT Reset(); + HRESULT Clone( [out] IEnumObjects **ppenum ); +}