cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

win32-kbd-hook.c (2986B)


      1/*
      2 * This work is licensed under the terms of the GNU GPL, version 2 or
      3 * (at your option) any later version.  See the COPYING file in the
      4 * top-level directory.
      5 *
      6 * The win32 keyboard hooking code was imported from project spice-gtk.
      7 */
      8
      9#include "qemu/osdep.h"
     10#include "sysemu/sysemu.h"
     11#include "ui/win32-kbd-hook.h"
     12
     13static Notifier win32_unhook_notifier;
     14static HHOOK win32_keyboard_hook;
     15static HWND win32_window;
     16static DWORD win32_grab;
     17
     18static LRESULT CALLBACK keyboard_hook_cb(int code, WPARAM wparam, LPARAM lparam)
     19{
     20    if  (win32_window && code == HC_ACTION && win32_window == GetFocus()) {
     21        KBDLLHOOKSTRUCT *hooked = (KBDLLHOOKSTRUCT *)lparam;
     22
     23        if (wparam != WM_KEYUP) {
     24            DWORD dwmsg = (hooked->flags << 24) |
     25                          ((hooked->scanCode & 0xff) << 16) | 1;
     26
     27            switch (hooked->vkCode) {
     28            case VK_CAPITAL:
     29                /* fall through */
     30            case VK_SCROLL:
     31                /* fall through */
     32            case VK_NUMLOCK:
     33                /* fall through */
     34            case VK_LSHIFT:
     35                /* fall through */
     36            case VK_RSHIFT:
     37                /* fall through */
     38            case VK_RCONTROL:
     39                /* fall through */
     40            case VK_LMENU:
     41                /* fall through */
     42            case VK_RMENU:
     43                break;
     44
     45            case VK_LCONTROL:
     46                /*
     47                 * When pressing AltGr, an extra VK_LCONTROL with a special
     48                 * scancode with bit 9 set is sent. Let's ignore the extra
     49                 * VK_LCONTROL, as that will make AltGr misbehave.
     50                 */
     51                if (hooked->scanCode & 0x200) {
     52                    return 1;
     53                }
     54                break;
     55
     56            default:
     57                if (win32_grab) {
     58                    SendMessage(win32_window, wparam, hooked->vkCode, dwmsg);
     59                    return 1;
     60                }
     61                break;
     62            }
     63
     64        } else {
     65            switch (hooked->vkCode) {
     66            case VK_LCONTROL:
     67                if (hooked->scanCode & 0x200) {
     68                    return 1;
     69                }
     70                break;
     71            }
     72        }
     73    }
     74
     75    return CallNextHookEx(NULL, code, wparam, lparam);
     76}
     77
     78static void keyboard_hook_unhook(Notifier *n, void *data)
     79{
     80    UnhookWindowsHookEx(win32_keyboard_hook);
     81    win32_keyboard_hook = NULL;
     82}
     83
     84void win32_kbd_set_window(void *hwnd)
     85{
     86    if (hwnd && !win32_keyboard_hook) {
     87        /* note: the installing thread must have a message loop */
     88        win32_keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_cb,
     89                                               GetModuleHandle(NULL), 0);
     90        if (win32_keyboard_hook) {
     91            win32_unhook_notifier.notify = keyboard_hook_unhook;
     92            qemu_add_exit_notifier(&win32_unhook_notifier);
     93        }
     94    }
     95
     96    win32_window = hwnd;
     97}
     98
     99void win32_kbd_set_grab(bool grab)
    100{
    101    win32_grab = grab;
    102}