http://bugs.winehq.org/show_bug.cgi?id=14604
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #15 from Anastasius Focht focht@gmx.net 2008-09-07 14:17:57 --- Hello,
that custom loader is something that only works in Win9X or when compatibility mode is enabled in Win2K/XP. Some this FAQ: http://robyrt.coolserver.net/firefight.txt which mentions to enable the app compat mode for Win2K/XP.
When you run executables in compatibility mode, special application shims are loaded at runtime which adjust/fix various win32 API behaviour for brain damaged .. err legacy applications. That mess is something that Wine doesn't want to replicate in it's whole "glory".
That zero thread ID when SetWindowsHookEx() is called is intended (default init) because a system global hook is requested and the code ought to run in Win9X only.
According to MSDN:
http://msdn.microsoft.com/en-us/library/ms644990.aspx
--- quote --- hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread. --- quote ---
The corresponding Wine code:
--- snip dll/user32/hook.c --- static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode ) { ... if (!proc) { SetLastError( ERROR_INVALID_FILTER_PROC ); return 0; }
if (tid) /* thread-local hook */ { if (id == WH_JOURNALRECORD || id == WH_JOURNALPLAYBACK || id == WH_KEYBOARD_LL || id == WH_MOUSE_LL || id == WH_SYSMSGFILTER) { /* these can only be global */ SetLastError( ERROR_INVALID_PARAMETER ); return 0; } } else /* system-global hook */ { if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0; else if (!inst) { SetLastError( ERROR_HOOK_NEEDS_HMOD ); return 0; } } ... --- snip dll/user32/hook.c ---
Write a simple conformance test which calls SetWindowsHookEx(WH_KEYBOARD, ptr, NULL, 0). On Windows XP you should get the error as specified by MSDN. If you run the same test in Win9X or Win9X compat mode of Win2K/XP you should get a valid handle back otherwise the code wouldn't make any sense.
When you look at Wine code you see that a valid module handle is required for retrieving the module filename when a system global hook is requested (tid = 0). The logical choice would be to use the main module handle in place (when passed hMod == NULL). This is probably what happens in Win9X/compat mode.
Regards