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:
parent
441ef40813
commit
7de48a7416
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue