Exemplo n.º 1
0
/***********************************************************************
 *		call_hook
 *
 * Call hook either in current thread or send message to the destination
 * thread.
 */
static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARAM lparam )
{
    DWORD_PTR ret = 0;

    if (info->tid)
    {
        struct hook_extra_info h_extra;
        h_extra.handle = info->handle;
        h_extra.lparam = lparam;

        TRACE( "calling hook in thread %04x %s code %x wp %lx lp %lx\n",
               info->tid, hook_names[info->id-WH_MINHOOK], code, wparam, lparam );

        switch(info->id)
        {
        case WH_KEYBOARD_LL:
            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_KEYBOARD_LL_HOOK,
                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
                                            get_ll_hook_timeout(), &ret );
            break;
        case WH_MOUSE_LL:
            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_MOUSE_LL_HOOK,
                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
                                            get_ll_hook_timeout(), &ret );
            break;
        default:
            ERR("Unknown hook id %d\n", info->id);
            assert(0);
            break;
        }
    }
    else if (info->proc)
    {
        TRACE( "calling hook %p %s code %x wp %lx lp %lx module %s\n",
               info->proc, hook_names[info->id-WH_MINHOOK], code, wparam,
               lparam, debugstr_w(info->module) );

        if (!info->module[0] ||
                (info->proc = get_hook_proc( info->proc, info->module )) != NULL)
        {
            struct user_thread_info *thread_info = get_user_thread_info();
            HHOOK prev = thread_info->hook;
            BOOL prev_unicode = thread_info->hook_unicode;

            thread_info->hook = info->handle;
            thread_info->hook_unicode = info->next_unicode;
            ret = call_hook_proc( info->proc, info->id, code, wparam, lparam,
                                  info->prev_unicode, info->next_unicode );
            thread_info->hook = prev;
            thread_info->hook_unicode = prev_unicode;
        }
    }

    if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
        get_user_thread_info()->key_state_time = 0;  /* force refreshing the key state cache */

    return ret;
}
Exemplo n.º 2
0
/***********************************************************************
 *		CallNextHookEx (USER32.@)
 */
LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
{
    struct user_thread_info *thread_info = get_user_thread_info();
    struct hook_info info;

    ZeroMemory( &info, sizeof(info) - sizeof(info.module) );

    SERVER_START_REQ( get_hook_info )
    {
        req->handle = wine_server_user_handle( thread_info->hook );
        req->get_next = 1;
        req->event = EVENT_MIN;
        wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
        if (!wine_server_call_err( req ))
        {
            info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info.handle       = wine_server_ptr_handle( reply->handle );
            info.id           = reply->id;
            info.pid          = reply->pid;
            info.tid          = reply->tid;
            info.proc         = wine_server_get_ptr( reply->proc );
            info.next_unicode = reply->unicode;
        }
    }
    SERVER_END_REQ;

    info.prev_unicode = thread_info->hook_unicode;
    return call_hook( &info, code, wparam, lparam );
}
Exemplo n.º 3
0
/***********************************************************************
 *           HOOK_IsHooked
 */
static BOOL HOOK_IsHooked( INT id )
{
    struct user_thread_info *thread_info = get_user_thread_info();

    if (!thread_info->active_hooks) return TRUE;
    return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0;
}
/*******************************************************************
 *		GetForegroundWindow  (USER32.@)
 */
HWND WINAPI GetForegroundWindow(void)
{
    struct user_thread_info *thread_info = get_user_thread_info();
    shmglobal_t *shm = wine_get_shmglobal();
    HWND ret = 0;
    DWORD epoch;

    if (shm)
    {
        epoch = shm->foreground_wnd_epoch;

        if (epoch == thread_info->foreground_wnd_epoch)
            return thread_info->foreground_wnd;
    }

    SERVER_START_REQ( get_thread_input )
    {
        req->tid = 0;
        if (!wine_server_call_err( req ))
        {
            ret = wine_server_ptr_handle( reply->foreground );
            if (shm)
            {
                thread_info->foreground_wnd         = ret;
                thread_info->foreground_wnd_epoch   = epoch;
            }
        }
    }
    SERVER_END_REQ;
    return ret;
}
Exemplo n.º 5
0
/***********************************************************************
 *           SetWinEventHook                            [USER32.@]
 *
 * Set up an event hook for a set of events.
 *
 * PARAMS
 *  event_min [I] Lowest event handled by pfnProc
 *  event_max [I] Highest event handled by pfnProc
 *  inst      [I] DLL containing pfnProc
 *  proc      [I] Callback event hook function
 *  pid       [I] Process to get events from, or 0 for all processes
 *  tid       [I] Thread to get events from, or 0 for all threads
 *  flags     [I] Flags indicating the status of pfnProc
 *
 * RETURNS
 *  Success: A handle representing the hook.
 *  Failure: A NULL handle.
 */
