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);