diff --git a/dlls/ole32/pointermoniker.c b/dlls/ole32/pointermoniker.c index 34692c4965b..14cf8af9eaa 100644 --- a/dlls/ole32/pointermoniker.c +++ b/dlls/ole32/pointermoniker.c @@ -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 (!result || !right) + return E_POINTER; - if ((ppmkComposite==NULL)||(pmkRight==NULL)) - return E_POINTER; + *result = NULL; - *ppmkComposite=0; + if (is_anti_moniker(right, &order)) + return order > 1 ? create_anti_moniker(order - 1, result) : S_OK; - 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(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); } /****************************************************************************** diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 1b44c80fe45..272c4e4c568 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -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); }