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.

319 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1991-1998 Microsoft Corporation
  3. Module Name:
  4. SFFDISK (Small Form Factor Disk)
  5. Abstract:
  6. Author:
  7. Neil Sandlin (neilsa) 26-Apr-99
  8. Environment:
  9. Kernel mode only.
  10. --*/
  11. #include "pch.h"
  12. //
  13. // Internal References
  14. //
  15. NTSTATUS
  16. DriverEntry(
  17. IN PDRIVER_OBJECT DriverObject,
  18. IN PUNICODE_STRING RegistryPath
  19. );
  20. VOID
  21. SffDiskUnload(
  22. IN PDRIVER_OBJECT DriverObject
  23. );
  24. NTSTATUS
  25. SffDiskCreateClose(
  26. IN PDEVICE_OBJECT DeviceObject,
  27. IN PIRP Irp
  28. );
  29. NTSTATUS
  30. SffDiskReadWrite(
  31. IN PDEVICE_OBJECT DeviceObject,
  32. IN PIRP Irp
  33. );
  34. #ifdef ALLOC_PRAGMA
  35. #pragma alloc_text(INIT,DriverEntry)
  36. #pragma alloc_text(PAGE,SffDiskCreateClose)
  37. #pragma alloc_text(PAGE,SffDiskReadWrite)
  38. #endif
  39. NTSTATUS
  40. DriverEntry(
  41. IN PDRIVER_OBJECT DriverObject,
  42. IN PUNICODE_STRING RegistryPath
  43. )
  44. /*++
  45. Routine Description:
  46. This routine is the driver's entry point, called by the I/O system
  47. to load the driver. The driver's entry points are initialized and
  48. a mutex to control paging is initialized.
  49. In DBG mode, this routine also examines the registry for special
  50. debug parameters.
  51. Arguments:
  52. DriverObject - a pointer to the object that represents this device
  53. driver.
  54. RegistryPath - a pointer to this driver's key in the Services tree.
  55. Return Value:
  56. STATUS_SUCCESS unless we can't allocate a mutex.
  57. --*/
  58. {
  59. NTSTATUS ntStatus = STATUS_SUCCESS;
  60. SffDiskDump(SFFDISKSHOW, ("SffDisk: DriverEntry\n") );
  61. //
  62. // Initialize the driver object with this driver's entry points.
  63. //
  64. DriverObject->MajorFunction[IRP_MJ_CREATE] = SffDiskCreateClose;
  65. DriverObject->MajorFunction[IRP_MJ_CLOSE] = SffDiskCreateClose;
  66. DriverObject->MajorFunction[IRP_MJ_READ] = SffDiskReadWrite;
  67. DriverObject->MajorFunction[IRP_MJ_WRITE] = SffDiskReadWrite;
  68. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SffDiskDeviceControl;
  69. DriverObject->MajorFunction[IRP_MJ_PNP] = SffDiskPnp;
  70. DriverObject->MajorFunction[IRP_MJ_POWER] = SffDiskPower;
  71. DriverObject->DriverUnload = SffDiskUnload;
  72. DriverObject->DriverExtension->AddDevice = SffDiskAddDevice;
  73. return ntStatus;
  74. }
  75. VOID
  76. SffDiskUnload(
  77. IN PDRIVER_OBJECT DriverObject
  78. )
  79. /*++
  80. Routine Description:
  81. Unload the driver from the system. The paging mutex is freed before
  82. final unload.
  83. Arguments:
  84. DriverObject - a pointer to the object that represents this device
  85. driver.
  86. Return Value:
  87. none
  88. --*/
  89. {
  90. SffDiskDump( SFFDISKSHOW, ("SffDiskUnload:\n"));
  91. //
  92. // The device object(s) should all be gone by now.
  93. //
  94. ASSERT( DriverObject->DeviceObject == NULL );
  95. return;
  96. }
  97. NTSTATUS
  98. SffDiskCreateClose(
  99. IN PDEVICE_OBJECT DeviceObject,
  100. IN PIRP Irp
  101. )
  102. /*++
  103. Routine Description:
  104. This routine is called only rarely by the I/O system; it's mainly
  105. for layered drivers to call. All it does is complete the IRP
  106. successfully.
  107. Arguments:
  108. DeviceObject - a pointer to the object that represents the device
  109. that I/O is to be done on.
  110. Irp - a pointer to the I/O Request Packet for this request.
  111. Return Value:
  112. Always returns STATUS_SUCCESS, since this is a null operation.
  113. --*/
  114. {
  115. UNREFERENCED_PARAMETER( DeviceObject );
  116. //
  117. // Null operation. Do not give an I/O boost since
  118. // no I/O was actually done. IoStatus.Information should be
  119. // FILE_OPENED for an open; it's undefined for a close.
  120. //
  121. Irp->IoStatus.Status = STATUS_SUCCESS;
  122. Irp->IoStatus.Information = FILE_OPENED;
  123. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  124. return STATUS_SUCCESS;
  125. }
  126. NTSTATUS
  127. SffDiskReadWrite(
  128. IN PDEVICE_OBJECT DeviceObject,
  129. IN PIRP Irp
  130. )
  131. /*++
  132. Routine Description:
  133. This routine handles read/write irps for the memory card. It validates
  134. parameters and calls SffDiskReadWrite to do the real work.
  135. Arguments:
  136. DeviceObject - a pointer to the object that represents the device
  137. that I/O is to be done on.
  138. Irp - a pointer to the I/O Request Packet for this request.
  139. Return Value:
  140. STATUS_SUCCESS if the packet was successfully read or written; the
  141. appropriate error is propogated otherwise.
  142. --*/
  143. {
  144. NTSTATUS status = STATUS_SUCCESS;
  145. PSFFDISK_EXTENSION sffdiskExtension = DeviceObject->DeviceExtension;
  146. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  147. SffDiskDump(SFFDISKRW,("SffDisk: DO %.8x %s offset %.8x, buffer %.8x, len %x\n",
  148. sffdiskExtension->DeviceObject,
  149. (irpSp->MajorFunction == IRP_MJ_WRITE) ?"WRITE":"READ",
  150. irpSp->Parameters.Read.ByteOffset.LowPart,
  151. MmGetSystemAddressForMdl(Irp->MdlAddress),
  152. irpSp->Parameters.Read.Length));
  153. //
  154. // If the device is not active (not started yet or removed) we will
  155. // just fail this request outright.
  156. //
  157. if ( sffdiskExtension->IsRemoved || !sffdiskExtension->IsStarted) {
  158. if ( sffdiskExtension->IsRemoved) {
  159. status = STATUS_DELETE_PENDING;
  160. } else {
  161. status = STATUS_UNSUCCESSFUL;
  162. }
  163. goto ReadWriteComplete;
  164. }
  165. if (((irpSp->Parameters.Read.ByteOffset.LowPart +
  166. irpSp->Parameters.Read.Length) > sffdiskExtension->ByteCapacity) ||
  167. (irpSp->Parameters.Read.ByteOffset.HighPart != 0)) {
  168. status = STATUS_INVALID_PARAMETER;
  169. goto ReadWriteComplete;
  170. }
  171. //
  172. // verify that user is really expecting some I/O operation to
  173. // occur.
  174. //
  175. if (!irpSp->Parameters.Read.Length) {
  176. //
  177. // Complete this zero length request with no boost.
  178. //
  179. Irp->IoStatus.Status = STATUS_SUCCESS;
  180. goto ReadWriteComplete;
  181. }
  182. if ((DeviceObject->Flags & DO_VERIFY_VOLUME) && !(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
  183. //
  184. // The disk changed, and we set this bit. Fail
  185. // all current IRPs for this device; when all are
  186. // returned, the file system will clear
  187. // DO_VERIFY_VOLUME.
  188. //
  189. status = STATUS_VERIFY_REQUIRED;
  190. goto ReadWriteComplete;
  191. }
  192. //
  193. // Do the operation
  194. //
  195. if (irpSp->MajorFunction == IRP_MJ_WRITE) {
  196. status = (*(sffdiskExtension->FunctionBlock->WriteProc))(sffdiskExtension, Irp);
  197. } else {
  198. status = (*(sffdiskExtension->FunctionBlock->ReadProc))(sffdiskExtension, Irp);
  199. }
  200. if (!NT_SUCCESS(status)) {
  201. SffDiskDump(SFFDISKFAIL,("SffDisk: Read/Write Error! %.8x\n", status));
  202. //
  203. // Retry the operation
  204. //
  205. if (irpSp->MajorFunction == IRP_MJ_WRITE) {
  206. status = (*(sffdiskExtension->FunctionBlock->WriteProc))(sffdiskExtension, Irp);
  207. } else {
  208. status = (*(sffdiskExtension->FunctionBlock->ReadProc))(sffdiskExtension, Irp);
  209. }
  210. SffDiskDump(SFFDISKFAIL,("SffDisk: status after retry %.8x\n", status));
  211. }
  212. ReadWriteComplete:
  213. if (NT_SUCCESS(status)) {
  214. Irp->IoStatus.Information = irpSp->Parameters.Read.Length;
  215. } else {
  216. Irp->IoStatus.Information = 0;
  217. }
  218. SffDiskDump(SFFDISKRW,("SffDisk: DO %.8x RW Irp complete %.8x %.8x\n",
  219. sffdiskExtension->DeviceObject,
  220. status, Irp->IoStatus.Information));
  221. Irp->IoStatus.Status = status;
  222. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  223. return status;
  224. }