[Bug 22764] Garmin chart plotter updater crashes on start (DM_GETDEFID handling, property sheet dialog box)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Dec 13 11:23:29 CST 2011


Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
                 CC|                            |focht at gmx.net
          Component|-unknown                    |user32
            Summary|Garmin chart plotter        |Garmin chart plotter
                   |updater crashes on start    |updater crashes on start
                   |                            |(DM_GETDEFID handling,
                   |                            |property sheet dialog box)

--- Comment #6 from Anastasius Focht <focht at gmx.net> 2011-12-13 11:23:29 CST ---

still present.

The binary to reproduce is double-packed.
Extract "program_card.exe" from "ChartplottersUpdatewithSDcard_20111111.exe".
Extract "Copy2Card.exe" from "program_card.exe".

After extraction the installer runs "Copy2Card.exe UpdateInfo.xml"
Running "Copy2Card.exe" without arguments is sufficient to reproduce the bug.

The app creates a wizard-like dialog (property sheet dialog box) with a
property sheet page and some button controls at bottom (Cancel, Help, Next,
Finish, Back).

Window/control hierarchy for better overview:

--- snip ---
Handle        Text        Parent   ID/menu    Style    ClsName
0005010E      Marine Pr.. Topmost             94CA00C4 #32770 (dialog box)
|00050112                 0005010E (000003EF) 40000007 Static
\0006004E     Copy2Card   0005010E            50020044 #32770 (dialog box)
 |00030132                0006004E (00003027) 40021000 Static
 |00040106    Cancel      0006004E (00000002) 50010001 Button
 |00040116    Help        0006004E (00000009) 48030000 Button
 |00050026                0006004E (00003020) 4C000000 SysTabControl32
 |00050108    &Next >     0006004E (00003024) 50010000 Button
 |00050114    Finish      0006004E (00003025) 48010000 Button
 |00050120                0006004E (00003026) 50021000 Static
 |00050126    < &Back     0006004E (00003023) 50010000 Button
 \0006011E    Copy2Card   0006004E            50010444 #32770 (dialog box)
  \0004002A   This wizard 0006011E (00000404) 50020000 Static
--- snip ---

Window/control creation sequence follows...

NOTE: handles from window hierarchy don't match with handles in trace snippets
due to different methods used (just resolve/substitute with IDs from traces).

The interesting one is the "Next" button (id=0x3024) which gets the focus and
default button id.
You can see the dialog showing up with one button control having focus for a
split second before the app exits (use +heap to slow it down).

--- snip ---
0023:Call comctl32.PropertySheetW(00db2330) ret=0042c00a
0023:Call user32.GetDlgItem(00010088,00003020) ret=68849cab
0023:Ret  user32.GetDlgItem() retval=00010096 ret=68849cab
0023:Call user32.SetPropW(00010088,6889f140 L"PropertySheetInfo",0014a070)
0023:Ret  user32.SetPropW() retval=00000001 ret=68849ccd
0023:Call user32.SetWindowLongW(00010088,00000008,0014a070) ret=68849cf2
0023:Ret  user32.SetWindowLongW() retval=00000000 ret=68849cf2
0023:Call user32.GetPropW(00010088,6889f140 L"PropertySheetInfo") ret=68846fde
0023:Ret  user32.GetPropW() retval=0014a070 ret=68846fde
0023:Call user32.GetDlgItem(00010088,00003023) ret=68846ff7
0023:Ret  user32.GetDlgItem() retval=0001008a ret=68846ff7
0023:Call user32.GetDlgItem(00010088,00003024) ret=68847010
0023:Ret  user32.GetDlgItem() retval=0001008c ret=68847010
0023:Call user32.GetDlgItem(00010088,00003025) ret=68847029
0023:Ret  user32.GetDlgItem() retval=0001008e ret=68847029
0023:Call user32.EnableWindow(0001008a,00000000) ret=68847092 
0023:Call user32.GetDlgItem(00010088,00003024) ret=68849f0a
0023:Ret  user32.GetDlgItem() retval=0001008c ret=68849f0a
0023:Call user32.SetFocus(0001008c) ret=68849f15 
0023:Ret  user32.SetFocus() retval=00000000 ret=68849f15
0023:Ret  user32.CreateDialogIndirectParamW() retval=0001009a ret=68844750
0023:Ret  user32.CreateDialogIndirectParamW() retval=00010088 ret=6884295b
0023:Ret  comctl32.PropertySheetW() retval=00010088 ret=0042c00a
0023:Ret  user32.CreateDialogIndirectParamW() retval=0001007c ret=00426719
--- snip ---

