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.

389 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. initunlo.c
  5. Abstract:
  6. This module contains the code that is very specific to initialization
  7. and unload operations in the irenum driver
  8. Author:
  9. Brian Lieuallen, 7-13-2000
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "internal.h"
  15. #pragma alloc_text(PAGE,IrEnumAddDevice)
  16. #pragma alloc_text(PAGE,IrEnumPnP)
  17. #pragma alloc_text(PAGE,IrEnumPower)
  18. #pragma alloc_text(PAGE,IrEnumWmi)
  19. NTSTATUS
  20. IrEnumAddDevice(
  21. IN PDRIVER_OBJECT DriverObject,
  22. IN PDEVICE_OBJECT Pdo
  23. )
  24. {
  25. NTSTATUS Status;
  26. PDEVICE_OBJECT Fdo = NULL;
  27. PDEVICE_OBJECT LowerDevice=NULL;
  28. //
  29. // Pointer to the device extension created for this
  30. // device
  31. //
  32. PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
  33. D_PNP(DbgPrint("IRENUM: AddDevice\n");)
  34. //
  35. // Create the device object for this device.
  36. //
  37. Status = IoCreateDevice(
  38. DriverObject,
  39. sizeof(FDO_DEVICE_EXTENSION),
  40. NULL,
  41. FILE_DEVICE_NULL,
  42. FILE_AUTOGENERATED_DEVICE_NAME,
  43. FALSE,
  44. &Fdo
  45. );
  46. if (!NT_SUCCESS(Status)) {
  47. goto CleanUp;
  48. }
  49. LowerDevice=IoAttachDeviceToDeviceStack(
  50. Fdo,
  51. Pdo
  52. );
  53. if (LowerDevice == NULL) {
  54. D_ERROR(DbgPrint("IRENUM: Could not attach to PDO\n");)
  55. Status=STATUS_INSUFFICIENT_RESOURCES;
  56. goto CleanUp;
  57. }
  58. Fdo->Flags |= LowerDevice->Flags;
  59. Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
  60. Fdo->StackSize=LowerDevice->StackSize+1;
  61. DeviceExtension=Fdo->DeviceExtension;
  62. DeviceExtension->DoType=DO_TYPE_FDO;
  63. DeviceExtension->DeviceObject = Fdo;
  64. DeviceExtension->Pdo=Pdo;
  65. DeviceExtension->LowerDevice=LowerDevice;
  66. DeviceExtension->CreateStaticDevice= (EnumStaticDevice != 0) ;
  67. CreateEnumObject(Fdo,&DeviceExtension->EnumHandle,DeviceExtension->CreateStaticDevice);
  68. return STATUS_SUCCESS;
  69. CleanUp:
  70. IoDeleteDevice(Fdo);
  71. return Status;
  72. }
  73. NTSTATUS
  74. IrEnumPnP(
  75. IN PDEVICE_OBJECT DeviceObject,
  76. IN PIRP Irp
  77. )
  78. {
  79. PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  80. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  81. NTSTATUS status;
  82. ULONG i;
  83. if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) {
  84. //
  85. // this one is for the child
  86. //
  87. return IrEnumPdoPnp(
  88. DeviceObject,
  89. Irp
  90. );
  91. }
  92. if (DeviceExtension->DoType != DO_TYPE_FDO) {
  93. DbgPrint("IRENUM: IrEnumPnp: Bad DevObj\n");
  94. Irp->IoStatus.Status = STATUS_SUCCESS;
  95. IoCompleteRequest(
  96. Irp,
  97. IO_NO_INCREMENT
  98. );
  99. return STATUS_SUCCESS;
  100. }
  101. switch (irpSp->MinorFunction) {
  102. case IRP_MN_START_DEVICE:
  103. Irp->IoStatus.Status = STATUS_SUCCESS;
  104. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  105. case IRP_MN_QUERY_STOP_DEVICE:
  106. D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_STOP_DEVICE\n");)
  107. Irp->IoStatus.Status = STATUS_SUCCESS;
  108. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  109. case IRP_MN_CANCEL_STOP_DEVICE:
  110. D_PNP(DbgPrint("IRENUM: IRP_MN_CANCEL_STOP_DEVICE\n");)
  111. Irp->IoStatus.Status = STATUS_SUCCESS;
  112. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  113. case IRP_MN_STOP_DEVICE:
  114. D_PNP(DbgPrint("IRENUM: IRP_MN_STOP_DEVICE\n");)
  115. Irp->IoStatus.Status = STATUS_SUCCESS;
  116. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  117. case IRP_MN_QUERY_DEVICE_RELATIONS: {
  118. PDEVICE_RELATIONS CurrentRelations=(PDEVICE_RELATIONS)Irp->IoStatus.Information;
  119. PDEVICE_RELATIONS NewRelations=NULL;
  120. D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_DEVICE_RELATIONS type=%d\n",irpSp->Parameters.QueryDeviceRelations.Type);)
  121. D_PNP(DbgPrint(" Information=%p\n",Irp->IoStatus.Information);)
  122. switch (irpSp->Parameters.QueryDeviceRelations.Type ) {
  123. case BusRelations: {
  124. if (DeviceExtension->EnumHandle != NULL) {
  125. status=GetDeviceList(
  126. DeviceExtension->EnumHandle,
  127. Irp
  128. );
  129. Irp->IoStatus.Status = status;
  130. if (!NT_SUCCESS(status)) {
  131. IoCompleteRequest(
  132. Irp,
  133. IO_NO_INCREMENT
  134. );
  135. return status;
  136. }
  137. }
  138. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  139. }
  140. case TargetDeviceRelation:
  141. default: {
  142. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  143. }
  144. }
  145. break;
  146. }
  147. case IRP_MN_QUERY_REMOVE_DEVICE:
  148. D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_REMOVE_DEVICE\n");)
  149. Irp->IoStatus.Status = STATUS_SUCCESS;
  150. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  151. case IRP_MN_CANCEL_REMOVE_DEVICE:
  152. D_PNP(DbgPrint("IRENUM: IRP_MN_CANCEL_REMOVE_DEVICE\n");)
  153. Irp->IoStatus.Status = STATUS_SUCCESS;
  154. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  155. case IRP_MN_SURPRISE_REMOVAL: {
  156. D_PNP(DbgPrint("IRENUM: IRP_MN_SURPRISE_REMOVAL\n");)
  157. Irp->IoStatus.Status = STATUS_SUCCESS;
  158. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  159. }
  160. break;
  161. case IRP_MN_REMOVE_DEVICE: {
  162. ULONG NewReferenceCount;
  163. D_PNP(DbgPrint("IRENUM: IRP_MN_REMOVE_DEVICE\n");)
  164. //
  165. // removing now for sure
  166. //
  167. DeviceExtension->Removing=TRUE;
  168. DeviceExtension->Removed=TRUE;
  169. IoCopyCurrentIrpStackLocationToNext(Irp);
  170. status=IoCallDriver(DeviceExtension->LowerDevice, Irp);
  171. //
  172. // detach from the driver below
  173. //
  174. IoDetachDevice(DeviceExtension->LowerDevice);
  175. DeviceExtension->DoType=DO_TYPE_DEL_FDO;
  176. if (DeviceExtension->EnumHandle != NULL) {
  177. CloseEnumObject(DeviceExtension->EnumHandle);
  178. }
  179. //
  180. // delete our device object
  181. //
  182. IoDeleteDevice(DeviceObject);
  183. D_PNP(DbgPrint("IRENUM: IRP_MN_REMOVE_DEVICE exit, %08lx\n",status);)
  184. return status;
  185. }
  186. default:
  187. D_PNP(DbgPrint("IRENUM: Sending to PDO PnP IRP, MN func=%d\n",irpSp->MinorFunction);)
  188. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  189. }
  190. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  191. return STATUS_SUCCESS;
  192. }
  193. NTSTATUS
  194. IrEnumPower(
  195. IN PDEVICE_OBJECT DeviceObject,
  196. IN PIRP Irp
  197. )
  198. {
  199. PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  200. if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) {
  201. //
  202. // this one is for the child
  203. //
  204. return IrEnumPdoPower(
  205. DeviceObject,
  206. Irp
  207. );
  208. }
  209. PoStartNextPowerIrp(Irp);
  210. IoSkipCurrentIrpStackLocation(Irp);
  211. return PoCallDriver(DeviceExtension->LowerDevice, Irp);
  212. }
  213. NTSTATUS
  214. IrEnumWmi(
  215. IN PDEVICE_OBJECT DeviceObject,
  216. IN PIRP Irp
  217. )
  218. {
  219. PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  220. PIO_STACK_LOCATION irpSp=IoGetCurrentIrpStackLocation(Irp);
  221. NTSTATUS Status;
  222. if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) {
  223. return IrEnumPdoWmi(
  224. DeviceObject,
  225. Irp
  226. );
  227. }
  228. if (irpSp->Parameters.WMI.ProviderId == (ULONG_PTR)DeviceObject) {
  229. //
  230. // The irp was targeted at this device, but we don't support wmi
  231. //
  232. Status = Irp->IoStatus.Status;
  233. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  234. } else {
  235. //
  236. // the irp is targeted at another device object in the stack
  237. //
  238. Status=ForwardIrp(DeviceExtension->LowerDevice, Irp);
  239. }
  240. return Status;
  241. }