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.

363 lines
9.8 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. OCRW.C
  5. Abstract:
  6. This source file contains the dispatch routines which handle
  7. opening, closing, reading, and writing to the device, i.e.:
  8. IRP_MJ_CREATE
  9. IRP_MJ_CLOSE
  10. IRP_MJ_READ
  11. IRP_MJ_WRITE
  12. Environment:
  13. kernel mode
  14. Revision History:
  15. Sept 01 : KenRay
  16. --*/
  17. //*****************************************************************************
  18. // I N C L U D E S
  19. //*****************************************************************************
  20. #include "genusb.h"
  21. #ifdef ALLOC_PRAGMA
  22. #pragma alloc_text(PAGE, GenUSB_Create)
  23. #pragma alloc_text(PAGE, GenUSB_Close)
  24. #pragma alloc_text(PAGE, GenUSB_Read)
  25. #pragma alloc_text(PAGE, GenUSB_Write)
  26. #endif
  27. //******************************************************************************
  28. //
  29. // GenUSB_Create()
  30. //
  31. // Dispatch routine which handles IRP_MJ_CREATE
  32. //
  33. //******************************************************************************
  34. NTSTATUS
  35. GenUSB_Create (
  36. IN PDEVICE_OBJECT DeviceObject,
  37. IN PIRP Irp
  38. )
  39. {
  40. PDEVICE_EXTENSION deviceExtension;
  41. NTSTATUS status;
  42. DBGPRINT(2, ("enter: GenUSB_Create\n"));
  43. DBGFBRK(DBGF_BRK_CREATE);
  44. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  45. LOGENTRY(deviceExtension, 'CREA', DeviceObject, Irp, 0);
  46. status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
  47. if (!NT_SUCCESS(status)) {
  48. Irp->IoStatus.Status = status;
  49. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  50. return status;
  51. }
  52. // While there are several readers of the IsStarted state, it is only
  53. // set at the end of GenUSB_StartDevice.
  54. if (!deviceExtension->IsStarted)
  55. {
  56. LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
  57. status = STATUS_DEVICE_NOT_CONNECTED;
  58. }
  59. else if (1 != InterlockedIncrement (&deviceExtension->OpenedCount))
  60. {
  61. InterlockedDecrement (&deviceExtension->OpenedCount);
  62. status = STATUS_SHARING_VIOLATION;
  63. }
  64. else
  65. {
  66. status = STATUS_SUCCESS;
  67. Irp->IoStatus.Information = 0;
  68. }
  69. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  70. Irp->IoStatus.Status = status;
  71. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  72. DBGPRINT(2, ("exit: GenUSB_Create\n"));
  73. LOGENTRY(deviceExtension, 'crea', 0, 0, 0);
  74. return status;
  75. }
  76. //******************************************************************************
  77. //
  78. // GenUSB_Close()
  79. //
  80. // Dispatch routine which handles IRP_MJ_CLOSE
  81. //
  82. //******************************************************************************
  83. NTSTATUS
  84. GenUSB_Close (
  85. IN PDEVICE_OBJECT DeviceObject,
  86. IN PIRP Irp
  87. )
  88. {
  89. PDEVICE_EXTENSION deviceExtension;
  90. //
  91. // Never check the remove lock, or started for close.
  92. //
  93. DBGPRINT(2, ("enter: GenUSB_Close\n"));
  94. DBGFBRK(DBGF_BRK_CLOSE);
  95. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  96. LOGENTRY(deviceExtension, 'CLOS', DeviceObject, Irp, 0);
  97. GenUSB_DeselectConfiguration (deviceExtension, TRUE);
  98. InterlockedDecrement (&deviceExtension->OpenedCount);
  99. Irp->IoStatus.Status = STATUS_SUCCESS;
  100. Irp->IoStatus.Information = 0;
  101. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  102. DBGPRINT(2, ("exit: GenUSB_Close\n"));
  103. LOGENTRY(deviceExtension, 'clos', 0, 0, 0);
  104. return STATUS_SUCCESS;
  105. }
  106. //******************************************************************************
  107. //
  108. // GenUSB_ReadWrite()
  109. //
  110. // Dispatch routine which handles IRP_MJ_READ and IRP_MJ_WRITE
  111. //
  112. //******************************************************************************
  113. NTSTATUS
  114. GenUSB_ReadComplete (
  115. IN PDEVICE_OBJECT DeviceObject,
  116. IN PIRP Irp,
  117. IN PVOID Unused,
  118. IN USBD_STATUS UrbStatus,
  119. IN ULONG Length
  120. )
  121. {
  122. PDEVICE_EXTENSION deviceExtension;
  123. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  124. LOGENTRY(deviceExtension, 'RedC', Irp, Length, UrbStatus);
  125. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  126. Irp->IoStatus.Information = Length;
  127. return Irp->IoStatus.Status;
  128. }
  129. NTSTATUS
  130. GenUSB_Read (
  131. IN PDEVICE_OBJECT DeviceObject,
  132. IN PIRP Irp
  133. )
  134. {
  135. NTSTATUS status;
  136. PDEVICE_EXTENSION deviceExtension;
  137. PIO_STACK_LOCATION irpSp;
  138. DBGPRINT(2, ("enter: GenUSB_Read\n"));
  139. DBGFBRK(DBGF_BRK_READWRITE);
  140. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  141. LOGENTRY(deviceExtension, 'R ', DeviceObject, Irp, 0);
  142. status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
  143. if (!NT_SUCCESS(status)) {
  144. Irp->IoStatus.Status = status;
  145. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  146. return status;
  147. }
  148. // While there are several readers of the IsStarted state, it is only
  149. // set at the end of GenUSB_StartDevice.
  150. if (!deviceExtension->IsStarted)
  151. {
  152. LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
  153. status = STATUS_DEVICE_NOT_CONNECTED;
  154. goto GenUSB_ReadReject;
  155. }
  156. irpSp = IoGetCurrentIrpStackLocation (Irp);
  157. if (0 != irpSp->Parameters.Read.ByteOffset.QuadPart)
  158. {
  159. status = STATUS_NOT_IMPLEMENTED;
  160. goto GenUSB_ReadReject;
  161. }
  162. //
  163. // After talking extensively with JD, he tells me that I do not need
  164. // to queue requests for power downs or query stop. If that is the
  165. // case then even if the device power state isn't PowerDeviceD0 we
  166. // can still allow trasfers. This, of course, is a property of the
  167. // brand new port driver that went into XP.
  168. //
  169. // if (DeviceExtension->DevicePowerState != PowerDeviceD0)
  170. // {
  171. // }
  172. //
  173. //
  174. // BUGBUG if we ever implement IDLE, we need to turn the device
  175. // back on here.
  176. //
  177. return GenUSB_TransmitReceive (
  178. deviceExtension,
  179. Irp,
  180. deviceExtension->ReadInterface,
  181. deviceExtension->ReadPipe,
  182. USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
  183. NULL,
  184. Irp->MdlAddress,
  185. irpSp->Parameters.Read.Length,
  186. NULL,
  187. GenUSB_ReadComplete);
  188. GenUSB_ReadReject:
  189. Irp->IoStatus.Status = status;
  190. Irp->IoStatus.Information = 0;
  191. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  192. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  193. DBGPRINT(2, ("exit: GenUSB_Read %08X\n", status));
  194. LOGENTRY(deviceExtension, 'r ', status, 0, 0);
  195. return status;
  196. }
  197. NTSTATUS
  198. GenUSB_WriteComplete (
  199. IN PDEVICE_OBJECT DeviceObject,
  200. IN PIRP Irp,
  201. IN PVOID Unused,
  202. IN USBD_STATUS UrbStatus,
  203. IN ULONG Length
  204. )
  205. {
  206. PDEVICE_EXTENSION deviceExtension;
  207. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  208. LOGENTRY(deviceExtension, 'WrtC', Irp, Length, UrbStatus);
  209. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  210. Irp->IoStatus.Information = Length;
  211. return Irp->IoStatus.Status;
  212. }
  213. NTSTATUS
  214. GenUSB_Write (
  215. IN PDEVICE_OBJECT DeviceObject,
  216. IN PIRP Irp
  217. )
  218. {
  219. NTSTATUS status;
  220. PDEVICE_EXTENSION deviceExtension;
  221. PIO_STACK_LOCATION irpSp;
  222. DBGPRINT(2, ("enter: GenUSB_Write\n"));
  223. DBGFBRK(DBGF_BRK_READWRITE);
  224. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  225. LOGENTRY(deviceExtension, 'W ', DeviceObject, Irp, 0);
  226. status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
  227. if (!NT_SUCCESS(status)) {
  228. Irp->IoStatus.Status = status;
  229. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  230. return status;
  231. }
  232. // While there are several readers of the IsStarted state, it is only
  233. // set at the end of GenUSB_StartDevice.
  234. if (!deviceExtension->IsStarted)
  235. {
  236. LOGENTRY(deviceExtension, 'IOns', DeviceObject, Irp, 0);
  237. status = STATUS_DEVICE_NOT_CONNECTED;
  238. goto GenUSB_WriteReject;
  239. }
  240. irpSp = IoGetCurrentIrpStackLocation (Irp);
  241. if (0 != irpSp->Parameters.Write.ByteOffset.QuadPart)
  242. {
  243. status = STATUS_NOT_IMPLEMENTED;
  244. goto GenUSB_WriteReject;
  245. }
  246. //
  247. // After talking extensively with JD, he tells me that I do not need
  248. // to queue requests for power downs or query stop. If that is the
  249. // case then even if the device power state isn't PowerDeviceD0 we
  250. // can still allow trasfers. This, of course, is a property of the
  251. // brand new port driver that went into XP.
  252. //
  253. // if (DeviceExtension->DevicePowerState != PowerDeviceD0)
  254. // {
  255. // }
  256. //
  257. //
  258. // BUGBUG if we ever implement IDLE, we need to turn the device
  259. // back on here.
  260. //
  261. return GenUSB_TransmitReceive (
  262. deviceExtension,
  263. Irp,
  264. deviceExtension->WriteInterface,
  265. deviceExtension->WritePipe,
  266. USBD_TRANSFER_DIRECTION_OUT,
  267. NULL,
  268. Irp->MdlAddress,
  269. irpSp->Parameters.Read.Length,
  270. NULL,
  271. GenUSB_WriteComplete);
  272. GenUSB_WriteReject:
  273. Irp->IoStatus.Status = status;
  274. Irp->IoStatus.Information = 0;
  275. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  276. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  277. DBGPRINT(2, ("exit: GenUSB_Write %08X\n", status));
  278. LOGENTRY(deviceExtension, 'w ', status, 0, 0);
  279. return status;
  280. }