[Bug 30266] New: Cygnus Fractal eXtreme crashes after trial dialog (expects gdi32 GetDIBits() returning number of scan lines when bits parameter is NULL)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Mar 25 11:34:05 CDT 2012


http://bugs.winehq.org/show_bug.cgi?id=30266

             Bug #: 30266
           Summary: Cygnus Fractal eXtreme crashes after trial dialog
                    (expects gdi32 GetDIBits() returning number of scan
                    lines when bits parameter is NULL)
           Product: Wine
           Version: 1.5.0
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdi32
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: focht at gmx.net
    Classification: Unclassified


Hello,

I sometimes peek into Winehq forum to look for interesting bugs :-)

http://forum.winehq.org/viewtopic.php?t=15117 (no answer)

--- quote ---
i cannot seem to get this app to run properly in wine.

Bruce, who is the programmer of it, told me he would be happy to make whatever
changes are necessary to make it work with wine, so if it's something on his
end, could somebody on the team reach out to him and help him get it going?

his website is:

http://cygnus-software.com/

I love fractals, and want to take full advantage of my i7 on my imac and would
really love to use his software but i absolutely will not go running windows to
do so...
--- quote ---

Download: ftp://ftp.cygnus-software.com/pub/fxsetup.msi

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/Cygnus Software/Fractal eXtreme 32-bit

$ WINEDEBUG=+tid,+seh,+relay,+snoop,+bitmap wine ./FractalX.exe >> log.txt 2>&1
--- snip ---

Trace log reveals:

