https://git.reactos.org/?p=reactos.git;a=commitdiff;h=338799bf8bf98698f3e4c…
commit 338799bf8bf98698f3e4c1c2b885d724a9a929da
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Feb 16 20:00:08 2018 +0900
Commit:     Ged Murphy <gedmurphy(a)reactos.org>
CommitDate: Fri Feb 16 11:00:08 2018 +0000
    improve SHGetFileInfo (#118)
    This patch reduces failures of SHGetFileInfo function. CORE-7159
    * improve WideByteToWideChar calls
    * fix bugs related to file attributes and SHGFI_EXETYPE
    * SHGFI_USEFILEATTRIBUTES and SHGFI_ICON fix
    * s/sizeof(temppsfi)/0/
---
 dll/win32/shell32/wine/shell32_main.c | 81 +++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 32 deletions(-)
diff --git a/dll/win32/shell32/wine/shell32_main.c b/dll/win32/shell32/wine/shell32_main.c
index b5638f0582..e64ef7f6fb 100644
--- a/dll/win32/shell32/wine/shell32_main.c
+++ b/dll/win32/shell32/wine/shell32_main.c
@@ -3,6 +3,7 @@
  *
  * Copyright 1998 Marcus Meissner
  * Copyright 1998 Juergen Schmied (jsch)  *  <juergen.schmied(a)metronet.de>
+ * Copyright 2017 Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -433,7 +434,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
     {
         psfi->szDisplayName[0] = '\0';
         psfi->szTypeName[0] = '\0';
-        psfi->iIcon = 0;
+        psfi->hIcon = NULL;
     }
     if (!(flags & SHGFI_PIDL))
@@ -449,12 +450,24 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
             lstrcpynW(szFullPath, path, MAX_PATH);
         }
     }
+    else
+    {
+        SHGetPathFromIDListW((LPITEMIDLIST)path, szFullPath);
+    }
     if (flags & SHGFI_EXETYPE)
     {
-        if (flags != SHGFI_EXETYPE)
-            return 0;
-        return shgfi_get_exe_type(szFullPath);
+        if (!(flags & SHGFI_SYSICONINDEX))
+        {
+            if (flags & SHGFI_USEFILEATTRIBUTES)
+            {
+                return TRUE;
+            }
+            else if (GetFileAttributesW(szFullPath) != INVALID_FILE_ATTRIBUTES)
+            {
+                return shgfi_get_exe_type(szFullPath);
+            }
+        }
     }
     /*
@@ -488,6 +501,8 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
                                 (LPCITEMIDLIST*)&pidlLast );
             if (SUCCEEDED(hr))
                 pidlLast = ILClone(pidlLast);
+            else
+                hr = S_OK;
             ILFree(pidl);
         }
         else
@@ -505,8 +520,18 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
             psfi->dwAttributes = 0xffffffff;
         }
         if (psfParent)
-            IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast,
-                                      &(psfi->dwAttributes) );
+        {
+            IShellFolder_GetAttributesOf(psfParent, 1, (LPCITEMIDLIST*)&pidlLast,
+                                         &(psfi->dwAttributes));
+        }
+    }
+
+    if (flags & SHGFI_USEFILEATTRIBUTES)
+    {
+        if (flags & SHGFI_ICON)
+        {
+            psfi->dwAttributes = 0;
+        }
     }
     /* get the displayname */
@@ -516,7 +541,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
         {
             lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath));
         }
-        else
+        else if (psfParent)
         {
             STRRET str;
             hr = IShellFolder_GetDisplayNameOf( psfParent, pidlLast,
@@ -618,7 +643,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
                     ret = FALSE;
             }
         }
-        else
+        else if (psfParent)
         {
             hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1,
                 (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW,
@@ -694,7 +719,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
                 }
             }
         }
-        else
+        else if (psfParent)
         {
             if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
                 uGilFlags, &(psfi->iIcon))))
@@ -769,33 +794,25 @@ DWORD_PTR WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes,
         pathW = temppath;
     }
-    if (psfi && (flags & SHGFI_ATTR_SPECIFIED))
-        temppsfi.dwAttributes=psfi->dwAttributes;
+    if (psfi)
+    {
+        temppsfi.hIcon = psfi->hIcon;
+        temppsfi.iIcon = psfi->iIcon;
+        temppsfi.dwAttributes = psfi->dwAttributes;
-    if (psfi == NULL)
-        ret = SHGetFileInfoW(pathW, dwFileAttributes, NULL, 0, flags);
-    else
         ret = SHGetFileInfoW(pathW, dwFileAttributes, &temppsfi, sizeof(temppsfi),
flags);
+        psfi->hIcon = temppsfi.hIcon;
+        psfi->iIcon = temppsfi.iIcon;
+        psfi->dwAttributes = temppsfi.dwAttributes;
-    if (psfi)
-    {
-        if(flags & SHGFI_ICON)
-            psfi->hIcon=temppsfi.hIcon;
-        if(flags & (SHGFI_SYSICONINDEX|SHGFI_ICON|SHGFI_ICONLOCATION))
-            psfi->iIcon=temppsfi.iIcon;
-        if(flags & SHGFI_ATTRIBUTES)
-            psfi->dwAttributes=temppsfi.dwAttributes;
-        if(flags & (SHGFI_DISPLAYNAME|SHGFI_ICONLOCATION))
-        {
-            WideCharToMultiByte(CP_ACP, 0, temppsfi.szDisplayName, -1,
-                  psfi->szDisplayName, sizeof(psfi->szDisplayName), NULL, NULL);
-        }
-        if(flags & SHGFI_TYPENAME)
-        {
-            WideCharToMultiByte(CP_ACP, 0, temppsfi.szTypeName, -1,
-                  psfi->szTypeName, sizeof(psfi->szTypeName), NULL, NULL);
-        }
+        WideCharToMultiByte(CP_ACP, 0, temppsfi.szDisplayName, -1,
+              psfi->szDisplayName, sizeof(psfi->szDisplayName), NULL, NULL);
+
+        WideCharToMultiByte(CP_ACP, 0, temppsfi.szTypeName, -1,
+              psfi->szTypeName, sizeof(psfi->szTypeName), NULL, NULL);
     }
+    else
+        ret = SHGetFileInfoW(pathW, dwFileAttributes, NULL, 0, flags);
     HeapFree(GetProcessHeap(), 0, temppath);