https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f8926dccbd70aafb399e3ba6e54b8043c5699c45

commit f8926dccbd70aafb399e3ba6e54b8043c5699c45
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Fri Jun 22 22:37:03 2018 +0900
Commit:     Hermès BÉLUSCA - MAÏTO <[email protected]>
CommitDate: Fri Jun 22 15:37:03 2018 +0200

    [SHELL32] Fix desktop.ini folder icon (#595)
    
    The folder icon location specified in desktop.ini of a folder should accept 
its relative path.
    CORE-9196
---
 dll/win32/shell32/folders/CFSFolder.cpp | 136 ++++++++++++++++++++++----------
 1 file changed, 93 insertions(+), 43 deletions(-)

diff --git a/dll/win32/shell32/folders/CFSFolder.cpp 
b/dll/win32/shell32/folders/CFSFolder.cpp
index 15039eac60..6928bf13b5 100644
--- a/dll/win32/shell32/folders/CFSFolder.cpp
+++ b/dll/win32/shell32/folders/CFSFolder.cpp
@@ -129,67 +129,117 @@ HRESULT GetCLSIDForFileType(PCUIDLIST_RELATIVE pidl, 
LPCWSTR KeyName, CLSID* pcl
     return S_OK;
 }
 
-static HRESULT getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST 
pidl, UINT uFlags,
-                                        LPWSTR szIconFile, UINT cchMax, int 
*piIndex, UINT *pwFlags)
+static HRESULT
+getDefaultIconLocation(LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT 
uFlags)
 {
-    static const WCHAR shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 
'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 };
+    static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
+
+    if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, piIndex))
+    {
+        lstrcpynW(szIconFile, swShell32Name, cchMax);
+        *piIndex = -IDI_SHELL_FOLDER;
+    }
+
+    if (uFlags & GIL_OPENICON)
+    {
+        // next icon
+        if (*piIndex < 0)
+            (*piIndex)--;
+        else
+            (*piIndex)++;
+    }
+
+    return S_OK;
+}
+
+static const WCHAR s_shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 
'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 };
+
+static BOOL
+getShellClassInfo(LPCWSTR Entry, LPWSTR pszValue, DWORD cchValueLen, LPCWSTR 
IniFile)
+{
+    return GetPrivateProfileStringW(s_shellClassInfo, Entry, NULL, pszValue, 
cchValueLen, IniFile);
+}
+
+static HRESULT
+getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST pidl, UINT uFlags,
+                         LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT 
*pwFlags)
+{
+    DWORD dwFileAttrs;
+    WCHAR wszPath[MAX_PATH];
+    WCHAR wszIniFullPath[MAX_PATH];
     static const WCHAR iconFile[] = { 'I', 'c', 'o', 'n', 'F', 'i', 'l', 'e', 
0 };
     static const WCHAR clsid[] = { 'C', 'L', 'S', 'I', 'D', 0 };
     static const WCHAR clsid2[] = { 'C', 'L', 'S', 'I', 'D', '2', 0 };
     static const WCHAR iconIndex[] = { 'I', 'c', 'o', 'n', 'I', 'n', 'd', 'e', 
'x', 0 };
+    static const WCHAR iconResource[] = { 'I', 'c', 'o', 'n', 'R', 'e', 's', 
'o', 'u', 'r', 'c', 'e', 0 };
     static const WCHAR wszDesktopIni[] = { 
'd','e','s','k','t','o','p','.','i','n','i',0 };
-    int icon_idx;
 
-    if (!(uFlags & GIL_DEFAULTICON) && 
(_ILGetFileAttributes(ILFindLastID(pidl), NULL, 0) & (FILE_ATTRIBUTE_SYSTEM | 
FILE_ATTRIBUTE_READONLY)) != 0 )
-    {
-        WCHAR wszFolderPath[MAX_PATH];
+    if (uFlags & GIL_DEFAULTICON)
+        goto Quit;
 
-        if (!ILGetDisplayNameExW(psf, pidl, wszFolderPath, 0))
-            return FALSE;
+    // get path
+    SHGetPathFromIDListW(pidl, wszPath);
+    if (!PathIsDirectoryW(wszPath))
+       goto Quit;
 
-        PathAppendW(wszFolderPath, wszDesktopIni);
+    // read-only or system folder?
+    dwFileAttrs = GetFileAttributes(wszPath);
+    if ((dwFileAttrs & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) == 0)
+       goto Quit;
 
-        if (PathFileExistsW(wszFolderPath))
-        {
-            WCHAR wszPath[MAX_PATH];
-            WCHAR wszCLSIDValue[CHARS_IN_GUID];
+    // build the full path of ini file
+    StringCchCopyW(wszIniFullPath, _countof(wszIniFullPath), wszPath);
+    PathAppendW(wszIniFullPath, wszDesktopIni);
 
-            if (GetPrivateProfileStringW(shellClassInfo, iconFile, NULL, 
wszPath, MAX_PATH, wszFolderPath))
-            {
-                ExpandEnvironmentStringsW(wszPath, szIconFile, cchMax);
+    WCHAR wszValue[MAX_PATH], wszTemp[MAX_PATH];
+    if (getShellClassInfo(iconFile, wszValue, _countof(wszValue), 
wszIniFullPath))
+    {
+        // wszValue --> wszTemp
+        ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp));
 
-                *piIndex = GetPrivateProfileIntW(shellClassInfo, iconIndex, 0, 
wszFolderPath);
-                return S_OK;
-            }
-            else if (GetPrivateProfileStringW(shellClassInfo, clsid, NULL, 
wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) &&
-                HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, 
&icon_idx))
-            {
-                *piIndex = icon_idx;
-                return S_OK;
-            }
-            else if (GetPrivateProfileStringW(shellClassInfo, clsid2, NULL, 
wszCLSIDValue, CHARS_IN_GUID, wszFolderPath) &&
-                HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, 
&icon_idx))
-            {
-                *piIndex = icon_idx;
-                return S_OK;
-            }
-        }
-    }
+        // wszPath + wszTemp --> wszPath
+        if (PathIsRelativeW(wszTemp))
+            PathAppendW(wszPath, wszTemp);
+        else
+            StringCchCopyW(wszPath, _countof(wszPath), wszTemp);
 
