#include "precomp.h"
-WINE_DEFAULT_DEBUG_CHANNEL(shell);
-
WCHAR swShell32Name[MAX_PATH];
DWORD NumIconOverlayHandlers = 0;
IShellIconOverlayIdentifier ** Handlers = NULL;
-static HRESULT getIconLocationForFolder(LPCITEMIDLIST pidl, UINT uFlags,
+static HRESULT getIconLocationForFolder(IShellFolder * psf, LPCITEMIDLIST pidl, UINT uFlags,
LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
{
- int icon_idx;
- WCHAR wszPath[MAX_PATH];
- WCHAR wszCLSIDValue[CHARS_IN_GUID];
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 (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconFile,
- wszPath, MAX_PATH))
- {
- WCHAR wszIconIndex[10];
- SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconIndex,
- wszIconIndex, 10);
- *piIndex = _wtoi(wszIconIndex);
- }
- else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid,
- wszCLSIDValue, CHARS_IN_GUID) &&
- HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
+ if (!(uFlags & GIL_DEFAULTICON) && (_ILGetFileAttributes(ILFindLastID(pidl), NULL, 0) & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY)) != 0 )
{
- *piIndex = icon_idx;
- }
- else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid2,
- wszCLSIDValue, CHARS_IN_GUID) &&
- HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
- {
- *piIndex = icon_idx;
- }
- else
- {
- static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
+ WCHAR wszFolderPath[MAX_PATH];
+
+ if (!ILGetDisplayNameExW(psf, pidl, wszFolderPath, 0))
+ return FALSE;
- if (!HCR_GetDefaultIconW(folder, szIconFile, cchMax, &icon_idx))
+ PathAppendW(wszFolderPath, wszDesktopIni);
+
+ if (PathFileExistsW(wszFolderPath))
{
- lstrcpynW(szIconFile, swShell32Name, cchMax);
- icon_idx = -IDI_SHELL_FOLDER;
+ 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;
+ }
}
+ }
- if (uFlags & GIL_OPENICON)
- *piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1;
- else
- *piIndex = icon_idx;
+ 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;
WCHAR szName[MAX_PATH];
WCHAR szValue[100];
CLSID clsid;
- IShellIconOverlayIdentifier * Overlay;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
return;
dwSize = sizeof(szValue) / sizeof(WCHAR);
if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szValue, &dwSize) == ERROR_SUCCESS)
{
+ CComPtr<IShellIconOverlayIdentifier> Overlay;
CLSIDFromString(szValue, &clsid);
- dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&Overlay);
+ dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellIconOverlayIdentifier, &Overlay));
if (dwResult == S_OK)
{
- Handlers[NumIconOverlayHandlers] = Overlay;
+ Handlers[NumIconOverlayHandlers] = Overlay.Detach();
NumIconOverlayHandlers++;
}
}
if(!SHGetPathFromIDListW(pidl, szPath))
return FALSE;
+ if (!Handlers)
+ InitIconOverlays();
HighestPriority = 101;
IconIndex = NumIconOverlayHandlers;
return FALSE;
}
-/**************************************************************************
-* IExtractIconW_Constructor
-*/
-IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
+HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
{
- CComPtr<IDefaultExtractIconInit> initIcon;
- IExtractIconW *extractIcon;
- GUID const * riid;
- int icon_idx;
- UINT flags;
- CHAR sTemp[MAX_PATH];
- WCHAR wTemp[MAX_PATH];
- LPITEMIDLIST pSimplePidl = ILFindLastID(pidl);
+ CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr;
+ int icon_idx = 0;
+ UINT flags = 0; // FIXME: Use it!
+ CHAR sTemp[MAX_PATH] = "";
+ WCHAR wTemp[MAX_PATH] = L"";
- hr = SHCreateDefaultExtractIcon(IID_IDefaultExtractIconInit, (void **)&initIcon);
+ hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
if (FAILED(hr))
- return NULL;
-
- hr = initIcon->QueryInterface(IID_IExtractIconW, (void **)&extractIcon);
- if (FAILED(hr))
- return NULL;
-
- 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]);
-
- if (HCR_GetDefaultIconW(xriid, wTemp, 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_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_GetDefaultIconW(drive, wTemp, MAX_PATH, &icon_idx))
- initIcon->SetNormalIcon(wTemp, icon_idx);
- else
- initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE);
- }
- }
+ return hr;
- else if (_ILIsFolder (pSimplePidl))
+ if (_ILIsFolder (pidl))
{
- if (SUCCEEDED(getIconLocationForFolder(
- pidl, 0, wTemp, MAX_PATH,
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, 0, wTemp, _countof(wTemp),
&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(
- pidl, GIL_DEFAULTICON, wTemp, MAX_PATH,
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, GIL_DEFAULTICON, wTemp, _countof(wTemp),
&icon_idx,
&flags)))
{
initIcon->SetDefaultIcon(wTemp, icon_idx);
}
- if (SUCCEEDED(getIconLocationForFolder(
- pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH,
- &icon_idx,
- &flags)))
- {
- initIcon->SetShortcutIcon(wTemp, icon_idx);
- }
- if (SUCCEEDED(getIconLocationForFolder(
- pidl, GIL_OPENICON, wTemp, MAX_PATH,
+ // if (SUCCEEDED(getIconLocationForFolder(psf,
+ // pidl, GIL_FORSHORTCUT, wTemp, _countof(wTemp),
+ // &icon_idx,
+ // &flags)))
+ // {
+ // initIcon->SetShortcutIcon(wTemp, icon_idx);
+ // }
+ if (SUCCEEDED(getIconLocationForFolder(psf,
+ pidl, GIL_OPENICON, wTemp, _countof(wTemp),
&icon_idx,
&flags)))
{
{
BOOL found = FALSE;
- if (_ILIsCPanelStruct(pSimplePidl))
- {
- if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx)))
- found = TRUE;
- }
- else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
+ if (_ILGetExtension(pidl, sTemp, _countof(sTemp)))
{
- if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
- && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &icon_idx))
+ if (HCR_MapTypeToValueA(sTemp, sTemp, _countof(sTemp), TRUE)
+ && HCR_GetIconA(sTemp, sTemp, NULL, _countof(sTemp), &icon_idx))
{
if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
{
- SHGetPathFromIDListW(pidl, wTemp);
+ ILGetDisplayNameExW(psf, pidl, wTemp, 0);
icon_idx = 0;
}
else
{
- MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, _countof(wTemp));
}
found = TRUE;
else if (!lstrcmpiA(sTemp, "lnkfile"))
{
/* extract icon from shell shortcut */
- CComPtr<IShellFolder> dsf;
- CComPtr<IShellLinkW> psl;
+ CComPtr<IShellLinkW> psl;
- if (SUCCEEDED(SHGetDesktopFolder(&dsf)))
+ HRESULT hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_NULL_PPV_ARG(IShellLinkW, &psl));
+ if (SUCCEEDED(hr))
{
- HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IShellLinkW, NULL, (LPVOID *)&psl);
+ hr = psl->GetIconLocation(wTemp, _countof(wTemp), &icon_idx);
- if (SUCCEEDED(hr))
- {
- hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx);
-
- if (SUCCEEDED(hr) && *sTemp)
- found = TRUE;
-
- }
+ if (SUCCEEDED(hr) && *wTemp)
+ found = TRUE;
}
}
}
+ /* FIXME: We should normally use the correct icon format according to 'flags' */
if (!found)
/* default icon */
initIcon->SetNormalIcon(swShell32Name, 0);
initIcon->SetNormalIcon(wTemp, icon_idx);
}
- return extractIcon;
-}
-
-/**************************************************************************
-* IExtractIconA_Constructor
-*/
-IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl)
-{
- IExtractIconW *extractIconW;
- IExtractIconA *extractIconA;
- HRESULT hr;
-
- extractIconW = IExtractIconW_Constructor(pidl);
- if (!extractIconW)
- return NULL;
-
- hr = extractIconW->QueryInterface(IID_IExtractIconA, (void **)&extractIconA);
- extractIconW->Release();
- if (FAILED(hr))
- return NULL;
- return extractIconA;
+ return initIcon->QueryInterface(iid, ppvOut);
}