Index: reactos/dll/win32/shell32/iconcache.cpp =================================================================== --- reactos/dll/win32/shell32/iconcache.cpp (revision 73623) +++ reactos/dll/win32/shell32/iconcache.cpp (working copy) @@ -323,7 +323,7 @@ * NOTES * appends an icon pair to the end of the cache */ -static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags) +static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags, HDPA sic) { LPSIC_ENTRY lpsice; INT ret, index, index1, indexDPA; @@ -341,8 +341,8 @@ EnterCriticalSection(&SHELL32_SicCS); - indexDPA = DPA_Search (sic_hdpa, lpsice, 0, SIC_CompareEntries, 0, DPAS_SORTED|DPAS_INSERTAFTER); - indexDPA = DPA_InsertPtr(sic_hdpa, indexDPA, lpsice); + indexDPA = DPA_Search (sic, lpsice, 0, SIC_CompareEntries, 0, DPAS_SORTED|DPAS_INSERTAFTER); + indexDPA = DPA_InsertPtr(sic, indexDPA, lpsice); if ( -1 == indexDPA ) { ret = INVALID_INDEX; @@ -374,7 +374,7 @@ leave: if(ret == INVALID_INDEX) { - if(indexDPA != -1) DPA_DeletePtr(sic_hdpa, indexDPA); + if(indexDPA != -1) DPA_DeletePtr(sic, indexDPA); HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile); SHFree(lpsice); } @@ -424,7 +424,7 @@ } } - ret = SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags); + ret = SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags, sic_hdpa); DestroyIcon(hiconLarge); DestroyIcon(hiconSmall); return ret; @@ -490,6 +490,7 @@ INT bpp; DWORD ilMask; BOOL result = FALSE; + HDPA priv_sic_hdpa; TRACE("Entered SIC_Initialize\n"); @@ -499,9 +500,18 @@ return TRUE; } - sic_hdpa = DPA_Create(16); - if (!sic_hdpa) + EnterCriticalSection(&SHELL32_SicCS); + if (sic_hdpa) { + TRACE("Icon cache already initialized (another thread got it)\n"); + LeaveCriticalSection(&SHELL32_SicCS); + return TRUE; + } + + priv_sic_hdpa = DPA_Create(16); + if (!priv_sic_hdpa) + { + LeaveCriticalSection(&SHELL32_SicCS); return FALSE; } @@ -556,7 +566,7 @@ ERR("Failed to create the big icon list.\n"); goto end; } - + /* Load the document icon, which is used as the default if an icon isn't found. */ hSm = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), @@ -582,20 +592,20 @@ goto end; } - if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0) == INVALID_INDEX) + if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0, priv_sic_hdpa) == INVALID_INDEX) { ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n"); goto end; } - if(SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0) == INVALID_INDEX) + if(SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0, priv_sic_hdpa) == INVALID_INDEX) { ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n"); goto end; } - + /* Everything went fine */ result = TRUE; - + end: /* The image list keeps a copy of the icons, we must destroy them */ if(hSm) DestroyIcon(hSm); @@ -604,14 +614,17 @@ /* Clean everything if something went wrong */ if(!result) { - if(sic_hdpa) DPA_Destroy(sic_hdpa); + if(priv_sic_hdpa) DPA_Destroy(priv_sic_hdpa); if(ShellSmallIconList) ImageList_Destroy(ShellSmallIconList); if(ShellBigIconList) ImageList_Destroy(ShellSmallIconList); - sic_hdpa = NULL; + priv_sic_hdpa = NULL; ShellSmallIconList = NULL; ShellBigIconList = NULL; } + sic_hdpa = priv_sic_hdpa; + LeaveCriticalSection(&SHELL32_SicCS); + TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); return result;