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.

189 lines
6.9 KiB

  1. //
  2. // GPT (GUID Partition Table) declarations.
  3. //
  4. //
  5. // DO WE EVER ALLOW GPT_TABLEs TO NOT BE PACKED UP AGAINST THEIR HEADER?
  6. // IF NOT, DO WE ALLOW PEOPLE TO MAKE ASSUMPTIONS ABOUT THEIR LOCATION?
  7. // DO WE NEED THE POINTER?
  8. //
  9. //
  10. // Rules:
  11. // None of these structures ever appear at LBA 0, because
  12. // we put a "fake" MBR there (the legacy defense MBR).
  13. // Therefore, LBA of 0 is useable as NULL.
  14. //
  15. // For All Entry's, StartingLBA must be >= FirstUsableLBA.
  16. // For All Entry's, EndingLBA must be <= LastUsableLBA.
  17. //
  18. // 0 is not a valid GUID. Therefore, emtpy GPT_ENTRY's will
  19. // have a PartitionType of 0.
  20. // However, if an entry is otherwise valid, but has a PartitionID
  21. // of 0, this means a GUID needs to be generated and placed there.
  22. //
  23. // LBA = Logical Block Address == Sector Number. Always count from 0.
  24. //
  25. // Block size (sector size) could be any number >= sizeof(GPT_ENTRY)
  26. // AND >= sizeof(GPT_HEADER). In practice, always >= 512 bytes.
  27. //
  28. // A block, B, is free for allocation to a partition if and only if
  29. // it is in the range FirstUsableLBA <= B <= LastUsableLBA AND it
  30. // is not already allocated to some other parition.
  31. //
  32. // GPT partitions are always contiguous arrays of blocks. however,
  33. // they need NOT be packed on the disk, their order in the GPT need
  34. // NOT match their order on the disk, there may be blank entries
  35. // in the GPT table, etc. Building an accurate view of the parititon
  36. // *requires* reading the entire GPT_TABLE into memory. In practice,
  37. // it will always be small enough for this to be easy.
  38. //
  39. #pragma pack (4)
  40. //
  41. // Each partition is described by a GPT_ENTRY.
  42. //
  43. #define PART_NAME_LEN 36
  44. typedef struct {
  45. EFI_GUID PartitionType; // declartion of this partition's type
  46. EFI_GUID PartitionID; // Unique ID for this particular partition
  47. // (unique to this instance)
  48. EFI_LBA StartingLBA; // 0 based block (sector) address of the
  49. // first block included in the partition.
  50. EFI_LBA EndingLBA; // 0 based block (sector) address of the
  51. // last block included in the partition.
  52. // If StartingLBA == EndingLBA then the
  53. // partition is 1 block long. this is legal.
  54. UINT64 Attributes; // Always ZERO for now
  55. CHAR16 PartitionName[PART_NAME_LEN]; // 36 unicode characters of name
  56. } GPT_ENTRY, *PGPT_ENTRY;
  57. C_ASSERT (sizeof (GPT_ENTRY) == 128);
  58. //
  59. // All of the GPT_ENTRY's are gathered into a GPT_TABLE, which
  60. // is stored as a linear array of blocks on the disk.
  61. //
  62. typedef struct {
  63. GPT_ENTRY Entry[1]; // Always an integer number of Entry's
  64. // per sector. Always at least 1 sector.
  65. // Can be any number of sectors...
  66. } GPT_TABLE, *PGPT_TABLE;
  67. //
  68. // A main and a backup header each describe the disk, and each points
  69. // to it's own copy of the GPT_TABLE...
  70. //
  71. typedef struct {
  72. UINT64 Signature; // GPT PART
  73. UINT32 Revision;
  74. UINT32 HeaderSize;
  75. UINT32 HeaderCRC32; // computed using 0 for own init value
  76. UINT32 Reserved0;
  77. EFI_LBA MyLBA; // 0 based sector number of the first
  78. // sector of this structure
  79. EFI_LBA AlternateLBA; // 0 based sector (block) number of the
  80. // first sector of the secondary
  81. // GPT_HEADER, or 0 if this is the
  82. // secondary.
  83. EFI_LBA FirstUsableLBA; // 0 based sector number of the first
  84. // sector that may be included in a partition.
  85. EFI_LBA LastUsableLBA; // last legal LBA, inclusive.
  86. EFI_GUID DiskGUID; // The unique ID of this LUN/spindle/disk
  87. EFI_LBA TableLBA; // The start of the table of entries...
  88. UINT32 EntriesAllocated; // Number of entries in the table, this is
  89. // how many allocated, NOT how many used.
  90. UINT32 SizeOfGPT_ENTRY; // sizeof(GPT_ENTRY) always mult. of 8
  91. UINT32 TableCRC32; // CRC32 of the table.
  92. // Reserved and zeros to the end of the block
  93. // Don't declare an array or sizeof() gives a nonsense answer..
  94. } GPT_HEADER, *PGPT_HEADER;
  95. C_ASSERT (sizeof (GPT_HEADER) == 92);
  96. #define GPT_HEADER_SIGNATURE 0x5452415020494645
  97. #define GPT_REVISION_1_0 0x00010000
  98. #define ENTRY_DEFAULT 128
  99. //#define ENTRY_DEFAULT 8 // TESTING ONLY
  100. #define ENTRY_SANITY_LIMIT 1024
  101. //
  102. // GPT Disk Layout
  103. //
  104. /*
  105. +---------------------------------------------------+
  106. LBA=0 | "Fake" MBR to ward off legacy parition apps |
  107. +---------------------------------------------------+
  108. LBA=1 | Primary GPT_HEADER |
  109. +---------------------------------------------------+
  110. LBA=2 | Primary GPT_TABLE starts |
  111. ... ... ...
  112. LBA=n | Primary GPT_TABLE ends |
  113. +---------------------------------------------------+
  114. LBA=n+1 | FirstUsableLBA = this block |
  115. ... ... ...
  116. LBA=x | LastUsableLBA = this block |
  117. +---------------------------------------------------+
  118. LBA=x+1 | Secondary GPT_TABLE starts |
  119. ... ... ...
  120. LBA=z | Secondary GPT_TABLE ends |
  121. +---------------------------------------------------+
  122. LBA=z+n | Secondary GPT_HEADER starts |
  123. ... ... ...
  124. LAST | Secondary GPT_HEADER ends at last sector of disk |
  125. +---------------------------------------------------+
  126. SO:
  127. Primary GPT_HEADER is always at LBA=1
  128. Secondary GPT_HEADER is at LBA=Last so long as GPT_HEADER fits
  129. in 1 sector, which we require.
  130. Primary Table is stacked up after the primary header,
  131. which points to it anyway.
  132. Secondary Table is stacked up before the secondary header,
  133. which points to it anyway.
  134. */
  135. //
  136. // ------------------ Functions To Manipulate GPT ---------------
  137. //
  138. typedef struct _LBA_BLOCK {
  139. EFI_LBA Header1_LBA;
  140. EFI_LBA Table1_LBA;
  141. EFI_LBA Header2_LBA;
  142. EFI_LBA Table2_LBA;
  143. } LBA_BLOCK, *PLBA_BLOCK;
  144. EFI_STATUS
  145. ReadGPT(
  146. EFI_HANDLE DiskHandle,
  147. PGPT_HEADER *Header,
  148. PGPT_TABLE *Table,
  149. PLBA_BLOCK *LbaBlock,
  150. UINTN *DiskType
  151. );
  152. EFI_STATUS
  153. WriteGPT(
  154. EFI_HANDLE DiskHandle,
  155. PGPT_HEADER Header,
  156. PGPT_TABLE Table,
  157. PLBA_BLOCK LbaBlock
  158. );
  159. EFI_STATUS
  160. CreateGPT(
  161. EFI_HANDLE DiskHandle,
  162. UINTN EntryRequest
  163. );
  164. #pragma pack ()