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.

995 lines
28 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. sppartit.h
  5. Abstract:
  6. Public header file for partitioning module in text setup.
  7. Author:
  8. Ted Miller (tedm) 27-Aug-1993
  9. Revision History:
  10. --*/
  11. #ifndef _SPPARTIT_
  12. #define _SPPARTIT_
  13. //
  14. // Number of entries in a partition table.
  15. //
  16. #define NUM_PARTITION_TABLE_ENTRIES_NEC98 16
  17. //#if (NUM_PARTITION_TABLE_ENTRIES < NUM_PARTITION_TABLE_ENTRIES_NEC98)
  18. #if defined(NEC_98) //NEC98
  19. #define PTABLE_DIMENSION NUM_PARTITION_TABLE_ENTRIES_NEC98
  20. # else //NEC98
  21. #define PTABLE_DIMENSION NUM_PARTITION_TABLE_ENTRIES
  22. # endif //NEC98
  23. //
  24. // The following table contains offsets from SP_TEXT_PARTITION_NAME_BASE
  25. // to get the message id of the name of each type of partition.
  26. //
  27. extern UCHAR PartitionNameIds[256];
  28. //
  29. // Original ordinal is the ordinal the partition had when we started.
  30. // OnDisk ordinal is the ordinal the partition will have when the system
  31. // is rebooted.
  32. // Current ordinal is the ordinal the partition has now, if we want to
  33. // address it. This may be different then OnDisk ordinal because of
  34. // how dynamic repartitioning is implemented.
  35. //
  36. typedef enum {
  37. PartitionOrdinalOriginal,
  38. PartitionOrdinalOnDisk,
  39. PartitionOrdinalCurrent
  40. } PartitionOrdinalType;
  41. //
  42. // Define structure for an on-disk partition table entry.
  43. //
  44. typedef struct _REAL_DISK_PTE_NEC98 {
  45. UCHAR ActiveFlag;
  46. UCHAR SystemId;
  47. UCHAR Reserved[2];
  48. UCHAR IPLSector;
  49. UCHAR IPLHead;
  50. UCHAR IPLCylinderLow;
  51. UCHAR IPLCylinderHigh;
  52. UCHAR StartSector;
  53. UCHAR StartHead;
  54. UCHAR StartCylinderLow;
  55. UCHAR StartCylinderHigh;
  56. UCHAR EndSector;
  57. UCHAR EndHead;
  58. UCHAR EndCylinderLow;
  59. UCHAR EndCylinderHigh;
  60. UCHAR SystemName[16];
  61. } REAL_DISK_PTE_NEC98, *PREAL_DISK_PTE_NEC98;
  62. typedef struct _REAL_DISK_PTE {
  63. UCHAR ActiveFlag;
  64. UCHAR StartHead;
  65. UCHAR StartSector;
  66. UCHAR StartCylinder;
  67. UCHAR SystemId;
  68. UCHAR EndHead;
  69. UCHAR EndSector;
  70. UCHAR EndCylinder;
  71. UCHAR RelativeSectors[4];
  72. UCHAR SectorCount[4];
  73. } REAL_DISK_PTE, *PREAL_DISK_PTE;
  74. typedef struct _ON_DISK_PTE {
  75. UCHAR ActiveFlag;
  76. UCHAR StartHead;
  77. UCHAR StartSector;
  78. UCHAR StartCylinder;
  79. UCHAR SystemId;
  80. UCHAR EndHead;
  81. UCHAR EndSector;
  82. UCHAR EndCylinder;
  83. UCHAR RelativeSectors[4];
  84. UCHAR SectorCount[4];
  85. #if defined(NEC_98) //NEC98
  86. //
  87. // add following entry for NEC98
  88. //
  89. UCHAR StartCylinderLow; // add NEC98 original value
  90. UCHAR StartCylinderHigh; // not convert int13 format
  91. UCHAR EndCylinderLow; // add NEC98 original value
  92. UCHAR EndCylinderHigh; // not convert int13 format
  93. UCHAR IPLSector; // add NEC98 original value
  94. UCHAR IPLHead; //
  95. UCHAR IPLCylinderLow; //
  96. UCHAR IPLCylinderHigh; //
  97. UCHAR IPLSectors[4]; // for PC-PTOS
  98. UCHAR Reserved[2]; //
  99. UCHAR SystemName[16]; //
  100. UCHAR OldSystemId; // reverse conversion for Sleep partition
  101. UCHAR RealDiskPosition; // for Dynamic Partitioning on NEC98
  102. #endif //NEC98
  103. } ON_DISK_PTE, *PON_DISK_PTE;
  104. //
  105. // Define structure for an REAL on-disk master boot record.
  106. //
  107. typedef struct _REAL_DISK_MBR_NEC98 {
  108. UCHAR JumpCode[4];
  109. UCHAR IPLSignature[4];
  110. UCHAR BootCode[502];
  111. UCHAR AA55Signature[2];
  112. //REAL_DISK_PTE_NEC98 PartitionTable[NUM_PARTITION_TABLE_ENTRIES_NEC98];
  113. REAL_DISK_PTE_NEC98 PartitionTable[16];
  114. } REAL_DISK_MBR_NEC98, *PREAL_DISK_MBR_NEC98;
  115. //
  116. // Define structure for an REAL on-disk master boot record.
  117. //
  118. typedef struct _REAL_DISK_MBR {
  119. UCHAR BootCode[440];
  120. UCHAR NTFTSignature[4];
  121. UCHAR Filler[2];
  122. REAL_DISK_PTE PartitionTable[NUM_PARTITION_TABLE_ENTRIES];
  123. UCHAR AA55Signature[2];
  124. } REAL_DISK_MBR, *PREAL_DISK_MBR;
  125. //
  126. // Define structure for an DUMMY on-disk master boot record.
  127. //
  128. typedef struct _ON_DISK_MBR {
  129. UCHAR BootCode[440];
  130. UCHAR NTFTSignature[4];
  131. UCHAR Filler[2];
  132. ON_DISK_PTE PartitionTable[PTABLE_DIMENSION];
  133. UCHAR AA55Signature[2];
  134. } ON_DISK_MBR, *PON_DISK_MBR;
  135. typedef struct _MBR_INFO {
  136. struct _MBR_INFO *Next;
  137. ON_DISK_MBR OnDiskMbr;
  138. BOOLEAN Dirty[PTABLE_DIMENSION];
  139. BOOLEAN ZapBootSector[PTABLE_DIMENSION];
  140. USHORT OriginalOrdinals[PTABLE_DIMENSION];
  141. USHORT OnDiskOrdinals[PTABLE_DIMENSION];
  142. USHORT CurrentOrdinals[PTABLE_DIMENSION];
  143. //
  144. // Fields that can be used locally for any purpose.
  145. //
  146. PVOID UserData[PTABLE_DIMENSION];
  147. ULONGLONG OnDiskSector;
  148. } MBR_INFO, *PMBR_INFO;
  149. typedef enum {
  150. EPTNone = 0,
  151. EPTContainerPartition,
  152. EPTLogicalDrive
  153. } EXTENDED_PARTITION_TYPE;
  154. //
  155. // Define structure that is used to track partitions and
  156. // free (unpartitioned) spaces.
  157. //
  158. typedef struct _DISK_REGION {
  159. struct _DISK_REGION *Next;
  160. ULONG DiskNumber;
  161. ULONGLONG StartSector;
  162. ULONGLONG SectorCount;
  163. BOOLEAN PartitionedSpace;
  164. ULONG PartitionNumber;
  165. //
  166. // The following fields are used only if PartitionedSpace is TRUE.
  167. //
  168. PMBR_INFO MbrInfo;
  169. ULONG TablePosition;
  170. BOOLEAN IsSystemPartition;
  171. BOOLEAN IsLocalSource;
  172. FilesystemType Filesystem;
  173. WCHAR TypeName[128]; // XENIX, FAT, NTFS, etc.
  174. ULONGLONG FreeSpaceKB; // -1 if can't determine.
  175. ULONG BytesPerCluster; // Number of bytes per cluster
  176. // (-1 if can't determine).
  177. ULONGLONG AdjustedFreeSpaceKB; // -1 if can't determine.
  178. // if the region contains the Local Source
  179. // then this field should contain
  180. // FreeSpaceKB + LocalSourceSize
  181. WCHAR VolumeLabel[20]; // First few chars of volume label
  182. WCHAR DriveLetter; // Always uppercase; 0 if none.
  183. BOOLEAN FtPartition;
  184. BOOLEAN DynamicVolume;
  185. BOOLEAN DynamicVolumeSuitableForOS;
  186. EXTENDED_PARTITION_TYPE ExtendedType;
  187. struct _DISK_REGION *Container;
  188. BOOLEAN Dirty;
  189. BOOLEAN Delete;
  190. PARTITION_INFORMATION_EX PartInfo;
  191. BOOLEAN PartInfoDirty;
  192. BOOLEAN IsReserved;
  193. //
  194. // The following fields are used to identify double space drives
  195. // They are valid only if the file system type is FilesystemFat
  196. // or FilesystemDoubleSpace
  197. //
  198. // If the file system type is FilesystemFat and NextCompressed is not NULL,
  199. // then the structure describes the host drive for compressed drives.
  200. // In this case, the following fields are valid:
  201. //
  202. // NextCompressed .... Points to a linked list of compressed drives
  203. // HostDrive.......... Contains the drive letter for the drive represented
  204. // by this structure. Note that HostDrive will be
  205. // not necessarily be equal to DriveLetter
  206. //
  207. // If the file system type is FilesystemDoubleSpace, then the structure
  208. // describes a compressed drive.
  209. // In this case the following fields are valid:
  210. //
  211. // NextCompressed ..... Points to the next compressed drive in the
  212. // linked list
  213. // PreviousCompressed.. Points to the previous compressed drive in
  214. // the linked list
  215. // HostRegion ......... Points to the structure that describes the
  216. // host drive for the compressed drive represented
  217. // by this structure
  218. // MountDrive ......... Drive letter of the drive described by this
  219. // structure (should be the same as HostRegion->HostDrive)
  220. // HostDrive .......... Drive where the CVF file that represents the
  221. // this compressed drive is located.
  222. // SeqNumber .......... Sequence number of the CVF file that representd
  223. // this compressed drive.
  224. //
  225. struct _DISK_REGION *NextCompressed;
  226. struct _DISK_REGION *PreviousCompressed;
  227. struct _DISK_REGION *HostRegion;
  228. WCHAR MountDrive;
  229. WCHAR HostDrive;
  230. USHORT SeqNumber;
  231. } DISK_REGION, *PDISK_REGION;
  232. //
  233. // There will be one of these structures per disk.
  234. //
  235. typedef struct _PARTITIONED_DISK {
  236. PHARD_DISK HardDisk;
  237. //
  238. //
  239. //
  240. BOOLEAN MbrWasValid;
  241. //
  242. // We can just store the MBR here since there is only one of them.
  243. //
  244. MBR_INFO MbrInfo;
  245. //
  246. // EBRs are stored in a linked list since there are an arbitrary number
  247. // of them. The one contained within this structure is a dummy and is
  248. // always zeroed out.
  249. //
  250. MBR_INFO FirstEbrInfo;
  251. //
  252. // Lists of regions (partitions and free spaces)
  253. // on the disk and within the extended partition.
  254. //
  255. PDISK_REGION PrimaryDiskRegions;
  256. PDISK_REGION ExtendedDiskRegions;
  257. } PARTITIONED_DISK, *PPARTITIONED_DISK;
  258. extern PPARTITIONED_DISK PartitionedDisks;
  259. //
  260. // Disk region containing the local source directory
  261. // in the winnt.exe setup case.
  262. //
  263. // If WinntSetup is TRUE, then this should be non-null.
  264. // If it is not non-null, then we couldn't locate the local source.
  265. //
  266. extern PDISK_REGION LocalSourceRegion;
  267. //
  268. // GPT partition type strings
  269. //
  270. #define PARTITION_MSFT_RESERVED_STR L"Microsoft reserved partition"
  271. #define PARTITION_LDM_METADATA_STR L"LDM metadata partition"
  272. #define PARTITION_LDM_DATA_STR L"LDM data partition"
  273. #define PARTITION_BASIC_DATA_STR L"Basic data partition"
  274. #define PARTITION_SYSTEM_STR L"EFI system partition"
  275. #if defined(REMOTE_BOOT)
  276. //
  277. // For remote boot, we create a fake disk region for the net(0) device.
  278. //
  279. extern PDISK_REGION RemoteBootTargetRegion;
  280. #endif // defined(REMOTE_BOOT)
  281. NTSTATUS
  282. SpPtInitialize(
  283. VOID
  284. );
  285. BOOLEAN
  286. SpPtDelete(
  287. IN ULONG DiskNumber,
  288. IN ULONGLONG StartSector
  289. );
  290. BOOLEAN
  291. SpPtCreate(
  292. IN ULONG DiskNumber,
  293. IN ULONGLONG StartSector,
  294. IN ULONGLONG SizeMB,
  295. IN BOOLEAN InExtended,
  296. IN PPARTITION_INFORMATION_EX PartInfo,
  297. OUT PDISK_REGION *ActualDiskRegion OPTIONAL
  298. );
  299. BOOLEAN
  300. SpPtExtend(
  301. IN PDISK_REGION Region,
  302. IN ULONGLONG SizeMB OPTIONAL
  303. );
  304. VOID
  305. SpPtQueryMinMaxCreationSizeMB(
  306. IN ULONG DiskNumber,
  307. IN ULONGLONG StartSector,
  308. IN BOOLEAN ForExtended,
  309. IN BOOLEAN InExtended,
  310. OUT PULONGLONG MinSize,
  311. OUT PULONGLONG MaxSize,
  312. OUT PBOOLEAN ReservedRegion
  313. );
  314. VOID
  315. SpPtGetSectorLayoutInformation(
  316. IN PDISK_REGION Region,
  317. OUT PULONGLONG HiddenSectors,
  318. OUT PULONGLONG VolumeSectorCount
  319. );
  320. NTSTATUS
  321. SpPtPrepareDisks(
  322. IN PVOID SifHandle,
  323. OUT PDISK_REGION *InstallRegion,
  324. OUT PDISK_REGION *SystemPartitionRegion,
  325. IN PWSTR SetupSourceDevicePath,
  326. IN PWSTR DirectoryOnSetupSource,
  327. IN BOOLEAN RemoteBootRepartition
  328. );
  329. PDISK_REGION
  330. SpPtAllocateDiskRegionStructure(
  331. IN ULONG DiskNumber,
  332. IN ULONGLONG StartSector,
  333. IN ULONGLONG SectorCount,
  334. IN BOOLEAN PartitionedSpace,
  335. IN PMBR_INFO MbrInfo,
  336. IN ULONG TablePosition
  337. );
  338. ULONG
  339. SpPtGetOrdinal(
  340. IN PDISK_REGION Region,
  341. IN PartitionOrdinalType OrdinalType
  342. );
  343. ULONGLONG
  344. SpPtSectorCountToMB(
  345. IN PHARD_DISK pHardDisk,
  346. IN ULONGLONG SectorCount
  347. );
  348. typedef BOOL
  349. (*PSPENUMERATEDISKREGIONS)(
  350. IN PPARTITIONED_DISK Disk,
  351. IN PDISK_REGION Region,
  352. IN ULONG_PTR Context
  353. );
  354. void
  355. SpEnumerateDiskRegions(
  356. IN PSPENUMERATEDISKREGIONS EnumRoutine,
  357. IN ULONG_PTR Context
  358. );
  359. BOOLEAN
  360. SpPtRegionDescription(
  361. IN PPARTITIONED_DISK pDisk,
  362. IN PDISK_REGION pRegion,
  363. OUT PWCHAR Buffer,
  364. IN ULONG BufferSize
  365. );
  366. PDISK_REGION
  367. SpPtLookupRegionByStart(
  368. IN PPARTITIONED_DISK pDisk,
  369. IN BOOLEAN ExtendedPartition,
  370. IN ULONGLONG StartSector
  371. );
  372. ULONG
  373. SpPtAlignStart(
  374. IN PHARD_DISK pHardDisk,
  375. IN ULONGLONG StartSector,
  376. IN BOOLEAN ForExtended
  377. );
  378. VOID
  379. SpPtInitializeCHSFields(
  380. IN PHARD_DISK HardDisk,
  381. IN ULONGLONG AbsoluteStartSector,
  382. IN ULONGLONG AbsoluteSectorCount,
  383. OUT PON_DISK_PTE pte
  384. );
  385. VOID
  386. SpPtAssignOrdinals(
  387. IN PPARTITIONED_DISK pDisk,
  388. IN BOOLEAN InitCurrentOrdinals,
  389. IN BOOLEAN InitOnDiskOrdinals,
  390. IN BOOLEAN InitOriginalOrdinals
  391. );
  392. ULONG
  393. SpGetMaxNtDirLen(VOID);
  394. VOID
  395. SpPtLocateSystemPartitions(VOID);
  396. VOID
  397. SpPtCountPrimaryPartitions(
  398. IN PPARTITIONED_DISK pDisk,
  399. OUT PULONG TotalPrimaryPartitionCount,
  400. OUT PULONG RecognizedPrimaryPartitionCount,
  401. OUT PBOOLEAN ExtendedExists);
  402. PDISK_REGION
  403. SpRegionFromNtName(
  404. IN PWSTR NtDeviceName,
  405. IN PartitionOrdinalType Type);
  406. VOID
  407. SppRepairWinntFiles(
  408. IN PVOID LogFileHandle,
  409. IN PVOID MasterSifHandle,
  410. IN PWSTR SourceDevicePath,
  411. IN PWSTR DirectoryOnSourceDevice,
  412. IN PWSTR SystemPartition,
  413. IN PWSTR SystemPartitionDirectory,
  414. IN PWSTR WinntPartition,
  415. IN PWSTR WinntPartitionDirectory);
  416. VOID
  417. SppRepairStartMenuGroupsAndItems(
  418. IN PWSTR WinntPartition,
  419. IN PWSTR WinntDirectory);
  420. VOID
  421. SppRepairHives(
  422. PVOID MasterSifHandle,
  423. PWSTR WinntPartition,
  424. PWSTR WinntPartitionDirectory,
  425. PWSTR SourceDevicePath,
  426. PWSTR DirectoryOnSourceDevice);
  427. NTSTATUS
  428. SpDoFormat(
  429. IN PWSTR RegionDescr,
  430. IN PDISK_REGION Region,
  431. IN ULONG FilesystemType,
  432. IN BOOLEAN IsFailureFatal,
  433. IN BOOLEAN CheckFatSize,
  434. IN BOOLEAN QuickFormat,
  435. IN PVOID SifHandle,
  436. IN DWORD ClusterSize,
  437. IN PWSTR SetupSourceDevicePath,
  438. IN PWSTR DirectoryOnSetupSource
  439. );
  440. NTSTATUS
  441. SpPtPartitionDiskForRemoteBoot(
  442. IN ULONG DiskNumber,
  443. OUT PDISK_REGION *RemainingRegion
  444. );
  445. VOID
  446. SpPtDeleteBootSetsForRegion(
  447. PDISK_REGION region
  448. );
  449. VOID
  450. SpPtDeletePartitionsForRemoteBoot(
  451. PPARTITIONED_DISK pDisk,
  452. PDISK_REGION startRegion,
  453. PDISK_REGION endRegion,
  454. BOOLEAN Extended
  455. );
  456. WCHAR
  457. SpGetDriveLetter(
  458. IN PWSTR DeviceName,
  459. OUT PMOUNTMGR_MOUNT_POINT * MountPoint OPTIONAL
  460. );
  461. WCHAR
  462. SpDeleteDriveLetter(
  463. IN PWSTR DeviceName
  464. );
  465. VOID
  466. SpPtDeleteDriveLetters(
  467. VOID
  468. );
  469. BOOL
  470. SpPtIsSystemPartitionRecognizable(
  471. VOID
  472. );
  473. VOID
  474. SpPtDetermineRegionSpace(
  475. IN PDISK_REGION pRegion
  476. );
  477. VOID
  478. SpCreateNewGuid(
  479. IN GUID *Guid
  480. );
  481. UCHAR
  482. SpPtGetPartitionType(
  483. IN PDISK_REGION Region
  484. );
  485. BOOLEAN
  486. SpPtnIsRawDiskDriveLayout(
  487. IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout
  488. );
  489. BOOLEAN
  490. SpPtnIsRegionSpecialMBRPartition(
  491. IN PDISK_REGION Region
  492. );
  493. extern ULONG RandomSeed;
  494. extern BOOLEAN ValidArcSystemPartition;
  495. //
  496. // Only on IA64 by default the RAW disk is marked as GPT disk
  497. //
  498. #if defined(_IA64_)
  499. #define SPPT_DEFAULT_PARTITION_STYLE PARTITION_STYLE_GPT
  500. #define SPPT_DEFAULT_DISK_STYLE DISK_FORMAT_TYPE_GPT
  501. #else
  502. #define SPPT_DEFAULT_PARTITION_STYLE PARTITION_STYLE_MBR
  503. #define SPPT_DEFAULT_DISK_STYLE DISK_FORMAT_TYPE_PCAT
  504. #endif
  505. #define SPPT_MINIMUM_ESP_SIZE_MB 100
  506. #define SPPT_MAXIMUM_ESP_SIZE_MB 1000
  507. //
  508. //
  509. // Various Disk, Partition, Region related Macros
  510. //
  511. // NB. These are used, because it makes code more readable and
  512. // in future these macros can represent potential interface for
  513. // accessing the opaque in memory partition structure
  514. //
  515. //
  516. #define SPPT_GET_NEW_DISK_SIGNATURE() RtlRandom(&RandomSeed)
  517. #define SPPT_DISK_CYLINDER_COUNT(_DiskId) (HardDisks[(_DiskId)].CylinderCount)
  518. #define SPPT_DISK_TRACKS_PER_CYLINDER(_DiskId) (HardDisks[(_DiskId)].Geometry.TracksPerCylinder)
  519. #define SPPT_DISK_CYLINDER_SIZE(_DiskId) (HardDisks[(_DiskId)].SectorsPerCylinder)
  520. #define SPPT_DISK_TRACK_SIZE(_DiskId) (HardDisks[(_DiskId)].Geometry.SectorsPerTrack)
  521. #define SPPT_DISK_SECTOR_SIZE(_DiskId) (HardDisks[(_DiskId)].Geometry.BytesPerSector)
  522. #define SPPT_DISK_IS_REMOVABLE(_DiskId) (HardDisks[(_DiskId)].Characteristics & FILE_REMOVABLE_MEDIA)
  523. #define SPPT_REGION_SECTOR_SIZE(_Region) (SPPT_DISK_SECTOR_SIZE((_Region)->DiskNumber))
  524. #define SPPT_DISK_SIZE(_DiskId) \
  525. (SPPT_DISK_SECTOR_SIZE((_DiskId)) * \
  526. HardDisks[(_DiskId)].DiskSizeSectors)
  527. #define SPPT_DISK_SIZE_KB(_DiskId) (SPPT_DISK_SIZE((_DiskId)) / 1024)
  528. #define SPPT_DISK_SIZE_MB(_DiskId) (SPPT_DISK_SIZE_KB((_DiskId)) / 1024)
  529. #define SPPT_DISK_SIZE_GB(_DiskId) (SPPT_DISK_SIZE_MB((_DiskId)) / 1024)
  530. #define SPPT_REGION_FREESPACE(_Region) \
  531. ((_Region)->SectorCount * SPPT_REGION_SECTOR_SIZE((_Region)))
  532. #define SPPT_REGION_FREESPACE_KB(_Region) (SPPT_REGION_FREESPACE((_Region)) / 1024)
  533. #define SPPT_REGION_FREESPACE_MB(_Region) (SPPT_REGION_FREESPACE_KB((_Region)) / 1024)
  534. #define SPPT_REGION_FREESPACE_GB(_Region) (SPPT_REGION_FREESPACE_MB((_Region)) / 1024)
  535. #define SPPT_IS_REGION_PARTITIONED(_Region) \
  536. ((_Region)->PartitionedSpace)
  537. #define SPPT_IS_REGION_FREESPACE(_Region) \
  538. (((_Region)->PartitionedSpace == FALSE) && \
  539. ((_Region)->ExtendedType == EPTNone))
  540. #define SPPT_SET_REGION_PARTITIONED(_Region, _Type) \
  541. ((_Region)->PartitionedSpace = (_Type))
  542. #define SPPT_IS_REGION_DIRTY(_Region) ((_Region)->Dirty)
  543. #define SPPT_SET_REGION_DIRTY(_Region, _Type) ((_Region)->Dirty = (_Type))
  544. #define SPPT_GET_PARTITION_TYPE(_Region) ((_Region)->PartInfo.Mbr.PartitionType)
  545. #define SPPT_SET_PARTITION_TYPE(_Region, _Type) \
  546. ((_Region)->PartInfo.Mbr.PartitionType = (_Type))
  547. #define SPPT_IS_VALID_PRIMARY_PARTITION_TYPE(_TypeId) \
  548. (IsRecognizedPartition((_TypeId)) && !IsFTPartition((_TypeId)))
  549. #define SPPT_IS_REGION_SYSTEMPARTITION(_Region) \
  550. (SPPT_IS_REGION_PARTITIONED(_Region) && ((_Region)->IsSystemPartition))
  551. #define SPPT_GET_PRIMARY_DISK_REGION(_HardDisk) \
  552. (PartitionedDisks[(_HardDisk)].PrimaryDiskRegions)
  553. #define SPPT_GET_EXTENDED_DISK_REGION(_HardDisk) \
  554. (PartitionedDisks[(_HardDisk)].ExtendedDiskRegions)
  555. #define SPPT_GET_HARDDISK(_DiskNumber) (HardDisks + (_DiskNumber))
  556. #define SPPT_GET_PARTITIONED_DISK(_DiskNumber) (PartitionedDisks + (_DiskNumber))
  557. #define SPPT_IS_RAW_DISK(_DiskNumber) \
  558. (HardDisks[(_DiskNumber)].FormatType == DISK_FORMAT_TYPE_RAW)
  559. #define SPPT_IS_GPT_DISK(_DiskNumber) \
  560. (HardDisks[(_DiskNumber)].FormatType == DISK_FORMAT_TYPE_GPT)
  561. #define SPPT_GET_DISK_TYPE(_DiskNumber) (HardDisks[(_DiskNumber)].FormatType)
  562. #define SPPT_IS_MBR_DISK(_DiskNumber) \
  563. (!SPPT_IS_GPT_DISK(_DiskNumber))
  564. #define SPPT_IS_REMOVABLE_DISK(_DiskNumber) \
  565. (SPPT_GET_HARDDISK(_DiskNumber)->Geometry.MediaType == RemovableMedia)
  566. #define SPPT_IS_REGION_EFI_SYSTEM_PARTITION(_Region) \
  567. (SPPT_IS_GPT_DISK((_Region)->DiskNumber) && \
  568. (RtlEqualMemory(&((_Region)->PartInfo.Gpt.PartitionType), \
  569. &PARTITION_SYSTEM_GUID, \
  570. sizeof(GUID))))
  571. #define SPPT_IS_EFI_SYSTEM_PARTITION(_PartInfo) \
  572. (((_PartInfo)->PartitionStyle == PARTITION_STYLE_GPT) && \
  573. (RtlEqualMemory(&((_PartInfo)->Gpt.PartitionType), \
  574. &PARTITION_SYSTEM_GUID, \
  575. sizeof(GUID))))
  576. #define SPPT_IS_REGION_RESERVED_PARTITION(_Region) \
  577. (SPPT_IS_REGION_PARTITIONED(_Region) && ((_Region)->IsReserved))
  578. #define SPPT_IS_REGION_MSFT_RESERVED(_Region) \
  579. (SPPT_IS_GPT_DISK((_Region)->DiskNumber) && \
  580. (RtlEqualMemory(&((_Region)->PartInfo.Gpt.PartitionType), \
  581. &PARTITION_MSFT_RESERVED_GUID, \
  582. sizeof(GUID))))
  583. #define SPPT_IS_PARTITION_MSFT_RESERVED(_PartInfo) \
  584. (((_PartInfo)->PartitionStyle == PARTITION_STYLE_GPT) && \
  585. (RtlEqualMemory(&((_PartInfo)->Gpt.PartitionType), \
  586. &PARTITION_MSFT_RESERVED_GUID, \
  587. sizeof(GUID))))
  588. #define SPPT_PARTITION_NEEDS_NUMBER(_PartInfo) \
  589. ((((_PartInfo)->PartitionNumber == 0) && \
  590. ((_PartInfo)->PartitionLength.QuadPart != 0)) && \
  591. (((_PartInfo)->PartitionStyle == PARTITION_STYLE_GPT) ? \
  592. (SPPT_IS_PARTITION_MSFT_RESERVED((_PartInfo))) : \
  593. ((IsContainerPartition((_PartInfo)->Mbr.PartitionType) == FALSE))))
  594. #define SPPT_IS_BLANK_DISK(_DiskId) (SPPT_GET_HARDDISK((_DiskId))->NewDisk)
  595. #define SPPT_SET_DISK_BLANK(_DiskId, _Blank) \
  596. (SPPT_GET_HARDDISK((_DiskId))->NewDisk = (_Blank))
  597. #define SPPT_IS_REGION_LOGICAL_DRIVE(_Region) \
  598. (SPPT_IS_MBR_DISK((_Region)->DiskNumber) && \
  599. ((_Region)->ExtendedType == EPTLogicalDrive))
  600. #define SPPT_IS_REGION_CONTAINER_PARTITION(_Region) \
  601. (SPPT_IS_MBR_DISK((_Region)->DiskNumber) && \
  602. ((_Region)->ExtendedType == EPTContainerPartition) && \
  603. IsContainerPartition((_Region)->PartInfo.Mbr.PartitionType))
  604. #define SPPT_IS_REGION_FIRST_CONTAINER_PARTITION(_Region) \
  605. (SPPT_IS_REGION_CONTAINER_PARTITION((_Region)) && \
  606. ((_Region)->Container == NULL))
  607. #define SPPT_IS_REGION_INSIDE_CONTAINER(_Region) ((_Region)->Container != NULL)
  608. #define SPPT_IS_REGION_INSIDE_FIRST_CONTAINER(_Region) \
  609. (((_Region)->Container != NULL) && ((_Region)->Container->Container == NULL))
  610. #define SPPT_IS_REGION_NEXT_TO_FIRST_CONTAINER(_Region) \
  611. ((_Region)->Container && \
  612. SPPT_IS_REGION_FIRST_CONTAINER_PARTITION((_Region)->Container) && \
  613. ((_Region)->Container->Next == (_Region)))
  614. #define SPPT_IS_REGION_PRIMARY_PARTITION(_Region) \
  615. (SPPT_IS_MBR_DISK((_Region)->DiskNumber) && \
  616. SPPT_IS_REGION_PARTITIONED((_Region)) && \
  617. ((_Region)->ExtendedType == EPTNone))
  618. #define SPPT_SET_REGION_EPT(_Region, _Type) \
  619. ((_Region)->ExtendedType = (_Type))
  620. #define SPPT_IS_REGION_ACTIVE_PARTITION(_Region) \
  621. (SPPT_IS_REGION_PRIMARY_PARTITION((_Region)) && \
  622. ((_Region)->PartInfo.Mbr.BootIndicator))
  623. #define SPPT_GET_REGION_LASTSECTOR(_Region) \
  624. ((_Region)->StartSector + (_Region)->SectorCount)
  625. #define SPPT_IS_REGION_DYNAMIC_VOLUME(_Region) \
  626. ((_Region)->DynamicVolume)
  627. #define SPPT_IS_REGION_LDM_METADATA(_Region) \
  628. (PARTITION_STYLE_GPT == (_Region)->PartInfo.PartitionStyle && \
  629. IsEqualGUID(&PARTITION_LDM_METADATA_GUID, &(_Region)->PartInfo.Gpt.PartitionType))
  630. #define SPPT_IS_REGION_CONTAINED(_Container, _Contained) \
  631. (((_Container)->StartSector <= (_Contained)->StartSector) && \
  632. ((_Container)->SectorCount >= (_Contained)->SectorCount) && \
  633. (SPPT_GET_REGION_LASTSECTOR((_Container)) > \
  634. (_Contained)->StartSector))
  635. #define SPPT_IS_REGION_MARKED_DELETE(_Region) ((_Region)->Delete)
  636. #define SPPT_SET_REGION_DELETED(_Region, _Type) ((_Region)->Delete = (_Type))
  637. #define SPPT_IS_VALID_SYSPART_FILESYSTEM(_FileSys) \
  638. (((_FileSys) == FilesystemFat) || \
  639. ((_FileSys) == FilesystemFat32))
  640. #define SPPT_IS_RECOGNIZED_FILESYSTEM(_FileSys) \
  641. (((_FileSys) == FilesystemFat) || \
  642. ((_FileSys) == FilesystemFat32) || \
  643. ((_FileSys) == FilesystemNtfs))
  644. #define SPPT_IS_REGION_FORMATTED(_Region) \
  645. (SPPT_IS_REGION_PARTITIONED(_Region) && \
  646. SPPT_IS_RECOGNIZED_FILESYSTEM((_Region)->Filesystem))
  647. #define SPPT_IS_NT_UPGRADE() (IsNTUpgrade == UpgradeFull)
  648. #define SPPT_MARK_REGION_AS_SYSTEMPARTITION(_Region, _Value) \
  649. (_Region)->IsSystemPartition = (_Value)
  650. #define SPPT_MARK_REGION_AS_ACTIVE(_Region, _Value) \
  651. (_Region)->PartInfo.Mbr.BootIndicator = (_Value)
  652. __inline
  653. ULONGLONG
  654. SpPtnGetDiskMSRSizeMB(
  655. IN ULONG DiskId
  656. )
  657. {
  658. return (SPPT_DISK_SIZE_GB(DiskId) >= 16) ? 128 : 32;
  659. }
  660. __inline
  661. BOOLEAN
  662. SpPtnIsValidMSRRegion(
  663. IN PDISK_REGION Region
  664. )
  665. {
  666. return (Region && SPPT_IS_REGION_FREESPACE(Region) &&
  667. (SpPtnGetDiskMSRSizeMB(Region->DiskNumber)
  668. <= SPPT_REGION_FREESPACE_MB(Region)));
  669. }
  670. __inline
  671. ULONGLONG
  672. SpPtnGetDiskESPSizeMB(
  673. IN ULONG DiskId
  674. )
  675. {
  676. return (max(SPPT_MINIMUM_ESP_SIZE_MB,
  677. min(SPPT_MAXIMUM_ESP_SIZE_MB,
  678. SPPT_DISK_SIZE_MB(DiskId) / 100)));
  679. }
  680. __inline
  681. BOOLEAN
  682. SpPtnIsValidESPRegionSize(
  683. IN PDISK_REGION Region
  684. )
  685. {
  686. BOOLEAN Result = FALSE;
  687. if (Region) {
  688. ULONGLONG EspSizeMB = SpPtnGetDiskESPSizeMB(Region->DiskNumber);
  689. ULONGLONG EspSizeSectors = (EspSizeMB * 1024 * 1024) / SPPT_DISK_SECTOR_SIZE(Region->DiskNumber);
  690. //
  691. // Align down required ESP size if possible
  692. //
  693. if (EspSizeSectors > SPPT_DISK_CYLINDER_SIZE(Region->DiskNumber)) {
  694. EspSizeSectors -= (EspSizeSectors % SPPT_DISK_CYLINDER_SIZE(Region->DiskNumber));
  695. }
  696. //
  697. // Take into account that the partition may start on the second track of the disk
  698. //
  699. if(EspSizeSectors > SPPT_DISK_TRACK_SIZE(Region->DiskNumber)) {
  700. EspSizeSectors -= SPPT_DISK_TRACK_SIZE(Region->DiskNumber);
  701. }
  702. Result = (EspSizeSectors <= Region->SectorCount);
  703. }
  704. return Result;
  705. }
  706. __inline
  707. BOOLEAN
  708. SpPtnIsValidESPRegion(
  709. IN PDISK_REGION Region
  710. )
  711. {
  712. return (Region && SPPT_IS_GPT_DISK(Region->DiskNumber) &&
  713. SPPT_IS_REGION_FREESPACE(Region) &&
  714. (Region == SPPT_GET_PRIMARY_DISK_REGION(Region->DiskNumber)) &&
  715. SpPtnIsValidESPRegionSize(Region));
  716. }
  717. __inline
  718. BOOLEAN
  719. SpPtnIsValidESPPartition(
  720. IN PDISK_REGION Region
  721. )
  722. {
  723. return (Region && SPPT_IS_GPT_DISK(Region->DiskNumber) &&
  724. SPPT_IS_REGION_PARTITIONED(Region) &&
  725. (Region == SPPT_GET_PRIMARY_DISK_REGION(Region->DiskNumber)) &&
  726. SpPtnIsValidESPRegionSize(Region));
  727. }
  728. __inline
  729. VOID
  730. SpPtnSetRegionPartitionInfo(
  731. IN PDISK_REGION Region,
  732. IN PPARTITION_INFORMATION_EX PartInfo
  733. )
  734. {
  735. if (Region && PartInfo) {
  736. if (SPPT_IS_MBR_DISK(Region->DiskNumber)) {
  737. Region->PartInfo.Mbr.PartitionType = PartInfo->Mbr.PartitionType;
  738. Region->PartInfo.Mbr.BootIndicator = PartInfo->Mbr.BootIndicator;
  739. Region->PartInfoDirty = TRUE;
  740. } else if (SPPT_IS_GPT_DISK(Region->DiskNumber)) {
  741. Region->PartInfo.Gpt = PartInfo->Gpt;
  742. Region->PartInfoDirty = TRUE;
  743. }
  744. }
  745. }
  746. __inline
  747. PWSTR
  748. SpPtnGetPartitionNameFromGUID(
  749. IN GUID *Guid,
  750. OUT PWSTR NameBuffer
  751. )
  752. {
  753. PWSTR Name = NULL;
  754. if (Guid && NameBuffer) {
  755. PWSTR PartitionName = NULL;
  756. if (IsEqualGUID(Guid, &PARTITION_MSFT_RESERVED_GUID)) {
  757. PartitionName = PARTITION_MSFT_RESERVED_STR;
  758. } else if (IsEqualGUID(Guid, &PARTITION_LDM_METADATA_GUID)) {
  759. PartitionName = PARTITION_LDM_METADATA_STR;
  760. } else if (IsEqualGUID(Guid, &PARTITION_LDM_DATA_GUID)) {
  761. PartitionName = PARTITION_LDM_DATA_STR;
  762. } else if (IsEqualGUID(Guid, &PARTITION_BASIC_DATA_GUID)) {
  763. PartitionName = PARTITION_BASIC_DATA_STR;
  764. } else if (IsEqualGUID(Guid, &PARTITION_SYSTEM_GUID)) {
  765. PartitionName = PARTITION_SYSTEM_STR;
  766. }
  767. if (PartitionName) {
  768. PARTITION_INFORMATION_GPT GptPart;
  769. Name = NameBuffer;
  770. wcsncpy(NameBuffer, PartitionName, sizeof(GptPart.Name)/sizeof(WCHAR));
  771. } else {
  772. *NameBuffer = UNICODE_NULL;
  773. }
  774. }
  775. return Name;
  776. }
  777. #endif // ndef _SPPARTIT_