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.

286 lines
9.2 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module CTRL.c |
  5. *
  6. * Entry points for handling IRPs to the "Control" device object.
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Mitchell S. Dernis Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic CTRL |
  15. * The control device object is used for programming GcKernel.
  16. * The main module, GckShell, delegates IRPs aimed at the control device
  17. * here.
  18. *
  19. **********************************************************************/
  20. #define __DEBUG_MODULE_IN_USE__ GCK_CTRL_C
  21. #include <wdm.h>
  22. #include <gckshell.h>
  23. #include "debug.h"
  24. //
  25. // Mark the pageable routines as such
  26. //
  27. #ifdef ALLOC_PRAGMA
  28. #pragma alloc_text (INIT, GCK_CTRL_DriverEntry)
  29. #pragma alloc_text (PAGE, GCK_CTRL_Create)
  30. #pragma alloc_text (PAGE, GCK_CTRL_Close)
  31. #pragma alloc_text (PAGE, GCK_CTRL_Unload)
  32. #endif
  33. // Allow debug output for this module, and set the intial level
  34. DECLARE_MODULE_DEBUG_LEVEL((DBG_WARN|DBG_ERROR|DBG_CRITICAL) );
  35. /***********************************************************************************
  36. **
  37. ** NTSTATUS GCK_CTRL_DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
  38. **
  39. ** @func Initializing the portions of the driver related to the control device, actually
  40. ** All of this was added to GCK_CTRL_AddDevice, which is called when the first filter
  41. ** device is added.
  42. **
  43. ** @rdesc STATUS_SUCCESS or various errors
  44. **
  45. *************************************************************************************/
  46. NTSTATUS GCK_CTRL_DriverEntry
  47. (
  48. IN PDRIVER_OBJECT pDriverObject, // @parm Driver Object
  49. IN PUNICODE_STRING puniRegistryPath // @parm Path to driver specific registry section.
  50. )
  51. {
  52. UNREFERENCED_PARAMETER (puniRegistryPath);
  53. UNREFERENCED_PARAMETER (pDriverObject);
  54. PAGED_CODE();
  55. GCK_DBG_ENTRY_PRINT(("Entering GCK_CTRL_DriverEntry\n"));
  56. //
  57. // Initialize Globals
  58. //
  59. GCK_DBG_TRACE_PRINT(("Initializing CTRL globals\n"));
  60. Globals.pControlObject = NULL;
  61. GCK_DBG_EXIT_PRINT (("Exiting GCK_CTRL_DriverEntry: STATUS_SUCCESS\n"));
  62. return STATUS_SUCCESS;
  63. }
  64. /***********************************************************************************
  65. **
  66. ** NTSTATUS GCK_CTRL_AddDevice( IN PDRIVER_OBJECT pDriverObject )
  67. **
  68. ** @func Adds a Control Device. Called from GCK_FLTR_AddDevice when the first
  69. ** Device is added.
  70. **
  71. ** @rdesc STATUS_SUCCESS, or various error codes
  72. **
  73. *************************************************************************************/
  74. NTSTATUS
  75. GCK_CTRL_AddDevice
  76. (
  77. IN PDRIVER_OBJECT pDriverObject
  78. )
  79. {
  80. NTSTATUS NtStatus = STATUS_SUCCESS;
  81. PDEVICE_OBJECT pDeviceObject;
  82. UNICODE_STRING uniNtNameString;
  83. UNICODE_STRING uniWin32NameString;
  84. PGCK_CONTROL_EXT pControlExt;
  85. PAGED_CODE();
  86. GCK_DBG_ENTRY_PRINT(("Entering GCK_CTRL_AddDevice\n"));
  87. //
  88. // Create a controlling device object. All control commands to the
  89. // filter driver come via IOCTL's to this device object. It lives
  90. // for the lifetime of the filter driver.
  91. //
  92. RtlInitUnicodeString (&uniNtNameString, GCK_CONTROL_NTNAME);
  93. NtStatus = IoCreateDevice (
  94. pDriverObject,
  95. sizeof (GCK_CONTROL_EXT),
  96. &uniNtNameString,
  97. FILE_DEVICE_UNKNOWN,
  98. 0, // No standard device characteristics
  99. FALSE, // This isn't an exclusive device
  100. &pDeviceObject
  101. );
  102. if(!NT_SUCCESS (NtStatus))
  103. {
  104. GCK_DBG_CRITICAL_PRINT (("Couldn't create the device. Status: 0x%0.8x\n", NtStatus));
  105. return NtStatus ;
  106. }
  107. //
  108. // Create W32 symbolic link name
  109. //
  110. GCK_DBG_TRACE_PRINT(("Creating symbolic link\n"));
  111. RtlInitUnicodeString (&uniWin32NameString, GCK_CONTROL_SYMNAME);
  112. NtStatus = IoCreateSymbolicLink (&uniWin32NameString, &uniNtNameString);
  113. if (!NT_SUCCESS(NtStatus))
  114. {
  115. GCK_DBG_CRITICAL_PRINT (("Couldn't create the symbolic Status: 0x%0.8x\n", NtStatus));
  116. IoDeleteDevice (pDeviceObject);
  117. return NtStatus;
  118. }
  119. //
  120. // Initialize Globals
  121. //
  122. GCK_DBG_TRACE_PRINT(("Initializing CTRL globals\n"));
  123. Globals.pControlObject = pDeviceObject;
  124. GCK_DBG_TRACE_PRINT(("Initializing Control Device\n"));
  125. pControlExt = pDeviceObject->DeviceExtension;
  126. pControlExt->ulGckDevObjType = GCK_DO_TYPE_CONTROL; //Put our name on this, so we can speak for him later
  127. pControlExt->lOutstandingIO = 1; // biassed to 1. Transition to zero signals Remove event
  128. Globals.pControlObject->Flags |= DO_BUFFERED_IO;
  129. Globals.pControlObject->Flags &= ~DO_DEVICE_INITIALIZING;
  130. GCK_DBG_EXIT_PRINT (("Normal exit of GCK_CTRL_AddDevice: 0x%0.8x\n", NtStatus));
  131. return NtStatus;
  132. }
  133. /***********************************************************************************
  134. **
  135. ** VOID GCK_CTRL_Remove()
  136. **
  137. ** @func Removes the one and only Control Device. Called from GCK_FLTR_Remove
  138. ** when all of the Filter devices go away. This was necessary, as
  139. ** the PnP loader won't unload you if you still have devices around
  140. ** even if they are legacy, and even if it started your driver.
  141. **
  142. ** @rdesc None
  143. **
  144. *************************************************************************************/
  145. VOID
  146. GCK_CTRL_Remove()
  147. {
  148. NTSTATUS NtStatus;
  149. PGCK_CONTROL_EXT pControlExt;
  150. UNICODE_STRING uniWin32NameString;
  151. GCK_DBG_ENTRY_PRINT(("Entering GCK_CTRL_Remove\n"));
  152. if( Globals.pControlObject)
  153. {
  154. GCK_DBG_TRACE_PRINT(("Removing Global Control Device\n"));
  155. //BUGBUG
  156. //BUGBUG Should be counting outstanding IRPs and blocking here until they
  157. //BUGBUG complete, before removing this.
  158. //BUGBUG
  159. //Kill the symbolic link we created on open
  160. RtlInitUnicodeString (&uniWin32NameString, GCK_CONTROL_SYMNAME);
  161. NtStatus = IoDeleteSymbolicLink(&uniWin32NameString);
  162. ASSERT( NT_SUCCESS(NtStatus) );
  163. if( NT_SUCCESS(NtStatus) )
  164. {
  165. //Delete the device
  166. IoDeleteDevice(Globals.pControlObject);
  167. Globals.pControlObject = NULL;
  168. }
  169. }
  170. GCK_DBG_EXIT_PRINT (("Exiting GCK_CTRL_Remove\n"));
  171. return;
  172. }
  173. /***********************************************************************************
  174. **
  175. ** NTSTATUS GCK_CTRL_Create ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
  176. **
  177. ** @func Handles the IRP_MJ_CREATE for the control device - Call generated by
  178. ** Win32 API CreateFile or OpenFile.
  179. **
  180. ** @rdesc STATUS_SUCCESS, or various error codes
  181. **
  182. *************************************************************************************/
  183. NTSTATUS GCK_CTRL_Create (
  184. IN PDEVICE_OBJECT pDeviceObject, // @parm DO target for IRP
  185. IN PIRP pIrp // @parm IRP
  186. )
  187. {
  188. PGCK_CONTROL_EXT pControlExt;
  189. PAGED_CODE ();
  190. GCK_DBG_ENTRY_PRINT(("Entering GCK_CTRL_Create\n"));
  191. //Cast device extension
  192. pControlExt = (PGCK_CONTROL_EXT) pDeviceObject->DeviceExtension;
  193. // Just an extra sanity check
  194. ASSERT( GCK_DO_TYPE_CONTROL == pControlExt->ulGckDevObjType);
  195. //free access to control devices
  196. pIrp->IoStatus.Information = 0;
  197. pIrp->IoStatus.Status = STATUS_SUCCESS;
  198. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  199. //Return
  200. GCK_DBG_EXIT_PRINT(("Exiting GCK_CTRL_Create\n"));
  201. return STATUS_SUCCESS;
  202. }
  203. /***********************************************************************************
  204. **
  205. ** NTSTATUS GCK_CTRL_Close ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
  206. **
  207. ** @func Handles IRP_MJ_CLOSE for the control device - Call generated by Win32 API CloseFile
  208. **
  209. ** @rdesc STATUS_SUCCESS or various errors
  210. **
  211. *************************************************************************************/
  212. NTSTATUS GCK_CTRL_Close (
  213. IN PDEVICE_OBJECT pDeviceObject, // @parm DO target for IRP
  214. IN PIRP pIrp // @parm IRP
  215. )
  216. {
  217. PGCK_CONTROL_EXT pControlExt;
  218. PGCK_FILTER_EXT pFilterExt;
  219. PDEVICE_OBJECT pFilterDeviceObject;
  220. PFILE_OBJECT pFileObject;
  221. PAGED_CODE ();
  222. GCK_DBG_ENTRY_PRINT(("Entering GCK_CTRL_Close\n"));
  223. //Cast device extension
  224. pControlExt = (PGCK_CONTROL_EXT) pDeviceObject->DeviceExtension;
  225. //Get file object from IRP
  226. pFileObject = IoGetCurrentIrpStackLocation(pIrp)->FileObject;
  227. // Just an extra sanity check
  228. ASSERT( GCK_DO_TYPE_CONTROL == pControlExt->ulGckDevObjType);
  229. //Close Test Mode for any device it was opened for
  230. //- if it was open by this handle - if it wasn't open this is a no-op
  231. ExAcquireFastMutex(&Globals.FilterObjectListFMutex);
  232. pFilterDeviceObject = Globals.pFilterObjectList;
  233. ExReleaseFastMutex(&Globals.FilterObjectListFMutex);
  234. while(pFilterDeviceObject)
  235. {
  236. pFilterExt = (PGCK_FILTER_EXT)pFilterDeviceObject->DeviceExtension;
  237. GCKF_EndTestScheme(pFilterExt, pFileObject);
  238. ExAcquireFastMutex(&Globals.FilterObjectListFMutex);
  239. pFilterDeviceObject = pFilterExt->pNextFilterObject;
  240. ExReleaseFastMutex(&Globals.FilterObjectListFMutex);
  241. }
  242. //free access to control devices
  243. pIrp->IoStatus.Information = 0;
  244. pIrp->IoStatus.Status = STATUS_SUCCESS;
  245. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  246. //Return
  247. GCK_DBG_EXIT_PRINT(("Exiting GCK_CTRL_Close.\n"));
  248. return STATUS_SUCCESS;
  249. }