Nikolay Sivov : scrrun: Implement IEnumVARIANT stub for folder collection.
Alexandre Julliard
julliard at winehq.org
Fri Jan 3 11:23:15 CST 2014
Module: wine
Branch: master
Commit: 47e1ac9f98ddc158bb69ae8c6594dc598af9e99d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=47e1ac9f98ddc158bb69ae8c6594dc598af9e99d
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Jan 3 16:35:07 2014 +0400
scrrun: Implement IEnumVARIANT stub for folder collection.
---
dlls/scrrun/filesystem.c | 132 +++++++++++++++++++++++++++++++++++++++-
dlls/scrrun/tests/filesystem.c | 53 ++++++++++++++++-
2 files changed, 182 insertions(+), 3 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c
index c96ae6d..5459b7e 100644
--- a/dlls/scrrun/filesystem.c
+++ b/dlls/scrrun/filesystem.c
@@ -36,6 +36,23 @@
WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
+struct enumdata {
+ union
+ {
+ struct
+ {
+ IFolderCollection *coll;
+ } foldercoll;
+ } u;
+};
+
+struct enumvariant {
+ IEnumVARIANT IEnumVARIANT_iface;
+ LONG ref;
+
+ struct enumdata data;
+};
+
struct foldercollection {
IFolderCollection IFolderCollection_iface;
LONG ref;
@@ -87,6 +104,11 @@ static inline struct foldercollection *impl_from_IFolderCollection(IFolderCollec
return CONTAINING_RECORD(iface, struct foldercollection, IFolderCollection_iface);
}
+static inline struct enumvariant *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
+{
+ return CONTAINING_RECORD(iface, struct enumvariant, IEnumVARIANT_iface);
+}
+
static inline HRESULT create_error(DWORD err)
{
switch(err) {
@@ -348,6 +370,107 @@ static HRESULT create_textstream(IOMode mode, ITextStream **ret)
return S_OK;
}
+static HRESULT WINAPI enumvariant_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
+
+ *obj = NULL;
+
+ if (IsEqualIID( riid, &IID_IEnumVARIANT ) ||
+ IsEqualIID( riid, &IID_IUnknown ))
+ {
+ *obj = iface;
+ IEnumVARIANT_AddRef(iface);
+ }
+ else
+ return E_NOINTERFACE;
+
+ return S_OK;
+}
+
+static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p)->(%d)\n", This, ref);
+ return ref;
+}
+
+static ULONG WINAPI foldercoll_enumvariant_Release(IEnumVARIANT *iface)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p)->(%d)\n", This, ref);
+
+ if (!ref)
+ {
+ IFolderCollection_Release(This->data.u.foldercoll.coll);
+ heap_free(This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI foldercoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ FIXME("(%p)->(%d %p %p): stub\n", This, celt, var, fetched);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldercoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ FIXME("(%p)->(%d): stub\n", This, celt);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldercoll_enumvariant_Reset(IEnumVARIANT *iface)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ FIXME("(%p): stub\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldercoll_enumvariant_Clone(IEnumVARIANT *iface, IEnumVARIANT **pclone)
+{
+ struct enumvariant *This = impl_from_IEnumVARIANT(iface);
+ FIXME("(%p)->(%p): stub\n", This, pclone);
+ return E_NOTIMPL;
+}
+
+static const IEnumVARIANTVtbl foldercollenumvariantvtbl = {
+ enumvariant_QueryInterface,
+ enumvariant_AddRef,
+ foldercoll_enumvariant_Release,
+ foldercoll_enumvariant_Next,
+ foldercoll_enumvariant_Skip,
+ foldercoll_enumvariant_Reset,
+ foldercoll_enumvariant_Clone
+};
+
+static HRESULT create_foldercoll_enum(struct foldercollection *collection, IUnknown **newenum)
+{
+ struct enumvariant *This;
+
+ *newenum = NULL;
+
+ This = heap_alloc(sizeof(*This));
+ if (!This) return E_OUTOFMEMORY;
+
+ This->IEnumVARIANT_iface.lpVtbl = &foldercollenumvariantvtbl;
+ This->ref = 1;
+ This->data.u.foldercoll.coll = &collection->IFolderCollection_iface;
+ IFolderCollection_AddRef(This->data.u.foldercoll.coll);
+
+ *newenum = (IUnknown*)&This->IEnumVARIANT_iface;
+
+ return S_OK;
+}
+
static HRESULT WINAPI foldercoll_QueryInterface(IFolderCollection *iface, REFIID riid, void **obj)
{
struct foldercollection *This = impl_from_IFolderCollection(iface);
@@ -468,8 +591,13 @@ static HRESULT WINAPI foldercoll_get_Item(IFolderCollection *iface, VARIANT key,
static HRESULT WINAPI foldercoll_get__NewEnum(IFolderCollection *iface, IUnknown **newenum)
{
struct foldercollection *This = impl_from_IFolderCollection(iface);
- FIXME("(%p)->(%p): stub\n", This, newenum);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p)\n", This, newenum);
+
+ if(!newenum)
+ return E_POINTER;
+
+ return create_foldercoll_enum(This, newenum);
}
static HRESULT WINAPI foldercoll_get_Count(IFolderCollection *iface, LONG *count)
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c
index 23cbd2c..b373df4 100644
--- a/dlls/scrrun/tests/filesystem.c
+++ b/dlls/scrrun/tests/filesystem.c
@@ -33,6 +33,15 @@
static IFileSystem3 *fs3;
+static inline ULONG get_refcount(IUnknown *iface)
+{
+ IUnknown_AddRef(iface);
+ return IUnknown_Release(iface);
+}
+
+#define GET_REFCOUNT(iface) \
+ get_refcount((IUnknown*)iface)
+
static void test_interfaces(void)
{
static const WCHAR nonexistent_dirW[] = {
@@ -781,7 +790,9 @@ static void test_FolderCollection(void)
static const WCHAR bW[] = {'\\','b',0};
IFolderCollection *folders;
WCHAR buffW[MAX_PATH], pathW[MAX_PATH], path2W[MAX_PATH];
- LONG count, count2;
+ IEnumVARIANT *enumvar, *clone;
+ LONG count, count2, ref, ref2;
+ IUnknown *unk, *unk2;
IFolder *folder;
HRESULT hr;
BSTR str;
@@ -818,6 +829,46 @@ static void test_FolderCollection(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(count2 > count, "got %d, %d\n", count, count2);
+ hr = IFolderCollection_get__NewEnum(folders, NULL);
+ ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+ hr = IFolderCollection_QueryInterface(folders, &IID_IEnumVARIANT, (void**)&unk);
+ ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
+
+ /* NewEnum creates new instance each time it's called */
+ ref = GET_REFCOUNT(folders);
+
+ unk = NULL;
+ hr = IFolderCollection_get__NewEnum(folders, &unk);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ ref2 = GET_REFCOUNT(folders);
+ ok(ref2 == ref + 1, "got %d, %d\n", ref2, ref);
+
+ unk2 = NULL;
+ hr = IFolderCollection_get__NewEnum(folders, &unk2);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(unk != unk2, "got %p, %p\n", unk2, unk);
+ IUnknown_Release(unk2);
+
+ /* now get IEnumVARIANT */
+ ref = GET_REFCOUNT(folders);
+ hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ref2 = GET_REFCOUNT(folders);
+ ok(ref2 == ref, "got %d, %d\n", ref2, ref);
+
+ /* clone enumerator */
+ hr = IEnumVARIANT_Clone(enumvar, &clone);
+todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+if (hr == S_OK) {
+ ok(clone != enumvar, "got %p, %p\n", enumvar, clone);
+ IEnumVARIANT_Release(clone);
+}
+ IEnumVARIANT_Release(enumvar);
+ IUnknown_Release(unk);
+
RemoveDirectoryW(pathW);
RemoveDirectoryW(path2W);
More information about the wine-cvs
mailing list