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.

542 lines
11 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. vfdriver.c
  5. Abstract:
  6. This module contains the verifier driver filter.
  7. Author:
  8. Adrian J. Oney (adriao) 12-June-2000
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. AdriaO 06/12/2000 - Authored
  13. --*/
  14. #include "vfdef.h" // Includes vfdef.h
  15. #include "vidriver.h"
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGEVRFY, VfDriverInit)
  18. #pragma alloc_text(PAGEVRFY, VfDriverAttachFilter)
  19. #pragma alloc_text(PAGEVRFY, ViDriverEntry)
  20. #pragma alloc_text(PAGEVRFY, ViDriverAddDevice)
  21. #pragma alloc_text(PAGEVRFY, ViDriverDispatchPnp)
  22. #pragma alloc_text(PAGEVRFY, ViDriverStartCompletionRoutine)
  23. #pragma alloc_text(PAGEVRFY, ViDriverDeviceUsageNotificationCompletionRoutine)
  24. #pragma alloc_text(PAGEVRFY, ViDriverDispatchPower)
  25. #pragma alloc_text(PAGEVRFY, ViDriverDispatchGeneric)
  26. #pragma alloc_text(PAGEVRFY, VfDriverIsVerifierFilterObject)
  27. #endif
  28. PDRIVER_OBJECT VfDriverObject = NULL;
  29. #ifdef ALLOC_DATA_PRAGMA
  30. #pragma const_seg("PAGEVRFC")
  31. #endif
  32. WCHAR VerifierDriverName[] = L"\\DRIVER\\VERIFIER";
  33. BOOLEAN VfDriverCreated = FALSE;
  34. VOID
  35. VfDriverInit(
  36. VOID
  37. )
  38. /*++
  39. Routine Description:
  40. This routine initializes the driver verifier filter code.
  41. Arguments:
  42. None.
  43. Return Value:
  44. None.
  45. --*/
  46. {
  47. }
  48. VOID
  49. VfDriverAttachFilter(
  50. IN PDEVICE_OBJECT PhysicalDeviceObject,
  51. IN VF_DEVOBJ_TYPE DeviceObjectType
  52. )
  53. /*++
  54. Routine Description:
  55. This is the Verifier driver dispatch handler for PnP IRPs.
  56. Arguments:
  57. PhysicalDeviceObject - Bottom of stack to attach to.
  58. DeviceObjectType - Type of filter the device object must simulate.
  59. Return Value:
  60. None.
  61. --*/
  62. {
  63. NTSTATUS status;
  64. PDEVICE_OBJECT newDeviceObject, lowerDeviceObject;
  65. PVERIFIER_EXTENSION verifierExtension;
  66. UNICODE_STRING driverString;
  67. if (!VfDriverCreated) {
  68. RtlInitUnicodeString(&driverString, VerifierDriverName);
  69. IoCreateDriver(&driverString, ViDriverEntry);
  70. VfDriverCreated = TRUE;
  71. }
  72. if (VfDriverObject == NULL) {
  73. return;
  74. }
  75. switch(DeviceObjectType) {
  76. case VF_DEVOBJ_PDO:
  77. //
  78. // This makes no sense. We can't impersonate a PDO.
  79. //
  80. return;
  81. case VF_DEVOBJ_BUS_FILTER:
  82. //
  83. // We don't have the code to impersonate a bus filter yet.
  84. //
  85. return;
  86. case VF_DEVOBJ_LOWER_DEVICE_FILTER:
  87. case VF_DEVOBJ_LOWER_CLASS_FILTER:
  88. break;
  89. case VF_DEVOBJ_FDO:
  90. //
  91. // This makes no sense. We can't impersonate an FDO.
  92. //
  93. return;
  94. case VF_DEVOBJ_UPPER_DEVICE_FILTER:
  95. case VF_DEVOBJ_UPPER_CLASS_FILTER:
  96. break;
  97. default:
  98. //
  99. // We don't even know what this is!
  100. //
  101. ASSERT(0);
  102. return;
  103. }
  104. lowerDeviceObject = IoGetAttachedDevice(PhysicalDeviceObject);
  105. if (lowerDeviceObject->DriverObject == VfDriverObject) {
  106. //
  107. // No need to add another filter. We are immediately below.
  108. //
  109. return;
  110. }
  111. //
  112. // Create a filter device object.
  113. //
  114. status = IoCreateDevice(
  115. VfDriverObject,
  116. sizeof(VERIFIER_EXTENSION),
  117. NULL, // No Name
  118. FILE_DEVICE_UNKNOWN,
  119. FILE_DEVICE_SECURE_OPEN,
  120. FALSE,
  121. &newDeviceObject
  122. );
  123. if (!NT_SUCCESS(status)) {
  124. return;
  125. }
  126. verifierExtension = (PVERIFIER_EXTENSION) newDeviceObject->DeviceExtension;
  127. verifierExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(
  128. newDeviceObject,
  129. PhysicalDeviceObject
  130. );
  131. //
  132. // Failure for attachment is an indication of a broken plug & play system.
  133. //
  134. if (verifierExtension->LowerDeviceObject == NULL) {
  135. IoDeleteDevice(newDeviceObject);
  136. return;
  137. }
  138. newDeviceObject->Flags |= verifierExtension->LowerDeviceObject->Flags &
  139. (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH);
  140. newDeviceObject->DeviceType = verifierExtension->LowerDeviceObject->DeviceType;
  141. newDeviceObject->Characteristics =
  142. verifierExtension->LowerDeviceObject->Characteristics;
  143. verifierExtension->Self = newDeviceObject;
  144. verifierExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  145. newDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  146. }
  147. NTSTATUS
  148. ViDriverEntry(
  149. IN PDRIVER_OBJECT DriverObject,
  150. IN PUNICODE_STRING RegistryPath
  151. )
  152. /*++
  153. Routine Description:
  154. This is the callback function when we call IoCreateDriver to create a
  155. Verifier Driver Object. In this function, we need to remember the
  156. DriverObject.
  157. Arguments:
  158. DriverObject - Pointer to the driver object created by the system.
  159. RegistryPath - is NULL.
  160. Return Value:
  161. STATUS_SUCCESS
  162. --*/
  163. {
  164. ULONG i;
  165. UNREFERENCED_PARAMETER(RegistryPath);
  166. //
  167. // File the pointer to our driver object away
  168. //
  169. VfDriverObject = DriverObject;
  170. //
  171. // Fill in the driver object
  172. //
  173. DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE) ViDriverAddDevice;
  174. //
  175. // Most IRPs are simply pass though
  176. //
  177. for(i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  178. DriverObject->MajorFunction[i] = ViDriverDispatchGeneric;
  179. }
  180. //
  181. // PnP and Power IRPs are of course trickier.
  182. //
  183. DriverObject->MajorFunction[IRP_MJ_PNP] = ViDriverDispatchPnp;
  184. DriverObject->MajorFunction[IRP_MJ_POWER] = ViDriverDispatchPower;
  185. return STATUS_SUCCESS;
  186. }
  187. NTSTATUS
  188. ViDriverAddDevice(
  189. IN PDRIVER_OBJECT DriverObject,
  190. IN PDEVICE_OBJECT PhysicalDeviceObject
  191. )
  192. /*++
  193. Routine Description:
  194. This is the AddDevice callback function exposed by the verifier driver
  195. object. It should never be invoked by the operating system.
  196. Arguments:
  197. DriverObject - Pointer to the verifier driver object.
  198. PhysicalDeviceObject - Stack PnP wishes to attach this driver too.
  199. Return Value:
  200. NTSTATUS
  201. --*/
  202. {
  203. UNREFERENCED_PARAMETER(DriverObject);
  204. UNREFERENCED_PARAMETER(PhysicalDeviceObject);
  205. //
  206. // We should never get here!
  207. //
  208. ASSERT(0);
  209. return STATUS_UNSUCCESSFUL;
  210. }
  211. NTSTATUS
  212. ViDriverDispatchPnp(
  213. IN PDEVICE_OBJECT DeviceObject,
  214. IN PIRP Irp
  215. )
  216. /*++
  217. Routine Description:
  218. This is the Verifier driver dispatch handler for PnP IRPs.
  219. Arguments:
  220. DeviceObject - Pointer to the verifier device object.
  221. Irp - Pointer to the incoming IRP.
  222. Return Value:
  223. NTSTATUS
  224. --*/
  225. {
  226. PVERIFIER_EXTENSION verifierExtension;
  227. PIO_STACK_LOCATION irpSp;
  228. PDEVICE_OBJECT lowerDeviceObject;
  229. NTSTATUS status;
  230. verifierExtension = (PVERIFIER_EXTENSION) DeviceObject->DeviceExtension;
  231. irpSp = IoGetCurrentIrpStackLocation(Irp);
  232. lowerDeviceObject = verifierExtension->LowerDeviceObject;
  233. switch(irpSp->MinorFunction) {
  234. case IRP_MN_START_DEVICE:
  235. IoCopyCurrentIrpStackLocationToNext(Irp);
  236. IoSetCompletionRoutine(
  237. Irp,
  238. ViDriverStartCompletionRoutine,
  239. NULL,
  240. TRUE,
  241. TRUE,
  242. TRUE
  243. );
  244. return IoCallDriver(lowerDeviceObject, Irp);
  245. case IRP_MN_REMOVE_DEVICE:
  246. IoCopyCurrentIrpStackLocationToNext(Irp);
  247. status = IoCallDriver(lowerDeviceObject, Irp);
  248. IoDetachDevice(lowerDeviceObject);
  249. IoDeleteDevice(DeviceObject);
  250. return status;
  251. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  252. //
  253. // On the way down, pagable might become set. Mimic the driver
  254. // above us. If no one is above us, just set pagable.
  255. //
  256. if ((DeviceObject->AttachedDevice == NULL) ||
  257. (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) {
  258. DeviceObject->Flags |= DO_POWER_PAGABLE;
  259. }
  260. IoCopyCurrentIrpStackLocationToNext(Irp);
  261. IoSetCompletionRoutine(
  262. Irp,
  263. ViDriverDeviceUsageNotificationCompletionRoutine,
  264. NULL,
  265. TRUE,
  266. TRUE,
  267. TRUE
  268. );
  269. return IoCallDriver(lowerDeviceObject, Irp);
  270. }
  271. IoCopyCurrentIrpStackLocationToNext(Irp);
  272. return IoCallDriver(lowerDeviceObject, Irp);
  273. }
  274. NTSTATUS
  275. ViDriverStartCompletionRoutine(
  276. IN PDEVICE_OBJECT DeviceObject,
  277. IN PIRP Irp,
  278. IN PVOID Context
  279. )
  280. {
  281. PVERIFIER_EXTENSION verifierExtension;
  282. UNREFERENCED_PARAMETER(Context);
  283. if (Irp->PendingReturned) {
  284. IoMarkIrpPending(Irp);
  285. }
  286. verifierExtension = (PVERIFIER_EXTENSION) DeviceObject->DeviceExtension;
  287. //
  288. // Inherit FILE_REMOVABLE_MEDIA during Start. This characteristic didn't
  289. // make a clean transition from NT4 to NT5 because it wasn't available
  290. // until the driver stack is started! Even worse, drivers *examine* this
  291. // characteristic during start as well.
  292. //
  293. if (verifierExtension->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
  294. DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
  295. }
  296. return STATUS_SUCCESS;
  297. }
  298. NTSTATUS
  299. ViDriverDeviceUsageNotificationCompletionRoutine(
  300. IN PDEVICE_OBJECT DeviceObject,
  301. IN PIRP Irp,
  302. IN PVOID Context
  303. )
  304. {
  305. PVERIFIER_EXTENSION verifierExtension;
  306. UNREFERENCED_PARAMETER(Context);
  307. if (Irp->PendingReturned) {
  308. IoMarkIrpPending(Irp);
  309. }
  310. verifierExtension = (PVERIFIER_EXTENSION) DeviceObject->DeviceExtension;
  311. //
  312. // On the way up, pagable might become clear. Mimic the driver below us.
  313. //
  314. if (!(verifierExtension->LowerDeviceObject->Flags & DO_POWER_PAGABLE)) {
  315. DeviceObject->Flags &= ~DO_POWER_PAGABLE;
  316. }
  317. return STATUS_SUCCESS;
  318. }
  319. NTSTATUS
  320. ViDriverDispatchPower(
  321. IN PDEVICE_OBJECT DeviceObject,
  322. IN PIRP Irp
  323. )
  324. /*++
  325. Routine Description:
  326. This is the Verifier driver dispatch handler for Power IRPs.
  327. Arguments:
  328. DeviceObject - Pointer to the verifier device object.
  329. Irp - Pointer to the incoming IRP.
  330. Return Value:
  331. NTSTATUS
  332. --*/
  333. {
  334. PVERIFIER_EXTENSION verifierExtension;
  335. verifierExtension = (PVERIFIER_EXTENSION) DeviceObject->DeviceExtension;
  336. PoStartNextPowerIrp(Irp);
  337. IoCopyCurrentIrpStackLocationToNext(Irp);
  338. return PoCallDriver(verifierExtension->LowerDeviceObject, Irp);
  339. }
  340. NTSTATUS
  341. ViDriverDispatchGeneric(
  342. IN PDEVICE_OBJECT DeviceObject,
  343. IN PIRP Irp
  344. )
  345. /*++
  346. Routine Description:
  347. This is the Verifier driver dispatch handler for generic IRPs.
  348. Arguments:
  349. DeviceObject - Pointer to the verifier device object.
  350. Irp - Pointer to the incoming IRP.
  351. Return Value:
  352. NTSTATUS
  353. --*/
  354. {
  355. PVERIFIER_EXTENSION verifierExtension;
  356. verifierExtension = (PVERIFIER_EXTENSION) DeviceObject->DeviceExtension;
  357. IoCopyCurrentIrpStackLocationToNext(Irp);
  358. return IoCallDriver(verifierExtension->LowerDeviceObject, Irp);
  359. }
  360. BOOLEAN
  361. VfDriverIsVerifierFilterObject(
  362. IN PDEVICE_OBJECT DeviceObject
  363. )
  364. /*++
  365. Routine Description:
  366. This determines whether the passed in device object is a verifier DO.
  367. Arguments:
  368. DeviceObject - Pointer to the device object to check.
  369. Return Value:
  370. TRUE/FALSE
  371. --*/
  372. {
  373. return (BOOLEAN) (DeviceObject->DriverObject->MajorFunction[IRP_MJ_PNP] == ViDriverDispatchPnp);
  374. }