Alexandre Julliard : shell32: Delay initialization of the icon cache until needed.
Alexandre Julliard
julliard at winehq.org
Thu Oct 17 13:51:50 CDT 2013
Module: wine
Branch: master
Commit: 116e33d50a3435a539bcf7e9b93ab4adbfbecef9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=116e33d50a3435a539bcf7e9b93ab4adbfbecef9
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Oct 17 18:01:04 2013 +0200
shell32: Delay initialization of the icon cache until needed.
---
dlls/shell32/iconcache.c | 123 +++++++++++++++++++++----------------------
dlls/shell32/shell32_main.c | 2 -
dlls/shell32/shell32_main.h | 1 -
3 files changed, 61 insertions(+), 65 deletions(-)
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c
index e2300f1..a2373fa 100644
--- a/dlls/shell32/iconcache.c
+++ b/dlls/shell32/iconcache.c
@@ -59,7 +59,8 @@ typedef struct
DWORD dwAccessTime;
} SIC_ENTRY, * LPSIC_ENTRY;
-static HDPA sic_hdpa = 0;
+static HDPA sic_hdpa;
+static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT;
static CRITICAL_SECTION SHELL32_SicCS;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -337,54 +338,9 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
}
/*****************************************************************************
- * 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, 0);
- }
-
- 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_Initialize [internal]
*/
-BOOL SIC_Initialize(void)
+static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context )
{
HICON hSm, hLg;
int cx_small, cy_small;
@@ -397,9 +353,6 @@ BOOL SIC_Initialize(void)
TRACE("\n");
- if (sic_hdpa) /* already initialized?*/
- return TRUE;
-
sic_hdpa = DPA_Create(16);
if (!sic_hdpa)
@@ -452,17 +405,62 @@ void SIC_Destroy(void)
if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
- sic_hdpa = NULL;
ImageList_Destroy(ShellSmallIconList);
- ShellSmallIconList = 0;
ImageList_Destroy(ShellBigIconList);
- ShellBigIconList = 0;
LeaveCriticalSection(&SHELL32_SicCS);
DeleteCriticalSection(&SHELL32_SicCS);
}
/*****************************************************************************
+ * 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;
+
+ InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
+
+ 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, 0);
+ }
+
+ 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_LoadOverlayIcon [internal]
*
* Load a shell overlay icon and return its icon cache index.
@@ -509,6 +507,8 @@ static int SIC_LoadOverlayIcon(int icon_idx)
RegCloseKey(hKeyShellIcons);
}
+ InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
+
return SIC_LoadIcon(iconPath, iconIdx, 0);
}
@@ -520,15 +520,12 @@ static int SIC_LoadOverlayIcon(int icon_idx)
*
*/
BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
-{ TRACE("(%p,%p)\n",lpBigList,lpSmallList);
- if (lpBigList)
- { *lpBigList = ShellBigIconList;
- }
- if (lpSmallList)
- { *lpSmallList = ShellSmallIconList;
- }
-
- return TRUE;
+{
+ TRACE("(%p,%p)\n",lpBigList,lpSmallList);
+ InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL );
+ if (lpBigList) *lpBigList = ShellBigIconList;
+ if (lpSmallList) *lpSmallList = ShellSmallIconList;
+ return TRUE;
}
/*************************************************************************
* PidlToSicIndex [INTERNAL]
@@ -557,6 +554,8 @@ BOOL PidlToSicIndex (
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)))
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 4c124bd..0bc88b0 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -1273,8 +1273,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
swShell32Name[MAX_PATH - 1] = '\0';
InitCommonControlsEx(NULL);
-
- SIC_Initialize();
InitChangeNotifications();
break;
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index c50330b..ee10756 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -47,7 +47,6 @@ extern HIMAGELIST ShellBigIconList DECLSPEC_HIDDEN;
/* Iconcache */
#define INVALID_INDEX -1
-BOOL SIC_Initialize(void) DECLSPEC_HIDDEN;
void SIC_Destroy(void) DECLSPEC_HIDDEN;
BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) DECLSPEC_HIDDEN;
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags ) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list