--- snip ---
...
0024:Call KERNEL32.CreateFileA(0032d3b8 "C:\\Program Files\\Cygnus
Software\\Fractal eXtreme
32-bit\\Plugins\\Mandelbrot.dll",80000000,00000001,00000000,00000003,00000080,00000000)
ret=0044ebc4
0024:Ret  KERNEL32.CreateFileA() retval=000001c8 ret=0044ebc4
0024:Call KERNEL32.CreateFileA(0032cfd0 "C:\\users\\focht\\My
Documents\\Fractal
eXtreme\\plugin_stamps\\Mandelbrot_Mandelbrot.bmp",80000000,00000001,00000000,00000003,00000080,00000000)
ret=0044ebde
0024:Ret  KERNEL32.CreateFileA() retval=ffffffff ret=0044ebde
0024:Call KERNEL32.CloseHandle(000001c8) ret=0044ec2c
0024:Ret  KERNEL32.CloseHandle() retval=00000001 ret=0044ec2c
0024:CALL MSVCR100.memset() ret=004529bd
0024:RET  MSVCR100.memset() retval=00557be0 ret=004529bd
0024:Call gdi32.CreateDCA(004b80f8 "Display",00000000,00000000,00000000)
ret=00452a23
0024:Ret  gdi32.CreateDCA() retval=0000119c ret=00452a23
0024:Call
gdi32.CreateDIBSection(0000119c,00557be0,00000000,00557bd0,00000000,00000000)
ret=00452a45
0024:trace:bitmap:CreateDIBSection format (110,110), planes 1, bpp 8, BI_RGB,
size 12320 RGB
0024:Ret  gdi32.CreateDIBSection() retval=000011a0 ret=00452a45
0024:Call gdi32.CreateCompatibleDC(0000119c) ret=00452a59
0024:Ret  gdi32.CreateCompatibleDC() retval=000011a4 ret=00452a59
0024:Call gdi32.SelectObject(000011a4,000011a0) ret=00452a6b
0024:Ret  gdi32.SelectObject() retval=0000006c ret=00452a6b
0024:Call gdi32.DeleteDC(0000119c) ret=00452a75
0024:Ret  gdi32.DeleteDC() retval=00000001 ret=00452a75
0024:CALL Mandelbrot.CalcPointFloat(00000000,0032cf88) ret=0040449a
0024:RET  Mandelbrot.CalcPointFloat() retval=00000000 ret=0040449a 
...
0024:CALL MSVCR100.fopen_s(<unknown, check return>) ret=0044f90a 
...
0024:Call KERNEL32.CreateFileA(0032cfd0 "C:\\users\\focht\\My
Documents\\Fractal
eXtreme\\plugin_stamps\\Mandelbrot_Mandelbrot.bmp",40000000,00000000,0032cdb4,00000002,00000080,00000000)
ret=78b27359
0024:Ret  KERNEL32.CreateFileA() retval=000001c8 ret=78b27359 
...
0024:RET  MSVCR100.fopen_s() retval=00000000 ret=0044f90a
0024:Call gdi32.SetDIBColorTable(000011a4,00000000,00000100,00557c08)
ret=00452c83
0024:Ret  gdi32.SetDIBColorTable() retval=00000100 ret=00452c83
0024:CALL MSVCR100.fwrite(0032ced0,00000001,0000000e,78b53068) ret=00448091
0024:Call ntdll.RtlAllocateHeap(00547000,00000000,00001000) ret=78ab0269
0024:Ret  ntdll.RtlAllocateHeap() retval=00558020 ret=78ab0269
0024:RET  MSVCR100.fwrite() retval=0000000e ret=00448091
0024:Call
gdi32.GetDIBits(000011a4,000011a0,00000000,0000006e,00000000,0032caa4,00000000)
ret=0044f6b6
0024:Ret  gdi32.GetDIBits() retval=00000001 ret=0044f6b6
0024:CALL MSVCR100.fwrite(0032caa4,00000001,00000028,78b53068) ret=00448091
0024:RET  MSVCR100.fwrite() retval=00000028 ret=00448091
0024:Call gdi32.SetDIBColorTable(000011a4,00000000,00000100,00557c08)
ret=00452c83
0024:Ret  gdi32.SetDIBColorTable() retval=00000100 ret=00452c83
0024:CALL MSVCR100.fwrite(00557c08,00000001,00000400,78b53068) ret=00448091
0024:RET  MSVCR100.fwrite() retval=00000400 ret=00448091
0024:CALL MSVCR100.fwrite(00000000,00000001,00003020,78b53068) ret=00448091
0024:Call KERNEL32.GetLastError() ret=78ab0706
0024:Ret  KERNEL32.GetLastError() retval=00000000 ret=78ab0706
0024:Call ntdll.RtlDecodePointer(fdf9bfb0) ret=78b2af62
0024:Ret  ntdll.RtlDecodePointer() retval=00000000 ret=78b2af62
0024:Call KERNEL32.IsDebuggerPresent() ret=78b2aee6
0024:Ret  KERNEL32.IsDebuggerPresent() retval=00000000 ret=78b2aee6
0024:Call KERNEL32.SetUnhandledExceptionFilter(00000000) ret=78b2aef0
0024:Ret  KERNEL32.SetUnhandledExceptionFilter() retval=004a62b6 ret=78b2aef0
0024:Call KERNEL32.UnhandledExceptionFilter(0032c690) ret=78b2aefd
wine: Unhandled exception 0xc0000417 at address 0x320023:0x78b2af3e (thread
0024), starting debugger... 
--- snip ---

The second fwrite() has a NULL ptr which causes the page fault.

Relevant app code leading to failure, annotated:

--- snip ---
...
0044F6B0  FF15 88C04A00    CALL DWORD PTR DS:[<&GDI32.GetDIBits>]
0044F6B6  8B7E 08          MOV EDI,DWORD PTR DS:[ESI+8] ;
bmi.bmiHeader.biHeight
0044F6B9  3BC7             CMP EAX,EDI
0044F6BB  75 4C            JNE SHORT 0044F709
0044F6BD  8B85 D0FBFFFF    MOV EAX,DWORD PTR SS:[LOCAL.268] ;
bmi.bmiHeader.biSizeImage
0044F6C3  85C0             TEST EAX,EAX
0044F6C5  74 42            JE SHORT 0044F709
0044F6C7  50               PUSH EAX
0044F6C8  FF15 48C44A00    CALL DWORD PTR DS:[<&MSVCR100.malloc>
0044F6CE  83C4 04          ADD ESP,4
0044F6D1  8985 B0FBFFFF    MOV DWORD PTR SS:[LOCAL.276],EAX
0044F6D7  85C0             TEST EAX,EAX
0044F6D9  74 2E            JE SHORT 0044F709
...
--- snip ---

The problem seems to be that the app expects GetDIBits() to return the number
of scan lines (comparison of return value against bmi.bmiHeader.biHeight).

MSDN: http://msdn.microsoft.com/en-us/library/dd144879%28v=vs.85%29.aspx

--- quote ---
int GetDIBits(
  __in     HDC hdc,
  __in     HBITMAP hbmp,
  __in     UINT uStartScan,
  __in     UINT cScanLines,
  __out    LPVOID lpvBits,
  __inout  LPBITMAPINFO lpbi,
  __in     UINT uUsage
);

...
Return value

If the lpvBits parameter is non-NULL and the function succeeds, the return
value is the number of scan lines copied from the bitmap.

If the lpvBits parameter is NULL and GetDIBits successfully fills the
BITMAPINFO structure, the return value is nonzero.

If the function fails, the return value is zero.

This function can return the following value.
--- quote ---

"return value is nonzero" Ah how precise. Roll a dice?

Digging further it seems Microsoft dropped the Win9x part of API documentation.
Some websites carry the "old" API documentation that states:

--- quote ---
If the lpvBits parameter is non-NULL and the function succeeds, the return
value is the number of scan lines copied from the bitmap.

Windows 95:

If the lpvBits parameter is NULL and GetDIBits successfully fills the
BITMAPINFO structure, the return value is the total number of scan lines in the
bitmap.

Windows NT:

If the lpvBits parameter is NULL and GetDIBits successfully fills the
BITMAPINFO structure, the return value is non-zero.

If the function fails, the return value is zero. 
--- quote ---

Source:
http://source.winehq.org/git/wine.git/blob/71ea68b65727a7abac8f179035fe895f8b641a37:/dlls/gdi32/dib.c#l1380

--- snip ---
1187 INT WINAPI GetDIBits(
1188     HDC hdc,         /* [in]  Handle to device context */
1189     HBITMAP hbitmap, /* [in]  Handle to bitmap */
1190     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
1191     UINT lines,      /* [in]  Number of scan lines to copy */
1192     LPVOID bits,       /* [out] Address of array for bitmap bits */
1193     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
1194     UINT coloruse)   /* [in]  RGB or palette index */
1195 {
...
1380     if (bits)
1381     {
1382         if(dst_info->bmiHeader.biHeight > 0)
1383             dst_info->bmiHeader.biHeight = src.height;
1384         else
1385             dst_info->bmiHeader.biHeight = -src.height;
1386 
1387         convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits,
FALSE );
1388         if (src_bits.free) src_bits.free( &src_bits );
1389         ret = lines;
1390     }
1391     else
1392         ret = empty_rect ? FALSE : TRUE;
1393 
1394     if (coloruse == DIB_PAL_COLORS)
1395     {
1396         WORD *index = (WORD *)dst_info->bmiColors;
1397         for (i = 0; i < dst_info->bmiHeader.biClrUsed; i++, index++)
1398             *index = i;
1399     }
1400 
1401     copy_color_info( info, dst_info, coloruse );
1402     if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
info->bmiHeader.biClrUsed = 0;
1403 
1404 done:
1405     release_dc_ptr( dc );
1406     GDI_ReleaseObj( hbitmap );
1407     return ret;
1408 }
--- snip ---

For testing I changed the code for line 1392 to also return the number of scan
lines in case of "NULL" bits parameter.
It lets the app successfully render/save fractals and the crash is gone.

$ du -sh fxsetup.msi 
6.0M    fxsetup.msi

$ sha1sum fxsetup.msi 
44a9ff9779596205f25d6d00051f594a4cc599b0  fxsetup.msi

$ wine --version
wine-1.5.0

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list