Source code of Windows XP (NT5)
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.

326 lines
8.6 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. disk.c
  5. Abstract:
  6. SCSI disk class driver
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include "disk.h"
  13. #define PtCache ClassDebugExternal1
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE, DiskReadPartitionTableEx)
  16. #pragma alloc_text(PAGE, DiskWritePartitionTableEx)
  17. #pragma alloc_text(PAGE, DiskSetPartitionInformationEx)
  18. #endif
  19. ULONG DiskBreakOnPtInval = FALSE;
  20. //
  21. // By default, 64-bit systems can see GPT disks and 32-bit systems
  22. // cannot. This will likely change in the future.
  23. //
  24. #if defined(_WIN64)
  25. ULONG DiskDisableGpt = FALSE;
  26. #else
  27. ULONG DiskDisableGpt = TRUE;
  28. #endif
  29. NTSTATUS
  30. DiskReadPartitionTableEx(
  31. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  32. IN BOOLEAN BypassCache,
  33. OUT PDRIVE_LAYOUT_INFORMATION_EX* DriveLayout
  34. )
  35. /*++
  36. Routine Description:
  37. This routine will return the current layout information for the disk.
  38. If the cached information is still valid then it will be returned,
  39. otherwise the layout will be retreived from the kernel and cached for
  40. future use.
  41. This routine must be called with the partitioning lock held. The
  42. partition list which is returned is not guaranteed to remain valid
  43. once the lock has been released.
  44. Arguments:
  45. Fdo - a pointer to the FDO for the disk.
  46. DriveLayout - a location to store a pointer to the drive layout information.
  47. Return Value:
  48. STATUS_SUCCESS if successful or an error status indicating what failed.
  49. --*/
  50. {
  51. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  52. NTSTATUS status;
  53. PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
  54. layoutEx = NULL;
  55. if(BypassCache) {
  56. diskData->CachedPartitionTableValid = FALSE;
  57. DebugPrint((PtCache, "DiskRPTEx: cache bypassed and invalidated for "
  58. "FDO %#p\n", Fdo));
  59. }
  60. //
  61. // If the cached partition table is present then return a copy of it.
  62. //
  63. if(diskData->CachedPartitionTableValid == TRUE) {
  64. ULONG partitionNumber;
  65. PDRIVE_LAYOUT_INFORMATION_EX layout = diskData->CachedPartitionTable;
  66. //
  67. // Clear the partition numbers from the list entries
  68. //
  69. for(partitionNumber = 0;
  70. partitionNumber < layout->PartitionCount;
  71. partitionNumber++) {
  72. layout->PartitionEntry[partitionNumber].PartitionNumber = 0;
  73. }
  74. *DriveLayout = diskData->CachedPartitionTable;
  75. DebugPrint((PtCache, "DiskRPTEx: cached PT returned (%#p) for "
  76. "FDO %#p\n",
  77. *DriveLayout, Fdo));
  78. return STATUS_SUCCESS;
  79. }
  80. ASSERTMSG("DiskReadPartitionTableEx is not using cached partition table",
  81. (DiskBreakOnPtInval == FALSE));
  82. //
  83. // If there's a cached partition table still around then free it.
  84. //
  85. if(diskData->CachedPartitionTable) {
  86. DebugPrint((PtCache, "DiskRPTEx: cached PT (%#p) freed for FDO %#p\n",
  87. diskData->CachedPartitionTable, Fdo));
  88. ExFreePool(diskData->CachedPartitionTable);
  89. diskData->CachedPartitionTable = NULL;
  90. }
  91. //
  92. // By default, X86 disables recognition of GPT disks. Instead we
  93. // return the protective MBR partition. Use IoReadPartitionTable
  94. // to get this.
  95. //
  96. status = IoReadPartitionTableEx(Fdo->DeviceObject, &layoutEx);
  97. if (DiskDisableGpt) {
  98. PDRIVE_LAYOUT_INFORMATION layout;
  99. if (NT_SUCCESS (status) &&
  100. layoutEx->PartitionStyle == PARTITION_STYLE_GPT) {
  101. //
  102. // ISSUE - 2000/29/08 - math: Remove from final product.
  103. // Leave this debug print in for a while until everybody
  104. // has had a chance to convert their GPT disks to MBR.
  105. //
  106. DbgPrint ("DISK: Disk %p recognized as a GPT disk on a system without GPT support.\n"
  107. " Disk will appear as RAW.\n",
  108. Fdo->DeviceObject);
  109. ExFreePool (layoutEx);
  110. status = IoReadPartitionTable(Fdo->DeviceObject,
  111. Fdo->DiskGeometry.BytesPerSector,
  112. FALSE,
  113. &layout);
  114. if (NT_SUCCESS (status)) {
  115. layoutEx = DiskConvertLayoutToExtended(layout);
  116. ExFreePool (layout);
  117. }
  118. }
  119. }
  120. diskData->CachedPartitionTable = layoutEx;
  121. //
  122. // If the routine fails make sure we don't have a stale partition table
  123. // pointer. Otherwise indicate that the table is now valid.
  124. //
  125. if(!NT_SUCCESS(status)) {
  126. diskData->CachedPartitionTable = NULL;
  127. } else {
  128. diskData->CachedPartitionTableValid = TRUE;
  129. }
  130. *DriveLayout = diskData->CachedPartitionTable;
  131. DebugPrint((PtCache, "DiskRPTEx: returning PT %#p for FDO %#p with status "
  132. "%#08lx. PT is %scached\n",
  133. *DriveLayout,
  134. Fdo,
  135. status,
  136. (diskData->CachedPartitionTableValid ? "" : "not ")));
  137. return status;
  138. }
  139. NTSTATUS
  140. DiskWritePartitionTableEx(
  141. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  142. IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout
  143. )
  144. /*++
  145. Routine Description:
  146. This routine will invalidate the cached partition table. It will then
  147. write the new drive layout to disk.
  148. Arguments:
  149. Fdo - the FDO for the disk getting the new partition table.
  150. DriveLayout - the new drive layout.
  151. Return Value:
  152. status
  153. --*/
  154. {
  155. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  156. //
  157. // Invalidate the cached partition table. Do not free it as it may be
  158. // the very drive layout that was passed in to us.
  159. //
  160. diskData->CachedPartitionTableValid = FALSE;
  161. DebugPrint((PtCache, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
  162. Fdo));
  163. if (DiskDisableGpt) {
  164. if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT) {
  165. return STATUS_NOT_SUPPORTED;
  166. }
  167. }
  168. return IoWritePartitionTableEx(Fdo->DeviceObject, DriveLayout);
  169. }
  170. NTSTATUS
  171. DiskSetPartitionInformationEx(
  172. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  173. IN ULONG PartitionNumber,
  174. IN struct _SET_PARTITION_INFORMATION_EX* PartitionInfo
  175. )
  176. {
  177. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  178. diskData->CachedPartitionTableValid = FALSE;
  179. DebugPrint((PtCache, "DiskSPIEx: Invalidating PT cache for FDO %#p\n",
  180. Fdo));
  181. if (DiskDisableGpt) {
  182. if (PartitionInfo->PartitionStyle == PARTITION_STYLE_GPT) {
  183. return STATUS_NOT_SUPPORTED;
  184. }
  185. }
  186. return IoSetPartitionInformationEx(Fdo->DeviceObject,
  187. PartitionNumber,
  188. PartitionInfo);
  189. }
  190. NTSTATUS
  191. DiskSetPartitionInformation(
  192. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  193. IN ULONG SectorSize,
  194. IN ULONG PartitionNumber,
  195. IN ULONG PartitionType
  196. )
  197. {
  198. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  199. diskData->CachedPartitionTableValid = FALSE;
  200. DebugPrint((PtCache, "DiskSPI: Invalidating PT cache for FDO %#p\n",
  201. Fdo));
  202. return IoSetPartitionInformation(Fdo->DeviceObject,
  203. SectorSize,
  204. PartitionNumber,
  205. PartitionType);
  206. }
  207. BOOLEAN
  208. DiskInvalidatePartitionTable(
  209. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  210. IN BOOLEAN PartitionLockHeld
  211. )
  212. {
  213. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  214. BOOLEAN wasValid;
  215. wasValid = (BOOLEAN) (diskData->CachedPartitionTableValid ? TRUE : FALSE);
  216. diskData->CachedPartitionTableValid = FALSE;
  217. DebugPrint((PtCache, "DiskIPT: Invalidating PT cache for FDO %#p\n",
  218. Fdo));
  219. if((PartitionLockHeld) && (diskData->CachedPartitionTable != NULL)) {
  220. DebugPrint((PtCache, "DiskIPT: Freeing PT cache (%#p) for FDO %#p\n",
  221. diskData->CachedPartitionTable, Fdo));
  222. ExFreePool(diskData->CachedPartitionTable);
  223. diskData->CachedPartitionTable = NULL;
  224. }
  225. return wasValid;
  226. }
  227. NTSTATUS
  228. DiskVerifyPartitionTable(
  229. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  230. IN BOOLEAN FixErrors
  231. )
  232. {
  233. PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
  234. if(FixErrors) {
  235. diskData->CachedPartitionTableValid = FALSE;
  236. DebugPrint((PtCache, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
  237. Fdo));
  238. }
  239. return IoVerifyPartitionTable(Fdo->DeviceObject, FixErrors);
  240. }