Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 60 ++++++----- dlls/ole32/tests/moniker.c | 192 +++++++++++++++++++++++++++++++--- 2 files changed, 209 insertions(+), 43 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 80a1a675766..e5437c8880f 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -495,7 +495,7 @@ static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, I TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker);
if (!ppenumMoniker) - return E_POINTER; + return E_INVALIDARG;
if (FAILED(hr = composite_get_components_alloc(moniker, &monikers))) return hr; @@ -1346,44 +1346,45 @@ EnumMonikerImpl_Release(IEnumMoniker* iface) return ref; }
-/****************************************************************************** - * EnumMonikerImpl_Next - ******************************************************************************/ -static HRESULT WINAPI -EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt, - ULONG* pceltFethed) +static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count, + IMoniker **m, ULONG *fetched) { EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); ULONG i;
+ TRACE("%p, %u, %p, %p.\n", iface, count, m, fetched); + + if (!m) + return E_INVALIDARG; + + *m = NULL; + /* retrieve the requested number of moniker from the current position */ - for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++) + for(i=0;((This->currentPos < This->tabSize) && (i < count));i++) { - rgelt[i]=This->tabMoniker[This->currentPos++]; - IMoniker_AddRef(rgelt[i]); + m[i] = This->tabMoniker[This->currentPos++]; + IMoniker_AddRef(m[i]); }
- if (pceltFethed!=NULL) - *pceltFethed= i; + if (fetched) + *fetched = i;
- if (i==celt) - return S_OK; - else - return S_FALSE; + return i == count ? S_OK : S_FALSE; }
-/****************************************************************************** - * EnumMonikerImpl_Skip - ******************************************************************************/ -static HRESULT WINAPI -EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt) +static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG count) { EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
- if ((This->currentPos+celt) >= This->tabSize) + TRACE("%p, %u.\n", iface, count); + + if (!count) + return S_OK; + + if ((This->currentPos + count) >= This->tabSize) return S_FALSE;
- This->currentPos+=celt; + This->currentPos += count;
return S_OK; } @@ -1401,15 +1402,16 @@ EnumMonikerImpl_Reset(IEnumMoniker* iface) return S_OK; }
-/****************************************************************************** - * EnumMonikerImpl_Clone - ******************************************************************************/ -static HRESULT WINAPI -EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum) +static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker *iface, IEnumMoniker **ret) { EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
- return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum); + TRACE("%p, %p.\n", iface, ret); + + if (!ret) + return E_INVALIDARG; + + return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ret); }
static const IEnumMonikerVtbl VT_EnumMonikerImpl = diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 7e4a42a0ee6..ed2accff6a9 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3163,8 +3163,8 @@ static void test_generic_composite_moniker(void) { "CI1I3", "CA1I2", MKSYS_GENERICCOMPOSITE, L"!I1!I2" }, }; IMoniker *moniker, *inverse, *moniker1, *moniker2, *moniker3, *moniker4; + IEnumMoniker *enummoniker, *enummoniker2; struct test_moniker *m, *m2; - IEnumMoniker *enummoniker; IRunningObjectTable *rot; DWORD hash, cookie; HRESULT hr; @@ -3293,19 +3293,6 @@ todo_wine TEST_MONIKER_TYPE(inverse, MKSYS_GENERICCOMPOSITE); IMoniker_Release(inverse);
- /* Enum() */ - hr = IMoniker_Enum(moniker, TRUE, &enummoniker); - ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr); - IEnumMoniker_Release(enummoniker); - - hr = IMoniker_Enum(moniker, FALSE, &enummoniker); - ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr); - IEnumMoniker_Release(enummoniker); - - hr = IMoniker_Enum(moniker, FALSE, NULL); -todo_wine - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - /* BindToObject() */ hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); @@ -3646,6 +3633,183 @@ todo_wine {
IMoniker_Release(moniker);
+ /* Enum() */ + hr = create_moniker_from_desc("CI1CI2I3", &moniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_Enum(moniker, FALSE, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + /* Forward direction */ + hr = IMoniker_Enum(moniker, TRUE, &enummoniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Next(enummoniker, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + moniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + + len = 1; + moniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!len, "Unexpected count %u.\n", len); + ok(!moniker2, "Unexpected pointer.\n"); + + hr = IEnumMoniker_Skip(enummoniker, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I1"); + IMoniker_Release(moniker2); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I2"); + IMoniker_Release(moniker2); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I3"); + IMoniker_Release(moniker2); + + len = 1; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(!len, "Unexpected count %u.\n", len); + + hr = IEnumMoniker_Skip(enummoniker, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Skip(enummoniker, 1); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Clone(enummoniker, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + enummoniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); +todo_wine { + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(!enummoniker2, "Unexpected pointer.\n"); +} + hr = IEnumMoniker_Reset(enummoniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Skip(enummoniker, 2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I3"); + IMoniker_Release(moniker2); + + enummoniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); +todo_wine { + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(!enummoniker2, "Unexpected pointer.\n"); +} + IEnumMoniker_Release(enummoniker); + + /* Backward direction */ + hr = IMoniker_Enum(moniker, FALSE, &enummoniker); + ok(hr == S_OK, "Failed to get enumerator, hr %#x.\n", hr); + + hr = IEnumMoniker_Next(enummoniker, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + moniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!moniker2, "Unexpected pointer.\n"); + + len = 1; + moniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Next(enummoniker, 0, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!len, "Unexpected count %u.\n", len); + ok(!moniker2, "Unexpected pointer.\n"); + + hr = IEnumMoniker_Skip(enummoniker, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I3"); + IMoniker_Release(moniker2); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I2"); + IMoniker_Release(moniker2); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I1"); + IMoniker_Release(moniker2); + + len = 1; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(!len, "Unexpected count %u.\n", len); + + hr = IEnumMoniker_Skip(enummoniker, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Skip(enummoniker, 1); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Clone(enummoniker, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + enummoniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); +todo_wine { + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(!enummoniker2, "Unexpected pointer.\n"); +} + hr = IEnumMoniker_Reset(enummoniker); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IEnumMoniker_Skip(enummoniker, 2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + len = 0; + hr = IEnumMoniker_Next(enummoniker, 1, &moniker2, &len); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(len == 1, "Unexpected count %u.\n", len); + TEST_DISPLAY_NAME(moniker2, L"!I1"); + IMoniker_Release(moniker2); + + enummoniker2 = (void *)0xdeadbeef; + hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); +todo_wine { + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(!enummoniker2, "Unexpected pointer.\n"); +} + IEnumMoniker_Release(enummoniker); + + IMoniker_Release(moniker); + IBindCtx_Release(bindctx); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 233 ++++++++++++++-------------------- dlls/ole32/tests/moniker.c | 12 ++ 2 files changed, 108 insertions(+), 137 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index e5437c8880f..cde3f1762f0 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -473,23 +473,29 @@ static void composite_get_components(IMoniker *moniker, IMoniker **components, u } }
-static HRESULT composite_get_components_alloc(CompositeMonikerImpl *moniker, IMoniker ***components) +static HRESULT composite_get_components_alloc(IMoniker *iface, unsigned int *count, IMoniker ***components) { + CompositeMonikerImpl *moniker; unsigned int index;
- if (!(*components = heap_alloc(moniker->comp_count * sizeof(**components)))) + if ((moniker = unsafe_impl_from_IMoniker(iface))) + *count = moniker->comp_count; + else + *count = 1; + + if (!(*components = heap_alloc(*count * sizeof(**components)))) return E_OUTOFMEMORY;
index = 0; - composite_get_components(&moniker->IMoniker_iface, *components, &index); + composite_get_components(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 count; HRESULT hr;
TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker); @@ -497,10 +503,10 @@ static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, I if (!ppenumMoniker) return E_INVALIDARG;
- if (FAILED(hr = composite_get_components_alloc(moniker, &monikers))) + if (FAILED(hr = composite_get_components_alloc(iface, &count, &monikers))) return hr;
- hr = EnumMonikerImpl_CreateEnumMoniker(monikers, moniker->comp_count, 0, forward, ppenumMoniker); + hr = EnumMonikerImpl_CreateEnumMoniker(monikers, count, 0, forward, ppenumMoniker); heap_free(monikers);
return hr; @@ -510,7 +516,7 @@ static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker *iface, IMoniker *ot { CompositeMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker; IMoniker **components, **other_components; - unsigned int i; + unsigned int i, count; HRESULT hr;
TRACE("%p, %p.\n", iface, other); @@ -524,8 +530,8 @@ static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker *iface, IMoniker *ot if (moniker->comp_count != other_moniker->comp_count) return S_FALSE;
- if (FAILED(hr = composite_get_components_alloc(moniker, &components))) return hr; - if (FAILED(hr = composite_get_components_alloc(other_moniker, &other_components))) + if (FAILED(hr = composite_get_components_alloc(iface, &count, &components))) return hr; + if (FAILED(hr = composite_get_components_alloc(other, &count, &other_components))) { heap_free(components); return hr; @@ -715,8 +721,8 @@ static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker *iface, IMo IMoniker **components, **other_components, **prefix_components; IMoniker *last, *c;
- if (FAILED(hr = composite_get_components_alloc(moniker, &components))) return hr; - if (FAILED(hr = composite_get_components_alloc(other_moniker, &other_components))) + if (FAILED(hr = composite_get_components_alloc(iface, &count, &components))) return hr; + if (FAILED(hr = composite_get_components_alloc(other, &count, &other_components))) { heap_free(components); return hr; @@ -788,156 +794,109 @@ static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker *iface, IMo return hr; }
-/*************************************************************************************************** - * GetAfterCommonPrefix (local function) - * This function returns a moniker that consist of the remainder when the common prefix is removed - ***************************************************************************************************/ -static VOID GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk) +static HRESULT composite_compose_components(IMoniker **comp, unsigned int count, IMoniker **ret) { - IMoniker *tempMk,*tempMk1,*tempMk2; - IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3; - ULONG nbRestMk=0; - DWORD mkSys; - HRESULT res1,res2; - - *restMk=0; - - /* to create an enumerator for pGenMk with current position pointed on the first element after common */ - /* prefix: enum the two monikers (left-right) then compare these enumerations (left-right) and stop */ - /* on the first difference. */ - IMoniker_Enum(pGenMk,TRUE,&enumMoniker1); - - IMoniker_IsSystemMoniker(commonMk,&mkSys); - - if (mkSys==MKSYS_GENERICCOMPOSITE){ - - IMoniker_Enum(commonMk,TRUE,&enumMoniker2); - while(1){ - - res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); - res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL); - - if ((res1==S_FALSE)||(res2==S_FALSE)){ - - if (res1==S_OK) - - nbRestMk++; + IMoniker *last, *c; + HRESULT hr = S_OK; + unsigned int i;
- IMoniker_Release(tempMk1); - IMoniker_Release(tempMk2); + last = comp[0]; + IMoniker_AddRef(last);
- break; - } - IMoniker_Release(tempMk1); - IMoniker_Release(tempMk2); - } - } - else{ - IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); - IMoniker_Release(tempMk1); + for (i = 1; i < count; ++i) + { + hr = CreateGenericComposite(last, comp[i], &c); + IMoniker_Release(last); + if (FAILED(hr)) break; + last = c; }
- /* count the number of elements in the enumerator after the common prefix */ - IEnumMoniker_Clone(enumMoniker1,&enumMoniker3); + *ret = SUCCEEDED(hr) ? last : NULL;
- for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++) + return hr; +}
- IMoniker_Release(tempMk); +static HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, + IMoniker **relpath) +{ + unsigned int count, this_count, other_count, prefix_len = 0; + IMoniker *inv, *tail = NULL, *other_tail = NULL, *rel = NULL; + IMoniker **components, **other_components; + unsigned int start = 0, other_start = 0; + HRESULT hr;
- if (nbRestMk==0) - return; + TRACE("%p, %p, %p.\n", iface, other, relpath);
- /* create a generic composite moniker with monikers located after the common prefix */ - IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); + if (!relpath) + return E_INVALIDARG;
- if (nbRestMk==1){ + *relpath = NULL;
- *restMk= tempMk1; - return; + if (FAILED(hr = composite_get_components_alloc(iface, &this_count, &components))) return hr; + if (FAILED(hr = composite_get_components_alloc(other, &other_count, &other_components))) + { + heap_free(components); + return hr; } - else { - - IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL); - - CreateGenericComposite(tempMk1,tempMk2,restMk);
- IMoniker_Release(tempMk1); - - IMoniker_Release(tempMk2); - - while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){ - - CreateGenericComposite(*restMk,tempMk1,&tempMk2); + /* Skip common prefix of equal components */ + count = min(other_count, this_count); + while (IMoniker_IsEqual(components[prefix_len], other_components[prefix_len]) == S_OK) + { + if (++prefix_len == count) break; + }
- IMoniker_Release(tempMk1); + if (prefix_len) + { + this_count -= prefix_len; + other_count -= prefix_len; + other_start += prefix_len; + start += prefix_len; + } + else + { + /* Replace first component of the other tail with relative path */ + if (SUCCEEDED(hr = IMoniker_RelativePathTo(*components, *other_components, &rel))) + *other_components = rel;
- IMoniker_Release(*restMk); + this_count--; + start++; + }
- *restMk=tempMk2; + /* Invert left side tail */ + if (this_count && SUCCEEDED(hr)) + { + if (SUCCEEDED(hr = composite_compose_components(&components[start], this_count, &tail))) + { + hr = IMoniker_Inverse(tail, &inv); + IMoniker_Release(tail); + tail = inv; } } -} - -/****************************************************************************** - * CompositeMoniker_RelativePathTo - ******************************************************************************/ -static HRESULT WINAPI -CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmkOther, - IMoniker** ppmkRelPath) -{ - HRESULT res; - IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0; - - TRACE("(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath); - - if (ppmkRelPath==NULL) - return E_POINTER; - - *ppmkRelPath=0;
- /* This method finds the common prefix of the two monikers and creates two monikers that consist */ - /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */ - /* of this moniker and composes the remainder of the other moniker on the right of it. */ + if (other_count && SUCCEEDED(hr)) + hr = composite_compose_components(&other_components[other_start], other_count, &other_tail);
- /* finds the common prefix of the two monikers */ - res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk); - - /* if there's no common prefix or the two moniker are equal the relative is the other moniker */ - if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){ - - *ppmkRelPath=pmkOther; - IMoniker_AddRef(pmkOther); - return MK_S_HIM; + if (tail || other_tail) + hr = CreateGenericComposite(tail, other_tail, relpath); + else if (SUCCEEDED(hr)) + { + *relpath = other; + IMoniker_AddRef(*relpath); + hr = MK_S_HIM; }
- GetAfterCommonPrefix(iface,commonMk,&restThisMk); - GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk); - - /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */ - /* moniker when the common prefix is removed */ - if (res==MK_S_HIM){ + if (rel) + IMoniker_Release(rel); + if (tail) + IMoniker_Release(tail); + if (other_tail) + IMoniker_Release(other_tail);
- IMoniker_Inverse(restThisMk,ppmkRelPath); - IMoniker_Release(restThisMk); - } - /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */ - /* when the common prefix is removed */ - else if (res==MK_S_ME){ - - *ppmkRelPath=restOtherMk; - IMoniker_AddRef(restOtherMk); - } - /* the relative path is the inverse for the remainder of this moniker and the remainder of the other */ - /* moniker on the right of it. */ - else if (res==S_OK){ + heap_free(other_components); + heap_free(components);
- IMoniker_Inverse(restThisMk,&invRestThisMk); - IMoniker_Release(restThisMk); - CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath); - IMoniker_Release(invRestThisMk); - IMoniker_Release(restOtherMk); - } - return S_OK; + return hr; }
static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc, diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index ed2accff6a9..a60472951f7 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3810,6 +3810,18 @@ todo_wine {
IMoniker_Release(moniker);
+ /* RelativePathTo() */ + hr = create_moniker_from_desc("CI1I2", &moniker1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = create_moniker_from_desc("CI2I3", &moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_RelativePathTo(moniker1, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMoniker_RelativePathTo(moniker1, moniker2, &moniker3); + ok(hr == MK_E_NOTBINDABLE, "Unexpected hr %#x.\n", hr); + IBindCtx_Release(bindctx); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 6 +++--- dlls/ole32/tests/moniker.c | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index cde3f1762f0..652962e1a87 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -1363,14 +1363,14 @@ EnumMonikerImpl_Reset(IEnumMoniker* iface)
static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker *iface, IEnumMoniker **ret) { - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - TRACE("%p, %p.\n", iface, ret);
if (!ret) return E_INVALIDARG;
- return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ret); + *ret = NULL; + + return E_NOTIMPL; }
static const IEnumMonikerVtbl VT_EnumMonikerImpl = diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index a60472951f7..abd17c9961f 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -3699,10 +3699,9 @@ todo_wine {
enummoniker2 = (void *)0xdeadbeef; hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); -todo_wine { ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); ok(!enummoniker2, "Unexpected pointer.\n"); -} + hr = IEnumMoniker_Reset(enummoniker); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -3718,10 +3717,9 @@ todo_wine {
enummoniker2 = (void *)0xdeadbeef; hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); -todo_wine { ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); ok(!enummoniker2, "Unexpected pointer.\n"); -} + IEnumMoniker_Release(enummoniker);
/* Backward direction */ @@ -3783,10 +3781,9 @@ todo_wine {
enummoniker2 = (void *)0xdeadbeef; hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); -todo_wine { ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); ok(!enummoniker2, "Unexpected pointer.\n"); -} + hr = IEnumMoniker_Reset(enummoniker); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -3802,10 +3799,9 @@ todo_wine {
enummoniker2 = (void *)0xdeadbeef; hr = IEnumMoniker_Clone(enummoniker, &enummoniker2); -todo_wine { ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); ok(!enummoniker2, "Unexpected pointer.\n"); -} + IEnumMoniker_Release(enummoniker);
IMoniker_Release(moniker);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/compositemoniker.c | 137 +++++++++++++--------------------- 1 file changed, 52 insertions(+), 85 deletions(-)
diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index 652962e1a87..a94e4734f45 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -72,13 +72,13 @@ static inline CompositeMonikerImpl *impl_from_IMarshal(IMarshal *iface) return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMarshal_iface); }
-/* EnumMoniker data structure */ -typedef struct EnumMonikerImpl{ +typedef struct EnumMonikerImpl +{ IEnumMoniker IEnumMoniker_iface; LONG ref; - IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */ - ULONG tabSize; /* size of tabMoniker */ - ULONG currentPos; /* index pointer on the current moniker */ + IMoniker **monikers; + unsigned int count; + unsigned int pos; } EnumMonikerImpl;
static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface) @@ -86,7 +86,7 @@ static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface) return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface); }
-static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk); +static HRESULT create_enumerator(IMoniker **components, unsigned int count, BOOL forward, IEnumMoniker **ret); static HRESULT composite_get_rightmost(CompositeMonikerImpl *composite, IMoniker **left, IMoniker **rightmost); static HRESULT composite_get_leftmost(CompositeMonikerImpl *composite, IMoniker **leftmost);
@@ -492,21 +492,21 @@ static HRESULT composite_get_components_alloc(IMoniker *iface, unsigned int *cou return S_OK; }
-static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ppenumMoniker) +static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ret_enum) { IMoniker **monikers; unsigned int count; HRESULT hr;
- TRACE("%p, %d, %p\n", iface, forward, ppenumMoniker); + TRACE("%p, %d, %p\n", iface, forward, ret_enum);
- if (!ppenumMoniker) + if (!ret_enum) return E_INVALIDARG;
if (FAILED(hr = composite_get_components_alloc(iface, &count, &monikers))) return hr;
- hr = EnumMonikerImpl_CreateEnumMoniker(monikers, count, 0, forward, ppenumMoniker); + hr = create_enumerator(monikers, count, forward, ret_enum); heap_free(monikers);
return hr; @@ -1280,36 +1280,30 @@ EnumMonikerImpl_AddRef(IEnumMoniker* iface)
}
-/****************************************************************************** - * EnumMonikerImpl_Release - ******************************************************************************/ -static ULONG WINAPI -EnumMonikerImpl_Release(IEnumMoniker* iface) +static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker *iface) { - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - ULONG i; - ULONG ref; - TRACE("(%p)\n",This); - - ref = InterlockedDecrement(&This->ref); - - /* destroy the object if there are no more references to it */ - if (ref == 0) { + EnumMonikerImpl *e = impl_from_IEnumMoniker(iface); + ULONG refcount = InterlockedDecrement(&e->ref); + unsigned int i;
- for(i=0;i<This->tabSize;i++) - IMoniker_Release(This->tabMoniker[i]); + TRACE("%p, refcount %d.\n", iface, refcount);
- HeapFree(GetProcessHeap(),0,This->tabMoniker); - HeapFree(GetProcessHeap(),0,This); + if (!refcount) + { + for (i = 0; i < e->count; ++i) + IMoniker_Release(e->monikers[i]); + heap_free(e->monikers); + heap_free(e); } - return ref; + + return refcount; }
static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count, IMoniker **m, ULONG *fetched) { - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - ULONG i; + EnumMonikerImpl *e = impl_from_IEnumMoniker(iface); + unsigned int i;
TRACE("%p, %u, %p, %p.\n", iface, count, m, fetched);
@@ -1319,9 +1313,9 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count, *m = NULL;
/* retrieve the requested number of moniker from the current position */ - for(i=0;((This->currentPos < This->tabSize) && (i < count));i++) + for (i = 0; (e->pos < e->count) && (i < count); ++i) { - m[i] = This->tabMoniker[This->currentPos++]; + m[i] = e->monikers[e->pos++]; IMoniker_AddRef(m[i]); }
@@ -1333,30 +1327,28 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker *iface, ULONG count,
static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker *iface, ULONG count) { - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); + EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
TRACE("%p, %u.\n", iface, count);
if (!count) return S_OK;
- if ((This->currentPos + count) >= This->tabSize) + if ((e->pos + count) >= e->count) return S_FALSE;
- This->currentPos += count; + e->pos += count;
return S_OK; }
-/****************************************************************************** - * EnumMonikerImpl_Reset - ******************************************************************************/ -static HRESULT WINAPI -EnumMonikerImpl_Reset(IEnumMoniker* iface) +static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface) { - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); + EnumMonikerImpl *e = impl_from_IEnumMoniker(iface);
- This->currentPos=0; + TRACE("%p.\n", iface); + + e->pos = 0;
return S_OK; } @@ -1384,60 +1376,35 @@ static const IEnumMonikerVtbl VT_EnumMonikerImpl = EnumMonikerImpl_Clone };
-/****************************************************************************** - * EnumMonikerImpl_CreateEnumMoniker - ******************************************************************************/ -static HRESULT -EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize, - ULONG currentPos, BOOL leftToRight, IEnumMoniker ** ppmk) +static HRESULT create_enumerator(IMoniker **components, unsigned int count, BOOL forward, IEnumMoniker **ret) { - EnumMonikerImpl* newEnumMoniker; - ULONG i; - - if (currentPos > tabSize) - return E_INVALIDARG; - - newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl)); - - if (newEnumMoniker == 0) - return STG_E_INSUFFICIENTMEMORY; - - /* Initialize the virtual function table. */ - newEnumMoniker->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl; - newEnumMoniker->ref = 1; + EnumMonikerImpl *object; + unsigned int i;
- newEnumMoniker->tabSize=tabSize; - newEnumMoniker->currentPos=currentPos; + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY;
- newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(newEnumMoniker->tabMoniker[0])); + object->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl; + object->ref = 1; + object->count = count;
- if (newEnumMoniker->tabMoniker==NULL) { - HeapFree(GetProcessHeap(), 0, newEnumMoniker); + if (!(object->monikers = heap_calloc(count, sizeof(*object->monikers)))) + { + heap_free(object); return E_OUTOFMEMORY; }
- if (leftToRight) - for (i=0;i<tabSize;i++){ - - newEnumMoniker->tabMoniker[i]=tabMoniker[i]; - IMoniker_AddRef(tabMoniker[i]); - } - else - for (i = tabSize; i > 0; i--){ - - newEnumMoniker->tabMoniker[tabSize-i]=tabMoniker[i - 1]; - IMoniker_AddRef(tabMoniker[i - 1]); - } + for (i = 0; i < count; ++i) + { + object->monikers[i] = forward ? components[i] : components[count - i - 1]; + IMoniker_AddRef(object->monikers[i]); + }
- *ppmk=&newEnumMoniker->IEnumMoniker_iface; + *ret = &object->IEnumMoniker_iface;
return S_OK; }
-/********************************************************************************/ -/* Virtual function table for the CompositeMonikerImpl class which includes */ -/* IPersist, IPersistStream and IMoniker functions. */ - static const IMonikerVtbl VT_CompositeMonikerImpl = { CompositeMonikerImpl_QueryInterface,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/Makefile.in | 2 +- dlls/ole32/filemoniker.c | 161 +++++++++++++++++++-------------------- dlls/ole32/moniker.c | 31 ++------ dlls/ole32/moniker.h | 3 - 4 files changed, 85 insertions(+), 112 deletions(-)
diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index 84694e1538d..340ffdbded2 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -1,6 +1,6 @@ MODULE = ole32.dll IMPORTLIB = ole32 -IMPORTS = uuid advapi32 user32 gdi32 combase rpcrt4 +IMPORTS = uuid advapi32 user32 gdi32 combase rpcrt4 kernelbase DELAYIMPORTS = oleaut32 EXTRADEFS = -D_OLE32_
diff --git a/dlls/ole32/filemoniker.c b/dlls/ole32/filemoniker.c index 213971ea96b..794b4507942 100644 --- a/dlls/ole32/filemoniker.c +++ b/dlls/ole32/filemoniker.c @@ -631,6 +631,85 @@ static void free_stringtable(LPOLESTR *stringTable) CoTaskMemFree(stringTable); }
+static int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable) +{ + LPOLESTR word; + int i=0,j,tabIndex=0, ret=0; + LPOLESTR *strgtable ; + + int len=lstrlenW(str); + + TRACE("%s, %p\n", debugstr_w(str), *stringTable); + + strgtable = CoTaskMemAlloc((len + 1)*sizeof(*strgtable)); + + if (strgtable==NULL) + return E_OUTOFMEMORY; + + word = CoTaskMemAlloc((len + 1)*sizeof(WCHAR)); + + if (word==NULL) + { + ret = E_OUTOFMEMORY; + goto lend; + } + + while(str[i]!=0){ + + if (str[i] == L'\') + { + + strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR)); + + if (strgtable[tabIndex]==NULL) + { + ret = E_OUTOFMEMORY; + goto lend; + } + + lstrcpyW(strgtable[tabIndex++], L"\"); + + i++; + + } + else { + + for (j = 0; str[i] && str[i] != L'\'; i++, j++) + word[j]=str[i]; + + word[j]=0; + + strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1)); + + if (strgtable[tabIndex]==NULL) + { + ret = E_OUTOFMEMORY; + goto lend; + } + + lstrcpyW(strgtable[tabIndex++],word); + } + } + strgtable[tabIndex]=NULL; + + *stringTable=strgtable; + + ret = tabIndex; + +lend: + if (ret < 0) + { + for (i = 0; i < tabIndex; i++) + CoTaskMemFree(strgtable[i]); + + CoTaskMemFree(strgtable); + } + + CoTaskMemFree(word); + + return ret; +} + /****************************************************************************** * FileMoniker_ComposeWith */ @@ -970,88 +1049,6 @@ failed: return ret; }
-/****************************************************************************** - * DecomposePath (local function) - */ -int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable) -{ - LPOLESTR word; - int i=0,j,tabIndex=0, ret=0; - LPOLESTR *strgtable ; - - int len=lstrlenW(str); - - TRACE("%s, %p\n", debugstr_w(str), *stringTable); - - strgtable = CoTaskMemAlloc((len + 1)*sizeof(*strgtable)); - - if (strgtable==NULL) - return E_OUTOFMEMORY; - - word = CoTaskMemAlloc((len + 1)*sizeof(WCHAR)); - - if (word==NULL) - { - ret = E_OUTOFMEMORY; - goto lend; - } - - while(str[i]!=0){ - - if (str[i] == L'\') - { - - strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR)); - - if (strgtable[tabIndex]==NULL) - { - ret = E_OUTOFMEMORY; - goto lend; - } - - lstrcpyW(strgtable[tabIndex++], L"\"); - - i++; - - } - else { - - for (j = 0; str[i] && str[i] != L'\'; i++, j++) - word[j]=str[i]; - - word[j]=0; - - strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1)); - - if (strgtable[tabIndex]==NULL) - { - ret = E_OUTOFMEMORY; - goto lend; - } - - lstrcpyW(strgtable[tabIndex++],word); - } - } - strgtable[tabIndex]=NULL; - - *stringTable=strgtable; - - ret = tabIndex; - -lend: - if (ret < 0) - { - for (i = 0; i < tabIndex; i++) - CoTaskMemFree(strgtable[i]); - - CoTaskMemFree(strgtable); - } - - CoTaskMemFree(word); - - return ret; -} - /****************************************************************************** * FileMoniker_RelativePathTo */ diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index aed491d406f..ac47f5528c8 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -32,6 +32,7 @@ #include "compobj_private.h" #include "moniker.h" #include "irot.h" +#include "pathcch.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -910,10 +911,9 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid) { IStorage *pstg=0; HRESULT res; - int nbElm, length, i; LONG sizeProgId, ret; - LPOLESTR *pathDec=0,absFile=0,progId=0; - LPWSTR extension; + LPOLESTR progId=0; + const WCHAR *extension;
TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);
@@ -954,26 +954,9 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid)
/* if the above strategies fail then search for the extension key in the registry */
- /* get the last element (absolute file) in the path name */ - nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec); - absFile=pathDec[nbElm-1]; - - /* failed if the path represents a directory and not an absolute file name*/ - if (!wcscmp(absFile, L"\")) { - CoTaskMemFree(pathDec); + res = PathCchFindExtension(filePathName, PATHCCH_MAX_CCH, &extension); + if (FAILED(res) || !extension || !*extension || !wcscmp(extension, L".")) return MK_E_INVALIDEXTENSION; - } - - /* get the extension of the file */ - extension = NULL; - length=lstrlenW(absFile); - for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--) - /* nothing */; - - if (!extension || !wcscmp(extension, L".")) { - CoTaskMemFree(pathDec); - return MK_E_INVALIDEXTENSION; - }
ret = RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId); if (!ret) { @@ -990,10 +973,6 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid) else res = HRESULT_FROM_WIN32(ret);
- for(i=0; pathDec[i]!=NULL;i++) - CoTaskMemFree(pathDec[i]); - CoTaskMemFree(pathDec); - return res != S_OK ? MK_E_INVALIDEXTENSION : res; }
diff --git a/dlls/ole32/moniker.h b/dlls/ole32/moniker.h index 995e0459e5e..8549bd46c1e 100644 --- a/dlls/ole32/moniker.h +++ b/dlls/ole32/moniker.h @@ -38,9 +38,6 @@ HRESULT WINAPI ClassMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, HRESULT WINAPI PointerMoniker_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv); HRESULT WINAPI ComCat_CreateInstance(IClassFactory *iface, IUnknown *pUnk, REFIID riid, void **ppv);
-/* This function decomposes a String path to a String Table containing all the elements ("" or "subDirectory" or "Directory" or "FileName") of the path */ -int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable) DECLSPEC_HIDDEN; - HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten, LPMONIKER *ppmk) DECLSPEC_HIDDEN; HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,