ole32/itemmoniker: 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:
parent
a27708dc9b
commit
7bf6fb787c
|
@ -511,77 +511,23 @@ static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
|
||||||
|
|
||||||
return MK_S_REDUCED_TO_SELF;
|
return MK_S_REDUCED_TO_SELF;
|
||||||
}
|
}
|
||||||
/******************************************************************************
|
|
||||||
* ItemMoniker_ComposeWith
|
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
|
||||||
******************************************************************************/
|
BOOL only_if_not_generic, IMoniker **result)
|
||||||
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
|
|
||||||
IMoniker* pmkRight,
|
|
||||||
BOOL fOnlyIfNotGeneric,
|
|
||||||
IMoniker** ppmkComposite)
|
|
||||||
{
|
{
|
||||||
HRESULT res=S_OK;
|
DWORD order;
|
||||||
DWORD mkSys,mkSys2, order;
|
|
||||||
IEnumMoniker* penumMk=0;
|
|
||||||
IMoniker *pmostLeftMk=0;
|
|
||||||
IMoniker* tempMkComposite=0;
|
|
||||||
|
|
||||||
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))
|
if (!result || !right)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
*ppmkComposite=0;
|
*result = NULL;
|
||||||
|
|
||||||
if (is_anti_moniker(pmkRight, &order))
|
if (is_anti_moniker(right, &order))
|
||||||
{
|
return order > 1 ? create_anti_moniker(order - 1, result) : S_OK;
|
||||||
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);
|
return only_if_not_generic ? MK_E_NEEDGENERIC : CreateGenericComposite(iface, right, result);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -127,6 +127,43 @@ static IMoniker *create_antimoniker(DWORD level)
|
||||||
return moniker;
|
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 round_global_size(SIZE_T size)
|
||||||
{
|
{
|
||||||
static SIZE_T global_size_alignment = -1;
|
static SIZE_T global_size_alignment = -1;
|
||||||
|
@ -2267,7 +2304,7 @@ static void test_item_moniker(void)
|
||||||
"Moniker_IsRunning",
|
"Moniker_IsRunning",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse;
|
IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse, *c;
|
||||||
DWORD i, hash, eaten, cookie;
|
DWORD i, hash, eaten, cookie;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IBindCtx *bindctx;
|
IBindCtx *bindctx;
|
||||||
|
@ -2589,7 +2626,7 @@ todo_wine
|
||||||
ok(!moniker2, "Unexpected pointer.\n");
|
ok(!moniker2, "Unexpected pointer.\n");
|
||||||
IMoniker_Release(anti);
|
IMoniker_Release(anti);
|
||||||
|
|
||||||
/* I + A2 -> (A) */
|
/* I + A2 -> A */
|
||||||
anti = create_antimoniker(2);
|
anti = create_antimoniker(2);
|
||||||
hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
|
hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
|
||||||
ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
|
||||||
|
@ -2601,6 +2638,24 @@ todo_wine
|
||||||
|
|
||||||
IMoniker_Release(anti);
|
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);
|
IMoniker_Release(moniker);
|
||||||
|
|
||||||
/* CommonPrefixWith */
|
/* CommonPrefixWith */
|
||||||
|
@ -2893,43 +2948,6 @@ todo_wine
|
||||||
IMoniker_Release(moniker2);
|
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 void test_generic_composite_moniker(void)
|
||||||
{
|
{
|
||||||
static const struct simplify_test
|
static const struct simplify_test
|
||||||
|
@ -3154,7 +3172,6 @@ todo_wine
|
||||||
|
|
||||||
/* See if non-generic composition is possible */
|
/* See if non-generic composition is possible */
|
||||||
hr = IMoniker_ComposeWith(moniker1, moniker, TRUE, &moniker2);
|
hr = IMoniker_ComposeWith(moniker1, moniker, TRUE, &moniker2);
|
||||||
todo_wine
|
|
||||||
ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
|
ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IBindCtx_GetRunningObjectTable(bindctx, &rot);
|
hr = IBindCtx_GetRunningObjectTable(bindctx, &rot);
|
||||||
|
|
Loading…
Reference in New Issue