Stub added for the IEnumObjects and IObjectCollection interfaces, so that programs won't crash when calling it.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53620 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56891
-- v7: actxprxy: Added IEnumObjects_Next_Proxy shell32: Added stub for IObjectCollection interface. shell32: Added stub for IEnumObjects interface.
From: Kevin Martinez 137180189+kevinrmartinez@users.noreply.github.com
--- dlls/shell32/Makefile.in | 1 + dlls/shell32/enumobjects.c | 166 +++++++++++++++++++++++++++++++ dlls/shell32/shell32_classes.idl | 5 + dlls/shell32/shell32_main.h | 1 + dlls/shell32/shellole.c | 1 + include/shobjidl.idl | 13 +++ 6 files changed, 187 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..16ad52168d8 --- /dev/null +++ b/dlls/shell32/enumobjects.c @@ -0,0 +1,166 @@ +/* + * EnumerableObjectCollection + * + * 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); + +struct enum_objects +{ + IEnumObjects IEnumObjects_iface; + LONG ref; +}; + +static inline struct enum_objects *impl_from_IEnumObjects(IEnumObjects *iface) +{ + return CONTAINING_RECORD(iface, struct enum_objects, IEnumObjects_iface); +} + +static HRESULT WINAPI enum_objects_QueryInterface(IEnumObjects *iface, REFIID riid, void **obj) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj); + + *obj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumObjects)) + { + *obj = &This->IEnumObjects_iface; + } + + if (*obj) + { + IUnknown_AddRef((IUnknown*)*obj); + return S_OK; + } + + WARN("no interface for %s.\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI enum_objects_AddRef(IEnumObjects *iface) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + ULONG refcount = InterlockedIncrement(&This->ref); + + TRACE("(%p): increasing refcount to %lu.\n", This, refcount); + + return refcount; +} + + static ULONG WINAPI enum_objects_Release(IEnumObjects *iface) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + ULONG refcount = InterlockedDecrement(&This->ref); + + TRACE("(%p): decreasing refcount to %lu.\n", This, refcount); + + if (!refcount) + { + free(This); + } + + return refcount; +} + +static HRESULT WINAPI enum_objects_Next(IEnumObjects *iface, ULONG celt, REFIID riid, void **rgelt, ULONG *celtFetched) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + + FIXME("(%p %ld, %p)->(%p, %p): stub!\n", This, celt, debugstr_guid(riid), rgelt, celtFetched); + + if (celtFetched) + *celtFetched = 0; + + return S_FALSE; +} + +static HRESULT WINAPI enum_objects_Skip(IEnumObjects *iface, ULONG celt) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + + FIXME("(%p %ld): stub!\n", This, celt); + + return E_NOTIMPL; +} + +static HRESULT WINAPI enum_objects_Reset(IEnumObjects *iface) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + + FIXME("(%p): stub!\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI enum_objects_Clone(IEnumObjects *iface, IEnumObjects **ppenum) +{ + struct enum_objects *This = impl_from_IEnumObjects(iface); + + FIXME("(%p)->(%p): stub!\n", This, ppenum); + + return E_NOTIMPL; +} + +static const IEnumObjectsVtbl enum_objects_vtbl = +{ + enum_objects_QueryInterface, + enum_objects_AddRef, + enum_objects_Release, + enum_objects_Next, + enum_objects_Skip, + enum_objects_Reset, + enum_objects_Clone, +}; + +HRESULT WINAPI EnumerableObjectCollection_Constructor(IUnknown *outer, REFIID riid, void **obj) +{ + struct enum_objects *This; + HRESULT hr; + + TRACE("(%p, %s, %p)\n", outer, debugstr_guid(riid), obj); + + if (outer) + return CLASS_E_NOAGGREGATION; + + if (!(This = heap_alloc(sizeof(*This)))) + return E_OUTOFMEMORY; + + This->ref = 1; + This->IEnumObjects_iface.lpVtbl = &enum_objects_vtbl; + + hr = IEnumObjects_QueryInterface(&This->IEnumObjects_iface, riid, obj); + IEnumObjects_Release(&This->IEnumObjects_iface); + return hr; +} diff --git a/dlls/shell32/shell32_classes.idl b/dlls/shell32/shell32_classes.idl index 135ef52f7b0..a6da0f7c434 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 {} diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index 6b5575c6879..c4b301f500a 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -103,6 +103,7 @@ HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, LPV HRESULT WINAPI KnownFolderManager_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv); HRESULT WINAPI IFileOperation_Constructor(IUnknown *outer, REFIID riid, void **out); HRESULT WINAPI ActiveDesktop_Constructor(IUnknown *outer, REFIID riid, void **out); +HRESULT WINAPI EnumerableObjectCollection_Constructor(IUnknown *outer, REFIID riid, void **obj);
extern HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST, LPWSTR, UINT, int*); HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize); diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c index aa9bd3e0f3e..fc3f6b032cd 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, EnumerableObjectCollection_Constructor}, {NULL, NULL} };
diff --git a/include/shobjidl.idl b/include/shobjidl.idl index 886cff89ef9..586efe574dc 100644 --- a/include/shobjidl.idl +++ b/include/shobjidl.idl @@ -4126,3 +4126,16 @@ interface IFileOperation : IUnknown HRESULT PerformOperations(); HRESULT GetAnyOperationsAborted([out] BOOL *aborted); } + +[ + object, + uuid(2c1c7e2e-2d0e-4059-831e-1e6f82335c2e), + pointer_default(unique) +] +interface IEnumObjects : IUnknown +{ + [local] 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); +}
From: Kevin Martinez 137180189+kevinrmartinez@users.noreply.github.com
--- dlls/shell32/enumobjects.c | 98 +++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/enumobjects.c b/dlls/shell32/enumobjects.c index 16ad52168d8..f71eda6f505 100644 --- a/dlls/shell32/enumobjects.c +++ b/dlls/shell32/enumobjects.c @@ -37,6 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); struct enum_objects { IEnumObjects IEnumObjects_iface; + IObjectCollection IObjectCollection_iface; LONG ref; };
@@ -45,6 +46,11 @@ static inline struct enum_objects *impl_from_IEnumObjects(IEnumObjects *iface) return CONTAINING_RECORD(iface, struct enum_objects, IEnumObjects_iface); }
+static inline struct enum_objects *impl_from_IObjectCollection(IObjectCollection *iface) +{ + return CONTAINING_RECORD(iface, struct enum_objects, IObjectCollection_iface); +} + static HRESULT WINAPI enum_objects_QueryInterface(IEnumObjects *iface, REFIID riid, void **obj) { struct enum_objects *This = impl_from_IEnumObjects(iface); @@ -57,6 +63,10 @@ static HRESULT WINAPI enum_objects_QueryInterface(IEnumObjects *iface, REFIID ri { *obj = &This->IEnumObjects_iface; } + else if (IsEqualIID(riid, &IID_IObjectCollection) || IsEqualIID(riid, &IID_IObjectArray)) + { + *obj = &This->IObjectCollection_iface; + }
if (*obj) { @@ -102,7 +112,7 @@ static HRESULT WINAPI enum_objects_Next(IEnumObjects *iface, ULONG celt, REFIID
if (celtFetched) *celtFetched = 0; - + return S_FALSE; }
@@ -144,6 +154,91 @@ static const IEnumObjectsVtbl enum_objects_vtbl = enum_objects_Clone, };
+static HRESULT WINAPI object_collection_QueryInterface(IObjectCollection *iface, REFIID riid, void **obj) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + return IEnumObjects_QueryInterface(&This->IEnumObjects_iface, riid, obj); +} + +static ULONG WINAPI object_collection_AddRef(IObjectCollection *iface) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + return IEnumObjects_AddRef(&This->IEnumObjects_iface); +} + +static ULONG WINAPI object_collection_Release(IObjectCollection *iface) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + return IEnumObjects_Release(&This->IEnumObjects_iface); +} + +static HRESULT WINAPI object_collection_GetCount(IObjectCollection *iface, UINT *count) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p)->(%p): stub!\n", This, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI object_collection_GetAt(IObjectCollection *iface, UINT index, REFIID riid, void **obj) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p %u, %s)->(%p): stub!\n", This, index, debugstr_guid(riid), obj); + + return E_NOTIMPL; +} + +static HRESULT WINAPI object_collection_AddObject(IObjectCollection *iface, IUnknown *obj) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p %p): stub!\n", This, obj); + + return E_NOTIMPL; +} + +static HRESULT WINAPI object_collection_AddFromArray(IObjectCollection *iface, IObjectArray *source_array) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p %p): stub!\n", This, source_array); + + return E_NOTIMPL; +} + +static HRESULT WINAPI object_collection_RemoveObjectAt(IObjectCollection *iface, UINT index) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p %u): stub!\n", This, index); + + return E_NOTIMPL; +} + +static HRESULT WINAPI object_collection_Clear(IObjectCollection *iface) +{ + struct enum_objects *This = impl_from_IObjectCollection(iface); + + FIXME("(%p): stub!\n", This); + + return E_NOTIMPL; +} + +static const IObjectCollectionVtbl object_collection_vtbl = +{ + object_collection_QueryInterface, + object_collection_AddRef, + object_collection_Release, + object_collection_GetCount, + object_collection_GetAt, + object_collection_AddObject, + object_collection_AddFromArray, + object_collection_RemoveObjectAt, + object_collection_Clear +}; + HRESULT WINAPI EnumerableObjectCollection_Constructor(IUnknown *outer, REFIID riid, void **obj) { struct enum_objects *This; @@ -159,6 +254,7 @@ HRESULT WINAPI EnumerableObjectCollection_Constructor(IUnknown *outer, REFIID ri
This->ref = 1; This->IEnumObjects_iface.lpVtbl = &enum_objects_vtbl; + This->IObjectCollection_iface.lpVtbl = &object_collection_vtbl;
hr = IEnumObjects_QueryInterface(&This->IEnumObjects_iface, riid, obj); IEnumObjects_Release(&This->IEnumObjects_iface);
From: Kevin Martinez 137180189+kevinrmartinez@users.noreply.github.com
--- dlls/actxprxy/usrmarshal.c | 18 ++++++++++++++++++ include/shobjidl.idl | 1 + 2 files changed, 19 insertions(+)
diff --git a/dlls/actxprxy/usrmarshal.c b/dlls/actxprxy/usrmarshal.c index e4eada6848f..5fa3c8581ec 100644 --- a/dlls/actxprxy/usrmarshal.c +++ b/dlls/actxprxy/usrmarshal.c @@ -247,3 +247,21 @@ HRESULT __RPC_STUB IParentAndItem_GetParentAndItem_Proxy( TRACE("(%p)->(%p %p %p)\n", This, parent, folder, child); return IParentAndItem_RemoteGetParentAndItem_Proxy(This, parent, folder, child); } + +HRESULT CALLBACK IEnumObjects_Next_Proxy(IEnumObjects *This, ULONG celt, REFIID riid, void **rgelt, ULONG *pceltFetched) +{ + ULONG fetched; + TRACE("(%p)->(%ld, %p, %p, %p)\n", This, celt, debugstr_guid(riid), rgelt, pceltFetched); + if (!pceltFetched) pceltFetched = &fetched; + return IEnumObjects_RemoteNext_Proxy(This, celt, riid, rgelt, pceltFetched); +} + +HRESULT __RPC_STUB IEnumObjects_Next_Stub(IEnumObjects *This, ULONG celt, REFIID riid, void **rgelt, ULONG *pceltFetched) +{ + HRESULT hr; + TRACE("(%p)->(%ld, %p, %p, %p)\n", This, celt, debugstr_guid(riid), rgelt, pceltFetched); + *pceltFetched = 0; + hr = IEnumObjects_Next(This, celt, riid, rgelt, pceltFetched); + if (hr == S_OK) *pceltFetched = celt; + return hr; +} diff --git a/include/shobjidl.idl b/include/shobjidl.idl index 586efe574dc..58dcc3a83f1 100644 --- a/include/shobjidl.idl +++ b/include/shobjidl.idl @@ -4135,6 +4135,7 @@ interface IFileOperation : IUnknown interface IEnumObjects : IUnknown { [local] HRESULT Next([in] ULONG celt, [in] REFIID riid, [out, iid_is(riid)] void **rgelt, [out, optional] ULONG *pceltFetched); + [call_as(Next)] HRESULT RemoteNext([in] ULONG celt, [in] REFIID riid, [out, size_is(celt), length_is(*pceltFetched), iid_is(riid)] void **rgelt, [out] ULONG *pceltFetched); HRESULT Skip([in] ULONG celt); HRESULT Reset(); HRESULT Clone([out] IEnumObjects **ppenum);
On Wed Aug 14 14:36:47 2024 +0000, Kevin Martinez wrote:
changed this line in [version 7 of the diff](/wine/wine/-/merge_requests/6130/diffs?diff_id=126464&start_sha=5002949e7553ded3afa35dd53ebdc315c2663152#9718da1edbba0f34e8a2e9e282c5e291ab926c91_179_179)
Understood, using reference from another file I changed it to %p.
On Wed Aug 14 14:39:14 2024 +0000, Elizabeth Figura wrote:
I think using a single space is pretty much universal, at least in new code. But as always consistency is most important.
Single space it is then.
Let's avoid tabs in new code, please.
Agreed.
On Wed Aug 14 14:36:48 2024 +0000, Kevin Martinez wrote:
changed this line in [version 7 of the diff](/wine/wine/-/merge_requests/6130/diffs?diff_id=126464&start_sha=5002949e7553ded3afa35dd53ebdc315c2663152#1706c332dfd6180886ecdcc70e698be052f47595_196_196)
Ok, was just following the example of other entries.