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