[WIN32K]
authorRafal Harabien <rafalh@reactos.org>
Fri, 9 Sep 2011 16:17:02 +0000 (16:17 +0000)
committerRafal Harabien <rafalh@reactos.org>
Fri, 9 Sep 2011 16:17:02 +0000 (16:17 +0000)
- Improve formating of input.c and keyboard.c

svn path=/trunk/; revision=53660

reactos/subsystems/win32/win32k/ntuser/input.c
reactos/subsystems/win32/win32k/ntuser/keyboard.c

index d0a1c30..d5e6dbb 100644 (file)
@@ -60,141 +60,141 @@ DWORD IntLastInputTick(BOOL LastInputTickSetGet);
 
 DWORD IntLastInputTick(BOOL LastInputTickSetGet)
 {
-   if (LastInputTickSetGet == TRUE)
-   {
-      LARGE_INTEGER TickCount;
-      KeQueryTickCount(&TickCount);
-      LastInputTick = MsqCalculateMessageTime(&TickCount);
-      if (gpsi) gpsi->dwLastRITEventTickCount = LastInputTick;
-   }
-   return LastInputTick;
+    if (LastInputTickSetGet == TRUE)
+    {
+        LARGE_INTEGER TickCount;
+        KeQueryTickCount(&TickCount);
+        LastInputTick = MsqCalculateMessageTime(&TickCount);
+        if (gpsi) gpsi->dwLastRITEventTickCount = LastInputTick;
+    }
+    return LastInputTick;
 }
 
 
 VOID FASTCALL DoTheScreenSaver(VOID)
 {
-   LARGE_INTEGER TickCount;
-   DWORD Test, TO;
-
-   if (gspv.iScrSaverTimeout > 0) // Zero means Off.
-   {
-      KeQueryTickCount(&TickCount);
-      Test = MsqCalculateMessageTime(&TickCount);
-      Test = Test - LastInputTick;
-      TO = 1000 * gspv.iScrSaverTimeout;
-      if (Test > TO)
-      {
-         TRACE("Screensaver Message Start! Tick %d Timeout %d \n", Test, gspv.iScrSaverTimeout);
-
-         if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
-         { 
-            if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
+    LARGE_INTEGER TickCount;
+    DWORD Test, TO;
+
+    if (gspv.iScrSaverTimeout > 0) // Zero means Off.
+    {
+        KeQueryTickCount(&TickCount);
+        Test = MsqCalculateMessageTime(&TickCount);
+        Test = Test - LastInputTick;
+        TO = 1000 * gspv.iScrSaverTimeout;
+        if (Test > TO)
+        {
+            TRACE("Screensaver Message Start! Tick %d Timeout %d \n", Test, gspv.iScrSaverTimeout);
+
+            if (ppiScrnSaver) // We are or we are not the screensaver, prevent reentry...
             {
-               ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
-               ERR("Screensaver is Idle\n");
+                if (!(ppiScrnSaver->W32PF_flags & W32PF_IDLESCREENSAVER))
+                {
+                    ppiScrnSaver->W32PF_flags |= W32PF_IDLESCREENSAVER;
+                    ERR("Screensaver is Idle\n");
+                }
             }
-         }
-         else
-         {
-            PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
-            if (ForegroundQueue && ForegroundQueue->ActiveWindow)
-               UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 1); // lParam 1 == Secure
             else
-               UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0);
-         }
-      }
-   }
+            {
+                PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
+                if (ForegroundQueue && ForegroundQueue->ActiveWindow)
+                    UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 1); // lParam 1 == Secure
+                else
+                    UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0);
+            }
+        }
+    }
 }
 
 VOID FASTCALL
 ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
 {
-   PMOUSE_INPUT_DATA mid;
-   MOUSEINPUT mi;
-   ULONG i;
-
-   ClearMouseInput(mi);
-   mi.time = 0;
-   mi.dwExtraInfo = 0;
-   for(i = 0; i < InputCount; i++)
-   {
-      mid = (Data + i);
-      mi.dx += mid->LastX;
-      mi.dy += mid->LastY;
-
-      /* Check if the mouse move is absolute */
-      if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
-      {
-         /* Set flag to convert to screen location */
-         mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
-      }
-
-      if(mid->ButtonFlags)
-      {
-         if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
-         {
-            mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
-         {
-            mi.dwFlags |= MOUSEEVENTF_LEFTUP;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
-         {
-            mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
-         {
-            mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
-         {
-            mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
-         {
-            mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
-         {
-            mi.mouseData |= XBUTTON1;
-            mi.dwFlags |= MOUSEEVENTF_XDOWN;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
-         {
-            mi.mouseData |= XBUTTON1;
-            mi.dwFlags |= MOUSEEVENTF_XUP;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
-         {
-            mi.mouseData |= XBUTTON2;
-            mi.dwFlags |= MOUSEEVENTF_XDOWN;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
-         {
-            mi.mouseData |= XBUTTON2;
-            mi.dwFlags |= MOUSEEVENTF_XUP;
-            SendMouseEvent(mi);
-         }
-         if(mid->ButtonFlags & MOUSE_WHEEL)
-         {
-            mi.mouseData = mid->ButtonData;
-            mi.dwFlags |= MOUSEEVENTF_WHEEL;
-            SendMouseEvent(mi);
-         }
-      }
-   }
-
-   SendMouseEvent(mi);
+    PMOUSE_INPUT_DATA mid;
+    MOUSEINPUT mi;
+    ULONG i;
+
+    ClearMouseInput(mi);
+    mi.time = 0;
+    mi.dwExtraInfo = 0;
+    for(i = 0; i < InputCount; i++)
+    {
+        mid = (Data + i);
+        mi.dx += mid->LastX;
+        mi.dy += mid->LastY;
+
+        /* Check if the mouse move is absolute */
+        if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
+        {
+            /* Set flag to convert to screen location */
+            mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
+        }
+
+        if(mid->ButtonFlags)
+        {
+            if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
+            {
+                mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
+            {
+                mi.dwFlags |= MOUSEEVENTF_LEFTUP;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
+            {
+                mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
+            {
+                mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
+            {
+                mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
+            {
+                mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
+            {
+                mi.mouseData |= XBUTTON1;
+                mi.dwFlags |= MOUSEEVENTF_XDOWN;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
+            {
+                mi.mouseData |= XBUTTON1;
+                mi.dwFlags |= MOUSEEVENTF_XUP;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
+            {
+                mi.mouseData |= XBUTTON2;
+                mi.dwFlags |= MOUSEEVENTF_XDOWN;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
+            {
+                mi.mouseData |= XBUTTON2;
+                mi.dwFlags |= MOUSEEVENTF_XUP;
+                SendMouseEvent(mi);
+            }
+            if(mid->ButtonFlags & MOUSE_WHEEL)
+            {
+                mi.mouseData = mid->ButtonData;
+                mi.dwFlags |= MOUSEEVENTF_WHEEL;
+                SendMouseEvent(mi);
+            }
+        }
+    }
+
+    SendMouseEvent(mi);
 }
 
 
@@ -203,117 +203,117 @@ ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
 VOID APIENTRY
 MouseThreadMain(PVOID StartContext)
 {
-   UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
-   OBJECT_ATTRIBUTES MouseObjectAttributes;
-   IO_STATUS_BLOCK Iosb;
-   NTSTATUS Status;
-   MOUSE_ATTRIBUTES MouseAttr;
-
-   KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
-                       LOW_REALTIME_PRIORITY + 3);
-
-   InitializeObjectAttributes(&MouseObjectAttributes,
-                              &MouseDeviceName,
-                              0,
-                              NULL,
-                              NULL);
-   do
-   {
-      LARGE_INTEGER DueTime;
-      KEVENT Event;
-      DueTime.QuadPart = (LONGLONG)(-10000000);
-      KeInitializeEvent(&Event, NotificationEvent, FALSE);
-      Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
-      Status = NtOpenFile(&MouseDeviceHandle,
-                       FILE_ALL_ACCESS,
-                       &MouseObjectAttributes,
-                       &Iosb,
-                       0,
-                       FILE_SYNCHRONOUS_IO_ALERT);
-   } while (!NT_SUCCESS(Status));
-
- /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
-   Status = Win32kInitWin32Thread(PsGetCurrentThread());
-   if (!NT_SUCCESS(Status))
-   {
-      ERR("Win32K: Failed making mouse thread a win32 thread.\n");
-      return; //(Status);
-   }
-
-   ptiMouse = PsGetCurrentThreadWin32Thread();
-   ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
-   TRACE("Mouse Thread 0x%x \n", ptiMouse);
-
-   KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
-                       LOW_REALTIME_PRIORITY + 3);
-
-   for(;;)
-   {
-      /*
-       * Wait to start input.
-       */
-      TRACE("Mouse Input Thread Waiting for start event\n");
-      Status = KeWaitForSingleObject(&InputThreadsStart,
-                                     0,
-                                     KernelMode,
-                                     TRUE,
-                                     NULL);
-      TRACE("Mouse Input Thread Starting...\n");
-
-      /*FIXME: Does mouse attributes need to be used for anything */
-      Status = NtDeviceIoControlFile(MouseDeviceHandle,
-                                     NULL,
-                                     NULL,
-                                     NULL,
-                                     &Iosb,
-                                     IOCTL_MOUSE_QUERY_ATTRIBUTES,
-                                     &MouseAttr, sizeof(MOUSE_ATTRIBUTES),
-                                     NULL, 0);
-      if(!NT_SUCCESS(Status))
-      {
-         TRACE("Failed to get mouse attributes\n");
-      }
-
-      /*
-       * Receive and process mouse input.
-       */
-      while(InputThreadsRunning)
-      {
-         MOUSE_INPUT_DATA MouseInput;
-         Status = NtReadFile(MouseDeviceHandle,
-                             NULL,
-                             NULL,
-                             NULL,
-                             &Iosb,
-                             &MouseInput,
-                             sizeof(MOUSE_INPUT_DATA),
-                             NULL,
-                             NULL);
-         if(Status == STATUS_ALERTED && !InputThreadsRunning)
-         {
-            break;
-         }
-         if(Status == STATUS_PENDING)
-         {
-            NtWaitForSingleObject(MouseDeviceHandle, FALSE, NULL);
-            Status = Iosb.Status;
-         }
-         if(!NT_SUCCESS(Status))
-         {
-            ERR("Win32K: Failed to read from mouse.\n");
-            return; //(Status);
-         }
-         TRACE("MouseEvent\n");
-                IntLastInputTick(TRUE);
-
-         UserEnterExclusive();
-
-         ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
-
-         UserLeave();
-      }
-      TRACE("Mouse Input Thread Stopped...\n");
-   }
+    UNICODE_STRING MouseDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
+    OBJECT_ATTRIBUTES MouseObjectAttributes;
+    IO_STATUS_BLOCK Iosb;
+    NTSTATUS Status;
+    MOUSE_ATTRIBUTES MouseAttr;
+
+    KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+                        LOW_REALTIME_PRIORITY + 3);
+
+    InitializeObjectAttributes(&MouseObjectAttributes,
+                               &MouseDeviceName,
+                               0,
+                               NULL,
+                               NULL);
+    do
+    {
+        LARGE_INTEGER DueTime;
+        KEVENT Event;
+        DueTime.QuadPart = (LONGLONG)(-10000000);
+        KeInitializeEvent(&Event, NotificationEvent, FALSE);
+        Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
+        Status = NtOpenFile(&MouseDeviceHandle,
+                            FILE_ALL_ACCESS,
+                            &MouseObjectAttributes,
+                            &Iosb,
+                            0,
+                            FILE_SYNCHRONOUS_IO_ALERT);
+    } while (!NT_SUCCESS(Status));
+
   /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
+    Status = Win32kInitWin32Thread(PsGetCurrentThread());
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed making mouse thread a win32 thread.\n");
+        return; //(Status);
+    }
+
+    ptiMouse = PsGetCurrentThreadWin32Thread();
+    ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
+    TRACE("Mouse Thread 0x%x \n", ptiMouse);
+
+    KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+                        LOW_REALTIME_PRIORITY + 3);
+
+    for(;;)
+    {
+        /*
+         * Wait to start input.
+         */
+        TRACE("Mouse Input Thread Waiting for start event\n");
+        Status = KeWaitForSingleObject(&InputThreadsStart,
+                                       0,
+                                       KernelMode,
+                                       TRUE,
+                                       NULL);
+        TRACE("Mouse Input Thread Starting...\n");
+
+        /*FIXME: Does mouse attributes need to be used for anything */
+        Status = NtDeviceIoControlFile(MouseDeviceHandle,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       &Iosb,
+                                       IOCTL_MOUSE_QUERY_ATTRIBUTES,
+                                       &MouseAttr, sizeof(MOUSE_ATTRIBUTES),
+                                       NULL, 0);
+        if(!NT_SUCCESS(Status))
+        {
+            TRACE("Failed to get mouse attributes\n");
+        }
+
+        /*
+         * Receive and process mouse input.
+         */
+        while(InputThreadsRunning)
+        {
+            MOUSE_INPUT_DATA MouseInput;
+            Status = NtReadFile(MouseDeviceHandle,
+                                NULL,
+                                NULL,
+                                NULL,
+                                &Iosb,
+                                &MouseInput,
+                                sizeof(MOUSE_INPUT_DATA),
+                                NULL,
+                                NULL);
+            if(Status == STATUS_ALERTED && !InputThreadsRunning)
+            {
+                break;
+            }
+            if(Status == STATUS_PENDING)
+            {
+                NtWaitForSingleObject(MouseDeviceHandle, FALSE, NULL);
+                Status = Iosb.Status;
+            }
+            if(!NT_SUCCESS(Status))
+            {
+                ERR("Win32K: Failed to read from mouse.\n");
+                return; //(Status);
+            }
+            TRACE("MouseEvent\n");
+            IntLastInputTick(TRUE);
+
+            UserEnterExclusive();
+
+            ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
+
+            UserLeave();
+        }
+        TRACE("Mouse Input Thread Stopped...\n");
+    }
 }
 
 /* Returns a value that indicates if the key is a modifier key, and
@@ -322,45 +322,45 @@ MouseThreadMain(PVOID StartContext)
 static UINT APIENTRY
 IntKeyboardGetModifiers(KEYBOARD_INPUT_DATA *InputData)
 {
-   if (InputData->Flags & KEY_E1)
-      return 0;
-
-   if (!(InputData->Flags & KEY_E0))
-   {
-      switch (InputData->MakeCode)
-      {
-         case 0x2a: /* left shift */
-         case 0x36: /* right shift */
-            return MOD_SHIFT;
-
-         case 0x1d: /* left control */
-            return MOD_CONTROL;
-
-         case 0x38: /* left alt */
-            return MOD_ALT;
-
-         default:
-            return 0;
-      }
-   }
-   else
-   {
-      switch (InputData->MakeCode)
-      {
-         case 0x1d: /* right control */
-            return MOD_CONTROL;
-
-         case 0x38: /* right alt */
-            return MOD_ALT;
-
-         case 0x5b: /* left gui (windows) */
-         case 0x5c: /* right gui (windows) */
-            return MOD_WIN;
-
-         default:
-            return 0;
-      }
-   }
+    if (InputData->Flags & KEY_E1)
+        return 0;
+
+    if (!(InputData->Flags & KEY_E0))
+    {
+        switch (InputData->MakeCode)
+        {
+            case 0x2a: /* left shift */
+            case 0x36: /* right shift */
+                return MOD_SHIFT;
+
+            case 0x1d: /* left control */
+                return MOD_CONTROL;
+
+            case 0x38: /* left alt */
+                return MOD_ALT;
+
+            default:
+                return 0;
+        }
+    }
+    else
+    {
+        switch (InputData->MakeCode)
+        {
+            case 0x1d: /* right control */
+                return MOD_CONTROL;
+
+            case 0x38: /* right alt */
+                return MOD_ALT;
+
+            case 0x5b: /* left gui (windows) */
+            case 0x5c: /* right gui (windows) */
+                return MOD_WIN;
+
+            default:
+                return 0;
+        }
+    }
 }
 
 /* Asks the keyboard driver to send a small table that shows which
@@ -370,51 +370,51 @@ static NTSTATUS APIENTRY
 IntKeyboardGetIndicatorTrans(HANDLE KeyboardDeviceHandle,
                              PKEYBOARD_INDICATOR_TRANSLATION *IndicatorTrans)
 {
-   NTSTATUS Status;
-   DWORD Size = 0;
-   IO_STATUS_BLOCK Block;
-   PKEYBOARD_INDICATOR_TRANSLATION Ret;
-
-   Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
-   Ret = ExAllocatePoolWithTag(PagedPool,
-                               Size,
-                               USERTAG_KBDTABLE);
-
-   while (Ret)
-   {
-      Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
-                                     NULL,
-                                     NULL,
-                                     NULL,
-                                     &Block,
-                                     IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
-                                     NULL, 0,
-                                     Ret, Size);
-
-      if (Status != STATUS_BUFFER_TOO_SMALL)
-         break;
-
-      ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
-
-      Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
-      Ret = ExAllocatePoolWithTag(PagedPool,
-                                  Size,
-                                  USERTAG_KBDTABLE);
-   }
-
-   if (!Ret)
-      return STATUS_INSUFFICIENT_RESOURCES;
-
-   if (Status != STATUS_SUCCESS)
-   {
-      ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
-      return Status;
-   }
-
-   *IndicatorTrans = Ret;
-   return Status;
+    NTSTATUS Status;
+    DWORD Size = 0;
+    IO_STATUS_BLOCK Block;
+    PKEYBOARD_INDICATOR_TRANSLATION Ret;
+
+    Size = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
+
+    Ret = ExAllocatePoolWithTag(PagedPool,
+                                Size,
+                                USERTAG_KBDTABLE);
+
+    while (Ret)
+    {
+        Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       &Block,
+                                       IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
+                                       NULL, 0,
+                                       Ret, Size);
+
+        if (Status != STATUS_BUFFER_TOO_SMALL)
+            break;
+
+        ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
+
+        Size += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
+
+        Ret = ExAllocatePoolWithTag(PagedPool,
+                                    Size,
+                                    USERTAG_KBDTABLE);
+    }
+
+    if (!Ret)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    if (Status != STATUS_SUCCESS)
+    {
+        ExFreePoolWithTag(Ret, USERTAG_KBDTABLE);
+        return Status;
+    }
+
+    *IndicatorTrans = Ret;
+    return Status;
 }
 
 /* Sends the keyboard commands to turn on/off the lights.
@@ -424,466 +424,466 @@ IntKeyboardUpdateLeds(HANDLE KeyboardDeviceHandle,
                       PKEYBOARD_INPUT_DATA KeyInput,
                       PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans)
 {
-   NTSTATUS Status;
-   UINT Count;
-   static KEYBOARD_INDICATOR_PARAMETERS Indicators;
-   IO_STATUS_BLOCK Block;
-
-   if (!IndicatorTrans)
-      return STATUS_NOT_SUPPORTED;
-
-   if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
-      return STATUS_SUCCESS;
-
-   for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
-   {
-      if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
-      {
-         Indicators.LedFlags ^=
-            IndicatorTrans->IndicatorList[Count].IndicatorFlags;
-
-         /* Update the lights on the hardware */
-
-         Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        &Block,
-                                        IOCTL_KEYBOARD_SET_INDICATORS,
-                                        &Indicators, sizeof(Indicators),
-                                        NULL, 0);
-
-         return Status;
-      }
-   }
-
-   return STATUS_SUCCESS;
+    NTSTATUS Status;
+    UINT Count;
+    static KEYBOARD_INDICATOR_PARAMETERS Indicators;
+    IO_STATUS_BLOCK Block;
+
+    if (!IndicatorTrans)
+        return STATUS_NOT_SUPPORTED;
+
+    if (KeyInput->Flags & (KEY_E0 | KEY_E1 | KEY_BREAK))
+        return STATUS_SUCCESS;
+
+    for (Count = 0; Count < IndicatorTrans->NumberOfIndicatorKeys; Count++)
+    {
+        if (KeyInput->MakeCode == IndicatorTrans->IndicatorList[Count].MakeCode)
+        {
+            Indicators.LedFlags ^=
+                IndicatorTrans->IndicatorList[Count].IndicatorFlags;
+
+            /* Update the lights on the hardware */
+
+            Status = NtDeviceIoControlFile(KeyboardDeviceHandle,
+                                           NULL,
+                                           NULL,
+                                           NULL,
+                                           &Block,
+                                           IOCTL_KEYBOARD_SET_INDICATORS,
+                                           &Indicators, sizeof(Indicators),
+                                           NULL, 0);
+
+            return Status;
+        }
+    }
+
+    return STATUS_SUCCESS;
 }
 
 static VOID APIENTRY
 IntKeyboardSendWinKeyMsg()
 {
-   PWND Window;
-   MSG Mesg;
-
-   if (!(Window = UserGetWindowObject(InputWindowStation->ShellWindow)))
-   {
-      ERR("Couldn't find window to send Windows key message!\n");
-      return;
-   }
-
-   Mesg.hwnd = InputWindowStation->ShellWindow;
-   Mesg.message = WM_SYSCOMMAND;
-   Mesg.wParam = SC_TASKLIST;
-   Mesg.lParam = 0;
-
-   /* The QS_HOTKEY is just a guess */
-   MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+    PWND Window;
+    MSG Mesg;
+
+    if (!(Window = UserGetWindowObject(InputWindowStation->ShellWindow)))
+    {
+        ERR("Couldn't find window to send Windows key message!\n");
+        return;
+    }
+
+    Mesg.hwnd = InputWindowStation->ShellWindow;
+    Mesg.message = WM_SYSCOMMAND;
+    Mesg.wParam = SC_TASKLIST;
+    Mesg.lParam = 0;
+
+    /* The QS_HOTKEY is just a guess */
+    MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
 }
 
 static VOID APIENTRY
 co_IntKeyboardSendAltKeyMsg()
 {
-   ERR("co_IntKeyboardSendAltKeyMsg\n");
+    ERR("co_IntKeyboardSendAltKeyMsg\n");
 //   co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); // This sends everything into a msg loop!
 }
 
 static VOID APIENTRY
 KeyboardThreadMain(PVOID StartContext)
 {
-   UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
-   OBJECT_ATTRIBUTES KeyboardObjectAttributes;
-   IO_STATUS_BLOCK Iosb;
-   NTSTATUS Status;
-   MSG msg;
-   PUSER_MESSAGE_QUEUE FocusQueue;
-   struct _ETHREAD *FocusThread;
-
-   PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
-   UINT ModifierState = 0;
-   USHORT LastMakeCode = 0;
-   USHORT LastFlags = 0;
-   UINT RepeatCount = 0;
-
-   InitializeObjectAttributes(&KeyboardObjectAttributes,
-                              &KeyboardDeviceName,
-                              0,
-                              NULL,
-                              NULL);
-   do
-   {
-      LARGE_INTEGER DueTime;
-      KEVENT Event;
-      DueTime.QuadPart = (LONGLONG)(-10000000);
-      KeInitializeEvent(&Event, NotificationEvent, FALSE);
-      Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
-      Status = NtOpenFile(&KeyboardDeviceHandle,
-                       FILE_ALL_ACCESS,
-                       &KeyboardObjectAttributes,
-                       &Iosb,
-                       0,
-                       FILE_SYNCHRONOUS_IO_ALERT);
-   } while (!NT_SUCCESS(Status));
-
-   /* Not sure if converting this thread to a win32 thread is such
-      a great idea. Since we're posting keyboard messages to the focus
-      window message queue, we'll be (indirectly) doing sendmessage
-      stuff from this thread (for WH_KEYBOARD_LL processing), which
-      means we need our own message queue. If keyboard messages were
-      instead queued to the system message queue, the thread removing
-      the message from the system message queue would be responsible
-      for WH_KEYBOARD_LL processing and we wouldn't need this thread
-      to be a win32 thread. */
-   Status = Win32kInitWin32Thread(PsGetCurrentThread());
-   if (!NT_SUCCESS(Status))
-   {
-      ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
-      return; //(Status);
-   }
-
-   ptiKeyboard = PsGetCurrentThreadWin32Thread();
-   ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
-   TRACE("Keyboard Thread 0x%x \n", ptiKeyboard);
-
-   KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
-                       LOW_REALTIME_PRIORITY + 3);
-
-   IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
-                                &IndicatorTrans);
-
-   for (;;)
-   {
-      /*
-       * Wait to start input.
-       */
-      TRACE( "Keyboard Input Thread Waiting for start event\n" );
-      Status = KeWaitForSingleObject(&InputThreadsStart,
-                                     0,
-                                     KernelMode,
-                                     TRUE,
-                                     NULL);
-
-      TRACE( "Keyboard Input Thread Starting...\n" );
-      /*
-       * Receive and process keyboard input.
-       */
-      while (InputThreadsRunning)
-      {
-         BOOLEAN NumKeys = 1;
-         BOOLEAN bLeftAlt;
-         KEYBOARD_INPUT_DATA KeyInput;
-         KEYBOARD_INPUT_DATA NextKeyInput;
-         LPARAM lParam = 0;
-         UINT fsModifiers, fsNextModifiers;
-         struct _ETHREAD *Thread;
-         HWND hWnd;
-         int id;
-
-         TRACE("KeyInput @ %08x\n", &KeyInput);
-
-         Status = NtReadFile (KeyboardDeviceHandle,
-                              NULL,
-                              NULL,
-                              NULL,
-                              &Iosb,
-                              &KeyInput,
-                              sizeof(KEYBOARD_INPUT_DATA),
-                              NULL,
-                              NULL);
-
-         if(Status == STATUS_ALERTED && !InputThreadsRunning)
-         {
-            break;
-         }
-         if(Status == STATUS_PENDING)
-         {
-            NtWaitForSingleObject(KeyboardDeviceHandle, FALSE, NULL);
-            Status = Iosb.Status;
-         }
-         if(!NT_SUCCESS(Status))
-         {
-            ERR("Win32K: Failed to read from keyboard.\n");
-            return; //(Status);
-         }
-
-         TRACE("KeyRaw: %s %04x\n",
-                (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
-                KeyInput.MakeCode );
-
-         if (Status == STATUS_ALERTED && !InputThreadsRunning)
-            break;
+    UNICODE_STRING KeyboardDeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
+    OBJECT_ATTRIBUTES KeyboardObjectAttributes;
+    IO_STATUS_BLOCK Iosb;
+    NTSTATUS Status;
+    MSG msg;
+    PUSER_MESSAGE_QUEUE FocusQueue;
+    struct _ETHREAD *FocusThread;
+
+    PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
+    UINT ModifierState = 0;
+    USHORT LastMakeCode = 0;
+    USHORT LastFlags = 0;
+    UINT RepeatCount = 0;
+
+    InitializeObjectAttributes(&KeyboardObjectAttributes,
+                               &KeyboardDeviceName,
+                               0,
+                               NULL,
+                               NULL);
+    do
+    {
+        LARGE_INTEGER DueTime;
+        KEVENT Event;
+        DueTime.QuadPart = (LONGLONG)(-10000000);
+        KeInitializeEvent(&Event, NotificationEvent, FALSE);
+        Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
+        Status = NtOpenFile(&KeyboardDeviceHandle,
+                            FILE_ALL_ACCESS,
+                            &KeyboardObjectAttributes,
+                            &Iosb,
+                            0,
+                            FILE_SYNCHRONOUS_IO_ALERT);
+    } while (!NT_SUCCESS(Status));
+
+    /* Not sure if converting this thread to a win32 thread is such
+       a great idea. Since we're posting keyboard messages to the focus
+       window message queue, we'll be (indirectly) doing sendmessage
+       stuff from this thread (for WH_KEYBOARD_LL processing), which
+       means we need our own message queue. If keyboard messages were
+       instead queued to the system message queue, the thread removing
+       the message from the system message queue would be responsible
+       for WH_KEYBOARD_LL processing and we wouldn't need this thread
+       to be a win32 thread. */
+    Status = Win32kInitWin32Thread(PsGetCurrentThread());
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed making keyboard thread a win32 thread.\n");
+        return; //(Status);
+    }
+
+    ptiKeyboard = PsGetCurrentThreadWin32Thread();
+    ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
+    TRACE("Keyboard Thread 0x%x \n", ptiKeyboard);
+
+    KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+                        LOW_REALTIME_PRIORITY + 3);
+
+    IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
+                                 &IndicatorTrans);
+
+    for (;;)
+    {
+        /*
+         * Wait to start input.
+         */
+        TRACE( "Keyboard Input Thread Waiting for start event\n" );
+        Status = KeWaitForSingleObject(&InputThreadsStart,
+                                       0,
+                                       KernelMode,
+                                       TRUE,
+                                       NULL);
+
+        TRACE( "Keyboard Input Thread Starting...\n" );
+        /*
+         * Receive and process keyboard input.
+         */
+        while (InputThreadsRunning)
+        {
+            BOOLEAN NumKeys = 1;
+            BOOLEAN bLeftAlt;
+            KEYBOARD_INPUT_DATA KeyInput;
+            KEYBOARD_INPUT_DATA NextKeyInput;
+            LPARAM lParam = 0;
+            UINT fsModifiers, fsNextModifiers;
+            struct _ETHREAD *Thread;
+            HWND hWnd;
+            int id;
+
+            TRACE("KeyInput @ %08x\n", &KeyInput);
+
+            Status = NtReadFile (KeyboardDeviceHandle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &Iosb,
+                                 &KeyInput,
+                                 sizeof(KEYBOARD_INPUT_DATA),
+                                 NULL,
+                                 NULL);
 
-         if (!NT_SUCCESS(Status))
-         {
-            ERR("Win32K: Failed to read from keyboard.\n");
-            return; //(Status);
-         }
+            if(Status == STATUS_ALERTED && !InputThreadsRunning)
+            {
+                break;
+            }
+            if(Status == STATUS_PENDING)
+            {
+                NtWaitForSingleObject(KeyboardDeviceHandle, FALSE, NULL);
+                Status = Iosb.Status;
+            }
+            if(!NT_SUCCESS(Status))
+            {
+                ERR("Win32K: Failed to read from keyboard.\n");
+                return; //(Status);
+            }
 
-         /* Set LastInputTick */
-         IntLastInputTick(TRUE);
+            TRACE("KeyRaw: %s %04x\n",
+                  (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
+                  KeyInput.MakeCode );
 
-         /* Update modifier state */
-         fsModifiers = IntKeyboardGetModifiers(&KeyInput);
+            if (Status == STATUS_ALERTED && !InputThreadsRunning)
+                break;
 
-         if (fsModifiers)
-         {
-            if (KeyInput.Flags & KEY_BREAK)
+            if (!NT_SUCCESS(Status))
             {
-               ModifierState &= ~fsModifiers;
-               if(fsModifiers == MOD_ALT)
-               {
-                   if(KeyInput.Flags & KEY_E0)
-                   {
-                      gKeyStateTable[VK_RMENU] = 0;
-                   }
-                   else
-                   {
-                      gKeyStateTable[VK_LMENU] = 0;
-                   }
-                   if (gKeyStateTable[VK_RMENU] == 0 &&
-                       gKeyStateTable[VK_LMENU] == 0)
-                   {
-                      gKeyStateTable[VK_MENU] = 0;
-                   }
-               }
+                ERR("Win32K: Failed to read from keyboard.\n");
+                return; //(Status);
             }
-            else
+
+            /* Set LastInputTick */
+            IntLastInputTick(TRUE);
+
+            /* Update modifier state */
+            fsModifiers = IntKeyboardGetModifiers(&KeyInput);
+
+            if (fsModifiers)
             {
-               ModifierState |= fsModifiers;
-
-               if (ModifierState == fsModifiers &&
-                     (fsModifiers == MOD_ALT || fsModifiers == MOD_WIN))
-               {
-                  /* First send out special notifications
-                   * (For alt, the message that turns on accelerator
-                   * display, not sure what for win. Both TODO though.)
-                   */
-                   bLeftAlt = FALSE;
-                   if(fsModifiers == MOD_ALT)
-                   {
-                      if(KeyInput.Flags & KEY_E0)
-                      {
-                         gKeyStateTable[VK_RMENU] = KS_DOWN_BIT;
-                      }
-                      else
-                      {
-                         gKeyStateTable[VK_LMENU] = KS_DOWN_BIT;
-                         bLeftAlt = TRUE;
-                      }
-
-                      gKeyStateTable[VK_MENU] = KS_DOWN_BIT;
-                   }
-
-                  /* Read the next key before sending this one */
-                  do
-                  {
-                     Status = NtReadFile (KeyboardDeviceHandle,
-                                          NULL,
-                                          NULL,
-                                          NULL,
-                                          &Iosb,
-                                          &NextKeyInput,
-                                          sizeof(KEYBOARD_INPUT_DATA),
-                                          NULL,
-                                          NULL);
-                     TRACE("KeyRaw: %s %04x\n",
-                            (NextKeyInput.Flags & KEY_BREAK) ? "up":"down",
-                            NextKeyInput.MakeCode );
-
-                     if (Status == STATUS_ALERTED && !InputThreadsRunning)
-                        goto KeyboardEscape;
-
-                  }
-                  while ((!(NextKeyInput.Flags & KEY_BREAK)) &&
-                         NextKeyInput.MakeCode == KeyInput.MakeCode);
-                  /* ^ Ignore repeats, they'll be KEY_MAKE and the same
-                   *   code. I'm not caring about the counting, not sure
-                   *   if that matters. I think not.
-                   */
-
-                  /* If the ModifierState is now empty again, send a
-                   * special notification and eat both keypresses
-                   */
-
-                  fsNextModifiers = IntKeyboardGetModifiers(&NextKeyInput);
-
-                  if (fsNextModifiers)
-                     ModifierState ^= fsNextModifiers;
-
-                  if (ModifierState == 0)
-                  {
-                     UserEnterExclusive();
-                     if (fsModifiers == MOD_WIN)
-                        IntKeyboardSendWinKeyMsg();
-                     else if (fsModifiers == MOD_ALT)
-                     {
-                        gKeyStateTable[VK_MENU] = 0;
-                        if(bLeftAlt)
+                if (KeyInput.Flags & KEY_BREAK)
+                {
+                    ModifierState &= ~fsModifiers;
+                    if(fsModifiers == MOD_ALT)
+                    {
+                        if(KeyInput.Flags & KEY_E0)
                         {
-                           gKeyStateTable[VK_LMENU] = 0;
+                            gKeyStateTable[VK_RMENU] = 0;
                         }
                         else
                         {
-                           gKeyStateTable[VK_RMENU] = 0;
+                            gKeyStateTable[VK_LMENU] = 0;
+                        }
+                        if (gKeyStateTable[VK_RMENU] == 0 &&
+                                gKeyStateTable[VK_LMENU] == 0)
+                        {
+                            gKeyStateTable[VK_MENU] = 0;
+                        }
+                    }
+                }
+                else
+                {
+                    ModifierState |= fsModifiers;
+
+                    if (ModifierState == fsModifiers &&
+                            (fsModifiers == MOD_ALT || fsModifiers == MOD_WIN))
+                    {
+                        /* First send out special notifications
+                         * (For alt, the message that turns on accelerator
+                         * display, not sure what for win. Both TODO though.)
+                         */
+                        bLeftAlt = FALSE;
+                        if(fsModifiers == MOD_ALT)
+                        {
+                            if(KeyInput.Flags & KEY_E0)
+                            {
+                                gKeyStateTable[VK_RMENU] = KS_DOWN_BIT;
+                            }
+                            else
+                            {
+                                gKeyStateTable[VK_LMENU] = KS_DOWN_BIT;
+                                bLeftAlt = TRUE;
+                            }
+
+                            gKeyStateTable[VK_MENU] = KS_DOWN_BIT;
                         }
-                        co_IntKeyboardSendAltKeyMsg();
-                     }
-                     UserLeave();
-                     continue;
-                  }
-
-                  NumKeys = 2;
-               }
-            }
-         }
-
-         UserEnterExclusive();
-
-         for (;NumKeys;memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
-               NumKeys--)
-         {
-            PKBL keyboardLayout = NULL;
-            lParam = 0;
-
-            IntKeyboardUpdateLeds(KeyboardDeviceHandle,
-                                  &KeyInput,
-                                  IndicatorTrans);
-
-            /* While we are working, we set up lParam. The format is:
-             *  0-15: The number of times this key has autorepeated
-             * 16-23: The keyboard scancode
-             *    24: Set if it's and extended key (I assume KEY_E0 | KEY_E1)
-             *        Note that E1 is only used for PAUSE (E1-1D-45) and
-             *        E0-45 happens not to be anything.
-             *    29: Alt is pressed ('Context code')
-             *    30: Previous state, if the key was down before this message
-             *        This is a cheap way to ignore autorepeat keys
-             *    31: 1 if the key is being pressed
-             */
-
-            /* If it's a KEY_MAKE (which is 0, so test using !KEY_BREAK)
-             * and it's the same key as the last one, increase the repeat
-             * count.
-             */
-
-            if (!(KeyInput.Flags & KEY_BREAK))
-            {
-               if (((KeyInput.Flags & (KEY_E0 | KEY_E1)) == LastFlags) &&
-                     (KeyInput.MakeCode == LastMakeCode))
-               {
-                  RepeatCount++;
-                  lParam |= (KF_REPEAT << 16);
-               }
-               else
-               {
-                  RepeatCount = 1;
-                  LastFlags = KeyInput.Flags & (KEY_E0 | KEY_E1);
-                  LastMakeCode = KeyInput.MakeCode;
-               }
-            }
-            else
-            {
-               LastFlags = 0;
-               LastMakeCode = 0; /* Should never match */
-               lParam |= (KF_UP << 16) | (KF_REPEAT << 16);
-            }
 
-            lParam |= RepeatCount;
+                        /* Read the next key before sending this one */
+                        do
+                        {
+                            Status = NtReadFile (KeyboardDeviceHandle,
+                                                 NULL,
+                                                 NULL,
+                                                 NULL,
+                                                 &Iosb,
+                                                 &NextKeyInput,
+                                                 sizeof(KEYBOARD_INPUT_DATA),
+                                                 NULL,
+                                                 NULL);
+                            TRACE("KeyRaw: %s %04x\n",
+                                  (NextKeyInput.Flags & KEY_BREAK) ? "up" : "down",
+                                  NextKeyInput.MakeCode );
+
+                            if (Status == STATUS_ALERTED && !InputThreadsRunning)
+                                goto KeyboardEscape;
 
-            lParam |= (KeyInput.MakeCode & 0xff) << 16;
+                        }
+                        while ((!(NextKeyInput.Flags & KEY_BREAK)) &&
+                                NextKeyInput.MakeCode == KeyInput.MakeCode);
+                        /* ^ Ignore repeats, they'll be KEY_MAKE and the same
+                         *   code. I'm not caring about the counting, not sure
+                         *   if that matters. I think not.
+                         */
 
-            if (KeyInput.Flags & KEY_E0)
-               lParam |= (KF_EXTENDED << 16);
+                        /* If the ModifierState is now empty again, send a
+                         * special notification and eat both keypresses
+                         */
 
-            if (ModifierState & MOD_ALT)
-            {
-               lParam |= (KF_ALTDOWN << 16);
+                        fsNextModifiers = IntKeyboardGetModifiers(&NextKeyInput);
 
-               if (!(KeyInput.Flags & KEY_BREAK))
-                  msg.message = WM_SYSKEYDOWN;
-               else
-                  msg.message = WM_SYSKEYUP;
-            }
-            else
-            {
-               if (!(KeyInput.Flags & KEY_BREAK))
-                  msg.message = WM_KEYDOWN;
-               else
-                  msg.message = WM_KEYUP;
+                        if (fsNextModifiers)
+                            ModifierState ^= fsNextModifiers;
+
+                        if (ModifierState == 0)
+                        {
+                            UserEnterExclusive();
+                            if (fsModifiers == MOD_WIN)
+                                IntKeyboardSendWinKeyMsg();
+                            else if (fsModifiers == MOD_ALT)
+                            {
+                                gKeyStateTable[VK_MENU] = 0;
+                                if(bLeftAlt)
+                                {
+                                    gKeyStateTable[VK_LMENU] = 0;
+                                }
+                                else
+                                {
+                                    gKeyStateTable[VK_RMENU] = 0;
+                                }
+                                co_IntKeyboardSendAltKeyMsg();
+                            }
+                            UserLeave();
+                            continue;
+                        }
+
+                        NumKeys = 2;
+                    }
+                }
             }
 
-            /* Find the target thread whose locale is in effect */
-            FocusQueue = IntGetFocusMessageQueue();
+            UserEnterExclusive();
 
-            if (FocusQueue)
+            for (; NumKeys; memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
+                    NumKeys--)
             {
-                msg.hwnd = FocusQueue->FocusWindow;
+                PKBL keyboardLayout = NULL;
+                lParam = 0;
+
+                IntKeyboardUpdateLeds(KeyboardDeviceHandle,
+                                      &KeyInput,
+                                      IndicatorTrans);
+
+                /* While we are working, we set up lParam. The format is:
+                 *  0-15: The number of times this key has autorepeated
+                 * 16-23: The keyboard scancode
+                 *    24: Set if it's and extended key (I assume KEY_E0 | KEY_E1)
+                 *        Note that E1 is only used for PAUSE (E1-1D-45) and
+                 *        E0-45 happens not to be anything.
+                 *    29: Alt is pressed ('Context code')
+                 *    30: Previous state, if the key was down before this message
+                 *        This is a cheap way to ignore autorepeat keys
+                 *    31: 1 if the key is being pressed
+                 */
+
+                /* If it's a KEY_MAKE (which is 0, so test using !KEY_BREAK)
+                 * and it's the same key as the last one, increase the repeat
+                 * count.
+                 */
+
+                if (!(KeyInput.Flags & KEY_BREAK))
+                {
+                    if (((KeyInput.Flags & (KEY_E0 | KEY_E1)) == LastFlags) &&
+                            (KeyInput.MakeCode == LastMakeCode))
+                    {
+                        RepeatCount++;
+                        lParam |= (KF_REPEAT << 16);
+                    }
+                    else
+                    {
+                        RepeatCount = 1;
+                        LastFlags = KeyInput.Flags & (KEY_E0 | KEY_E1);
+                        LastMakeCode = KeyInput.MakeCode;
+                    }
+                }
+                else
+                {
+                    LastFlags = 0;
+                    LastMakeCode = 0; /* Should never match */
+                    lParam |= (KF_UP << 16) | (KF_REPEAT << 16);
+                }
+
+                lParam |= RepeatCount;
+
+                lParam |= (KeyInput.MakeCode & 0xff) << 16;
 
-                FocusThread = FocusQueue->Thread;
-                if (FocusThread && FocusThread->Tcb.Win32Thread)
+                if (KeyInput.Flags & KEY_E0)
+                    lParam |= (KF_EXTENDED << 16);
+
+                if (ModifierState & MOD_ALT)
                 {
-                    keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+                    lParam |= (KF_ALTDOWN << 16);
+
+                    if (!(KeyInput.Flags & KEY_BREAK))
+                        msg.message = WM_SYSKEYDOWN;
+                    else
+                        msg.message = WM_SYSKEYUP;
+                }
+                else
+                {
+                    if (!(KeyInput.Flags & KEY_BREAK))
+                        msg.message = WM_KEYDOWN;
+                    else
+                        msg.message = WM_KEYUP;
                 }
-                if ( FocusQueue->QF_flags & QF_DIALOGACTIVE )
-                   lParam |= (KF_DLGMODE << 16);
-                if ( FocusQueue->MenuOwner )//FocusQueue->MenuState ) // MenuState needs a start flag...
-                   lParam |= (KF_MENUMODE << 16);
-            }
-            if (!keyboardLayout)
-            {
-                keyboardLayout = W32kGetDefaultKeyLayout();
-            }
 
-            msg.lParam = lParam;
-
-            /* This function uses lParam to fill wParam according to the
-             * keyboard layout in use.
-             */
-            W32kKeyProcessMessage(&msg,
-                                  keyboardLayout->KBTables,
-                                  KeyInput.Flags & KEY_E0 ? 0xE0 :
-                                  (KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
-
-            if (GetHotKey(ModifierState,
-                          msg.wParam,
-                          &Thread,
-                          &hWnd,
-                          &id))
-            {
-               if (!(KeyInput.Flags & KEY_BREAK))
-               {
-                  TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, id);
-                  MsqPostHotKeyMessage (Thread,
-                                        hWnd,
-                                        (WPARAM)id,
-                                        MAKELPARAM((WORD)ModifierState,
-                                                   (WORD)msg.wParam));
-               }
-               continue; /* Eat key up motion too */
-            }
+                /* Find the target thread whose locale is in effect */
+                FocusQueue = IntGetFocusMessageQueue();
 
-            if (!FocusQueue)
-            {
-                /* There is no focused window to receive a keyboard message */
-                continue;
-            }
-            if ( msg.wParam == VK_F10 ) // Bypass this key before it is in the queue.
-            {
-               if (msg.message == WM_KEYUP) msg.message = WM_SYSKEYUP;
-               if (msg.message == WM_KEYDOWN) msg.message = WM_SYSKEYDOWN;
+                if (FocusQueue)
+                {
+                    msg.hwnd = FocusQueue->FocusWindow;
+
+                    FocusThread = FocusQueue->Thread;
+                    if (FocusThread && FocusThread->Tcb.Win32Thread)
+                    {
+                        keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+                    }
+                    if ( FocusQueue->QF_flags & QF_DIALOGACTIVE )
+                        lParam |= (KF_DLGMODE << 16);
+                    if ( FocusQueue->MenuOwner )//FocusQueue->MenuState ) // MenuState needs a start flag...
+                        lParam |= (KF_MENUMODE << 16);
+                }
+                if (!keyboardLayout)
+                {
+                    keyboardLayout = W32kGetDefaultKeyLayout();
+                }
+
+                msg.lParam = lParam;
+
+                /* This function uses lParam to fill wParam according to the
+                 * keyboard layout in use.
+                 */
+                W32kKeyProcessMessage(&msg,
+                                      keyboardLayout->KBTables,
+                                      KeyInput.Flags & KEY_E0 ? 0xE0 :
+                                      (KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
+
+                if (GetHotKey(ModifierState,
+                              msg.wParam,
+                              &Thread,
+                              &hWnd,
+                              &id))
+                {
+                    if (!(KeyInput.Flags & KEY_BREAK))
+                    {
+                        TRACE("Hot key pressed (hWnd %lx, id %d)\n", hWnd, id);
+                        MsqPostHotKeyMessage (Thread,
+                                              hWnd,
+                                              (WPARAM)id,
+                                              MAKELPARAM((WORD)ModifierState,
+                                                         (WORD)msg.wParam));
+                    }
+                    continue; /* Eat key up motion too */
+                }
+
+                if (!FocusQueue)
+                {
+                    /* There is no focused window to receive a keyboard message */
+                    continue;
+                }
+                if ( msg.wParam == VK_F10 ) // Bypass this key before it is in the queue.
+                {
+                    if (msg.message == WM_KEYUP) msg.message = WM_SYSKEYUP;
+                    if (msg.message == WM_KEYDOWN) msg.message = WM_SYSKEYDOWN;
+                }
+                /*
+                 * Post a keyboard message.
+                 */
+                co_MsqPostKeyboardMessage(msg.message, msg.wParam, msg.lParam);
             }
-            /*
-             * Post a keyboard message.
-             */
-            co_MsqPostKeyboardMessage(msg.message,msg.wParam,msg.lParam);
-         }
 
-         UserLeave();
-      }
+            UserLeave();
+        }
 
 KeyboardEscape:
-      TRACE( "KeyboardInput Thread Stopped...\n" );
-   }
+        TRACE( "KeyboardInput Thread Stopped...\n" );
+    }
 }
 
 
@@ -895,61 +895,61 @@ static PVOID Objects[2];
 static VOID APIENTRY
 RawInputThreadMain(PVOID StartContext)
 {
-  NTSTATUS Status;
-  LARGE_INTEGER DueTime;
-
-  DueTime.QuadPart = (LONGLONG)(-10000000);
-
-  do
-  {
-      KEVENT Event;
-      KeInitializeEvent(&Event, NotificationEvent, FALSE);
-      Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
-  } while (!NT_SUCCESS(Status));
-
-
-  Objects[0] = &InputThreadsStart;
-  Objects[1] = MasterTimer;
-
-  // This thread requires win32k!
-  Status = Win32kInitWin32Thread(PsGetCurrentThread());
-  if (!NT_SUCCESS(Status))
-  {
-     ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
-     return; //(Status);
-  }
-
-  ptiRawInput = PsGetCurrentThreadWin32Thread();
-  ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
-  TRACE("Raw Input Thread 0x%x \n", ptiRawInput);
-
-  KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
-                       LOW_REALTIME_PRIORITY + 3);
-
-  UserEnterExclusive();
-  StartTheTimers();
-  UserLeave();
-
-  //
-  // ATM, we just have one job to handle, merge the other two later.
-  //
-  for(;;)
-  {
-      TRACE( "Raw Input Thread Waiting for start event\n" );
-
-      Status = KeWaitForMultipleObjects( 2,
-                                         Objects,
-                                         WaitAll, //WaitAny,
-                                         WrUserRequest,
-                                         KernelMode,
-                                         TRUE,
-                                         NULL,
-                                         NULL);
-      TRACE( "Raw Input Thread Starting...\n" );
-
-      ProcessTimers();
-  }
-  ERR("Raw Input Thread Exit!\n");
+    NTSTATUS Status;
+    LARGE_INTEGER DueTime;
+
+    DueTime.QuadPart = (LONGLONG)(-10000000);
+
+    do
+    {
+        KEVENT Event;
+        KeInitializeEvent(&Event, NotificationEvent, FALSE);
+        Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
+    } while (!NT_SUCCESS(Status));
+
+
+    Objects[0] = &InputThreadsStart;
+    Objects[1] = MasterTimer;
+
+    // This thread requires win32k!
+    Status = Win32kInitWin32Thread(PsGetCurrentThread());
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
+        return; //(Status);
+    }
+
+    ptiRawInput = PsGetCurrentThreadWin32Thread();
+    ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
+    TRACE("Raw Input Thread 0x%x \n", ptiRawInput);
+
+    KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+                        LOW_REALTIME_PRIORITY + 3);
+
+    UserEnterExclusive();
+    StartTheTimers();
+    UserLeave();
+
+    //
+    // ATM, we just have one job to handle, merge the other two later.
+    //
+    for(;;)
+    {
+        TRACE( "Raw Input Thread Waiting for start event\n" );
+
+        Status = KeWaitForMultipleObjects( 2,
+                                           Objects,
+                                           WaitAll, //WaitAny,
+                                           WrUserRequest,
+                                           KernelMode,
+                                           TRUE,
+                                           NULL,
+                                           NULL);
+        TRACE( "Raw Input Thread Starting...\n" );
+
+        ProcessTimers();
+    }
+    ERR("Raw Input Thread Exit!\n");
 }
 
 INIT_FUNCTION
@@ -957,883 +957,883 @@ NTSTATUS
 NTAPI
 InitInputImpl(VOID)
 {
-   NTSTATUS Status;
-
-   KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
-
-   MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
-   if (!MasterTimer)
-   {
-      ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
-      ASSERT(FALSE);
-      return STATUS_UNSUCCESSFUL;
-   }
-   KeInitializeTimer(MasterTimer);
-
-   /* Initialize the default keyboard layout */
-   if(!UserInitDefaultKeyboardLayout())
-   {
-      ERR("Failed to initialize default keyboard layout!\n");
-   }
-
-   Status = PsCreateSystemThread(&RawInputThreadHandle,
-                                 THREAD_ALL_ACCESS,
-                                 NULL,
-                                 NULL,
-                                 &RawInputThreadId,
-                                 RawInputThreadMain,
-                                 NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      ERR("Win32K: Failed to create raw thread.\n");
-   }
-
-   Status = PsCreateSystemThread(&KeyboardThreadHandle,
-                                 THREAD_ALL_ACCESS,
-                                 NULL,
-                                 NULL,
-                                 &KeyboardThreadId,
-                                 KeyboardThreadMain,
-                                 NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      ERR("Win32K: Failed to create keyboard thread.\n");
-   }
-
-   Status = PsCreateSystemThread(&MouseThreadHandle,
-                                 THREAD_ALL_ACCESS,
-                                 NULL,
-                                 NULL,
-                                 &MouseThreadId,
-                                 MouseThreadMain,
-                                 NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      ERR("Win32K: Failed to create mouse thread.\n");
-   }
-
-   InputThreadsRunning = TRUE;
-   KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
-
-   return STATUS_SUCCESS;
+    NTSTATUS Status;
+
+    KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
+
+    MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
+    if (!MasterTimer)
+    {
+        ERR("Win32K: Failed making Raw Input thread a win32 thread.\n");
+        ASSERT(FALSE);
+        return STATUS_UNSUCCESSFUL;
+    }
+    KeInitializeTimer(MasterTimer);
+
+    /* Initialize the default keyboard layout */
+    if(!UserInitDefaultKeyboardLayout())
+    {
+        ERR("Failed to initialize default keyboard layout!\n");
+    }
+
+    Status = PsCreateSystemThread(&RawInputThreadHandle,
+                                  THREAD_ALL_ACCESS,
+                                  NULL,
+                                  NULL,
+                                  &RawInputThreadId,
+                                  RawInputThreadMain,
+                                  NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed to create raw thread.\n");
+    }
+
+    Status = PsCreateSystemThread(&KeyboardThreadHandle,
+                                  THREAD_ALL_ACCESS,
+                                  NULL,
+                                  NULL,
+                                  &KeyboardThreadId,
+                                  KeyboardThreadMain,
+                                  NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed to create keyboard thread.\n");
+    }
+
+    Status = PsCreateSystemThread(&MouseThreadHandle,
+                                  THREAD_ALL_ACCESS,
+                                  NULL,
+                                  NULL,
+                                  &MouseThreadId,
+                                  MouseThreadMain,
+                                  NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Win32K: Failed to create mouse thread.\n");
+    }
+
+    InputThreadsRunning = TRUE;
+    KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
+
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS FASTCALL
 CleanupInputImp(VOID)
 {
-   return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 BOOL FASTCALL
 IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt)
 {
-   PTHREADINFO OldBlock;
-   ASSERT(W32Thread);
-
-   if(!W32Thread->rpdesk || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
-   {
-      /*
-       * fail blocking if exiting the thread
-       */
-
-      return FALSE;
-   }
-
-   /*
-    * FIXME - check access rights of the window station
-    *         e.g. services running in the service window station cannot block input
-    */
-   if(!ThreadHasInputAccess(W32Thread) ||
-         !IntIsActiveDesktop(W32Thread->rpdesk))
-   {
-      EngSetLastError(ERROR_ACCESS_DENIED);
-      return FALSE;
-   }
-
-   ASSERT(W32Thread->rpdesk);
-   OldBlock = W32Thread->rpdesk->BlockInputThread;
-   if(OldBlock)
-   {
-      if(OldBlock != W32Thread)
-      {
-         EngSetLastError(ERROR_ACCESS_DENIED);
-         return FALSE;
-      }
-      W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
-      return OldBlock == NULL;
-   }
-
-   W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
-   return OldBlock == NULL;
+    PTHREADINFO OldBlock;
+    ASSERT(W32Thread);
+
+    if(!W32Thread->rpdesk || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
+    {
+        /*
+         * fail blocking if exiting the thread
+         */
+
+        return FALSE;
+    }
+
+    /*
+     * FIXME - check access rights of the window station
+     *         e.g. services running in the service window station cannot block input
+     */
+    if(!ThreadHasInputAccess(W32Thread) ||
+            !IntIsActiveDesktop(W32Thread->rpdesk))
+    {
+        EngSetLastError(ERROR_ACCESS_DENIED);
+        return FALSE;
+    }
+
+    ASSERT(W32Thread->rpdesk);
+    OldBlock = W32Thread->rpdesk->BlockInputThread;
+    if(OldBlock)
+    {
+        if(OldBlock != W32Thread)
+        {
+            EngSetLastError(ERROR_ACCESS_DENIED);
+            return FALSE;
+        }
+        W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
+        return OldBlock == NULL;
+    }
+
+    W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
+    return OldBlock == NULL;
 }
 
 BOOL
 APIENTRY
 NtUserBlockInput(
-   BOOL BlockIt)
+    BOOL BlockIt)
 {
-   DECLARE_RETURN(BOOLEAN);
+    DECLARE_RETURN(BOOLEAN);
 
-   TRACE("Enter NtUserBlockInput\n");
-   UserEnterExclusive();
+    TRACE("Enter NtUserBlockInput\n");
+    UserEnterExclusive();
 
-   RETURN( IntBlockInput(PsGetCurrentThreadWin32Thread(), BlockIt));
+    RETURN( IntBlockInput(PsGetCurrentThreadWin32Thread(), BlockIt));
 
 CLEANUP:
-   TRACE("Leave NtUserBlockInput, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserBlockInput, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 BOOL FASTCALL
 IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
 {
-   const UINT SwapBtnMsg[2][2] =
-      {
-         {WM_LBUTTONDOWN, WM_RBUTTONDOWN},
-         {WM_LBUTTONUP, WM_RBUTTONUP}
-      };
-   const WPARAM SwapBtn[2] =
-      {
-         MK_LBUTTON, MK_RBUTTON
-      };
-   POINT MousePos;
-   PSYSTEM_CURSORINFO CurInfo;
-   BOOL SwapButtons;
-   MSG Msg;
-
-   ASSERT(mi);
-
-   CurInfo = IntGetSysCursorInfo();
-
-   if(!mi->time)
-   {
-      LARGE_INTEGER LargeTickCount;
-      KeQueryTickCount(&LargeTickCount);
-      mi->time = MsqCalculateMessageTime(&LargeTickCount);
-   }
-
-   SwapButtons = gspv.bMouseBtnSwap;
-
-   MousePos = gpsi->ptCursor;
-
-   if(mi->dwFlags & MOUSEEVENTF_MOVE)
-   {
-      if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
-      {
-         MousePos.x = mi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16;
-         MousePos.y = mi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16;
-      }
-      else
-      {
-         MousePos.x += mi->dx;
-         MousePos.y += mi->dy;
-      }
-   }
-
-   /*
-    * Insert the messages into the system queue
-    */
-   Msg.wParam = 0;
-   Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
-   Msg.pt = MousePos;
-
-   if (gKeyStateTable[VK_SHIFT] & KS_DOWN_BIT)
-   {
-      Msg.wParam |= MK_SHIFT;
-   }
-
-   if (gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)
-   {
-      Msg.wParam |= MK_CONTROL;
-   }
-
-   if(mi->dwFlags & MOUSEEVENTF_MOVE)
-   {
-      UserSetCursorPos(MousePos.x, MousePos.y, Injected, mi->dwExtraInfo, TRUE);
-   }
-   if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
-   {
-      gKeyStateTable[VK_LBUTTON] |= KS_DOWN_BIT;
-      Msg.message = SwapBtnMsg[0][SwapButtons];
-      CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-   else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
-   {
-      gKeyStateTable[VK_LBUTTON] &= ~KS_DOWN_BIT;
-      Msg.message = SwapBtnMsg[1][SwapButtons];
-      CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-   if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
-   {
-      gKeyStateTable[VK_MBUTTON] |= KS_DOWN_BIT;
-      Msg.message = WM_MBUTTONDOWN;
-      CurInfo->ButtonsDown |= MK_MBUTTON;
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-   else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
-   {
-      gKeyStateTable[VK_MBUTTON] &= ~KS_DOWN_BIT;
-      Msg.message = WM_MBUTTONUP;
-      CurInfo->ButtonsDown &= ~MK_MBUTTON;
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-   if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
-   {
-      gKeyStateTable[VK_RBUTTON] |= KS_DOWN_BIT;
-      Msg.message = SwapBtnMsg[0][!SwapButtons];
-      CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-   else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
-   {
-      gKeyStateTable[VK_RBUTTON] &= ~KS_DOWN_BIT;
-      Msg.message = SwapBtnMsg[1][!SwapButtons];
-      CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
-      Msg.wParam |= CurInfo->ButtonsDown;
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-
-   if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
-         (mi->dwFlags & MOUSEEVENTF_WHEEL))
-   {
-      /* fail because both types of events use the mouseData field */
-      return FALSE;
-   }
-
-   if(mi->dwFlags & MOUSEEVENTF_XDOWN)
-   {
-      Msg.message = WM_XBUTTONDOWN;
-      if(mi->mouseData & XBUTTON1)
-      {
-         gKeyStateTable[VK_XBUTTON1] |= KS_DOWN_BIT;
-         CurInfo->ButtonsDown |= MK_XBUTTON1;
-         Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
-         co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-      }
-      if(mi->mouseData & XBUTTON2)
-      {
-         gKeyStateTable[VK_XBUTTON2] |= KS_DOWN_BIT;
-         CurInfo->ButtonsDown |= MK_XBUTTON2;
-         Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
-         co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-      }
-   }
-   else if(mi->dwFlags & MOUSEEVENTF_XUP)
-   {
-      Msg.message = WM_XBUTTONUP;
-      if(mi->mouseData & XBUTTON1)
-      {
-         gKeyStateTable[VK_XBUTTON1] &= ~KS_DOWN_BIT;
-         CurInfo->ButtonsDown &= ~MK_XBUTTON1;
-         Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
-         co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-      }
-      if(mi->mouseData & XBUTTON2)
-      {
-         gKeyStateTable[VK_XBUTTON2] &= ~KS_DOWN_BIT;
-         CurInfo->ButtonsDown &= ~MK_XBUTTON2;
-         Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
-         co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-      }
-   }
-   if(mi->dwFlags & MOUSEEVENTF_WHEEL)
-   {
-      Msg.message = WM_MOUSEWHEEL;
-      Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
-      co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
-   }
-
-   return TRUE;
+    const UINT SwapBtnMsg[2][2] =
+    {
+        {WM_LBUTTONDOWN, WM_RBUTTONDOWN},
+        {WM_LBUTTONUP, WM_RBUTTONUP}
+    };
+    const WPARAM SwapBtn[2] =
+    {
+        MK_LBUTTON, MK_RBUTTON
+    };
+    POINT MousePos;
+    PSYSTEM_CURSORINFO CurInfo;
+    BOOL SwapButtons;
+    MSG Msg;
+
+    ASSERT(mi);
+
+    CurInfo = IntGetSysCursorInfo();
+
+    if(!mi->time)
+    {
+        LARGE_INTEGER LargeTickCount;
+        KeQueryTickCount(&LargeTickCount);
+        mi->time = MsqCalculateMessageTime(&LargeTickCount);
+    }
+
+    SwapButtons = gspv.bMouseBtnSwap;
+
+    MousePos = gpsi->ptCursor;
+
+    if(mi->dwFlags & MOUSEEVENTF_MOVE)
+    {
+        if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
+        {
+            MousePos.x = mi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16;
+            MousePos.y = mi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16;
+        }
+        else
+        {
+            MousePos.x += mi->dx;
+            MousePos.y += mi->dy;
+        }
+    }
+
+    /*
+     * Insert the messages into the system queue
+     */
+    Msg.wParam = 0;
+    Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
+    Msg.pt = MousePos;
+
+    if (gKeyStateTable[VK_SHIFT] & KS_DOWN_BIT)
+    {
+        Msg.wParam |= MK_SHIFT;
+    }
+
+    if (gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)
+    {
+        Msg.wParam |= MK_CONTROL;
+    }
+
+    if(mi->dwFlags & MOUSEEVENTF_MOVE)
+    {
+        UserSetCursorPos(MousePos.x, MousePos.y, Injected, mi->dwExtraInfo, TRUE);
+    }
+    if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
+    {
+        gKeyStateTable[VK_LBUTTON] |= KS_DOWN_BIT;
+        Msg.message = SwapBtnMsg[0][SwapButtons];
+        CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+    else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
+    {
+        gKeyStateTable[VK_LBUTTON] &= ~KS_DOWN_BIT;
+        Msg.message = SwapBtnMsg[1][SwapButtons];
+        CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+    if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
+    {
+        gKeyStateTable[VK_MBUTTON] |= KS_DOWN_BIT;
+        Msg.message = WM_MBUTTONDOWN;
+        CurInfo->ButtonsDown |= MK_MBUTTON;
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+    else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
+    {
+        gKeyStateTable[VK_MBUTTON] &= ~KS_DOWN_BIT;
+        Msg.message = WM_MBUTTONUP;
+        CurInfo->ButtonsDown &= ~MK_MBUTTON;
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+    if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
+    {
+        gKeyStateTable[VK_RBUTTON] |= KS_DOWN_BIT;
+        Msg.message = SwapBtnMsg[0][!SwapButtons];
+        CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+    else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
+    {
+        gKeyStateTable[VK_RBUTTON] &= ~KS_DOWN_BIT;
+        Msg.message = SwapBtnMsg[1][!SwapButtons];
+        CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
+        Msg.wParam |= CurInfo->ButtonsDown;
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+
+    if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
+            (mi->dwFlags & MOUSEEVENTF_WHEEL))
+    {
+        /* fail because both types of events use the mouseData field */
+        return FALSE;
+    }
+
+    if(mi->dwFlags & MOUSEEVENTF_XDOWN)
+    {
+        Msg.message = WM_XBUTTONDOWN;
+        if(mi->mouseData & XBUTTON1)
+        {
+            gKeyStateTable[VK_XBUTTON1] |= KS_DOWN_BIT;
+            CurInfo->ButtonsDown |= MK_XBUTTON1;
+            Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
+            co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+        }
+        if(mi->mouseData & XBUTTON2)
+        {
+            gKeyStateTable[VK_XBUTTON2] |= KS_DOWN_BIT;
+            CurInfo->ButtonsDown |= MK_XBUTTON2;
+            Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
+            co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+        }
+    }
+    else if(mi->dwFlags & MOUSEEVENTF_XUP)
+    {
+        Msg.message = WM_XBUTTONUP;
+        if(mi->mouseData & XBUTTON1)
+        {
+            gKeyStateTable[VK_XBUTTON1] &= ~KS_DOWN_BIT;
+            CurInfo->ButtonsDown &= ~MK_XBUTTON1;
+            Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
+            co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+        }
+        if(mi->mouseData & XBUTTON2)
+        {
+            gKeyStateTable[VK_XBUTTON2] &= ~KS_DOWN_BIT;
+            CurInfo->ButtonsDown &= ~MK_XBUTTON2;
+            Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
+            co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+        }
+    }
+    if(mi->dwFlags & MOUSEEVENTF_WHEEL)
+    {
+        Msg.message = WM_MOUSEWHEEL;
+        Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
+        co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo, TRUE);
+    }
+
+    return TRUE;
 }
 
 BOOL FASTCALL
 IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
 {
-   PUSER_MESSAGE_QUEUE FocusMessageQueue;
-   MSG Msg;
-   LARGE_INTEGER LargeTickCount;
-   KBDLLHOOKSTRUCT KbdHookData;
-   WORD flags, wVkStripped, wVkL, wVkR, wVk = ki->wVk, vk_hook = ki->wVk;
-
-   Msg.lParam = 0;
-
-   // Condition may arise when calling MsqPostMessage and waiting for an event.
-   ASSERT (UserIsEntered());
-
-   wVk = LOBYTE(wVk);
-   Msg.wParam = wVk;
-   flags = LOBYTE(ki->wScan);
-
-   FocusMessageQueue = IntGetFocusMessageQueue();
-
-   if (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
-   /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
-   if ( FocusMessageQueue && FocusMessageQueue->QF_flags & QF_DIALOGACTIVE )
-      flags |= KF_DLGMODE;
-   if ( FocusMessageQueue && FocusMessageQueue->MenuOwner )//FocusMessageQueue->MenuState ) // MenuState needs a start flag...
-      flags |= KF_MENUMODE;
-
-   /* strip left/right for menu, control, shift */
-   switch (wVk)
-   {
-   case VK_MENU:
-   case VK_LMENU:
-   case VK_RMENU:
-      wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
-      wVkStripped = VK_MENU;
-      wVkL = VK_LMENU;
-      wVkR = VK_RMENU;
-      break;
-   case VK_CONTROL:
-   case VK_LCONTROL:
-   case VK_RCONTROL:
-      wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
-      wVkStripped = VK_CONTROL;
-      wVkL = VK_LCONTROL;
-      wVkR = VK_RCONTROL;
-      break;
-   case VK_SHIFT:
-   case VK_LSHIFT:
-   case VK_RSHIFT:
-      wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
-      wVkStripped = VK_SHIFT;
-      wVkL = VK_LSHIFT;
-      wVkR = VK_RSHIFT;
-      break;
-   default:
-      wVkStripped = wVkL = wVkR = wVk;
-   }
-
-   if (ki->dwFlags & KEYEVENTF_KEYUP)
-   {
-      Msg.message = WM_KEYUP;
-      if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT) &&
-          ((wVkStripped == VK_MENU) || (wVkStripped == VK_CONTROL)
-           || !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)))
-          || (wVkStripped == VK_F10))
-      {
-         if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
-             (wVkStripped != VK_MENU)) /* <ALT>-down...<something else>-up */
-             Msg.message = WM_SYSKEYUP;
-         TrackSysKey = 0;
-      }
-      flags |= KF_REPEAT | KF_UP;
-   }
-   else
-   {
-      Msg.message = WM_KEYDOWN;
-      if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT || wVkStripped == VK_MENU) &&
-          !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT || wVkStripped == VK_CONTROL))
-          || (wVkStripped == VK_F10))
-      {
-         Msg.message = WM_SYSKEYDOWN;
-         TrackSysKey = wVkStripped;
-      }
-      if (!(ki->dwFlags & KEYEVENTF_UNICODE) && gKeyStateTable[wVk] & KS_DOWN_BIT) flags |= KF_REPEAT;
-   }
-
-   if (ki->dwFlags & KEYEVENTF_UNICODE)
-   {
-      vk_hook = Msg.wParam = wVk = VK_PACKET;
-      Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
-   }
-
-   if (!(ki->dwFlags & KEYEVENTF_UNICODE))
-   {
-      if (ki->dwFlags & KEYEVENTF_KEYUP)
-      {
-         gKeyStateTable[wVk] &= ~KS_DOWN_BIT;
-         gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
-      }
-      else
-      {
-         if (!(gKeyStateTable[wVk] & KS_DOWN_BIT)) gKeyStateTable[wVk] ^= KS_LOCK_BIT;
-         gKeyStateTable[wVk] |= KS_DOWN_BIT;
-         gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
-      }
-
-      if (gKeyStateTable[VK_MENU] & KS_DOWN_BIT) flags |= KF_ALTDOWN;
-
-      if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
-
-      Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
-   }
-
-   Msg.hwnd = 0;
-
-   if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
-       Msg.hwnd = FocusMessageQueue->FocusWindow;
-
-   if (!ki->time)
-   {
-      KeQueryTickCount(&LargeTickCount);
-      Msg.time = MsqCalculateMessageTime(&LargeTickCount);
-   }
-   else
-      Msg.time = ki->time;
-
-   /* All messages have to contain the cursor point. */
-   Msg.pt = gpsi->ptCursor;
-
-   KbdHookData.vkCode = vk_hook;
-   KbdHookData.scanCode = ki->wScan;
-   KbdHookData.flags = (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
-   if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
-   KbdHookData.time = Msg.time;
-   KbdHookData.dwExtraInfo = ki->dwExtraInfo;
-   if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
-   {
-      ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
-             Msg.message, vk_hook, Msg.lParam);
-
-      return FALSE;
-   }
-
-   if (FocusMessageQueue == NULL)
-   {
-         TRACE("No focus message queue\n");
-
-         return FALSE;
-   }
-
-   if (FocusMessageQueue->FocusWindow != (HWND)0)
-   {
-         Msg.hwnd = FocusMessageQueue->FocusWindow;
-         TRACE("Msg.hwnd = %x\n", Msg.hwnd);
-
-         FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
-
-      // Post to hardware queue, based on the first part of wine "some GetMessage tests"
-      // in test_PeekMessage()
-         MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
-   }
-   else
-   {
-         TRACE("Invalid focus window handle\n");
-   }
-
-   return TRUE;
-}
+    PUSER_MESSAGE_QUEUE FocusMessageQueue;
+    MSG Msg;
+    LARGE_INTEGER LargeTickCount;
+    KBDLLHOOKSTRUCT KbdHookData;
+    WORD flags, wVkStripped, wVkL, wVkR, wVk = ki->wVk, vk_hook = ki->wVk;
+
+    Msg.lParam = 0;
+
+    // Condition may arise when calling MsqPostMessage and waiting for an event.
+    ASSERT (UserIsEntered());
+
+    wVk = LOBYTE(wVk);
+    Msg.wParam = wVk;
+    flags = LOBYTE(ki->wScan);
+
+    FocusMessageQueue = IntGetFocusMessageQueue();
+
+    if (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
+    /* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
+    if ( FocusMessageQueue && FocusMessageQueue->QF_flags & QF_DIALOGACTIVE )
+        flags |= KF_DLGMODE;
+    if ( FocusMessageQueue && FocusMessageQueue->MenuOwner )//FocusMessageQueue->MenuState ) // MenuState needs a start flag...
+        flags |= KF_MENUMODE;
+
+    /* strip left/right for menu, control, shift */
+    switch (wVk)
+    {
+        case VK_MENU:
+        case VK_LMENU:
+        case VK_RMENU:
+            wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RMENU : VK_LMENU;
+            wVkStripped = VK_MENU;
+            wVkL = VK_LMENU;
+            wVkR = VK_RMENU;
+            break;
+        case VK_CONTROL:
+        case VK_LCONTROL:
+        case VK_RCONTROL:
+            wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RCONTROL : VK_LCONTROL;
+            wVkStripped = VK_CONTROL;
+            wVkL = VK_LCONTROL;
+            wVkR = VK_RCONTROL;
+            break;
+        case VK_SHIFT:
+        case VK_LSHIFT:
+        case VK_RSHIFT:
+            wVk = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) ? VK_RSHIFT : VK_LSHIFT;
+            wVkStripped = VK_SHIFT;
+            wVkL = VK_LSHIFT;
+            wVkR = VK_RSHIFT;
+            break;
+        default:
+            wVkStripped = wVkL = wVkR = wVk;
+    }
+
+    if (ki->dwFlags & KEYEVENTF_KEYUP)
+    {
+        Msg.message = WM_KEYUP;
+        if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT) &&
+                ((wVkStripped == VK_MENU) || (wVkStripped == VK_CONTROL)
+                 || !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT)))
+                || (wVkStripped == VK_F10))
+        {
+            if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
+                    (wVkStripped != VK_MENU)) /* <ALT>-down...<something else>-up */
+                Msg.message = WM_SYSKEYUP;
+            TrackSysKey = 0;
+        }
+        flags |= KF_REPEAT | KF_UP;
+    }
+    else
+    {
+        Msg.message = WM_KEYDOWN;
+        if (((gKeyStateTable[VK_MENU] & KS_DOWN_BIT || wVkStripped == VK_MENU) &&
+                !(gKeyStateTable[VK_CONTROL] & KS_DOWN_BIT || wVkStripped == VK_CONTROL))
+                || (wVkStripped == VK_F10))
+        {
+            Msg.message = WM_SYSKEYDOWN;
+            TrackSysKey = wVkStripped;
+        }
+        if (!(ki->dwFlags & KEYEVENTF_UNICODE) && gKeyStateTable[wVk] & KS_DOWN_BIT) flags |= KF_REPEAT;
+    }
+
+    if (ki->dwFlags & KEYEVENTF_UNICODE)
+    {
+        vk_hook = Msg.wParam = wVk = VK_PACKET;
+        Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
+    }
+
+    if (!(ki->dwFlags & KEYEVENTF_UNICODE))
+    {
+        if (ki->dwFlags & KEYEVENTF_KEYUP)
+        {
+            gKeyStateTable[wVk] &= ~KS_DOWN_BIT;
+            gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
+        }
+        else
+        {
+            if (!(gKeyStateTable[wVk] & KS_DOWN_BIT)) gKeyStateTable[wVk] ^= KS_LOCK_BIT;
+            gKeyStateTable[wVk] |= KS_DOWN_BIT;
+            gKeyStateTable[wVkStripped] = gKeyStateTable[wVkL] | gKeyStateTable[wVkR];
+        }
 
-BOOL FASTCALL
-UserAttachThreadInput( PTHREADINFO pti, PTHREADINFO ptiTo, BOOL fAttach)
-{
-   PATTACHINFO pai;
+        if (gKeyStateTable[VK_MENU] & KS_DOWN_BIT) flags |= KF_ALTDOWN;
+
+        if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
+
+        Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
+    }
 
-   /* Can not be the same thread.*/
-   if (pti == ptiTo) return FALSE;
+    Msg.hwnd = 0;
 
-   /* Do not attach to system threads or between different desktops. */
-   if ( pti->TIF_flags & TIF_DONTATTACHQUEUE ||
-        ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
-        pti->rpdesk != ptiTo->rpdesk )
-      return FALSE;
+    if (FocusMessageQueue && (FocusMessageQueue->FocusWindow != (HWND)0))
+        Msg.hwnd = FocusMessageQueue->FocusWindow;
 
-   /* If Attach set, allocate and link. */
-   if ( fAttach )
-   {
-      pai = ExAllocatePoolWithTag(PagedPool, sizeof(ATTACHINFO), USERTAG_ATTACHINFO);
-      if ( !pai ) return FALSE;
+    if (!ki->time)
+    {
+        KeQueryTickCount(&LargeTickCount);
+        Msg.time = MsqCalculateMessageTime(&LargeTickCount);
+    }
+    else
+        Msg.time = ki->time;
 
-      pai->paiNext = gpai;
-      pai->pti1 = pti;
-      pai->pti2 = ptiTo;
-      gpai = pai;
-   }
-   else /* If clear, unlink and free it. */
-   {
-      PATTACHINFO paiprev = NULL;
+    /* All messages have to contain the cursor point. */
+    Msg.pt = gpsi->ptCursor;
 
-      if ( !gpai ) return FALSE;
+    KbdHookData.vkCode = vk_hook;
+    KbdHookData.scanCode = ki->wScan;
+    KbdHookData.flags = (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
+    if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
+    KbdHookData.time = Msg.time;
+    KbdHookData.dwExtraInfo = ki->dwExtraInfo;
+    if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
+    {
+        ERR("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+            Msg.message, vk_hook, Msg.lParam);
 
-      pai = gpai;
+        return FALSE;
+    }
 
-      /* Search list and free if found or return false. */
-      do
-      {
-        if ( pai->pti2 == ptiTo && pai->pti1 == pti ) break;
-        paiprev = pai;
-        pai = pai->paiNext;
-      } while (pai);
+    if (FocusMessageQueue == NULL)
+    {
+        TRACE("No focus message queue\n");
 
-      if ( !pai ) return FALSE;
+        return FALSE;
+    }
 
-      if (paiprev) paiprev->paiNext = pai->paiNext;
+    if (FocusMessageQueue->FocusWindow != (HWND)0)
+    {
+        Msg.hwnd = FocusMessageQueue->FocusWindow;
+        TRACE("Msg.hwnd = %x\n", Msg.hwnd);
 
-      ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
-  }
+        FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
 
-  return TRUE;
+        // Post to hardware queue, based on the first part of wine "some GetMessage tests"
+        // in test_PeekMessage()
+        MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
+    }
+    else
+    {
+        TRACE("Invalid focus window handle\n");
+    }
+
+    return TRUE;
+}
+
+BOOL FASTCALL
+UserAttachThreadInput( PTHREADINFO pti, PTHREADINFO ptiTo, BOOL fAttach)
+{
+    PATTACHINFO pai;
+
+    /* Can not be the same thread.*/
+    if (pti == ptiTo) return FALSE;
+
+    /* Do not attach to system threads or between different desktops. */
+    if ( pti->TIF_flags & TIF_DONTATTACHQUEUE ||
+            ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
+            pti->rpdesk != ptiTo->rpdesk )
+        return FALSE;
+
+    /* If Attach set, allocate and link. */
+    if ( fAttach )
+    {
+        pai = ExAllocatePoolWithTag(PagedPool, sizeof(ATTACHINFO), USERTAG_ATTACHINFO);
+        if ( !pai ) return FALSE;
+
+        pai->paiNext = gpai;
+        pai->pti1 = pti;
+        pai->pti2 = ptiTo;
+        gpai = pai;
+    }
+    else /* If clear, unlink and free it. */
+    {
+        PATTACHINFO paiprev = NULL;
+
+        if ( !gpai ) return FALSE;
+
+        pai = gpai;
+
+        /* Search list and free if found or return false. */
+        do
+        {
+            if ( pai->pti2 == ptiTo && pai->pti1 == pti ) break;
+            paiprev = pai;
+            pai = pai->paiNext;
+        } while (pai);
+
+        if ( !pai ) return FALSE;
+
+        if (paiprev) paiprev->paiNext = pai->paiNext;
+
+        ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
+    }
+
+    return TRUE;
 }
 
 UINT
 APIENTRY
 NtUserSendInput(
-   UINT nInputs,
-   LPINPUT pInput,
-   INT cbSize)
+    UINT nInputs,
+    LPINPUT pInput,
+    INT cbSize)
 {
-   PTHREADINFO W32Thread;
-   UINT cnt;
-   DECLARE_RETURN(UINT);
-
-   TRACE("Enter NtUserSendInput\n");
-   UserEnterExclusive();
-
-   W32Thread = PsGetCurrentThreadWin32Thread();
-   ASSERT(W32Thread);
-
-   if(!W32Thread->rpdesk)
-   {
-      RETURN( 0);
-   }
-
-   if(!nInputs || !pInput || (cbSize != sizeof(INPUT)))
-   {
-      EngSetLastError(ERROR_INVALID_PARAMETER);
-      RETURN( 0);
-   }
-
-   /*
-    * FIXME - check access rights of the window station
-    *         e.g. services running in the service window station cannot block input
-    */
-   if(!ThreadHasInputAccess(W32Thread) ||
-         !IntIsActiveDesktop(W32Thread->rpdesk))
-   {
-      EngSetLastError(ERROR_ACCESS_DENIED);
-      RETURN( 0);
-   }
-
-   cnt = 0;
-   while(nInputs--)
-   {
-      INPUT SafeInput;
-      NTSTATUS Status;
-
-      Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
-      if(!NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         RETURN( cnt);
-      }
-
-      switch(SafeInput.type)
-      {
-         case INPUT_MOUSE:
-            if(IntMouseInput(&SafeInput.mi, TRUE))
-            {
-               cnt++;
-            }
-            break;
-         case INPUT_KEYBOARD:
-            if(IntKeyboardInput(&SafeInput.ki, TRUE))
-            {
-               cnt++;
-            }
-            break;
-         case INPUT_HARDWARE:
-            break;
+    PTHREADINFO W32Thread;
+    UINT cnt;
+    DECLARE_RETURN(UINT);
+
+    TRACE("Enter NtUserSendInput\n");
+    UserEnterExclusive();
+
+    W32Thread = PsGetCurrentThreadWin32Thread();
+    ASSERT(W32Thread);
+
+    if(!W32Thread->rpdesk)
+    {
+        RETURN( 0);
+    }
+
+    if(!nInputs || !pInput || (cbSize != sizeof(INPUT)))
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        RETURN( 0);
+    }
+
+    /*
+     * FIXME - check access rights of the window station
+     *         e.g. services running in the service window station cannot block input
+     */
+    if(!ThreadHasInputAccess(W32Thread) ||
+            !IntIsActiveDesktop(W32Thread->rpdesk))
+    {
+        EngSetLastError(ERROR_ACCESS_DENIED);
+        RETURN( 0);
+    }
+
+    cnt = 0;
+    while(nInputs--)
+    {
+        INPUT SafeInput;
+        NTSTATUS Status;
+
+        Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
+        if(!NT_SUCCESS(Status))
+        {
+            SetLastNtError(Status);
+            RETURN( cnt);
+        }
+
+        switch(SafeInput.type)
+        {
+            case INPUT_MOUSE:
+                if(IntMouseInput(&SafeInput.mi, TRUE))
+                {
+                    cnt++;
+                }
+                break;
+            case INPUT_KEYBOARD:
+                if(IntKeyboardInput(&SafeInput.ki, TRUE))
+                {
+                    cnt++;
+                }
+                break;
+            case INPUT_HARDWARE:
+                break;
 #ifndef NDEBUG
 
-         default:
-            ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
-            break;
+            default:
+                ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
+                break;
 #endif
 
-      }
-   }
+        }
+    }
 
-   RETURN( cnt);
+    RETURN( cnt);
 
 CLEANUP:
-   TRACE("Leave NtUserSendInput, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserSendInput, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 BOOL
 FASTCALL
 IntQueryTrackMouseEvent(
-   LPTRACKMOUSEEVENT lpEventTrack)
+    LPTRACKMOUSEEVENT lpEventTrack)
 {
-   PDESKTOP pDesk;
-   PTHREADINFO pti;
-
-   pti = PsGetCurrentThreadWin32Thread();
-   pDesk = pti->rpdesk;
-
-   /* Always cleared with size set and return true. */
-   RtlZeroMemory(lpEventTrack ,sizeof(TRACKMOUSEEVENT));
-   lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT);
-
-   if ( pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) &&
-        pDesk->spwndTrack &&
-        pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue )
-   {
-      if ( pDesk->htEx != HTCLIENT )
-         lpEventTrack->dwFlags |= TME_NONCLIENT;
-
-      if ( pDesk->dwDTFlags & DF_TME_LEAVE )
-         lpEventTrack->dwFlags |= TME_LEAVE;
-
-      if ( pDesk->dwDTFlags & DF_TME_HOVER )
-      {
-         lpEventTrack->dwFlags |= TME_HOVER;
-         lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime;
-      }
-      lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack);
-   }
-   return TRUE;
+    PDESKTOP pDesk;
+    PTHREADINFO pti;
+
+    pti = PsGetCurrentThreadWin32Thread();
+    pDesk = pti->rpdesk;
+
+    /* Always cleared with size set and return true. */
+    RtlZeroMemory(lpEventTrack , sizeof(TRACKMOUSEEVENT));
+    lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT);
+
+    if ( pDesk->dwDTFlags & (DF_TME_LEAVE | DF_TME_HOVER) &&
+            pDesk->spwndTrack &&
+            pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue )
+    {
+        if ( pDesk->htEx != HTCLIENT )
+            lpEventTrack->dwFlags |= TME_NONCLIENT;
+
+        if ( pDesk->dwDTFlags & DF_TME_LEAVE )
+            lpEventTrack->dwFlags |= TME_LEAVE;
+
+        if ( pDesk->dwDTFlags & DF_TME_HOVER )
+        {
+            lpEventTrack->dwFlags |= TME_HOVER;
+            lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime;
+        }
+        lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack);
+    }
+    return TRUE;
 }
 
 BOOL
 FASTCALL
 IntTrackMouseEvent(
-   LPTRACKMOUSEEVENT lpEventTrack)
+    LPTRACKMOUSEEVENT lpEventTrack)
 {
-   PDESKTOP pDesk;
-   PTHREADINFO pti;
-   PWND pWnd;
-   POINT point;
-
-   pti = PsGetCurrentThreadWin32Thread();
-   pDesk = pti->rpdesk;
-
-   if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
-      return FALSE;
-
-   if ( pDesk->spwndTrack != pWnd ||
-       (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) )
-   {
-      if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) )
-      {
-         UserPostMessage( lpEventTrack->hwndTrack,
-                          lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
-                          0, 0);
-      }
-      TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack,pWnd);
-      return TRUE;
-   }
-
-   /* Tracking spwndTrack same as pWnd */
-   if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
-   {
-      if ( lpEventTrack->dwFlags & TME_LEAVE )
-         pDesk->dwDTFlags &= ~DF_TME_LEAVE;
-
-      if ( lpEventTrack->dwFlags & TME_HOVER )
-      {
-         if ( pDesk->dwDTFlags & DF_TME_HOVER )
-         { // Kill hover timer.
-            IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
-            pDesk->dwDTFlags &= ~DF_TME_HOVER;
-         }
-      }
-   }
-   else // Not Canceled.
-   {
-      if ( lpEventTrack->dwFlags & TME_LEAVE )
-         pDesk->dwDTFlags |= DF_TME_LEAVE;
-
-      if ( lpEventTrack->dwFlags & TME_HOVER )
-      {
-         pDesk->dwDTFlags |= DF_TME_HOVER;
-
-         if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT )
-            pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out.
-         else
-            pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime;
-         // Start timer for the hover period.
-         IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM);
-         // Get windows thread message points.
-         point = pWnd->head.pti->ptLast;
-         // Set desktop mouse hover from the system default hover rectangle.
-         RECTL_vSetRect(&pDesk->rcMouseHover,
-                         point.x - gspv.iMouseHoverWidth  / 2,
-                         point.y - gspv.iMouseHoverHeight / 2,
-                         point.x + gspv.iMouseHoverWidth  / 2,
-                         point.y + gspv.iMouseHoverHeight / 2);
-      }
-   }
-   return TRUE;
+    PDESKTOP pDesk;
+    PTHREADINFO pti;
+    PWND pWnd;
+    POINT point;
+
+    pti = PsGetCurrentThreadWin32Thread();
+    pDesk = pti->rpdesk;
+
+    if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
+        return FALSE;
+
+    if ( pDesk->spwndTrack != pWnd ||
+            (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) )
+    {
+        if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) )
+        {
+            UserPostMessage( lpEventTrack->hwndTrack,
+                             lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
+                             0, 0);
+        }
+        TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack, pWnd);
+        return TRUE;
+    }
+
+    /* Tracking spwndTrack same as pWnd */
+    if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
+    {
+        if ( lpEventTrack->dwFlags & TME_LEAVE )
+            pDesk->dwDTFlags &= ~DF_TME_LEAVE;
+
+        if ( lpEventTrack->dwFlags & TME_HOVER )
+        {
+            if ( pDesk->dwDTFlags & DF_TME_HOVER )
+            {   // Kill hover timer.
+                IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
+                pDesk->dwDTFlags &= ~DF_TME_HOVER;
+            }
+        }
+    }
+    else // Not Canceled.
+    {
+        if ( lpEventTrack->dwFlags & TME_LEAVE )
+            pDesk->dwDTFlags |= DF_TME_LEAVE;
+
+        if ( lpEventTrack->dwFlags & TME_HOVER )
+        {
+            pDesk->dwDTFlags |= DF_TME_HOVER;
+
+            if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT )
+                pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out.
+            else
+                pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime;
+            // Start timer for the hover period.
+            IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM);
+            // Get windows thread message points.
+            point = pWnd->head.pti->ptLast;
+            // Set desktop mouse hover from the system default hover rectangle.
+            RECTL_vSetRect(&pDesk->rcMouseHover,
+                           point.x - gspv.iMouseHoverWidth  / 2,
+                           point.y - gspv.iMouseHoverHeight / 2,
+                           point.x + gspv.iMouseHoverWidth  / 2,
+                           point.y + gspv.iMouseHoverHeight / 2);
+        }
+    }
+    return TRUE;
 }
 
 BOOL
 APIENTRY
 NtUserTrackMouseEvent(
-   LPTRACKMOUSEEVENT lpEventTrack)
+    LPTRACKMOUSEEVENT lpEventTrack)
 {
-   TRACKMOUSEEVENT saveTME;
-   BOOL Ret = FALSE;
-
-   TRACE("Enter NtUserTrackMouseEvent\n");
-   UserEnterExclusive();
-
-   _SEH2_TRY
-   {
-      ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
-      RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT));
-   }
-   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-   {
-      SetLastNtError(_SEH2_GetExceptionCode());
-      _SEH2_YIELD(goto Exit;)
-   }
-   _SEH2_END;
-
-   if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) )
-   {
-      EngSetLastError(ERROR_INVALID_PARAMETER);
-      goto Exit;
-   }
-
-   if (saveTME.dwFlags & ~(TME_CANCEL|TME_QUERY|TME_NONCLIENT|TME_LEAVE|TME_HOVER) )
-   {
-      EngSetLastError(ERROR_INVALID_FLAGS);
-      goto Exit;
-   }
-
-   if ( saveTME.dwFlags & TME_QUERY )
-   {
-      Ret = IntQueryTrackMouseEvent(&saveTME);
-      _SEH2_TRY
-      {
-         ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
-         RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT));
-      }
-      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-      {
-         SetLastNtError(_SEH2_GetExceptionCode());
-         Ret = FALSE;
-      }
-      _SEH2_END;
-   }
-   else
-   {
-      Ret = IntTrackMouseEvent(&saveTME);
-   }
-   
+    TRACKMOUSEEVENT saveTME;
+    BOOL Ret = FALSE;
+
+    TRACE("Enter NtUserTrackMouseEvent\n");
+    UserEnterExclusive();
+
+    _SEH2_TRY
+    {
+        ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
+        RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastNtError(_SEH2_GetExceptionCode());
+        _SEH2_YIELD(goto Exit;)
+    }
+    _SEH2_END;
+
+    if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) )
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        goto Exit;
+    }
+
+    if (saveTME.dwFlags & ~(TME_CANCEL | TME_QUERY | TME_NONCLIENT | TME_LEAVE | TME_HOVER) )
+    {
+        EngSetLastError(ERROR_INVALID_FLAGS);
+        goto Exit;
+    }
+
+    if ( saveTME.dwFlags & TME_QUERY )
+    {
+        Ret = IntQueryTrackMouseEvent(&saveTME);
+        _SEH2_TRY
+        {
+            ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
+            RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            SetLastNtError(_SEH2_GetExceptionCode());
+            Ret = FALSE;
+        }
+        _SEH2_END;
+    }
+    else
+    {
+        Ret = IntTrackMouseEvent(&saveTME);
+    }
+
 Exit:
