Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 61 +++++++---------------- dlls/ole32/tests/moniker.c | 92 ++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 56 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 40889ae42b2..b2ec02e1150 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -740,57 +740,32 @@ static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker *iface, return hr; }
-/****************************************************************************** - * CompositeMoniker_Inverse - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +static HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker *iface, IMoniker **inverse) { - HRESULT res; - IMoniker *tempMk,*antiMk,*rightMostMk,*tempInvMk,*rightMostInvMk; - IEnumMoniker *enumMoniker; - - TRACE("(%p,%p)\n",iface,ppmk); - - if (ppmk==NULL) - return E_POINTER; - - /* This method returns a composite moniker that consists of the inverses of each of the components */ - /* of the original composite, stored in reverse order */ - - *ppmk = NULL; - - res=CreateAntiMoniker(&antiMk); - if (FAILED(res)) - return res; - - res=IMoniker_ComposeWith(iface,antiMk,FALSE,&tempMk); - IMoniker_Release(antiMk); - if (FAILED(res)) - return res; - - if (tempMk==NULL) + CompositeMonikerImpl *moniker = impl_from_IMoniker(iface); + IMoniker *right_inverted, *left_inverted; + HRESULT hr;
- return IMoniker_Inverse(iface,ppmk); + TRACE("%p, %p.\n", iface, inverse);
- else{ + if (!inverse) + return E_INVALIDARG;
- IMoniker_Enum(iface,FALSE,&enumMoniker); - IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL); - IEnumMoniker_Release(enumMoniker); + *inverse = NULL;
- IMoniker_Inverse(rightMostMk,&rightMostInvMk); - CompositeMonikerImpl_Inverse(tempMk,&tempInvMk); + if (FAILED(hr = IMoniker_Inverse(moniker->right, &right_inverted))) return hr; + if (FAILED(hr = IMoniker_Inverse(moniker->left, &left_inverted))) + { + IMoniker_Release(right_inverted); + return hr; + }
- res=CreateGenericComposite(rightMostInvMk,tempInvMk,ppmk); + hr = CreateGenericComposite(right_inverted, left_inverted, inverse);
- IMoniker_Release(tempMk); - IMoniker_Release(rightMostMk); - IMoniker_Release(tempInvMk); - IMoniker_Release(rightMostInvMk); + IMoniker_Release(left_inverted); + IMoniker_Release(right_inverted);
- return res; - } + return hr; }
static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 7d88c132d3d..7f0b9ec5841 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -53,18 +53,21 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
-#define CHECK_EXPECTED_METHOD(method_name) \ -do { \ - ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \ - if (*expected_method_list) \ - { \ - ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \ - *expected_method_list, method_name); \ - expected_method_list++; \ - } \ -} while(0) - static char const * const *expected_method_list; + +#define CHECK_EXPECTED_METHOD(method_name) check_expected_method_(__LINE__, method_name) +static void check_expected_method_(unsigned int line, const char *method_name) +{ + if (!expected_method_list) return; + ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); + if (*expected_method_list) + { + ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", + *expected_method_list, method_name); + expected_method_list++; + } +} + static const WCHAR wszFileName1[] = {'c',':','\','w','i','n','d','o','w','s','\','t','e','s','t','1','.','d','o','c',0}; static const WCHAR wszFileName2[] = {'c',':','\','w','i','n','d','o','w','s','\','t','e','s','t','2','.','d','o','c',0};
@@ -384,6 +387,7 @@ struct test_moniker IOleItemContainer IOleItemContainer_iface; IParseDisplayName IParseDisplayName_iface; LONG refcount; + const char *inverse;
BOOL no_IROTData; }; @@ -665,7 +669,7 @@ Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight, BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite) { CHECK_EXPECTED_METHOD("Moniker_ComposeWith"); - return E_NOTIMPL; + return MK_E_NEEDGENERIC; }
static HRESULT WINAPI @@ -714,8 +718,9 @@ Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, static HRESULT WINAPI Moniker_Inverse(IMoniker* iface,IMoniker** ppmk) { + struct test_moniker *moniker = impl_from_IMoniker(iface); CHECK_EXPECTED_METHOD("Moniker_Inverse"); - return E_NOTIMPL; + return create_moniker_from_desc(moniker->inverse, ppmk); }
static HRESULT WINAPI @@ -933,6 +938,7 @@ static void test_ROT(void) hr = IRunningObjectTable_IsRunning(pROT, &test_moniker->IMoniker_iface); ok_ole_success(hr, IRunningObjectTable_IsRunning); ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list); + expected_method_list = NULL;
hr = IRunningObjectTable_Revoke(pROT, dwCookie); ok_ole_success(hr, IRunningObjectTable_Revoke); @@ -2545,6 +2551,7 @@ static void test_item_moniker(void) expected_method_list = methods_isrunning; hr = IMoniker_IsRunning(moniker, bindctx, &container_moniker->IMoniker_iface, moniker2); ok(hr == 0x8beef000, "Unexpected hr %#x.\n", hr); + expected_method_list = NULL;
IMoniker_Release(moniker2);
@@ -3043,6 +3050,7 @@ static void test_generic_composite_moniker(void) { "CI1I3", "CA1I2", MKSYS_GENERICCOMPOSITE, L"!I1!I2" }, }; IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3; + struct test_moniker *m, *m2; IEnumMoniker *enummoniker; IRunningObjectTable *rot; DWORD hash, cookie; @@ -3377,6 +3385,64 @@ todo_wine IMoniker_Release(moniker2); IMoniker_Release(moniker1);
+ /* Inverse() */ + hr = create_moniker_from_desc("CI1I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_Inverse(moniker1, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_Inverse(moniker1, &inverse); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + TEST_MONIKER_TYPE(inverse, MKSYS_GENERICCOMPOSITE); + TEST_DISPLAY_NAME(inverse, L"\..\.."); + IMoniker_Release(inverse); + IMoniker_Release(moniker1); + + hr = create_moniker_from_desc("CA1A2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + inverse = (void *)0xdeadbeef; + hr = IMoniker_Inverse(moniker1, &inverse); + ok(hr == MK_E_NOINVERSE, "Unexpected hr %#x.\n", hr); + ok(!inverse, "Unexpected pointer.\n"); + IMoniker_Release(moniker1); + + hr = create_moniker_from_desc("CI1A2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + inverse = (void *)0xdeadbeef; + hr = IMoniker_Inverse(moniker1, &inverse); + ok(hr == MK_E_NOINVERSE, "Unexpected hr %#x.\n", hr); + ok(!inverse, "Unexpected pointer.\n"); + IMoniker_Release(moniker1); + + /* Now with custom moniker to observe inverse order */ + m = create_test_moniker(); + m->inverse = "I5"; + hr = create_moniker_from_desc("I1", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = CreateGenericComposite(moniker1, &m->IMoniker_iface, &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + TEST_MONIKER_TYPE(moniker2, MKSYS_GENERICCOMPOSITE); + inverse = (void *)0xdeadbeef; + hr = IMoniker_Inverse(moniker2, &inverse); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!inverse, "Unexpected pointer.\n"); + IMoniker_Release(moniker1); + + /* Use custom monikers for both, so they don't invert to anti monikers. */ + m2 = create_test_moniker(); + m2->inverse = "I4"; + + hr = CreateGenericComposite(&m2->IMoniker_iface, &m->IMoniker_iface, &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_Inverse(moniker2, &inverse); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + TEST_MONIKER_TYPE(inverse, MKSYS_GENERICCOMPOSITE); + TEST_DISPLAY_NAME(inverse, L"!I5!I4"); + IMoniker_Release(inverse); + IMoniker_Release(moniker2); + + IMoniker_Release(&m->IMoniker_iface); + IMoniker_Release(&m2->IMoniker_iface); + IBindCtx_Release(bindctx); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/antimoniker.c | 17 ++++++----------- dlls/ole32/tests/moniker.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/antimoniker.c b/dlls/ole32/antimoniker.c index c0937a8d903..28c4dd91ac5 100644 --- a/dlls/ole32/antimoniker.c +++ b/dlls/ole32/antimoniker.c @@ -438,20 +438,15 @@ static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker return MonikerCommonPrefixWith(iface, other, prefix); }
-/****************************************************************************** - * AntiMoniker_RelativePathTo - ******************************************************************************/ -static HRESULT WINAPI -AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result) { - TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); + TRACE("%p, %p, %p.\n", iface, other, result);
- if (ppmkRelPath==NULL) - return E_POINTER; - - IMoniker_AddRef(pmOther); + if (!other || !result) + return E_INVALIDARG;
- *ppmkRelPath=pmOther; + IMoniker_AddRef(other); + *result = other;
return MK_S_HIM; } diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 7f0b9ec5841..95e4b865467 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3026,6 +3026,35 @@ todo_wine IBindCtx_Release(bindctx); IMoniker_Release(moniker); IMoniker_Release(moniker2); + + /* RelativePathTo() */ + moniker = create_antimoniker(1); + hr = create_moniker_from_desc("I1", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, NULL, &moniker3); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, moniker2, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, moniker2, &moniker3); + ok(hr == MK_S_HIM, "Unexpected hr %#x.\n", hr); + ok(moniker3 == moniker2, "Unexpected object.\n"); + IMoniker_Release(moniker3); + IMoniker_Release(moniker2); + + moniker2 = create_antimoniker(2); + hr = IMoniker_RelativePathTo(moniker, moniker2, &moniker3); + ok(hr == MK_S_HIM, "Unexpected hr %#x.\n", hr); + ok(moniker3 == moniker2, "Unexpected object.\n"); + IMoniker_Release(moniker3); + hr = IMoniker_RelativePathTo(moniker2, moniker, &moniker3); + ok(hr == MK_S_HIM, "Unexpected hr %#x.\n", hr); + ok(moniker3 == moniker, "Unexpected object.\n"); + IMoniker_Release(moniker3); + + IMoniker_Release(moniker2); + IMoniker_Release(moniker); }
static void test_generic_composite_moniker(void)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/itemmoniker.c | 13 +++++-------- dlls/ole32/tests/moniker.c | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/dlls/ole32/itemmoniker.c b/dlls/ole32/itemmoniker.c index 770b042aac7..1ab9c52dbfb 100644 --- a/dlls/ole32/itemmoniker.c +++ b/dlls/ole32/itemmoniker.c @@ -714,17 +714,14 @@ static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker return MonikerCommonPrefixWith(iface, other, prefix); }
-/****************************************************************************** - * ItemMoniker_RelativePathTo - ******************************************************************************/ -static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result) { - TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); + TRACE("%p, %p, %p.\n", iface, other, result);
- if (ppmkRelPath==NULL) - return E_POINTER; + if (!other || !result) + return E_INVALIDARG;
- *ppmkRelPath=0; + *result = NULL;
return MK_E_NOTBINDABLE; } diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 95e4b865467..a9660354b01 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -2376,7 +2376,7 @@ static void test_item_moniker(void) "Moniker_IsRunning", NULL }; - IMoniker *moniker, *moniker2, *moniker3, *reduced, *anti, *inverse, *c; + IMoniker *moniker, *moniker1, *moniker2, *moniker3, *reduced, *anti, *inverse, *c; DWORD i, hash, eaten, cookie; HRESULT hr; IBindCtx *bindctx; @@ -2757,6 +2757,26 @@ todo_wine IMoniker_Release(moniker2);
IMoniker_Release(moniker); + + /* RelativePathTo() */ + hr = create_moniker_from_desc("I1", &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc("I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_RelativePathTo(moniker, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, NULL, &moniker2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, moniker1, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + moniker2 = (void *)0xdeadbeef; + hr = IMoniker_RelativePathTo(moniker, moniker1, &moniker2); + ok(hr == MK_E_NOTBINDABLE, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + + IMoniker_Release(moniker1); + IMoniker_Release(moniker); }
static void stream_write_dword(IStream *stream, DWORD value)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/pointermoniker.c | 16 ++++++---------- dlls/ole32/tests/moniker.c | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/pointermoniker.c b/dlls/ole32/pointermoniker.c index 14cf8af9eaa..aa4a01d9e75 100644 --- a/dlls/ole32/pointermoniker.c +++ b/dlls/ole32/pointermoniker.c @@ -368,20 +368,16 @@ static HRESULT WINAPI PointerMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoni return MK_E_NOPREFIX; }
-/****************************************************************************** - * PointerMoniker_RelativePathTo - ******************************************************************************/ -static HRESULT WINAPI -PointerMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +static HRESULT WINAPI PointerMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result) { - TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); + TRACE("%p, %p, %p.\n", iface, other, result);
- if (ppmkRelPath==NULL) - return E_POINTER; + if (!result) + return E_INVALIDARG;
- *ppmkRelPath = NULL; + *result = NULL;
- return E_NOTIMPL; + return other ? E_NOTIMPL : E_INVALIDARG; }
/****************************************************************************** diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index a9660354b01..91382da6a02 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3497,7 +3497,7 @@ todo_wine
static void test_pointer_moniker(void) { - IMoniker *moniker, *moniker2, *prefix, *inverse, *anti, *c; + IMoniker *moniker, *moniker2, *moniker3, *prefix, *inverse, *anti, *c; struct test_factory factory; IEnumMoniker *enummoniker; DWORD hash, size; @@ -3726,6 +3726,23 @@ todo_wine IMoniker_Release(moniker2); IMoniker_Release(c);
+ /* RelativePathTo() */ + hr = create_moniker_from_desc("I1", &moniker3); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + moniker2 = (void *)0xdeadbeef; + hr = IMoniker_RelativePathTo(moniker, NULL, &moniker2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + hr = IMoniker_RelativePathTo(moniker, moniker3, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + moniker2 = (void *)0xdeadbeef; + hr = IMoniker_RelativePathTo(moniker, moniker3, &moniker2); + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + IMoniker_Release(moniker3); + IMoniker_Release(moniker); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/filemoniker.c | 17 ++++++----------- dlls/ole32/tests/moniker.c | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/ole32/filemoniker.c b/dlls/ole32/filemoniker.c index f52881108c7..213971ea96b 100644 --- a/dlls/ole32/filemoniker.c +++ b/dlls/ole32/filemoniker.c @@ -608,21 +608,16 @@ FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLef return E_NOTIMPL; }
-/****************************************************************************** - * FileMoniker_Reduce - ******************************************************************************/ -static HRESULT WINAPI -FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar, - IMoniker** ppmkToLeft, IMoniker** ppmkReduced) +static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD howfar, + IMoniker **toleft, IMoniker **reduced) { - 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;
IMoniker_AddRef(iface); - - *ppmkReduced=iface; + *reduced = iface;
return MK_S_REDUCED_TO_SELF; } diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 91382da6a02..2c257dcff50 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -2098,7 +2098,7 @@ todo_wine
static void test_file_moniker(WCHAR* path) { - IMoniker *moniker1 = NULL, *moniker2 = NULL, *inverse, *reduced, *anti; + IMoniker *moniker1 = NULL, *moniker2 = NULL, *m3, *inverse, *reduced, *anti; IEnumMoniker *enummoniker; IBindCtx *bind_ctx; IStream *stream; @@ -2142,9 +2142,19 @@ static void test_file_moniker(WCHAR* path) ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr);
hr = IMoniker_Reduce(moniker1, NULL, MKRREDUCE_ALL, NULL, &reduced); -todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ hr = IMoniker_Reduce(moniker1, bind_ctx, MKRREDUCE_ALL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + m3 = anti = create_antimoniker(1); + hr = IMoniker_Reduce(moniker1, bind_ctx, MKRREDUCE_ALL, &m3, &reduced); + ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr); + ok(reduced == moniker1, "Unexpected moniker.\n"); + ok(m3 == anti, "Unexpected pointer.\n"); + IMoniker_Release(reduced); + IMoniker_Release(anti); + hr = IMoniker_Reduce(moniker1, bind_ctx, MKRREDUCE_ALL, NULL, &reduced); ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr); ok(reduced == moniker1, "Unexpected moniker.\n");
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 50 +++++++++++++++++------------------ dlls/ole32/tests/moniker.c | 39 +++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 27 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index b2ec02e1150..4451f0daae6 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -315,23 +315,30 @@ CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize) return S_OK; }
+static HRESULT compose_with(IMoniker *left, IMoniker *right, IMoniker **c) +{ + HRESULT hr = IMoniker_ComposeWith(left, right, TRUE, c); + if (FAILED(hr) && hr != MK_E_NEEDGENERIC) return hr; + return CreateGenericComposite(left, right, c); +} + static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker *iface, IBindCtx *pbc, - IMoniker *pmkToLeft, REFIID riid, void **result) + IMoniker *toleft, REFIID riid, void **result) { + CompositeMonikerImpl *moniker = impl_from_IMoniker(iface); + IMoniker *left, *rightmost, *c; IRunningObjectTable *rot; IUnknown *object; HRESULT hr; - IMoniker *tempMk,*antiMk,*rightMostMk; - IEnumMoniker *enumMoniker;
- TRACE("(%p,%p,%p,%s,%p)\n", iface, pbc, pmkToLeft, debugstr_guid(riid), result); + TRACE("%p, %p, %p, %s, %p.\n", iface, pbc, toleft, debugstr_guid(riid), result);
if (!result) return E_POINTER;
*result = NULL;
- if (!pmkToLeft) + if (!toleft) { hr = IBindCtx_GetRunningObjectTable(pbc, &rot); if (SUCCEEDED(hr)) @@ -343,25 +350,25 @@ static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker *iface, IBindCt hr = IUnknown_QueryInterface(object, riid, result); IUnknown_Release(object); } - } - else{ - /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */ - /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
- IMoniker_Enum(iface,FALSE,&enumMoniker); - IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL); - IEnumMoniker_Release(enumMoniker); + return hr; + }
- hr = CreateAntiMoniker(&antiMk); - hr = IMoniker_ComposeWith(iface,antiMk,0,&tempMk); - IMoniker_Release(antiMk); + /* Try to bind rightmost component with (toleft, composite->left) composite at its left side */ + if (FAILED(hr = composite_get_rightmost(moniker, &left, &rightmost))) + return hr;
- hr = IMoniker_BindToObject(rightMostMk,pbc,tempMk,riid,result); + hr = compose_with(toleft, left, &c); + IMoniker_Release(left);
- IMoniker_Release(tempMk); - IMoniker_Release(rightMostMk); + if (SUCCEEDED(hr)) + { + hr = IMoniker_BindToObject(rightmost, pbc, c, riid, result); + IMoniker_Release(c); }
+ IMoniker_Release(rightmost); + return hr; }
@@ -683,13 +690,6 @@ CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, } }
-static HRESULT compose_with(IMoniker *left, IMoniker *right, IMoniker **c) -{ - HRESULT hr = IMoniker_ComposeWith(left, right, TRUE, c); - if (FAILED(hr) && hr != MK_E_NEEDGENERIC) return hr; - return CreateGenericComposite(left, right, c); -} - static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *toleft, FILETIME *changetime) { diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 2c257dcff50..795d8750d05 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3108,7 +3108,7 @@ static void test_generic_composite_moniker(void) { "CI1I2", "A3", MKSYS_ANTIMONIKER, L"\.." }, { "CI1I3", "CA1I2", MKSYS_GENERICCOMPOSITE, L"!I1!I2" }, }; - IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3; + IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3, *moniker4; struct test_moniker *m, *m2; IEnumMoniker *enummoniker; IRunningObjectTable *rot; @@ -3267,10 +3267,45 @@ todo_wine hr = IRunningObjectTable_Revoke(rot, cookie); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IRunningObjectTable_Release(rot); + IMoniker_Release(moniker); + + /* BindToObject() with moniker at left */ + hr = CreatePointerMoniker((IUnknown *)rot, &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* (I1,P) */ + hr = create_moniker_from_desc("I1", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = CreateGenericComposite(moniker2, moniker, &moniker3); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_BindToObject(moniker3, bindctx, moniker2, &IID_IMoniker, (void **)&unknown); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + + /* Register (I1,I1,P), check if ROT is used for left != NULL case */ + hr = CreateGenericComposite(moniker2, moniker3, &moniker4); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ cookie = 0; + hr = IRunningObjectTable_Register(rot, ROTFLAGS_REGISTRATIONKEEPSALIVE, (IUnknown *)moniker4, + moniker4, &cookie); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_BindToObject(moniker3, bindctx, moniker2, &IID_IMoniker, (void **)&unknown); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + + hr = IRunningObjectTable_Revoke(rot, cookie); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMoniker_Release(moniker3); + IMoniker_Release(moniker2); IMoniker_Release(moniker);
+ IRunningObjectTable_Release(rot); + /* Uninitialized composite */ hr = CoCreateInstance(&CLSID_CompositeMoniker, NULL, CLSCTX_SERVER, &IID_IMoniker, (void **)&moniker); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);