#include "precomp.h"
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
WCHAR swShell32Name[MAX_PATH];
DWORD NumIconOverlayHandlers = 0;
IShellIconOverlayIdentifier ** Handlers = NULL;
-static HRESULT getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST pidl, UINT uFlags,
- LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
-{
- static const WCHAR shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 };
- 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 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 (!ILGetDisplayNameExW(psf, pidl, wszFolderPath, 0))
- return FALSE;
-
- PathAppendW(wszFolderPath, wszDesktopIni);
-
- if (PathFileExistsW(wszFolderPath))
- {
- WCHAR wszPath[MAX_PATH];
- WCHAR wszCLSIDValue[CHARS_IN_GUID];
-
- if (GetPrivateProfileStringW(shellClassInfo, iconFile, NULL, wszPath, MAX_PATH, wszFolderPath))
- {
- ExpandEnvironmentStringsW(wszPath, szIconFile, cchMax);
-
- *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;
- }
- }
- }
-
- static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
-
- if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, &icon_idx))
- {
- lstrcpynW(szIconFile, swShell32Name, cchMax);
- icon_idx = -IDI_SHELL_FOLDER;
- }
-
- if (uFlags & GIL_OPENICON)
- *piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1;
- else
- *piIndex = icon_idx;
-
- return S_OK;
-}
-
-void InitIconOverlays(void)
+static void InitIconOverlays(void)
{
HKEY hKey;
DWORD dwIndex, dwResult, dwSize;
if(!SHGetPathFromIDListW(pidl, szPath))
return FALSE;
+ if (!Handlers)
+ InitIconOverlays();
HighestPriority = 101;
IconIndex = NumIconOverlayHandlers;
else
return FALSE;
}
-
-HRESULT GenericExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
-{
- CComPtr<IDefaultExtractIconInit> initIcon;
- GUID const * riid;
- int icon_idx;
- UINT flags;
- CHAR sTemp[MAX_PATH];
- WCHAR wTemp[MAX_PATH];
- LPCITEMIDLIST pSimplePidl = pidl;
- HRESULT hr;
-
- hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
- if (FAILED(hr))
- return hr;
-
- if (_ILIsDesktop(pSimplePidl))
- {
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP);
- }
- else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
- {
- /* my computer and other shell extensions */
- static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\',
- '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-',
- '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x',
- '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0
- };
- WCHAR xriid[50];
-
- swprintf(xriid, fmt,
- riid->Data1, riid->Data2, riid->Data3,
- riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
- riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
-
- const WCHAR* iconname = NULL;
- if (_ILIsBitBucket(pSimplePidl))
- {
- static const WCHAR szFull[] = {'F','u','l','l',0};
- static const WCHAR szEmpty[] = {'E','m','p','t','y',0};
- CComPtr<IEnumIDList> EnumIDList;
- CoInitialize(NULL);
-
- CComPtr<IShellFolder2> psfRecycleBin;
- CComPtr<IShellFolder> psfDesktop;
- hr = SHGetDesktopFolder(&psfDesktop);
-
- if (SUCCEEDED(hr))
- hr = psfDesktop->BindToObject(pSimplePidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin));
- if (SUCCEEDED(hr))
- hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList);
-
- ULONG itemcount;
- LPITEMIDLIST pidl = NULL;
- if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK)
- {
- CoTaskMemFree(pidl);
- iconname = szFull;
- } else {
- iconname = szEmpty;
- }
- }
-
- if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx))
- {
- initIcon->SetNormalIcon(wTemp, icon_idx);
- }
- else
- {
- if (IsEqualGUID(*riid, CLSID_MyComputer))
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER);
- else if (IsEqualGUID(*riid, CLSID_MyDocuments))
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS);
- else if (IsEqualGUID(*riid, CLSID_NetworkPlaces))
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES);
- else
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER);
- }
- }
-
- else if (_ILIsDrive (pSimplePidl))
- {
- static const WCHAR drive[] = { 'D', 'r', 'i', 'v', 'e', 0 };
- int icon_idx = -1;
-
- if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH))
- {
- switch(GetDriveTypeA(sTemp))
- {
- case DRIVE_REMOVABLE:
- icon_idx = IDI_SHELL_3_14_FLOPPY;
- break;
- case DRIVE_CDROM:
- icon_idx = IDI_SHELL_CDROM;
- break;
- case DRIVE_REMOTE:
- icon_idx = IDI_SHELL_NETDRIVE;
- break;
- case DRIVE_RAMDISK:
- icon_idx = IDI_SHELL_RAMDISK;
- break;
- case DRIVE_NO_ROOT_DIR:
- icon_idx = IDI_SHELL_CDROM;
- break;
- }
- }
-
- if (icon_idx != -1)
- {
- initIcon->SetNormalIcon(swShell32Name, -icon_idx);
- }
- else
- {
- if (HCR_GetIconW(drive, wTemp, NULL, MAX_PATH, &icon_idx))
- initIcon->SetNormalIcon(wTemp, icon_idx);
- else
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE);
- }
- }
-
- else if (_ILIsFolder (pSimplePidl))
- {
- if (SUCCEEDED(getIconLocationForFolder(psf,
- pidl, 0, wTemp, MAX_PATH,
- &icon_idx,
- &flags)))
- {
- initIcon->SetNormalIcon(wTemp, icon_idx);
- // FIXME: if/when getIconLocationForFolder does something for
- // GIL_FORSHORTCUT, code below should be uncommented. and
- // the following line removed.
- initIcon->SetShortcutIcon(wTemp, icon_idx);
- }
- if (SUCCEEDED(getIconLocationForFolder(psf,
- pidl, GIL_DEFAULTICON, wTemp, MAX_PATH,
- &icon_idx,
- &flags)))
- {
- initIcon->SetDefaultIcon(wTemp, icon_idx);
- }
- // if (SUCCEEDED(getIconLocationForFolder(psf,
- // pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH,
- // &icon_idx,
- // &flags)))
- // {
- // initIcon->SetShortcutIcon(wTemp, icon_idx);
- // }
- if (SUCCEEDED(getIconLocationForFolder(psf,
- pidl, GIL_OPENICON, wTemp, MAX_PATH,
- &icon_idx,
- &flags)))
- {
- initIcon->SetOpenIcon(wTemp, icon_idx);
- }
- }
- else
- {
- BOOL found = FALSE;
-
- if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
- {
- if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
- && HCR_GetIconA(sTemp, sTemp, NULL, MAX_PATH, &icon_idx))
- {
- if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
- {
- ILGetDisplayNameExW(psf, pidl, wTemp, 0);
- icon_idx = 0;
- }
- else
- {
- MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH);
- }
-
- found = TRUE;
- }
- else if (!lstrcmpiA(sTemp, "lnkfile"))
- {
- /* extract icon from shell shortcut */
- CComPtr<IShellFolder> dsf;
- CComPtr<IShellLinkW> psl;
-
- if (SUCCEEDED(SHGetDesktopFolder(&dsf)))
- {
- HRESULT hr = dsf->GetUIObjectOf(NULL, 1, &pidl, IID_NULL_PPV_ARG(IShellLinkW, &psl));
-
- if (SUCCEEDED(hr))
- {
- hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx);
-
- if (SUCCEEDED(hr) && *sTemp)
- found = TRUE;
-
- }
- }
- }
- }
-
- if (!found)
- /* default icon */
- initIcon->SetNormalIcon(swShell32Name, 0);
- else
- initIcon->SetNormalIcon(wTemp, icon_idx);
- }
-
- return initIcon->QueryInterface(iid, ppvOut);
-}