Ignore:
Timestamp:
Dec 16, 1999, 1:11:49 AM (26 years ago)
Author:
sandervl
Message:

sendmessage + hook updates + misc fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/HOOK.CPP

    r949 r2084  
    1 /* $Id: HOOK.CPP,v 1.5 1999-09-15 23:18:47 sandervl Exp $ */
     1/* $Id: HOOK.CPP,v 1.6 1999-12-16 00:11:44 sandervl Exp $ */
    22
    33/*
    4  * Win32 hook API functions for OS/2
    5  *
    6  * Copyright 1998 Sander van Leeuwen
     4 * Windows hook functions
     5 *
     6 * Copyright 1999 Sander van Leeuwen (OS/2 Port)
     7 *
     8 * Port of Wine code (windows\hook.c; dated 990920)
     9 * All 16 bits code removed
     10 *
     11 * Copyright 1994, 1995 Alexandre Julliard
     12 *                 1996 Andrew Lewycky
     13 *
     14 * Based on investigations by Alex Korobka
    715 *
    816 *
    917 * Project Odin Software License can be found in LICENSE.TXT
    10  *
    11  */
     18 */
     19
     20/*
     21 * Warning!
     22 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
     23 * a pointer to the next function. Now it is in fact composed of a USER heap
     24 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
     25 */
     26
    1227#include <os2win.h>
    13 #include <stdarg.h>
    14 #include "misc.h"
    15 #include "hooks.h"
    16 
    17 //******************************************************************************
    18 //******************************************************************************
    19 HHOOK WIN32API SetWindowsHookExA(int idHook, HOOKPROC hkprc, HINSTANCE hmod, DWORD dwThreadId)
    20 {
    21  HHOOK    rc;
    22  HOOKPROC_O32 os2hkprc;
    23 
    24     switch(idHook) {
    25         case WH_CALLWNDPROC:
    26                 os2hkprc = HkWindow::GetOS2Hook();
    27                 break;
    28         case WH_CBT:
     28#include "hook.h"
     29#include "win.h"
     30#include "queue.h"
     31#include "task.h"
     32#include "winproc.h"
     33#include "debugtools.h"
     34#include <misc.h>
     35#include <heapstring.h>
     36#include <vmutex.h>
     37#include <wprocess.h>
     38
     39DEFAULT_DEBUG_CHANNEL(hook)
     40
     41#include "pshpack1.h"
     42
     43  /* Hook data (pointed to by a HHOOK) */
     44typedef struct
     45{
     46    HANDLE     next;               /* 00 Next hook in chain */
     47    HOOKPROC   proc;               /* 04 Hook procedure (original) */
     48    INT        id;                 /* 08 Hook id (WH_xxx) */
     49    DWORD      ownerThread;        /* 0C Owner thread (0 for system hook) */
     50    HMODULE    ownerModule;        /* 10 Owner module */
     51    DWORD      flags;              /* 14 flags */
     52    DWORD      magic;              /* 18 magic dword */
     53} HOOKDATA;
     54
     55#include "poppack.h"
     56
     57#define HOOK_MAGIC1  ((int)'H' | (int)'K' << 8)  /* 'HK' */
     58#define HOOK_MAGIC ((HOOK_MAGIC1<<16)|HOOK_MAGIC1) // 'HKHK'
     59
     60#define CHECK_MAGIC(a) ((a != 0) && (((HOOKDATA *)a)->magic == HOOK_MAGIC))
     61
     62//Global DLL Data
     63#pragma data_seg(_GLOBALDATA)
     64static HANDLE HOOK_systemHooks[WH_NB_HOOKS] = { 0 };
     65static VMutex systemHookMutex(TRUE);
     66#pragma data_seg()
     67static HANDLE HOOK_threadHooks[WH_NB_HOOKS] = { 0 };
     68static VMutex threadHookMutex;
     69
     70typedef VOID (*HOOK_MapFunc)(INT, INT, WPARAM *, LPARAM *);
     71typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
     72                               LPARAM);
     73
     74/***********************************************************************
     75 *           HOOK_Map32ATo32W
     76 */
     77static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
     78                             LPARAM *plParam)
     79{
     80    if (id == WH_CBT && code == HCBT_CREATEWND)
     81    {
     82        LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
     83        LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)HeapAlloc(GetProcessHeap(), 0,
     84                                                                sizeof(*lpcbtcwW) );
     85        lpcbtcwW->lpcs = (CREATESTRUCTW*)HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwW->lpcs) );
     86
     87        lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
     88        *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
     89
     90        if (HIWORD(lpcbtcwA->lpcs->lpszName))
    2991        {
    30                 HkCBT *hkhook = new HkCBT(0, hkprc, hmod, dwThreadId);;
    31 #ifdef DEBUG
    32                 WriteLog("OS2SetWindowsHookExA WH_CBT %X, %X, %X, %X\n", idHook, hkprc, hmod, dwThreadId);
     92            lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
     93                                                    lpcbtcwA->lpcs->lpszName );
     94        }
     95        else
     96          lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
     97
     98        if (HIWORD(lpcbtcwA->lpcs->lpszClass))
     99        {
     100            lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
     101                                                   lpcbtcwA->lpcs->lpszClass );
     102        }
     103        else
     104          lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
     105        *plParam = (LPARAM)lpcbtcwW;
     106    }
     107    return;
     108}
     109
     110
     111/***********************************************************************
     112 *           HOOK_UnMap32ATo32W
     113 */
     114static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
     115                               LPARAM lParamOrig, WPARAM wParam,
     116                               LPARAM lParam)
     117{
     118    if (id == WH_CBT && code == HCBT_CREATEWND)
     119    {
     120        LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
     121        if (HIWORD(lpcbtcwW->lpcs->lpszName))
     122            HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
     123        if (HIWORD(lpcbtcwW->lpcs->lpszClass))
     124            HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
     125        HeapFree( GetProcessHeap(), 0, lpcbtcwW->lpcs );
     126        HeapFree( GetProcessHeap(), 0, lpcbtcwW );
     127    }
     128    return;
     129}
     130
     131
     132/***********************************************************************
     133 *           HOOK_Map32WTo32A
     134 */
     135static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
     136                             LPARAM *plParam)
     137{
     138    if (id == WH_CBT && code == HCBT_CREATEWND)
     139    {
     140        LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
     141        LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)HeapAlloc(GetProcessHeap(), 0,
     142                                                                sizeof(*lpcbtcwA) );
     143        lpcbtcwA->lpcs = (CREATESTRUCTA*)HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwA->lpcs) );
     144
     145        lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
     146        *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
     147
     148        if (HIWORD(lpcbtcwW->lpcs->lpszName))
     149          lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
     150                                                    lpcbtcwW->lpcs->lpszName );
     151        else
     152          lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
     153
     154        if (HIWORD(lpcbtcwW->lpcs->lpszClass))
     155          lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
     156                                                   lpcbtcwW->lpcs->lpszClass );
     157        else
     158          lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
     159        *plParam = (LPARAM)lpcbtcwA;
     160    }
     161    return;
     162}
     163
     164
     165/***********************************************************************
     166 *           HOOK_UnMap32WTo32A
     167 */
     168static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
     169                               LPARAM lParamOrig, WPARAM wParam,
     170                               LPARAM lParam)
     171{
     172    if (id == WH_CBT && code == HCBT_CREATEWND)
     173    {
     174        LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
     175        if (HIWORD(lpcbtcwA->lpcs->lpszName))
     176            HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
     177        if (HIWORD(lpcbtcwA->lpcs->lpszClass))
     178            HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
     179        HeapFree( GetProcessHeap(), 0, lpcbtcwA->lpcs );
     180        HeapFree( GetProcessHeap(), 0, lpcbtcwA );
     181    }
     182    return;
     183}
     184
     185
     186/***********************************************************************
     187 *           Map Function Tables
     188 */
     189static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
     190{
     191    { NULL, NULL,             NULL },
     192    { NULL, NULL,             HOOK_Map32ATo32W },
     193    { NULL, HOOK_Map32WTo32A, NULL }
     194};
     195
     196static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
     197{
     198    { NULL, NULL,               NULL },
     199    { NULL, NULL,               HOOK_UnMap32ATo32W },
     200    { NULL, HOOK_UnMap32WTo32A, NULL }
     201};
     202
     203
     204/***********************************************************************
     205 *           Internal Functions
     206 */
     207
     208/***********************************************************************
     209 *           HOOK_GetNextHook
     210 *
     211 * Get the next hook of a given hook.
     212 */
     213static HANDLE HOOK_GetNextHook( HANDLE hook )
     214{
     215    HOOKDATA *data = (HOOKDATA *)hook;
     216
     217    if (!data || !hook) return 0;
     218    if (data->next) return data->next;
     219    if (!data->ownerThread) return 0;  /* Already system hook */
     220
     221    /* Now start enumerating the system hooks */
     222    return HOOK_systemHooks[data->id - WH_MINHOOK];
     223}
     224
     225
     226/***********************************************************************
     227 *           HOOK_GetHook
     228 *
     229 * Get the first hook for a given type.
     230 */
     231static HANDLE HOOK_GetHook( INT id, DWORD threadId )
     232{
     233  MESSAGEQUEUE *queue;
     234  HANDLE hook = 0;
     235  THDB *thdb;
     236   
     237    thdb = GetTHDBFromThreadId(threadId);
     238    if(thdb) {
     239        hook = thdb->hooks[id - WH_MINHOOK];
     240    }
     241    if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
     242
     243    return hook;
     244}
     245
     246
     247/***********************************************************************
     248 *           HOOK_SetHook
     249 *
     250 * Install a given hook.
     251 */
     252static HHOOK HOOK_SetHook( INT id, LPVOID proc, INT type,
     253                           HMODULE hModule, DWORD dwThreadId )
     254{
     255  HOOKDATA *data;
     256  THDB     *thdb;
     257 
     258    if ((id < WH_MINHOOK) || (id > WH_MAXHOOK) || !proc )
     259    {
     260        SetLastError(ERROR_INVALID_PARAMETER);
     261        return 0;
     262    }
     263
     264    dprintf(("Setting hook %d: %08x %04x %08lx\n",
     265             id, (UINT)proc, hModule, dwThreadId ));
     266
     267#ifndef __WIN32OS2__
     268    /* Create task queue if none present */
     269    GetFastQueue16();
     270
     271    if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);
    33272#endif
    34                 return((HHOOK)hkhook);
     273
     274
     275    if (dwThreadId)  /* Task-specific hook */
     276    {
     277        if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
     278            (id == WH_SYSMSGFILTER)) {
     279                SetLastError(ERROR_INVALID_PARAMETER);
     280                return 0;  /* System-only hooks */
    35281        }
    36         case WH_DEBUG:
    37                 os2hkprc = HkDebug::GetOS2Hook();       
    38                 break;
    39         case WH_JOURNALPLAYBACK:
    40                 os2hkprc = HkJrnlPlayback::GetOS2Hook();       
    41                 break;
    42         case WH_JOURNALRECORD:
    43                 os2hkprc = HkJrnlRecord::GetOS2Hook(); 
    44                 break;
    45         case WH_GETMESSAGE:
    46                 os2hkprc = HkGetMessage::GetOS2Hook(); 
    47                 break;
    48         case WH_MOUSE:
    49                 os2hkprc = HkMouse::GetOS2Hook();       
    50                 break;
    51         case WH_KEYBOARD:
    52                 os2hkprc = HkKeyboard::GetOS2Hook();   
    53                 break;
    54         case WH_SHELL:
    55                 os2hkprc = HkShell::GetOS2Hook();       
    56                 break;
    57         case WH_SYSMSGFILTER:
    58                 os2hkprc = HkSysMsgFilter::GetOS2Hook();       
    59                 break;
    60         case WH_MSGFILTER:
    61                 os2hkprc = HkMsgFilter::GetOS2Hook();   
    62                 break;
    63     }
    64 
    65     rc = O32_SetWindowsHookEx(idHook, os2hkprc, hmod, dwThreadId);
    66 
    67     if(rc) {
    68       switch(idHook) {
    69         case WH_CALLWNDPROC:
    70                 new HkWindow(rc, hkprc, hmod, dwThreadId);
    71                 break;
    72         case WH_CBT:
    73                 break;
    74         case WH_DEBUG:
    75                 new HkDebug(rc, hkprc, hmod, dwThreadId);;     
    76                 break;
    77         case WH_JOURNALPLAYBACK:
    78                 new HkJrnlPlayback(rc, hkprc, hmod, dwThreadId);;       
    79                 break;
    80         case WH_JOURNALRECORD:
    81                 new HkJrnlRecord(rc, hkprc, hmod, dwThreadId);;
    82                 break;
    83         case WH_GETMESSAGE:
    84                 new HkGetMessage(rc, hkprc, hmod, dwThreadId);;
    85                 break;
    86         case WH_MOUSE:
    87                 new HkMouse(rc, hkprc, hmod, dwThreadId);;     
    88                 break;
    89         case WH_KEYBOARD:
    90                 new HkKeyboard(rc, hkprc, hmod, dwThreadId);;   
    91                 break;
    92         case WH_SHELL:
    93                 new HkShell(rc, hkprc, hmod, dwThreadId);;     
    94                 break;
    95         case WH_SYSMSGFILTER:
    96                 new HkSysMsgFilter(rc, hkprc, hmod, dwThreadId);;       
    97                 break;
    98         case WH_MSGFILTER:
    99                 new HkMsgFilter(rc, hkprc, hmod, dwThreadId);; 
    100                 break;
    101       }
    102     }
    103 #ifdef DEBUG
    104     WriteLog("OS2SetWindowsHookExA %X, %X, %X, %X, returned %X\n", idHook, hkprc, hmod, dwThreadId, rc);
     282    }
     283
     284    /* Create the hook structure */
     285
     286    data = (HOOKDATA *) HeapAlloc(GetProcessHeap(), 0, sizeof(HOOKDATA));
     287    data->proc        = (HOOKPROC)proc;
     288    data->id          = id;
     289    data->ownerThread = dwThreadId;
     290    data->ownerModule = hModule;
     291    data->flags       = type;
     292    data->magic       = HOOK_MAGIC;
     293
     294    /* Insert it in the correct linked list */
     295    if(dwThreadId)
     296    {
     297        thdb = GetTHDBFromThreadId(dwThreadId);
     298        if(!thdb) {
     299                dprintf(("HOOK_SetHook: can't find thread database for thread %x", dwThreadId));
     300                return 0;
     301        }
     302        threadHookMutex.enter();
     303        data->next = thdb->hooks[id - WH_MINHOOK];
     304        thdb->hooks[id - WH_MINHOOK] = (DWORD)data;
     305        threadHookMutex.leave();
     306    }
     307    else
     308    {
     309        systemHookMutex.enter();
     310        data->next = HOOK_systemHooks[id - WH_MINHOOK];
     311        HOOK_systemHooks[id - WH_MINHOOK] = (HANDLE)data;
     312        systemHookMutex.leave();
     313    }
     314
     315    return (HHOOK)data;
     316}
     317
     318
     319/***********************************************************************
     320 *           HOOK_RemoveHook
     321 *
     322 * Remove a hook from the list.
     323 */
     324static BOOL HOOK_RemoveHook( HOOKDATA *data )
     325{
     326  HOOKDATA *prevHook;
     327  THDB     *thdb;
     328  VMutex   *hookMutex;
     329
     330    dprintf(("Removing hook %08x\n", data));
     331   
     332    if (data->flags & HOOK_INUSE)
     333    {
     334        /* Mark it for deletion later on */
     335        dprintf(("Hook still running, deletion delayed\n" ));
     336        data->flags |= HOOK_DELAYED_DELETE;
     337        return TRUE;
     338    }
     339
     340#ifndef __WIN32OS2__
     341    if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);
    105342#endif
    106     return(rc);
    107 }
    108 //******************************************************************************
    109 //******************************************************************************
    110 HHOOK WIN32API SetWindowsHookA(int idHook, HOOKPROC hkprc)
    111 {
    112  HHOOK rc;
    113 
    114     rc = SetWindowsHookExA(idHook, hkprc, NULL, 0);
    115 #ifdef DEBUG
    116     WriteLog("OS2SetWindowsHookA %X, %X, returned %X\n", idHook, hkprc, rc);
     343     
     344    /* Remove it from the linked list */
     345
     346    if (data->ownerThread)
     347    {
     348        thdb = GetTHDBFromThreadId(data->ownerThread);
     349        if(!thdb) {
     350                dprintf(("HOOK_RemoveHook: can't find thread database for thread %x", data->ownerThread));
     351                return FALSE;
     352        }
     353        hookMutex = &threadHookMutex;
     354        hookMutex->enter();
     355        prevHook = (HOOKDATA *)thdb->hooks[data->id - WH_MINHOOK];
     356    }
     357    else {
     358        hookMutex = &systemHookMutex;
     359        hookMutex->enter();
     360        prevHook = (HOOKDATA *)HOOK_systemHooks[data->id - WH_MINHOOK];
     361    }
     362    while (prevHook && prevHook != data)
     363        prevHook = (HOOKDATA *)prevHook->next;
     364
     365    if (!prevHook) {
     366        hookMutex->leave();
     367        return FALSE;
     368    }
     369    prevHook = (HOOKDATA *)data->next;
     370    hookMutex->leave();
     371
     372    HeapFree(GetProcessHeap(), 0, (LPVOID)data );
     373    return TRUE;
     374}
     375
     376
     377/***********************************************************************
     378 *           HOOK_FindValidHook
     379 */
     380static HANDLE HOOK_FindValidHook( HANDLE hook )
     381{
     382    HOOKDATA *data;
     383
     384    for (;;)
     385    {
     386        if (!(data = (HOOKDATA *)hook)) return 0;
     387        if (data->proc) return hook;
     388        hook = data->next;
     389    }
     390}
     391
     392
     393/***********************************************************************
     394 *           HOOK_CallHook
     395 *
     396 * Call a hook procedure.
     397 */
     398static LRESULT HOOK_CallHook( HANDLE hook, INT fromtype, INT code,
     399                              WPARAM wParam, LPARAM lParam )
     400{
     401    MESSAGEQUEUE *queue;
     402    HANDLE prevHook;
     403    HOOKDATA *data = (HOOKDATA *)hook;
     404    LRESULT ret;
     405
     406    WPARAM wParamOrig = wParam;
     407    LPARAM lParamOrig = lParam;
     408    HOOK_MapFunc MapFunc;
     409    HOOK_UnMapFunc UnMapFunc;
     410
     411    MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
     412    UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
     413
     414    if (MapFunc)
     415      MapFunc( data->id, code, &wParam, &lParam );
     416
     417    /* Now call it */
     418
     419    data->flags |= HOOK_INUSE;
     420
     421    dprintf2(("Calling hook %04x: %d %08x %08lx\n", hook, code, wParam, lParam ));
     422
     423    ret = data->proc(code, wParam, lParam);
     424
     425    data->flags &= ~HOOK_INUSE;
     426
     427    if (UnMapFunc)
     428      UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
     429
     430    if(data->flags & HOOK_DELAYED_DELETE) HOOK_RemoveHook( data );
     431
     432    return ret;
     433}
     434
     435/***********************************************************************
     436 *           Exported Functions & APIs
     437 */
     438
     439/***********************************************************************
     440 *           HOOK_IsHooked
     441 *
     442 * Replacement for calling HOOK_GetHook from other modules.
     443 */
     444BOOL HOOK_IsHooked( INT id )
     445{
     446    /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
     447       avoid queue being created if someone wants to merely check ... */
     448
     449    return HOOK_GetHook( id, GetCurrentThreadId() ) != 0;
     450}
     451
     452/***********************************************************************
     453 *           HOOK_CallHooks32A
     454 *
     455 * Call a hook chain.
     456 */
     457LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
     458                           LPARAM lParam )
     459{
     460    HANDLE hook;
     461
     462    if (!(hook = HOOK_GetHook( id, GetCurrentThreadId() ))) return 0;
     463    if (!(hook = HOOK_FindValidHook(hook))) return 0;
     464    return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
     465}
     466
     467/***********************************************************************
     468 *           HOOK_CallHooks32W
     469 *
     470 * Call a hook chain.
     471 */
     472LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
     473                           LPARAM lParam )
     474{
     475    HANDLE hook;
     476
     477    if (!(hook = HOOK_GetHook( id, GetCurrentThreadId() ))) return 0;
     478    if (!(hook = HOOK_FindValidHook(hook))) return 0;
     479    return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
     480                          lParam );
     481}
     482
     483
     484#if 0
     485/***********************************************************************
     486 *           HOOK_ResetQueueHooks
     487 */
     488void HOOK_ResetQueueHooks( HQUEUE hQueue )
     489{
     490    MESSAGEQUEUE *queue;
     491
     492    if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
     493    {
     494        HOOKDATA*       data;
     495        HHOOK           hook;
     496        int             id;
     497        for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
     498        {
     499            hook = queue->hooks[id - WH_MINHOOK];
     500            while( hook )
     501            {
     502                if( (data = (HOOKDATA *)hook) )
     503                {
     504                  data->ownerQueue = hQueue;
     505                  hook = data->next;
     506                } else break;
     507            }
     508        }
     509
     510        QUEUE_Unlock( queue );
     511    }
     512}
    117513#endif
    118     return(rc);
    119 }
    120 //******************************************************************************
    121 //******************************************************************************
    122 HHOOK WIN32API SetWindowsHookExW(int idHook, HOOKPROC hkprc, HINSTANCE hmod, DWORD dwThreadId)
    123 {
    124 #ifdef DEBUG
    125     WriteLog("OS2SetWindowsHookExW\n");
    126 #endif
    127     return(SetWindowsHookExA(idHook, hkprc, hmod, dwThreadId));
    128 }
    129 //******************************************************************************
    130 //******************************************************************************
    131 BOOL WIN32API UnhookWindowsHookEx(HHOOK hook)
    132 {
    133 #ifdef DEBUG
    134     WriteLog("OS2UnhookWindowsHookEx\n");
    135 #endif
    136    
    137     if(HkWindow::UnHookWindowsHook(hook) == FALSE)
    138      if(HkCBT::UnHookWindowsHook(hook) == TRUE) {
    139         return(TRUE);
    140      }
    141      else
    142       if(HkGetMessage::UnHookWindowsHook(hook) == FALSE)
    143        if(HkMsgFilter::UnHookWindowsHook(hook) == FALSE)
    144         if(HkSysMsgFilter::UnHookWindowsHook(hook) == FALSE)
    145          if(HkMouse::UnHookWindowsHook(hook) == FALSE)
    146           if(HkKeyboard::UnHookWindowsHook(hook) == FALSE)
    147            if(HkShell::UnHookWindowsHook(hook) == FALSE)
    148             if(HkDebug::UnHookWindowsHook(hook) == FALSE)
    149              if(HkJrnlPlayback::UnHookWindowsHook(hook) == FALSE)
    150               if(HkJrnlRecord::UnHookWindowsHook(hook) == FALSE) {
    151                 dprintf(("Hook %X not found!\n", hook));
    152               }
    153     return O32_UnhookWindowsHookEx(hook);
    154 }
    155 //******************************************************************************
    156 //******************************************************************************
    157 BOOL WIN32API UnhookWindowsHook(int nCode, HOOKPROC hkproc)
    158 {
    159  HHOOK hook = 0;
    160    
    161     switch(nCode) {
    162         case WH_CALLWNDPROC:
    163                 hook = HkWindow::FindHookProc(hkproc); 
    164                 break;
    165         case WH_CBT:
    166                 hook = HkCBT::FindHookProc(hkproc);
    167                 break;
    168         case WH_DEBUG:
    169                 hook = HkDebug::FindHookProc(hkproc);   
    170                 break;
    171         case WH_JOURNALPLAYBACK:
    172                 hook = HkJrnlPlayback::FindHookProc(hkproc);   
    173                 break;
    174         case WH_JOURNALRECORD:
    175                 hook = HkJrnlRecord::FindHookProc(hkproc);     
    176                 break;
    177         case WH_GETMESSAGE:
    178                 hook = HkGetMessage::FindHookProc(hkproc);     
    179                 break;
    180         case WH_MOUSE:
    181                 hook = HkMouse::FindHookProc(hkproc);   
    182                 break;
    183         case WH_KEYBOARD:
    184                 hook = HkKeyboard::FindHookProc(hkproc);       
    185                 break;
    186         case WH_SHELL:
    187                 hook = HkShell::FindHookProc(hkproc);
    188                 break;
    189         case WH_SYSMSGFILTER:
    190                 hook = HkSysMsgFilter::FindHookProc(hkproc);   
    191                 break;
    192         case WH_MSGFILTER:
    193                 hook = HkMsgFilter::FindHookProc(hkproc);       
    194                 break;
    195     }
    196 #ifdef DEBUG
    197     WriteLog("OS2UnhookWindowsHook %X\n", hook);
    198 #endif
    199     if(hook == 0)
    200         return(FALSE);
    201 
    202     return O32_UnhookWindowsHookEx(hook);
    203 }
    204 //******************************************************************************
    205 //******************************************************************************
    206 LRESULT WIN32API CallNextHookEx(HHOOK arg1, int arg2, WPARAM arg3, LPARAM  arg4)
    207 {
    208  HkCBT *hook;
    209 
    210 #ifdef DEBUG
    211     WriteLog("OS2CallNextHookEx\n");
    212 #endif
    213     if((hook = HkCBT::FindHook(arg1)) != NULL) {
    214                 return hook->CallNextHook(arg1, arg2, arg3, arg4);
    215     }
    216     else        return O32_CallNextHookEx(arg1, arg2, arg3, arg4);
    217 }
    218 //******************************************************************************
    219 //TODO
    220 //******************************************************************************
    221 BOOL WIN32API CallMsgFilterA( LPMSG msg, int nCode)
    222 {
    223 #ifdef DEBUG
    224     WriteLog("USER32:  CallMsgFilterA\n");
    225 #endif
    226 #if 0
    227     if(HkSysMsgFilter::OS2HkCBTProc(msg->hwnd, nCode, 0, (LPARAM)msg))
    228         return TRUE;
    229 
    230     return HkMsgFilter::OS2HkCBTProc(hwnd, Msg, wParam, lParam);
    231 #else
    232     return 0;
    233 #endif
    234 }
    235 //******************************************************************************
    236 //TODO
    237 //******************************************************************************
    238 BOOL WIN32API CallMsgFilterW( LPMSG msg, int nCode)
    239 {
    240 #ifdef DEBUG
    241     WriteLog("USER32:  CallMsgFilterW\n");
    242 #endif
    243 #if 0
    244     if(HkSysMsgFilter::OS2HkCBTProc(msg->hwnd, nCode, 0, (LPARAM)msg))
    245         return TRUE;
    246 
    247     return HkMsgFilter::OS2HkCBTProc(hwnd, Msg, wParam, lParam);
    248 #else
    249     return 0;
    250 #endif
    251 }
    252 //******************************************************************************
    253 //******************************************************************************
     514
     515/***********************************************************************
     516 *           HOOK_FreeModuleHooks
     517 */
     518void HOOK_FreeModuleHooks( HMODULE hModule )
     519{
     520 /* remove all system hooks registered by this module */
     521
     522  HOOKDATA*     hptr;
     523  HHOOK         hook, next;
     524  int           id;
     525
     526  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
     527    {
     528       hook = HOOK_systemHooks[id - WH_MINHOOK];
     529       while( hook )
     530          if( (hptr = (HOOKDATA *)hook) )
     531            {
     532              next = hptr->next;
     533              if( hptr->ownerModule == hModule )
     534                {
     535                  hptr->flags &= HOOK_MAPTYPE;
     536                  HOOK_RemoveHook(hptr);
     537                }
     538              hook = next;
     539            }
     540          else hook = 0;
     541    }
     542}
     543
     544/***********************************************************************
     545 *           HOOK_FreeQueueHooks
     546 */
     547void HOOK_FreeQueueHooks( DWORD threadId )
     548{
     549  /* remove all hooks registered by this queue */
     550
     551  HOOKDATA*     hptr = NULL;
     552  HHOOK         hook, next;
     553  int           id;
     554
     555  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
     556    {
     557       hook = HOOK_GetHook( id, threadId );
     558       while( hook )
     559        {
     560          next = HOOK_GetNextHook(hook);
     561
     562          hptr = (HOOKDATA *)hook;
     563          if( hptr && hptr->ownerThread == threadId )
     564            {
     565              hptr->flags &= HOOK_MAPTYPE;
     566              HOOK_RemoveHook(hptr);
     567            }
     568          hook = next;
     569        }
     570    }
     571}
     572
     573
     574/***********************************************************************
     575 *           SetWindowsHook32A   (USER32.525)
     576 */
     577HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
     578{
     579    return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
     580}
     581
     582/***********************************************************************
     583 *           SetWindowsHook32W   (USER32.528)
     584 */
     585HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
     586{
     587    return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
     588}
     589
     590/***********************************************************************
     591 *           SetWindowsHookEx32A   (USER32.526)
     592 */
     593HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
     594                                  DWORD dwThreadId )
     595{
     596    return HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, dwThreadId );
     597}
     598
     599/***********************************************************************
     600 *           SetWindowsHookEx32W   (USER32.527)
     601 */
     602HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
     603                                  DWORD dwThreadId )
     604{
     605    return HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, dwThreadId );
     606}
     607
     608/***********************************************************************
     609 *           UnhookWindowsHook32   (USER32.557)
     610 */
     611BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
     612{
     613    HANDLE hook = HOOK_GetHook( id, GetCurrentThreadId() );
     614
     615    dprintf(("UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc ));
     616
     617    while (hook)
     618    {
     619        HOOKDATA *data = (HOOKDATA *)hook;
     620        if (data->proc == proc) break;
     621        hook = HOOK_GetNextHook( hook );
     622    }
     623    if (!hook) return FALSE;
     624    return HOOK_RemoveHook( (HOOKDATA *)hook );
     625}
     626
     627
     628/***********************************************************************
     629 *           UnhookWindowHookEx32   (USER32.558)
     630 */
     631BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
     632{
     633    if (CHECK_MAGIC(hhook) == FALSE)
     634        return FALSE;
     635
     636    return HOOK_RemoveHook( (HOOKDATA *)hhook );
     637}
     638
     639/***********************************************************************
     640 *           CallNextHookEx32    (USER32.17)
     641 *
     642 * There aren't ANSI and UNICODE versions of this.
     643 */
     644LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
     645                                 LPARAM lParam )
     646{
     647    HANDLE next;
     648    INT fromtype;       /* figure out Ansi/Unicode */
     649    HOOKDATA *oldhook;
     650
     651    if (CHECK_MAGIC(hhook) == FALSE)
     652        return FALSE;
     653
     654    if (!(next = HOOK_GetNextHook( hhook ))) return 0;
     655
     656    oldhook = (HOOKDATA *)hhook ;
     657    fromtype = oldhook->flags & HOOK_MAPTYPE;
     658
     659    return HOOK_CallHook( next, fromtype, code, wParam, lParam );
     660}
     661
     662
     663/***********************************************************************
     664 *           CallMsgFilter32A   (USER32.15)
     665 */
     666/*
     667 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
     668 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
     669 */
     670BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
     671{
     672    if (GetSysModalWindow()) return FALSE;      /* ??? */
     673    if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
     674      return TRUE;
     675    return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
     676}
     677
     678
     679/***********************************************************************
     680 *           CallMsgFilter32W   (USER32.16)
     681 */
     682BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
     683{
     684    if (GetSysModalWindow()) return FALSE;      /* ??? */
     685    if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
     686      return TRUE;
     687    return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );
     688}
     689
Note: See TracChangeset for help on using the changeset viewer.