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