[PATCH v2 0/1] MR10036: winemac.drv: Attempt to correct the size of icon resources.
It seems that some apps have different sizes in the GRPICONDIR and the IMAGE_RESOURCE_DATA_ENTRY. winemenubuilder has had the same workaround since 2014 - see c205e6800a63a5df9960d8484a2e67687d53bc50. --- The size difference is great enough in some situations (e.g. Brotato) that the attempt read the resource may fault. The original mailing list discussion about the winemenubuilder patch is [here](https://marc.info/?l=wine-patches&m=140903555724711&w=2). Huge thanks to @bshanks for spotting that patch. This has apparently always been faulting for some apps, but only became an issue after !10032. The subsequent syscall fault unwinds out of the pthread_once that !10032 added, so future threads that wind up there will hang. -- v2: winemac.drv: Attempt to correct the size of icon resources. https://gitlab.winehq.org/wine/wine/-/merge_requests/10036
From: Tim Clem <tclem@codeweavers.com> It seems that some apps have different sizes in the GRPICONDIR and the IMAGE_RESOURCE_DATA_ENTRY. winemenubuilder has had the same workaround since 2014 - see c205e6800a63a5df9960d8484a2e67687d53bc50. --- dlls/winemac.drv/dllmain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dlls/winemac.drv/dllmain.c b/dlls/winemac.drv/dllmain.c index 7ece4dc99a3..ffef945aace 100644 --- a/dlls/winemac.drv/dllmain.c +++ b/dlls/winemac.drv/dllmain.c @@ -290,6 +290,7 @@ static NTSTATUS WINAPI macdrv_app_icon(void *arg, ULONG size) LPCWSTR name; HGLOBAL icon_res_data; BYTE *icon_bits; + DWORD actual_size; if (!width) width = 256; if (!height) height = 256; @@ -324,6 +325,9 @@ static NTSTATUS WINAPI macdrv_app_icon(void *arg, ULONG size) continue; } + /* Some apps have inaccurate sizes in the GRPICONDIR. */ + actual_size = min(icon_dir->idEntries[i].dwBytesInRes, SizeofResource(NULL, res_info)); + icon_res_data = LoadResource(NULL, res_info); if (!icon_res_data) { @@ -338,7 +342,7 @@ static NTSTATUS WINAPI macdrv_app_icon(void *arg, ULONG size) entry->width = width; entry->height = height; - entry->size = icon_dir->idEntries[i].dwBytesInRes; + entry->size = actual_size; if (!memcmp(icon_bits, png_magic, sizeof(png_magic))) { @@ -348,7 +352,7 @@ static NTSTATUS WINAPI macdrv_app_icon(void *arg, ULONG size) } else { - HICON icon = CreateIconFromResourceEx(icon_bits, icon_dir->idEntries[i].dwBytesInRes, + HICON icon = CreateIconFromResourceEx(icon_bits, actual_size, TRUE, 0x00030000, width, height, 0); if (icon) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10036
On Thu Feb 5 20:53:31 2026 +0000, Tim Clem wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/10036/diffs?diff_id=242401&start_sha=91d2c22689fcb5ca1999272940e7ed7532ba3fb1#be8b5f4a9db563a69a7a00b5ab48dfe1acb10bef_329_329) Oh yah, totally. Thanks!
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128901
This has apparently always been faulting for some apps, but only became an issue after !10032 (merged). The subsequent syscall fault unwinds out of the pthread_once that !10032 (merged) added, so future threads that wind up there will hang.
This can't happen, it's a fault in PE code which will be handled be KiUserCallbackDispatcher. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128903
On Thu Feb 5 20:56:58 2026 +0000, Alexandre Julliard wrote:
This has apparently always been faulting for some apps, but only became an issue after !10032 (merged). The subsequent syscall fault unwinds out of the pthread_once that !10032 (merged) added, so future threads that wind up there will hang. This can't happen, it's a fault in PE code which will be handled be KiUserCallbackDispatcher. It's not in PE code though, the fault is in winemac.drv when it tries to make a CFDataRef for the resource.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128904
On Thu Feb 5 21:01:20 2026 +0000, Tim Clem wrote:
~~It's not in PE code though, the fault is in winemac.drv when it tries to make a CFDataRef for the resource.~~ Oh ugh, ignore me. Hm. Well one way or another that pthread_once gets stranded... Is that because we are passing the PNG bits through? I'm not sure why we do this, CreateIconFromResourceEx should be able to handle PNGs.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128905
On Thu Feb 5 21:03:25 2026 +0000, Alexandre Julliard wrote:
Is that because we are passing the PNG bits through? I'm not sure why we do this, CreateIconFromResourceEx should be able to handle PNGs. Yes, for PNGs we pass the bits back to Unix for processing. Perhaps we do that because we ultimately need a CGImageRef, and we can skip the roundtripping from an HICON (create_cgimage_from_icon) if we know it's a png?
But yes, it does look like we could skip that and use CreateIconFromResourceEx universally. But even if we used CreateIconFromResourceEx, we'd still fault, just in PE rather than Unix, unless we correct the size. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128906
On Thu Feb 5 21:12:40 2026 +0000, Tim Clem wrote:
Yes, for PNGs we pass the bits back to Unix for processing. Perhaps we do that because we ultimately need a CGImageRef, and we can skip the roundtripping from an HICON (create_cgimage_from_icon) if we know it's a png? But yes, it does look like we could skip that and use CreateIconFromResourceEx universally. But even if we used CreateIconFromResourceEx, we'd still fault, just in PE rather than Unix, unless we correct the size. I don't expect CreateIconFromResourceEx to copy the entire resource, so hopefully it won't fault.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128907
On Thu Feb 5 21:16:09 2026 +0000, Alexandre Julliard wrote:
I don't expect CreateIconFromResourceEx to copy the entire resource, so hopefully it won't fault. Ok, I'll give that a shot.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128908
On Thu Feb 5 21:16:44 2026 +0000, Tim Clem wrote:
Ok, I'll give that a shot. If we use `CreateIconFromResourceEx()`, doesn't that mean that Wine decompresses the PNG, then we have to draw it into a CGImage? These are typically Vista icons, so 256x256 or larger. `create_cgimage_from_icon()` and `create_cgimage_from_icon_bitmaps()` are also not simple functions.
It seems preferable to just give the PNG to macOS when that's possible. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10036#note_128909
participants (4)
-
Alexandre Julliard (@julliard) -
Brendan Shanks (@bshanks) -
Tim Clem -
Tim Clem (@tclem)