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.

381 lines
13 KiB

  1. /*++
  2. Copyright (c) 1991-1998 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. Author:
  7. Neil Sandlin (neilsa) 26-Apr-99
  8. Environment:
  9. Kernel mode only.
  10. --*/
  11. #include "pch.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGE,MemCardDeviceControl)
  14. #endif
  15. NTSTATUS
  16. MemCardDeviceControl(
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. )
  20. /*++
  21. Routine Description:
  22. This routine is called by the I/O system to perform a device I/O
  23. control function.
  24. Arguments:
  25. DeviceObject - a pointer to the object that represents the device
  26. that I/O is to be done on.
  27. Irp - a pointer to the I/O Request Packet for this request.
  28. Return Value:
  29. STATUS_SUCCESS or STATUS_PENDING if recognized I/O control code,
  30. STATUS_INVALID_DEVICE_REQUEST otherwise.
  31. --*/
  32. {
  33. PIO_STACK_LOCATION irpSp;
  34. PMEMCARD_EXTENSION memcardExtension;
  35. PDISK_GEOMETRY outputBuffer;
  36. NTSTATUS status;
  37. ULONG outputBufferLength;
  38. UCHAR i;
  39. ULONG formatExParametersSize;
  40. PFORMAT_EX_PARAMETERS formatExParameters;
  41. MemCardDump( MEMCARDIOCTL, ("MemCard: IOCTL entered\n") );
  42. memcardExtension = DeviceObject->DeviceExtension;
  43. irpSp = IoGetCurrentIrpStackLocation( Irp );
  44. //
  45. // If the device has been removed we will just fail this request outright.
  46. //
  47. if ( memcardExtension->IsRemoved ) {
  48. Irp->IoStatus.Information = 0;
  49. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  50. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  51. return STATUS_DELETE_PENDING;
  52. }
  53. //
  54. // If the device hasn't been started we will let the IOCTL through. This
  55. // is another hack for ACPI.
  56. //
  57. if (!memcardExtension->IsStarted) {
  58. IoSkipCurrentIrpStackLocation( Irp );
  59. return IoCallDriver( memcardExtension->TargetObject, Irp );
  60. }
  61. switch( irpSp->Parameters.DeviceIoControl.IoControlCode ) {
  62. case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: {
  63. PMOUNTDEV_NAME mountName;
  64. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n",
  65. DeviceObject, Irp));
  66. ASSERT(memcardExtension->DeviceName.Buffer);
  67. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  68. sizeof(MOUNTDEV_NAME) ) {
  69. status = STATUS_INVALID_PARAMETER;
  70. break;
  71. }
  72. mountName = Irp->AssociatedIrp.SystemBuffer;
  73. mountName->NameLength = memcardExtension->DeviceName.Length;
  74. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  75. sizeof(USHORT) + mountName->NameLength) {
  76. status = STATUS_BUFFER_OVERFLOW;
  77. Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
  78. break;
  79. }
  80. RtlCopyMemory( mountName->Name, memcardExtension->DeviceName.Buffer,
  81. mountName->NameLength);
  82. mountName->Name[mountName->NameLength / sizeof(USHORT)] = L'0';
  83. status = STATUS_SUCCESS;
  84. Irp->IoStatus.Information = sizeof(USHORT) + mountName->NameLength;
  85. break;
  86. }
  87. case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: {
  88. PMOUNTDEV_UNIQUE_ID uniqueId;
  89. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n",
  90. DeviceObject, Irp));
  91. if ( !memcardExtension->InterfaceString.Buffer ||
  92. irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  93. sizeof(MOUNTDEV_UNIQUE_ID)) {
  94. status = STATUS_INVALID_PARAMETER;
  95. break;
  96. }
  97. uniqueId = Irp->AssociatedIrp.SystemBuffer;
  98. uniqueId->UniqueIdLength =
  99. memcardExtension->InterfaceString.Length;
  100. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  101. sizeof(USHORT) + uniqueId->UniqueIdLength) {
  102. status = STATUS_BUFFER_OVERFLOW;
  103. Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
  104. break;
  105. }
  106. RtlCopyMemory( uniqueId->UniqueId,
  107. memcardExtension->InterfaceString.Buffer,
  108. uniqueId->UniqueIdLength );
  109. status = STATUS_SUCCESS;
  110. Irp->IoStatus.Information = sizeof(USHORT) +
  111. uniqueId->UniqueIdLength;
  112. break;
  113. }
  114. case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: {
  115. MemCardDump(MEMCARDIOCTL,("MemCard: DO %.8x Irp %.8x IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n",
  116. DeviceObject, Irp));
  117. status = STATUS_INVALID_DEVICE_REQUEST;
  118. break;
  119. }
  120. case IOCTL_DISK_GET_MEDIA_TYPES: {
  121. ULONG ByteCapacity;
  122. MemCardDump(MEMCARDIOCTL,("MemCard: DO %.8x Irp %.8x IOCTL_DISK_GET_MEDIA_TYPES\n",
  123. DeviceObject, Irp));
  124. outputBufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  125. outputBuffer = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
  126. //
  127. // Make sure that the input buffer has enough room to return
  128. // at least one descriptions of a supported media type.
  129. //
  130. if (outputBufferLength < (sizeof(DISK_GEOMETRY))) {
  131. status = STATUS_BUFFER_TOO_SMALL;
  132. break;
  133. }
  134. //
  135. // Assume success, although we might modify it to a buffer
  136. // overflow warning below (if the buffer isn't big enough
  137. // to hold ALL of the media descriptions).
  138. //
  139. status = STATUS_SUCCESS;
  140. i = 0;
  141. Irp->IoStatus.Information = 0;
  142. //
  143. // Fill in capacities from 512K to 8M
  144. //
  145. for (ByteCapacity = 0x80000; ByteCapacity <= 0x800000; ByteCapacity*=2) {
  146. if (outputBufferLength < (sizeof(DISK_GEOMETRY) + Irp->IoStatus.Information)) {
  147. status = STATUS_BUFFER_OVERFLOW;
  148. break;
  149. }
  150. outputBuffer->MediaType = FixedMedia;
  151. outputBuffer->Cylinders.LowPart = ByteCapacity / (8 * 2 * 512);
  152. outputBuffer->Cylinders.HighPart = 0;
  153. outputBuffer->TracksPerCylinder = 2;
  154. outputBuffer->SectorsPerTrack = 8;
  155. outputBuffer->BytesPerSector = 512;
  156. MemCardDump( MEMCARDIOCTL, ("MemCard: Cyls=%x\n", outputBuffer->Cylinders.LowPart));
  157. outputBuffer++;
  158. Irp->IoStatus.Information += sizeof( DISK_GEOMETRY );
  159. }
  160. break;
  161. }
  162. case IOCTL_DISK_CHECK_VERIFY:
  163. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_CHECK_VERIFY\n",
  164. DeviceObject, Irp));
  165. status = STATUS_SUCCESS;
  166. break;
  167. case IOCTL_DISK_GET_DRIVE_GEOMETRY: {
  168. PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
  169. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_GET_DRIVE_GEOMETRY\n",
  170. DeviceObject, Irp));
  171. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( DISK_GEOMETRY ) ) {
  172. status = STATUS_INVALID_PARAMETER;
  173. break;
  174. }
  175. status = STATUS_SUCCESS;
  176. if (!memcardExtension->ByteCapacity) {
  177. //
  178. // Just zero out everything. The
  179. // caller shouldn't look at it.
  180. //
  181. outputBuffer->MediaType = Unknown;
  182. outputBuffer->Cylinders.LowPart = 0;
  183. outputBuffer->Cylinders.HighPart = 0;
  184. outputBuffer->TracksPerCylinder = 0;
  185. outputBuffer->SectorsPerTrack = 0;
  186. outputBuffer->BytesPerSector = 0;
  187. } else {
  188. //
  189. // Return the geometry of the current
  190. // media.
  191. //
  192. outputBuffer->MediaType = FixedMedia;
  193. outputBuffer->Cylinders.HighPart = 0;
  194. outputBuffer->Cylinders.LowPart = memcardExtension->ByteCapacity / (8 * 2 * 512);
  195. outputBuffer->TracksPerCylinder = 2;
  196. outputBuffer->SectorsPerTrack = 8;
  197. outputBuffer->BytesPerSector = 512;
  198. }
  199. MemCardDump( MEMCARDIOCTL, ("MemCard: Capacity=%.8x => Cyl=%x\n",
  200. memcardExtension->ByteCapacity, outputBuffer->Cylinders.LowPart));
  201. Irp->IoStatus.Information = sizeof( DISK_GEOMETRY );
  202. break;
  203. }
  204. case IOCTL_DISK_IS_WRITABLE: {
  205. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_IS_WRITABLE\n",
  206. DeviceObject, Irp));
  207. if ((memcardExtension->PcmciaInterface.IsWriteProtected)(memcardExtension->UnderlyingPDO)) {
  208. status = STATUS_INVALID_PARAMETER;
  209. } else {
  210. status = STATUS_SUCCESS;
  211. }
  212. break;
  213. }
  214. case IOCTL_DISK_VERIFY: {
  215. PVERIFY_INFORMATION verifyInformation = Irp->AssociatedIrp.SystemBuffer;
  216. if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION)) {
  217. status = STATUS_INVALID_PARAMETER;
  218. break;
  219. }
  220. //NOTE: not implemented
  221. Irp->IoStatus.Information = verifyInformation->Length;
  222. status = STATUS_SUCCESS;
  223. break;
  224. }
  225. case IOCTL_DISK_GET_DRIVE_LAYOUT: {
  226. PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
  227. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_GET_DRIVE_LAYOUT\n",
  228. DeviceObject, Irp));
  229. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DRIVE_LAYOUT_INFORMATION) ) {
  230. status = STATUS_INVALID_PARAMETER;
  231. break;
  232. }
  233. RtlZeroMemory(outputBuffer, sizeof(DRIVE_LAYOUT_INFORMATION));
  234. outputBuffer->PartitionCount = 1;
  235. outputBuffer->PartitionEntry[0].StartingOffset.LowPart = 512;
  236. outputBuffer->PartitionEntry[0].PartitionLength.LowPart = memcardExtension->ByteCapacity;
  237. outputBuffer->PartitionEntry[0].RecognizedPartition = TRUE;
  238. status = STATUS_SUCCESS;
  239. Irp->IoStatus.Information = sizeof(DRIVE_LAYOUT_INFORMATION);
  240. break;
  241. }
  242. case IOCTL_DISK_GET_PARTITION_INFO: {
  243. PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
  244. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_GET_PARTITION_INFO\n",
  245. DeviceObject, Irp));
  246. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( PARTITION_INFORMATION ) ) {
  247. status = STATUS_INVALID_PARAMETER;
  248. break;
  249. }
  250. RtlZeroMemory(outputBuffer, sizeof(PARTITION_INFORMATION));
  251. outputBuffer->RecognizedPartition = TRUE;
  252. outputBuffer->StartingOffset.LowPart = 512;
  253. outputBuffer->PartitionLength.LowPart = memcardExtension->ByteCapacity;
  254. status = STATUS_SUCCESS;
  255. Irp->IoStatus.Information = sizeof( PARTITION_INFORMATION );
  256. break;
  257. }
  258. case IOCTL_DISK_SET_DRIVE_LAYOUT:
  259. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL_DISK_SET_DRIVE_LAYOUT\n",
  260. DeviceObject, Irp));
  261. case IOCTL_MOUNTMGR_CHANGE_NOTIFY:
  262. case IOCTL_MOUNTDEV_LINK_CREATED:
  263. case IOCTL_MOUNTDEV_LINK_DELETED:
  264. default: {
  265. MemCardDump(MEMCARDIOCTL,
  266. ("MemCard: IOCTL - unsupported device request %.8x\n", irpSp->Parameters.DeviceIoControl.IoControlCode));
  267. status = STATUS_INVALID_DEVICE_REQUEST;
  268. break;
  269. //IoSkipCurrentIrpStackLocation( Irp );
  270. //status = IoCallDriver( memcardExtension->TargetObject, Irp );
  271. //return status;
  272. }
  273. }
  274. if ( status != STATUS_PENDING ) {
  275. Irp->IoStatus.Status = status;
  276. if (!NT_SUCCESS( status ) && IoIsErrorUserInduced( status )) {
  277. IoSetHardErrorOrVerifyDevice( Irp, DeviceObject );
  278. }
  279. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL comp %.8x\n", DeviceObject, Irp, status));
  280. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  281. }
  282. MemCardDump( MEMCARDIOCTL, ("MemCard: DO %.8x Irp %.8x IOCTL <-- %.8x \n", DeviceObject, Irp, status));
  283. return status;
  284. }