Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Windows 16-bit hook functions |
| 3 | * |
| 4 | * Copyright 1994, 1995, 2002 Alexandre Julliard |
| 5 | * Copyright 1996 Andrew Lewycky |
| 6 | * |
| 7 | * Based on investigations by Alex Korobka |
| 8 | * |
| 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Lesser General Public |
| 11 | * License as published by the Free Software Foundation; either |
| 12 | * version 2.1 of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This library is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * Lesser General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU Lesser General Public |
| 20 | * License along with this library; if not, write to the Free Software |
Jonathan Ernst | 360a3f9 | 2006-05-18 14:49:52 +0200 | [diff] [blame] | 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 22 | */ |
| 23 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 24 | #include <stdarg.h> |
| 25 | |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 26 | #include "windef.h" |
| 27 | #include "winbase.h" |
| 28 | #include "winuser.h" |
| 29 | #include "wownt32.h" |
| 30 | #include "wine/winuser16.h" |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 31 | #include "win.h" |
Alexandre Julliard | 6a78c16 | 2004-12-08 18:06:14 +0000 | [diff] [blame] | 32 | #include "user_private.h" |
Alexandre Julliard | 18d0297 | 2002-12-03 23:34:52 +0000 | [diff] [blame] | 33 | #include "winproc.h" |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 34 | #include "wine/debug.h" |
| 35 | |
| 36 | WINE_DEFAULT_DEBUG_CHANNEL(hook); |
| 37 | |
| 38 | |
| 39 | static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp ); |
| 40 | static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp ); |
| 41 | static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp ); |
| 42 | static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp ); |
| 43 | static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp ); |
| 44 | static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp ); |
| 45 | static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp ); |
| 46 | |
| 47 | #define WH_MAXHOOK16 WH_SHELL /* Win16 only supports up to WH_SHELL */ |
| 48 | #define NB_HOOKS16 (WH_MAXHOOK16 - WH_MINHOOK + 1) |
| 49 | |
| 50 | static const HOOKPROC hook_procs[NB_HOOKS16] = |
| 51 | { |
| 52 | call_WH_MSGFILTER, /* WH_MSGFILTER */ |
| 53 | NULL, /* WH_JOURNALRECORD */ |
| 54 | NULL, /* WH_JOURNALPLAYBACK */ |
| 55 | call_WH_KEYBOARD, /* WH_KEYBOARD */ |
| 56 | call_WH_GETMESSAGE, /* WH_GETMESSAGE */ |
| 57 | call_WH_CALLWNDPROC, /* WH_CALLWNDPROC */ |
| 58 | call_WH_CBT, /* WH_CBT */ |
| 59 | NULL, /* WH_SYSMSGFILTER */ |
| 60 | call_WH_MOUSE, /* WH_MOUSE */ |
| 61 | NULL, /* WH_HARDWARE */ |
| 62 | NULL, /* WH_DEBUG */ |
| 63 | call_WH_SHELL /* WH_SHELL */ |
| 64 | }; |
| 65 | |
| 66 | |
| 67 | /* this structure is stored in the thread queue */ |
| 68 | struct hook16_queue_info |
| 69 | { |
| 70 | INT id; /* id of current hook */ |
| 71 | HHOOK hook[NB_HOOKS16]; /* Win32 hook handles */ |
| 72 | HOOKPROC16 proc[NB_HOOKS16]; /* 16-bit hook procedures */ |
| 73 | }; |
| 74 | |
| 75 | |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 76 | |
| 77 | /*********************************************************************** |
| 78 | * map_msg_16_to_32 |
| 79 | */ |
Andrew Talbot | 48d7408 | 2007-03-17 10:34:08 +0000 | [diff] [blame] | 80 | static inline void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 ) |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 81 | { |
| 82 | msg32->hwnd = WIN_Handle32(msg16->hwnd); |
| 83 | msg32->message = msg16->message; |
| 84 | msg32->wParam = msg16->wParam; |
| 85 | msg32->lParam = msg16->lParam; |
| 86 | msg32->time = msg16->time; |
| 87 | msg32->pt.x = msg16->pt.x; |
| 88 | msg32->pt.y = msg16->pt.y; |
| 89 | } |
| 90 | |
| 91 | |
| 92 | /*********************************************************************** |
| 93 | * map_msg_32_to_16 |
| 94 | */ |
Andrew Talbot | 48d7408 | 2007-03-17 10:34:08 +0000 | [diff] [blame] | 95 | static inline void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 ) |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 96 | { |
| 97 | msg16->hwnd = HWND_16(msg32->hwnd); |
| 98 | msg16->message = msg32->message; |
| 99 | msg16->wParam = msg32->wParam; |
| 100 | msg16->lParam = msg32->lParam; |
| 101 | msg16->time = msg32->time; |
| 102 | msg16->pt.x = msg32->pt.x; |
| 103 | msg16->pt.y = msg32->pt.y; |
| 104 | } |
| 105 | |
| 106 | |
| 107 | /*********************************************************************** |
| 108 | * call_hook_16 |
| 109 | */ |
| 110 | static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp ) |
| 111 | { |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 112 | struct hook16_queue_info *info = get_user_thread_info()->hook16_info; |
Alexandre Julliard | 7e92c9a | 2003-02-27 21:09:45 +0000 | [diff] [blame] | 113 | WORD args[4]; |
Mike McCormack | c787b14 | 2005-07-06 10:36:28 +0000 | [diff] [blame] | 114 | DWORD ret; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 115 | INT prev_id = info->id; |
| 116 | info->id = id; |
Alexandre Julliard | 7e92c9a | 2003-02-27 21:09:45 +0000 | [diff] [blame] | 117 | |
| 118 | args[3] = code; |
| 119 | args[2] = wp; |
| 120 | args[1] = HIWORD(lp); |
| 121 | args[0] = LOWORD(lp); |
| 122 | WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret ); |
| 123 | |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 124 | info->id = prev_id; |
| 125 | |
| 126 | /* Grrr. While the hook procedure is supposed to have an LRESULT return |
| 127 | value even in Win16, it seems that for those hook types where the |
| 128 | return value is interpreted as BOOL, Windows doesn't actually check |
| 129 | the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on |
| 130 | that, because they neglect to clear DX ... */ |
| 131 | if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret ); |
| 132 | return ret; |
| 133 | } |
| 134 | |
| 135 | |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 136 | struct wndproc_hook_params |
| 137 | { |
| 138 | HHOOK hhook; |
| 139 | INT code; |
| 140 | WPARAM wparam; |
| 141 | }; |
| 142 | |
| 143 | /* callback for WINPROC_Call16To32A */ |
| 144 | static LRESULT wndproc_hook_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, |
| 145 | LRESULT *result, void *arg ) |
| 146 | { |
| 147 | struct wndproc_hook_params *params = arg; |
| 148 | CWPSTRUCT cwp; |
| 149 | |
| 150 | cwp.hwnd = hwnd; |
| 151 | cwp.message = msg; |
| 152 | cwp.wParam = wp; |
| 153 | cwp.lParam = lp; |
| 154 | *result = 0; |
| 155 | return CallNextHookEx( params->hhook, params->code, params->wparam, (LPARAM)&cwp ); |
| 156 | } |
| 157 | |
| 158 | /* callback for WINPROC_Call32ATo16 */ |
| 159 | static LRESULT wndproc_hook_callback16( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp, |
| 160 | LRESULT *result, void *arg ) |
| 161 | { |
| 162 | struct wndproc_hook_params *params = arg; |
| 163 | CWPSTRUCT16 cwp; |
| 164 | LRESULT ret; |
| 165 | |
| 166 | cwp.hwnd = hwnd; |
| 167 | cwp.message = msg; |
| 168 | cwp.wParam = wp; |
| 169 | cwp.lParam = lp; |
| 170 | |
| 171 | lp = MapLS( &cwp ); |
| 172 | ret = call_hook_16( WH_CALLWNDPROC, params->code, params->wparam, lp ); |
| 173 | UnMapLS( lp ); |
| 174 | |
| 175 | *result = 0; |
| 176 | return ret; |
| 177 | } |
| 178 | |
| 179 | |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 180 | /*********************************************************************** |
| 181 | * call_WH_MSGFILTER |
| 182 | */ |
| 183 | static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp ) |
| 184 | { |
| 185 | MSG *msg32 = (MSG *)lp; |
| 186 | MSG16 msg16; |
| 187 | LRESULT ret; |
| 188 | |
| 189 | map_msg_32_to_16( msg32, &msg16 ); |
| 190 | lp = MapLS( &msg16 ); |
| 191 | ret = call_hook_16( WH_MSGFILTER, code, wp, lp ); |
| 192 | UnMapLS( lp ); |
| 193 | return ret; |
| 194 | } |
| 195 | |
| 196 | |
| 197 | /*********************************************************************** |
| 198 | * call_WH_KEYBOARD |
| 199 | */ |
| 200 | static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp ) |
| 201 | { |
| 202 | return call_hook_16( WH_KEYBOARD, code, wp, lp ); |
| 203 | } |
| 204 | |
| 205 | |
| 206 | /*********************************************************************** |
| 207 | * call_WH_GETMESSAGE |
| 208 | */ |
| 209 | static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp ) |
| 210 | { |
| 211 | MSG *msg32 = (MSG *)lp; |
| 212 | MSG16 msg16; |
| 213 | LRESULT ret; |
| 214 | |
| 215 | map_msg_32_to_16( msg32, &msg16 ); |
| 216 | |
| 217 | lp = MapLS( &msg16 ); |
| 218 | ret = call_hook_16( WH_GETMESSAGE, code, wp, lp ); |
| 219 | UnMapLS( lp ); |
| 220 | |
| 221 | map_msg_16_to_32( &msg16, msg32 ); |
| 222 | return ret; |
| 223 | } |
| 224 | |
| 225 | |
| 226 | /*********************************************************************** |
| 227 | * call_WH_CALLWNDPROC |
| 228 | */ |
| 229 | static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp ) |
| 230 | { |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 231 | struct wndproc_hook_params params; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 232 | CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp; |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 233 | LRESULT result; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 234 | |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 235 | params.code = code; |
| 236 | params.wparam = wp; |
| 237 | return WINPROC_CallProc32ATo16( wndproc_hook_callback16, cwp32->hwnd, cwp32->message, |
| 238 | cwp32->wParam, cwp32->lParam, &result, ¶ms ); |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 239 | } |
| 240 | |
| 241 | |
| 242 | /*********************************************************************** |
| 243 | * call_WH_CBT |
| 244 | */ |
| 245 | static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp ) |
| 246 | { |
| 247 | LRESULT ret = 0; |
| 248 | |
| 249 | switch (code) |
| 250 | { |
| 251 | case HCBT_CREATEWND: |
| 252 | { |
| 253 | CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lp; |
| 254 | CBT_CREATEWND16 cbtcw16; |
| 255 | CREATESTRUCT16 cs16; |
| 256 | |
Alexandre Julliard | 55d72b7 | 2004-01-28 21:41:56 +0000 | [diff] [blame] | 257 | cs16.lpCreateParams = (SEGPTR)cbtcw32->lpcs->lpCreateParams; |
Alexandre Julliard | 54100873d | 2003-05-16 20:17:52 +0000 | [diff] [blame] | 258 | cs16.hInstance = HINSTANCE_16(cbtcw32->lpcs->hInstance); |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 259 | cs16.hMenu = HMENU_16(cbtcw32->lpcs->hMenu); |
| 260 | cs16.hwndParent = HWND_16(cbtcw32->lpcs->hwndParent); |
| 261 | cs16.cy = cbtcw32->lpcs->cy; |
| 262 | cs16.cx = cbtcw32->lpcs->cx; |
| 263 | cs16.y = cbtcw32->lpcs->y; |
| 264 | cs16.x = cbtcw32->lpcs->x; |
| 265 | cs16.style = cbtcw32->lpcs->style; |
| 266 | cs16.lpszName = MapLS( cbtcw32->lpcs->lpszName ); |
| 267 | cs16.lpszClass = MapLS( cbtcw32->lpcs->lpszClass ); |
| 268 | cs16.dwExStyle = cbtcw32->lpcs->dwExStyle; |
| 269 | |
| 270 | cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 ); |
| 271 | cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter ); |
| 272 | |
| 273 | lp = MapLS( &cbtcw16 ); |
| 274 | ret = call_hook_16( WH_CBT, code, wp, lp ); |
| 275 | UnMapLS( cs16.lpszName ); |
| 276 | UnMapLS( cs16.lpszClass ); |
| 277 | |
| 278 | cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter ); |
| 279 | UnMapLS( (SEGPTR)cbtcw16.lpcs ); |
| 280 | UnMapLS( lp ); |
| 281 | break; |
| 282 | } |
| 283 | |
| 284 | case HCBT_ACTIVATE: |
| 285 | { |
| 286 | CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lp; |
| 287 | CBTACTIVATESTRUCT16 cas16; |
| 288 | |
| 289 | cas16.fMouse = cas32->fMouse; |
| 290 | cas16.hWndActive = HWND_16( cas32->hWndActive ); |
| 291 | |
| 292 | lp = MapLS( &cas16 ); |
| 293 | ret = call_hook_16( WH_CBT, code, wp, lp ); |
| 294 | UnMapLS( lp ); |
| 295 | break; |
| 296 | } |
| 297 | case HCBT_CLICKSKIPPED: |
| 298 | { |
| 299 | MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp; |
| 300 | MOUSEHOOKSTRUCT16 ms16; |
| 301 | |
| 302 | ms16.pt.x = ms32->pt.x; |
| 303 | ms16.pt.y = ms32->pt.y; |
| 304 | ms16.hwnd = HWND_16( ms32->hwnd ); |
| 305 | ms16.wHitTestCode = ms32->wHitTestCode; |
| 306 | ms16.dwExtraInfo = ms32->dwExtraInfo; |
| 307 | |
| 308 | lp = MapLS( &ms16 ); |
| 309 | ret = call_hook_16( WH_CBT, code, wp, lp ); |
| 310 | UnMapLS( lp ); |
| 311 | break; |
| 312 | } |
| 313 | case HCBT_MOVESIZE: |
| 314 | { |
| 315 | RECT *rect32 = (RECT *)lp; |
| 316 | RECT16 rect16; |
| 317 | |
Alexandre Julliard | 3c39a99 | 2004-08-31 00:02:02 +0000 | [diff] [blame] | 318 | rect16.left = rect32->left; |
| 319 | rect16.top = rect32->top; |
| 320 | rect16.right = rect32->right; |
| 321 | rect16.bottom = rect32->bottom; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 322 | lp = MapLS( &rect16 ); |
| 323 | ret = call_hook_16( WH_CBT, code, wp, lp ); |
| 324 | UnMapLS( lp ); |
| 325 | break; |
| 326 | } |
| 327 | } |
| 328 | return ret; |
| 329 | } |
| 330 | |
| 331 | |
| 332 | /*********************************************************************** |
| 333 | * call_WH_MOUSE |
| 334 | */ |
| 335 | static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp ) |
| 336 | { |
| 337 | MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp; |
| 338 | MOUSEHOOKSTRUCT16 ms16; |
| 339 | LRESULT ret; |
| 340 | |
| 341 | ms16.pt.x = ms32->pt.x; |
| 342 | ms16.pt.y = ms32->pt.y; |
| 343 | ms16.hwnd = HWND_16( ms32->hwnd ); |
| 344 | ms16.wHitTestCode = ms32->wHitTestCode; |
| 345 | ms16.dwExtraInfo = ms32->dwExtraInfo; |
| 346 | |
| 347 | lp = MapLS( &ms16 ); |
| 348 | ret = call_hook_16( WH_MOUSE, code, wp, lp ); |
| 349 | UnMapLS( lp ); |
| 350 | return ret; |
| 351 | } |
| 352 | |
| 353 | |
| 354 | /*********************************************************************** |
| 355 | * call_WH_SHELL |
| 356 | */ |
| 357 | static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp ) |
| 358 | { |
| 359 | return call_hook_16( WH_SHELL, code, wp, lp ); |
| 360 | } |
| 361 | |
| 362 | |
| 363 | /*********************************************************************** |
| 364 | * SetWindowsHook (USER.121) |
| 365 | */ |
| 366 | FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc ) |
| 367 | { |
| 368 | HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) ); |
| 369 | |
| 370 | /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */ |
| 371 | HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0; |
| 372 | |
| 373 | return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask ); |
| 374 | } |
| 375 | |
| 376 | |
| 377 | /*********************************************************************** |
| 378 | * SetWindowsHookEx (USER.291) |
| 379 | */ |
| 380 | HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask ) |
| 381 | { |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 382 | struct user_thread_info *thread_info = get_user_thread_info(); |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 383 | struct hook16_queue_info *info; |
| 384 | HHOOK hook; |
| 385 | int index = id - WH_MINHOOK; |
| 386 | |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 387 | if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0; |
| 388 | if (!hook_procs[index]) |
| 389 | { |
| 390 | FIXME( "hook type %d broken in Win16\n", id ); |
| 391 | return 0; |
| 392 | } |
| 393 | if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id ); |
| 394 | else if (hTask != GetCurrentTask()) |
| 395 | { |
| 396 | FIXME( "setting hook (%d) on other task not supported\n", id ); |
| 397 | return 0; |
| 398 | } |
| 399 | |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 400 | if (!(info = thread_info->hook16_info)) |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 401 | { |
| 402 | if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0; |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 403 | thread_info->hook16_info = info; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 404 | } |
| 405 | if (info->hook[index]) |
| 406 | { |
| 407 | FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id ); |
| 408 | return 0; |
| 409 | } |
| 410 | if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0; |
| 411 | info->hook[index] = hook; |
| 412 | info->proc[index] = proc; |
| 413 | return hook; |
| 414 | } |
| 415 | |
| 416 | |
| 417 | /*********************************************************************** |
| 418 | * UnhookWindowsHook (USER.234) |
| 419 | */ |
| 420 | BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc ) |
| 421 | { |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 422 | struct hook16_queue_info *info; |
| 423 | int index = id - WH_MINHOOK; |
| 424 | |
| 425 | if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE; |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 426 | if (!(info = get_user_thread_info()->hook16_info)) return FALSE; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 427 | if (info->proc[index] != proc) return FALSE; |
| 428 | if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE; |
| 429 | info->hook[index] = 0; |
| 430 | info->proc[index] = 0; |
| 431 | return TRUE; |
| 432 | } |
| 433 | |
| 434 | |
| 435 | /*********************************************************************** |
| 436 | * UnhookWindowsHookEx (USER.292) |
| 437 | */ |
| 438 | BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook ) |
| 439 | { |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 440 | struct hook16_queue_info *info; |
| 441 | int index; |
| 442 | |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 443 | if (!(info = get_user_thread_info()->hook16_info)) return FALSE; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 444 | for (index = 0; index < NB_HOOKS16; index++) |
| 445 | { |
| 446 | if (info->hook[index] == hhook) |
| 447 | { |
| 448 | info->hook[index] = 0; |
| 449 | info->proc[index] = 0; |
| 450 | return UnhookWindowsHookEx( hhook ); |
| 451 | } |
| 452 | } |
| 453 | return FALSE; |
| 454 | } |
| 455 | |
| 456 | |
| 457 | /*********************************************************************** |
| 458 | * CallMsgFilter32 (USER.823) |
| 459 | */ |
| 460 | BOOL16 WINAPI CallMsgFilter32_16( MSG32_16 *lpmsg16_32, INT16 code, BOOL16 wHaveParamHigh ) |
| 461 | { |
| 462 | MSG msg32; |
| 463 | BOOL16 ret; |
| 464 | |
| 465 | if (GetSysModalWindow16()) return FALSE; |
| 466 | msg32.hwnd = WIN_Handle32( lpmsg16_32->msg.hwnd ); |
| 467 | msg32.message = lpmsg16_32->msg.message; |
| 468 | msg32.lParam = lpmsg16_32->msg.lParam; |
| 469 | msg32.time = lpmsg16_32->msg.time; |
| 470 | msg32.pt.x = lpmsg16_32->msg.pt.x; |
| 471 | msg32.pt.y = lpmsg16_32->msg.pt.y; |
| 472 | if (wHaveParamHigh) msg32.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh); |
| 473 | else msg32.wParam = lpmsg16_32->msg.wParam; |
| 474 | |
| 475 | ret = (BOOL16)CallMsgFilterA(&msg32, code); |
| 476 | |
| 477 | lpmsg16_32->msg.hwnd = HWND_16( msg32.hwnd ); |
| 478 | lpmsg16_32->msg.message = msg32.message; |
| 479 | lpmsg16_32->msg.wParam = LOWORD(msg32.wParam); |
| 480 | lpmsg16_32->msg.lParam = msg32.lParam; |
| 481 | lpmsg16_32->msg.time = msg32.time; |
| 482 | lpmsg16_32->msg.pt.x = msg32.pt.x; |
| 483 | lpmsg16_32->msg.pt.y = msg32.pt.y; |
| 484 | if (wHaveParamHigh) lpmsg16_32->wParamHigh = HIWORD(msg32.wParam); |
| 485 | return ret; |
| 486 | } |
| 487 | |
| 488 | |
| 489 | /*********************************************************************** |
| 490 | * CallMsgFilter (USER.123) |
| 491 | */ |
| 492 | BOOL16 WINAPI CallMsgFilter16( MSG16 *msg, INT16 code ) |
| 493 | { |
| 494 | return CallMsgFilter32_16( (MSG32_16 *)msg, code, FALSE ); |
| 495 | } |
| 496 | |
| 497 | |
| 498 | /*********************************************************************** |
| 499 | * CallNextHookEx (USER.293) |
| 500 | */ |
| 501 | LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam ) |
| 502 | { |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 503 | struct hook16_queue_info *info; |
| 504 | LRESULT ret = 0; |
| 505 | |
Alexandre Julliard | 86be9f2 | 2005-04-27 08:18:20 +0000 | [diff] [blame] | 506 | if (!(info = get_user_thread_info()->hook16_info)) return 0; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 507 | |
| 508 | switch (info->id) |
| 509 | { |
| 510 | case WH_MSGFILTER: |
| 511 | { |
| 512 | MSG16 *msg16 = MapSL(lparam); |
| 513 | MSG msg32; |
| 514 | |
| 515 | map_msg_16_to_32( msg16, &msg32 ); |
| 516 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 ); |
| 517 | break; |
| 518 | } |
| 519 | |
| 520 | case WH_GETMESSAGE: |
| 521 | { |
| 522 | MSG16 *msg16 = MapSL(lparam); |
| 523 | MSG msg32; |
| 524 | |
| 525 | map_msg_16_to_32( msg16, &msg32 ); |
| 526 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 ); |
| 527 | map_msg_32_to_16( &msg32, msg16 ); |
| 528 | break; |
| 529 | } |
| 530 | |
| 531 | case WH_CALLWNDPROC: |
| 532 | { |
| 533 | CWPSTRUCT16 *cwp16 = MapSL(lparam); |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 534 | LRESULT result; |
| 535 | struct wndproc_hook_params params; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 536 | |
Alexandre Julliard | dc61a4b | 2006-05-20 16:34:14 +0200 | [diff] [blame] | 537 | params.hhook = hhook; |
| 538 | params.code = code; |
| 539 | params.wparam = wparam; |
| 540 | ret = WINPROC_CallProc16To32A( wndproc_hook_callback, cwp16->hwnd, cwp16->message, |
| 541 | cwp16->wParam, cwp16->lParam, &result, ¶ms ); |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 542 | break; |
| 543 | } |
| 544 | |
| 545 | case WH_CBT: |
| 546 | switch (code) |
| 547 | { |
| 548 | case HCBT_CREATEWND: |
| 549 | { |
| 550 | CBT_CREATEWNDA cbtcw32; |
| 551 | CREATESTRUCTA cs32; |
| 552 | CBT_CREATEWND16 *cbtcw16 = MapSL(lparam); |
| 553 | CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs ); |
| 554 | |
| 555 | cbtcw32.lpcs = &cs32; |
| 556 | cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter ); |
| 557 | |
Alexandre Julliard | 55d72b7 | 2004-01-28 21:41:56 +0000 | [diff] [blame] | 558 | cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams; |
Alexandre Julliard | 54100873d | 2003-05-16 20:17:52 +0000 | [diff] [blame] | 559 | cs32.hInstance = HINSTANCE_32(cs16->hInstance); |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 560 | cs32.hMenu = HMENU_32(cs16->hMenu); |
| 561 | cs32.hwndParent = WIN_Handle32(cs16->hwndParent); |
| 562 | cs32.cy = cs16->cy; |
| 563 | cs32.cx = cs16->cx; |
| 564 | cs32.y = cs16->y; |
| 565 | cs32.x = cs16->x; |
| 566 | cs32.style = cs16->style; |
| 567 | cs32.lpszName = MapSL( cs16->lpszName ); |
| 568 | cs32.lpszClass = MapSL( cs16->lpszClass ); |
| 569 | cs32.dwExStyle = cs16->dwExStyle; |
| 570 | |
| 571 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 ); |
| 572 | cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter ); |
| 573 | break; |
| 574 | } |
| 575 | case HCBT_ACTIVATE: |
| 576 | { |
| 577 | CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam); |
| 578 | CBTACTIVATESTRUCT cas32; |
| 579 | cas32.fMouse = cas16->fMouse; |
| 580 | cas32.hWndActive = WIN_Handle32(cas16->hWndActive); |
| 581 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 ); |
| 582 | break; |
| 583 | } |
| 584 | case HCBT_CLICKSKIPPED: |
| 585 | { |
| 586 | MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam); |
| 587 | MOUSEHOOKSTRUCT ms32; |
| 588 | |
| 589 | ms32.pt.x = ms16->pt.x; |
| 590 | ms32.pt.y = ms16->pt.y; |
| 591 | /* wHitTestCode may be negative, so convince compiler to do |
| 592 | correct sign extension. Yay. :| */ |
| 593 | ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode; |
| 594 | ms32.dwExtraInfo = ms16->dwExtraInfo; |
| 595 | ms32.hwnd = WIN_Handle32( ms16->hwnd ); |
| 596 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 ); |
| 597 | break; |
| 598 | } |
| 599 | case HCBT_MOVESIZE: |
| 600 | { |
| 601 | RECT16 *rect16 = MapSL(lparam); |
| 602 | RECT rect32; |
| 603 | |
Alexandre Julliard | 3c39a99 | 2004-08-31 00:02:02 +0000 | [diff] [blame] | 604 | rect32.left = rect16->left; |
| 605 | rect32.top = rect16->top; |
| 606 | rect32.right = rect16->right; |
| 607 | rect32.bottom = rect16->bottom; |
Alexandre Julliard | 0286135 | 2002-10-29 00:41:42 +0000 | [diff] [blame] | 608 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 ); |
| 609 | break; |
| 610 | } |
| 611 | } |
| 612 | break; |
| 613 | |
| 614 | case WH_MOUSE: |
| 615 | { |
| 616 | MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam); |
| 617 | MOUSEHOOKSTRUCT ms32; |
| 618 | |
| 619 | ms32.pt.x = ms16->pt.x; |
| 620 | ms32.pt.y = ms16->pt.y; |
| 621 | /* wHitTestCode may be negative, so convince compiler to do |
| 622 | correct sign extension. Yay. :| */ |
| 623 | ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode); |
| 624 | ms32.dwExtraInfo = ms16->dwExtraInfo; |
| 625 | ms32.hwnd = WIN_Handle32(ms16->hwnd); |
| 626 | ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 ); |
| 627 | break; |
| 628 | } |
| 629 | |
| 630 | case WH_SHELL: |
| 631 | case WH_KEYBOARD: |
| 632 | ret = CallNextHookEx( hhook, code, wparam, lparam ); |
| 633 | break; |
| 634 | |
| 635 | case WH_HARDWARE: |
| 636 | case WH_FOREGROUNDIDLE: |
| 637 | case WH_CALLWNDPROCRET: |
| 638 | case WH_SYSMSGFILTER: |
| 639 | case WH_JOURNALRECORD: |
| 640 | case WH_JOURNALPLAYBACK: |
| 641 | default: |
| 642 | FIXME("\t[%i] 16to32 translation unimplemented\n", info->id); |
| 643 | ret = CallNextHookEx( hhook, code, wparam, lparam ); |
| 644 | break; |
| 645 | } |
| 646 | return ret; |
| 647 | } |
| 648 | |
| 649 | |
| 650 | /*********************************************************************** |
| 651 | * DefHookProc (USER.235) |
| 652 | */ |
| 653 | LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wparam, LPARAM lparam, HHOOK *hhook ) |
| 654 | { |
| 655 | return CallNextHookEx16( *hhook, code, wparam, lparam ); |
| 656 | } |