Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/tests/moniker.c | 59 ++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-)
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index ae46db110b6..db068f1426f 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -36,6 +36,21 @@ #include "wine/test.h" #include "wine/heap.h"
+#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
#define CHECK_EXPECTED_METHOD(method_name) \ @@ -1896,6 +1911,13 @@ static void test_class_moniker(void) hr = CreateClassMoniker(&GUID_NULL, &moniker); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ check_interface(moniker, &IID_IMoniker, TRUE); + check_interface(moniker, &IID_IPersist, TRUE); + check_interface(moniker, &IID_IPersistStream, TRUE); + check_interface(moniker, &CLSID_ClassMoniker, TRUE); + check_interface(moniker, &IID_IROTData, TRUE); + check_interface(moniker, &IID_IMarshal, TRUE); + hr = IMoniker_GetSizeMax(moniker, &size); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(size.QuadPart == 20, "Unexpected size %u.\n", size.LowPart); @@ -2222,6 +2244,14 @@ static void test_file_monikers(void) hr = CreateFileMoniker(filename, &moniker); ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+ check_interface(moniker, &IID_IMoniker, TRUE); +todo_wine + check_interface(moniker, &IID_IPersist, FALSE); + check_interface(moniker, &IID_IPersistStream, TRUE); + check_interface(moniker, &CLSID_FileMoniker, TRUE); + check_interface(moniker, &IID_IROTData, TRUE); + check_interface(moniker, &IID_IMarshal, TRUE); + hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IStorage, (void **)&storage); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
@@ -2753,6 +2783,14 @@ static void test_anti_moniker(void) hr = CreateAntiMoniker(&moniker); ok_ole_success(hr, CreateAntiMoniker);
+ check_interface(moniker, &IID_IMoniker, TRUE); +todo_wine + check_interface(moniker, &IID_IPersist, FALSE); + check_interface(moniker, &IID_IPersistStream, TRUE); + check_interface(moniker, &CLSID_AntiMoniker, TRUE); + check_interface(moniker, &IID_IROTData, TRUE); + check_interface(moniker, &IID_IMarshal, TRUE); + hr = IMoniker_QueryInterface(moniker, &CLSID_AntiMoniker, (void **)&unknown); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(unknown == (IUnknown *)moniker, "Unexpected interface.\n"); @@ -3067,6 +3105,13 @@ static void test_generic_composite_moniker(void) hr = CreateGenericComposite(moniker1, moniker2, &moniker); ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+ check_interface(moniker, &IID_IMoniker, TRUE); +todo_wine + check_interface(moniker, &IID_IPersist, FALSE); + check_interface(moniker, &IID_IPersistStream, TRUE); + check_interface(moniker, &IID_IROTData, TRUE); + check_interface(moniker, &IID_IMarshal, TRUE); + hr = CreateGenericComposite(moniker1, moniker2, &moniker); ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr); TEST_MONIKER_TYPE(moniker, MKSYS_GENERICCOMPOSITE); @@ -3253,7 +3298,6 @@ static void test_pointer_moniker(void) FILETIME filetime; IUnknown *unknown; IStream *stream; - IROTData *rotdata; LPOLESTR display_name; IMarshal *marshal; LARGE_INTEGER pos; @@ -3267,6 +3311,14 @@ static void test_pointer_moniker(void) hr = CreatePointerMoniker((IUnknown *)&factory.IClassFactory_iface, &moniker); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ check_interface(moniker, &IID_IMoniker, TRUE); +todo_wine + check_interface(moniker, &IID_IPersist, FALSE); + check_interface(moniker, &IID_IPersistStream, TRUE); + check_interface(moniker, &CLSID_PointerMoniker, TRUE); + check_interface(moniker, &IID_IMarshal, TRUE); + check_interface(moniker, &IID_IROTData, FALSE); + hr = IMoniker_QueryInterface(moniker, &IID_IMoniker, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
@@ -3318,11 +3370,6 @@ static void test_pointer_moniker(void) hr = IMoniker_IsDirty(moniker); ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
- /* IROTData::GetComparisonData test */ - - hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata); - ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr); - /* Saving */
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 1 + dlls/ole32/tests/moniker.c | 78 ++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 0907950cb17..efb0e9de9e8 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -934,6 +934,7 @@ CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface, IMoniker* pmkOther, if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){
*ppmkPrefix=pmkOther; + IMoniker_AddRef(*ppmkPrefix);
return MK_S_HIM; } diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index db068f1426f..ed55ec3e825 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3042,7 +3042,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; + IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3; IEnumMoniker *enummoniker; IRunningObjectTable *rot; DWORD hash, cookie; @@ -3284,6 +3284,66 @@ todo_wine IMoniker_Release(moniker); IMoniker_Release(moniker1);
+ /* CommonPrefixWith() */ + hr = create_moniker_from_desc("CI1I2", &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc("CI1I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + moniker2 = (void *)0xdeadbeef; + hr = IMoniker_CommonPrefixWith(moniker, NULL, &moniker2); +todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + + /* With itself */ + hr = IMoniker_CommonPrefixWith(moniker, moniker, &moniker2); + ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); +todo_wine + ok(moniker2 != moniker, "Unexpected object.\n"); + TEST_DISPLAY_NAME(moniker2, L"!I1!I2"); + IMoniker_Release(moniker2); + + /* Equal composites */ + hr = IMoniker_CommonPrefixWith(moniker, moniker1, &moniker2); + ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); +todo_wine + ok(moniker2 != moniker && moniker2 != moniker1, "Unexpected object.\n"); + hr = IMoniker_IsEqual(moniker, moniker2); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMoniker_Release(moniker2); + + hr = create_moniker_from_desc("I2", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_CommonPrefixWith(moniker, moniker2, &moniker3); + ok(hr == MK_E_NOPREFIX, "Unexpected hr %#x.\n", hr); + IMoniker_Release(moniker2); + + hr = create_moniker_from_desc("I1", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_CommonPrefixWith(moniker, moniker2, &moniker3); + ok(hr == MK_S_HIM, "Unexpected hr %#x.\n", hr); + hr = IMoniker_IsEqual(moniker2, moniker3); +todo_wine + ok(hr == S_OK && moniker3 != moniker2, "Unexpected object.\n"); + IMoniker_Release(moniker3); + + hr = IMoniker_CommonPrefixWith(moniker2, moniker, &moniker3); +todo_wine + ok(hr == MK_S_ME, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + { + hr = IMoniker_IsEqual(moniker2, moniker3); + ok(hr == S_OK && moniker3 != moniker2, "Unexpected object.\n"); + IMoniker_Release(moniker3); + } + + IMoniker_Release(moniker2); + + IMoniker_Release(moniker); + IMoniker_Release(moniker1); + IBindCtx_Release(bindctx); }
@@ -3720,11 +3780,15 @@ todo_wine { hr = CreateItemMoniker(L"!", L"Item", &item); ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+ moniker = (void *)0xdeadbeef; hr = MonikerCommonPrefixWith(item, NULL, &moniker); ok(hr == MK_E_NOPREFIX, "Unexpected hr %#x.\n", hr); + ok(!moniker, "Unexpected pointer.\n");
+ moniker = (void *)0xdeadbeef; hr = MonikerCommonPrefixWith(NULL, item, &moniker); ok(hr == MK_E_NOPREFIX, "Unexpected hr %#x.\n", hr); + ok(!moniker, "Unexpected pointer.\n");
hr = MonikerCommonPrefixWith(item, item, &moniker); ok(hr == MK_E_NOPREFIX, "Unexpected hr %#x.\n", hr); @@ -3796,6 +3860,18 @@ todo_wine {
IMoniker_Release(composite2); IMoniker_Release(composite); + + /* (I1,(I2,I3)) x ((I1,I2),I4) */ + hr = create_moniker_from_desc("CI1CI2I3", &composite); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc("CCI1I2I4", &composite2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = MonikerCommonPrefixWith(composite, composite2, &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + TEST_MONIKER_TYPE(moniker, MKSYS_GENERICCOMPOSITE); + TEST_DISPLAY_NAME(moniker, L"!I1!I2"); + IMoniker_Release(moniker); + IMoniker_Release(file2); IMoniker_Release(file1); IMoniker_Release(item);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 230 +++++++++++++++++----------------- dlls/ole32/tests/moniker.c | 15 ++- 2 files changed, 128 insertions(+), 117 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index efb0e9de9e8..4eb9b32fe5e 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -88,6 +88,7 @@ static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk); static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost); +static HRESULT composite_get_leftmost(CompositeMonikerImpl *composite, IMoniker **leftmost);
/******************************************************************************* * CompositeMoniker_QueryInterface @@ -524,11 +525,23 @@ static void composite_get_components(IMoniker *moniker, IMoniker **components, u } }
+static HRESULT composite_get_components_alloc(CompositeMonikerImpl *moniker, IMoniker ***components) +{ + unsigned int index; + + if (!(*components = heap_alloc(moniker->comp_count * sizeof(**components)))) + return E_OUTOFMEMORY; + + index = 0; + composite_get_components(&moniker->IMoniker_iface, *components, &index); + + return S_OK; +} + static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ppenumMoniker) { CompositeMonikerImpl *moniker = impl_from_IMoniker(iface); IMoniker **monikers; - unsigned int index; HRESULT hr;
TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker); @@ -536,11 +549,8 @@ static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, I if (!ppenumMoniker) return E_POINTER;
- if (!(monikers = heap_alloc(moniker->comp_count * sizeof(*monikers)))) - return E_OUTOFMEMORY; - - index = 0; - composite_get_components(iface, monikers, &index); + if (FAILED(hr = composite_get_components_alloc(moniker, &monikers))) + return hr;
hr = EnumMonikerImpl_CreateEnumMoniker(monikers, moniker->comp_count, 0, forward, ppenumMoniker); heap_free(monikers); @@ -812,135 +822,102 @@ CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) } }
-/****************************************************************************** - * CompositeMoniker_CommonPrefixWith - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface, IMoniker* pmkOther, - IMoniker** ppmkPrefix) +static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, + IMoniker **prefix) { - DWORD mkSys; - HRESULT res1,res2; - IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2; - IEnumMoniker *enumMoniker1,*enumMoniker2; - ULONG i,nbCommonMk=0; + CompositeMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker; + unsigned int i, count, prefix_len = 0; + IMoniker *leftmost; + HRESULT hr; + + TRACE("%p, %p, %p.\n", iface, other, prefix);
/* If the other moniker is a composite, this method compares the components of each composite from left */ /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */ /* of the leftmost components were common to both monikers. */
- if (ppmkPrefix==NULL) - return E_POINTER; - - *ppmkPrefix=0; - - if (pmkOther==NULL) - return MK_E_NOPREFIX; + if (prefix) + *prefix = NULL;
- IMoniker_IsSystemMoniker(pmkOther,&mkSys); - - if(mkSys==MKSYS_GENERICCOMPOSITE){ - - IMoniker_Enum(iface,TRUE,&enumMoniker1); - IMoniker_Enum(pmkOther,TRUE,&enumMoniker2); - - while(1){ - - res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL); - res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL); - - if ((res1==S_FALSE) && (res2==S_FALSE)){ - - /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/ - *ppmkPrefix=iface; - IMoniker_AddRef(iface); - return MK_S_US; - } - else if ((res1==S_OK) && (res2==S_OK)){ - - if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK) - - nbCommonMk++; - - else - break; + if (!other || !prefix) + return E_INVALIDARG;
- } - else if (res1==S_OK){ + if ((other_moniker = unsafe_impl_from_IMoniker(other))) + { + IMoniker **components, **other_components, **prefix_components; + IMoniker *last, *c;
- /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */ - /* ppmkPrefix to the other moniker. */ - *ppmkPrefix=pmkOther; - return MK_S_HIM; - } - else{ - /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */ - /* to this moniker. */ - *ppmkPrefix=iface; - return MK_S_ME; - } + if (FAILED(hr = composite_get_components_alloc(moniker, &components))) return hr; + if (FAILED(hr = composite_get_components_alloc(other_moniker, &other_components))) + { + heap_free(components); + return hr; }
- IEnumMoniker_Release(enumMoniker1); - IEnumMoniker_Release(enumMoniker2); - - /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */ - if (nbCommonMk==0) - return MK_E_NOPREFIX; - - IEnumMoniker_Reset(enumMoniker1); - - IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); - - /* if we have more than one common moniker the result will be a composite moniker */ - if (nbCommonMk>1){ - - /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/ - IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL); - CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix); - IMoniker_Release(tempMk1); - IMoniker_Release(tempMk2); - - /* compose all common monikers in a composite moniker */ - for(i=0;i<nbCommonMk;i++){ + count = min(moniker->comp_count, other_moniker->comp_count); + if (!(prefix_components = heap_calloc(count, sizeof(*prefix_components)))) + { + heap_free(components); + heap_free(other_components); + return E_OUTOFMEMORY; + }
- IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); + /* Collect prefix components */ + for (i = 0; i < count; ++i) + { + IMoniker *p;
- CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2); + if (FAILED(hr = IMoniker_CommonPrefixWith(components[i], other_components[i], &p))) + break; + prefix_components[prefix_len++] = p; + /* S_OK means that prefix was found and is neither of tested monikers */ + if (hr == S_OK) break; + }
- IMoniker_Release(*ppmkPrefix); + heap_free(components); + heap_free(other_components);
- IMoniker_Release(tempMk1); + if (!prefix_len) return MK_E_NOPREFIX;
- *ppmkPrefix=tempMk2; - } - return S_OK; + last = prefix_components[0]; + for (i = 1; i < prefix_len; ++i) + { + hr = CreateGenericComposite(last, prefix_components[i], &c); + IMoniker_Release(last); + IMoniker_Release(prefix_components[i]); + if (FAILED(hr)) break; + last = c; } - else{ - /* if we have only one common moniker the result will be a simple moniker which is the most-left one*/ - *ppmkPrefix=tempMk1; + heap_free(prefix_components);
- return S_OK; + if (SUCCEEDED(hr)) + { + *prefix = last; + if (IMoniker_IsEqual(iface, *prefix) == S_OK) + hr = MK_S_US; + else if (prefix_len < count) + hr = S_OK; + else + hr = prefix_len == moniker->comp_count ? MK_S_ME : MK_S_HIM; } - } - else{ - /* If the other moniker is not a composite, the method simply compares it to the leftmost component - of this moniker.*/ - - IMoniker_Enum(iface,TRUE,&enumMoniker1); - - IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
- if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){ - - *ppmkPrefix=pmkOther; - IMoniker_AddRef(*ppmkPrefix); + return hr; + }
- return MK_S_HIM; + /* For non-composite, compare to leftmost component */ + if (SUCCEEDED(hr = composite_get_leftmost(moniker, &leftmost))) + { + if ((hr = IMoniker_IsEqual(leftmost, other)) == S_OK) + { + *prefix = leftmost; + IMoniker_AddRef(*prefix); } - else - return MK_E_NOPREFIX; + + hr = hr == S_OK ? MK_S_HIM : MK_E_NOPREFIX; + IMoniker_Release(leftmost); } + + return hr; }
/*************************************************************************************************** @@ -1866,6 +1843,35 @@ static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker return hr; }
+static HRESULT composite_get_leftmost(CompositeMonikerImpl *composite, IMoniker **leftmost) +{ + struct comp_node *root, *node; + HRESULT hr; + + if (!unsafe_impl_from_IMoniker(composite->left)) + { + *leftmost = composite->left; + IMoniker_AddRef(*leftmost); + return S_OK; + } + + if (FAILED(hr = moniker_get_tree_representation(&composite->IMoniker_iface, NULL, &root))) + return hr; + + if (!(node = moniker_tree_get_leftmost(root))) + { + WARN("Couldn't get right most component.\n"); + return E_FAIL; + } + + *leftmost = node->moniker; + IMoniker_AddRef(*leftmost); + + moniker_tree_release(root); + + return S_OK; +} + static HRESULT moniker_simplify_composition(IMoniker *left, IMoniker *right, unsigned int *count, IMoniker **new_left, IMoniker **new_right) { diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index ed55ec3e825..1e4c2e0211d 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3290,24 +3290,30 @@ todo_wine hr = create_moniker_from_desc("CI1I2", &moniker1); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMoniker_CommonPrefixWith(moniker, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_CommonPrefixWith(moniker, moniker1, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + moniker2 = (void *)0xdeadbeef; hr = IMoniker_CommonPrefixWith(moniker, NULL, &moniker2); -todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ok(!moniker2, "Unexpected pointer.\n");
/* With itself */ hr = IMoniker_CommonPrefixWith(moniker, moniker, &moniker2); +todo_wine ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); + hr = IMoniker_IsEqual(moniker, moniker2); todo_wine - ok(moniker2 != moniker, "Unexpected object.\n"); - TEST_DISPLAY_NAME(moniker2, L"!I1!I2"); + ok(hr == S_OK && moniker2 != moniker, "Unexpected hr %#x.\n", hr); IMoniker_Release(moniker2);
/* Equal composites */ hr = IMoniker_CommonPrefixWith(moniker, moniker1, &moniker2); - ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); todo_wine + ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); ok(moniker2 != moniker && moniker2 != moniker1, "Unexpected object.\n"); hr = IMoniker_IsEqual(moniker, moniker2); todo_wine @@ -3325,7 +3331,6 @@ todo_wine hr = IMoniker_CommonPrefixWith(moniker, moniker2, &moniker3); ok(hr == MK_S_HIM, "Unexpected hr %#x.\n", hr); hr = IMoniker_IsEqual(moniker2, moniker3); -todo_wine ok(hr == S_OK && moniker3 != moniker2, "Unexpected object.\n"); IMoniker_Release(moniker3);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 65 ++++++++++++++--------------------- dlls/ole32/tests/moniker.c | 18 +++++++--- 2 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 4eb9b32fe5e..60d11b3ba90 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -558,56 +558,41 @@ static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, I return hr; }
-/****************************************************************************** - * CompositeMoniker_IsEqual - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other) { - IEnumMoniker *enumMoniker1,*enumMoniker2; - IMoniker *tempMk1,*tempMk2; - HRESULT res1,res2,res; - BOOL done; - - TRACE("(%p,%p)\n",iface,pmkOtherMoniker); + CompositeMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker; + IMoniker **components, **other_components; + unsigned int i; + HRESULT hr;
- if (pmkOtherMoniker==NULL) - return S_FALSE; + TRACE("%p, %p.\n", iface, other);
- /* This method returns S_OK if the components of both monikers are equal when compared in the */ - /* left-to-right order.*/ - IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1); + if (!other) + return E_INVALIDARG;
- if (enumMoniker1==NULL) + if (!(other_moniker = unsafe_impl_from_IMoniker(other))) return S_FALSE;
- IMoniker_Enum(iface,TRUE,&enumMoniker2); - - do { - - res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); - res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL); - - if((res1==S_OK)&&(res2==S_OK)){ - done = (res = IMoniker_IsEqual(tempMk1,tempMk2)) == S_FALSE; - } - else - { - res = (res1==S_FALSE) && (res2==S_FALSE); - done = TRUE; - } + if (moniker->comp_count != other_moniker->comp_count) + return S_FALSE;
- if (res1==S_OK) - IMoniker_Release(tempMk1); + if (FAILED(hr = composite_get_components_alloc(moniker, &components))) return hr; + if (FAILED(hr = composite_get_components_alloc(other_moniker, &other_components))) + { + heap_free(components); + return hr; + }
- if (res2==S_OK) - IMoniker_Release(tempMk2); - } while (!done); + for (i = 0; i < moniker->comp_count; ++i) + { + if ((hr = IMoniker_IsEqual(components[i], other_components[i]) != S_OK)) + break; + }
- IEnumMoniker_Release(enumMoniker1); - IEnumMoniker_Release(enumMoniker2); + heap_free(other_components); + heap_free(components);
- return res; + return hr; }
static HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker *iface, DWORD *hash) diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 1e4c2e0211d..962ae6c269f 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3303,20 +3303,16 @@ todo_wine
/* With itself */ hr = IMoniker_CommonPrefixWith(moniker, moniker, &moniker2); -todo_wine ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); hr = IMoniker_IsEqual(moniker, moniker2); -todo_wine ok(hr == S_OK && moniker2 != moniker, "Unexpected hr %#x.\n", hr); IMoniker_Release(moniker2);
/* Equal composites */ hr = IMoniker_CommonPrefixWith(moniker, moniker1, &moniker2); -todo_wine ok(hr == MK_S_US, "Unexpected hr %#x.\n", hr); ok(moniker2 != moniker && moniker2 != moniker1, "Unexpected object.\n"); hr = IMoniker_IsEqual(moniker, moniker2); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); IMoniker_Release(moniker2);
@@ -3349,6 +3345,20 @@ todo_wine IMoniker_Release(moniker); IMoniker_Release(moniker1);
+ /* IsEqual() */ + hr = create_moniker_from_desc("CI1I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc("CI1I2", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_IsEqual(moniker1, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_IsEqual(moniker1, moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMoniker_IsEqual(moniker1, moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMoniker_Release(moniker2); + IMoniker_Release(moniker1); + IBindCtx_Release(bindctx); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 24 +++++------------------- dlls/ole32/tests/moniker.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 60d11b3ba90..40889ae42b2 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -485,28 +485,14 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar } }
-/****************************************************************************** - * CompositeMoniker_ComposeWith - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight, - BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite) +static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right, + BOOL only_if_not_generic, IMoniker **composite) { - TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite); - - if ((ppmkComposite==NULL)||(pmkRight==NULL)) - return E_POINTER; - - *ppmkComposite=0; - - /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */ - /* otherwise, the method returns the result of combining the two monikers by calling the */ - /* CreateGenericComposite function */ + TRACE("%p, %p, %d, %p.\n", iface, right, only_if_not_generic, composite);
- if (fOnlyIfNotGeneric) - return MK_E_NEEDGENERIC; + *composite = NULL;
- return CreateGenericComposite(iface,pmkRight,ppmkComposite); + return only_if_not_generic ? MK_E_NEEDGENERIC : CreateGenericComposite(iface, right, composite); }
static void composite_get_components(IMoniker *moniker, IMoniker **components, unsigned int *index) diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 962ae6c269f..7d88c132d3d 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3359,6 +3359,24 @@ todo_wine IMoniker_Release(moniker2); IMoniker_Release(moniker1);
+ /* ComposeWith() */ + hr = create_moniker_from_desc("CI1I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = create_moniker_from_desc("I3", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_ComposeWith(moniker1, NULL, FALSE, &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(moniker == moniker1, "Unexpected pointer.\n"); + IMoniker_Release(moniker); + + hr = IMoniker_ComposeWith(moniker1, NULL, TRUE, &moniker); + ok(hr == MK_E_NEEDGENERIC, "Unexpected hr %#x.\n", hr); + ok(!moniker, "Unexpected pointer.\n"); + + IMoniker_Release(moniker2); + IMoniker_Release(moniker1); + IBindCtx_Release(bindctx); }