[PATCH 3/4] shell32: Take a reference on the imagelist returned with SHGFI_SYSICONINDEX.

Huw Davies huw at codeweavers.com
Fri Apr 21 03:49:27 CDT 2017


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/shell32/shell32_main.c    |  2 ++
 dlls/shell32/tests/shlfileop.c | 59 +++++++++++++++++++++++++++++++-----------
 2 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 1a22150d86..0ccde93223 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -40,6 +40,7 @@
 #include "rpcproxy.h"
 #include "shlwapi.h"
 #include "propsys.h"
+#include "commoncontrols.h"
 
 #include "undocshell.h"
 #include "pidl.h"
@@ -730,6 +731,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
                 ret = (DWORD_PTR)small_icons;
             else
                 ret = (DWORD_PTR)big_icons;
+            IImageList_AddRef((IImageList*)ret);
         }
     }
 
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index 4ae93ff23c..b13c554cfe 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -21,10 +21,12 @@
 #include <stdarg.h>
 #include <stdio.h>
 
+#define COBJMACROS
 #define WINE_NOWINSOCK
 #include <windows.h>
 #include "shellapi.h"
 #include "shlobj.h"
+#include "commoncontrols.h"
 
 #include "wine/test.h"
 
@@ -325,6 +327,8 @@ static void test_get_file_info_iconlist(void)
     LPITEMIDLIST pidList;
     SHFILEINFOA shInfoa;
     SHFILEINFOW shInfow;
+    IImageList *small_list, *large_list;
+    ULONG start_refs, refs;
 
     hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
     if (FAILED(hr)) {
@@ -332,11 +336,22 @@ static void test_get_file_info_iconlist(void)
          return;
     }
 
+    SHGetImageList( SHIL_LARGE, &IID_IImageList, (void **)&large_list );
+    SHGetImageList( SHIL_SMALL, &IID_IImageList, (void **)&small_list );
+
+    start_refs = IImageList_AddRef( small_list );
+    IImageList_Release( small_list );
+
     memset(&shInfoa, 0xcf, sizeof(shInfoa));
     hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
             &shInfoa, sizeof(shInfoa),
 	    SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
-    ok((hSysImageList != INVALID_HANDLE_VALUE) && (hSysImageList > (HIMAGELIST) 0xffff), "Can't get handle for CSIDL_DESKTOP imagelist\n");
+    ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
+    refs = IImageList_AddRef( small_list );
+    IImageList_Release( small_list );
+    ok( refs == start_refs + 1 ||
+        broken( refs == start_refs ), /* XP and 2003 */
+        "got %d, start_refs %d\n", refs, start_refs );
     todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
     todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
     ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
@@ -344,7 +359,7 @@ static void test_get_file_info_iconlist(void)
        shInfoa.dwAttributes ==  0 || /* Vista */
        broken(shInfoa.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
        "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL), unexpected dwAttributes\n");
-    CloseHandle(hSysImageList);
+    /* Don't release hSysImageList here (and in similar places below) because of the broken reference behaviour of XP and 2003. */
 
     if (!pSHGetFileInfoW)
     {
@@ -362,20 +377,19 @@ static void test_get_file_info_iconlist(void)
         win_skip("SHGetFileInfoW is not implemented\n");
         return;
     }
-    ok((hSysImageList != INVALID_HANDLE_VALUE) && (hSysImageList > (HIMAGELIST) 0xffff), "Can't get handle for CSIDL_DESKTOP imagelist\n");
+    ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
     todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
     ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
     ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
     ok(shInfow.dwAttributes == 0xcfcfcfcf ||
        shInfoa.dwAttributes ==  0, /* Vista */
        "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) unexpected dwAttributes\n");
-    CloseHandle(hSysImageList);
 
     /* Various suposidly invalid flag testing */
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr =  pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
 	    SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
-    ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
+    ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes==0xcfcfcfcf ||
        shInfoa.dwAttributes==0, /* Vista */
@@ -400,9 +414,9 @@ static void test_get_file_info_iconlist(void)
     todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
 
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
 	    SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
-    ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
+    ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes==0xcfcfcfcf ||
        shInfoa.dwAttributes==0, /* Vista */
@@ -430,18 +444,18 @@ static void test_get_file_info_iconlist(void)
     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
 
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
 	    SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
         SHGFI_ATTRIBUTES);
-    ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
+    ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
 
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
 	    SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
         SHGFI_EXETYPE);
-    todo_wine ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
+    todo_wine ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes==0xcfcfcfcf ||
        shInfoa.dwAttributes==0, /* Vista */
@@ -462,17 +476,18 @@ static void test_get_file_info_iconlist(void)
     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
 
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
 	    SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
         SHGFI_ATTRIBUTES);
+    ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
     ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
 
     memset(&shInfow, 0xcf, sizeof(shInfow));
-    hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
         SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
-    todo_wine ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
+    todo_wine ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
     ok(shInfow.dwAttributes==0xcfcfcfcf ||
        shInfoa.dwAttributes==0, /* Vista */
@@ -492,7 +507,21 @@ static void test_get_file_info_iconlist(void)
     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
 
+    memset(&shInfow, 0xcf, sizeof(shInfow));
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+	    SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SHELLICONSIZE);
+    ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
+    ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
+
+    memset(&shInfow, 0xcf, sizeof(shInfow));
+    hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
+	    SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SHELLICONSIZE);
+    ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
+    ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
+
     ILFree(pidList);
+    IImageList_Release( small_list );
+    IImageList_Release( large_list );
 }
 
 
-- 
2.12.0




More information about the wine-patches mailing list