Source code of Windows XP (NT5)
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.

153 lines
4.9 KiB

  1. /*************************************************************************
  2. *
  3. * keyboard.c
  4. *
  5. * This module contains routines for managing the ICA keyboard channel.
  6. *
  7. * Copyright 1998, Microsoft.
  8. *
  9. *************************************************************************/
  10. /*
  11. * Includes
  12. */
  13. #include <precomp.h>
  14. #pragma hdrstop
  15. #include <ntddkbd.h>
  16. NTSTATUS
  17. IcaDeviceControlKeyboard(
  18. IN PICA_CHANNEL pChannel,
  19. IN PIRP Irp,
  20. IN PIO_STACK_LOCATION IrpSp
  21. )
  22. /*++
  23. Routine Description:
  24. This is the device control routine for the ICA keyboard channel.
  25. Arguments:
  26. pChannel -- pointer to ICA_CHANNEL object
  27. Irp - Pointer to I/O request packet
  28. IrpSp - pointer to the stack location to use for this request.
  29. Return Value:
  30. NTSTATUS -- Indicates whether the request was successfully queued.
  31. --*/
  32. {
  33. ULONG code;
  34. SD_IOCTL SdIoctl;
  35. PICA_STACK pStack;
  36. NTSTATUS Status;
  37. /*
  38. * Extract the IOCTL control code and process the request.
  39. */
  40. code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
  41. TRACECHANNEL(( pChannel, TC_ICADD, TT_API1, "ICADD: IcaDeviceControlKeyboard, fc %d, ref %u (enter)\n",
  42. (code & 0x3fff) >> 2, pChannel->RefCount ));
  43. switch ( code ) {
  44. #if 0 // no longer used
  45. /*
  46. * Special IOCTL to allow keyboard input data to be fed
  47. * into the keyboard channel.
  48. */
  49. case IOCTL_KEYBOARD_ICA_INPUT :
  50. /*
  51. * Make sure the input data is the correct size.
  52. */
  53. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength %
  54. sizeof(KEYBOARD_INPUT_DATA) )
  55. return( STATUS_BUFFER_TOO_SMALL );
  56. /*
  57. * We need a stack object to pass to IcaChannelInputInternal.
  58. * Any one will do so we grab the head of the stack list.
  59. * (There MUST be one for this IOCTL to succeed.)
  60. */
  61. IcaLockConnection( pChannel->pConnect );
  62. if ( IsListEmpty( &pChannel->pConnect->StackHead ) ) {
  63. IcaUnlockConnection( pChannel->pConnect );
  64. return( STATUS_INVALID_DEVICE_REQUEST );
  65. }
  66. pStack = CONTAINING_RECORD( pChannel->pConnect->StackHead.Flink,
  67. ICA_STACK, StackEntry );
  68. IcaReferenceStack( pStack );
  69. IcaUnlockConnection( pChannel->pConnect );
  70. /*
  71. * Send keyboard input
  72. */
  73. IcaChannelInputInternal( pStack, Channel_Keyboard, 0, NULL,
  74. (PCHAR)IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  75. IrpSp->Parameters.DeviceIoControl.InputBufferLength );
  76. IcaDereferenceStack( pStack );
  77. Status = STATUS_SUCCESS;
  78. break;
  79. #endif
  80. /*
  81. * The following keyboard ioctls use METHOD_NEITHER so get the
  82. * input buffer from the DeviceIoControl parameters.
  83. */
  84. case IOCTL_KEYBOARD_ICA_LAYOUT :
  85. case IOCTL_KEYBOARD_ICA_SCANMAP :
  86. case IOCTL_KEYBOARD_ICA_TYPE :
  87. if ( Irp->RequestorMode != KernelMode ) {
  88. ProbeForRead( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  89. IrpSp->Parameters.DeviceIoControl.InputBufferLength,
  90. TYPE_ALIGNMENT(BYTE) );
  91. ProbeForWrite( Irp->UserBuffer,
  92. IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  93. TYPE_ALIGNMENT(BYTE) );
  94. }
  95. SdIoctl.IoControlCode = code;
  96. SdIoctl.InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  97. SdIoctl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  98. SdIoctl.OutputBuffer = Irp->UserBuffer;
  99. SdIoctl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  100. Status = IcaCallDriver( pChannel, SD$IOCTL, &SdIoctl );
  101. break;
  102. /*
  103. * All other keyboard ioctls use METHOD_BUFFERED so get the
  104. * input buffer from the AssociatedIrp.SystemBuffer field.
  105. */
  106. default:
  107. SdIoctl.IoControlCode = code;
  108. SdIoctl.InputBuffer = Irp->AssociatedIrp.SystemBuffer;
  109. SdIoctl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  110. SdIoctl.OutputBuffer = SdIoctl.InputBuffer;
  111. SdIoctl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  112. Status = IcaCallDriver( pChannel, SD$IOCTL, &SdIoctl );
  113. if (Status == STATUS_SUCCESS )
  114. Irp->IoStatus.Information = SdIoctl.BytesReturned;
  115. break;
  116. }
  117. TRACECHANNEL(( pChannel, TC_ICADD, TT_API1, "ICADD: IcaDeviceControlKeyboard, fc %d, ref %u, 0x%x\n",
  118. (code & 0x3fff) >> 2, pChannel->RefCount, Status ));
  119. return( Status );
  120. }