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.

320 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. vfwmi.c
  5. Abstract:
  6. This module handles System Control Irp verification.
  7. Author:
  8. Adrian J. Oney (adriao) 20-Apr-1998
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. AdriaO 06/15/2000 - Seperated out from ntos\io\flunkirp.c
  13. --*/
  14. #include "vfdef.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(INIT, VfWmiInit)
  17. #pragma alloc_text(PAGEVRFY, VfWmiDumpIrpStack)
  18. #pragma alloc_text(PAGEVRFY, VfWmiVerifyNewRequest)
  19. #pragma alloc_text(PAGEVRFY, VfWmiVerifyIrpStackDownward)
  20. #pragma alloc_text(PAGEVRFY, VfWmiVerifyIrpStackUpward)
  21. #pragma alloc_text(PAGEVRFY, VfWmiTestStartedPdoStack)
  22. #endif
  23. #ifdef ALLOC_DATA_PRAGMA
  24. #pragma const_seg("PAGEVRFC")
  25. #endif
  26. const PCHAR WmiIrpNames[] = {
  27. "IRP_MN_QUERY_ALL_DATA", // 0x00
  28. "IRP_MN_QUERY_SINGLE_INSTANCE", // 0x01
  29. "IRP_MN_CHANGE_SINGLE_INSTANCE", // 0x02
  30. "IRP_MN_CHANGE_SINGLE_ITEM", // 0x03
  31. "IRP_MN_ENABLE_EVENTS", // 0x04
  32. "IRP_MN_DISABLE_EVENTS", // 0x05
  33. "IRP_MN_ENABLE_COLLECTION", // 0x06
  34. "IRP_MN_DISABLE_COLLECTION", // 0x07
  35. "IRP_MN_REGINFO", // 0x08
  36. "IRP_MN_EXECUTE_METHOD", // 0x09
  37. NULL
  38. };
  39. #define MAX_NAMED_WMI_IRP 0x9
  40. #ifdef ALLOC_DATA_PRAGMA
  41. #pragma const_seg()
  42. #endif // ALLOC_DATA_PRAGMA
  43. VOID
  44. VfWmiInit(
  45. VOID
  46. )
  47. {
  48. VfMajorRegisterHandlers(
  49. IRP_MJ_SYSTEM_CONTROL,
  50. VfWmiDumpIrpStack,
  51. VfWmiVerifyNewRequest,
  52. VfWmiVerifyIrpStackDownward,
  53. VfWmiVerifyIrpStackUpward,
  54. NULL,
  55. NULL,
  56. NULL,
  57. NULL,
  58. NULL,
  59. NULL,
  60. VfWmiTestStartedPdoStack
  61. );
  62. }
  63. VOID
  64. FASTCALL
  65. VfWmiVerifyNewRequest(
  66. IN PIOV_REQUEST_PACKET IovPacket,
  67. IN PDEVICE_OBJECT DeviceObject,
  68. IN PIO_STACK_LOCATION IrpLastSp OPTIONAL,
  69. IN PIO_STACK_LOCATION IrpSp,
  70. IN PIOV_STACK_LOCATION StackLocationData,
  71. IN PVOID CallerAddress OPTIONAL
  72. )
  73. {
  74. PIRP irp = IovPacket->TrackedIrp;
  75. NTSTATUS currentStatus;
  76. UNREFERENCED_PARAMETER (IrpSp);
  77. UNREFERENCED_PARAMETER (IrpLastSp);
  78. UNREFERENCED_PARAMETER (DeviceObject);
  79. currentStatus = irp->IoStatus.Status;
  80. //
  81. // Verify new IRPs start out life accordingly
  82. //
  83. if (currentStatus!=STATUS_NOT_SUPPORTED) {
  84. WDM_FAIL_ROUTINE((
  85. DCERROR_WMI_IRP_BAD_INITIAL_STATUS,
  86. DCPARAM_IRP + DCPARAM_ROUTINE,
  87. CallerAddress,
  88. irp
  89. ));
  90. //
  91. // Don't blame anyone else for this guy's mistake.
  92. //
  93. if (!NT_SUCCESS(currentStatus)) {
  94. StackLocationData->Flags |= STACKFLAG_FAILURE_FORWARDED;
  95. }
  96. }
  97. }
  98. VOID
  99. FASTCALL
  100. VfWmiVerifyIrpStackDownward(
  101. IN PIOV_REQUEST_PACKET IovPacket,
  102. IN PDEVICE_OBJECT DeviceObject,
  103. IN PIO_STACK_LOCATION IrpLastSp OPTIONAL,
  104. IN PIO_STACK_LOCATION IrpSp,
  105. IN PIOV_STACK_LOCATION RequestHeadLocationData,
  106. IN PIOV_STACK_LOCATION StackLocationData,
  107. IN PVOID CallerAddress OPTIONAL
  108. )
  109. {
  110. PIRP irp = IovPacket->TrackedIrp;
  111. PDRIVER_OBJECT driverObject;
  112. PIOV_SESSION_DATA iovSessionData;
  113. UNREFERENCED_PARAMETER (IrpSp);
  114. UNREFERENCED_PARAMETER (IrpLastSp);
  115. iovSessionData = VfPacketGetCurrentSessionData(IovPacket);
  116. //
  117. // Verify the IRP was forwarded properly
  118. //
  119. if (iovSessionData->ForwardMethod == SKIPPED_A_DO) {
  120. WDM_FAIL_ROUTINE((
  121. DCERROR_SKIPPED_DEVICE_OBJECT,
  122. DCPARAM_IRP + DCPARAM_ROUTINE,
  123. CallerAddress,
  124. irp
  125. ));
  126. }
  127. //
  128. // For some IRP major's going down a stack, there *must* be a handler
  129. //
  130. driverObject = DeviceObject->DriverObject;
  131. if (!IovUtilHasDispatchHandler(driverObject, IRP_MJ_SYSTEM_CONTROL)) {
  132. RequestHeadLocationData->Flags |= STACKFLAG_BOGUS_IRP_TOUCHED;
  133. WDM_FAIL_ROUTINE((
  134. DCERROR_MISSING_DISPATCH_FUNCTION,
  135. DCPARAM_IRP + DCPARAM_ROUTINE,
  136. driverObject->DriverInit,
  137. irp
  138. ));
  139. StackLocationData->Flags |= STACKFLAG_NO_HANDLER;
  140. }
  141. }
  142. VOID
  143. FASTCALL
  144. VfWmiVerifyIrpStackUpward(
  145. IN PIOV_REQUEST_PACKET IovPacket,
  146. IN PIO_STACK_LOCATION IrpSp,
  147. IN PIOV_STACK_LOCATION RequestHeadLocationData,
  148. IN PIOV_STACK_LOCATION StackLocationData,
  149. IN BOOLEAN IsNewlyCompleted,
  150. IN BOOLEAN RequestFinalized
  151. )
  152. {
  153. PIRP irp;
  154. BOOLEAN mustPassDown, isBogusIrp, isPdo;
  155. PVOID routine;
  156. UNREFERENCED_PARAMETER (RequestHeadLocationData);
  157. UNREFERENCED_PARAMETER (RequestFinalized);
  158. //
  159. // Who'd we call for this one?
  160. //
  161. irp = IovPacket->TrackedIrp;
  162. routine = StackLocationData->LastDispatch;
  163. ASSERT(routine) ;
  164. //
  165. // If this "Request" has been "Completed", perform some checks
  166. //
  167. if (IsNewlyCompleted) {
  168. //
  169. // Remember bogosity...
  170. //
  171. isBogusIrp = (BOOLEAN)((IovPacket->Flags&TRACKFLAG_BOGUS)!=0);
  172. //
  173. // Is this a PDO?
  174. //
  175. isPdo = (BOOLEAN)((StackLocationData->Flags&STACKFLAG_REACHED_PDO)!=0);
  176. //
  177. // Was anything completed too early?
  178. // A driver may outright fail almost anything but a bogus IRP
  179. //
  180. mustPassDown = (BOOLEAN)(!(StackLocationData->Flags&STACKFLAG_NO_HANDLER));
  181. mustPassDown &= (!isPdo);
  182. mustPassDown &= ((PDEVICE_OBJECT) IrpSp->Parameters.WMI.ProviderId != IrpSp->DeviceObject);
  183. if (mustPassDown) {
  184. WDM_FAIL_ROUTINE((
  185. DCERROR_WMI_IRP_NOT_FORWARDED,
  186. DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ,
  187. routine,
  188. irp,
  189. IrpSp->Parameters.WMI.ProviderId
  190. ));
  191. }
  192. }
  193. }
  194. VOID
  195. FASTCALL
  196. VfWmiDumpIrpStack(
  197. IN PIO_STACK_LOCATION IrpSp
  198. )
  199. {
  200. DbgPrint("IRP_MJ_SYSTEM_CONTROL.");
  201. if (IrpSp->MinorFunction <= MAX_NAMED_WMI_IRP) {
  202. DbgPrint(WmiIrpNames[IrpSp->MinorFunction]);
  203. } else if (IrpSp->MinorFunction == 0xFF) {
  204. DbgPrint("IRP_MN_BOGUS");
  205. } else {
  206. DbgPrint("(Bogus)");
  207. }
  208. }
  209. VOID
  210. FASTCALL
  211. VfWmiTestStartedPdoStack(
  212. IN PDEVICE_OBJECT PhysicalDeviceObject
  213. )
  214. /*++
  215. Description:
  216. As per the title, we are going to throw some IRPs at the stack to
  217. see if they are handled correctly.
  218. Returns:
  219. Nothing
  220. --*/
  221. {
  222. IO_STACK_LOCATION irpSp;
  223. PAGED_CODE();
  224. //
  225. // Initialize the stack location to pass to IopSynchronousCall()
  226. //
  227. RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
  228. if (VfSettingsIsOptionEnabled(NULL, VERIFIER_OPTION_SEND_BOGUS_WMI_IRPS)) {
  229. //
  230. // Send a bogus WMI IRP
  231. //
  232. // Note that we shouldn't be sending this IRP to any stack that doesn't
  233. // terminate with a devnode. The WmiSystemControl export from WmiLib
  234. // says "NotWmiIrp if it sees these. The callers should still pass down
  235. // the IRP.
  236. //
  237. ASSERT(IovUtilIsPdo(PhysicalDeviceObject));
  238. irpSp.MajorFunction = IRP_MJ_SYSTEM_CONTROL;
  239. irpSp.MinorFunction = 0xff;
  240. irpSp.Parameters.WMI.ProviderId = (ULONG_PTR) PhysicalDeviceObject;
  241. VfIrpSendSynchronousIrp(
  242. PhysicalDeviceObject,
  243. &irpSp,
  244. TRUE,
  245. STATUS_NOT_SUPPORTED,
  246. 0,
  247. NULL,
  248. NULL
  249. );
  250. }
  251. }