ReactOS  0.4.14-dev-384-g5b37caa
part.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4 
5 Module Name:
6 
7  disk.c
8 
9 Abstract:
10 
11  SCSI disk class driver
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 Revision History:
20 
21 --*/
22 
23 #include "disk.h"
24 
25 #define PtCache ClassDebugExternal1
26 
27 #ifdef ALLOC_PRAGMA
28 
29 #pragma alloc_text(PAGE, DiskReadPartitionTableEx)
30 #pragma alloc_text(PAGE, DiskWritePartitionTableEx)
31 #pragma alloc_text(PAGE, DiskSetPartitionInformationEx)
32 #endif
33 
35 
36 //
37 // By default, 64-bit systems can see GPT disks and 32-bit systems
38 // cannot. This will likely change in the future.
39 //
40 
41 #if defined(_WIN64)
43 #else
45 #endif
46 
48 NTAPI
51  IN BOOLEAN BypassCache,
53  )
54 /*++
55 
56 Routine Description:
57 
58  This routine will return the current layout information for the disk.
59  If the cached information is still valid then it will be returned,
60  otherwise the layout will be retrieved from the kernel and cached for
61  future use.
62 
63  This routine must be called with the partitioning lock held. The
64  partition list which is returned is not guaranteed to remain valid
65  once the lock has been released.
66 
67 Arguments:
68 
69  Fdo - a pointer to the FDO for the disk.
70 
71  DriveLayout - a location to store a pointer to the drive layout information.
72 
73 Return Value:
74 
75  STATUS_SUCCESS if successful or an error status indicating what failed.
76 
77 --*/
78 
79 {
80  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
83 
84  layoutEx = NULL;
85 
86  if(BypassCache) {
87  diskData->CachedPartitionTableValid = FALSE;
88  DebugPrint((PtCache, "DiskRPTEx: cache bypassed and invalidated for "
89  "FDO %#p\n", Fdo));
90  }
91 
92  //
93  // If the cached partition table is present then return a copy of it.
94  //
95 
96  if (diskData->CachedPartitionTableValid != FALSE) {
97 
98  ULONG partitionNumber;
100 
101  //
102  // Clear the partition numbers from the list entries
103  //
104 
105  for(partitionNumber = 0;
106  partitionNumber < layout->PartitionCount;
107  partitionNumber++) {
108  layout->PartitionEntry[partitionNumber].PartitionNumber = 0;
109  }
110 
111  *DriveLayout = diskData->CachedPartitionTable;
112 
113  DebugPrint((PtCache, "DiskRPTEx: cached PT returned (%#p) for "
114  "FDO %#p\n",
115  *DriveLayout, Fdo));
116 
117  return STATUS_SUCCESS;
118  }
119 
120  ASSERTMSG("DiskReadPartitionTableEx is not using cached partition table",
122 
123  //
124  // If there's a cached partition table still around then free it.
125  //
126 
127  if(diskData->CachedPartitionTable) {
128  DebugPrint((PtCache, "DiskRPTEx: cached PT (%#p) freed for FDO %#p\n",
129  diskData->CachedPartitionTable, Fdo));
130 
131  ExFreePool(diskData->CachedPartitionTable);
132  diskData->CachedPartitionTable = NULL;
133  }
134 
135  //
136  // By default, X86 disables recognition of GPT disks. Instead we
137  // return the protective MBR partition. Use IoReadPartitionTable
138  // to get this.
139  //
140 
141  status = IoReadPartitionTableEx(Fdo->DeviceObject, &layoutEx);
142 
143  if (DiskDisableGpt) {
145 
146  if (NT_SUCCESS (status) &&
147  layoutEx->PartitionStyle == PARTITION_STYLE_GPT) {
148 
149  //
150  // ISSUE - 2000/29/08 - math: Remove from final product.
151  // Leave this debug print in for a while until everybody
152  // has had a chance to convert their GPT disks to MBR.
153  //
154 
155  DbgPrint ("DISK: Disk %p recognized as a GPT disk on a system without GPT support.\n"
156  " Disk will appear as RAW.\n",
157  Fdo->DeviceObject);
158 
159  ExFreePool (layoutEx);
160  status = IoReadPartitionTable(Fdo->DeviceObject,
161  Fdo->DiskGeometry.BytesPerSector,
162  FALSE,
163  &layout);
164  if (NT_SUCCESS (status)) {
166  ExFreePool (layout);
167  }
168  }
169  }
170 
171  diskData->CachedPartitionTable = layoutEx;
172 
173  //
174  // If the routine fails make sure we don't have a stale partition table
175  // pointer. Otherwise indicate that the table is now valid.
176  //
177 
178  if(!NT_SUCCESS(status)) {
179  diskData->CachedPartitionTable = NULL;
180  } else {
181  diskData->CachedPartitionTableValid = TRUE;
182  }
183 
184  *DriveLayout = diskData->CachedPartitionTable;
185 
186  DebugPrint((PtCache, "DiskRPTEx: returning PT %#p for FDO %#p with status "
187  "%#08lx. PT is %scached\n",
188  *DriveLayout,
189  Fdo,
190  status,
191  (diskData->CachedPartitionTableValid ? "" : "not ")));
192 
193 
194  return status;
195 }
196 
197 NTSTATUS
198 NTAPI
201  IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout
202  )
203 /*++
204 
205 Routine Description:
206 
207  This routine will invalidate the cached partition table. It will then
208  write the new drive layout to disk.
209 
210 Arguments:
211 
212  Fdo - the FDO for the disk getting the new partition table.
213 
214  DriveLayout - the new drive layout.
215 
216 Return Value:
217 
218  status
219 
220 --*/
221 {
222  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
223 
224  //
225  // Invalidate the cached partition table. Do not free it as it may be
226  // the very drive layout that was passed in to us.
227  //
228 
229  diskData->CachedPartitionTableValid = FALSE;
230 
231  DebugPrint((PtCache, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
232  Fdo));
233 
234  if (DiskDisableGpt) {
235  if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT) {
236  return STATUS_NOT_SUPPORTED;
237  }
238  }
239 
240  return IoWritePartitionTableEx(Fdo->DeviceObject, DriveLayout);
241 }
242 
243 NTSTATUS
244 NTAPI
249  )
250 {
251  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
252 
253  diskData->CachedPartitionTableValid = FALSE;
254  DebugPrint((PtCache, "DiskSPIEx: Invalidating PT cache for FDO %#p\n",
255  Fdo));
256 
257  if (DiskDisableGpt) {
258  if (PartitionInfo->PartitionStyle == PARTITION_STYLE_GPT) {
259  return STATUS_NOT_SUPPORTED;
260  }
261  }
262 
263  return IoSetPartitionInformationEx(Fdo->DeviceObject,
265  PartitionInfo);
266 }
267 
268 NTSTATUS
269 NTAPI
275  )
276 {
277  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
278 
279  diskData->CachedPartitionTableValid = FALSE;
280  DebugPrint((PtCache, "DiskSPI: Invalidating PT cache for FDO %#p\n",
281  Fdo));
282 
283  return IoSetPartitionInformation(Fdo->DeviceObject,
284  SectorSize,
286  PartitionType);
287 }
288 
289 BOOLEAN
290 NTAPI
293  IN BOOLEAN PartitionLockHeld
294  )
295 {
296  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
297  BOOLEAN wasValid;
298 
299  wasValid = (BOOLEAN) (diskData->CachedPartitionTableValid ? TRUE : FALSE);
300  diskData->CachedPartitionTableValid = FALSE;
301 
302  DebugPrint((PtCache, "DiskIPT: Invalidating PT cache for FDO %#p\n",
303  Fdo));
304 
305  if((PartitionLockHeld) && (diskData->CachedPartitionTable != NULL)) {
306  DebugPrint((PtCache, "DiskIPT: Freeing PT cache (%#p) for FDO %#p\n",
307  diskData->CachedPartitionTable, Fdo));
308  ExFreePool(diskData->CachedPartitionTable);
309  diskData->CachedPartitionTable = NULL;
310  }
311 
312  return wasValid;
313 }
314 
315 NTSTATUS
316 NTAPI
320  )
321 {
322  PDISK_DATA diskData = Fdo->CommonExtension.DriverData;
323 
324  if(FixErrors) {
325  diskData->CachedPartitionTableValid = FALSE;
326  DebugPrint((PtCache, "DiskWPTEx: Invalidating PT cache for FDO %#p\n",
327  Fdo));
328  }
329 
330  return IoVerifyPartitionTable(Fdo->DeviceObject, FixErrors);
331 }
NTSTATUS NTAPI DiskSetPartitionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: part.c:270
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
PDRIVE_LAYOUT_INFORMATION_EX CachedPartitionTable
Definition: disk.h:292
#define DbgPrint
Definition: loader.c:25
ULONG DiskDisableGpt
Definition: part.c:44
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI DiskReadPartitionTableEx(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN BOOLEAN BypassCache, OUT PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: part.c:49
ULONG DiskBreakOnPtInval
Definition: part.c:34
NTSTATUS NTAPI IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX **DriveLayout)
Definition: fstubex.c:2245
NTSTATUS NTAPI DiskSetPartitionInformationEx(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN ULONG PartitionNumber, IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo)
Definition: part.c:245
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI DiskInvalidatePartitionTable(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN BOOLEAN PartitionLockHeld)
Definition: part.c:291
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
NTSTATUS NTAPI IoSetPartitionInformationEx(IN PDEVICE_OBJECT DeviceObject, IN ULONG PartitionNumber, IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo)
Definition: fstubex.c:2312
PDRIVE_LAYOUT_INFORMATION_EX NTAPI DiskConvertLayoutToExtended(IN CONST PDRIVE_LAYOUT_INFORMATION Layout)
Definition: enum.c:147
NTSTATUS NTAPI IoVerifyPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FixErrors)
Definition: fstubex.c:2377
static DWORD layout
Definition: bitmap.c:46
NTSTATUS NTAPI IoWritePartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: fstubex.c:2429
NTSTATUS FASTCALL IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
Definition: partition.c:495
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
BOOL FixErrors
Definition: chkdsk.c:69
NTSTATUS NTAPI DiskWritePartitionTableEx(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout)
Definition: part.c:199
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
NTSTATUS FASTCALL IoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: ntoskrnl.c:64
CHAR PartitionType
Definition: part_xbox.c:33
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
_In_ ULONG SectorSize
Definition: halfuncs.h:291
ULONG CachedPartitionTableValid
Definition: disk.h:282
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define PtCache
Definition: part.c:25
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI DiskVerifyPartitionTable(IN PFUNCTIONAL_DEVICE_EXTENSION Fdo, IN BOOLEAN FixErrors)
Definition: part.c:317
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97