Module: wine Branch: master Commit: a1f7339137a2857674a1b2835ed9539bbbafe415 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a1f7339137a2857674a1b2835e... Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Fri Sep 15 13:14:17 2017 +0300 shell32: Implement Application property for FolderItem. Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/shell32/shelldispatch.c | 28 +++++++++++++++++----------- dlls/shell32/tests/shelldispatch.c | 25 +++++++++++++++++++++---- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/dlls/shell32/shelldispatch.c b/dlls/shell32/shelldispatch.c index a225f45..ee6f340 100644 --- a/dlls/shell32/shelldispatch.c +++ b/dlls/shell32/shelldispatch.c @@ -77,6 +77,7 @@ typedef struct { typedef struct { FolderItem2 FolderItem2_iface; LONG ref; + FolderImpl *folder; VARIANT dir; } FolderItemImpl; @@ -646,6 +647,7 @@ static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface) if (!ref) { VariantClear(&This->dir); + Folder3_Release(&This->folder->Folder3_iface); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -707,13 +709,13 @@ static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface, return hr; } -static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface, - IDispatch **ppid) +static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface, IDispatch **disp) { - FIXME("(%p,%p)\n", iface, ppid); + FolderItemImpl *This = impl_from_FolderItem(iface); - *ppid = NULL; - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, disp); + + return Folder3_get_Application(&This->folder->Folder3_iface, disp); } static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface, @@ -928,7 +930,7 @@ static const FolderItem2Vtbl FolderItemImpl_Vtbl = { FolderItemImpl_ExtendedProperty }; -static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi) +static HRESULT FolderItem_Constructor(FolderImpl *folder, VARIANT *dir, FolderItem **ppfi) { FolderItemImpl *This; HRESULT ret; @@ -950,7 +952,10 @@ static HRESULT FolderItem_Constructor(VARIANT *dir, FolderItem **ppfi) return E_OUTOFMEMORY; } - *ppfi = (FolderItem*)&This->FolderItem2_iface; + This->folder = folder; + Folder3_AddRef(&folder->Folder3_iface); + + *ppfi = (FolderItem *)&This->FolderItem2_iface; return ret; } @@ -1137,7 +1142,7 @@ static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, F break; case VT_ERROR: - return FolderItem_Constructor(&This->folder->dir, ppid); + return FolderItem_Constructor(This->folder, &This->folder->dir, ppid); default: return E_NOTIMPL; @@ -1145,7 +1150,7 @@ static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, F V_VT(&path_var) = VT_BSTR; V_BSTR(&path_var) = SysAllocString(path_str); - ret = FolderItem_Constructor(&path_var, ppid); + ret = FolderItem_Constructor(This->folder, &path_var, ppid); VariantClear(&path_var); return ret; } @@ -1451,6 +1456,7 @@ static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid) static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item) { + FolderImpl *This = impl_from_Folder(iface); FolderItem *self; BSTR str; WCHAR pathW[MAX_PATH]; @@ -1479,7 +1485,7 @@ static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString(pathW); - hr = FolderItem_Constructor(&v, item); + hr = FolderItem_Constructor(This, &v, item); VariantClear(&v); return hr; } @@ -1523,7 +1529,7 @@ static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi) TRACE("(%p,%p)\n", iface, ppfi); - return FolderItem_Constructor(&This->dir, ppfi); + return FolderItem_Constructor(This, &This->dir, ppfi); } static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul) diff --git a/dlls/shell32/tests/shelldispatch.c b/dlls/shell32/tests/shelldispatch.c index 831402a..eb8a8c7 100644 --- a/dlls/shell32/tests/shelldispatch.c +++ b/dlls/shell32/tests/shelldispatch.c @@ -483,7 +483,7 @@ static void test_items(void) if (item) FolderItem_Release(item); VariantClear(&var); - /* recreate the folder object */ + /* recreate the items object */ FolderItems_Release(items); items = NULL; r = Folder_Items(folder, &items); @@ -491,7 +491,11 @@ static void test_items(void) ok(!!items, "items is null\n"); r = FolderItems_QueryInterface(items, &IID_FolderItems2, (void**)&items2); ok(r == S_OK || broken(r == E_NOINTERFACE) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r); - if (r == S_OK) ok(!!items2, "items2 is null\n"); + if (r == S_OK) + { + ok(!!items2, "items2 is null\n"); + FolderItems2_Release(items2); + } r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3); ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r); ok(!!items3, "items3 is null\n"); @@ -510,11 +514,25 @@ static void test_items(void) V_VT(&var) = VT_I2; V_I2(&var) = 0; + + EXPECT_REF(folder, 2); + EXPECT_REF(items, 2); item = NULL; r = FolderItems_Item(items, var, &item); ok(r == S_OK, "FolderItems::Item failed: %08x\n", r); ok(!!item, "item is null\n"); - if (item) FolderItem_Release(item); + EXPECT_REF(folder, 3); + EXPECT_REF(items, 2); + + r = Folder_get_Application(folder, &disp); + ok(r == S_OK, "Failed to get application pointer %#x.\n", r); + r = FolderItem_get_Application(item, &disp2); + ok(r == S_OK, "Failed to get application pointer %#x.\n", r); + ok(disp == disp2, "Unexpected application pointer.\n"); + IDispatch_Release(disp2); + IDispatch_Release(disp); + + FolderItem_Release(item); V_VT(&var) = VT_I4; V_I4(&var) = 0; @@ -740,7 +758,6 @@ todo_wine FolderItems_Release(items); Folder_Release(folder); - if (items2) FolderItems2_Release(items2); if (items3) FolderItems3_Release(items3); IShellDispatch_Release(sd); }