[2/2] shell32: Add proper support for SHGetFileInfo(SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES).

Francois Gouget fgouget at free.fr
Thu Jan 18 09:23:30 CST 2007


This fixes the WinZip 11 and SimSig installers.
---
 dlls/shell32/shell32_main.c    |   67 ++++++++++++++++++++++++++++------------
 dlls/shell32/tests/shlfileop.c |    6 ++--
 2 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 476a4ae..9ee744f 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -356,14 +356,6 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
          (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL)))
         return FALSE;
 
-    if ( (flags & SHGFI_USEFILEATTRIBUTES) &&
-         (flags & (SHGFI_ICONLOCATION | SHGFI_ICON | SHGFI_SYSICONINDEX)) )
-    {
-        FIXME("This combination of flags is not supported yet\n");
-        /* And it would cause a crash, so return false instead */
-        return FALSE;
-    }
-
     /* windows initializes these values regardless of the flags */
     if (psfi != NULL)
     {
@@ -519,21 +511,56 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
     {
         UINT uDummy,uFlags;
 
-        hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1,
-               (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW,
-               &uDummy, (LPVOID*)&pei);
-        if (SUCCEEDED(hr))
+        if (flags & SHGFI_USEFILEATTRIBUTES)
         {
-            hr = IExtractIconW_GetIconLocation(pei, uGilFlags,
-                    szLocation, MAX_PATH, &iIndex, &uFlags);
-            psfi->iIcon = iIndex;
-
-            if (!(uFlags & GIL_NOTFILENAME))
-                lstrcpyW (psfi->szDisplayName, szLocation);
+            if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+            {
+                lstrcpyW(psfi->szDisplayName, swShell32Name);
+                psfi->iIcon = -IDI_SHELL_FOLDER;
+            }
             else
-                ret = FALSE;
+            {
+                WCHAR* szExt;
+                static const WCHAR p1W[] = {'%','1',0};
+                WCHAR sTemp [MAX_PATH];
 
-            IExtractIconW_Release(pei);
+                szExt = (LPWSTR) PathFindExtensionW(szFullPath);
+                TRACE("szExt=%s\n", debugstr_w(szExt));
+                if ( szExt &&
+                     HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) &&
+                     HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &psfi->iIcon))
+                {
+                    if (lstrcmpW(p1W, sTemp))
+                        strcpyW(psfi->szDisplayName, sTemp);
+                    else
+                    {
+                        /* the icon is in the file */
+                        strcpyW(psfi->szDisplayName, szFullPath);
+                    }
+                }
+                else
+                    ret = FALSE;
+            }
+        }
+        else
+        {
+            hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1,
+                (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW,
+                &uDummy, (LPVOID*)&pei);
+            if (SUCCEEDED(hr))
+            {
+                hr = IExtractIconW_GetIconLocation(pei, uGilFlags,
+                    szLocation, MAX_PATH, &iIndex, &uFlags);
+
+                if (uFlags & GIL_NOTFILENAME)
+                    ret = FALSE;
+                else
+                {
+                    lstrcpyW (psfi->szDisplayName, szLocation);
+                    psfi->iIcon = iIndex;
+                }                
+                IExtractIconW_Release(pei);
+            }
         }
     }
 
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c
index f6e599e..b363c5e 100644
--- a/dlls/shell32/tests/shlfileop.c
+++ b/dlls/shell32/tests/shlfileop.c
@@ -140,7 +140,7 @@ static void test_get_file_info(void)
     rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
                       &shfi, sizeof(shfi),
                       SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
-    todo_wine ok(rc, "SHGetFileInfoA(c:\\nonexistent) failed\n");
+    ok(rc, "SHGetFileInfoA(c:\\nonexistent) failed\n");
     if (rc)
     {
         ok(strcpy(shfi.szDisplayName, "dummy") != 0, "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
@@ -157,7 +157,7 @@ static void test_get_file_info(void)
         rc=SHGetFileInfoA(notepad, GetFileAttributes(notepad),
                           &shfi, sizeof(shfi),
                           SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
-        todo_wine ok(rc, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) failed\n", notepad);
+        ok(rc, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) failed\n", notepad);
         strcpy(shfi2.szDisplayName, "dummy");
         shfi2.iIcon=0xdeadbeef;
         rc2=SHGetFileInfoA(notepad, 0,
@@ -177,7 +177,7 @@ static void test_get_file_info(void)
     rc=SHGetFileInfoA("test4.txt", GetFileAttributes("test4.txt"),
                       &shfi, sizeof(shfi),
                       SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
-    todo_wine ok(rc, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) failed\n");
+    ok(rc, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) failed\n");
     strcpy(shfi2.szDisplayName, "dummy");
     shfi2.iIcon=0xdeadbeef;
     rc2=SHGetFileInfoA("test4.txt", 0,
-- 
1.4.4.3



More information about the wine-patches mailing list