Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 89 +++++++++++------------------------ dlls/ole32/tests/moniker.c | 19 +++++++- 2 files changed, 46 insertions(+), 62 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index c6d0d3c47a6..80a1a675766 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -408,76 +408,43 @@ static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker *iface, IBindC return hr; }
-/****************************************************************************** - * CompositeMoniker_Reduce - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar, - IMoniker** ppmkToLeft, IMoniker** ppmkReduced) +static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD howfar, + IMoniker **toleft, IMoniker **reduced) { - HRESULT res; - IMoniker *tempMk,*antiMk,*rightMostMk,*leftReducedComposedMk,*rightMostReducedMk; - IEnumMoniker *enumMoniker; - - TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced); - - if (ppmkReduced==NULL) - return E_POINTER; - - /* This method recursively calls Reduce for each of its component monikers. */ - - if (ppmkToLeft==NULL){ + CompositeMonikerImpl *moniker = impl_from_IMoniker(iface); + IMoniker *m, *reduced_left, *reduced_right; + BOOL was_reduced; + HRESULT hr;
- IMoniker_Enum(iface,FALSE,&enumMoniker); - IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL); - IEnumMoniker_Release(enumMoniker); + TRACE("%p, %p, %d, %p, %p.\n", iface, pbc, howfar, toleft, reduced);
- CreateAntiMoniker(&antiMk); - IMoniker_ComposeWith(iface,antiMk,0,&tempMk); - IMoniker_Release(antiMk); + if (!pbc || !reduced) + return E_INVALIDARG;
- res = IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced); - IMoniker_Release(tempMk); - IMoniker_Release(rightMostMk); + if (FAILED(hr = IMoniker_Reduce(moniker->left, pbc, howfar, NULL, &reduced_left))) + return hr;
- return res; + m = moniker->left; + if (FAILED(hr = IMoniker_Reduce(moniker->right, pbc, howfar, &m, &reduced_right))) + { + IMoniker_Release(reduced_left); + return hr; } - else if (*ppmkToLeft==NULL)
- return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced); - - else{ - - /* separate the composite moniker in to left and right moniker */ - IMoniker_Enum(iface,FALSE,&enumMoniker); - IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL); - IEnumMoniker_Release(enumMoniker); - - CreateAntiMoniker(&antiMk); - IMoniker_ComposeWith(iface,antiMk,0,&tempMk); - IMoniker_Release(antiMk); - - /* If any of the components reduces itself, the method returns S_OK and passes back a composite */ - /* of the reduced components */ - if (IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,NULL,&rightMostReducedMk) && - IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk) ){ - IMoniker_Release(tempMk); - IMoniker_Release(rightMostMk); - - return CreateGenericComposite(leftReducedComposedMk,rightMostReducedMk,ppmkReduced); - } - else{ - /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/ - IMoniker_Release(tempMk); - IMoniker_Release(rightMostMk); - - IMoniker_AddRef(iface); + if ((was_reduced = (reduced_left != moniker->left || reduced_right != moniker->right))) + { + hr = CreateGenericComposite(reduced_left, reduced_right, reduced); + } + else + { + *reduced = iface; + IMoniker_AddRef(*reduced); + }
- *ppmkReduced=iface; + IMoniker_Release(reduced_left); + IMoniker_Release(reduced_right);
- return MK_S_REDUCED_TO_SELF; - } - } + return was_reduced ? hr : MK_S_REDUCED_TO_SELF; }
static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right, diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index ea58c09356e..7e4a42a0ee6 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3439,7 +3439,6 @@ todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, moniker1, &ft); -todo_wine ok(hr == MK_E_NOTBINDABLE, "Unexpected hr %#x.\n", hr);
hr = IRunningObjectTable_Revoke(rot, cookie); @@ -3629,6 +3628,24 @@ todo_wine {
IMoniker_Release(moniker);
+ /* Reduce() */ + hr = create_moniker_from_desc("CI1I2", &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_Reduce(moniker, NULL, MKRREDUCE_ALL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ALL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_Reduce(moniker, NULL, MKRREDUCE_ALL, NULL, &moniker2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ALL, NULL, &moniker2); + ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr); + ok(moniker2 == moniker, "Unexpected object.\n"); + IMoniker_Release(moniker2); + + IMoniker_Release(moniker); + IBindCtx_Release(bindctx); }