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.

258 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. UNREFERENCED_PARAMETER (DeviceObject);
  30. KeSetEvent ((PKEVENT) Context, 0, FALSE);
  31. return STATUS_MORE_PROCESSING_REQUIRED;
  32. }
  33. NTSTATUS
  34. MouHid_Create (
  35. IN PDEVICE_OBJECT DeviceObject,
  36. IN PIRP Irp
  37. )
  38. /*++
  39. Routine Description:
  40. This is the dispatch routine for create/open requests. This request
  41. completes successfully, unless the filename's length is non-zero.
  42. Arguments:
  43. DeviceObject - Pointer to the device object.
  44. Irp - Pointer to the request packet.
  45. Return Value:
  46. NT status code.
  47. --*/
  48. {
  49. PIO_STACK_LOCATION irpSp = NULL;
  50. NTSTATUS status = STATUS_SUCCESS;
  51. PDEVICE_EXTENSION data = NULL;
  52. KEVENT event;
  53. Print (DBG_CC_TRACE, ("DispatchCreate: Enter.\n"));
  54. data = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  55. //
  56. // Get a pointer to the current parameters for this request. The
  57. // information is contained in the current stack location.
  58. //
  59. irpSp = IoGetCurrentIrpStackLocation (Irp);
  60. //
  61. // Determine if request is trying to open a subdirectory of the
  62. // given device object. This is not allowed.
  63. //
  64. if (0 != irpSp->FileObject->FileName.Length) {
  65. Print(DBG_CC_ERROR, ("ERROR: Create Access Denied.\n"));
  66. status = STATUS_ACCESS_DENIED;
  67. goto MouHid_CreateReject;
  68. }
  69. status = IoAcquireRemoveLock (&data->RemoveLock, Irp);
  70. if (!NT_SUCCESS (status)) {
  71. goto MouHid_CreateReject;
  72. }
  73. ExAcquireFastMutex (&data->CreateCloseMutex);
  74. if (NULL == data->ConnectData.ClassService) {
  75. //
  76. // No Connection yet. How can we be enabled?
  77. //
  78. Print (DBG_IOCTL_ERROR, ("ERROR: enable before connect!\n"));
  79. status = STATUS_UNSUCCESSFUL;
  80. } else {
  81. IoCopyCurrentIrpStackLocationToNext (Irp);
  82. KeInitializeEvent(&event, NotificationEvent, FALSE);
  83. IoSetCompletionRoutine (Irp,
  84. MouHid_CreateComplete,
  85. &event,
  86. TRUE,
  87. TRUE,
  88. TRUE);
  89. status = IoCallDriver (data->TopOfStack, Irp);
  90. KeWaitForSingleObject(&event,
  91. Executive, // Waiting for reason of a driver
  92. KernelMode, // Waiting in kernel mode
  93. FALSE, // No allert
  94. NULL); // No timeout
  95. if (NT_SUCCESS (status)) {
  96. status = Irp->IoStatus.Status;
  97. }
  98. if (NT_SUCCESS (status)) {
  99. InterlockedIncrement(&data->EnableCount);
  100. if (NULL == data->ReadFile &&
  101. (irpSp->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA)) {
  102. //
  103. // We want to start the read pump.
  104. //
  105. Print (DBG_IOCTL_INFO, ("Enabling Mouse \n"));
  106. data->ReadFile = irpSp->FileObject;
  107. KeResetEvent (&data->ReadCompleteEvent);
  108. data->ReadInterlock = MOUHID_END_READ;
  109. // Acquire another time for the read irp.
  110. IoAcquireRemoveLock (&data->RemoveLock, data->ReadIrp);
  111. data->ReadIrp->IoStatus.Status = STATUS_SUCCESS;
  112. status = MouHid_StartRead (data);
  113. if (STATUS_PENDING == status) {
  114. status = STATUS_SUCCESS;
  115. } else if (!NT_SUCCESS(status)) {
  116. //
  117. // Set it back to NULL so that a future open tries again
  118. // Read should not fail if open passed. ASSERT!
  119. //
  120. ASSERT(NT_SUCCESS(status));
  121. data->ReadFile = NULL;
  122. }
  123. }
  124. ASSERT (data->EnableCount < 100);
  125. ASSERT (0 < data->EnableCount);
  126. }
  127. }
  128. ExReleaseFastMutex (&data->CreateCloseMutex);
  129. Irp->IoStatus.Status = status;
  130. Irp->IoStatus.Information = 0;
  131. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  132. IoReleaseRemoveLock (&data->RemoveLock, Irp);
  133. Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
  134. return status;
  135. MouHid_CreateReject:
  136. Irp->IoStatus.Status = status;
  137. Irp->IoStatus.Information = 0;
  138. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  139. Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
  140. return status;
  141. }
  142. NTSTATUS
  143. MouHid_Close (
  144. IN PDEVICE_OBJECT DeviceObject,
  145. IN PIRP Irp
  146. )
  147. /*++
  148. Routine Description:
  149. This is the dispatch routine for close requests. This request
  150. completes successfully, unless the file name length is zero.
  151. Arguments:
  152. DeviceObject - Pointer to the device object.
  153. Irp - Pointer to the request packet.
  154. Return Value:
  155. NT status code.
  156. --*/
  157. {
  158. PDEVICE_EXTENSION data;
  159. PIO_STACK_LOCATION stack;
  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 Mouse \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. data->ReadFile = NULL;
  185. }
  186. ExReleaseFastMutex (&data->CreateCloseMutex);
  187. IoSkipCurrentIrpStackLocation (Irp);
  188. Print(DBG_CC_TRACE, ("DispatchClose: Exit \n"));
  189. return IoCallDriver (data->TopOfStack, Irp);
  190. }