3 Copyright (C) Microsoft Corporation, 1991 - 1999
11 SCSI disk class driver
25 #define PtCache ClassDebugExternal1
29 #pragma alloc_text(PAGE, DiskReadPartitionTableEx)
30 #pragma alloc_text(PAGE, DiskWritePartitionTableEx)
31 #pragma alloc_text(PAGE, DiskSetPartitionInformationEx)
34 ULONG DiskBreakOnPtInval
= FALSE
;
37 // By default, 64-bit systems can see GPT disks and 32-bit systems
38 // cannot. This will likely change in the future.
42 ULONG DiskDisableGpt
= FALSE
;
44 ULONG DiskDisableGpt
= TRUE
;
48 DiskReadPartitionTableEx(
49 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
50 IN BOOLEAN BypassCache
,
51 OUT PDRIVE_LAYOUT_INFORMATION_EX
* DriveLayout
57 This routine will return the current layout information for the disk.
58 If the cached information is still valid then it will be returned,
59 otherwise the layout will be retreived from the kernel and cached for
62 This routine must be called with the partitioning lock held. The
63 partition list which is returned is not guaranteed to remain valid
64 once the lock has been released.
68 Fdo - a pointer to the FDO for the disk.
70 DriveLayout - a location to store a pointer to the drive layout information.
74 STATUS_SUCCESS if successful or an error status indicating what failed.
79 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
81 PDRIVE_LAYOUT_INFORMATION_EX layoutEx
;
86 diskData
->CachedPartitionTableValid
= FALSE
;
87 DebugPrint((PtCache
, "DiskRPTEx: cache bypassed and invalidated for "
92 // If the cached partition table is present then return a copy of it.
95 if(diskData
->CachedPartitionTableValid
== TRUE
) {
97 ULONG partitionNumber
;
98 PDRIVE_LAYOUT_INFORMATION_EX layout
= diskData
->CachedPartitionTable
;
101 // Clear the partition numbers from the list entries
104 for(partitionNumber
= 0;
105 partitionNumber
< layout
->PartitionCount
;
107 layout
->PartitionEntry
[partitionNumber
].PartitionNumber
= 0;
110 *DriveLayout
= diskData
->CachedPartitionTable
;
112 DebugPrint((PtCache
, "DiskRPTEx: cached PT returned (%#p) for "
116 return STATUS_SUCCESS
;
119 ASSERTMSG("DiskReadPartitionTableEx is not using cached partition table",
120 (DiskBreakOnPtInval
== FALSE
));
123 // If there's a cached partition table still around then free it.
126 if(diskData
->CachedPartitionTable
) {
127 DebugPrint((PtCache
, "DiskRPTEx: cached PT (%#p) freed for FDO %#p\n",
128 diskData
->CachedPartitionTable
, Fdo
));
130 ExFreePool(diskData
->CachedPartitionTable
);
131 diskData
->CachedPartitionTable
= NULL
;
135 // By default, X86 disables recognition of GPT disks. Instead we
136 // return the protective MBR partition. Use IoReadPartitionTable
140 status
= IoReadPartitionTableEx(Fdo
->DeviceObject
, &layoutEx
);
142 if (DiskDisableGpt
) {
143 PDRIVE_LAYOUT_INFORMATION layout
;
145 if (NT_SUCCESS (status
) &&
146 layoutEx
->PartitionStyle
== PARTITION_STYLE_GPT
) {
149 // ISSUE - 2000/29/08 - math: Remove from final product.
150 // Leave this debug print in for a while until everybody
151 // has had a chance to convert their GPT disks to MBR.
154 DbgPrint ("DISK: Disk %p recognized as a GPT disk on a system without GPT support.\n"
155 " Disk will appear as RAW.\n",
158 ExFreePool (layoutEx
);
159 status
= IoReadPartitionTable(Fdo
->DeviceObject
,
160 Fdo
->DiskGeometry
.BytesPerSector
,
163 if (NT_SUCCESS (status
)) {
164 layoutEx
= DiskConvertLayoutToExtended(layout
);
170 diskData
->CachedPartitionTable
= layoutEx
;
173 // If the routine fails make sure we don't have a stale partition table
174 // pointer. Otherwise indicate that the table is now valid.
177 if(!NT_SUCCESS(status
)) {
178 diskData
->CachedPartitionTable
= NULL
;
180 diskData
->CachedPartitionTableValid
= TRUE
;
183 *DriveLayout
= diskData
->CachedPartitionTable
;
185 DebugPrint((PtCache
, "DiskRPTEx: returning PT %#p for FDO %#p with status "
186 "%#08lx. PT is %scached\n",
190 (diskData
->CachedPartitionTableValid
? "" : "not ")));
198 DiskWritePartitionTableEx(
199 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
200 IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout
206 This routine will invalidate the cached partition table. It will then
207 write the new drive layout to disk.
211 Fdo - the FDO for the disk getting the new partition table.
213 DriveLayout - the new drive layout.
221 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
224 // Invalidate the cached partition table. Do not free it as it may be
225 // the very drive layout that was passed in to us.
228 diskData
->CachedPartitionTableValid
= FALSE
;
230 DebugPrint((PtCache
, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
233 if (DiskDisableGpt
) {
234 if (DriveLayout
->PartitionStyle
== PARTITION_STYLE_GPT
) {
235 return STATUS_NOT_SUPPORTED
;
239 return IoWritePartitionTableEx(Fdo
->DeviceObject
, DriveLayout
);
243 DiskSetPartitionInformationEx(
244 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
245 IN ULONG PartitionNumber
,
246 IN
struct _SET_PARTITION_INFORMATION_EX
* PartitionInfo
249 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
251 diskData
->CachedPartitionTableValid
= FALSE
;
252 DebugPrint((PtCache
, "DiskSPIEx: Invalidating PT cache for FDO %#p\n",
255 if (DiskDisableGpt
) {
256 if (PartitionInfo
->PartitionStyle
== PARTITION_STYLE_GPT
) {
257 return STATUS_NOT_SUPPORTED
;
261 return IoSetPartitionInformationEx(Fdo
->DeviceObject
,
267 DiskSetPartitionInformation(
268 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
270 IN ULONG PartitionNumber
,
271 IN ULONG PartitionType
274 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
276 diskData
->CachedPartitionTableValid
= FALSE
;
277 DebugPrint((PtCache
, "DiskSPI: Invalidating PT cache for FDO %#p\n",
280 return IoSetPartitionInformation(Fdo
->DeviceObject
,
287 DiskInvalidatePartitionTable(
288 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
289 IN BOOLEAN PartitionLockHeld
292 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
295 wasValid
= (BOOLEAN
) (diskData
->CachedPartitionTableValid
? TRUE
: FALSE
);
296 diskData
->CachedPartitionTableValid
= FALSE
;
298 DebugPrint((PtCache
, "DiskIPT: Invalidating PT cache for FDO %#p\n",
301 if((PartitionLockHeld
) && (diskData
->CachedPartitionTable
!= NULL
)) {
302 DebugPrint((PtCache
, "DiskIPT: Freeing PT cache (%#p) for FDO %#p\n",
303 diskData
->CachedPartitionTable
, Fdo
));
304 ExFreePool(diskData
->CachedPartitionTable
);
305 diskData
->CachedPartitionTable
= NULL
;
312 DiskVerifyPartitionTable(
313 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo
,
317 PDISK_DATA diskData
= Fdo
->CommonExtension
.DriverData
;
320 diskData
->CachedPartitionTableValid
= FALSE
;
321 DebugPrint((PtCache
, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
325 return IoVerifyPartitionTable(Fdo
->DeviceObject
, FixErrors
);