You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
507 lines
14 KiB
507 lines
14 KiB
/****************************************************************************/
|
|
/* keyboard.c */
|
|
/* */
|
|
/* Keyboard IOCtl handling */
|
|
/* */
|
|
/* Copyright 1996, Citrix Systems Inc. */
|
|
/* Copyright (C) 1997-1999 Microsoft Corporation */
|
|
/****************************************************************************/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
#include <precomp.h>
|
|
#pragma hdrstop
|
|
|
|
#define TRC_FILE "keyboard"
|
|
#define pTRCWd pWd
|
|
#include <adcg.h>
|
|
#include <nwdwapi.h>
|
|
#include <nwdwint.h>
|
|
#include <acomapi.h>
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* 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 */
|
|
|