diff --git a/dlls/ole32/itemmoniker.c b/dlls/ole32/itemmoniker.c index c42cc75c224..770b042aac7 100644 --- a/dlls/ole32/itemmoniker.c +++ b/dlls/ole32/itemmoniker.c @@ -511,77 +511,23 @@ static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, return MK_S_REDUCED_TO_SELF; } -/****************************************************************************** - * ItemMoniker_ComposeWith - ******************************************************************************/ -static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, - IMoniker* pmkRight, - BOOL fOnlyIfNotGeneric, - IMoniker** ppmkComposite) + +static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right, + BOOL only_if_not_generic, IMoniker **result) { - HRESULT res=S_OK; - DWORD mkSys,mkSys2, order; - IEnumMoniker* penumMk=0; - IMoniker *pmostLeftMk=0; - IMoniker* tempMkComposite=0; + DWORD order; - TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite); + TRACE("%p, %p, %d, %p\n", iface, right, only_if_not_generic, result); - if ((ppmkComposite==NULL)||(pmkRight==NULL)) - return E_POINTER; + 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(mkSys==MKSYS_GENERICCOMPOSITE){ + if (is_anti_moniker(right, &order)) + return order > 1 ? create_anti_moniker(order - 1, result) : S_OK; - 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 4d40dcb6e4b..1b44c80fe45 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -127,6 +127,43 @@ static IMoniker *create_antimoniker(DWORD level) return moniker; } +static HRESULT create_moniker_from_desc(const char *desc, unsigned int *eaten, + IMoniker **moniker) +{ + IMoniker *left, *right; + WCHAR nameW[3]; + HRESULT hr; + + desc += *eaten; + + switch (*desc) + { + case 'I': + nameW[0] = desc[0]; + nameW[1] = desc[1]; + nameW[2] = 0; + *eaten += 2; + return CreateItemMoniker(L"!", nameW, moniker); + case 'A': + *eaten += 2; + *moniker = create_antimoniker(desc[1] - '0'); + return S_OK; + case 'C': + (*eaten)++; + hr = create_moniker_from_desc(desc, eaten, &left); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc(desc, eaten, &right); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = CreateGenericComposite(left, right, moniker); + IMoniker_Release(left); + IMoniker_Release(right); + return hr; + default: + ok(0, "Unexpected description %s.\n", desc); + return E_NOTIMPL; + } +} + static SIZE_T round_global_size(SIZE_T size) { static SIZE_T global_size_alignment = -1; @@ -2267,7 +2304,7 @@ static void test_item_moniker(void) "Moniker_IsRunning", NULL }; - IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse; + IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse, *c; DWORD i, hash, eaten, cookie; HRESULT hr; IBindCtx *bindctx; @@ -2589,7 +2626,7 @@ todo_wine ok(!moniker2, "Unexpected pointer.\n"); IMoniker_Release(anti); - /* I + A2 -> (A) */ + /* I + A2 -> A */ anti = create_antimoniker(2); hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2); ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr); @@ -2601,6 +2638,24 @@ todo_wine IMoniker_Release(anti); + /* I + (A,A3) -> A3 */ + + /* Simplification has to through generic composite logic, + even when resolved to non-composite, generic composite option has to be enabled. */ + 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); + IMoniker_Release(moniker); /* CommonPrefixWith */ @@ -2893,43 +2948,6 @@ todo_wine IMoniker_Release(moniker2); } -static HRESULT create_moniker_from_desc(const char *desc, unsigned int *eaten, - IMoniker **moniker) -{ - IMoniker *left, *right; - WCHAR nameW[3]; - HRESULT hr; - - desc += *eaten; - - switch (*desc) - { - case 'I': - nameW[0] = desc[0]; - nameW[1] = desc[1]; - nameW[2] = 0; - *eaten += 2; - return CreateItemMoniker(L"!", nameW, moniker); - case 'A': - *eaten += 2; - *moniker = create_antimoniker(desc[1] - '0'); - return S_OK; - case 'C': - (*eaten)++; - hr = create_moniker_from_desc(desc, eaten, &left); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - hr = create_moniker_from_desc(desc, eaten, &right); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - hr = CreateGenericComposite(left, right, moniker); - IMoniker_Release(left); - IMoniker_Release(right); - return hr; - default: - ok(0, "Unexpected description %s.\n", desc); - return E_NOTIMPL; - } -} - static void test_generic_composite_moniker(void) { static const struct simplify_test @@ -3154,7 +3172,6 @@ todo_wine /* See if non-generic composition is possible */ hr = IMoniker_ComposeWith(moniker1, moniker, TRUE, &moniker2); -todo_wine ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr); hr = IBindCtx_GetRunningObjectTable(bindctx, &rot);