http://bugs.winehq.org/show_bug.cgi?id=7380
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #29 from Anastasius Focht focht@gmx.net 2008-01-17 10:35:50 --- Hello,
PowerISO 3.x (nice tool to read/convert .daa image files) has same problem and crashes. There are many applications in the wild which use MFC either dynamically or (worse) statically linked and can't be fixed - so wine needs to be fixed.
As already pointed out by someone, the problem lies in the internal MFC function AfxLoadSysColorBitmap() (utility function of CToolbar class) which doesn't handle toolbar bitmap resources > 256 colors correctly.
The "bits" data pointer which is given as argument to StretchDIBits() gets incorrectly calculated resulting in invalid pointer. Basically it adds bitmap info header offset and size of color table
Pseudo code: ofs = header.biSize + (1 << header.biBitCount)*sizeof(RGBQUAD)
This doesn't work for 24 bit bitmap resources nowadays found in many apps.
When windows encounters such invalid "bits" pointer it doesn't process the data at all and returns 0 lines converted. Obviously wine needs to do the same within the gdi32.StretchDIBits() call.
The invalid pointer value has high bits set, as result from buggy ((1 << 24)*4 + heap_pointer + sizeof(bitmapheader) calculation. Validating the pointer value by looking at address bits doesn't make much sense so put SEH somewhere in code path, like in x11 driver's X11DRV_DIB_SetImageBits() outlined in patch(try3).
If you have a problem with x11 driver stuff wrapped in SEH (= might hide other app bugs) you might consider an alternative solution, aimed at that specific API function itself. It's the only API function called with this buggy data from MFC, so a short "probe" read of "bits" in gdi32.StretchDIBits() to detect buggy MFC might be sufficient.
The advantage of such "short circuit" probe read in StretchDIBits() would be that in case of encountering this bug it doesn't need to go all the way into x11 driver with locks and validating/converting just to end up in page fault when doing x11 bits transfer... and as said, it doesn't hide other app bugs from different API which use might use X11DRV_DIB_SetImageBits too.
Anyway the problem is known and all that is left is some decision where to place the SEH guard.
Regards