Signed-off-by: Nikolay Sivov <nsivov(a)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