* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-/* Directory to load key layouts from */
-#define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\"
+
/* Lock modifiers */
#define CAPITAL_BIT 0x80000000
#define NUMLOCK_BIT 0x40000000
/* Key States */
#define KS_DOWN_MASK 0xc0
#define KS_DOWN_BIT 0x80
-#define KS_LOCK_BIT 0x01
+#define KS_LOCK_BIT 0x01
+/* Scan Codes */
+#define SC_KEY_UP 0x8000
/* lParam bits */
#define LP_EXT_BIT (1<<24)
/* From kbdxx.c -- Key changes with numlock */
BYTE gQueueKeyStateTable[256];
-PKBDRVFILE KBLList = NULL; // Keyboard layout list.
-
/* FUNCTIONS *****************************************************************/
static UINT DontDistinguishShifts( UINT ret )
{
if( ret == VK_LSHIFT || ret == VK_RSHIFT )
- ret = VK_LSHIFT;
+ ret = VK_SHIFT;
if( ret == VK_LCONTROL || ret == VK_RCONTROL )
- ret = VK_LCONTROL;
+ ret = VK_CONTROL;
if( ret == VK_LMENU || ret == VK_RMENU )
- ret = VK_LMENU;
+ ret = VK_MENU;
return ret;
}
-static VOID STDCALL SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
+static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
{
ASSERT(vk <= 0xff);
gQueueKeyStateTable[vk] ^= KS_LOCK_BIT;
}
- if (ext && vk == VK_LSHIFT)
- vk = VK_RSHIFT;
- if (ext && vk == VK_LCONTROL)
- vk = VK_RCONTROL;
- if (ext && vk == VK_LMENU)
- vk = VK_RMENU;
+ 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)
gQueueKeyStateTable[vk] |= KS_DOWN_BIT;
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_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 );
/* Handle Alt+Gr */
- if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
- KS_DOWN_BIT )
- ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+ 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)
{
return FALSE;
}
+
for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
{
vtwTbl = &keyLayout->pVkToWcharTable[nMod];
if( CapsMod >= keyLayout->pVkToWcharTable[nMod].nModifications )
{
- DWORD MaxBit = 1;
- while( MaxBit <
- keyLayout->pVkToWcharTable[nMod].nModifications )
- MaxBit <<= 1;
+ return FALSE;
+ }
- CapsMod &= MaxBit - 1; /* Guarantee that CapsMod lies
- in bounds. */
+ if( vkPtr->wch[CapsMod] == WCH_NONE )
+ {
+ return FALSE;
}
*pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
if( vkPtr->VirtualKey != 0xff )
{
DPRINT( "Found dead key with no trailer in the table.\n" );
- DPRINT( "VK: %04x, ADDR: %08x\n", wVirtKey, (int)vkPtr );
+ DPRINT( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
return FALSE;
}
*pwcTranslatedChar = vkPtr->wch[CapsMod];
}
static
-int STDCALL
+int APIENTRY
ToUnicodeInner(UINT wVirtKey,
UINT wScanCode,
PBYTE lpKeyState,
}
-DWORD
-STDCALL
+SHORT
+APIENTRY
NtUserGetKeyState(
- DWORD key)
+ INT key)
{
DECLARE_RETURN(DWORD);
-DWORD
-STDCALL
+SHORT
+APIENTRY
NtUserGetAsyncKeyState(
- DWORD key)
+ INT key)
{
- DECLARE_RETURN(DWORD);
+ DECLARE_RETURN(SHORT);
DPRINT("Enter NtUserGetAsyncKeyState\n");
UserEnterExclusive();
- RETURN(UserGetAsyncKeyState(key));
+ RETURN((SHORT)UserGetAsyncKeyState(key));
CLEANUP:
DPRINT("Leave NtUserGetAsyncKeyState, ret=%i\n",_ret_);
-int STDCALL ToUnicodeEx( UINT wVirtKey,
- UINT wScanCode,
- PBYTE lpKeyState,
- LPWSTR pwszBuff,
- int cchBuff,
- UINT wFlags,
- HKL dwhkl )
-{
- int ToUnicodeResult = 0;
-
- if (0 == (lpKeyState[wVirtKey] & KS_DOWN_BIT))
- {
- ToUnicodeResult = 0;
- }
- else
- {
- ToUnicodeResult = ToUnicodeInner( wVirtKey,
- wScanCode,
- lpKeyState,
- pwszBuff,
- cchBuff,
- wFlags,
- PsGetCurrentThreadWin32Thread() ?
- PsGetCurrentThreadWin32Thread()->KeyboardLayout : 0 );
- }
-
- return ToUnicodeResult;
-}
-
-int STDCALL ToUnicode( UINT wVirtKey,
- UINT wScanCode,
- PBYTE lpKeyState,
- LPWSTR pwszBuff,
- int cchBuff,
- UINT wFlags )
-{
- return ToUnicodeEx( wVirtKey,
- wScanCode,
- gQueueKeyStateTable,
- pwszBuff,
- cchBuff,
- wFlags,
- 0 );
-}
-
-/*
- * Utility to copy and append two unicode strings.
- *
- * IN OUT PUNICODE_STRING ResultFirst -> First string and result
- * IN PUNICODE_STRING Second -> Second string to append
- * IN BOOL Deallocate -> TRUE: Deallocate First string before
- * overwriting.
- *
- * Returns NTSTATUS.
- */
-
-NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst,
- PUNICODE_STRING Second,
- BOOL Deallocate)
-{
- NTSTATUS Status;
- PWSTR new_string =
- ExAllocatePoolWithTag(PagedPool,
- (ResultFirst->Length + Second->Length + sizeof(WCHAR)),
- TAG_STRING);
- if( !new_string )
- {
- return STATUS_NO_MEMORY;
- }
- memcpy( new_string, ResultFirst->Buffer,
- ResultFirst->Length );
- memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
- Second->Buffer,
- Second->Length );
- if( Deallocate )
- RtlFreeUnicodeString(ResultFirst);
- ResultFirst->Length += Second->Length;
- ResultFirst->MaximumLength = ResultFirst->Length;
- new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
- Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
- STATUS_SUCCESS : STATUS_NO_MEMORY;
- ExFreePool(new_string);
- return Status;
-}
-
-/*
- * Utility function to read a value from the registry more easily.
- *
- * IN PUNICODE_STRING KeyName -> Name of key to open
- * IN PUNICODE_STRING ValueName -> Name of value to open
- * OUT PUNICODE_STRING ReturnedValue -> String contained in registry
- *
- * Returns NTSTATUS
- */
-
-static NTSTATUS NTAPI ReadRegistryValue( PUNICODE_STRING KeyName,
- PUNICODE_STRING ValueName,
- PUNICODE_STRING ReturnedValue )
-{
- NTSTATUS Status;
- HANDLE KeyHandle;
- OBJECT_ATTRIBUTES KeyAttributes;
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- ULONG Length = 0;
- ULONG ResLength = 0;
- UNICODE_STRING Temp;
-
- InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
- Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
- if( !NT_SUCCESS(Status) )
- {
- return Status;
- }
-
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
- 0,
- 0,
- &ResLength);
-
- if( Status != STATUS_BUFFER_TOO_SMALL )
- {
- NtClose(KeyHandle);
- return Status;
- }
-
- ResLength += sizeof( *KeyValuePartialInfo );
- KeyValuePartialInfo =
- ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
- Length = ResLength;
-
- if( !KeyValuePartialInfo )
- {
- NtClose(KeyHandle);
- return STATUS_NO_MEMORY;
- }
-
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
- (PVOID)KeyValuePartialInfo,
- Length,
- &ResLength);
-
- if( !NT_SUCCESS(Status) )
- {
- NtClose(KeyHandle);
- ExFreePool(KeyValuePartialInfo);
- return Status;
- }
-
- Temp.Length = Temp.MaximumLength = KeyValuePartialInfo->DataLength;
- Temp.Buffer = (PWCHAR)KeyValuePartialInfo->Data;
-
- /* At this point, KeyValuePartialInfo->Data contains the key data */
- RtlInitUnicodeString(ReturnedValue,L"");
- AppendUnicodeString(ReturnedValue,&Temp,FALSE);
-
- ExFreePool(KeyValuePartialInfo);
- NtClose(KeyHandle);
-
- return Status;
-}
-
-typedef PVOID (*KbdLayerDescriptor)(VOID);
-NTSTATUS STDCALL LdrGetProcedureAddress(PVOID module,
- PANSI_STRING import_name,
- DWORD flags,
- PVOID *func_addr);
-
-void InitKbdLayout( PVOID *pkKeyboardLayout )
-{
- WCHAR LocaleBuffer[16];
- UNICODE_STRING LayoutKeyName;
- UNICODE_STRING LayoutValueName;
- UNICODE_STRING DefaultLocale;
- UNICODE_STRING LayoutFile;
- UNICODE_STRING FullLayoutPath;
- LCID LocaleId;
- PWCHAR KeyboardLayoutWSTR;
- HMODULE kbModule = 0;
- NTSTATUS Status;
- ANSI_STRING kbdProcedureName;
- KbdLayerDescriptor layerDescGetFn;
-
-#define XX_STATUS(x) if (!NT_SUCCESS(Status = (x))) continue;
-
- do
- {
- Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not get default locale (%08lx).\n", Status);
- }
- else
- {
- DPRINT("DefaultLocale = %lx\n", LocaleId);
- swprintf(LocaleBuffer, L"%08lx", LocaleId);
- DPRINT("DefaultLocale = %S\n", LocaleBuffer);
- RtlInitUnicodeString(&DefaultLocale, LocaleBuffer);
-
- RtlInitUnicodeString(&LayoutKeyName,
- L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
- L"\\Control\\KeyboardLayouts\\");
-
- AppendUnicodeString(&LayoutKeyName,&DefaultLocale,FALSE);
-
- RtlInitUnicodeString(&LayoutValueName,L"Layout File");
-
- Status = ReadRegistryValue(&LayoutKeyName,&LayoutValueName,&LayoutFile);
-
- RtlFreeUnicodeString(&LayoutKeyName);
-
- if( !NT_SUCCESS(Status) )
- {
- DPRINT1("Got default locale but not layout file. (%08lx)\n",
- Status);
- }
- else
- {
- DPRINT("Read registry and got %wZ\n", &LayoutFile);
-
-
- RtlInitUnicodeString(&FullLayoutPath,SYSTEMROOT_DIR);
- AppendUnicodeString(&FullLayoutPath,&LayoutFile,FALSE);
-
- DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
-
- RtlFreeUnicodeString(&LayoutFile);
-
- KeyboardLayoutWSTR =
- ExAllocatePoolWithTag(PagedPool,
- FullLayoutPath.Length + sizeof(WCHAR),
- TAG_STRING);
-
- if( !KeyboardLayoutWSTR )
- {
- DPRINT1("Couldn't allocate a string for the keyboard layout name.\n");
- RtlFreeUnicodeString(&FullLayoutPath);
- return;
- }
- memcpy(KeyboardLayoutWSTR,FullLayoutPath.Buffer,
- FullLayoutPath.Length);
- KeyboardLayoutWSTR[FullLayoutPath.Length / sizeof(WCHAR)] = 0;
-
- kbModule = EngLoadImage(KeyboardLayoutWSTR);
- DPRINT( "Load Keyboard Layout: %S\n", KeyboardLayoutWSTR );
-
- if( !kbModule )
- DPRINT1( "Load Keyboard Layout: No %wZ\n", &FullLayoutPath );
-
- ExFreePool(KeyboardLayoutWSTR);
- RtlFreeUnicodeString(&FullLayoutPath);
- }
- }
-
- if( !kbModule )
- {
- DPRINT1("Trying to load US Keyboard Layout\n");
- kbModule = EngLoadImage(L"\\SystemRoot\\system32\\kbdus.dll");
-
- if (!kbModule)
- {
- DPRINT1("Failed to load any Keyboard Layout\n");
- return;
- }
- }
-
- RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
-
- LdrGetProcedureAddress((PVOID)kbModule,
- &kbdProcedureName,
- 0,
- (PVOID*)&layerDescGetFn);
-
- if( layerDescGetFn )
- {
- *pkKeyboardLayout = layerDescGetFn();
- }
- }
- while (FALSE);
-
- if( !*pkKeyboardLayout )
- {
- DPRINT1("Failed to load the keyboard layout.\n");
- }
-
-#undef XX_STATUS
-}
-
-PKBDTABLES W32kGetDefaultKeyLayout(VOID)
-{
- PKBDTABLES pkKeyboardLayout = 0;
- InitKbdLayout( (PVOID) &pkKeyboardLayout );
- return pkKeyboardLayout;
-}
-
BOOL FASTCALL
IntTranslateKbdMessage(LPMSG lpMsg,
- HKL dwhkl)
+ UINT flags)
{
+ PTHREADINFO pti;
static INT dead_char = 0;
LONG UState = 0;
WCHAR wp[2] = { 0 };
BOOL Result = FALSE;
DWORD ScanCode = 0;
-
- keyLayout = PsGetCurrentThreadWin32Thread()->KeyboardLayout;
+ pti = PsGetCurrentThreadWin32Thread();
+ 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;
- ScanCode = (lpMsg->lParam >> 16) & 0xff;
-
/* All messages have to contain the cursor point. */
- IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
- &NewMsg.pt);
+ NewMsg.pt = gpsi->ptCursor;
+
+ 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;
+ }
+
+ ScanCode = (lpMsg->lParam >> 16) & 0xff;
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
gQueueKeyStateTable, wp, 2, 0,
NewMsg.wParam = dead_char;
NewMsg.lParam = lpMsg->lParam;
dead_char = 0;
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
}
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
Result = TRUE;
}
else if (UState == -1)
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0];
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
Result = TRUE;
}
}
DWORD
-STDCALL
+APIENTRY
NtUserGetKeyboardState(
LPBYTE lpKeyState)
{
BOOL Result = TRUE;
DECLARE_RETURN(DWORD);
-
+
DPRINT("Enter NtUserGetKeyboardState\n");
UserEnterShared();
-
+
if (lpKeyState)
{
if(!NT_SUCCESS(MmCopyToCaller(lpKeyState, gQueueKeyStateTable, 256)))
}
RETURN(Result);
-
+
CLEANUP:
DPRINT("Leave NtUserGetKeyboardState, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
-DWORD
-STDCALL
+BOOL
+APIENTRY
NtUserSetKeyboardState(LPBYTE lpKeyState)
{
BOOL Result = TRUE;
DECLARE_RETURN(DWORD);
-
+
DPRINT("Enter NtUserSetKeyboardState\n");
UserEnterExclusive();
if(! NT_SUCCESS(MmCopyFromCaller(gQueueKeyStateTable, lpKeyState, 256)))
Result = FALSE;
}
-
+
RETURN(Result);
CLEANUP:
switch( Type )
{
case 0:
- if( Code == VK_RSHIFT )
+ if( Code == VK_SHIFT )
Code = VK_LSHIFT;
- if( Code == VK_RMENU )
+ if( Code == VK_MENU )
Code = VK_LMENU;
- if( Code == VK_RCONTROL )
+ if( Code == VK_CONTROL )
Code = VK_LCONTROL;
ret = VkToScan( Code, FALSE, keyLayout );
break;
}
UINT
-STDCALL
+APIENTRY
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl )
{
+ PTHREADINFO pti;
PKBDTABLES keyLayout;
DECLARE_RETURN(UINT);
-
+
DPRINT("Enter NtUserMapVirtualKeyEx\n");
UserEnterExclusive();
-
- keyLayout = PsGetCurrentThreadWin32Thread() ? PsGetCurrentThreadWin32Thread()->KeyboardLayout : 0;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
if( !keyLayout )
RETURN(0);
RETURN(IntMapVirtualKeyEx( Code, Type, keyLayout ));
-
+
CLEANUP:
DPRINT("Leave NtUserMapVirtualKeyEx, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+ END_CLEANUP;
}
int
-STDCALL
+APIENTRY
NtUserToUnicodeEx(
UINT wVirtKey,
UINT wScanCode,
UINT wFlags,
HKL dwhkl )
{
+ PTHREADINFO pti;
BYTE KeyStateBuf[0x100];
PWCHAR OutPwszBuff = 0;
int ret = 0;
DECLARE_RETURN(int);
-
+
DPRINT("Enter NtUserSetKeyboardState\n");
- UserEnterShared();//faxme: this syscall doesnt seem to need any locking...
+ 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,
DPRINT1( "Couldn't copy key state from caller.\n" );
RETURN(0);
}
- OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
- if( !OutPwszBuff )
+
+ /* Virtual code is correct? */
+ if (wVirtKey < 0x100)
{
- DPRINT1( "ExAllocatePool(%d) failed\n", sizeof(WCHAR) * cchBuff);
- RETURN(0);
+ OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
+ if( !OutPwszBuff )
+ {
+ DPRINT1( "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);
}
- RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
-
- ret = ToUnicodeEx( wVirtKey,
- wScanCode,
- KeyStateBuf,
- OutPwszBuff,
- cchBuff,
- wFlags,
- dwhkl );
-
- MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
- ExFreePool(OutPwszBuff);
RETURN(ret);
-
+
CLEANUP:
DPRINT("Leave NtUserSetKeyboardState, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+ END_CLEANUP;
}
static int W32kSimpleToupper( int ch )
}
DWORD
-STDCALL
+APIENTRY
NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize )
{
+ PTHREADINFO pti;
int i;
DWORD ret = 0;
UINT CareVk = 0;
PKBDTABLES keyLayout;
VSC_LPWSTR *KeyNames;
DECLARE_RETURN(DWORD);
-
+
DPRINT("Enter NtUserGetKeyNameText\n");
UserEnterShared();
-
- keyLayout = PsGetCurrentThreadWin32Thread() ?
- PsGetCurrentThreadWin32Thread()->KeyboardLayout : 0;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
if( !keyLayout || nSize < 1 )
RETURN(0);
if( lParam & (1<<25) )
{
CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
- if( VkCode == VK_LSHIFT || VkCode == VK_RSHIFT )
- VkCode = VK_LSHIFT;
- if( VkCode == VK_LCONTROL || VkCode == VK_RCONTROL )
- VkCode = VK_LCONTROL;
- if( VkCode == VK_LMENU || VkCode == VK_RMENU )
- VkCode = VK_LMENU;
+ 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
{
}
RETURN(ret);
-
+
CLEANUP:
DPRINT("Leave NtUserGetKeyNameText, ret=%i\n",_ret_);
UserLeave();
}
-DWORD
-STDCALL
-NtUserGetKeyboardLayoutList(
- DWORD Items,
- DWORD pHklBuff)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-BOOL
-STDCALL
-NtUserGetKeyboardLayoutName(
- LPWSTR lpszName)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-HKL FASTCALL
-UserGetKeyboardLayout(
- DWORD dwThreadId)
-{
- NTSTATUS Status;
- PETHREAD Thread;
- PW32THREAD W32Thread;
- PKBDTABLES layout;
-
- if (!dwThreadId)
- W32Thread = PsGetCurrentThreadWin32Thread();
- else
- {
- Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);//fixme: deref thread
- if(!NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- W32Thread = Thread->Tcb.Win32Thread; /* Wrong, but returning the pointer to
- the table. */
- }
- layout = W32Thread->KeyboardLayout;
- if(!layout)
- return 0;
- return (HKL)layout;
-}
-
-
-HKL
-STDCALL
-NtUserGetKeyboardLayout(
- DWORD dwThreadId)
-{
- DECLARE_RETURN(HKL);
-
- UserEnterShared();
- DPRINT("Enter NtUserGetKeyboardLayout\n");
-
- RETURN( UserGetKeyboardLayout(dwThreadId));
-
-CLEANUP:
- DPRINT("Leave NtUserGetKeyboardLayout, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
DWORD FASTCALL
}
-HKL
-STDCALL
-NtUserLoadKeyboardLayoutEx(
- IN HANDLE Handle,
- IN DWORD offTable,
- IN HKL hKL,
- IN PUNICODE_STRING puszKLID,
- IN UINT KLayoutLangID,
- IN UINT Flags)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
Based on TryToTranslateChar, instead of processing VirtualKey match,
look for wChar match.
*/
DWORD
-STDCALL
+APIENTRY
NtUserVkKeyScanEx(
- DWORD wChar,
- DWORD KeyboardLayout,
- DWORD Unknown2)
+ WCHAR wChar,
+ HKL hKeyboardLayout,
+ BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
{
-/* FAXME: currently, this routine doesnt seem to need any locking */
-
PKBDTABLES KeyLayout;
PVK_TO_WCHAR_TABLE vtwTbl;
PVK_TO_WCHARS10 vkPtr;
size_t size_this_entry;
int nMod;
- DWORD CapsMod = 0, CapsState = 0;
+ PKBL pkbl = NULL;
+ DWORD CapsMod = 0, CapsState = 0, Ret = -1;
- if(!KeyboardLayout)
- return -1;
- KeyLayout = (PKBDTABLES) KeyboardLayout;
+ DPRINT("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++)
{
CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
DPRINT("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
- return ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
+ Ret = ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
+ goto Exit;
}
}
vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
}
}
- return -1;
+Exit:
+ UserLeave();
+ return Ret;
}