-   TRACE("Leave NtUserTrackMouseEvent, ret=%i\n",Ret);
-   UserLeave();
-   return Ret;
+    TRACE("Leave NtUserTrackMouseEvent, ret=%i\n", Ret);
+    UserLeave();
+    return Ret;
 }
 
 extern MOUSEMOVEPOINT MouseHistoryOfMoves[];
-extern INT gcur_count; 
+extern INT gcur_count;
 
 DWORD
 APIENTRY
 NtUserGetMouseMovePointsEx(
-   UINT cbSize,
-   LPMOUSEMOVEPOINT lpptIn,
-   LPMOUSEMOVEPOINT lpptOut,
-   int nBufPoints,
-   DWORD resolution)
+    UINT cbSize,
+    LPMOUSEMOVEPOINT lpptIn,
+    LPMOUSEMOVEPOINT lpptOut,
+    int nBufPoints,
+    DWORD resolution)
 {
-   MOUSEMOVEPOINT Safeppt;
-   BOOL Hit;
-   INT Count = -1;
-   DECLARE_RETURN(DWORD);
-
-   TRACE("Enter NtUserGetMouseMovePointsEx\n");
-   UserEnterExclusive();
-
-   if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
-   {
-      EngSetLastError(ERROR_INVALID_PARAMETER);
-      RETURN( -1);
-   }
-
-   if (!lpptIn || (!lpptOut && nBufPoints))
-   {
-      EngSetLastError(ERROR_NOACCESS);
-      RETURN( -1);
-   }
-
-   _SEH2_TRY
-   {
-      ProbeForRead( lpptIn, cbSize, 1);
-      RtlCopyMemory(&Safeppt, lpptIn, cbSize);
-   }
-   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-   {
-      SetLastNtError(_SEH2_GetExceptionCode());
-      _SEH2_YIELD(RETURN( -1))
-   }
-   _SEH2_END;
-
-   // http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx
-   // This explains the math issues in transforming points.
-   Count = gcur_count; // FIFO is forward so retrieve backward.
-   Hit = FALSE;
-   do
-   {
-       if (Safeppt.x == 0 && Safeppt.y == 0)
-          break; // No test.
-       // Finds the point, it returns the last nBufPoints prior to and including the supplied point. 
-       if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y)
-       {
-          if ( Safeppt.time ) // Now test time and it seems to be absolute.
-          {
-             if (Safeppt.time == MouseHistoryOfMoves[Count].time)
-             {
-                Hit = TRUE;
-                break;
-             }
-             else
-             {
-                if (--Count < 0) Count = 63;
-                continue;
-             }
-          }
-          Hit = TRUE;
-          break;
-       }
-       if (--Count < 0) Count = 63;
-   }
-   while ( Count != gcur_count);
-
-   switch(resolution)
-   {
-     case GMMP_USE_DISPLAY_POINTS:
-        if (nBufPoints)
+    MOUSEMOVEPOINT Safeppt;
+    BOOL Hit;
+    INT Count = -1;
+    DECLARE_RETURN(DWORD);
+
+    TRACE("Enter NtUserGetMouseMovePointsEx\n");
+    UserEnterExclusive();
+
+    if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        RETURN( -1);
+    }
+
+    if (!lpptIn || (!lpptOut && nBufPoints))
+    {
+        EngSetLastError(ERROR_NOACCESS);
+        RETURN( -1);
+    }
+
+    _SEH2_TRY
+    {
+        ProbeForRead( lpptIn, cbSize, 1);
+        RtlCopyMemory(&Safeppt, lpptIn, cbSize);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastNtError(_SEH2_GetExceptionCode());
+        _SEH2_YIELD(RETURN( -1))
+    }
+    _SEH2_END;
+
+    // http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx
+    // This explains the math issues in transforming points.
+    Count = gcur_count; // FIFO is forward so retrieve backward.
+    Hit = FALSE;
+    do
+    {
+        if (Safeppt.x == 0 && Safeppt.y == 0)
+            break; // No test.
+        // Finds the point, it returns the last nBufPoints prior to and including the supplied point.
+        if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y)
         {
-           _SEH2_TRY
-           {
-              ProbeForWrite(lpptOut, cbSize, 1);
-           }
-           _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-           {
-              SetLastNtError(_SEH2_GetExceptionCode());
-              _SEH2_YIELD(RETURN( -1))
-           }
-           _SEH2_END;
+            if ( Safeppt.time ) // Now test time and it seems to be absolute.
+            {
+                if (Safeppt.time == MouseHistoryOfMoves[Count].time)
+                {
+                    Hit = TRUE;
+                    break;
+                }
+                else
+                {
+                    if (--Count < 0) Count = 63;
+                    continue;
+                }
+            }
+            Hit = TRUE;
+            break;
         }
