[SHELL32] Enable custom CD/DVD icons (#639)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Wed, 27 Jun 2018 21:06:54 +0000 (06:06 +0900)
committerHermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
Wed, 27 Jun 2018 21:06:54 +0000 (23:06 +0200)
Properly show the custom icon specified in "autorun.inf" file in CDs/DVDs.
CORE-14766

dll/win32/shell32/folders/CDrivesFolder.cpp

index a4c09b1..77f6420 100644 (file)
@@ -4,7 +4,7 @@
  *    Copyright 1997                Marcus Meissner
  *    Copyright 1998, 1999, 2002    Juergen Schmied
  *    Copyright 2009                Andrew Hill
- *    Copyright 2017                Katayama Hirofumi MZ
+ *    Copyright 2017-2018           Katayama Hirofumi MZ
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -297,6 +297,51 @@ HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
     return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
 }
 
+static HRESULT
+getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags,
+                        LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
+{
+    WCHAR wszPath[MAX_PATH];
+    WCHAR wszAutoRunInfPath[MAX_PATH];
+    WCHAR wszValue[MAX_PATH], wszTemp[MAX_PATH];
+    static const WCHAR wszAutoRunInf[] = { 'a','u','t','o','r','u','n','.','i','n','f',0 };
+    static const WCHAR wszAutoRun[] = { 'a','u','t','o','r','u','n',0 };
+
+    // get path
+    if (!ILGetDisplayNameExW(psf, pidl, wszPath, 0))
+        return E_FAIL;
+    if (!PathIsDirectoryW(wszPath))
+        return E_FAIL;
+
+    // build the full path of autorun.inf
+    StringCchCopyW(wszAutoRunInfPath, _countof(wszAutoRunInfPath), wszPath);
+    PathAppendW(wszAutoRunInfPath, wszAutoRunInf);
+
+    // autorun.inf --> wszValue
+    if (GetPrivateProfileStringW(wszAutoRun, L"icon", NULL, wszValue, _countof(wszValue),
+                                 wszAutoRunInfPath) && wszValue[0] != 0)
+    {
+        // wszValue --> wszTemp
+        ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp));
+
+        // parse the icon location
+        *piIndex = PathParseIconLocationW(wszTemp);
+
+        // 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;
+    }
+
+    return E_FAIL;
+}
+
 HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
 {
     CComPtr<IDefaultExtractIconInit> initIcon;
@@ -311,11 +356,17 @@ HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl
 
     WCHAR wTemp[MAX_PATH];
     int icon_idx;
+    UINT flags = 0;
     if ((DriveType == DRIVE_FIXED || DriveType == DRIVE_UNKNOWN) &&
         (HCR_GetIconW(L"Drive", wTemp, NULL, MAX_PATH, &icon_idx)))
     {
         initIcon->SetNormalIcon(wTemp, icon_idx);
     }
+    else if (SUCCEEDED(getIconLocationForDrive(psf, pidl, 0, wTemp, _countof(wTemp),
+                                               &icon_idx, &flags)))
+    {
+        initIcon->SetNormalIcon(wTemp, icon_idx);
+    }
     else
     {
         icon_idx = iDriveIconIds[DriveType];