/****************************************************************************/ /* keyboard.c */ /* */ /* Keyboard IOCtl handling */ /* */ /* Copyright 1996, Citrix Systems Inc. */ /* Copyright (C) 1997-1999 Microsoft Corporation */ /****************************************************************************/ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #pragma hdrstop #define TRC_FILE "keyboard" #define pTRCWd pWd #include #include #include #include /******************************************************************************* * * KeyboardQueryAttributes * * return the keyboard attributes * * typedef struct _KEYBOARD_ID { * UCHAR Type; * UCHAR Subtype; * } KEYBOARD_ID, *PKEYBOARD_ID; * * typedef struct _KEYBOARD_ATTRIBUTES { * KEYBOARD_ID KeyboardIdentifier; * USHORT KeyboardMode; * USHORT NumberOfFunctionKeys; * USHORT NumberOfIndicators; * USHORT NumberOfKeysTotal; * ULONG InputDataQueueLength; * KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatMinimum; * KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatMaximum; * } KEYBOARD_ATTRIBUTES, *PKEYBOARD_ATTRIBUTES; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - nothing * output - KEYBOARD_ATTRIBUTES * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardQueryAttributes( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_ATTRIBUTES pAttrib; if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES) ) return( STATUS_BUFFER_TOO_SMALL ); pAttrib = (PKEYBOARD_ATTRIBUTES)pSdIoctl->OutputBuffer; pAttrib->KeyboardIdentifier.Type = 4; pAttrib->KeyboardIdentifier.Subtype = 0; pAttrib->KeyboardMode = 1; pAttrib->NumberOfFunctionKeys = 12; pAttrib->NumberOfIndicators = 3; pAttrib->NumberOfKeysTotal = 101; pAttrib->InputDataQueueLength = 100; pAttrib->KeyRepeatMinimum.UnitId = 0; pAttrib->KeyRepeatMinimum.Rate = 2; pAttrib->KeyRepeatMinimum.Delay = 250; pAttrib->KeyRepeatMaximum.UnitId = 0; pAttrib->KeyRepeatMaximum.Rate = 30; pAttrib->KeyRepeatMaximum.Delay = 1000; pSdIoctl->BytesReturned = sizeof(KEYBOARD_ATTRIBUTES); return( STATUS_SUCCESS ); } /******************************************************************************* * * KeyboardQueryTypematic * * return the keyboard typematic rate * * typedef struct _KEYBOARD_TYPEMATIC_PARAMETERS { * USHORT UnitId; * USHORT Rate; * USHORT Delay; * } KEYBOARD_TYPEMATIC_PARAMETERS, *PKEYBOARD_TYPEMATIC_PARAMETERS; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - nothing * output - KEYBOARD_TYPEMATIC_PARAMETERS * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardQueryTypematic( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_TYPEMATIC_PARAMETERS pTypematic; if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS) ) return( STATUS_BUFFER_TOO_SMALL ); pTypematic = (PKEYBOARD_TYPEMATIC_PARAMETERS)pSdIoctl->OutputBuffer; *pTypematic = pWd->KeyboardTypematic; pSdIoctl->BytesReturned = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS); return( STATUS_SUCCESS ); } /******************************************************************************* * * KeyboardSetTypematic * * set the keyboard typematic rate * * typedef struct _KEYBOARD_TYPEMATIC_PARAMETERS { * USHORT UnitId; * USHORT Rate; * USHORT Delay; * } KEYBOARD_TYPEMATIC_PARAMETERS, *PKEYBOARD_TYPEMATIC_PARAMETERS; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - KEYBOARD_TYPEMATIC_PARAMETERS * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetTypematic( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_TYPEMATIC_PARAMETERS pTypematic; if ( pSdIoctl->InputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS) ) return( STATUS_BUFFER_TOO_SMALL ); pTypematic = (PKEYBOARD_TYPEMATIC_PARAMETERS)pSdIoctl->InputBuffer; pWd->KeyboardTypematic = *pTypematic; return( STATUS_SUCCESS ); } /******************************************************************************* * * KeyboardQueryIndicators * * return the state of the keyboard indicators * * typedef struct _KEYBOARD_INDICATOR_PARAMETERS { * USHORT UnitId; * USHORT LedFlags; * } KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - nothing * output - KEYBOARD_INDICATOR_PARAMETERS * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardQueryIndicators( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_INDICATOR_PARAMETERS pIndicator; if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS) ) return( STATUS_BUFFER_TOO_SMALL ); pIndicator = (PKEYBOARD_INDICATOR_PARAMETERS)pSdIoctl->OutputBuffer; *pIndicator = pWd->KeyboardIndicators; pSdIoctl->BytesReturned = sizeof(KEYBOARD_INDICATOR_PARAMETERS); return( STATUS_SUCCESS ); } /******************************************************************************* * * KeyboardSetIndicators * * set the keyboard indicators * * typedef struct _KEYBOARD_INDICATOR_PARAMETERS { * USHORT UnitId; * USHORT LedFlags; * } KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - KEYBOARD_INDICATOR_PARAMETERS * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetIndicators( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_INDICATOR_PARAMETERS pIndicator; NTSTATUS Status = STATUS_SUCCESS; if (pSdIoctl->InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { Status = STATUS_BUFFER_TOO_SMALL; } else { pIndicator = (PKEYBOARD_INDICATOR_PARAMETERS)pSdIoctl->InputBuffer; if (pWd->KeyboardIndicators.LedFlags != (pIndicator->LedFlags & 0x7)) { pWd->KeyboardIndicators.UnitId = pIndicator->UnitId; pWd->KeyboardIndicators.LedFlags = (pIndicator->LedFlags & 0x7); if ((pWd->StackClass == Stack_Shadow) || (pIndicator->LedFlags & KEYBOARD_LED_INJECTED)) { WDWKeyboardSetIndicators(pWd); } } } return( Status ); } /******************************************************************************* * * KeyboardQueryIndicatorTranslation * * return the state of the keyboard indicators * * typedef struct _INDICATOR_LIST { * USHORT MakeCode; * USHORT IndicatorFlags; * } INDICATOR_LIST, *PINDICATOR_LIST; * * typedef struct _KEYBOARD_INDICATOR_TRANSLATION { * USHORT NumberOfIndicatorKeys; * INDICATOR_LIST IndicatorList[1]; * } KEYBOARD_INDICATOR_TRANSLATION, *PKEYBOARD_INDICATOR_TRANSLATION; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - nothing * output - ICA_STACK_CONFIG * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardQueryIndicatorTranslation( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { pSdIoctl->BytesReturned = 0; return( STATUS_INVALID_DEVICE_REQUEST ); } /******************************************************************************* * * KeyboardSetLayout * * set the keyboard layouts for shadow hotkey processing * * ENTRY: * pWd (input) * pointer to wd data structure * pSdIoctl (input/output) * input - keyboard layout table * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetLayout( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { NTSTATUS Status; PVOID pKbdLayout; PVOID pKbdTbl; if ( pSdIoctl->InputBufferLength < 1 ) { Status = STATUS_BUFFER_TOO_SMALL; goto error; } /* * The keyboard layout is in winstation space so copy it to a new buffer and * adjust the pointers. The pointers where all relative to a base address before * so just duplicate the fixup code from Win32K. */ pKbdLayout = COM_Malloc(pSdIoctl->InputBufferLength); if (pKbdLayout == NULL) { Status = STATUS_NO_MEMORY; goto error; } RtlCopyMemory( pKbdLayout, pSdIoctl->InputBuffer, pSdIoctl->InputBufferLength ); Status = KeyboardFixupLayout( pKbdLayout, pSdIoctl->InputBuffer, pSdIoctl->InputBufferLength, pSdIoctl->OutputBuffer, &pKbdTbl ); if ( !NT_SUCCESS( Status ) ) { COM_Free( pKbdLayout ); pKbdLayout = NULL; goto error; } if ( pWd->pKbdLayout ) COM_Free( pWd->pKbdLayout ); pWd->pKbdLayout = pKbdLayout; pWd->pKbdTbl = pKbdTbl; error: TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetLayout %X\n", Status )); return( Status ); } /******************************************************************************* * * KeyboardSetScanMap * * set the keyboard scan map for shadow hotkey processing * * ENTRY: * pWd (input) * pointer to wd data structure * pSdIoctl (input/output) * input - keyboard scan map table * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetScanMap( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { NTSTATUS Status; PVOID pScanMap; DC_BEGIN_FN("KeyboardSetScanMap"); if (pSdIoctl->InputBufferLength >= 1) { // The keyboard scan code map is in winstation space so copy it to // a new buffer. pScanMap = COM_Malloc( pSdIoctl->InputBufferLength ); if (pScanMap != NULL ) { RtlCopyMemory(pScanMap, pSdIoctl->InputBuffer, pSdIoctl->InputBufferLength); // Scancode maps are allocated once. TRC_ASSERT((pWd->gpScancodeMap == NULL), (TB,"Previous scancode map present")); pWd->gpScancodeMap = pScanMap; Status = STATUS_SUCCESS; } else { Status = STATUS_NO_MEMORY; } } else { Status = STATUS_BUFFER_TOO_SMALL; } TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetScanMap %X\n", Status )); DC_END_FN(); return Status; } /******************************************************************************* * * KeyboardSetType * * set the keyboard scan map for shadow hotkey processing * * ENTRY: * pWd (input) * pointer to wd data structure * pSdIoctl (input/output) * input - keyboard type * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetType( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { NTSTATUS Status = STATUS_SUCCESS; if ( pSdIoctl->InputBufferLength < sizeof(BOOLEAN) ) { Status = STATUS_BUFFER_TOO_SMALL; goto error; } pWd->KeyboardType101 = *(PBOOLEAN)(pSdIoctl->InputBuffer); error: TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetType %X\n", Status )); return( Status ); } /******************************************************************************* * * KeyboardSetImeStatus * * set ime status to the keyboard * * typedef struct _KEYBOARD_IME_STATUS { * USHORT UnitId; * ULONG ImeOpen; * ULONG ImeConvMode; * } KEYBOARD_IME_STATUS, *PKEYBOARD_IME_STATUS; * * * ENTRY: * pWd (input) * Pointer to wd data structure * pSdIoctl (input/output) * input - KEYBOARD_IME_STATUS * output - nothing * * EXIT: * STATUS_SUCCESS - no error * ******************************************************************************/ NTSTATUS KeyboardSetImeStatus( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl ) { PKEYBOARD_IME_STATUS pImeStatus; NTSTATUS Status = STATUS_SUCCESS; if (pSdIoctl->InputBufferLength < sizeof(KEYBOARD_IME_STATUS)) { Status = STATUS_BUFFER_TOO_SMALL; } else { pImeStatus = (PKEYBOARD_IME_STATUS)pSdIoctl->InputBuffer; pWd->KeyboardImeStatus = *pImeStatus; WDWKeyboardSetImeStatus(pWd); } return( Status ); } #ifdef __cplusplus } #endif /* __cplusplus */