/***************************************************************************** * SIC_GetIconIndex [internal] * * Parameters * sSourceFile [IN] filename of file containing the icon * index [IN] index/resID (negated) in this file * * NOTES * look in the cache for a proper icon. if not available the icon is taken * from the file and cached */ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) { SIC_ENTRY sice; INT ret, index = INVALID_INDEX; WCHAR path[MAX_PATH]; TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex); GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL); sice.sSourceFile = path; sice.dwSourceIndex = dwSourceIndex; sice.dwFlags = dwFlags; EnterCriticalSection(&SHELL32_SicCS); if (NULL != DPA_GetPtr (sic_hdpa, 0)) { /* search linear from position 0*/ index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, DPAS_SORTED); } if ( INVALID_INDEX == index ) { ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags); } else { TRACE("-- found\n"); ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex; } LeaveCriticalSection(&SHELL32_SicCS); return ret; }
/***************************************************************************** * SIC_GetIconIndex [internal] * * Parameters * sSourceFile [IN] filename of file containing the icon * index [IN] index/resID (negated) in this file * * NOTES * look in the cache for a proper icon. if not available the icon is taken * from the file and cached */ INT SIC_GetIconIndex (LPCSTR sSourceFile, INT dwSourceIndex ) { SIC_ENTRY sice; INT ret, index = INVALID_INDEX; TRACE("%s %i\n", sSourceFile, dwSourceIndex); sice.sSourceFile = PathFindFileNameA(sSourceFile); sice.dwSourceIndex = dwSourceIndex; EnterCriticalSection(&SHELL32_SicCS); if (NULL != pDPA_GetPtr (sic_hdpa, 0)) { /* search linear from position 0*/ index = pDPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0); } if ( INVALID_INDEX == index ) { ret = SIC_LoadIcon (sSourceFile, dwSourceIndex); } else { TRACE("-- found\n"); ret = ((LPSIC_ENTRY)pDPA_GetPtr(sic_hdpa, index))->dwListIndex; } LeaveCriticalSection(&SHELL32_SicCS); return ret; }
/************************************************************************* * PidlToSicIndex [INTERNAL] * * PARAMETERS * sh [IN] IShellFolder * pidl [IN] * bBigIcon [IN] * uFlags [IN] GIL_* * pIndex [OUT] index within the SIC * */ BOOL PidlToSicIndex ( IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) { IExtractIconW *ei; WCHAR szIconFile[MAX_PATH]; /* file containing the icon */ INT iSourceIndex; /* index or resID(negated) in this file */ BOOL ret = FALSE; UINT dwFlags = 0; int iShortcutDefaultIndex = INVALID_INDEX; TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small"); InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei))) { if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags); ret = TRUE; } IExtractIconW_Release(ei); } if (INVALID_INDEX == *pIndex) /* default icon when failed */ { if (0 == (uFlags & GIL_FORSHORTCUT)) { *pIndex = 0; } else { if (INVALID_INDEX == iShortcutDefaultIndex) { iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT); } *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0); } } return ret; }
/***************************************************************************** * SIC_LoadOverlayIcon [internal] * * Load a shell overlay icon and return its icon cache index. */ static int SIC_LoadOverlayIcon(int icon_idx) { WCHAR buffer[1024], wszIdx[8]; HKEY hKeyShellIcons; LPCWSTR iconPath; int iconIdx; static const WCHAR wszShellIcons[] = { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0 }; static const WCHAR wszNumFmt[] = {'%','d',0}; iconPath = swShell32Name; /* default: load icon from shell32.dll */ iconIdx = icon_idx; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS) { DWORD count = sizeof(buffer); sprintfW(wszIdx, wszNumFmt, icon_idx); /* read icon path and index */ if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS) { LPWSTR p = strchrW(buffer, ','); if (!p) { ERR("Icon index in %s/%s corrupted, no comma.\n", debugstr_w(wszShellIcons),debugstr_w(wszIdx)); RegCloseKey(hKeyShellIcons); return -1; } *p++ = 0; iconPath = buffer; iconIdx = atoiW(p); } RegCloseKey(hKeyShellIcons); } InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); return SIC_LoadIcon(iconPath, iconIdx, 0); }
/************************************************************************* * PidlToSicIndex [INTERNAL] * * PARAMETERS * sh [IN] IShellFolder * pidl [IN] * bBigIcon [IN] * uFlags [IN] GIL_* * pIndex [OUT] index within the SIC * */ BOOL PidlToSicIndex ( IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) { CComPtr<IExtractIconW> ei; WCHAR szIconFile[MAX_PATH]; /* file containing the icon */ INT iSourceIndex; /* index or resID(negated) in this file */ BOOL ret = FALSE; UINT dwFlags = 0; int iShortcutDefaultIndex = INVALID_INDEX; TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small"); if (SUCCEEDED (sh->GetUIObjectOf(0, 1, &pidl, IID_NULL_PPV_ARG(IExtractIconW, &ei)))) { if (SUCCEEDED(ei->GetIconLocation(uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags); ret = TRUE; } } if (INVALID_INDEX == *pIndex) /* default icon when failed */ { if (0 == (uFlags & GIL_FORSHORTCUT)) { *pIndex = 0; } else { if (INVALID_INDEX == iShortcutDefaultIndex) { iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT); } *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0); } } return ret; }
/***************************************************************************** * SIC_LoadOverlayIcon [internal] * * Load a shell overlay icon and return its icon cache index. */ static int SIC_LoadOverlayIcon(int icon_idx) { WCHAR buffer[1024], wszIdx[8]; HKEY hKeyShellIcons; LPCWSTR iconPath; int iconIdx; static const WCHAR wszShellIcons[] = { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0 }; static const WCHAR wszNumFmt[] = {'%','d',0}; iconPath = swShell32Name; /* default: load icon from shell32.dll */ iconIdx = icon_idx; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS) { DWORD count = sizeof(buffer); swprintf(wszIdx, wszNumFmt, icon_idx); /* read icon path and index */ if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS) { LPWSTR p = wcschr(buffer, ','); if (p) *p++ = 0; iconPath = buffer; iconIdx = _wtoi(p); } RegCloseKey(hKeyShellIcons); } return SIC_LoadIcon(iconPath, iconIdx, 0); }