ole32/composite: Fix argument handling in component enumerator methods.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-09-30 11:26:45 +03:00 committed by Alexandre Julliard
parent 441ef40813
commit 7de48a7416
2 changed files with 209 additions and 43 deletions

View File

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

View File

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