diff --git a/README.md b/README.md index 253bd034..b91c88ba 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Wine-Compholio contains fixes for the following Wine bugs: * ATL IOCS data should not be stored in GWLP_USERDATA ([Wine Bug #21767](http://bugs.winehq.org/show_bug.cgi?id=21767 "JLC's Internet TV crashes on startup")) * Add Dynamic DST exceptions for Israel Standard Time ([Wine Bug #36374](http://bugs.winehq.org/show_bug.cgi?id=36374 "Israel timezone handled incorrectly")) * Add implementation of WTSEnumerateProcessesW ([Wine Bug #29903](http://bugs.winehq.org/show_bug.cgi?id=29903 "Some Microsoft debuggers fail to enumerate processes due to wtsapi32.WTSEnumerateProcessesW() being a stub (Microsoft Visual Studio 2005, DbgCLR from .NET 2.0 SDK)")) +* Add support for extra large and jumbo icon lists in shell32 ([Wine Bug #24721](http://bugs.winehq.org/show_bug.cgi?id=24721 "Explorer++ crashes when choosing to view large icons or extra large icons")) * Allow special characters in pipe names. ([Wine Bug #28995](http://bugs.winehq.org/show_bug.cgi?id=28995 "Unable to use named pipes with \">\" character in the name")) * Create AppData\LocalLow directory inside the profile directory ([Wine Bug #22896](http://bugs.winehq.org/show_bug.cgi?id=22896 "Multiple applications and games need support for shell32 FOLDERID_LocalAppDataLow (.NET based Unity Engine games, Java JRE 6 in Vista mode)")) * Create Saved Games directory inside the profile directory ([Wine Bug #28312](http://bugs.winehq.org/show_bug.cgi?id=28312 "Assassin's Creed Brotherhood v1.03 needs \"Saved Games\" folder")) diff --git a/patches/Makefile b/patches/Makefile index 7c3d376a..99c3aa58 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -28,6 +28,7 @@ PATCHLIST := Miscellaneous.ok \ server-Misc_ACL.ok \ server-Stored_ACLs.ok \ shell32-Default_Folder_ACLs.ok \ + shell32-Icons.ok \ shell32-Register_Folders.ok \ shell32-SHCreateSessionKey.ok \ shlwapi-UrlCombine.ok \ @@ -504,6 +505,24 @@ shell32-Default_Folder_ACLs.ok: echo '+ { "shell32-Default_Folder_ACLs", "Erich E. Hoover", "Generate default ACLs for user shell folders. [rev 6]" },'; \ ) > shell32-Default_Folder_ACLs.ok +# Patchset shell32-Icons +# | +# | Included patches: +# | * Add support for extra large and jumbo icon lists in shell32. [by Michael Müller] +# | +# | This patchset fixes the following Wine bugs: +# | * [#24721] Explorer++ crashes when choosing to view large icons or extra large icons +# | +# | Modified files: +# | * dlls/shell32/iconcache.c, dlls/shell32/shell32_main.h, dlls/shell32/shellord.c +# | +.INTERMEDIATE: shell32-Icons.ok +shell32-Icons.ok: + $(PATCH) < shell32-Icons/0001-shell32-Add-support-for-extra-large-and-jumbo-icon-l.patch + @( \ + echo '+ { "shell32-Icons", "Michael Müller", "Add support for extra large and jumbo icon lists in shell32." },'; \ + ) > shell32-Icons.ok + # Patchset shell32-Register_Folders # | # | Included patches: diff --git a/patches/shell32-Icons/0001-shell32-Add-support-for-extra-large-and-jumbo-icon-l.patch b/patches/shell32-Icons/0001-shell32-Add-support-for-extra-large-and-jumbo-icon-l.patch new file mode 100644 index 00000000..66ba8f12 --- /dev/null +++ b/patches/shell32-Icons/0001-shell32-Add-support-for-extra-large-and-jumbo-icon-l.patch @@ -0,0 +1,364 @@ +From 3db9d42a6ca9547e18ccbcb3b323379e85b206bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 3 Aug 2014 02:23:44 +0200 +Subject: shell32: Add support for extra large and jumbo icon lists. + +--- + dlls/shell32/iconcache.c | 198 +++++++++++++++++++++++++++++--------------- + dlls/shell32/shell32_main.h | 3 + + dlls/shell32/shellord.c | 28 +++++-- + 3 files changed, 153 insertions(+), 76 deletions(-) + +diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c +index b294908..b9fef10 100644 +--- a/dlls/shell32/iconcache.c ++++ b/dlls/shell32/iconcache.c +@@ -62,7 +62,9 @@ typedef struct + static HDPA sic_hdpa; + static INIT_ONCE sic_init_once = INIT_ONCE_STATIC_INIT; + static HIMAGELIST ShellSmallIconList; +-static HIMAGELIST ShellBigIconList; ++static HIMAGELIST ShellLargeIconList; ++static HIMAGELIST ShellExtraLargeIconList; ++static HIMAGELIST ShellJumboIconList; + + static CRITICAL_SECTION SHELL32_SicCS; + static CRITICAL_SECTION_DEBUG critsect_debug = +@@ -109,7 +111,7 @@ static int SIC_LoadOverlayIcon(int icon_idx); + * Creates a new icon as a copy of the passed-in icon, overlayed with a + * shortcut image. + */ +-static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) ++static HICON SIC_OverlayShortcutImage(HICON SourceIcon, int type) + { ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; + HICON ShortcutIcon, TargetIcon; + BITMAP SourceBitmapInfo, ShortcutBitmapInfo; +@@ -139,10 +141,16 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) + + if (s_imgListIdx != -1) + { +- if (large) +- ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT); +- else +- ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); ++ if (type == SHIL_SMALL) ++ ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); ++ else if (type == SHIL_LARGE) ++ ShortcutIcon = ImageList_GetIcon(ShellLargeIconList, s_imgListIdx, ILD_TRANSPARENT); ++ else if (type == SHIL_EXTRALARGE) ++ ShortcutIcon = ImageList_GetIcon(ShellExtraLargeIconList, s_imgListIdx, ILD_TRANSPARENT); ++ else if (type == SHIL_JUMBO) ++ ShortcutIcon = ImageList_GetIcon(ShellJumboIconList, s_imgListIdx, ILD_TRANSPARENT); ++ else ++ ShortcutIcon = NULL; + } else + ShortcutIcon = NULL; + +@@ -258,11 +266,14 @@ fail: + * 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) +-{ LPSIC_ENTRY lpsice; +- INT ret, index, index1; ++static INT SIC_IconAppend(LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, ++ HICON hLargeIcon, HICON hExtraLargeIcon, HICON hJumboIcon, DWORD dwFlags) ++{ ++ LPSIC_ENTRY lpsice; ++ INT ret, index, index1, index2, index3; + WCHAR path[MAX_PATH]; +- TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon); ++ TRACE("%s %i %p %p %p %p %d\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon, ++ hLargeIcon, hExtraLargeIcon, hJumboIcon, dwFlags); + + lpsice = SHAlloc(sizeof(SIC_ENTRY)); + +@@ -284,13 +295,14 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI + } + else + { +- index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon); +- index1= ImageList_AddIcon (ShellBigIconList, hBigIcon); ++ index = ImageList_AddIcon( ShellSmallIconList, hSmallIcon ); ++ index1 = ImageList_AddIcon( ShellLargeIconList, hLargeIcon ); ++ index2 = ImageList_AddIcon( ShellExtraLargeIconList, hExtraLargeIcon ); ++ index3 = ImageList_AddIcon( ShellJumboIconList, hJumboIcon ); ++ ++ if (index != index1 || index != index2 || index != index3) ++ FIXME("iconlists out of sync 0x%x 0x%x 0x%x 0x%x\n", index, index1, index2, index3); + +- if (index!=index1) +- { +- FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1); +- } + lpsice->dwListIndex = index; + ret = lpsice->dwListIndex; + } +@@ -305,15 +317,22 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI + * gets small/big icon by number from a file + */ + static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) +-{ HICON hiconLarge=0; +- HICON hiconSmall=0; +- HICON hiconLargeShortcut; +- HICON hiconSmallShortcut; +- +- PrivateExtractIconsW( sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 0, 1, 0 ); +- PrivateExtractIconsW( sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 0, 1, 0 ); +- +- if ( !hiconLarge || !hiconSmall) ++{ ++ HICON hiconSmall=0; ++ HICON hiconLarge=0; ++ HICON hiconExtraLarge=0; ++ HICON hiconJumbo=0; ++ HICON hiconSmallShortcut; ++ HICON hiconLargeShortcut; ++ HICON hiconExtraLargeShortcut; ++ HICON hiconJumboShortcut; ++ ++ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, 0, 1, 0 ); ++ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, 0, 1, 0 ); ++ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 48, 48, &hiconExtraLarge, 0, 1, 0 ); ++ PrivateExtractIconsW( sSourceFile, dwSourceIndex, 256, 256, &hiconJumbo, 0, 1, 0 ); ++ ++ if ( !hiconSmall || !hiconLarge || !hiconExtraLarge || !hiconJumbo ) + { + WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall); + return -1; +@@ -321,38 +340,59 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) + + if (0 != (dwFlags & GIL_FORSHORTCUT)) + { +- hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE); +- hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE); +- if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) +- { +- hiconLarge = hiconLargeShortcut; +- hiconSmall = hiconSmallShortcut; +- } +- else +- { +- WARN("Failed to create shortcut overlayed icons\n"); +- if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); +- if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); +- dwFlags &= ~ GIL_FORSHORTCUT; +- } ++ hiconSmallShortcut = SIC_OverlayShortcutImage( hiconSmall, SHIL_SMALL ); ++ hiconLargeShortcut = SIC_OverlayShortcutImage( hiconLarge, SHIL_LARGE ); ++ hiconExtraLargeShortcut = SIC_OverlayShortcutImage( hiconExtraLarge, SHIL_EXTRALARGE ); ++ hiconJumboShortcut = SIC_OverlayShortcutImage( hiconJumbo, SHIL_JUMBO ); ++ ++ if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut && ++ NULL != hiconExtraLargeShortcut && NULL != hiconJumboShortcut) ++ { ++ hiconSmall = hiconSmallShortcut; ++ hiconLarge = hiconLargeShortcut; ++ hiconExtraLarge = hiconExtraLargeShortcut; ++ hiconJumbo = hiconJumboShortcut; ++ } ++ else ++ { ++ WARN("Failed to create shortcut overlayed icons\n"); ++ if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); ++ if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); ++ if (NULL != hiconExtraLargeShortcut) DestroyIcon(hiconExtraLargeShortcut); ++ if (NULL != hiconJumboShortcut) DestroyIcon(hiconJumboShortcut); ++ dwFlags &= ~ GIL_FORSHORTCUT; ++ } + } + +- return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags); ++ return SIC_IconAppend( sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, ++ hiconExtraLarge, hiconJumbo, dwFlags ); + } + /***************************************************************************** + * SIC_Initialize [internal] + */ + static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context ) + { +- HICON hSm, hLg; +- int cx_small, cy_small; +- int cx_large, cy_large; ++ HICON hSm, hLg, hELg, hJb; ++ int cx_small, cy_small; ++ int cx_large, cy_large; ++ int cx_extralarge, cy_extralarge; ++ int cx_jumbo, cy_jumbo; + + cx_small = GetSystemMetrics(SM_CXSMICON); + cy_small = GetSystemMetrics(SM_CYSMICON); + cx_large = GetSystemMetrics(SM_CXICON); + cy_large = GetSystemMetrics(SM_CYICON); + ++ /* ++ * TODO: according to ++ * http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx ++ * the size can be configured, but where is the value defined? ++ */ ++ cx_extralarge = 48; ++ cy_extralarge = 48; ++ cx_jumbo = 256; ++ cy_jumbo = 256; ++ + TRACE("\n"); + + sic_hdpa = DPA_Create(16); +@@ -362,28 +402,36 @@ static BOOL WINAPI SIC_Initialize( INIT_ONCE *once, void *param, void **context + return(FALSE); + } + +- ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20); +- ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20); ++ ShellSmallIconList = ImageList_Create( cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20 ); ++ ShellLargeIconList = ImageList_Create( cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20 ); ++ ShellExtraLargeIconList = ImageList_Create( cx_extralarge,cy_extralarge,ILC_COLOR32|ILC_MASK,0,0x20 ); ++ ShellJumboIconList = ImageList_Create( cx_jumbo,cy_jumbo,ILC_COLOR32|ILC_MASK,0,0x20 ); ++ ++ ImageList_SetBkColor( ShellSmallIconList, CLR_NONE ); ++ ImageList_SetBkColor( ShellLargeIconList, CLR_NONE ); ++ ImageList_SetBkColor( ShellExtraLargeIconList, CLR_NONE ); ++ ImageList_SetBkColor( ShellJumboIconList, CLR_NONE ); ++ ++ /* Load the document icon, which is used as the default if an icon isn't found. */ ++ hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), ++ IMAGE_ICON, cx_small, cy_small, LR_SHARED); ++ hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), ++ IMAGE_ICON, cx_large, cy_large, LR_SHARED); ++ hELg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), ++ IMAGE_ICON, cx_extralarge, cy_extralarge, LR_SHARED); ++ hJb = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), ++ IMAGE_ICON, cx_jumbo, cy_jumbo, LR_SHARED); ++ if (!hSm || !hLg || !hELg || !hJb) ++ { ++ FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); ++ return FALSE; ++ } + +- ImageList_SetBkColor(ShellSmallIconList, CLR_NONE); +- ImageList_SetBkColor(ShellBigIconList, CLR_NONE); ++ SIC_IconAppend( swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, hELg, hJb, 0 ); ++ SIC_IconAppend( swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, hELg, hJb, 0 ); + +- /* Load the document icon, which is used as the default if an icon isn't found. */ +- hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), +- IMAGE_ICON, cx_small, cy_small, LR_SHARED); +- hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), +- IMAGE_ICON, cx_large, cy_large, LR_SHARED); +- +- if (!hSm || !hLg) +- { +- FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); +- return FALSE; +- } +- +- SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); +- SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); +- +- TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); ++ TRACE("hIconSmall=%p hIconLarge=%p hExtraLargeIcon=%p hJumboIcon=%p\n", ++ ShellSmallIconList, ShellLargeIconList, ShellExtraLargeIconList, ShellJumboIconList); + + return TRUE; + } +@@ -407,10 +455,14 @@ void SIC_Destroy(void) + + if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL ); + +- if (ShellSmallIconList) +- ImageList_Destroy(ShellSmallIconList); +- if (ShellBigIconList) +- ImageList_Destroy(ShellBigIconList); ++ if (ShellSmallIconList) ++ ImageList_Destroy( ShellSmallIconList ); ++ if (ShellLargeIconList) ++ ImageList_Destroy( ShellLargeIconList ); ++ if (ShellExtraLargeIconList) ++ ImageList_Destroy( ShellExtraLargeIconList ); ++ if (ShellJumboIconList) ++ ImageList_Destroy( ShellJumboIconList ); + + LeaveCriticalSection(&SHELL32_SicCS); + DeleteCriticalSection(&SHELL32_SicCS); +@@ -527,10 +579,20 @@ BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList + { + TRACE("(%p,%p)\n",lpBigList,lpSmallList); + InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); +- if (lpBigList) *lpBigList = ShellBigIconList; ++ if (lpBigList) *lpBigList = ShellLargeIconList; + if (lpSmallList) *lpSmallList = ShellSmallIconList; + return TRUE; + } ++ ++void SHELL_GetInternalImageLists(HIMAGELIST *lpSmallList, HIMAGELIST *lpLargeList, ++ HIMAGELIST *lpExtraLargeList, HIMAGELIST *lpJumboList) ++{ ++ if (lpSmallList) *lpSmallList = ShellSmallIconList; ++ if (lpLargeList) *lpLargeList = ShellLargeIconList; ++ if (lpExtraLargeList) *lpExtraLargeList = ShellExtraLargeIconList; ++ if (lpJumboList) *lpJumboList = ShellJumboIconList; ++} ++ + /************************************************************************* + * PidlToSicIndex [INTERNAL] + * +diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h +index 954f1e4..e1e77f1 100644 +--- a/dlls/shell32/shell32_main.h ++++ b/dlls/shell32/shell32_main.h +@@ -232,4 +232,7 @@ BOOL CreateFolderEnumList(IEnumIDListImpl *list, LPCWSTR lpszPath, DWORD dwFlags + void release_typelib(void) DECLSPEC_HIDDEN; + void release_desktop_folder(void) DECLSPEC_HIDDEN; + ++void SHELL_GetInternalImageLists(HIMAGELIST *lpSmallList, HIMAGELIST *lpLargeList, ++ HIMAGELIST *lpExtraLargeList, HIMAGELIST *lpJumboList) DECLSPEC_HIDDEN; ++ + #endif +diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c +index 56c9fe9..e4d4f48 100644 +--- a/dlls/shell32/shellord.c ++++ b/dlls/shell32/shellord.c +@@ -2182,20 +2182,32 @@ void WINAPI SHFlushSFCache(void) + */ + HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv) + { +- HIMAGELIST hLarge, hSmall; ++ HIMAGELIST hSmall, hLarge, hExtraLarge, hJumbo; + HIMAGELIST hNew; + HRESULT ret = E_FAIL; + +- /* Wine currently only maintains large and small image lists */ +- if ((iImageList != SHIL_LARGE) && (iImageList != SHIL_SMALL) && (iImageList != SHIL_SYSSMALL)) ++ SHELL_GetInternalImageLists( &hSmall, &hLarge, &hExtraLarge, &hJumbo ); ++ ++ switch (iImageList) + { +- FIXME("Unsupported image list %i requested\n", iImageList); +- return E_FAIL; ++ case SHIL_SMALL: ++ case SHIL_SYSSMALL: ++ hNew = ImageList_Duplicate( hSmall ); ++ break; ++ case SHIL_LARGE: ++ hNew = ImageList_Duplicate( hLarge ); ++ break; ++ case SHIL_EXTRALARGE: ++ hNew = ImageList_Duplicate( hExtraLarge ); ++ break; ++ case SHIL_JUMBO: ++ hNew = ImageList_Duplicate( hJumbo ); ++ break; ++ default: ++ FIXME("Unsupported image list %i requested\n", iImageList); ++ return E_FAIL; + } + +- Shell_GetImageLists(&hLarge, &hSmall); +- hNew = ImageList_Duplicate(iImageList == SHIL_LARGE ? hLarge : hSmall); +- + /* Get the interface for the new image list */ + if (hNew) + { +-- +1.8.3.2 + diff --git a/patches/shell32-Icons/definition b/patches/shell32-Icons/definition new file mode 100644 index 00000000..b7e2452b --- /dev/null +++ b/patches/shell32-Icons/definition @@ -0,0 +1,4 @@ +Author: Michael Müller +Subject: Add support for extra large and jumbo icon lists in shell32. +Revision: 1 +Fixes: [24721] Add support for extra large and jumbo icon lists in shell32