1 /* 2 * PROJECT: ReactOS Setup Library 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Partition list functions 5 * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net) 6 * Copyright 2018-2019 Hermes Belusca-Maito 7 */ 8 9 #pragma once 10 11 /* EXTRA HANDFUL MACROS *****************************************************/ 12 13 // NOTE: They should be moved into some global header. 14 15 /* OEM MBR partition types recognized by NT (see [MS-DMRP] Appendix B) */ 16 #define PARTITION_EISA 0x12 // EISA partition 17 #define PARTITION_HIBERNATION 0x84 // Hibernation partition for laptops 18 #define PARTITION_DIAGNOSTIC 0xA0 // Diagnostic partition on some Hewlett-Packard (HP) notebooks 19 #define PARTITION_DELL 0xDE // Dell partition 20 #define PARTITION_IBM 0xFE // IBM Initial Microprogram Load (IML) partition 21 22 #define IsOEMPartition(PartitionType) \ 23 ( ((PartitionType) == PARTITION_EISA) || \ 24 ((PartitionType) == PARTITION_HIBERNATION) || \ 25 ((PartitionType) == PARTITION_DIAGNOSTIC) || \ 26 ((PartitionType) == PARTITION_DELL) || \ 27 ((PartitionType) == PARTITION_IBM) ) 28 29 30 /* PARTITION UTILITY FUNCTIONS **********************************************/ 31 32 typedef enum _FORMATSTATE 33 { 34 Unformatted, 35 UnformattedOrDamaged, 36 UnknownFormat, 37 Preformatted, 38 Formatted 39 } FORMATSTATE, *PFORMATSTATE; 40 41 typedef struct _PARTENTRY 42 { 43 LIST_ENTRY ListEntry; 44 45 /* The disk this partition belongs to */ 46 struct _DISKENTRY *DiskEntry; 47 48 /* Partition geometry */ 49 ULARGE_INTEGER StartSector; 50 ULARGE_INTEGER SectorCount; 51 52 BOOLEAN BootIndicator; // NOTE: See comment for the PARTLIST::SystemPartition member. 53 UCHAR PartitionType; 54 ULONG OnDiskPartitionNumber; /* Enumerated partition number (primary partitions first, excluding the extended partition container, then the logical partitions) */ 55 ULONG PartitionNumber; /* Current partition number, only valid for the currently running NTOS instance */ 56 ULONG PartitionIndex; /* Index in the LayoutBuffer->PartitionEntry[] cached array of the corresponding DiskEntry */ 57 58 WCHAR DriveLetter; 59 WCHAR VolumeLabel[20]; 60 WCHAR FileSystem[MAX_PATH+1]; 61 FORMATSTATE FormatState; 62 63 BOOLEAN LogicalPartition; 64 65 /* Partition is partitioned disk space */ 66 BOOLEAN IsPartitioned; 67 68 /** The following three properties may be replaced by flags **/ 69 70 /* Partition is new, table does not exist on disk yet */ 71 BOOLEAN New; 72 73 /* Partition must be checked */ 74 BOOLEAN NeedsCheck; 75 76 } PARTENTRY, *PPARTENTRY; 77 78 typedef struct _DISKENTRY 79 { 80 LIST_ENTRY ListEntry; 81 82 /* The list of disks/partitions this disk belongs to */ 83 struct _PARTLIST *PartList; 84 85 MEDIA_TYPE MediaType; /* FixedMedia or RemovableMedia */ 86 87 /* Disk geometry */ 88 89 ULONGLONG Cylinders; 90 ULONG TracksPerCylinder; 91 ULONG SectorsPerTrack; 92 ULONG BytesPerSector; 93 94 ULARGE_INTEGER SectorCount; 95 ULONG SectorAlignment; 96 ULONG CylinderAlignment; 97 98 /* BIOS Firmware parameters */ 99 BOOLEAN BiosFound; 100 ULONG HwAdapterNumber; 101 ULONG HwControllerNumber; 102 ULONG HwDiskNumber; /* Disk number currently assigned on the system */ 103 ULONG HwFixedDiskNumber; /* Disk number on the system when *ALL* removable disks are not connected */ 104 // ULONG Signature; // Obtained from LayoutBuffer->Signature 105 // ULONG Checksum; 106 107 /* SCSI parameters */ 108 ULONG DiskNumber; 109 // SCSI_ADDRESS; 110 USHORT Port; 111 USHORT Bus; 112 USHORT Id; 113 114 /* Has the partition list been modified? */ 115 BOOLEAN Dirty; 116 117 BOOLEAN NewDisk; /* If TRUE, the disk is uninitialized */ 118 PARTITION_STYLE DiskStyle; /* MBR/GPT-partitioned disk, or uninitialized disk (RAW) */ 119 120 UNICODE_STRING DriverName; 121 122 PDRIVE_LAYOUT_INFORMATION LayoutBuffer; 123 // TODO: When adding support for GPT disks: 124 // Use PDRIVE_LAYOUT_INFORMATION_EX which indicates whether 125 // the disk is MBR, GPT, or unknown (uninitialized). 126 // Depending on the style, either use the MBR or GPT partition info. 127 128 LIST_ENTRY PrimaryPartListHead; /* List of primary partitions */ 129 LIST_ENTRY LogicalPartListHead; /* List of logical partitions (Valid only for MBR-partitioned disks) */ 130 131 /* Pointer to the unique extended partition on this disk (Valid only for MBR-partitioned disks) */ 132 PPARTENTRY ExtendedPartition; 133 134 } DISKENTRY, *PDISKENTRY; 135 136 typedef struct _BIOSDISKENTRY 137 { 138 LIST_ENTRY ListEntry; 139 ULONG AdapterNumber; 140 ULONG ControllerNumber; 141 ULONG DiskNumber; 142 ULONG Signature; 143 ULONG Checksum; 144 PDISKENTRY DiskEntry; /* Corresponding recognized disk; is NULL if the disk is not recognized */ // RecognizedDiskEntry; 145 CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; 146 CM_INT13_DRIVE_PARAMETER Int13DiskData; 147 } BIOSDISKENTRY, *PBIOSDISKENTRY; 148 149 typedef struct _PARTLIST 150 { 151 /* 152 * The system partition where the boot manager resides. 153 * The corresponding system disk is obtained via: 154 * SystemPartition->DiskEntry. 155 */ 156 // NOTE: It seems to appear that the specifications of ARC and (u)EFI 157 // actually allow for multiple system partitions to exist on the system. 158 // If so we should instead rely on the BootIndicator bit of the PARTENTRY 159 // structure in order to find these. 160 PPARTENTRY SystemPartition; 161 162 LIST_ENTRY DiskListHead; 163 LIST_ENTRY BiosDiskListHead; 164 165 } PARTLIST, *PPARTLIST; 166 167 #define PARTITION_TBL_SIZE 4 168 169 #define PARTITION_MAGIC 0xAA55 170 171 /* Defines system type for MBR showing that a GPT is following */ 172 #define EFI_PMBR_OSTYPE_EFI 0xEE 173 174 #include <pshpack1.h> 175 176 typedef struct _PARTITION 177 { 178 unsigned char BootFlags; /* bootable? 0=no, 128=yes */ 179 unsigned char StartingHead; /* beginning head number */ 180 unsigned char StartingSector; /* beginning sector number */ 181 unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */ 182 unsigned char PartitionType; /* Operating System type indicator code */ 183 unsigned char EndingHead; /* ending head number */ 184 unsigned char EndingSector; /* ending sector number */ 185 unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */ 186 unsigned int StartingBlock; /* first sector relative to start of disk */ 187 unsigned int SectorCount; /* number of sectors in partition */ 188 } PARTITION, *PPARTITION; 189 190 typedef struct _PARTITION_SECTOR 191 { 192 UCHAR BootCode[440]; /* 0x000 */ 193 ULONG Signature; /* 0x1B8 */ 194 UCHAR Reserved[2]; /* 0x1BC */ 195 PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */ 196 USHORT Magic; /* 0x1FE */ 197 } PARTITION_SECTOR, *PPARTITION_SECTOR; 198 199 #include <poppack.h> 200 201 typedef struct 202 { 203 LIST_ENTRY ListEntry; 204 ULONG DiskNumber; 205 ULONG Identifier; 206 ULONG Signature; 207 } BIOS_DISK, *PBIOS_DISK; 208 209 210 211 ULONGLONG 212 AlignDown( 213 IN ULONGLONG Value, 214 IN ULONG Alignment); 215 216 ULONGLONG 217 AlignUp( 218 IN ULONGLONG Value, 219 IN ULONG Alignment); 220 221 ULONGLONG 222 RoundingDivide( 223 IN ULONGLONG Dividend, 224 IN ULONGLONG Divisor); 225 226 227 #define GetPartEntryOffsetInBytes(PartEntry) \ 228 ((PartEntry)->StartSector.QuadPart * (PartEntry)->DiskEntry->BytesPerSector) 229 230 #define GetPartEntrySizeInBytes(PartEntry) \ 231 ((PartEntry)->SectorCount.QuadPart * (PartEntry)->DiskEntry->BytesPerSector) 232 233 #define GetDiskSizeInBytes(DiskEntry) \ 234 ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector) 235 236 237 BOOLEAN 238 IsSuperFloppy( 239 IN PDISKENTRY DiskEntry); 240 241 BOOLEAN 242 IsPartitionActive( 243 IN PPARTENTRY PartEntry); 244 245 PPARTLIST 246 CreatePartitionList(VOID); 247 248 VOID 249 DestroyPartitionList( 250 IN PPARTLIST List); 251 252 PDISKENTRY 253 GetDiskByBiosNumber( 254 IN PPARTLIST List, 255 IN ULONG HwDiskNumber); 256 257 PDISKENTRY 258 GetDiskByNumber( 259 IN PPARTLIST List, 260 IN ULONG DiskNumber); 261 262 PDISKENTRY 263 GetDiskBySCSI( 264 IN PPARTLIST List, 265 IN USHORT Port, 266 IN USHORT Bus, 267 IN USHORT Id); 268 269 PDISKENTRY 270 GetDiskBySignature( 271 IN PPARTLIST List, 272 IN ULONG Signature); 273 274 PPARTENTRY 275 GetPartition( 276 // IN PPARTLIST List, 277 IN PDISKENTRY DiskEntry, 278 IN ULONG PartitionNumber); 279 280 BOOLEAN 281 GetDiskOrPartition( 282 IN PPARTLIST List, 283 IN ULONG DiskNumber, 284 IN ULONG PartitionNumber OPTIONAL, 285 OUT PDISKENTRY* pDiskEntry, 286 OUT PPARTENTRY* pPartEntry OPTIONAL); 287 288 PPARTENTRY 289 SelectPartition( 290 IN PPARTLIST List, 291 IN ULONG DiskNumber, 292 IN ULONG PartitionNumber); 293 294 PPARTENTRY 295 GetNextPartition( 296 IN PPARTLIST List, 297 IN PPARTENTRY CurrentPart OPTIONAL); 298 299 PPARTENTRY 300 GetPrevPartition( 301 IN PPARTLIST List, 302 IN PPARTENTRY CurrentPart OPTIONAL); 303 304 ERROR_NUMBER 305 PartitionCreationChecks( 306 _In_ PPARTENTRY PartEntry); 307 308 ERROR_NUMBER 309 ExtendedPartitionCreationChecks( 310 _In_ PPARTENTRY PartEntry); 311 312 BOOLEAN 313 CreatePartition( 314 _In_ PPARTLIST List, 315 _Inout_ PPARTENTRY PartEntry, 316 _In_opt_ ULONGLONG SizeBytes); 317 318 BOOLEAN 319 CreateExtendedPartition( 320 _In_ PPARTLIST List, 321 _Inout_ PPARTENTRY PartEntry, 322 _In_opt_ ULONGLONG SizeBytes); 323 324 NTSTATUS 325 DismountVolume( 326 IN PPARTENTRY PartEntry); 327 328 BOOLEAN 329 DeletePartition( 330 IN PPARTLIST List, 331 IN PPARTENTRY PartEntry, 332 OUT PPARTENTRY* FreeRegion OPTIONAL); 333 334 PPARTENTRY 335 FindSupportedSystemPartition( 336 IN PPARTLIST List, 337 IN BOOLEAN ForceSelect, 338 IN PDISKENTRY AlternativeDisk OPTIONAL, 339 IN PPARTENTRY AlternativePart OPTIONAL); 340 341 BOOLEAN 342 SetActivePartition( 343 IN PPARTLIST List, 344 IN PPARTENTRY PartEntry, 345 IN PPARTENTRY OldActivePart OPTIONAL); 346 347 NTSTATUS 348 WritePartitions( 349 IN PDISKENTRY DiskEntry); 350 351 BOOLEAN 352 WritePartitionsToDisk( 353 IN PPARTLIST List); 354 355 BOOLEAN 356 SetMountedDeviceValue( 357 IN WCHAR Letter, 358 IN ULONG Signature, 359 IN LARGE_INTEGER StartingOffset); 360 361 BOOLEAN 362 SetMountedDeviceValues( 363 IN PPARTLIST List); 364 365 VOID 366 SetMBRPartitionType( 367 IN PPARTENTRY PartEntry, 368 IN UCHAR PartitionType); 369 370 BOOLEAN 371 GetNextUnformattedPartition( 372 IN PPARTLIST List, 373 OUT PDISKENTRY *pDiskEntry OPTIONAL, 374 OUT PPARTENTRY *pPartEntry); 375 376 BOOLEAN 377 GetNextUncheckedPartition( 378 IN PPARTLIST List, 379 OUT PDISKENTRY *pDiskEntry OPTIONAL, 380 OUT PPARTENTRY *pPartEntry); 381 382 /* EOF */ 383