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.

273 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. Create.c
  5. Abstract:
  6. This module contains the code for IRP_MJ_CREATE and IRP_MJ_CLOSE
  7. and IRP_MJ_DEVICE_CONTROL
  8. Environment:
  9. Kernel & user mode
  10. Revision History:
  11. Nov-96 : Created by Kenneth D. Ray
  12. --*/
  13. #include "kbdhid.h"
  14. NTSTATUS
  15. KbdHid_CreateComplete (
  16. IN PDEVICE_OBJECT DeviceObject,
  17. IN PIRP Irp,
  18. IN PVOID Context
  19. )
  20. /*++
  21. Routine Description:
  22. The pnp IRP is in the process of completing.
  23. signal
  24. Arguments:
  25. Context set to the device object in question.
  26. --*/
  27. {
  28. UNREFERENCED_PARAMETER (DeviceObject);
  29. KeSetEvent ((PKEVENT) Context, 0, FALSE);
  30. return STATUS_MORE_PROCESSING_REQUIRED;
  31. }
  32. NTSTATUS
  33. KbdHid_Create (
  34. IN PDEVICE_OBJECT DeviceObject, // the kbdhid device object
  35. IN PIRP Irp
  36. )
  37. /*++
  38. Routine Description:
  39. This is the dispatch routine for create/open requests. This request
  40. completes successfully, unless the filename's length is non-zero.
  41. Arguments:
  42. DeviceObject - Pointer to the device object.
  43. Irp - Pointer to the request packet.
  44. Return Value:
  45. NT status code.
  46. --*/
  47. {
  48. PIO_STACK_LOCATION irpSp = NULL;
  49. NTSTATUS status = STATUS_SUCCESS;
  50. PDEVICE_EXTENSION data = NULL;
  51. KEVENT event;
  52. Print(DBG_CC_TRACE, ("DispatchCreate: Enter.\n"));
  53. data = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  54. //
  55. // Get a pointer to the current parameters for this request. The
  56. // information is contained in the current stack location.
  57. //
  58. irpSp = IoGetCurrentIrpStackLocation (Irp);
  59. //
  60. // Determine if request is trying to open a subdirectory of the
  61. // given device object. This is not allowed.
  62. //
  63. if (0 != irpSp->FileObject->FileName.Length) {
  64. Print(DBG_CC_ERROR, ("ERROR: Create Access Denied.\n"));
  65. status = STATUS_ACCESS_DENIED;
  66. goto KbdHid_CreateReject;
  67. }
  68. status = IoAcquireRemoveLock (&data->RemoveLock, Irp);
  69. if (!NT_SUCCESS (status)) {
  70. goto KbdHid_CreateReject;
  71. }
  72. ExAcquireFastMutex (&data->CreateCloseMutex);
  73. if (NULL == data->ConnectData.ClassService) {
  74. //
  75. // No Connection yet. How can we be enabled?
  76. //
  77. Print (DBG_IOCTL_ERROR, ("ERROR: enable before connect!\n"));
  78. status = STATUS_UNSUCCESSFUL;
  79. } else {
  80. IoCopyCurrentIrpStackLocationToNext (Irp);
  81. KeInitializeEvent(&event, NotificationEvent, FALSE);
  82. IoSetCompletionRoutine (Irp,
  83. KbdHid_CreateComplete,
  84. &event,
  85. TRUE,
  86. TRUE,
  87. TRUE);
  88. status = IoCallDriver (data->TopOfStack, Irp);
  89. KeWaitForSingleObject(&event,
  90. Executive, // Waiting for reason of a driver
  91. KernelMode, // Waiting in kernel mode
  92. FALSE, // No allert
  93. NULL); // No timeout
  94. if (NT_SUCCESS (status)) {
  95. status = Irp->IoStatus.Status;
  96. }
  97. if (NT_SUCCESS (status)) {
  98. InterlockedIncrement(&data->EnableCount);
  99. if (NULL == data->ReadFile &&
  100. (irpSp->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA)) {
  101. //
  102. // We want to start the read pump.
  103. //
  104. Print (DBG_IOCTL_INFO, ("Enabling Keyboard \n"));
  105. data->ReadFile = irpSp->FileObject;
  106. KeResetEvent (&data->ReadCompleteEvent);
  107. data->ReadInterlock = KBDHID_END_READ;
  108. // Acquire another time for the read irp.
  109. IoAcquireRemoveLock (&data->RemoveLock, data->ReadIrp);
  110. data->ReadIrp->IoStatus.Status = STATUS_SUCCESS;
  111. status = KbdHid_StartRead (data);
  112. if (STATUS_PENDING == status) {
  113. status = STATUS_SUCCESS;
  114. } else if (!NT_SUCCESS(status)) {
  115. //
  116. // Set it back to NULL so that a future open tries again.
  117. // Read should not fail if open passed. ASSERT!
  118. //
  119. ASSERT(NT_SUCCESS(status));
  120. data->ReadFile = NULL;
  121. }
  122. }
  123. ASSERT (data->EnableCount < 100);
  124. ASSERT (0 < data->EnableCount);
  125. }
  126. }
  127. ExReleaseFastMutex (&data->CreateCloseMutex);
  128. Irp->IoStatus.Status = status;
  129. Irp->IoStatus.Information = 0;
  130. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  131. IoReleaseRemoveLock (&data->RemoveLock, Irp);
  132. Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
  133. return status;
  134. KbdHid_CreateReject:
  135. Irp->IoStatus.Status = status;
  136. Irp->IoStatus.Information = 0;
  137. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  138. Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
  139. return status;
  140. }
  141. NTSTATUS
  142. KbdHid_Close (
  143. IN PDEVICE_OBJECT DeviceObject, // the kbdhid device object
  144. IN PIRP Irp
  145. )
  146. /*++
  147. Routine Description:
  148. This is the dispatch routine for close requests. This request
  149. completes successfully, unless the file name length is zero.
  150. Arguments:
  151. DeviceObject - Pointer to the device object.
  152. Irp - Pointer to the request packet.
  153. Return Value:
  154. NT status code.
  155. --*/
  156. {
  157. PDEVICE_EXTENSION data;
  158. PIO_STACK_LOCATION stack;
  159. LARGE_INTEGER time;
  160. Print(DBG_CC_TRACE, ("DispatchClose: Enter\n"));
  161. data = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  162. stack = IoGetCurrentIrpStackLocation (Irp);
  163. ExAcquireFastMutex (&data->CreateCloseMutex);
  164. ASSERT (data->EnableCount < 100);
  165. ASSERT (0 < data->EnableCount);
  166. if (0 == InterlockedDecrement(&data->EnableCount)) {
  167. Print (DBG_IOCTL_INFO, ("Disabling Keyboard \n"));
  168. KeWaitForSingleObject (&data->ReadSentEvent,
  169. Executive,
  170. KernelMode,
  171. FALSE,
  172. NULL
  173. );
  174. if (IoCancelIrp (data->ReadIrp)) {
  175. KeWaitForSingleObject (&data->ReadCompleteEvent,
  176. Executive,
  177. KernelMode,
  178. FALSE,
  179. NULL
  180. );
  181. }
  182. // ASSERT (NULL != data->ReadFile);
  183. // ASSERT (data->ReadFile == stack->FileObject);
  184. time = data->AutoRepeatDelay;
  185. KeCancelTimer (&data->AutoRepeatTimer);
  186. #if KEYBOARD_HW_CHATTERY_FIX
  187. KeCancelTimer (&data->InitiateStartReadTimer);
  188. //
  189. // NB the time is a negative (relative) number;
  190. //
  191. if (data->InitiateStartReadDelay.QuadPart < time.QuadPart) {
  192. time = data->InitiateStartReadDelay;
  193. }
  194. #endif // KEYBOARD_HW_CHATTERY_FIX
  195. time.QuadPart *= 2;
  196. KeDelayExecutionThread (KernelMode, FALSE, &time);
  197. data->ReadFile = NULL;
  198. }
  199. ExReleaseFastMutex (&data->CreateCloseMutex);
  200. IoSkipCurrentIrpStackLocation (Irp);
  201. Print(DBG_CC_TRACE, ("DispatchClose: Exit \n"));
  202. return IoCallDriver (data->TopOfStack, Irp);
  203. }