ole32/composite: Reimplement Reduce().

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-29 10:23:27 +03:00 committed by Alexandre Julliard
parent 5855196be9
commit f95fe051f0
2 changed files with 47 additions and 63 deletions

View file

@ -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;
CompositeMonikerImpl *moniker = impl_from_IMoniker(iface);
IMoniker *m, *reduced_left, *reduced_right;
BOOL was_reduced;
HRESULT hr;
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("%p, %p, %d, %p, %p.\n", iface, pbc, howfar, toleft, reduced);
if (ppmkReduced==NULL)
return E_POINTER;
if (!pbc || !reduced)
return E_INVALIDARG;
/* This method recursively calls Reduce for each of its component monikers. */
if (FAILED(hr = IMoniker_Reduce(moniker->left, pbc, howfar, NULL, &reduced_left)))
return hr;
if (ppmkToLeft==NULL){
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);
res = IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
IMoniker_Release(tempMk);
IMoniker_Release(rightMostMk);
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);
*ppmkReduced=iface;
return MK_S_REDUCED_TO_SELF;
}
if ((was_reduced = (reduced_left != moniker->left || reduced_right != moniker->right)))
{
hr = CreateGenericComposite(reduced_left, reduced_right, reduced);
}
else
{
*reduced = iface;
IMoniker_AddRef(*reduced);
}
IMoniker_Release(reduced_left);
IMoniker_Release(reduced_right);
return was_reduced ? hr : MK_S_REDUCED_TO_SELF;
}
static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,

View file

@ -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);
}