[PATCH 6/7] shell32: Implement IShellItemArray::GetAttributes

David Hedberg david.hedberg at gmail.com
Wed Jul 30 13:43:25 CDT 2014


---
 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




More information about the wine-patches mailing list