[PATCH 1/5] ole32/composite: Fix argument handling in component enumerator methods.

Nikolay Sivov nsivov at codeweavers.com
Thu Sep 30 03:26:45 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/ole32/compositemoniker.c |  60 ++++++-----
 dlls/ole32/tests/moniker.c    | 192 +++++++++++++++++++++++++++++++---
 2 files changed, 209 insertions(+), 43 deletions(-)

diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c
index 80a1a675766..e5437c8880f 100644
--- a/dlls/ole32/compositemoniker.c
+++ b/dlls/ole32/compositemoniker.c
@@ -495,7 +495,7 @@ static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, I
     TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker);
 
     if (!ppenumMoniker)
-        return E_POINTER;
+        return E_INVALIDARG;
 
     if (FAILED(hr = composite_get_components_alloc(moniker, &monikers)))
         return hr;
@@ -1346,44 +1346,45 @@ EnumMonikerImpl_Release(IEnumMoniker* iface)
     return ref;
 }
 
-/******************************************************************************
- *        EnumMonikerImpl_Next
- ******************************************************************************/
-static HRESULT WINAPI
-EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
-               ULONG* pceltFethed)
+static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count,
+        IMoniker **m, ULONG *fetched)
 {
     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
     ULONG i;
 
+    TRACE("%p, %u, %p, %p.\n", iface, count, m, fetched);
+
+    if (!m)
+        return E_INVALIDARG;
+
+    *m = NULL;
+
     /* retrieve the requested number of moniker from the current position */
-    for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
+    for(i=0;((This->currentPos < This->tabSize) && (i < count));i++)
     {
-        rgelt[i]=This->tabMoniker[This->currentPos++];
-        IMoniker_AddRef(rgelt[i]);
+        m[i] = This->tabMoniker[This->currentPos++];
+        IMoniker_AddRef(m[i]);
     }
 
-    if (pceltFethed!=NULL)
-        *pceltFethed= i;
+    if (fetched)
+        *fetched = i;
 
-    if (i==celt)
-        return S_OK;
-    else
-        return S_FALSE;
+    return i == count ? S_OK : S_FALSE;
 }
 
-/******************************************************************************
- *        EnumMonikerImpl_Skip
- ******************************************************************************/
-static HRESULT WINAPI
-EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt)
+static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG count)
 {
     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
 
-    if ((This->currentPos+celt) >= This->tabSize)
+    TRACE("%p, %u.\n", iface, count);
+
+    if (!count)
+        return S_OK;
+
+    if ((This->currentPos + count) >= This->tabSize)
         return S_FALSE;
 
-    This->currentPos+=celt;
+    This->currentPos += count;
 
     return S_OK;
 }
@@ -1401,15 +1402,16 @@ EnumMonikerImpl_Reset(IEnumMoniker* iface)
     return S_OK;
 }
 
-/******************************************************************************
- *        EnumMonikerImpl_Clone
- ******************************************************************************/
-static HRESULT WINAPI
-EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum)
+static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker *iface, IEnumMoniker **ret)
 {
     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
 
-    return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
+    TRACE("%p, %p.\n", iface, ret);
+
+    if (!ret)
+        return E_INVALIDARG;
+
+    return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ret);
 }
 
 static const IEnumMonikerVtbl VT_EnumMonikerImpl =
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 7e4a42a0ee6..ed2accff6a9 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -3163,8 +3163,8 @@ static void test_generic_composite_moniker(void)
         { "CI1I3", "CA1I2", MKSYS_GENERICCOMPOSITE, L"!I1!I2" },
     };
     IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3, *moniker4;
+    IEnumMoniker *enummoniker, *enummoniker2;
     struct test_moniker *m, *m2;
-    IEnumMoniker *enummoniker;
     IRunningObjectTable *rot;
     DWORD hash, cookie;
     HRESULT hr;