HWINEVENTHOOK WINAPI SetWinEventHook(DWORD event_min, DWORD event_max,
                                     HMODULE inst, WINEVENTPROC proc,
                                     DWORD pid, DWORD tid, DWORD flags)
{
    HWINEVENTHOOK handle = 0;
    WCHAR module[MAX_PATH];
    DWORD len;

    TRACE("%d,%d,%p,%p,%08x,%04x,%08x\n", event_min, event_max, inst,
          proc, pid, tid, flags);

    if (inst)
    {
        if (!(len = GetModuleFileNameW(inst, module, MAX_PATH)) || len >= MAX_PATH)
            inst = 0;
    }

    if ((flags & WINEVENT_INCONTEXT) && !inst)
    {
        SetLastError(ERROR_HOOK_NEEDS_HMOD);
        return 0;
    }

    if (event_min > event_max)
    {
        SetLastError(ERROR_INVALID_HOOK_FILTER);
        return 0;
    }

    /* FIXME: what if the tid or pid belongs to another process? */
    if (tid)  /* thread-local hook */
        inst = 0;

    SERVER_START_REQ( set_hook )
    {
        req->id        = WH_WINEVENT;
        req->pid       = pid;
        req->tid       = tid;
        req->event_min = event_min;
        req->event_max = event_max;
        req->flags     = flags;
        req->unicode   = 1;
        if (inst) /* make proc relative to the module base */
        {
            req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
            wine_server_add_data( req, module, strlenW(module) * sizeof(WCHAR) );
        }
        else req->proc = wine_server_client_ptr( proc );

        if (!wine_server_call_err( req ))
        {
            handle = wine_server_ptr_handle( reply->handle );
            get_user_thread_info()->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;

    TRACE("-> %p\n", handle);
    return handle;
}
Exemplo n.º 6
0
static inline BOOL find_first_hook(DWORD id, DWORD event, HWND hwnd, LONG object_id,
                                   LONG child_id, struct hook_info *info)
{
    struct user_thread_info *thread_info = get_user_thread_info();
    BOOL ret;

    if (!HOOK_IsHooked( id ))
    {
        TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
        return FALSE;
    }

    SERVER_START_REQ( start_hook_chain )
    {
        req->id = id;
        req->event = event;
        req->window = wine_server_user_handle( hwnd );
        req->object_id = object_id;
        req->child_id = child_id;
        wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
        ret = !wine_server_call( req );
        if (ret)
        {
            info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info->handle    = wine_server_ptr_handle( reply->handle );
            info->proc      = wine_server_get_ptr( reply->proc );
            info->tid       = reply->tid;
            thread_info->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;
    return ret && (info->tid || info->proc);
}
Exemplo n.º 7
0
/***********************************************************************
 *		GetCursorInfo (USER32.@)
 */
BOOL WINAPI GetCursorInfo( PCURSORINFO pci )
{
    if (!pci) return 0;
    if (get_user_thread_info()->cursor_count >= 0) pci->flags = CURSOR_SHOWING;
    else pci->flags = 0;
    GetCursorPos(&pci->ptScreenPos);
    return 1;
}
Exemplo n.º 8
0
/******************************************************************************
 *              SetThreadDesktop   (USER32.@)
 */
BOOL WINAPI SetThreadDesktop( HDESK handle )
{
    BOOL ret;

    SERVER_START_REQ( set_thread_desktop )
    {
        req->handle = handle;
        ret = !wine_server_call_err( req );
    }
    SERVER_END_REQ;
    if (ret) get_user_thread_info()->desktop = 0;  /* reset the desktop window */
    return ret;
}
Exemplo n.º 9
0
/***********************************************************************
 *		UnhookWindowsHook (USER.234)
 */
BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
{
    struct hook16_queue_info *info;
    int index = id - WH_MINHOOK;

    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
    if (!(info = get_user_thread_info()->hook16_info)) return FALSE;
    if (info->proc[index] != proc) return FALSE;
    if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE;
    info->hook[index] = 0;
    info->proc[index] = 0;
    return TRUE;
}
Exemplo n.º 10
0
static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
{
    static int warned;
    HWND parent = GetAncestor( hwnd, GA_PARENT );

    /* HWND_MESSAGE windows don't need a graphics driver */
    if (!parent || parent == get_user_thread_info()->msg_window) return TRUE;
    if (warned++) return FALSE;

    ERR_(winediag)( "Application tried to create a window, but no driver could be loaded.\n" );
    if (driver_load_error[0]) ERR_(winediag)( "%s\n", driver_load_error );
    return FALSE;
}
Exemplo n.º 11
0
/***********************************************************************
 *           UnhookWinEvent                             [USER32.@]
 *
 * Remove an event hook for a set of events.
 *
 * PARAMS
 *  hEventHook [I] Event hook to remove
 *
 * RETURNS
 *  Success: TRUE. The event hook has been removed.
 *  Failure: FALSE, if hEventHook is invalid.
 */
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK hEventHook)
{
    BOOL ret;

    SERVER_START_REQ( remove_hook )
    {
        req->handle = wine_server_user_handle( hEventHook );
        req->id     = WH_WINEVENT;
        ret = !wine_server_call_err( req );
        if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
    }
    SERVER_END_REQ;
    return ret;
}
Exemplo n.º 12
0
/**********************************************************************
 *           thread_detach
 */
static void thread_detach(void)
{
    struct user_thread_info *thread_info = get_user_thread_info();

    exiting_thread_id = GetCurrentThreadId();

    WDML_NotifyThreadDetach();

    if (thread_info->top_window) WIN_DestroyThreadWindows( thread_info->top_window );
    if (thread_info->msg_window) WIN_DestroyThreadWindows( thread_info->msg_window );
    CloseHandle( thread_info->server_queue );
    HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );

    exiting_thread_id = 0;
}
Exemplo n.º 13
0
/***********************************************************************
 *		UnhookWindowsHookEx (USER32.@)
 */
BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
{
    BOOL ret;

    SERVER_START_REQ( remove_hook )
    {
        req->handle = wine_server_user_handle( hhook );
        req->id     = 0;
        ret = !wine_server_call_err( req );
        if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
    }
    SERVER_END_REQ;
    if (!ret && GetLastError() == ERROR_INVALID_HANDLE) SetLastError( ERROR_INVALID_HOOK_HANDLE );
    return ret;
}
Exemplo n.º 14
0
/***********************************************************************
 *		HOOK_CallHooks
 */
LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode )
{
    struct user_thread_info *thread_info = get_user_thread_info();
    struct hook_info info;
    DWORD_PTR ret = 0;

    USER_CheckNotLock();

    if (!HOOK_IsHooked( id ))
    {
        TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
        return 0;
    }

    ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
    info.prev_unicode = unicode;
    info.id = id;

    SERVER_START_REQ( start_hook_chain )
    {
        req->id = info.id;
        req->event = EVENT_MIN;
        wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
        if (!wine_server_call( req ))
        {
            info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
            info.handle       = wine_server_ptr_handle( reply->handle );
            info.pid          = reply->pid;
            info.tid          = reply->tid;
            info.proc         = wine_server_get_ptr( reply->proc );
            info.next_unicode = reply->unicode;
            thread_info->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;

    if (!info.tid && !info.proc) return 0;
    ret = call_hook( &info, code, wparam, lparam );

    SERVER_START_REQ( finish_hook_chain )
    {
        req->id = id;
        wine_server_call( req );
    }
    SERVER_END_REQ;
    return ret;
}
Exemplo n.º 15
0
/***********************************************************************
 *		UnhookWindowsHookEx (USER.292)
 */
BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
{
    struct hook16_queue_info *info;
    int index;

    if (!(info = get_user_thread_info()->hook16_info)) return FALSE;
    for (index = 0; index < NB_HOOKS16; index++)
    {
        if (info->hook[index] == hhook)
        {
            info->hook[index] = 0;
            info->proc[index] = 0;
            return UnhookWindowsHookEx( hhook );
        }
    }
    return FALSE;
}
Exemplo n.º 16
0
/***********************************************************************
 *		UnhookWindowsHook (USER32.@)
 */
BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
{
    BOOL ret;

    TRACE( "%s %p\n", hook_names[id-WH_MINHOOK], proc );

    SERVER_START_REQ( remove_hook )
    {
        req->handle = 0;
        req->id   = id;
        req->proc = wine_server_client_ptr( proc );
        ret = !wine_server_call_err( req );
        if (ret) get_user_thread_info()->active_hooks = reply->active_hooks;
    }
    SERVER_END_REQ;
    if (!ret && GetLastError() == ERROR_INVALID_HANDLE) SetLastError( ERROR_INVALID_HOOK_HANDLE );
    return ret;
}
Exemplo n.º 17
0
/******************************************************************************
 *              SetThreadDesktop   (USER32.@)
 */
BOOL WINAPI SetThreadDesktop( HDESK handle )
{
    BOOL ret;

    SERVER_START_REQ( set_thread_desktop )
    {
        req->handle = wine_server_obj_handle( handle );
        ret = !wine_server_call_err( req );
    }
    SERVER_END_REQ;
    if (ret)  /* reset the desktop windows */
    {
        struct user_thread_info *thread_info = get_user_thread_info();
        thread_info->top_window = 0;
        thread_info->msg_window = 0;
    }
    return ret;
}
Exemplo n.º 18
0
static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
{
    static int warned;

    /* HWND_MESSAGE windows don't need a graphics driver */
    if (GetAncestor( hwnd, GA_PARENT ) == get_user_thread_info()->msg_window) return TRUE;
    if (warned++) return FALSE;

    MESSAGE( "Application tried to create a window, but no driver could be loaded.\n");
    switch (driver_load_error)
    {
    case ERROR_MOD_NOT_FOUND:
        MESSAGE( "The X11 driver is missing.  Check your build!\n" );
        break;
    case ERROR_DLL_INIT_FAILED:
        MESSAGE( "Make sure that your X server is running and that $DISPLAY is set correctly.\n" );
        break;
    default:
        MESSAGE( "Unknown error (%d).\n", driver_load_error );
    }

    return FALSE;
}
Exemplo n.º 19
0
/***********************************************************************
 *           call_hook_16
 */
static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp )
{
    struct hook16_queue_info *info = get_user_thread_info()->hook16_info;
    WORD args[4];
    DWORD ret;
    INT prev_id = info->id;
    info->id = id;

    args[3] = code;
    args[2] = wp;
    args[1] = HIWORD(lp);
    args[0] = LOWORD(lp);
    WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret );

    info->id = prev_id;

    /* Grrr. While the hook procedure is supposed to have an LRESULT return
       value even in Win16, it seems that for those hook types where the
       return value is interpreted as BOOL, Windows doesn't actually check
       the HIWORD ...  Some buggy Win16 programs, notably WINFILE, rely on
       that, because they neglect to clear DX ... */
    if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret );
    return ret;
}
Exemplo n.º 20
0
/***********************************************************************
 *		CallNextHookEx (USER.293)
 */
LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam )
{
    struct hook16_queue_info *info;
    LRESULT ret = 0;

    if (!(info = get_user_thread_info()->hook16_info)) return 0;

    switch (info->id)
    {
    case WH_MSGFILTER:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        map_msg_16_to_32( msg16, &msg32 );
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
        break;
    }

    case WH_GETMESSAGE:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        map_msg_16_to_32( msg16, &msg32 );
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
        map_msg_32_to_16( &msg32, msg16 );
        break;
    }

    case WH_CALLWNDPROC:
    {
        CWPSTRUCT16 *cwp16 = MapSL(lparam);
        LRESULT result;
        struct wndproc_hook_params params;

        params.hhook  = hhook;
        params.code   = code;
        params.wparam = wparam;
        ret = WINPROC_CallProc16To32A( wndproc_hook_callback, cwp16->hwnd, cwp16->message,
                                       cwp16->wParam, cwp16->lParam, &result, &params );
        break;
    }

    case WH_CBT:
        switch (code)
        {
        case HCBT_CREATEWND:
            {
                CBT_CREATEWNDA cbtcw32;
                CREATESTRUCTA cs32;
                CBT_CREATEWND16 *cbtcw16 = MapSL(lparam);
                CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs );

                cbtcw32.lpcs = &cs32;
                cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter );

                cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams;
                cs32.hInstance      = HINSTANCE_32(cs16->hInstance);
                cs32.hMenu          = HMENU_32(cs16->hMenu);
                cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
                cs32.cy             = cs16->cy;
                cs32.cx             = cs16->cx;
                cs32.y              = cs16->y;
                cs32.x              = cs16->x;
                cs32.style          = cs16->style;
                cs32.lpszName       = MapSL( cs16->lpszName );
                cs32.lpszClass      = MapSL( cs16->lpszClass );
                cs32.dwExStyle      = cs16->dwExStyle;

                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 );
                cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter );
                break;
            }
        case HCBT_ACTIVATE:
            {
                CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam);
                CBTACTIVATESTRUCT cas32;
                cas32.fMouse = cas16->fMouse;
                cas32.hWndActive = WIN_Handle32(cas16->hWndActive);
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 );
                break;
            }
        case HCBT_CLICKSKIPPED:
            {
                MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
                MOUSEHOOKSTRUCT ms32;

                ms32.pt.x = ms16->pt.x;
                ms32.pt.y = ms16->pt.y;
                /* wHitTestCode may be negative, so convince compiler to do
                   correct sign extension. Yay. :| */
                ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode;
                ms32.dwExtraInfo = ms16->dwExtraInfo;
                ms32.hwnd = WIN_Handle32( ms16->hwnd );
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
                break;
            }
        case HCBT_MOVESIZE:
            {
                RECT16 *rect16 = MapSL(lparam);
                RECT rect32;

                rect32.left   = rect16->left;
                rect32.top    = rect16->top;
                rect32.right  = rect16->right;
                rect32.bottom = rect16->bottom;
                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 );
                break;
            }
        }
        break;

    case WH_MOUSE:
    {
        MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
        MOUSEHOOKSTRUCT ms32;

        ms32.pt.x = ms16->pt.x;
        ms32.pt.y = ms16->pt.y;
        /* wHitTestCode may be negative, so convince compiler to do
           correct sign extension. Yay. :| */
        ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode);
        ms32.dwExtraInfo = ms16->dwExtraInfo;
        ms32.hwnd = WIN_Handle32(ms16->hwnd);
        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
        break;
    }

    case WH_SHELL:
    case WH_KEYBOARD:
        ret = CallNextHookEx( hhook, code, wparam, lparam );
        break;

    case WH_HARDWARE:
    case WH_FOREGROUNDIDLE:
    case WH_CALLWNDPROCRET:
    case WH_SYSMSGFILTER:
    case WH_JOURNALRECORD:
    case WH_JOURNALPLAYBACK:
    default:
        FIXME("\t[%i] 16to32 translation unimplemented\n", info->id);
        ret = CallNextHookEx( hhook, code, wparam, lparam );
        break;
    }
    return ret;
}
Exemplo n.º 21
0
Arquivo: hook.c Projeto: AndreRH/wine
/***********************************************************************
 *		call_hook
 *
 * Call hook either in current thread or send message to the destination
 * thread.
 */
