Dmitry Timoshkov : taskschd: Implement ITaskFolderCollection:: get__NewEnum.
Alexandre Julliard
julliard at winehq.org
Tue Jan 28 13:33:24 CST 2014
Module: wine
Branch: master
Commit: d33c0e14ae7088e608a6bfb30008774f1905eb1c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d33c0e14ae7088e608a6bfb30008774f1905eb1c
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Tue Jan 28 11:54:48 2014 +0900
taskschd: Implement ITaskFolderCollection::get__NewEnum.
---
dlls/taskschd/folder_collection.c | 157 ++++++++++++++++++++++++++++++++++++-
dlls/taskschd/tests/scheduler.c | 4 -
2 files changed, 155 insertions(+), 6 deletions(-)
diff --git a/dlls/taskschd/folder_collection.c b/dlls/taskschd/folder_collection.c
index e8e4933..c8cc89b 100644
--- a/dlls/taskschd/folder_collection.c
+++ b/dlls/taskschd/folder_collection.c
@@ -42,6 +42,8 @@ typedef struct
LONG count;
} TaskFolderCollection;
+static HRESULT NewEnum_create(TaskFolderCollection *folders, IUnknown **obj);
+
static inline TaskFolderCollection *impl_from_ITaskFolderCollection(ITaskFolderCollection *iface)
{
return CONTAINING_RECORD(iface, TaskFolderCollection, ITaskFolderCollection_iface);
@@ -190,8 +192,13 @@ static HRESULT WINAPI folders_get_Item(ITaskFolderCollection *iface, VARIANT ind
static HRESULT WINAPI folders_get__NewEnum(ITaskFolderCollection *iface, IUnknown **penum)
{
- FIXME("%p,%p: stub\n", iface, penum);
- return E_NOTIMPL;
+ TaskFolderCollection *folders = impl_from_ITaskFolderCollection(iface);
+
+ TRACE("%p,%p\n", iface, penum);
+
+ if (!penum) return E_POINTER;
+
+ return NewEnum_create(folders, penum);
}
static const ITaskFolderCollectionVtbl TaskFolderCollection_vtbl =
@@ -319,3 +326,149 @@ HRESULT TaskFolderCollection_create(const WCHAR *path, ITaskFolderCollection **o
return S_OK;
}
+
+typedef struct
+{
+ IEnumVARIANT IEnumVARIANT_iface;
+ LONG ref, pos;
+ TaskFolderCollection *folders;
+} EnumVARIANT;
+
+static inline EnumVARIANT *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
+{
+ return CONTAINING_RECORD(iface, EnumVARIANT, IEnumVARIANT_iface);
+}
+
+static HRESULT WINAPI enumvar_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
+{
+ if (!riid || !obj) return E_INVALIDARG;
+
+ TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualGUID(riid, &IID_IEnumVARIANT) ||
+ IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IEnumVARIANT_AddRef(iface);
+ *obj = iface;
+ return S_OK;
+ }
+
+ FIXME("interface %s is not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI enumvar_AddRef(IEnumVARIANT *iface)
+{
+ EnumVARIANT *enumvar = impl_from_IEnumVARIANT(iface);
+ return InterlockedIncrement(&enumvar->ref);
+}
+
+static ULONG WINAPI enumvar_Release(IEnumVARIANT *iface)
+{
+ EnumVARIANT *enumvar = impl_from_IEnumVARIANT(iface);
+ LONG ref = InterlockedDecrement(&enumvar->ref);
+
+ if (!ref)
+ {
+ TRACE("destroying %p\n", iface);
+ ITaskFolderCollection_Release(&enumvar->folders->ITaskFolderCollection_iface);
+ heap_free(enumvar);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI enumvar_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
+{
+ EnumVARIANT *enumvar = impl_from_IEnumVARIANT(iface);
+ LONG i;
+
+ TRACE("%p,%u,%p,%p\n", iface, celt, var, fetched);
+
+ for (i = 0; i < celt && enumvar->pos < enumvar->folders->count; i++)
+ {
+ ITaskFolder *folder;
+ HRESULT hr;
+
+ hr = TaskFolder_create(enumvar->folders->path, enumvar->folders->list[enumvar->pos++], &folder, FALSE);
+ if (hr) return hr;
+
+ if (!var)
+ {
+ ITaskFolder_Release(folder);
+ return E_POINTER;
+ }
+
+ V_VT(&var[i]) = VT_DISPATCH;
+ V_DISPATCH(&var[i]) = (IDispatch *)folder;
+ }
+
+ if (fetched) *fetched = i;
+
+ return i == celt ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI enumvar_Skip(IEnumVARIANT *iface, ULONG celt)
+{
+ EnumVARIANT *enumvar = impl_from_IEnumVARIANT(iface);
+
+ TRACE("%p,%u\n", iface, celt);
+
+ enumvar->pos += celt;
+
+ if (enumvar->pos > enumvar->folders->count)
+ {
+ enumvar->pos = enumvar->folders->count;
+ return S_FALSE;
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI enumvar_Reset(IEnumVARIANT *iface)
+{
+ EnumVARIANT *enumvar = impl_from_IEnumVARIANT(iface);
+
+ TRACE("%p\n", iface);
+
+ enumvar->pos = 0;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI enumvar_Clone(IEnumVARIANT *iface, IEnumVARIANT **penum)
+{
+ FIXME("%p,%p: stub\n", iface, penum);
+ return E_NOTIMPL;
+}
+
+static const struct IEnumVARIANTVtbl EnumVARIANT_vtbl =
+{
+ enumvar_QueryInterface,
+ enumvar_AddRef,
+ enumvar_Release,
+ enumvar_Next,
+ enumvar_Skip,
+ enumvar_Reset,
+ enumvar_Clone
+};
+
+static HRESULT NewEnum_create(TaskFolderCollection *folders, IUnknown **obj)
+{
+ EnumVARIANT *enumvar;
+
+ enumvar = heap_alloc(sizeof(*enumvar));
+ if (!enumvar) return E_OUTOFMEMORY;
+
+ enumvar->IEnumVARIANT_iface.lpVtbl = &EnumVARIANT_vtbl;
+ enumvar->ref = 1;
+ enumvar->pos = 0;
+ enumvar->folders = folders;
+ ITaskFolderCollection_AddRef(&folders->ITaskFolderCollection_iface);
+
+ *obj = (IUnknown *)&enumvar->IEnumVARIANT_iface;
+
+ TRACE("created %p\n", *obj);
+
+ return S_OK;
+}
diff --git a/dlls/taskschd/tests/scheduler.c b/dlls/taskschd/tests/scheduler.c
index d9f622e..f30a1be 100644
--- a/dlls/taskschd/tests/scheduler.c
+++ b/dlls/taskschd/tests/scheduler.c
@@ -544,10 +544,7 @@ static void test_FolderCollection(void)
ok(hr == E_NOINTERFACE, "expected E_NOINTERFACE, got %#x\n", hr);
hr = ITaskFolderCollection_get__NewEnum(folders, &unknown);
-todo_wine
ok(hr == S_OK, "get__NewEnum error %#x\n", hr);
- /* FIXME: remove once implemented */
- if (hr != S_OK) goto failed;
hr = IUnknown_QueryInterface(unknown, &IID_IEnumUnknown, (void **)&enumvar);
ok(hr == E_NOINTERFACE, "expected E_NOINTERFACE, got %#x\n", hr);
hr = IUnknown_QueryInterface(unknown, &IID_IEnumVARIANT, (void **)&enumvar);
@@ -592,7 +589,6 @@ todo_wine
IDispatch_Release(V_DISPATCH(&var[0]));
IDispatch_Release(V_DISPATCH(&var[1]));
-failed:
ITaskFolderCollection_Release(folders);
hr = ITaskFolder_DeleteFolder(root, Wine_Folder1, 0);
More information about the wine-cvs
mailing list