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.

268 lines
7.0 KiB

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