static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARAM lparam )
{
    DWORD_PTR ret = 0;

    if (info->tid)
    {
        struct hook_extra_info h_extra;
        h_extra.handle = info->handle;
        h_extra.lparam = lparam;

        TRACE( "calling hook in thread %04x %s code %x wp %lx lp %lx\n",
               info->tid, hook_names[info->id-WH_MINHOOK], code, wparam, lparam );

        switch(info->id)
        {
        case WH_KEYBOARD_LL:
            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_KEYBOARD_LL_HOOK,
                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
                                            get_ll_hook_timeout(), &ret );
            break;
        case WH_MOUSE_LL:
            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_MOUSE_LL_HOOK,
                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
                                            get_ll_hook_timeout(), &ret );
            break;
        default:
            ERR("Unknown hook id %d\n", info->id);
            assert(0);
            break;
        }
    }
    else if (info->proc)
    {
        struct user_thread_info *thread_info = get_user_thread_info();
        HMODULE free_module = 0;

        /*
         * Windows protects from stack overflow in recursive hook calls. Different Windows
         * allow different depths.
         */
        if (thread_info->hook_call_depth >= 25)
        {
            WARN("Too many hooks called recursively, skipping call.\n");
            return 0;
        }

        TRACE( "calling hook %p %s code %x wp %lx lp %lx module %s\n",
               info->proc, hook_names[info->id-WH_MINHOOK], code, wparam,
               lparam, debugstr_w(info->module) );

        if (!info->module[0] ||
            (info->proc = get_hook_proc( info->proc, info->module, &free_module )) != NULL)
        {
            HHOOK prev = thread_info->hook;
            BOOL prev_unicode = thread_info->hook_unicode;

            thread_info->hook = info->handle;
            thread_info->hook_unicode = info->next_unicode;
            thread_info->hook_call_depth++;
            ret = call_hook_proc( info->proc, info->id, code, wparam, lparam,
                                  info->prev_unicode, info->next_unicode );
            thread_info->hook = prev;
            thread_info->hook_unicode = prev_unicode;
            thread_info->hook_call_depth--;

            if (free_module) FreeLibrary(free_module);
        }
    }

    if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
        interlocked_xchg_add( &global_key_state_counter, 1 );  /* force refreshing the key state cache */

    return ret;
}
Exemplo n.º 22
0
/***********************************************************************
 *		set_windows_hook
 *
 * Implementation of SetWindowsHookExA and SetWindowsHookExW.
 */
