Module: wine Branch: master Commit: 47e1ac9f98ddc158bb69ae8c6594dc598af9e99d URL: http://source.winehq.org/git/wine.git/?a=commit;h=47e1ac9f98ddc158bb69ae8c65...
Author: Nikolay Sivov nsivov@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);