ole32/pointermoniker: Always use generic composition in ComposeWith().

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-24 15:51:42 +03:00 committed by Alexandre Julliard
parent 7bf6fb787c
commit 59bf44b569
2 changed files with 43 additions and 69 deletions

View File

@ -241,80 +241,23 @@ PointerMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* PointerMoniker_ComposeWith
******************************************************************************/
static HRESULT WINAPI
PointerMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
static HRESULT WINAPI PointerMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
BOOL only_if_not_generic, IMoniker **result)
{
DWORD order;
HRESULT res=S_OK;
DWORD mkSys,mkSys2, order;
IEnumMoniker* penumMk=0;
IMoniker *pmostLeftMk=0;
IMoniker* tempMkComposite=0;
TRACE("%p, %p, %d, %p.\n", iface, right, only_if_not_generic, result);
TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);
if ((ppmkComposite==NULL)||(pmkRight==NULL))
if (!result || !right)
return E_POINTER;
*ppmkComposite=0;
*result = NULL;
if (is_anti_moniker(pmkRight, &order))
{
return order > 1 ? create_anti_moniker(order - 1, ppmkComposite) : S_OK;
}
else
{
/* if pmkRight is a composite whose leftmost component is an anti-moniker, */
/* the returned moniker is the composite after the leftmost anti-moniker is removed. */
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
if (is_anti_moniker(right, &order))
return order > 1 ? create_anti_moniker(order - 1, result) : S_OK;
if(mkSys==MKSYS_GENERICCOMPOSITE){
res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
if (FAILED(res))
return res;
res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
if(mkSys2==MKSYS_ANTIMONIKER){
IMoniker_Release(pmostLeftMk);
tempMkComposite=iface;
IMoniker_AddRef(iface);
while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
IMoniker_Release(tempMkComposite);
IMoniker_Release(pmostLeftMk);
tempMkComposite=*ppmkComposite;
IMoniker_AddRef(tempMkComposite);
}
return res;
}
else
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
a NULL moniker and a return value of MK_E_NEEDGENERIC */
else
if (!fOnlyIfNotGeneric)
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
else
return MK_E_NEEDGENERIC;
}
return only_if_not_generic ? MK_E_NEEDGENERIC : CreateGenericComposite(iface, right, result);
}
/******************************************************************************

View File

@ -3213,7 +3213,7 @@ todo_wine
static void test_pointer_moniker(void)
{
IMoniker *moniker, *moniker2, *prefix, *inverse, *anti;
IMoniker *moniker, *moniker2, *prefix, *inverse, *anti, *c;
struct test_factory factory;
IEnumMoniker *enummoniker;
DWORD hash, size;
@ -3224,6 +3224,7 @@ static void test_pointer_moniker(void)
IStream *stream;
IROTData *rotdata;
LPOLESTR display_name;
unsigned int eaten;
IMarshal *marshal;
LARGE_INTEGER pos;
CLSID clsid;
@ -3412,6 +3413,36 @@ static void test_pointer_moniker(void)
IMoniker_Release(anti);
/* Simplification has to through generic composite logic,
even when resolved to non-composite, generic composite option has to be enabled. */
/* P + (A,A3) -> A3 */
eaten = 0;
hr = create_moniker_from_desc("CA1A3", &eaten, &c);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMoniker_ComposeWith(moniker, c, TRUE, &moniker2);
ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
hr = IMoniker_ComposeWith(moniker, c, FALSE, &moniker2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
hr = IMoniker_Hash(moniker2, &hash);
ok(hr == S_OK, "Failed to get hash, hr %#x.\n", hr);
ok(hash == 0x80000003, "Unexpected hash.\n");
IMoniker_Release(moniker2);
IMoniker_Release(c);
/* P + (A,I) -> I */
eaten = 0;
hr = create_moniker_from_desc("CA1I1", &eaten, &c);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMoniker_ComposeWith(moniker, c, TRUE, &moniker2);
ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
hr = IMoniker_ComposeWith(moniker, c, FALSE, &moniker2);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
TEST_MONIKER_TYPE(moniker2, MKSYS_ITEMMONIKER);
IMoniker_Release(moniker2);
IMoniker_Release(c);
IMoniker_Release(moniker);
}