Leaked source code of windows server 2003
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.

163 lines
5.4 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. CLONG Method;
  38. /*
  39. * Extract the IOCTL control code and process the request.
  40. */
  41. code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
  42. TRACECHANNEL(( pChannel, TC_ICADD, TT_API1, "ICADD: IcaDeviceControlKeyboard, fc %d, ref %u (enter)\n",
  43. (code & 0x3fff) >> 2, pChannel->RefCount ));
  44. switch ( code ) {
  45. #if 0 // no longer used
  46. /*
  47. * Special IOCTL to allow keyboard input data to be fed
  48. * into the keyboard channel.
  49. */
  50. case IOCTL_KEYBOARD_ICA_INPUT :
  51. /*
  52. * Make sure the input data is the correct size.
  53. */
  54. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength %
  55. sizeof(KEYBOARD_INPUT_DATA) )
  56. return( STATUS_BUFFER_TOO_SMALL );
  57. /*
  58. * We need a stack object to pass to IcaChannelInputInternal.
  59. * Any one will do so we grab the head of the stack list.
  60. * (There MUST be one for this IOCTL to succeed.)
  61. */
  62. IcaLockConnection( pChannel->pConnect );
  63. if ( IsListEmpty( &pChannel->pConnect->StackHead ) ) {
  64. IcaUnlockConnection( pChannel->pConnect );
  65. return( STATUS_INVALID_DEVICE_REQUEST );
  66. }
  67. pStack = CONTAINING_RECORD( pChannel->pConnect->StackHead.Flink,
  68. ICA_STACK, StackEntry );
  69. IcaReferenceStack( pStack );
  70. IcaUnlockConnection( pChannel->pConnect );
  71. /*
  72. * Send keyboard input
  73. */
  74. IcaChannelInputInternal( pStack, Channel_Keyboard, 0, NULL,
  75. (PCHAR)IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  76. IrpSp->Parameters.DeviceIoControl.InputBufferLength );
  77. IcaDereferenceStack( pStack );
  78. Status = STATUS_SUCCESS;
  79. break;
  80. #endif
  81. /*
  82. * The following keyboard ioctls use METHOD_NEITHER so get the
  83. * input buffer from the DeviceIoControl parameters.
  84. */
  85. case IOCTL_KEYBOARD_ICA_LAYOUT :
  86. case IOCTL_KEYBOARD_ICA_SCANMAP :
  87. case IOCTL_KEYBOARD_ICA_TYPE :
  88. if ( Irp->RequestorMode != KernelMode ) {
  89. ProbeForRead( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  90. IrpSp->Parameters.DeviceIoControl.InputBufferLength,
  91. TYPE_ALIGNMENT(BYTE) );
  92. ProbeForWrite( Irp->UserBuffer,
  93. IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  94. TYPE_ALIGNMENT(BYTE) );
  95. }
  96. SdIoctl.IoControlCode = code;
  97. SdIoctl.InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  98. SdIoctl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  99. SdIoctl.OutputBuffer = Irp->UserBuffer;
  100. SdIoctl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  101. Status = IcaCallDriver( pChannel, SD$IOCTL, &SdIoctl );
  102. break;
  103. /*
  104. * All other keyboard ioctls use METHOD_BUFFERED so get the
  105. * input buffer from the AssociatedIrp.SystemBuffer field.
  106. */
  107. default:
  108. // Verify the buffer method.
  109. Method = code & 0x03;
  110. ASSERT( Method == METHOD_BUFFERED );
  111. if ( Method != METHOD_BUFFERED ) {
  112. Status = STATUS_INVALID_DEVICE_REQUEST;
  113. }
  114. else {
  115. SdIoctl.IoControlCode = code;
  116. SdIoctl.InputBuffer = Irp->AssociatedIrp.SystemBuffer;
  117. SdIoctl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  118. SdIoctl.OutputBuffer = SdIoctl.InputBuffer;
  119. SdIoctl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  120. Status = IcaCallDriver( pChannel, SD$IOCTL, &SdIoctl );
  121. if (Status == STATUS_SUCCESS )
  122. Irp->IoStatus.Information = SdIoctl.BytesReturned;
  123. }
  124. break;
  125. }
  126. TRACECHANNEL(( pChannel, TC_ICADD, TT_API1, "ICADD: IcaDeviceControlKeyboard, fc %d, ref %u, 0x%x\n",
  127. (code & 0x3fff) >> 2, pChannel->RefCount, Status ));
  128. return( Status );
  129. }