-    static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
+        // wszPath --> szIconFile
+        GetFullPathNameW(wszPath, cchMax, szIconFile, NULL);
 
-    if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, &icon_idx))
+        *piIndex = GetPrivateProfileIntW(s_shellClassInfo, iconIndex, 0, 
wszIniFullPath);
+        return S_OK;
+    }
+    else if (getShellClassInfo(clsid, wszValue, _countof(wszValue), 
wszIniFullPath) &&
+             HCR_GetIconW(wszValue, szIconFile, NULL, cchMax, piIndex))
     {
-        lstrcpynW(szIconFile, swShell32Name, cchMax);
-        icon_idx = -IDI_SHELL_FOLDER;
+        return S_OK;
     }
+    else if (getShellClassInfo(clsid2, wszValue, _countof(wszValue), 
wszIniFullPath) &&
+             HCR_GetIconW(wszValue, szIconFile, NULL, cchMax, piIndex))
+    {
+        return S_OK;
+    }
+    else if (getShellClassInfo(iconResource, wszValue, _countof(wszValue), 
wszIniFullPath))
+    {
+        // wszValue --> wszTemp
+        ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp));
 
-    if (uFlags & GIL_OPENICON)
-        *piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1;
-    else
-        *piIndex = icon_idx;
+        // parse the icon location
+        *piIndex = PathParseIconLocationW(wszTemp);
 
-    return S_OK;
+        // wszPath + wszTemp --> wszPath
+        if (PathIsRelativeW(wszTemp))
+            PathAppendW(wszPath, wszTemp);
+        else
+            StringCchCopyW(wszPath, _countof(wszPath), wszTemp);
+
+        // wszPath --> szIconFile
+        GetFullPathNameW(wszPath, cchMax, szIconFile, NULL);
+        return S_OK;
+    }
+
+Quit:
+    return getDefaultIconLocation(szIconFile, cchMax, piIndex, uFlags);
 }
 
 HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, 
REFIID iid, LPVOID * ppvOut)

Reply via email to