improve SHGetFileInfo (#118)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Fri, 16 Feb 2018 11:00:08 +0000 (20:00 +0900)
committerGed Murphy <gedmurphy@reactos.org>
Fri, 16 Feb 2018 11:00:08 +0000 (11:00 +0000)
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

index b5638f0..e64ef7f 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 1998 Marcus Meissner
  * Copyright 1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
+ * Copyright 2017 Katayama Hirofumi MZ <katayama.hirofumi.mz@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);