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.

426 lines
15 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. #include "ntddvol.h"
  13. #include "ntddft.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE,SffDiskDeviceControl)
  16. #endif
  17. NTSTATUS
  18. SffDiskDeviceControl(
  19. IN PDEVICE_OBJECT DeviceObject,
  20. IN PIRP Irp
  21. )
  22. /*++
  23. Routine Description:
  24. This routine is called by the I/O system to perform a device I/O
  25. control function.
  26. Arguments:
  27. DeviceObject - a pointer to the object that represents the device
  28. that I/O is to be done on.
  29. Irp - a pointer to the I/O Request Packet for this request.
  30. Return Value:
  31. STATUS_SUCCESS or STATUS_PENDING if recognized I/O control code,
  32. STATUS_INVALID_DEVICE_REQUEST otherwise.
  33. --*/
  34. {
  35. PIO_STACK_LOCATION irpSp;
  36. PSFFDISK_EXTENSION sffdiskExtension;
  37. PDISK_GEOMETRY outputBuffer;
  38. NTSTATUS status;
  39. ULONG outputBufferLength;
  40. UCHAR i;
  41. ULONG formatExParametersSize;
  42. PFORMAT_EX_PARAMETERS formatExParameters;
  43. sffdiskExtension = DeviceObject->DeviceExtension;
  44. irpSp = IoGetCurrentIrpStackLocation( Irp );
  45. SffDiskDump(SFFDISKIOCTL, ("SffDisk: IOCTL - %.8x\n", irpSp->Parameters.DeviceIoControl.IoControlCode));
  46. //
  47. // If the device has been removed we will just fail this request outright.
  48. //
  49. if ( sffdiskExtension->IsRemoved ) {
  50. Irp->IoStatus.Information = 0;
  51. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  52. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  53. return STATUS_DELETE_PENDING;
  54. }
  55. //
  56. // If the device hasn't been started we will let the IOCTL through. This
  57. // is another hack for ACPI.
  58. //
  59. if (!sffdiskExtension->IsStarted) {
  60. IoSkipCurrentIrpStackLocation( Irp );
  61. return IoCallDriver( sffdiskExtension->TargetObject, Irp );
  62. }
  63. switch( irpSp->Parameters.DeviceIoControl.IoControlCode ) {
  64. case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: {
  65. PMOUNTDEV_NAME mountName;
  66. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n",
  67. DeviceObject, Irp));
  68. ASSERT(sffdiskExtension->DeviceName.Buffer);
  69. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  70. sizeof(MOUNTDEV_NAME) ) {
  71. status = STATUS_INVALID_PARAMETER;
  72. break;
  73. }
  74. mountName = Irp->AssociatedIrp.SystemBuffer;
  75. mountName->NameLength = sffdiskExtension->DeviceName.Length;
  76. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  77. sizeof(USHORT) + mountName->NameLength) {
  78. status = STATUS_BUFFER_OVERFLOW;
  79. Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
  80. break;
  81. }
  82. RtlCopyMemory( mountName->Name, sffdiskExtension->DeviceName.Buffer,
  83. mountName->NameLength);
  84. mountName->Name[mountName->NameLength / sizeof(USHORT)] = L'0';
  85. status = STATUS_SUCCESS;
  86. Irp->IoStatus.Information = sizeof(USHORT) + mountName->NameLength;
  87. break;
  88. }
  89. case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: {
  90. PMOUNTDEV_UNIQUE_ID uniqueId;
  91. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n",
  92. DeviceObject, Irp));
  93. if ( !sffdiskExtension->InterfaceString.Buffer ||
  94. irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  95. sizeof(MOUNTDEV_UNIQUE_ID)) {
  96. status = STATUS_INVALID_PARAMETER;
  97. break;
  98. }
  99. uniqueId = Irp->AssociatedIrp.SystemBuffer;
  100. uniqueId->UniqueIdLength =
  101. sffdiskExtension->InterfaceString.Length;
  102. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  103. sizeof(USHORT) + uniqueId->UniqueIdLength) {
  104. status = STATUS_BUFFER_OVERFLOW;
  105. Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
  106. break;
  107. }
  108. RtlCopyMemory( uniqueId->UniqueId,
  109. sffdiskExtension->InterfaceString.Buffer,
  110. uniqueId->UniqueIdLength );
  111. status = STATUS_SUCCESS;
  112. Irp->IoStatus.Information = sizeof(USHORT) +
  113. uniqueId->UniqueIdLength;
  114. break;
  115. }
  116. case IOCTL_DISK_CHECK_VERIFY: {
  117. PULONG pChangeCount = Irp->AssociatedIrp.SystemBuffer;
  118. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_CHECK_VERIFY\n",
  119. DeviceObject, Irp));
  120. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
  121. status = STATUS_INVALID_PARAMETER;
  122. break;
  123. }
  124. *pChangeCount = 0;
  125. Irp->IoStatus.Information = sizeof(ULONG);
  126. status = STATUS_SUCCESS;
  127. break;
  128. }
  129. case IOCTL_DISK_GET_DRIVE_GEOMETRY: {
  130. PDISK_GEOMETRY outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  131. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_GET_DRIVE_GEOMETRY\n",
  132. DeviceObject, Irp));
  133. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( DISK_GEOMETRY ) ) {
  134. status = STATUS_INVALID_PARAMETER;
  135. break;
  136. }
  137. outputBuffer->MediaType = FixedMedia;
  138. outputBuffer->Cylinders.QuadPart = sffdiskExtension->Cylinders;
  139. outputBuffer->TracksPerCylinder = sffdiskExtension->TracksPerCylinder;
  140. outputBuffer->SectorsPerTrack = sffdiskExtension->SectorsPerTrack;
  141. outputBuffer->BytesPerSector = sffdiskExtension->BytesPerSector;
  142. SffDiskDump( SFFDISKIOCTL, ("SffDisk: Capacity=%.8x => Cyl=%x\n",
  143. sffdiskExtension->ByteCapacity, outputBuffer->Cylinders.LowPart));
  144. status = STATUS_SUCCESS;
  145. Irp->IoStatus.Information = sizeof( DISK_GEOMETRY );
  146. break;
  147. }
  148. case IOCTL_DISK_IS_WRITABLE: {
  149. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_IS_WRITABLE\n",
  150. DeviceObject, Irp));
  151. if ((*(sffdiskExtension->FunctionBlock->IsWriteProtected))(sffdiskExtension)) {
  152. status = STATUS_MEDIA_WRITE_PROTECTED;
  153. } else {
  154. status = STATUS_SUCCESS;
  155. }
  156. break;
  157. }
  158. case IOCTL_DISK_VERIFY: {
  159. PVERIFY_INFORMATION verifyInformation = Irp->AssociatedIrp.SystemBuffer;
  160. if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION)) {
  161. status = STATUS_INVALID_PARAMETER;
  162. break;
  163. }
  164. //NOTE: not implemented
  165. Irp->IoStatus.Information = verifyInformation->Length;
  166. status = STATUS_SUCCESS;
  167. break;
  168. }
  169. #if 0
  170. case IOCTL_DISK_GET_DRIVE_LAYOUT: {
  171. PDRIVE_LAYOUT_INFORMATION outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  172. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_GET_DRIVE_LAYOUT\n",
  173. DeviceObject, Irp));
  174. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DRIVE_LAYOUT_INFORMATION) ) {
  175. status = STATUS_INVALID_PARAMETER;
  176. break;
  177. }
  178. RtlZeroMemory(outputBuffer, sizeof(DRIVE_LAYOUT_INFORMATION));
  179. outputBuffer->PartitionCount = 1;
  180. outputBuffer->PartitionEntry[0].StartingOffset.LowPart = 512;
  181. outputBuffer->PartitionEntry[0].PartitionLength.QuadPart = sffdiskExtension->ByteCapacity;
  182. outputBuffer->PartitionEntry[0].RecognizedPartition = TRUE;
  183. status = STATUS_SUCCESS;
  184. Irp->IoStatus.Information = sizeof(DRIVE_LAYOUT_INFORMATION);
  185. break;
  186. }
  187. case IOCTL_DISK_GET_PARTITION_INFO: {
  188. PPARTITION_INFORMATION outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  189. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_GET_PARTITION_INFO\n",
  190. DeviceObject, Irp));
  191. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( PARTITION_INFORMATION ) ) {
  192. status = STATUS_INVALID_PARAMETER;
  193. break;
  194. }
  195. RtlZeroMemory(outputBuffer, sizeof(PARTITION_INFORMATION));
  196. outputBuffer->RecognizedPartition = TRUE;
  197. outputBuffer->StartingOffset.LowPart = 512;
  198. outputBuffer->PartitionLength.QuadPart = sffdiskExtension->ByteCapacity;
  199. status = STATUS_SUCCESS;
  200. Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
  201. break;
  202. }
  203. #endif
  204. case IOCTL_DISK_GET_PARTITION_INFO_EX: {
  205. PPARTITION_INFORMATION_EX partitionInfo = Irp->AssociatedIrp.SystemBuffer;
  206. SffDiskDump(SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_DISK_GET_PARTITION_INFO_EX\n",
  207. DeviceObject, Irp));
  208. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION_EX)) {
  209. status = STATUS_INVALID_PARAMETER;
  210. break;
  211. }
  212. RtlZeroMemory(partitionInfo, sizeof(PARTITION_INFORMATION_EX));
  213. partitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
  214. partitionInfo->StartingOffset.QuadPart = sffdiskExtension->RelativeOffset;
  215. partitionInfo->PartitionLength.QuadPart = sffdiskExtension->ByteCapacity - sffdiskExtension->RelativeOffset;
  216. // partitionInfo->PartitionNumber
  217. switch(sffdiskExtension->SystemId) {
  218. case PARTITION_FAT_12:
  219. case PARTITION_FAT_16:
  220. case PARTITION_HUGE:
  221. partitionInfo->Mbr.PartitionType = sffdiskExtension->SystemId;
  222. break;
  223. }
  224. status = STATUS_SUCCESS;
  225. Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
  226. break;
  227. }
  228. case IOCTL_DISK_GET_LENGTH_INFO: {
  229. PGET_LENGTH_INFORMATION lengthInfo = Irp->AssociatedIrp.SystemBuffer;
  230. SffDiskDump(SFFDISKIOCTL, ("SffDisk: IOCTL_DISK_GET_LENGTH_INFO\n"));
  231. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION)) {
  232. status = STATUS_INVALID_PARAMETER;
  233. break;
  234. }
  235. RtlZeroMemory(lengthInfo, sizeof(GET_LENGTH_INFORMATION));
  236. lengthInfo->Length.QuadPart = sffdiskExtension->ByteCapacity - sffdiskExtension->RelativeOffset;
  237. status = STATUS_SUCCESS;
  238. Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
  239. break;
  240. }
  241. case IOCTL_STORAGE_GET_HOTPLUG_INFO: {
  242. PSTORAGE_HOTPLUG_INFO info = Irp->AssociatedIrp.SystemBuffer;
  243. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL_STORAGE_GET_HOTPLUG_INFO\n",
  244. DeviceObject, Irp));
  245. if ( irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_HOTPLUG_INFO)) {
  246. status = STATUS_INVALID_PARAMETER;
  247. break;
  248. }
  249. info->MediaRemovable = FALSE;
  250. info->MediaHotplug = FALSE;
  251. info->DeviceHotplug = TRUE;
  252. info->WriteCacheEnableOverride = FALSE;
  253. status = STATUS_SUCCESS;
  254. Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
  255. break;
  256. }
  257. case IOCTL_STORAGE_GET_DEVICE_NUMBER:
  258. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_STORAGE_GET_DEVICE_NUMBER \n"));
  259. status = STATUS_INVALID_DEVICE_REQUEST;
  260. break;
  261. case FT_BALANCED_READ_MODE:
  262. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - FT_BALANCED_READ_MODE\n"));
  263. status = STATUS_INVALID_DEVICE_REQUEST;
  264. break;
  265. case IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY:
  266. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY\n"));
  267. status = STATUS_INVALID_DEVICE_REQUEST;
  268. break;
  269. case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
  270. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n"));
  271. status = STATUS_INVALID_DEVICE_REQUEST;
  272. break;
  273. case IOCTL_MOUNTDEV_LINK_CREATED:
  274. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_MOUNTDEV_LINK_CREATED\n"));
  275. status = STATUS_INVALID_DEVICE_REQUEST;
  276. break;
  277. case IOCTL_MOUNTDEV_LINK_DELETED:
  278. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_MOUNTDEV_LINK_DELETED\n"));
  279. status = STATUS_INVALID_DEVICE_REQUEST;
  280. break;
  281. case IOCTL_MOUNTDEV_QUERY_STABLE_GUID:
  282. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_MOUNTDEV_QUERY_STABLE_GUID\n"));
  283. status = STATUS_INVALID_DEVICE_REQUEST;
  284. break;
  285. case IOCTL_VOLUME_GET_GPT_ATTRIBUTES:
  286. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_VOLUME_GET_GPT_ATTRIBUTES\n"));
  287. status = STATUS_INVALID_DEVICE_REQUEST;
  288. break;
  289. case IOCTL_VOLUME_ONLINE:
  290. SffDiskDump(SFFDISKIOCTL, ("SffDisk: unsupported! - IOCTL_VOLUME_ONLINE\n"));
  291. status = STATUS_INVALID_DEVICE_REQUEST;
  292. break;
  293. default: {
  294. SffDiskDump(SFFDISKIOCTL,
  295. ("SffDisk: IOCTL - UNKNOWN - unsupported device request %.8x\n", irpSp->Parameters.DeviceIoControl.IoControlCode));
  296. status = STATUS_INVALID_DEVICE_REQUEST;
  297. break;
  298. }
  299. }
  300. if ( status != STATUS_PENDING ) {
  301. Irp->IoStatus.Status = status;
  302. if (!NT_SUCCESS( status ) && IoIsErrorUserInduced( status )) {
  303. IoSetHardErrorOrVerifyDevice( Irp, DeviceObject );
  304. }
  305. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL comp %.8x\n", DeviceObject, Irp, status));
  306. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  307. }
  308. SffDiskDump( SFFDISKIOCTL, ("SffDisk: DO %.8x Irp %.8x IOCTL <-- %.8x \n", DeviceObject, Irp, status));
  309. return status;
  310. }