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.

386 lines
12 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module FLTR.c |
  5. *
  6. * Implementation of basic IRP handlers for Filter Device Objects
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Mitchell S. Dernis Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic FLTR |
  15. * The non-Power and PnP IRP handler routines are handled in this module
  16. * for all Device Objects created as filters for the raw HID-Pdos.
  17. *
  18. **********************************************************************/
  19. #define __DEBUG_MODULE_IN_USE__ GCK_FLTR_C
  20. #include <wdm.h>
  21. #include "Debug.h"
  22. #include "GckShell.h"
  23. DECLARE_MODULE_DEBUG_LEVEL((DBG_WARN|DBG_ERROR|DBG_CRITICAL));
  24. //
  25. // Mark the pageable routines as such
  26. //
  27. #ifdef ALLOC_PRAGMA
  28. #pragma alloc_text (INIT, GCK_FLTR_DriverEntry)
  29. #pragma alloc_text (PAGE, GCK_FLTR_Create)
  30. #pragma alloc_text (PAGE, GCK_FLTR_Close)
  31. #pragma alloc_text (PAGE, GCK_FLTR_Ioctl)
  32. #pragma alloc_text (PAGE, GCK_FLTR_Unload)
  33. #endif
  34. /***********************************************************************************
  35. **
  36. ** NTSTATUS GCK_FLTR_DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
  37. **
  38. ** @func Initializing the portions of the driver related to the filter devices.
  39. **
  40. ** @rdesc STATUS_SUCCESS
  41. **
  42. *************************************************************************************/
  43. NTSTATUS GCK_FLTR_DriverEntry
  44. (
  45. IN PDRIVER_OBJECT pDriverObject, // @parm Driver Object
  46. IN PUNICODE_STRING puniRegistryPath // @parm Path to driver specific registry section.
  47. )
  48. {
  49. UNREFERENCED_PARAMETER(pDriverObject);
  50. UNREFERENCED_PARAMETER(puniRegistryPath);
  51. //
  52. // Initialize Globals related to filter devices
  53. //
  54. GCK_DBG_TRACE_PRINT(("Initializing globals\n"));
  55. Globals.ulFilteredDeviceCount = 0;
  56. Globals.pFilterObjectList = NULL;
  57. Globals.pSWVB_FilterExt=NULL; // Nobody owns the virtual bus yet.
  58. Globals.pVirtualKeyboardPdo = NULL; // No keyboard object
  59. Globals.ulVirtualKeyboardRefCount = 0; // No keyboard users
  60. ExInitializeFastMutex(&Globals.FilterObjectListFMutex);
  61. return STATUS_SUCCESS;
  62. }
  63. /***********************************************************************************
  64. **
  65. ** NTSTATUS GCK_FLTR_Create ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
  66. **
  67. ** @func Handles the IRP_MJ_CREATE for filter devices
  68. ** - Called generated by Win32 API CreateFile or OpenFile
  69. **
  70. ** @rdesc STATUS_SUCCESS, or various error codes
  71. **
  72. *************************************************************************************/
  73. NTSTATUS GCK_FLTR_Create (
  74. IN PDEVICE_OBJECT pDeviceObject, // @parm DO target for IRP
  75. IN PIRP pIrp // @parm IRP
  76. )
  77. {
  78. NTSTATUS NtStatus = STATUS_SUCCESS;
  79. PGCK_FILTER_EXT pFilterExt;
  80. PDEVICE_OBJECT pCurDeviceObject;
  81. PIO_STACK_LOCATION pIrpStack;
  82. KEVENT SyncEvent;
  83. USHORT usShareAccess;
  84. PAGED_CODE ();
  85. GCK_DBG_ENTRY_PRINT (("Entering GCK_FLTR\n"));
  86. //cast device extension to proper type
  87. pFilterExt = (PGCK_FILTER_EXT) pDeviceObject->DeviceExtension;
  88. // Just an extra sanity check
  89. ASSERT( GCK_DO_TYPE_FILTER == pFilterExt->ulGckDevObjType);
  90. //
  91. // Increment IRP count, ASAP, note we couldn't do this until now, as we
  92. // knew not whether the device extension was really a GCK_FILTER_EXT
  93. //
  94. GCK_IncRemoveLock(&pFilterExt->RemoveLock);
  95. // Make sure we are not in the process of going away
  96. if(
  97. GCK_STATE_STARTED != pFilterExt->eDeviceState &&
  98. GCK_STATE_STOP_PENDING != pFilterExt->eDeviceState
  99. )
  100. {
  101. GCK_DBG_WARN_PRINT(("Create while remove pending\n"));
  102. NtStatus = STATUS_DELETE_PENDING;
  103. pIrp->IoStatus.Information = 0;
  104. pIrp->IoStatus.Status = NtStatus;
  105. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  106. }
  107. else // process this
  108. {
  109. GCK_DBG_TRACE_PRINT(("GCK_Create calling lower driver\n"));
  110. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  111. //
  112. //We lie to hidclass about the desired share access,
  113. //because it doesn't know not to count us.
  114. //Notice below that we restore this before passing to our
  115. //internal poll routines, so that we can track it there.
  116. //
  117. usShareAccess=pIrpStack->Parameters.Create.ShareAccess;
  118. pIrpStack->Parameters.Create.ShareAccess = FILE_READ_DATA|FILE_WRITE_DATA;
  119. //This is our internal poll trying to create a file object, just call down
  120. if( pFilterExt->InternalPoll.InternalCreateThread == KeGetCurrentThread())
  121. {
  122. IoSkipCurrentIrpStackLocation(pIrp);
  123. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  124. }
  125. //This is a request from above, capture on the way up
  126. else
  127. {
  128. GCK_IP_AddFileObject(
  129. pFilterExt,
  130. pIrpStack->FileObject,
  131. pIrpStack->Parameters.Create.ShareAccess,
  132. pIrpStack->Parameters.Create.SecurityContext->DesiredAccess
  133. );
  134. GCKF_KickDeviceForData(pFilterExt);
  135. // Call create synchronously
  136. KeInitializeEvent(&SyncEvent, SynchronizationEvent, FALSE);
  137. IoCopyCurrentIrpStackLocationToNext(pIrp);
  138. IoSetCompletionRoutine(
  139. pIrp,
  140. GCK_FLTR_CreateComplete,
  141. (PVOID)&SyncEvent,
  142. TRUE,
  143. TRUE,
  144. TRUE
  145. );
  146. IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  147. KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);
  148. NtStatus = pIrp->IoStatus.Status;
  149. // If create succeeded, we need to remember the FileObject
  150. GCK_IP_ConfirmFileObject(pFilterExt, pIrpStack->FileObject, (BOOLEAN)(NT_SUCCESS(pIrp->IoStatus.Status) ? TRUE : FALSE) );
  151. IoCompleteRequest(pIrp, IO_NO_INCREMENT); // This was misssing!!!
  152. }
  153. }
  154. //
  155. // We are done with this IRP, so decrement the outstanding count
  156. // and signal remove if this was the last outstanding IRP
  157. //
  158. GCK_DecRemoveLock(&pFilterExt->RemoveLock);
  159. GCK_DBG_EXIT_PRINT(("Exiting GCK_Create(2). Status: 0x%0.8x\n", NtStatus));
  160. return NtStatus;
  161. }
  162. /***********************************************************************************
  163. **
  164. ** NTSTATUS GCK_FLTR_CreateComplete(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext)
  165. **
  166. ** @mfunc Completion Routine for IRP_MJ_CREATE
  167. **
  168. ** @rdesc STATUS_SUCCESS
  169. **
  170. *************************************************************************************/
  171. NTSTATUS
  172. GCK_FLTR_CreateComplete
  173. (
  174. IN PDEVICE_OBJECT pDeviceObject,
  175. IN PIRP pIrp,
  176. IN PVOID pContext
  177. )
  178. {
  179. PKEVENT pSyncEvent;
  180. UNREFERENCED_PARAMETER(pDeviceObject);
  181. UNREFERENCED_PARAMETER(pIrp);
  182. // Cast context to device extension
  183. pSyncEvent = (PKEVENT) pContext;
  184. KeSetEvent(pSyncEvent, IO_NO_INCREMENT, FALSE);
  185. //Done with this IRP, never need to see it again
  186. return STATUS_MORE_PROCESSING_REQUIRED;
  187. }
  188. /***********************************************************************************
  189. **
  190. ** NTSTATUS GCK_FLTR_Close ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
  191. **
  192. ** @func Handles IRP_MJ_CLOSE for filter device objects - Call generated by Win32 API CloseFile
  193. **
  194. ** @rdesc STATUS_SUCCESS or various errors
  195. **
  196. *************************************************************************************/
  197. NTSTATUS GCK_FLTR_Close (
  198. IN PDEVICE_OBJECT pDeviceObject, // @parm DO target for IRP
  199. IN PIRP pIrp // @parm IRP
  200. )
  201. {
  202. NTSTATUS NtStatus = STATUS_SUCCESS;
  203. PGCK_FILTER_EXT pFilterExt;
  204. PIO_STACK_LOCATION pIrpStack;
  205. PAGED_CODE ();
  206. GCK_DBG_ENTRY_PRINT (("GCK_Close, pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
  207. //cast device extension to proper type
  208. pFilterExt = (PGCK_FILTER_EXT) pDeviceObject->DeviceExtension;
  209. // Just an extra sanity check
  210. ASSERT( GCK_DO_TYPE_FILTER == pFilterExt->ulGckDevObjType);
  211. //
  212. // Increment IRP count, ASAP, note we couldn't do this until now, as we
  213. // knew not whether the device extension was really a GCK_FILTER_EXT
  214. //
  215. GCK_IncRemoveLock(&pFilterExt->RemoveLock);
  216. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  217. //cleanup pending IO and our tracking of the FileObject -
  218. //however not applicable if it is our internal polling open, that is being close
  219. if(pIrpStack->FileObject != pFilterExt->InternalPoll.pInternalFileObject)
  220. {
  221. //Complete pending I\O on FileObject
  222. if(
  223. GCK_STATE_STARTED == pFilterExt->eDeviceState ||
  224. GCK_STATE_STOP_PENDING == pFilterExt->eDeviceState
  225. )
  226. {
  227. //There is no pending I\O if the device is not started yet
  228. GCKF_CompleteReadRequestsForFileObject(pFilterExt, pIrpStack->FileObject);
  229. }
  230. //forget file object
  231. GCK_IP_RemoveFileObject(pFilterExt, pIrpStack->FileObject);
  232. }
  233. //send the Irp along
  234. IoSkipCurrentIrpStackLocation (pIrp);
  235. NtStatus = IoCallDriver(pFilterExt->pTopOfStack, pIrp);
  236. // Decrement outstanding IO and signal if went to zero
  237. GCK_DecRemoveLock(&pFilterExt->RemoveLock);
  238. GCK_DBG_EXIT_PRINT(("Exiting GCK_Close(2). Status: 0x%0.8x\n", NtStatus));
  239. return NtStatus;
  240. }
  241. /***********************************************************************************
  242. **
  243. ** NTSTATUS GCK_FLTR_Read (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  244. **
  245. ** @func Handles IRP_MJ_READ for filter device objects - Generated by Win32 ReadFile
  246. **
  247. ** @rdesc STATUS_SUCCESS, or various errors
  248. **
  249. *************************************************************************************/
  250. NTSTATUS GCK_FLTR_Read
  251. (
  252. IN PDEVICE_OBJECT pDeviceObject, // @parm Target of IRP
  253. IN PIRP pIrp // @parm IRP to handle
  254. )
  255. {
  256. NTSTATUS NtStatus;
  257. LARGE_INTEGER lgiWaitTime;
  258. PGCK_FILTER_EXT pFilterExt;
  259. PIO_STACK_LOCATION pIrpStack;
  260. PIO_STACK_LOCATION pPrivateIrpStack;
  261. PVOID pvIrpBuffer;
  262. PFILE_OBJECT pIrpsFileObject;
  263. static int iEnterCount=0;
  264. unsigned int i=0;
  265. GCK_DBG_RT_ENTRY_PRINT(("Entering GCK_Read. pDO = 0x%0.8x, pIrp = 0x%0.8x\n", pDeviceObject, pIrp));
  266. //cast device extension to proper type
  267. pFilterExt = (PGCK_FILTER_EXT) pDeviceObject->DeviceExtension;
  268. // Just an extra sanity check
  269. ASSERT( GCK_DO_TYPE_FILTER == pFilterExt->ulGckDevObjType);
  270. // Increment IRP count while we handle this one
  271. GCK_IncRemoveLock(&pFilterExt->RemoveLock);
  272. // If we have been removed, we shouldn't be getting read IRPs
  273. if(
  274. GCK_STATE_STARTED != pFilterExt->eDeviceState &&
  275. GCK_STATE_STOP_PENDING != pFilterExt->eDeviceState
  276. )
  277. {
  278. GCK_DBG_WARN_PRINT(( "GCK_Read called with delete pending\n"));
  279. NtStatus = STATUS_DELETE_PENDING;
  280. pIrp->IoStatus.Information = 0;
  281. pIrp->IoStatus.Status = NtStatus;
  282. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  283. // Decrement outstanding IRP count, and signal if it want to zero
  284. GCK_DecRemoveLock(&pFilterExt->RemoveLock);
  285. }
  286. else
  287. {
  288. //
  289. // Send Reqeust to filter, the filterhooks module is responsible
  290. // for all the necessary Asynchronous IRP handling steps, we just
  291. // return status pending.
  292. //
  293. NtStatus = GCKF_IncomingReadRequests(pFilterExt, pIrp);
  294. // Poll the lower driver, if one is not yet pending.
  295. GCK_IP_OneTimePoll(pFilterExt);
  296. }
  297. GCK_DBG_RT_EXIT_PRINT(("Exiting GCK_Read(2). Status: 0x%0.8x\n", NtStatus));
  298. return NtStatus;
  299. }
  300. /***********************************************************************************
  301. **
  302. ** NTSTATUS GCK_FLTR_Ioctl (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  303. **
  304. ** @mfunc Handles all IOCTLs for the filter devices - this is just a straight pass through
  305. **
  306. ** @rdesc STATUS_SUCCESS, various errors
  307. **
  308. *************************************************************************************/
  309. NTSTATUS GCK_FLTR_Ioctl
  310. (
  311. IN PDEVICE_OBJECT pDeviceObject, // @parm pointer to Device Object
  312. IN PIRP pIrp // @parm pointer to IRP
  313. )
  314. {
  315. PGCK_FILTER_EXT pFilterExt;
  316. NTSTATUS NtStatus;
  317. PAGED_CODE ();
  318. GCK_DBG_ENTRY_PRINT(("Entering GCK_FLTR_Ioctl, pDeviceObject = 0x%0.8x, pIRP = 0x%0.8x\n", pDeviceObject, pIrp));
  319. //cast device extension to proper type
  320. pFilterExt = (PGCK_FILTER_EXT) pDeviceObject->DeviceExtension;
  321. //
  322. // If we have been removed we need to refuse this IRP
  323. //
  324. if (GCK_STATE_REMOVED == pFilterExt->eDeviceState) {
  325. GCK_DBG_TRACE_PRINT(("GCK_FLTR_Ioctl called while delete pending\n"));
  326. ASSERT(FALSE);
  327. NtStatus = STATUS_DELETE_PENDING;
  328. pIrp->IoStatus.Information = 0;
  329. pIrp->IoStatus.Status = NtStatus;
  330. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  331. }
  332. else
  333. {
  334. // Send the IRP on unchanged.
  335. IoSkipCurrentIrpStackLocation (pIrp);
  336. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  337. }
  338. GCK_DBG_EXIT_PRINT(("Exiting GCK_FLTR_Ioctl, Status: 0x%0.8x\n", NtStatus));
  339. return NtStatus;
  340. }