Hello,
I've been following the wine-devel lists for some time now, but I
never found time to actually work on something... until now. I am
trying to get civilization 2 to work (with some succes). I chose that
game for some reasons (I like the game and the error looks easy, a bit
like the tutorials).
I made the following trace:
0013:Call user32.GetWindowLongA(00170034,0000000a) ret=005d2a16
0013:Ret user32.GetWindowLongA() retval=00000000 ret=005d2a16
0013:Call user32.GetClassLongA(00170034,ffffffee) ret=005d2a25
0013:Ret user32.GetClassLongA() retval=0000000c ret=005d2a25
0013:Call user32.GetWindowLongA(00170034,00000004) ret=005d2a39
0013:Ret user32.GetWindowLongA() retval=778bfd70 ret=005d2a39
0013:trace:seh:__regs_RtlRaiseException code=c0000005 flags=0 addr=0x40f81f
0013:trace:seh:__regs_RtlRaiseException info[0]=00000000
0013:trace:seh:__regs_RtlRaiseException info[1]=00000008
0013:trace:seh:__regs_RtlRaiseException eax=00000000 ebx=7793cd94 ecx=00000000
edx=7794dfe4 esi=00170034 edi=000c0054
It shows a call to GetWindowLongA with nIndex = 10, which is not
valid, and so it returns NULL. After this the program generates a
STATUS_ACCESS_VIOLATION, and hangs.
After searching trough win.c I found the following comment:
/*
* Some programs try to access last element from 16 bit
* code using illegal offset value. Hopefully this is
* what those programs really expect.
*/
changing the if statement that follows according to the following
patch made civilization 2 work, although the performance is really
bad. I tried making a test for this, to check if this behaviour is the
same on windows, but I'm unable to make a test that will run. I don't
know h ow to make the cbWndExtra and wExtra fields in the WND struct
into something usefull, so it will not segfault. Mayby it is possible
to leave them empty, but I don't know how, if I leave them empty every
test with nIndex > 0 failes.
I hope this is somewhat usefull.
Krist
Index: dlls/user/win.c
===================================================================
RCS file: /home/wine/wine/dlls/user/win.c,v
retrieving revision 1.6
diff -u -p -r1.6 win.c
--- dlls/user/win.c 7 Jun 2005 20:11:17 -0000 1.6
+++ dlls/user/win.c 13 Jun 2005 19:08:25 -0000
@@ -1863,8 +1863,7 @@ static LONG_PTR WIN_GetWindowLong( HWND
* code using illegal offset value. Hopefully this is
* what those programs really expect.
*/
- if (type == WIN_PROC_16 &&
- wndPtr->cbWndExtra >= 4 &&
+ if (wndPtr->cbWndExtra >= 4 &&
offset == wndPtr->cbWndExtra - sizeof(WORD))
{
INT offset2 = wndPtr->cbWndExtra - sizeof(LONG);