static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode )
{
    HHOOK handle = 0;
    WCHAR module[MAX_PATH];
    DWORD len;

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

    if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH))
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }

    SERVER_START_REQ( set_hook )
    {
        req->id        = id;
        req->pid       = 0;
        req->tid       = tid;
        req->event_min = EVENT_MIN;
        req->event_max = EVENT_MAX;
        req->flags     = WINEVENT_INCONTEXT;
        req->unicode   = unicode;
        if (inst) /* make proc relative to the module base */
        {
            req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
            wine_server_add_data( req, module, strlenW(module) * sizeof(WCHAR) );
        }
        else req->proc = wine_server_client_ptr( proc );

        if (!wine_server_call_err( req ))
        {
            handle = wine_server_ptr_handle( reply->handle );
            get_user_thread_info()->active_hooks = reply->active_hooks;
        }
    }
    SERVER_END_REQ;

    TRACE( "%s %p %x -> %p\n", hook_names[id-WH_MINHOOK], proc, tid, handle );
    return handle;
}
Exemplo n.º 23
-1
/***********************************************************************
 *		SetWindowsHookEx (USER.291)
 */
HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask )
{
    struct user_thread_info *thread_info = get_user_thread_info();
    struct hook16_queue_info *info;
    HHOOK hook;
    int index = id - WH_MINHOOK;

    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0;
    if (!hook_procs[index])
    {
        FIXME( "hook type %d broken in Win16\n", id );
        return 0;
    }
    if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id );
    else if (hTask != GetCurrentTask())
    {
        FIXME( "setting hook (%d) on other task not supported\n", id );
        return 0;
    }

    if (!(info = thread_info->hook16_info))
    {
        if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0;
        thread_info->hook16_info = info;
    }
    if (info->hook[index])
    {
        FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id );
        return 0;
    }
    if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0;
    info->hook[index] = hook;
    info->proc[index] = proc;
    return hook;
}