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.

433 lines
9.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. NTSTATUS
  16. IrCommAddDevice(
  17. IN PDRIVER_OBJECT DriverObject,
  18. IN PDEVICE_OBJECT Pdo
  19. )
  20. {
  21. NTSTATUS Status;
  22. ULONG Incoming;
  23. PDEVICE_OBJECT Fdo = NULL;
  24. PDEVICE_OBJECT LowerDevice=NULL;
  25. //
  26. // Pointer to the device extension created for this
  27. // device
  28. //
  29. PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
  30. D_PNP(DbgPrint("IrComm: AddDevice\n");)
  31. //
  32. // Create the device object for this device.
  33. //
  34. Status = IoCreateDevice(
  35. DriverObject,
  36. sizeof(FDO_DEVICE_EXTENSION),
  37. NULL,
  38. FILE_DEVICE_NULL,
  39. FILE_AUTOGENERATED_DEVICE_NAME,
  40. FALSE,
  41. &Fdo
  42. );
  43. if (!NT_SUCCESS(Status)) {
  44. return Status;
  45. }
  46. DeviceExtension=Fdo->DeviceExtension;
  47. LowerDevice=IoAttachDeviceToDeviceStack(
  48. Fdo,
  49. Pdo
  50. );
  51. if (LowerDevice == NULL) {
  52. D_ERROR(DbgPrint("IRCOMM: Could not attach to PDO\n");)
  53. Status=STATUS_INSUFFICIENT_RESOURCES;
  54. goto CleanUp;
  55. }
  56. Fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
  57. Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
  58. Fdo->StackSize=LowerDevice->StackSize+1;
  59. RtlZeroMemory(DeviceExtension,sizeof(*DeviceExtension));
  60. D_ERROR(DbgPrint("IRCOMM: Device Extension %p\n",DeviceExtension);)
  61. DeviceExtension->DeviceObject = Fdo;
  62. DeviceExtension->Pdo=Pdo;
  63. DeviceExtension->LowerDevice=LowerDevice;
  64. KeInitializeTimer(
  65. &DeviceExtension->Read.IntervalTimer
  66. );
  67. KeInitializeDpc(
  68. &DeviceExtension->Read.IntervalTimerDpc,
  69. IntervalTimeProc,
  70. DeviceExtension
  71. );
  72. KeInitializeTimer(
  73. &DeviceExtension->Read.TotalTimer
  74. );
  75. KeInitializeDpc(
  76. &DeviceExtension->Read.TotalTimerDpc,
  77. TotalTimerProc,
  78. DeviceExtension
  79. );
  80. KeInitializeSpinLock(
  81. &DeviceExtension->SpinLock
  82. );
  83. KeInitializeSpinLock(
  84. &DeviceExtension->Read.ReadLock
  85. );
  86. KeInitializeSpinLock(
  87. &DeviceExtension->Mask.Lock
  88. );
  89. IrCommHandleSymbolicLink(
  90. Pdo,
  91. &DeviceExtension->InterfaceName,
  92. TRUE
  93. );
  94. //
  95. // see if this is going to be instance of the driver is going to accept
  96. // incoming connection instead outgoing connections.
  97. //
  98. // default of outgoing if the key can't be read
  99. //
  100. DeviceExtension->OutgoingConnection=TRUE;
  101. Status=GetRegistryKeyValue(
  102. Pdo,
  103. PLUGPLAY_REGKEY_DRIVER,
  104. L"ListenForIncommingConnections",
  105. REG_DWORD,
  106. &Incoming,
  107. sizeof(Incoming)
  108. );
  109. if (NT_SUCCESS(Status)) {
  110. DeviceExtension->OutgoingConnection= (Incoming == 0) ? TRUE : FALSE;
  111. }
  112. //
  113. // open the file handles to the irda stack here in the system process context.
  114. // The handles will only be used to close the object during remove.
  115. //
  116. DeviceExtension->TdiObjects=OpenTdiObjects(
  117. "IrDA:IrCOMM",
  118. DeviceExtension->OutgoingConnection
  119. );
  120. if (DeviceExtension->TdiObjects == NULL) {
  121. D_ERROR(DbgPrint("IRCOMM: Could not open tdi objects\n");)
  122. Status=STATUS_INSUFFICIENT_RESOURCES;
  123. goto CleanUp;
  124. }
  125. InitializePacketQueue(
  126. &DeviceExtension->Write.Queue,
  127. DeviceExtension,
  128. WriteStartRoutine
  129. );
  130. InitializePacketQueue(
  131. &DeviceExtension->Read.Queue,
  132. DeviceExtension,
  133. ReadStartRoutine
  134. );
  135. InitializePacketQueue(
  136. &DeviceExtension->Mask.Queue,
  137. DeviceExtension,
  138. MaskStartRoutine
  139. );
  140. InitializePacketQueue(
  141. &DeviceExtension->Uart.Queue,
  142. DeviceExtension,
  143. UartStartRoutine
  144. );
  145. #if 0
  146. DeviceExtension->LineControl.StopBits=1;
  147. DeviceExtension->LineControl.Parity=0;
  148. DeviceExtension->LineControl.WordLength=8;
  149. DeviceExtension->BaudRate=115200;
  150. #endif
  151. DeviceExtension->Read.BytesInBuffer=0;
  152. DeviceExtension->Read.NextFilledByte=&DeviceExtension->Read.InputBuffer[0];
  153. DeviceExtension->Read.NextEmptyByte=&DeviceExtension->Read.InputBuffer[0];
  154. return STATUS_SUCCESS;
  155. CleanUp:
  156. if (DeviceExtension->InterfaceName.Buffer != NULL) {
  157. IrCommHandleSymbolicLink(
  158. DeviceExtension->Pdo,
  159. &DeviceExtension->InterfaceName,
  160. FALSE
  161. );
  162. }
  163. if (DeviceExtension->LowerDevice != NULL) {
  164. IoDetachDevice(DeviceExtension->LowerDevice);
  165. }
  166. IoDeleteDevice(Fdo);
  167. return Status;
  168. }
  169. NTSTATUS
  170. IrCommPnP(
  171. IN PDEVICE_OBJECT DeviceObject,
  172. IN PIRP Irp
  173. )
  174. {
  175. PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  176. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  177. NTSTATUS status;
  178. ULONG i;
  179. switch (irpSp->MinorFunction) {
  180. case IRP_MN_START_DEVICE:
  181. D_PNP(DbgPrint("IRCOMM: IRP_MN_START_DEVICE\n");)
  182. Irp->IoStatus.Status = STATUS_SUCCESS;
  183. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  184. case IRP_MN_QUERY_STOP_DEVICE:
  185. D_PNP(DbgPrint("IRCOMM: IRP_MN_QUERY_STOP_DEVICE\n");)
  186. Irp->IoStatus.Status = STATUS_SUCCESS;
  187. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  188. case IRP_MN_CANCEL_STOP_DEVICE:
  189. D_PNP(DbgPrint("IRCOMM: IRP_MN_CANCEL_STOP_DEVICE\n");)
  190. Irp->IoStatus.Status = STATUS_SUCCESS;
  191. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  192. case IRP_MN_STOP_DEVICE:
  193. D_PNP(DbgPrint("IRCOMM: IRP_MN_STOP_DEVICE\n");)
  194. Irp->IoStatus.Status = STATUS_SUCCESS;
  195. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  196. case IRP_MN_QUERY_REMOVE_DEVICE:
  197. D_PNP(DbgPrint("IrComm: IRP_MN_QUERY_REMOVE_DEVICE\n");)
  198. Irp->IoStatus.Status = STATUS_SUCCESS;
  199. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  200. case IRP_MN_CANCEL_REMOVE_DEVICE:
  201. D_PNP(DbgPrint("IrComm: IRP_MN_CANCEL_REMOVE_DEVICE\n");)
  202. Irp->IoStatus.Status = STATUS_SUCCESS;
  203. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  204. case IRP_MN_SURPRISE_REMOVAL: {
  205. D_PNP(DbgPrint("IrComm: IRP_MN_SURPRISE_REMOVAL\n");)
  206. DeviceExtension->Removing=TRUE;
  207. //
  208. // now that new io is blocked, flush out all pended irps
  209. //
  210. CleanupIoRequests(DeviceExtension);
  211. Irp->IoStatus.Status = STATUS_SUCCESS;
  212. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  213. }
  214. break;
  215. case IRP_MN_REMOVE_DEVICE: {
  216. ULONG NewReferenceCount;
  217. D_PNP(DbgPrint("IrComm: IRP_MN_REMOVE_DEVICE\n");)
  218. //
  219. // removing now for sure
  220. //
  221. DeviceExtension->Removing=TRUE;
  222. DeviceExtension->Removed=TRUE;
  223. if (DeviceExtension->InterfaceName.Buffer != NULL) {
  224. IrCommHandleSymbolicLink(
  225. DeviceExtension->Pdo,
  226. &DeviceExtension->InterfaceName,
  227. FALSE
  228. );
  229. }
  230. if (DeviceExtension->TdiObjects != NULL) {
  231. //
  232. // close the tdi objects that we opened during AddDevice(). This has to
  233. // be done in the same process as they were opened which is the system process
  234. //
  235. CloseTdiObjects(DeviceExtension->TdiObjects);
  236. }
  237. IoCopyCurrentIrpStackLocationToNext(Irp);
  238. status=IoCallDriver(DeviceExtension->LowerDevice, Irp);
  239. //
  240. // detach from the driver below
  241. //
  242. IoDetachDevice(DeviceExtension->LowerDevice);
  243. //
  244. // delete our device object
  245. //
  246. IoDeleteDevice(DeviceObject);
  247. D_PNP(DbgPrint("IrComm: IRP_MN_REMOVE_DEVICE exit, %08lx\n",status);)
  248. return status;
  249. }
  250. default:
  251. D_PNP(DbgPrint("IrComm: Sending to PDO PnP IRP, MN func=%d\n",irpSp->MinorFunction);)
  252. return ForwardIrp(DeviceExtension->LowerDevice, Irp);
  253. }
  254. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  255. return STATUS_SUCCESS;
  256. }
  257. NTSTATUS
  258. IrCommPower(
  259. IN PDEVICE_OBJECT DeviceObject,
  260. IN PIRP Irp
  261. )
  262. {
  263. PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  264. PoStartNextPowerIrp(Irp);
  265. IoSkipCurrentIrpStackLocation(Irp);
  266. return PoCallDriver(DeviceExtension->LowerDevice, Irp);
  267. }
  268. NTSTATUS
  269. IrCommWmi(
  270. IN PDEVICE_OBJECT DeviceObject,
  271. IN PIRP Irp
  272. )
  273. {
  274. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  275. return STATUS_SUCCESS;
  276. }