-        Count = nBufPoints;
-        break;
-     case GMMP_USE_HIGH_RESOLUTION_POINTS:
-        break;
-     default:
-        EngSetLastError(ERROR_POINT_NOT_FOUND);
-        RETURN( -1);
-   }
+        if (--Count < 0) Count = 63;
+    }
+    while ( Count != gcur_count);
+
+    switch(resolution)
+    {
+        case GMMP_USE_DISPLAY_POINTS:
+            if (nBufPoints)
+            {
+                _SEH2_TRY
+                {
+                    ProbeForWrite(lpptOut, cbSize, 1);
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    SetLastNtError(_SEH2_GetExceptionCode());
+                    _SEH2_YIELD(RETURN( -1))
+                }
+                _SEH2_END;
+            }
+            Count = nBufPoints;
+            break;
+        case GMMP_USE_HIGH_RESOLUTION_POINTS:
+            break;
+        default:
+            EngSetLastError(ERROR_POINT_NOT_FOUND);
+            RETURN( -1);
+    }
 
-   RETURN( Count);
+    RETURN( Count);
 
 CLEANUP:
-   TRACE("Leave NtUserGetMouseMovePointsEx, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserGetMouseMovePointsEx, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 /* EOF */
index 6734712..151c701 100644 (file)
@@ -42,8 +42,8 @@ NTSTATUS
 NTAPI
 InitKeyboardImpl(VOID)
 {
-   RtlZeroMemory(&gKeyStateTable, 0x100);
-   return STATUS_SUCCESS;
+    RtlZeroMemory(&gKeyStateTable, 0x100);
+    return STATUS_SUCCESS;
 }
 
 /*** Statics used by TranslateMessage ***/
@@ -52,104 +52,104 @@ InitKeyboardImpl(VOID)
 
 static UINT DontDistinguishShifts( UINT ret )
 {
-   if( ret == VK_LSHIFT || ret == VK_RSHIFT )
-      ret = VK_SHIFT;
-   if( ret == VK_LCONTROL || ret == VK_RCONTROL )
-      ret = VK_CONTROL;
-   if( ret == VK_LMENU || ret == VK_RMENU )
-      ret = VK_MENU;
-   return ret;
+    if( ret == VK_LSHIFT || ret == VK_RSHIFT )
+        ret = VK_SHIFT;
+    if( ret == VK_LCONTROL || ret == VK_RCONTROL )
+        ret = VK_CONTROL;
+    if( ret == VK_LMENU || ret == VK_RMENU )
+        ret = VK_MENU;
+    return ret;
 }
 
 static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
 {
-   ASSERT(vk <= 0xff);
-
-   /* Special handling for toggles like numpad and caps lock */
-   if (vk == VK_CAPITAL || vk == VK_NUMLOCK)
-   {
-      if (down)
-         gKeyStateTable[vk] ^= KS_LOCK_BIT;
-   }
-
-   if (vk == VK_SHIFT)
-      vk = ext ? VK_RSHIFT : VK_LSHIFT;
-   if (vk == VK_CONTROL)
-      vk = ext ? VK_RCONTROL : VK_LCONTROL;
-   if (vk == VK_MENU)
-      vk = ext ? VK_RMENU : VK_LMENU;
-
-   if (down)
-      gKeyStateTable[vk] |= KS_DOWN_BIT;
-   else
-      gKeyStateTable[vk] &= ~KS_DOWN_BIT;
-
-   if (vk == VK_LSHIFT || vk == VK_RSHIFT)
-   {
-      if ((gKeyStateTable[VK_LSHIFT] & KS_DOWN_BIT) ||
-            (gKeyStateTable[VK_RSHIFT] & KS_DOWN_BIT))
-      {
-         gKeyStateTable[VK_SHIFT] |= KS_DOWN_BIT;
-      }
-      else
-      {
-         gKeyStateTable[VK_SHIFT] &= ~KS_DOWN_BIT;
-      }
-   }
-
-   if (vk == VK_LCONTROL || vk == VK_RCONTROL)
-   {
-      if ((gKeyStateTable[VK_LCONTROL] & KS_DOWN_BIT) ||
-            (gKeyStateTable[VK_RCONTROL] & KS_DOWN_BIT))
-      {
-         gKeyStateTable[VK_CONTROL] |= KS_DOWN_BIT;
-      }
-      else
-      {
-         gKeyStateTable[VK_CONTROL] &= ~KS_DOWN_BIT;
-      }
-   }
-
-   if (vk == VK_LMENU || vk == VK_RMENU)
-   {
-      if ((gKeyStateTable[VK_LMENU] & KS_DOWN_BIT) ||
-            (gKeyStateTable[VK_RMENU] & KS_DOWN_BIT))
-      {
-         gKeyStateTable[VK_MENU] |= KS_DOWN_BIT;
-      }
-      else
-      {
-         gKeyStateTable[VK_MENU] &= ~KS_DOWN_BIT;
-      }
-   }
+    ASSERT(vk <= 0xff);
+
+    /* Special handling for toggles like numpad and caps lock */
+    if (vk == VK_CAPITAL || vk == VK_NUMLOCK)
+    {
+        if (down)
+            gKeyStateTable[vk] ^= KS_LOCK_BIT;
+    }
+
+    if (vk == VK_SHIFT)
+        vk = ext ? VK_RSHIFT : VK_LSHIFT;
+    if (vk == VK_CONTROL)
+        vk = ext ? VK_RCONTROL : VK_LCONTROL;
+    if (vk == VK_MENU)
+        vk = ext ? VK_RMENU : VK_LMENU;
+
+    if (down)
+        gKeyStateTable[vk] |= KS_DOWN_BIT;
+    else
+        gKeyStateTable[vk] &= ~KS_DOWN_BIT;
+
+    if (vk == VK_LSHIFT || vk == VK_RSHIFT)
+    {
+        if ((gKeyStateTable[VK_LSHIFT] & KS_DOWN_BIT) ||
+                (gKeyStateTable[VK_RSHIFT] & KS_DOWN_BIT))
+        {
+            gKeyStateTable[VK_SHIFT] |= KS_DOWN_BIT;
+        }
+        else
+        {
+            gKeyStateTable[VK_SHIFT] &= ~KS_DOWN_BIT;
+        }
+    }
+
+    if (vk == VK_LCONTROL || vk == VK_RCONTROL)
+    {
+        if ((gKeyStateTable[VK_LCONTROL] & KS_DOWN_BIT) ||
+                (gKeyStateTable[VK_RCONTROL] & KS_DOWN_BIT))
+        {
+            gKeyStateTable[VK_CONTROL] |= KS_DOWN_BIT;
+        }
+        else
+        {
+            gKeyStateTable[VK_CONTROL] &= ~KS_DOWN_BIT;
+        }
+    }
+
+    if (vk == VK_LMENU || vk == VK_RMENU)
+    {
+        if ((gKeyStateTable[VK_LMENU] & KS_DOWN_BIT) ||
+                (gKeyStateTable[VK_RMENU] & KS_DOWN_BIT))
+        {
+            gKeyStateTable[VK_MENU] |= KS_DOWN_BIT;
+        }
+        else
+        {
+            gKeyStateTable[VK_MENU] &= ~KS_DOWN_BIT;
+        }
+    }
 }
 
 VOID DumpKeyState( PBYTE KeyState )
 {
-   int i;
-
-   DbgPrint( "KeyState { " );
-   for( i = 0; i < 0x100; i++ )
-   {
-      if( KeyState[i] )
-         DbgPrint( "%02x(%02x) ", i, KeyState[i] );
-   }
-   DbgPrint( "};\n" );
+    int i;
+
+    DbgPrint( "KeyState { " );
+    for( i = 0; i < 0x100; i++ )
+    {
+        if( KeyState[i] )
+            DbgPrint( "%02x(%02x) ", i, KeyState[i] );
+    }
+    DbgPrint( "};\n" );
 }
 
 static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
                      int FakeModLeft, int FakeModRight )
 {
-   if( !KeyState || !pkKT )
-      return 0;
+    if( !KeyState || !pkKT )
+        return 0;
 
-   /* Search special codes first */
-   if( FakeModLeft && KeyState[FakeModLeft] )
-      return KeyState[FakeModLeft];
-   else if( FakeModRight && KeyState[FakeModRight] )
-      return KeyState[FakeModRight];
+    /* Search special codes first */
+    if( FakeModLeft && KeyState[FakeModLeft] )
+        return KeyState[FakeModLeft];
+    else if( FakeModRight && KeyState[FakeModRight] )
+        return KeyState[FakeModRight];
 
-   return 0;
+    return 0;
 }
 
 /* Search the keyboard layout modifiers table for the shift bit.  I don't
@@ -158,65 +158,65 @@ static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
 
 static DWORD FASTCALL GetShiftBit( PKBDTABLES pkKT, DWORD Vk )
 {
-   int i;
+    int i;
 
-   for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
-      if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
-         return pkKT->pCharModifiers->pVkToBit[i].ModBits;
+    for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
+        if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
+            return pkKT->pCharModifiers->pVkToBit[i].ModBits;
 
-   return 0;
+    return 0;
 }
 
 static DWORD ModBits( PKBDTABLES pkKT, PBYTE KeyState )
 {
-   DWORD ModBits = 0;
+    DWORD ModBits = 0;
 
-   if( !KeyState )
-      return 0;
+    if( !KeyState )
+        return 0;
 
-   /* DumpKeyState( KeyState ); */
+    /* DumpKeyState( KeyState ); */
 
