Ejemplo 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;
}
Ejemplo n.º 2
0
Archivo: hook.c Proyecto: 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;
}