scrrun: Implement IEnumVARIANT stub for folder collection.

This commit is contained in:
Nikolay Sivov 2014-01-03 16:35:07 +04:00 committed by Alexandre Julliard
parent 51f5ab1999
commit 47e1ac9f98
2 changed files with 182 additions and 3 deletions

View file

@ -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)

View file

@ -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);