@@ -3293,19 +3293,6 @@ todo_wine
     TEST_MONIKER_TYPE(inverse, MKSYS_GENERICCOMPOSITE);
     IMoniker_Release(inverse);
 
-    /* Enum() */
-    hr = IMoniker_Enum(moniker, TRUE, &enummoniker);
-    ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr);
-    IEnumMoniker_Release(enummoniker);
-
-    hr = IMoniker_Enum(moniker, FALSE, &enummoniker);
-    ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr);
-    IEnumMoniker_Release(enummoniker);
-
-    hr = IMoniker_Enum(moniker, FALSE, NULL);
-todo_wine
-    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
-
     /* BindToObject() */
     hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
@@ -3646,6 +3633,183 @@ todo_wine {
 
     IMoniker_Release(moniker);
 
+    /* Enum() */
+    hr = create_moniker_from_desc("CI1CI2I3", &moniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMoniker_Enum(moniker, FALSE, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    /* Forward direction */
+    hr = IMoniker_Enum(moniker, TRUE, &enummoniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Next(enummoniker, 0, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    moniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+
+    len = 1;
+    moniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!len, "Unexpected count %u.\n", len);
+    ok(!moniker2, "Unexpected pointer.\n");
+
+    hr = IEnumMoniker_Skip(enummoniker, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I1");
+    IMoniker_Release(moniker2);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I2");
+    IMoniker_Release(moniker2);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I3");
+    IMoniker_Release(moniker2);
+
+    len = 1;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+    ok(!len, "Unexpected count %u.\n", len);
+
+    hr = IEnumMoniker_Skip(enummoniker, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Skip(enummoniker, 1);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Clone(enummoniker, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    enummoniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Clone(enummoniker, &enummoniker2);
+todo_wine {
+    ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
+    ok(!enummoniker2, "Unexpected pointer.\n");
+}
+    hr = IEnumMoniker_Reset(enummoniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Skip(enummoniker, 2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I3");
+    IMoniker_Release(moniker2);
+
+    enummoniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Clone(enummoniker, &enummoniker2);
+todo_wine {
+    ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
+    ok(!enummoniker2, "Unexpected pointer.\n");
+}
+    IEnumMoniker_Release(enummoniker);
+
+    /* Backward direction */
+    hr = IMoniker_Enum(moniker, FALSE, &enummoniker);
+    ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Next(enummoniker, 0, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    moniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+
+    len = 1;
+    moniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!len, "Unexpected count %u.\n", len);
+    ok(!moniker2, "Unexpected pointer.\n");
+
+    hr = IEnumMoniker_Skip(enummoniker, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I3");
+    IMoniker_Release(moniker2);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I2");
+    IMoniker_Release(moniker2);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I1");
+    IMoniker_Release(moniker2);
+
+    len = 1;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+    ok(!len, "Unexpected count %u.\n", len);
+
+    hr = IEnumMoniker_Skip(enummoniker, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Skip(enummoniker, 1);
+    ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Clone(enummoniker, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    enummoniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Clone(enummoniker, &enummoniker2);
+todo_wine {
+    ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
+    ok(!enummoniker2, "Unexpected pointer.\n");
+}
+    hr = IEnumMoniker_Reset(enummoniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IEnumMoniker_Skip(enummoniker, 2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    len = 0;
+    hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(len == 1, "Unexpected count %u.\n", len);
+    TEST_DISPLAY_NAME(moniker2, L"!I1");
+    IMoniker_Release(moniker2);
+
+    enummoniker2 = (void *)0xdeadbeef;
+    hr = IEnumMoniker_Clone(enummoniker, &enummoniker2);
+todo_wine {
+    ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
+    ok(!enummoniker2, "Unexpected pointer.\n");
+}
+    IEnumMoniker_Release(enummoniker);
+
+    IMoniker_Release(moniker);
+
     IBindCtx_Release(bindctx);
 }
 
-- 
2.33.0




More information about the wine-devel mailing list