-   if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
-         KS_DOWN_BIT)
-      ModBits |= GetShiftBit( pkKT, VK_SHIFT );
+    if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
+            KS_DOWN_BIT)
+        ModBits |= GetShiftBit( pkKT, VK_SHIFT );
 
-   if (KeysSet( pkKT, KeyState, VK_SHIFT, 0 ) &
-         KS_DOWN_BIT)
-      ModBits |= GetShiftBit( pkKT, VK_SHIFT );
+    if (KeysSet( pkKT, KeyState, VK_SHIFT, 0 ) &
+            KS_DOWN_BIT)
+        ModBits |= GetShiftBit( pkKT, VK_SHIFT );
 
-   if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
-         KS_DOWN_BIT )
-      ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+    if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
+            KS_DOWN_BIT )
+        ModBits |= GetShiftBit( pkKT, VK_CONTROL );
 
-   if (KeysSet( pkKT, KeyState, VK_CONTROL, 0 ) &
-         KS_DOWN_BIT )
-      ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+    if (KeysSet( pkKT, KeyState, VK_CONTROL, 0 ) &
+            KS_DOWN_BIT )
+        ModBits |= GetShiftBit( pkKT, VK_CONTROL );
 
-   if (KeysSet( pkKT, KeyState, VK_LMENU, VK_RMENU ) &
-         KS_DOWN_BIT )
-      ModBits |= GetShiftBit( pkKT, VK_MENU );
+    if (KeysSet( pkKT, KeyState, VK_LMENU, VK_RMENU ) &
+            KS_DOWN_BIT )
+        ModBits |= GetShiftBit( pkKT, VK_MENU );
 
