http://bugs.winehq.org/show_bug.cgi?id=14604
--- Comment #18 from Nicolas Le Cam niko.lecam@gmail.com 2008-09-07 16:15:01 --- (In reply to comment #15) Thanks Anastasius for explanations. I already know that but I did think it wasn't the right direction to search. I explain here why I was fooled by disassembly, see :
First I saw that. Here is the call to SetWindowsHookExA. 0x0041f5a1: movl 0x00450ed8,%eax 0x0041f5a6: pushl %eax 0x0041f5a7: pushl $0x0 0x0041f5a9: pushl $0x41f510 0x0041f5ae: pushl $0x2 0x0041f5b0: call *0x46eae8 -> 0x7ebbdbe0 SetWindowsHookExA [/home/nlecam/Development/Wine/Sources/wine/dlls/user32/hook.c:477] in user32 0x0041f5b6: movl %eax,0x00452364
tid is retrieved from memory (0x00450ed8).
So I searched for 0x00450ed8 references. I found a first one here : 0x00418a3b: call *0x46e7ec -> 0x7ee8c2e0 GetCurrentThreadId in kernel32 0x00418a41: movl %eax,0x00450ed8
And a second one here : 0x004203e5: movl 0x00450ed8,%eax 0x004203ea: pushl %eax 0x004203eb: pushl $0x0 0x004203ed: pushl $0x4202c0 0x004203f2: pushl $0x7 0x004203f4: call *0x46eae8 -> 0x7ebbdbe0 SetWindowsHookExA [/home/nlecam/Development/Wine/Sources/wine/dlls/user32/hook.c:477] in user32 0x004203fa: movl %eax,0x004526cc
No other references to that global variable. So I thought it shouldn't be possible for tid to be nil. Except for some write bound overrun that was crushing it before it was used. I did search for such write operations on this area. I didn't find anything. So I decided to look at the execution flow just after your comments and here what I have found :
0x004189ee: call 0x0041f590 (Set keyboard hook, use 0x00450ed8 as tid) 0x004189f3: call 0x004203c0 (Set mouse hook, use 0x00450ed8 as tid) 0x004189f8: cmpl $0,0xc(%ebp) 0x004189fc: jz 0x00418a0a 0x004189fe: movl 0x20(%ebp),%eax 0x00418a01: pushl %eax 0x00418a02: call 0x004178b0 0x00418a07: addl $4,%esp 0x00418a0a: call 0x00420930 0x00418a0f: pushl $0x20000 Wine-dbg> 0x00418a14: call 0x004210a0 0x00418a19: addl $4,%esp 0x00418a1c: pushl $0x20000 0x00418a21: call 0x00421510 0x00418a26: addl $4,%esp 0x00418a29: movl $0x0,0x00450ef8 0x00418a33: movl 0x8(%ebp),%eax 0x00418a36: movl %eax,0x00450ee4 0x00418a3b: call *0x46e7ec -> 0x7ee8c2e0 GetCurrentThreadId in kernel32 0x00418a41: movl %eax,0x00450ed8
So this programs calls two times SetWindowsHookExA using a global variable as the tid value. Then set this global variable using GetCurrentThreadId. As you said, "such apps/games deserve to die ;-)".
If a patch seems useful, I can provide one that add win9x compat mode to SetWindowsHookExA. But as Anastasius, I'm not comfortable with win9x compatibility tweaks.