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.

386 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module provides the functions which dispatch IRPs to FDOs and PDOs.
  7. Author:
  8. Andy Thornton (andrewth) 20-Oct-97
  9. Revision History:
  10. --*/
  11. #include "mfp.h"
  12. NTSTATUS
  13. MfAddDevice(
  14. IN PDRIVER_OBJECT DriverObject,
  15. IN PDEVICE_OBJECT PhysicalDeviceObject
  16. );
  17. NTSTATUS
  18. MfDispatchPnp(
  19. IN PDEVICE_OBJECT DeviceObject,
  20. IN PIRP Irp
  21. );
  22. NTSTATUS
  23. MfDispatchPower(
  24. IN PDEVICE_OBJECT DeviceObject,
  25. IN PIRP Irp
  26. );
  27. NTSTATUS
  28. MfDispatchPower(
  29. IN PDEVICE_OBJECT DeviceObject,
  30. IN PIRP Irp
  31. );
  32. #ifdef ALLOC_PRAGMA
  33. #pragma alloc_text(PAGE, MfAddDevice)
  34. #pragma alloc_text(PAGE, MfDispatchPnp)
  35. #pragma alloc_text(PAGE, MfForwardIrpToParent)
  36. #pragma alloc_text(PAGE, MfDispatchNop)
  37. #endif
  38. NTSTATUS
  39. MfAddDevice(
  40. IN PDRIVER_OBJECT DriverObject,
  41. IN PDEVICE_OBJECT PhysicalDeviceObject
  42. )
  43. /*++
  44. Routine Description:
  45. Given a physical device object, this routine creates a functional
  46. device object for it and attaches it to the top of the stack.
  47. Arguments:
  48. DriverObject - Pointer to our driver's DRIVER_OBJECT structure.
  49. PhysicalDeviceObject - Pointer to the physical device object for which
  50. we must create a functional device object.
  51. Return Value:
  52. NT status.
  53. --*/
  54. {
  55. NTSTATUS status;
  56. PDEVICE_OBJECT fdo = NULL;
  57. PMF_PARENT_EXTENSION extension;
  58. ASSERT(DriverObject == MfDriverObject);
  59. PAGED_CODE();
  60. //
  61. // Create our FDO
  62. //
  63. status = MfCreateFdo(&fdo);
  64. if (!NT_SUCCESS(status)) {
  65. goto cleanup;
  66. }
  67. extension = fdo->DeviceExtension;
  68. extension->PhysicalDeviceObject = PhysicalDeviceObject;
  69. //
  70. // Attach to the stack
  71. //
  72. extension->AttachedDevice = IoAttachDeviceToDeviceStack(
  73. fdo,
  74. PhysicalDeviceObject
  75. );
  76. if (!extension->AttachedDevice) {
  77. //
  78. // Could not attach
  79. //
  80. status = STATUS_NO_SUCH_DEVICE;
  81. goto cleanup;
  82. }
  83. fdo->Flags |= DO_POWER_PAGABLE;
  84. fdo->Flags &= ~DO_DEVICE_INITIALIZING;
  85. DEBUG_MSG(1, ("Completed AddDevice for PDO 0x%08x\n", PhysicalDeviceObject));
  86. return STATUS_SUCCESS;
  87. cleanup:
  88. if (fdo) {
  89. IoDeleteDevice(fdo);
  90. }
  91. return status;
  92. }
  93. NTSTATUS
  94. MfDispatchPnp(
  95. IN PDEVICE_OBJECT DeviceObject,
  96. IN PIRP Irp
  97. )
  98. /*++
  99. Routine Description:
  100. This routine handles all IRP_MJ_PNP IRPs for this driver. It dispatches to
  101. the appropriate fdo/pdo routine.
  102. Arguments:
  103. DeviceObject - Pointer to the device object for which this IRP applies.
  104. Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
  105. Return Value:
  106. NT status.
  107. --*/
  108. {
  109. NTSTATUS status;
  110. PMF_COMMON_EXTENSION common;
  111. PIO_STACK_LOCATION irpStack;
  112. PAGED_CODE();
  113. ASSERT_MF_DEVICE(DeviceObject);
  114. common = (PMF_COMMON_EXTENSION) DeviceObject->DeviceExtension;
  115. irpStack = IoGetCurrentIrpStackLocation(Irp);
  116. ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);
  117. if (IS_FDO(common)) {
  118. return MfDispatchPnpFdo(DeviceObject,
  119. (PMF_PARENT_EXTENSION) common,
  120. irpStack,
  121. Irp
  122. );
  123. } else {
  124. return MfDispatchPnpPdo(DeviceObject,
  125. (PMF_CHILD_EXTENSION) common,
  126. irpStack,
  127. Irp
  128. );
  129. }
  130. }
  131. NTSTATUS
  132. MfDispatchPower(
  133. IN PDEVICE_OBJECT DeviceObject,
  134. IN PIRP Irp
  135. )
  136. /*++
  137. Routine Description:
  138. This routine handles all IRP_MJ_POWER IRPs for this driver. It dispatches
  139. to the routines described in the PoDispatchTable entry in the device object
  140. extension.
  141. This routine is NOT pageable as it can be called at DISPATCH_LEVEL
  142. Arguments:
  143. DeviceObject - Pointer to the device object for which this IRP applies.
  144. Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
  145. Return Value:
  146. NT status.
  147. --*/
  148. {
  149. NTSTATUS status;
  150. PMF_COMMON_EXTENSION common;
  151. PIO_STACK_LOCATION irpStack;
  152. ASSERT_MF_DEVICE(DeviceObject);
  153. //
  154. // Find out who we are and what we need to do
  155. //
  156. common = (PMF_COMMON_EXTENSION) DeviceObject->DeviceExtension;
  157. irpStack = IoGetCurrentIrpStackLocation(Irp);
  158. ASSERT(irpStack->MajorFunction == IRP_MJ_POWER);
  159. if (IS_FDO(common)) {
  160. return MfDispatchPowerFdo(DeviceObject,
  161. (PMF_PARENT_EXTENSION) common,
  162. irpStack,
  163. Irp);
  164. } else {
  165. return MfDispatchPowerPdo(DeviceObject,
  166. (PMF_CHILD_EXTENSION) common,
  167. irpStack,
  168. Irp);
  169. }
  170. }
  171. NTSTATUS
  172. MfIrpNotSupported(
  173. IN PIRP Irp,
  174. IN PVOID Extension,
  175. IN PIO_STACK_LOCATION IrpStack
  176. )
  177. /*++
  178. Routine Description:
  179. This function handles the unsupported IRPs for both mf PDOs and FDOs
  180. This is NOT paged because is can be called from MfDispatchPower which can
  181. be called at DISPATCH_LEVEL
  182. Arguments:
  183. Irp - Points to the IRP associated with this request.
  184. Extension - Points to the device extension.
  185. IrpStack - Points to the current stack location for this request.
  186. Return Value:
  187. STATUS_NOT_SUPPORTED
  188. --*/
  189. {
  190. UNREFERENCED_PARAMETER(Irp);
  191. UNREFERENCED_PARAMETER(Extension);
  192. UNREFERENCED_PARAMETER(IrpStack);
  193. DEBUG_MSG(1, ("Skipping upsupported IRP\n"));
  194. return STATUS_NOT_SUPPORTED;
  195. }
  196. NTSTATUS
  197. MfForwardIrpToParent(
  198. IN PIRP Irp,
  199. IN PMF_CHILD_EXTENSION Child,
  200. IN PIO_STACK_LOCATION IrpStack
  201. )
  202. /*++
  203. Routine Description:
  204. This function builds a new Pnp irp and sends it to the parent device,
  205. returning the status and information to the child stack
  206. Arguments:
  207. Irp - Points to the IRP associated with this request.
  208. Parent - Points to the parent FDO's device extension.
  209. IrpStack - Points to the current stack location for this request.
  210. Return Value:
  211. The status of the IRP from the parent stack.
  212. --*/
  213. {
  214. PAGED_CODE();
  215. DEBUG_MSG(1, ("\tForwarding IRP to parent stack\n"));
  216. ASSERT(Child->Common.Type == MfPhysicalDeviceObject);
  217. ASSERT(IrpStack->MajorFunction == IRP_MJ_PNP);
  218. return MfSendPnpIrp(Child->Parent->Self,
  219. IrpStack,
  220. &Irp->IoStatus.Information
  221. );
  222. }
  223. NTSTATUS
  224. MfDispatchNop(
  225. IN PDEVICE_OBJECT DeviceObject,
  226. IN PIRP Irp
  227. )
  228. /*++
  229. Routine Description:
  230. This routine handles irps like IRP_MJ_DEVICE_CONTROL, which we don't support.
  231. This handler will complete the irp (if PDO) or pass it (if FDO).
  232. Arguments:
  233. DeviceObject - Pointer to the device object for which this IRP applies.
  234. Irp - Pointer to the IRP to dispatch.
  235. Return Value:
  236. NT status.
  237. --*/
  238. {
  239. NTSTATUS status;
  240. PMF_COMMON_EXTENSION common;
  241. PDEVICE_OBJECT attachedDevice;
  242. PAGED_CODE();
  243. ASSERT_MF_DEVICE(DeviceObject);
  244. common = (PMF_COMMON_EXTENSION) DeviceObject->DeviceExtension;
  245. if (IS_FDO(common)) {
  246. attachedDevice = ((PMF_PARENT_EXTENSION) common)->AttachedDevice;
  247. IoSkipCurrentIrpStackLocation(Irp);
  248. status = IoCallDriver(attachedDevice, Irp);
  249. } else {
  250. status = STATUS_NOT_SUPPORTED;
  251. Irp->IoStatus.Status = status;
  252. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  253. }
  254. return status;
  255. }