-   /* Handle Alt+Gr */
-   if (pkKT->fLocalFlags & 0x1) 
-      if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
-            KS_DOWN_BIT)
-         ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+    /* Handle Alt+Gr */
+    if (pkKT->fLocalFlags & 0x1)
+        if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
+                KS_DOWN_BIT)
+            ModBits |= GetShiftBit( pkKT, VK_CONTROL );
 
-   /* Deal with VK_CAPITAL */
-   if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
-   {
-      ModBits |= CAPITAL_BIT;
-   }
+    /* Deal with VK_CAPITAL */
+    if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
+    {
+        ModBits |= CAPITAL_BIT;
+    }
 
-   /* Deal with VK_NUMLOCK */
-   if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
-   {
-      ModBits |= NUMLOCK_BIT;
-   }
+    /* Deal with VK_NUMLOCK */
+    if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
+    {
+        ModBits |= NUMLOCK_BIT;
+    }
 
-   TRACE( "Current Mod Bits: %x\n", ModBits );
+    TRACE( "Current Mod Bits: %x\n", ModBits );
 
-   return ModBits;
+    return ModBits;
 }
 
 static BOOL TryToTranslateChar(WORD wVirtKey,
@@ -226,70 +226,70 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
                                PWCHAR pwcTranslatedChar,
                                PKBDTABLES keyLayout )
 {
-   PVK_TO_WCHAR_TABLE vtwTbl;
-   PVK_TO_WCHARS10 vkPtr;
-   size_t size_this_entry;
-   int nMod;
-   DWORD CapsMod = 0, CapsState = 0;
-
-   CapsState = ModBits & ~MOD_BITS_MASK;
-   ModBits = ModBits & MOD_BITS_MASK;
-
-   TRACE ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
-
-   if (ModBits > keyLayout->pCharModifiers->wMaxModBits)
-   {
-      return FALSE;
-   }
-
-   for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
-   {
-      vtwTbl = &keyLayout->pVkToWcharTable[nMod];
-      size_this_entry = vtwTbl->cbSize;
-      vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
-      while(vkPtr->VirtualKey)
-      {
-         if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
-         {
-            CapsMod = keyLayout->pCharModifiers->ModNumber
-                      [ModBits ^
-                       ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
-
-            if( CapsMod >= keyLayout->pVkToWcharTable[nMod].nModifications )
-            {
-               return FALSE;
-            }
+    PVK_TO_WCHAR_TABLE vtwTbl;
+    PVK_TO_WCHARS10 vkPtr;
+    size_t size_this_entry;
+    int nMod;
+    DWORD CapsMod = 0, CapsState = 0;
 
-            if( vkPtr->wch[CapsMod] == WCH_NONE )
-            {
-               return FALSE;
-            }
+    CapsState = ModBits & ~MOD_BITS_MASK;
+    ModBits = ModBits & MOD_BITS_MASK;
 
-            *pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
-            *pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
-            *pwcTranslatedChar = vkPtr->wch[CapsMod];
+    TRACE ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
 
-            TRACE("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
-                   nMod, wVirtKey,
-                   CapsMod, CapsState, *pwcTranslatedChar);
+    if (ModBits > keyLayout->pCharModifiers->wMaxModBits)
+    {
+        return FALSE;
+    }
 
-            if( *pbDead )
+    for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
+    {
+        vtwTbl = &keyLayout->pVkToWcharTable[nMod];
+        size_this_entry = vtwTbl->cbSize;
+        vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
+        while(vkPtr->VirtualKey)
+        {
+            if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
             {
-               vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
-               if( vkPtr->VirtualKey != 0xff )
-               {
-                  TRACE( "Found dead key with no trailer in the table.\n" );
-                  TRACE( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
-                  return FALSE;
-               }
-               *pwcTranslatedChar = vkPtr->wch[CapsMod];
+                CapsMod = keyLayout->pCharModifiers->ModNumber
+                          [ModBits ^
+                           ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
+
+                if( CapsMod >= keyLayout->pVkToWcharTable[nMod].nModifications )
+                {
+                    return FALSE;
+                }
+
+                if( vkPtr->wch[CapsMod] == WCH_NONE )
+                {
+                    return FALSE;
+                }
+
+                *pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
+                *pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
+                *pwcTranslatedChar = vkPtr->wch[CapsMod];
+
+                TRACE("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
+                      nMod, wVirtKey,
+                      CapsMod, CapsState, *pwcTranslatedChar);
+
+                if( *pbDead )
+                {
+                    vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+                    if( vkPtr->VirtualKey != 0xff )
+                    {
+                        TRACE( "Found dead key with no trailer in the table.\n" );
+                        TRACE( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
+                        return FALSE;
+                    }
+                    *pwcTranslatedChar = vkPtr->wch[CapsMod];
+                }
+                return TRUE;
             }
-            return TRUE;
-         }
-         vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
-      }
-   }
-   return FALSE;
+            vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+        }
+    }
+    return FALSE;
 }
 
 static
@@ -302,52 +302,52 @@ ToUnicodeInner(UINT wVirtKey,
                UINT wFlags,
                PKBDTABLES pkKT)
 {
-   WCHAR wcTranslatedChar;
-   BOOL bDead;
-   BOOL bLigature;
-
-   if( !pkKT )
-      return 0;
-
-   if( TryToTranslateChar( wVirtKey,
-                           ModBits( pkKT, lpKeyState ),
-                           &bDead,
-                           &bLigature,
-                           &wcTranslatedChar,
-                           pkKT ) )
-   {
-      if( bLigature )
-      {
-         WARN("Not handling ligature (yet)\n" );
-         return 0;
-      }
-
-      if( cchBuff > 0 )
-         pwszBuff[0] = wcTranslatedChar;
-
-      return bDead ? -1 : 1;
-   }
-
-   return 0;
+    WCHAR wcTranslatedChar;
+    BOOL bDead;
+    BOOL bLigature;
+
+    if( !pkKT )
+        return 0;
+
+    if( TryToTranslateChar( wVirtKey,
+                            ModBits( pkKT, lpKeyState ),
+                            &bDead,
+                            &bLigature,
+                            &wcTranslatedChar,
+                            pkKT ) )
+    {
+        if( bLigature )
+        {
+            WARN("Not handling ligature (yet)\n" );
+            return 0;
+        }
+
+        if( cchBuff > 0 )
+            pwszBuff[0] = wcTranslatedChar;
+
+        return bDead ? -1 : 1;
+    }
+
+    return 0;
 }
 
 
 DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
 {
-   DWORD ret = 0;
-
-   if( key < 0x100 )
-   {
-      ret = ((DWORD)(gKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
-            (gKeyStateTable[key] & KS_LOCK_BIT);
-      if ( ret & 0x8000 )
-         ret |= 0xFFFF0000; // If down, windows returns 0xFFFF8000.
-   }
-   else
-   {
-      EngSetLastError(ERROR_INVALID_PARAMETER);
-   }
-   return ret;
+    DWORD ret = 0;
+
+    if( key < 0x100 )
+    {
+        ret = ((DWORD)(gKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
+              (gKeyStateTable[key] & KS_LOCK_BIT);
+        if ( ret & 0x8000 )
+            ret |= 0xFFFF0000; // If down, windows returns 0xFFFF8000.
+    }
+    else
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -378,19 +378,19 @@ WORD FASTCALL get_key_state(void)
 SHORT
 APIENTRY
 NtUserGetAsyncKeyState(
-   INT key)
+    INT key)
 {
-   DECLARE_RETURN(SHORT);
+    DECLARE_RETURN(SHORT);
 
-   TRACE("Enter NtUserGetAsyncKeyState\n");
-   UserEnterExclusive();
+    TRACE("Enter NtUserGetAsyncKeyState\n");
+    UserEnterExclusive();
 
-   RETURN((SHORT)UserGetAsyncKeyState(key));
+    RETURN((SHORT)UserGetAsyncKeyState(key));
 
 CLEANUP:
-   TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 
@@ -399,159 +399,159 @@ BOOL FASTCALL
 IntTranslateKbdMessage(LPMSG lpMsg,
                        UINT flags)
 {
-   PTHREADINFO pti;
-   static INT dead_char = 0;
-   LONG UState = 0;
-   WCHAR wp[2] = { 0 };
-   MSG NewMsg = { 0 };
-   PKBDTABLES keyLayout;
-   PWND pWndMsg;
-   BOOL Result = FALSE;
-
-   pWndMsg = UserGetWindowObject(lpMsg->hwnd);
-   if (!pWndMsg) // Must have a window!
-   {
-      ERR("No Window for Translate.\n");
-      return FALSE;
-   }
-
-   pti = pWndMsg->head.pti;
-   keyLayout = pti->KeyboardLayout->KBTables;
-   if( !keyLayout )
-      return FALSE;
-
-   if (lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST)
-      return FALSE;
-   if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
-      return FALSE;
-
-   /* All messages have to contain the cursor point. */
-   NewMsg.pt = gpsi->ptCursor;
-
-   TRACE("IntTranslateKbdMessage %s\n", lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN");
+    PTHREADINFO pti;
+    static INT dead_char = 0;
+    LONG UState = 0;
+    WCHAR wp[2] = { 0 };
+    MSG NewMsg = { 0 };
+    PKBDTABLES keyLayout;
+    PWND pWndMsg;
+    BOOL Result = FALSE;
+
+    pWndMsg = UserGetWindowObject(lpMsg->hwnd);
+    if (!pWndMsg) // Must have a window!
+    {
+        ERR("No Window for Translate.\n");
+        return FALSE;
+    }
+
+    pti = pWndMsg->head.pti;
+    keyLayout = pti->KeyboardLayout->KBTables;
+    if( !keyLayout )
+        return FALSE;
+
+    if (lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST)
+        return FALSE;
+    if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
+        return FALSE;
+
+    /* All messages have to contain the cursor point. */
+    NewMsg.pt = gpsi->ptCursor;
+
+    TRACE("IntTranslateKbdMessage %s\n", lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN");
 
     switch (lpMsg->wParam)
     {
-    case VK_PACKET:
-        NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
-        NewMsg.hwnd = lpMsg->hwnd;
-        NewMsg.wParam = HIWORD(lpMsg->lParam);
-        NewMsg.lParam = LOWORD(lpMsg->lParam);
-        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
-        return TRUE;
+        case VK_PACKET:
+            NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+            NewMsg.hwnd = lpMsg->hwnd;
+            NewMsg.wParam = HIWORD(lpMsg->lParam);
+            NewMsg.lParam = LOWORD(lpMsg->lParam);
+            MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+            return TRUE;
     }
 
-   UState = ToUnicodeInner( lpMsg->wParam,
-                            HIWORD(lpMsg->lParam) & 0xff,
-                            gKeyStateTable,
-                            wp,
-                            2,
-                            0,
-                            keyLayout );
-
-   if (UState == 1)
-   {
-      NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
-      if (dead_char)
-      {
-         ULONG i;
-         WCHAR first, second;
-         TRACE("PREVIOUS DEAD CHAR: %c\n", dead_char);
-
-         for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
-         {
-            first = keyLayout->pDeadKey[i].dwBoth >> 16;
-            second = keyLayout->pDeadKey[i].dwBoth;
-            if (first == dead_char && second == wp[0])
+    UState = ToUnicodeInner( lpMsg->wParam,
+                             HIWORD(lpMsg->lParam) & 0xff,
+                             gKeyStateTable,
+                             wp,
+                             2,
+                             0,
+                             keyLayout );
+
+    if (UState == 1)
+    {
+        NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+        if (dead_char)
+        {
+            ULONG i;
+            WCHAR first, second;
+            TRACE("PREVIOUS DEAD CHAR: %c\n", dead_char);
+
+            for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
             {
-               wp[0] = keyLayout->pDeadKey[i].wchComposed;
-               dead_char = 0;
-               break;
+                first = keyLayout->pDeadKey[i].dwBoth >> 16;
+                second = keyLayout->pDeadKey[i].dwBoth;
+                if (first == dead_char && second == wp[0])
+                {
+                    wp[0] = keyLayout->pDeadKey[i].wchComposed;
+                    dead_char = 0;
+                    break;
+                }
             }
-         }
-
-         TRACE("FINAL CHAR: %c\n", wp[0]);
-      }
-
-      if (dead_char)
-      {
-         NewMsg.hwnd = lpMsg->hwnd;
-         NewMsg.wParam = dead_char;
-         NewMsg.lParam = lpMsg->lParam;
-         dead_char = 0;
-         MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
-      }
-
-      NewMsg.hwnd = lpMsg->hwnd;
-      NewMsg.wParam = wp[0];
-      NewMsg.lParam = lpMsg->lParam;
-      TRACE( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
-      MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
-      Result = TRUE;
-   }
-   else if (UState == -1)
-   {
-      NewMsg.message =
-         (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
-      NewMsg.hwnd = lpMsg->hwnd;
-      NewMsg.wParam = wp[0];
-      NewMsg.lParam = lpMsg->lParam;
-      dead_char = wp[0];
-      MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
-      Result = TRUE;
-   }
-   TRACE("IntTranslateKbdMessage E %s\n", NewMsg.message == WM_CHAR ? "WM_CHAR" : "WM_SYSCHAR");
-   return Result;
+
+            TRACE("FINAL CHAR: %c\n", wp[0]);
+        }
+
+        if (dead_char)
+        {
+            NewMsg.hwnd = lpMsg->hwnd;
+            NewMsg.wParam = dead_char;
+            NewMsg.lParam = lpMsg->lParam;
+            dead_char = 0;
+            MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+        }
+
+        NewMsg.hwnd = lpMsg->hwnd;
+        NewMsg.wParam = wp[0];
+        NewMsg.lParam = lpMsg->lParam;
+        TRACE( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
+        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+        Result = TRUE;
+    }
+    else if (UState == -1)
+    {
+        NewMsg.message =
+            (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
+        NewMsg.hwnd = lpMsg->hwnd;
+        NewMsg.wParam = wp[0];
+        NewMsg.lParam = lpMsg->lParam;
+        dead_char = wp[0];
+        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+        Result = TRUE;
+    }
+    TRACE("IntTranslateKbdMessage E %s\n", NewMsg.message == WM_CHAR ? "WM_CHAR" : "WM_SYSCHAR");
+    return Result;
 }
 
 static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT )
 {
-   int i;
+    int i;
 
-   for( i = 0; i < pkKT->bMaxVSCtoVK; i++ )
-   {
-      if( pkKT->pusVSCtoVK[i] == Code )
-      {
-         return i;
-      }
-   }
+    for( i = 0; i < pkKT->bMaxVSCtoVK; i++ )
+    {
+        if( pkKT->pusVSCtoVK[i] == Code )
+        {
+            return i;
+        }
+    }
 
-   return 0;
+    return 0;
 }
 
 UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT )
 {
-   if( !pkKT )
-   {
-      TRACE("ScanToVk: No layout\n");
-      return 0;
-   }
-
-   if( ExtKey )
-   {
-      int i;
-
-      for( i = 0; pkKT->pVSCtoVK_E0[i].Vsc; i++ )
-      {
-         if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
-            return pkKT->pVSCtoVK_E0[i].Vk & 0xff;
-      }
-      for( i = 0; pkKT->pVSCtoVK_E1[i].Vsc; i++ )
-      {
-         if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
-            return pkKT->pVSCtoVK_E1[i].Vk & 0xff;
-      }
-
-      return 0;
-   }
-   else
-   {
-      if( Code >= pkKT->bMaxVSCtoVK )
-      {
-         return 0;
-      }
-      return pkKT->pusVSCtoVK[Code] & 0xff;
-   }
+    if( !pkKT )
+    {
+        TRACE("ScanToVk: No layout\n");
+        return 0;
+    }
+
+    if( ExtKey )
+    {
+        int i;
+
+        for( i = 0; pkKT->pVSCtoVK_E0[i].Vsc; i++ )
+        {
+            if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
+                return pkKT->pVSCtoVK_E0[i].Vk & 0xff;
+        }
+        for( i = 0; pkKT->pVSCtoVK_E1[i].Vsc; i++ )
+        {
+            if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
+                return pkKT->pVSCtoVK_E1[i].Vk & 0xff;
+        }
+
+        return 0;
+    }
+    else
+    {
+        if( Code >= pkKT->bMaxVSCtoVK )
+        {
+            return 0;
+        }
+        return pkKT->pusVSCtoVK[Code] & 0xff;
+    }
 }
 
 /*
@@ -575,248 +575,248 @@ UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT )
 
 static UINT IntMapVirtualKeyEx( UINT Code, UINT Type, PKBDTABLES keyLayout )
 {
-   UINT ret = 0;
-
-   switch( Type )
-   {
-      case MAPVK_VK_TO_VSC:
-         if( Code == VK_SHIFT )
-            Code = VK_LSHIFT;
-         if( Code == VK_MENU )
-            Code = VK_LMENU;
-         if( Code == VK_CONTROL )
-            Code = VK_LCONTROL;
-         ret = VkToScan( Code, FALSE, keyLayout );
-         break;
-
-      case MAPVK_VSC_TO_VK:
-         ret =
-            DontDistinguishShifts
-            (IntMapVirtualKeyEx( Code, MAPVK_VSC_TO_VK_EX, keyLayout ) );
-         break;
-
-      case MAPVK_VK_TO_CHAR:
-         {
+    UINT ret = 0;
+
+    switch( Type )
+    {
+        case MAPVK_VK_TO_VSC:
+            if( Code == VK_SHIFT )
+                Code = VK_LSHIFT;
+            if( Code == VK_MENU )
+                Code = VK_LMENU;
+            if( Code == VK_CONTROL )
+                Code = VK_LCONTROL;
+            ret = VkToScan( Code, FALSE, keyLayout );
+            break;
+
+        case MAPVK_VSC_TO_VK:
+            ret =
+                DontDistinguishShifts
+                (IntMapVirtualKeyEx( Code, MAPVK_VSC_TO_VK_EX, keyLayout ) );
+            break;
+
+        case MAPVK_VK_TO_CHAR:
+        {
             WCHAR wp[2] = {0};
 
             ret = VkToScan( Code, FALSE, keyLayout );
             ToUnicodeInner( Code, ret, 0, wp, 2, 0, keyLayout );
             ret = wp[0];
-         }
-         break;
-
-      case MAPVK_VSC_TO_VK_EX:
-
-         ret = ScanToVk( Code, FALSE, keyLayout );
-         break;
-      
-      case MAPVK_VK_TO_VSC_EX:
-         STUB;
-         break;
-      
-      default:
-         ERR("Wrong type value: %u\n", Type);
-   }
-
-   return ret;
+        }
+        break;
+
+        case MAPVK_VSC_TO_VK_EX:
+
+            ret = ScanToVk( Code, FALSE, keyLayout );
+            break;
+
+        case MAPVK_VK_TO_VSC_EX:
+            STUB;
+            break;
+
+        default:
+            ERR("Wrong type value: %u\n", Type);
+    }
+
+    return ret;
 }
 
 UINT
 APIENTRY
 NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl )
 {
-   PTHREADINFO pti;
-   PKBDTABLES keyLayout;
-   DECLARE_RETURN(UINT);
+    PTHREADINFO pti;
+    PKBDTABLES keyLayout;
+    DECLARE_RETURN(UINT);
 
-   TRACE("Enter NtUserMapVirtualKeyEx\n");
-   UserEnterExclusive();
+    TRACE("Enter NtUserMapVirtualKeyEx\n");
+    UserEnterExclusive();
 
-   pti = PsGetCurrentThreadWin32Thread();
-   keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
+    pti = PsGetCurrentThreadWin32Thread();
+    keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
 
-   if( !keyLayout )
-      RETURN(0);
+    if( !keyLayout )
+        RETURN(0);
 
-   RETURN(IntMapVirtualKeyEx( Code, Type, keyLayout ));
+    RETURN(IntMapVirtualKeyEx( Code, Type, keyLayout ));
 
 CLEANUP:
-   TRACE("Leave NtUserMapVirtualKeyEx, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserMapVirtualKeyEx, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 
 int
 APIENTRY
 NtUserToUnicodeEx(
-   UINT wVirtKey,
-   UINT wScanCode,
-   PBYTE lpKeyState,
-   LPWSTR pwszBuff,
-   int cchBuff,
-   UINT wFlags,
-   HKL dwhkl )
+    UINT wVirtKey,
+    UINT wScanCode,
+    PBYTE lpKeyState,
+    LPWSTR pwszBuff,
+    int cchBuff,
+    UINT wFlags,
+    HKL dwhkl )
 {
-   PTHREADINFO pti;
-   BYTE KeyStateBuf[0x100];
-   PWCHAR OutPwszBuff = 0;
-   int ret = 0;
-   DECLARE_RETURN(int);
-
-   TRACE("Enter NtUserSetKeyboardState\n");
-   UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
-
-   /* Key up? */
-   if (wScanCode & SC_KEY_UP)
-   {
-      RETURN(0);
-   }
-
-   if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
-                                    lpKeyState,
-                                    sizeof(KeyStateBuf))) )
-   {
-      ERR( "Couldn't copy key state from caller.\n" );
-      RETURN(0);
-   }
-   
-   /* Virtual code is correct? */
-   if (wVirtKey < 0x100)
-   {
-      OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
-      if( !OutPwszBuff )
-      {
-         ERR( "ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
-         RETURN(0);
-      }
-      RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
-
-      pti = PsGetCurrentThreadWin32Thread();
-      ret = ToUnicodeInner( wVirtKey,
-                            wScanCode,
-                            KeyStateBuf,
-                            OutPwszBuff,
-                            cchBuff,
-                            wFlags,
-                            pti ? pti->KeyboardLayout->KBTables : 0 );
-
-      MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
-      ExFreePoolWithTag(OutPwszBuff, TAG_STRING);
-   }
-
-   RETURN(ret);
+    PTHREADINFO pti;
+    BYTE KeyStateBuf[0x100];
+    PWCHAR OutPwszBuff = 0;
+    int ret = 0;
+    DECLARE_RETURN(int);
+
+    TRACE("Enter NtUserSetKeyboardState\n");
+    UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
+
+    /* Key up? */
+    if (wScanCode & SC_KEY_UP)
+    {
+        RETURN(0);
+    }
+
+    if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
+                                     lpKeyState,
+                                     sizeof(KeyStateBuf))) )
+    {
+        ERR( "Couldn't copy key state from caller.\n" );
+        RETURN(0);
+    }
+
+    /* Virtual code is correct? */
+    if (wVirtKey < 0x100)
+    {
+        OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
+        if( !OutPwszBuff )
+        {
+            ERR( "ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
+            RETURN(0);
+        }
+        RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
+
+        pti = PsGetCurrentThreadWin32Thread();
+        ret = ToUnicodeInner( wVirtKey,
+                              wScanCode,
+                              KeyStateBuf,
+                              OutPwszBuff,
+                              cchBuff,
+                              wFlags,
+                              pti ? pti->KeyboardLayout->KBTables : 0 );
+
+        MmCopyToCaller(pwszBuff, OutPwszBuff, sizeof(WCHAR)*cchBuff);
+        ExFreePoolWithTag(OutPwszBuff, TAG_STRING);
+    }
+
+    RETURN(ret);
 
 CLEANUP:
-   TRACE("Leave NtUserSetKeyboardState, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserSetKeyboardState, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 static int W32kSimpleToupper( int ch )
 {
-   if( ch >= 'a' && ch <= 'z' )
-      ch = ch - 'a' + 'A';
-   return ch;
+    if( ch >= 'a' && ch <= 'z' )
+        ch = ch - 'a' + 'A';
+    return ch;
 }
 
 DWORD
 APIENTRY
 NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize )
 {
-   PTHREADINFO pti;
-   int i;
-   DWORD ret = 0;
-   UINT CareVk = 0;
-   UINT VkCode = 0;
-   UINT ScanCode = (lParam >> 16) & 0xff;
-   BOOL ExtKey = lParam & (1<<24) ? TRUE : FALSE;
-   PKBDTABLES keyLayout;
-   VSC_LPWSTR *KeyNames;
-   DECLARE_RETURN(DWORD);
-
-   TRACE("Enter NtUserGetKeyNameText\n");
-   UserEnterShared();
-
-   pti = PsGetCurrentThreadWin32Thread();
-   keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
-
-   if( !keyLayout || nSize < 1 )
-      RETURN(0);
-
-   if( lParam & (1<<25) )
-   {
-      CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
-      switch (VkCode)
-      {
-          case VK_RSHIFT:
-              ScanCode |= 0x100;
-          case VK_LSHIFT:
-             VkCode = VK_SHIFT;
-             break;
-          case VK_LCONTROL:
-          case VK_RCONTROL:
-             VkCode = VK_CONTROL;
-             break;
-          case VK_LMENU:
-          case VK_RMENU:
-             VkCode = VK_MENU;
-             break;
-      }
-   }
-   else
-   {
-      VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
-   }
-
-   KeyNames = 0;
-
-   if( CareVk != VkCode )
-      ScanCode = VkToScan( VkCode, ExtKey, keyLayout );
-
-   if( ExtKey )
-      KeyNames = keyLayout->pKeyNamesExt;
-   else
-      KeyNames = keyLayout->pKeyNames;
-
-   for( i = 0; KeyNames[i].pwsz; i++ )
-   {
-      if( KeyNames[i].vsc == ScanCode )
-      {
-         UINT StrLen = wcslen(KeyNames[i].pwsz);
-         UINT StrMax = StrLen > (nSize - 1) ? (nSize - 1) : StrLen;
-         WCHAR null_wc = 0;
-         if( NT_SUCCESS( MmCopyToCaller( lpString,
-                                         KeyNames[i].pwsz,
-                                         StrMax * sizeof(WCHAR) ) ) &&
-               NT_SUCCESS( MmCopyToCaller( lpString + StrMax,
-                                           &null_wc,
-                                           sizeof( WCHAR ) ) ) )
-         {
-            ret = StrMax;
-            break;
-         }
-      }
-   }
+    PTHREADINFO pti;
+    int i;
+    DWORD ret = 0;
+    UINT CareVk = 0;
+    UINT VkCode = 0;
+    UINT ScanCode = (lParam >> 16) & 0xff;
+    BOOL ExtKey = lParam & (1 << 24) ? TRUE : FALSE;
+    PKBDTABLES keyLayout;
+    VSC_LPWSTR *KeyNames;
+    DECLARE_RETURN(DWORD);
+
+    TRACE("Enter NtUserGetKeyNameText\n");
+    UserEnterShared();
+
+    pti = PsGetCurrentThreadWin32Thread();
+    keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
+
+    if( !keyLayout || nSize < 1 )
+        RETURN(0);
+
+    if( lParam & (1 << 25) )
+    {
+        CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
+        switch (VkCode)
+        {
+            case VK_RSHIFT:
+                ScanCode |= 0x100;
+            case VK_LSHIFT:
+                VkCode = VK_SHIFT;
+                break;
+            case VK_LCONTROL:
+            case VK_RCONTROL:
+                VkCode = VK_CONTROL;
+                break;
+            case VK_LMENU:
+            case VK_RMENU:
+                VkCode = VK_MENU;
+                break;
+        }
+    }
+    else
+    {
+        VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
+    }
 
-   if( ret == 0 )
-   {
-      WCHAR UCName[2];
+    KeyNames = 0;
 
-      UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, MAPVK_VK_TO_CHAR, keyLayout ));
-      UCName[1] = 0;
-      ret = 1;
+    if( CareVk != VkCode )
+        ScanCode = VkToScan( VkCode, ExtKey, keyLayout );
 
-      if( !NT_SUCCESS(MmCopyToCaller( lpString, UCName, 2 * sizeof(WCHAR) )) )
-         RETURN(0);
-   }
+    if( ExtKey )
+        KeyNames = keyLayout->pKeyNamesExt;
+    else
+        KeyNames = keyLayout->pKeyNames;
+
+    for( i = 0; KeyNames[i].pwsz; i++ )
+    {
+        if( KeyNames[i].vsc == ScanCode )
+        {
+            UINT StrLen = wcslen(KeyNames[i].pwsz);
+            UINT StrMax = StrLen > (nSize - 1) ? (nSize - 1) : StrLen;
+            WCHAR null_wc = 0;
+            if( NT_SUCCESS( MmCopyToCaller( lpString,
+                                            KeyNames[i].pwsz,
+                                            StrMax * sizeof(WCHAR) ) ) &&
+                    NT_SUCCESS( MmCopyToCaller( lpString + StrMax,
+                                                &null_wc,
+                                                sizeof( WCHAR ) ) ) )
+            {
+                ret = StrMax;
+                break;
+            }
+        }
+    }
+
+    if( ret == 0 )
+    {
+        WCHAR UCName[2];
+
+        UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, MAPVK_VK_TO_CHAR, keyLayout ));
+        UCName[1] = 0;
+        ret = 1;
+
+        if( !NT_SUCCESS(MmCopyToCaller( lpString, UCName, 2 * sizeof(WCHAR) )) )
+            RETURN(0);
+    }
 
-   RETURN(ret);
+    RETURN(ret);
 
 CLEANUP:
-   TRACE("Leave NtUserGetKeyNameText, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
+    TRACE("Leave NtUserGetKeyNameText, ret=%i\n", _ret_);
+    UserLeave();
+    END_CLEANUP;
 }
 
 /*
@@ -829,12 +829,12 @@ W32kKeyProcessMessage(LPMSG Msg,
                       PKBDTABLES KeyboardLayout,
                       BYTE Prefix)
 {
-   DWORD ScanCode = 0, ModifierBits = 0;
-   DWORD i = 0;
-   DWORD BaseMapping = 0;
-   DWORD RawVk = 0;
-   static WORD NumpadConversion[][2] =
-      { { VK_DELETE, VK_DECIMAL },
+    DWORD ScanCode = 0, ModifierBits = 0;
+    DWORD i = 0;
+    DWORD BaseMapping = 0;
+    DWORD RawVk = 0;
+    static WORD NumpadConversion[][2] =
+    {   { VK_DELETE, VK_DECIMAL },
         { VK_INSERT, VK_NUMPAD0 },
         { VK_END,    VK_NUMPAD1 },
         { VK_DOWN,   VK_NUMPAD2 },
@@ -845,109 +845,110 @@ W32kKeyProcessMessage(LPMSG Msg,
         { VK_HOME,   VK_NUMPAD7 },
         { VK_UP,     VK_NUMPAD8 },
         { VK_PRIOR,  VK_NUMPAD9 },
-        { 0,0 } };
-   PVSC_VK VscVkTable = NULL;
-
-   if( !KeyboardLayout || !Msg ||
-         (Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
-          Msg->message != WM_KEYUP   && Msg->message != WM_SYSKEYUP) )
-   {
-      return;
-   }
-
-   /* arty -- handle numpad -- On real windows, the actual key produced
-    * by the messaging layer is different based on the state of numlock. */
-   ModifierBits = ModBits(KeyboardLayout,gKeyStateTable);
-
-   /* Get the raw scan code, so we can look up whether the key is a numpad
-    * key
-    *
-    * Shift and the LP_EXT_BIT cancel. */
-   ScanCode = (Msg->lParam >> 16) & 0xff;
-   TRACE("ScanCode %04x\n",ScanCode);
-
-   BaseMapping = Msg->wParam =
-                    IntMapVirtualKeyEx( ScanCode, MAPVK_VSC_TO_VK, KeyboardLayout );
-   if( Prefix == 0 )
-   {
-      if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
-         RawVk = 0xff;
-      else
-         RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
-   }
-   else
-   {
-      if( Prefix == 0xE0 )
-      {
-         /* ignore shift codes */
-         if( ScanCode == 0x2A || ScanCode == 0x36 )
-         {
+        { 0, 0 }
+    };
+    PVSC_VK VscVkTable = NULL;
+
+    if( !KeyboardLayout || !Msg ||
+            (Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
+             Msg->message != WM_KEYUP   && Msg->message != WM_SYSKEYUP) )
+    {
+        return;
+    }
+
+    /* arty -- handle numpad -- On real windows, the actual key produced
+     * by the messaging layer is different based on the state of numlock. */
+    ModifierBits = ModBits(KeyboardLayout, gKeyStateTable);
+
+    /* Get the raw scan code, so we can look up whether the key is a numpad
+     * key
+     *
+     * Shift and the LP_EXT_BIT cancel. */
+    ScanCode = (Msg->lParam >> 16) & 0xff;
+    TRACE("ScanCode %04x\n", ScanCode);
+
+    BaseMapping = Msg->wParam =
+                      IntMapVirtualKeyEx( ScanCode, MAPVK_VSC_TO_VK, KeyboardLayout );
+    if( Prefix == 0 )
+    {
+        if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
+            RawVk = 0xff;
+        else
+            RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
+    }
+    else
+    {
+        if( Prefix == 0xE0 )
+        {
+            /* ignore shift codes */
+            if( ScanCode == 0x2A || ScanCode == 0x36 )
+            {
+                return;
+            }
+            VscVkTable = KeyboardLayout->pVSCtoVK_E0;
+        }
+        else if( Prefix == 0xE1 )
+        {
+            VscVkTable = KeyboardLayout->pVSCtoVK_E1;
+        }
+
+        if (!VscVkTable)
+        {
+            ERR("somethings wrong, Prefix=0x%x", Prefix);
             return;
-         }
-         VscVkTable = KeyboardLayout->pVSCtoVK_E0;
-      }
-      else if( Prefix == 0xE1 )
-      {
-         VscVkTable = KeyboardLayout->pVSCtoVK_E1;
-      }
-
-      if (!VscVkTable)
-      {
-          ERR("somethings wrong, Prefix=0x%x", Prefix);
-          return;
-      }
-
-      RawVk = 0xff;
-      while (VscVkTable->Vsc)
-      {
-         if( VscVkTable->Vsc == ScanCode )
-         {
-            RawVk = VscVkTable->Vk;
-         }
-         VscVkTable++;
-      }
-   }
-
-   if ((ModifierBits & NUMLOCK_BIT) &&
-         !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
-         (RawVk & KNUMP) &&
-         !(Msg->lParam & LP_EXT_BIT))
-   {
-      /* The key in question is a numpad key.  Search for a translation. */
-      for (i = 0; NumpadConversion[i][0]; i++)
-      {
-         if ((BaseMapping & 0xff) == NumpadConversion[i][0]) /* RawVk? */
-         {
-            Msg->wParam = NumpadConversion[i][1];
-            break;
-         }
-      }
-   }
-
-   TRACE("Key: [%04x -> %04x]\n", BaseMapping, Msg->wParam);
-
-   /* Now that we have the VK, we can set the keymap appropriately
-    * This is a better place for this code, as it's guaranteed to be
-    * run, unlike translate message. */
-   if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN)
-   {
-      SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
-                   TRUE ); /* Strike key */
-   }
-   else if (Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
-   {
-      SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
-                   FALSE ); /* Release key */
-   }
-
-   /* We need to unset SYSKEYDOWN if the ALT key is an ALT+Gr */
-   if( gKeyStateTable[VK_RMENU] & KS_DOWN_BIT )
-   {
-      if( Msg->message == WM_SYSKEYDOWN )
-         Msg->message = WM_KEYDOWN;
-      else
-         Msg->message = WM_KEYUP;
-   }
+        }
+
+        RawVk = 0xff;
+        while (VscVkTable->Vsc)
+        {
+            if( VscVkTable->Vsc == ScanCode )
+            {
+                RawVk = VscVkTable->Vk;
+            }
+            VscVkTable++;
+        }
+    }
+
+    if ((ModifierBits & NUMLOCK_BIT) &&
+            !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
+            (RawVk & KNUMP) &&
+            !(Msg->lParam & LP_EXT_BIT))
+    {
+        /* The key in question is a numpad key.  Search for a translation. */
+        for (i = 0; NumpadConversion[i][0]; i++)
+        {
+            if ((BaseMapping & 0xff) == NumpadConversion[i][0]) /* RawVk? */
+            {
+                Msg->wParam = NumpadConversion[i][1];
+                break;
+            }
+        }
+    }
+
+    TRACE("Key: [%04x -> %04x]\n", BaseMapping, Msg->wParam);
+
+    /* Now that we have the VK, we can set the keymap appropriately
+     * This is a better place for this code, as it's guaranteed to be
+     * run, unlike translate message. */
+    if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN)
+    {
+        SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
+                     TRUE ); /* Strike key */
+    }
+    else if (Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
+    {
+        SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
+                     FALSE ); /* Release key */
+    }
+
+    /* We need to unset SYSKEYDOWN if the ALT key is an ALT+Gr */
+    if( gKeyStateTable[VK_RMENU] & KS_DOWN_BIT )
+    {
+        if( Msg->message == WM_SYSKEYDOWN )
+            Msg->message = WM_KEYDOWN;
+        else
+            Msg->message = WM_KEYUP;
+    }
 
 }
 
