From: David Hedberg Subject: [PATCH 6/7] shell32: Implement IShellItemArray::GetAttributes Message-Id: <1406745806-17144-6-git-send-email-david.hedberg@gmail.com> Date: Wed, 30 Jul 2014 20:43:25 +0200 --- dlls/shell32/shellitem.c | 41 +++++++++++++++++- dlls/shell32/tests/shlfolder.c | 98 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/dlls/shell32/shellitem.c b/dlls/shell32/shellitem.c index 707a4c2..772023a 100644 --- a/dlls/shell32/shellitem.c +++ b/dlls/shell32/shellitem.c @@ -881,9 +881,46 @@ static HRESULT WINAPI IShellItemArray_fnGetAttributes(IShellItemArray *iface, SFGAOF *psfgaoAttribs) { IShellItemArrayImpl *This = impl_from_IShellItemArray(iface); - FIXME("Stub: %p (%x, %x, %p)\n", This, AttribFlags, sfgaoMask, psfgaoAttribs); + HRESULT hr = S_OK; + SFGAOF attr; + UINT i; + TRACE("%p (%x, %x, %p)\n", This, AttribFlags, sfgaoMask, psfgaoAttribs); - return E_NOTIMPL; + if(AttribFlags & ~(SIATTRIBFLAGS_AND|SIATTRIBFLAGS_OR)) + FIXME("%08x contains unsupported attribution flags", AttribFlags); + + for(i = 0; i < This->item_count; i++) + { + hr = IShellItem_GetAttributes(This->array[i], sfgaoMask, &attr); + if(FAILED(hr)) + break; + + if(i == 0) + { + *psfgaoAttribs = attr; + continue; + } + + switch(AttribFlags & SIATTRIBFLAGS_MASK) + { + case SIATTRIBFLAGS_AND: + *psfgaoAttribs &= attr; + break; + case SIATTRIBFLAGS_OR: + *psfgaoAttribs |= attr; + break; + } + } + + if(SUCCEEDED(hr)) + { + if(*psfgaoAttribs == sfgaoMask) + return S_OK; + + return S_FALSE; + } + + return hr; } static HRESULT WINAPI IShellItemArray_fnGetCount(IShellItemArray *iface, diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index 38d265a..6ea6813 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -3984,6 +3984,103 @@ static void test_ShellItemGetAttributes(void) Cleanup(); } +static void test_ShellItemArrayGetAttributes(void) +{ + IShellItemArray *psia_files, *psia_folders1, *psia_folders2, *psia_all; + IShellFolder *pdesktopsf; + LPCITEMIDLIST pidl_array[5]; + SFGAOF attr; + HRESULT hr; + WCHAR curdirW[MAX_PATH]; + WCHAR buf[MAX_PATH]; + UINT i; + static const WCHAR testdir1W[] = {'t','e','s','t','d','i','r',0}; + static const WCHAR testdir2W[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','2',0}; + static const WCHAR testdir3W[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','3',0}; + static const WCHAR testfile1W[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0}; + static const WCHAR testfile2W[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','2','.','t','x','t',0}; + static const WCHAR *testfilesW[5] = { testdir1W, testdir2W, testdir3W, testfile1W, testfile2W }; + + if(!pSHCreateShellItemArrayFromShellItem) + { + win_skip("No SHCreateShellItemArrayFromShellItem, skipping test.."); + return; + } + + CreateFilesFolders(); + CreateDirectoryA(".\\testdir\\testdir3", NULL); + + SHGetDesktopFolder(&pdesktopsf); + + GetCurrentDirectoryW(MAX_PATH, curdirW); + myPathAddBackslashW(curdirW); + + for(i = 0; i < 5; i++) + { + lstrcpyW(buf, curdirW); + lstrcatW(buf, testfilesW[i]); + hr = IShellFolder_ParseDisplayName(pdesktopsf, NULL, NULL, buf, NULL, (LPITEMIDLIST*)&pidl_array[i], NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + } + IShellFolder_Release(pdesktopsf); + + hr = pSHCreateShellItemArrayFromIDLists(2, pidl_array, &psia_folders1); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = pSHCreateShellItemArrayFromIDLists(2, &pidl_array[1], &psia_folders2); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = pSHCreateShellItemArrayFromIDLists(2, &pidl_array[3], &psia_files); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = pSHCreateShellItemArrayFromIDLists(4, &pidl_array[1], &psia_all); /* All except the first */ + ok(hr == S_OK, "got 0x%08x\n", hr); + + for(i = 0; i < 5; i++) + pILFree((LPITEMIDLIST)pidl_array[i]); + + /* [testfolder/, testfolder/testfolder2] seems to break in Vista */ + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_folders1, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attr); + ok(hr == S_OK || broken(hr == E_UNEXPECTED) /* Vista */, "Got 0x%08x\n", hr); + ok(attr == SFGAO_FOLDER || broken(attr == 0) /* Vista */, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_folders1, SIATTRIBFLAGS_OR, SFGAO_FOLDER, &attr); + ok(hr == S_OK || broken(hr == E_UNEXPECTED) /* Vista */, "Got 0x%08x\n", hr); + ok(attr == SFGAO_FOLDER || broken(attr == 0) /* Vista */, "Got 0x%08x\n", attr); + + /* [testfolder/testfolder2, testfolder/testfolder3] works */ + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_folders2, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attr); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(attr == SFGAO_FOLDER, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_files, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attr); + ok(hr == S_FALSE || broken(hr == S_OK) /* Vista */, "Got 0x%08x\n", hr); + ok(attr == 0, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_all, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attr); + ok(hr == S_FALSE || broken(hr == S_OK) /* Vista */, "Got 0x%08x\n", hr); + ok(attr == 0, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_folders2, SIATTRIBFLAGS_OR, SFGAO_FOLDER, &attr); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(attr == SFGAO_FOLDER, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_files, SIATTRIBFLAGS_OR, SFGAO_FOLDER, &attr); + ok(hr == S_FALSE || broken(hr == S_OK) /* Vista */, "Got 0x%08x\n", hr); + ok(attr == 0, "Got 0x%08x\n", attr); + attr = 0xdeadbeef; + hr = IShellItemArray_GetAttributes(psia_all, SIATTRIBFLAGS_OR, SFGAO_FOLDER, &attr); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(attr == SFGAO_FOLDER, "Got 0x%08x\n", attr); + + IShellItemArray_Release(psia_folders1); + IShellItemArray_Release(psia_folders2); + IShellItemArray_Release(psia_files); + IShellItemArray_Release(psia_all); + + RemoveDirectoryA(".\\testdir\\testdir3"); + Cleanup(); +} + static void test_SHParseDisplayName(void) { LPITEMIDLIST pidl1, pidl2; @@ -5006,6 +5103,7 @@ START_TEST(shlfolder) test_SHChangeNotify(TRUE); test_ShellItemBindToHandler(); test_ShellItemGetAttributes(); + test_ShellItemArrayGetAttributes(); test_SHCreateDefaultContextMenu(); test_SHCreateShellFolderView(); test_SHCreateShellFolderViewEx(); -- 2.0.1