The problem:

--- snip ---
0023:Call user32.SendMessageW(00010088,00000476,00000000,00000000) ret=0042c0ce
0023:Call window proc 0x42feee
0023:Call user32.CallWindowProcW(6862eb83,00010088,00000476,00000000,00000000)
0023:Call window proc 0x6862eb83
0023:Call dialog proc 0x688499c0
0023:Call user32.GetPropW(00010088,6889f140 L"PropertySheetInfo") ret=6884a2ad
0023:Ret  user32.GetPropW() retval=0014a070 ret=6884a2ad
0023:Call user32.SetWindowLongW(00010088,00000000,0001009a) ret=6884a31d
0023:Ret  user32.SetWindowLongW() retval=00000000 ret=6884a31d
0023:Ret  dialog proc 0x688499c0
retval=00000001 result=0001009a
0023:Ret  window proc 0x6862eb83
0023:Ret  user32.CallWindowProcW() retval=0001009a ret=0042d457
0023:Ret  window proc 0x42feee
0023:Ret  user32.SendMessageW() retval=0001009a ret=0042c0ce
0023:Call user32.GetParent(0001009a) ret=00425fde
0023:Ret  user32.GetParent() retval=00010088 ret=00425fde
0023:Call user32.GetDlgItem(0001009a,00000001) ret=00425cec
0023:Ret  user32.GetDlgItem() retval=00000000 ret=00425cec
0023:Call user32.GetDlgItem(00010088,00000001) ret=00425cec
0023:Ret  user32.GetDlgItem() retval=00000000 ret=00425cec
<internal exception, minidump, exit>
--- snip ---

The app code calling GetDlgItem( hwnd, 1) is obviously wrong, resulting in exit
(NULL hwnd is returned).
It seems the control id passed to GetDlgItem() is stored in some class instance
member data of C++ class hierarchy.

The following sequence shows the retrieval of the wrong control id which gets
stored for later use:

--- snip ---
0024:Call user32.SendMessageW(0001009a,00000400,00000000,00000000) ret=00422efd
0024:Call window proc 0x42feee
0024:Call user32.CallWindowProcW(6841fb83,0001009a,00000400,00000000,00000000)
0024:Call window proc 0x6841fb83
0024:trace:win:WIN_SetWindowLong 0x1009a 0 0 W
0024:Call dialog proc 0x426007
0024:Ret  dialog proc 0x426007
(hwnd=0x1009a,msg=WM_USER,wp=00000000,lp=00000000) retval=00000000
0024:Ret  window proc 0x6841fb83
(hwnd=0x1009a,msg=WM_USER,wp=00000000,lp=00000000) retval=534b0001
0024:Ret  user32.CallWindowProcW() retval=534b0001 ret=0042d457
0024:Ret  window proc 0x42feee
(hwnd=0x1009a,msg=WM_USER,wp=00000000,lp=00000000) retval=534b0001
0024:Ret  user32.SendMessageW() retval=534b0001 ret=00422efd
--- snip ---


SendMessage(0001009a, DM_GETDEFID) resulting loWORD -> 0x0001

The sheet page (hwnd=0001009a -> 0006011E in Window/control hierarchy snippet)
is on the same level as the buttons and part of the property sheet dialog box

DM_SETDEFID for "Next" button was sent earlier on the parent property sheet

--- snip ---
0024:Call user32.SendMessageW(00010088,00000401,00003024,00000000) ret=7a0dc137
0024:Call window proc 0x42feee
0024:Call user32.GetDlgItem(00010088,00003024) ret=0042b8fe
0024:Ret  user32.GetDlgItem() retval=0001008c ret=0042b8fe
--- snip ---

Wine code resulting in current behaviour:


--- snip ---
 266         case DM_GETDEFID:
 267             if (dlgInfo && !(dlgInfo->flags & DF_END))
 268             {
 269                 HWND hwndDefId;
 270                 if (dlgInfo->idResult)
 271                     return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
 272                 if ((hwndDefId = DEFDLG_FindDefButton( hwnd )))
 273                     return MAKELONG( GetDlgCtrlID( hwndDefId ),
 274             }
 275             return 0;
--- snip ---

I changed the code to retrieve the dialog info (-> idResult) from the parent
(the property sheet dialog) and it helped the app to display the wizard dialog

$ sha1sum ChartplottersUpdatewithSDcard_20111111.exe 

$ wine --version


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