@@ -955,20 +956,20 @@ W32kKeyProcessMessage(LPMSG Msg,
 
 DWORD FASTCALL
 UserGetKeyboardType(
-   DWORD TypeFlag)
+    DWORD TypeFlag)
 {
-   switch(TypeFlag)
-   {
-      case 0:        /* Keyboard type */
-         return 4;    /* AT-101 */
-      case 1:        /* Keyboard Subtype */
-         return 0;    /* There are no defined subtypes */
-      case 2:        /* Number of F-keys */
-         return 12;   /* We're doing an 101 for now, so return 12 F-keys */
-      default:
-         ERR("Unknown type!\n");
-         return 0;    /* The book says 0 here, so 0 */
-   }
+    switch(TypeFlag)
+    {
+        case 0:        /* Keyboard type */
+            return 4;    /* AT-101 */
+        case 1:        /* Keyboard Subtype */
+            return 0;    /* There are no defined subtypes */
+        case 2:        /* Number of F-keys */
+            return 12;   /* We're doing an 101 for now, so return 12 F-keys */
+        default:
+            ERR("Unknown type!\n");
+            return 0;    /* The book says 0 here, so 0 */
+    }
 }
 
 
@@ -979,64 +980,64 @@ UserGetKeyboardType(
 DWORD
 APIENTRY
 NtUserVkKeyScanEx(
-   WCHAR wChar,
-   HKL hKeyboardLayout,
-   BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
+    WCHAR wChar,
+    HKL hKeyboardLayout,
+    BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
 {
-   PKBDTABLES KeyLayout;
-   PVK_TO_WCHAR_TABLE vtwTbl;
-   PVK_TO_WCHARS10 vkPtr;
-   size_t size_this_entry;
-   int nMod;
-   PKBL pkbl = NULL;
-   DWORD CapsMod = 0, CapsState = 0, Ret = -1;
-
-   TRACE("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, hKeyboardLayout);
-   UserEnterShared();
-
-   if (UsehKL)
-   {
-      if ( !hKeyboardLayout || !(pkbl = UserHklToKbl(hKeyboardLayout)))
-      goto Exit;
-   }
-   else // From VkKeyScanAW it is FALSE so KeyboardLayout is white noise.
-   {
-     pkbl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
-   }   
-
-   KeyLayout = pkbl->KBTables;
-
-   for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
-   {
-      vtwTbl = &KeyLayout->pVkToWcharTable[nMod];
-      size_this_entry = vtwTbl->cbSize;
-      vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
-
-      while(vkPtr->VirtualKey)
-      {
-         /*
-            0x01 Shift key
-            0x02 Ctrl key
-            0x04 Alt key
-            Should have only 8 valid possibilities. Including zero.
-          */
-         for(CapsState = 0; CapsState < vtwTbl->nModifications; CapsState++)
-         {
-            if(vkPtr->wch[CapsState] == wChar)
+    PKBDTABLES KeyLayout;
+    PVK_TO_WCHAR_TABLE vtwTbl;
+    PVK_TO_WCHARS10 vkPtr;
+    size_t size_this_entry;
+    int nMod;
+    PKBL pkbl = NULL;
+    DWORD CapsMod = 0, CapsState = 0, Ret = -1;
+
+    TRACE("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, hKeyboardLayout);
+    UserEnterShared();
+
+    if (UsehKL)
+    {
+        if ( !hKeyboardLayout || !(pkbl = UserHklToKbl(hKeyboardLayout)))
+            goto Exit;
+    }
+    else // From VkKeyScanAW it is FALSE so KeyboardLayout is white noise.
+    {
+        pkbl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
+    }
+
+    KeyLayout = pkbl->KBTables;
+
+    for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
+    {
+        vtwTbl = &KeyLayout->pVkToWcharTable[nMod];
+        size_this_entry = vtwTbl->cbSize;
+        vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
+
+        while(vkPtr->VirtualKey)
+        {
+            /*
+               0x01 Shift key
+               0x02 Ctrl key
+               0x04 Alt key
+               Should have only 8 valid possibilities. Including zero.
+             */
+            for(CapsState = 0; CapsState < vtwTbl->nModifications; CapsState++)
             {
-               CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
-               TRACE("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
-                      nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
-               Ret = ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
-               goto Exit;
+                if(vkPtr->wch[CapsState] == wChar)
+                {
+                    CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
+                    TRACE("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
+                          nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
+                    Ret = ((CapsMod << 8) | (vkPtr->VirtualKey & 0xff));
+                    goto Exit;
+                }
             }
-         }
-         vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
-      }
-   }
+            vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+        }
+    }
 Exit:
-   UserLeave();
-   return Ret;
+    UserLeave();
+    return Ret;
 }