partlibp.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. partlibp.h
  5. Abstract:
  6. This header contains internal definitions for the partition library.
  7. Author:
  8. Evan Green 6-Feb-2014
  9. --*/
  10. //
  11. // ------------------------------------------------------------------- Includes
  12. //
  13. #define RTL_API __DLLEXPORT
  14. #include <minoca/kernel/driver.h>
  15. #include <minoca/lib/partlib.h>
  16. //
  17. // ---------------------------------------------------------------- Definitions
  18. //
  19. #define PARTITION_SIGNATURE 0xAA55
  20. #define PARTITION_SIGNATURE_OFFSET 0x1FE
  21. //
  22. // Define the minimum block size for a disk.
  23. //
  24. #define MINIMUM_BLOCK_SIZE 512
  25. //
  26. // Define the MBR disk identifier offset.
  27. //
  28. #define MBR_DISK_ID_OFFSET 0x1B8
  29. #define MBR_DISK_ID_SIZE 4
  30. //
  31. // Define the offset of the partition table.
  32. //
  33. #define PARTITION_TABLE_OFFSET 0x1BE
  34. //
  35. // Define the number of entries in a partition table.
  36. //
  37. #define PARTITION_TABLE_SIZE 4
  38. //
  39. // Define the initial allocation size for the partition information array.
  40. //
  41. #define INITIAL_PARTITION_INFORMATION_CAPACITY 4
  42. //
  43. // Define the boot flag for MBR style partitions.
  44. //
  45. #define MBR_PARTITION_BOOT 0x80
  46. //
  47. // Define the maximum cylinder number.
  48. //
  49. #define MBR_MAX_CYLINDER 0x3FF
  50. //
  51. // Define the GPT header signature.
  52. //
  53. #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
  54. #define GPT_HEADER_REVISION_1 0x00010000
  55. //
  56. // Define the size of a GPT GUID.
  57. //
  58. #define GPT_GUID_SIZE 16
  59. //
  60. // Define the minimum size of the GPT partition entries array.
  61. //
  62. #define GPT_MINIMUM_PARTITION_ENTRIES_SIZE (16 * 1024)
  63. //
  64. // Define the desired alignment for partition start values.
  65. //
  66. #define GPT_PARTITION_ALIGNMENT (4 * 1024)
  67. //
  68. // Define some well known GPT disk GUIDs.
  69. //
  70. #define GPT_PARTITION_TYPE_EMPTY \
  71. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  72. #define GPT_PARTITION_TYPE_EFI_SYSTEM \
  73. {0x28, 0x73, 0x2A, 0xC1, 0x1F, 0xF8, 0xD2, 0x11, \
  74. 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B}
  75. #define GPT_PARTITION_TYPE_MINOCA \
  76. {0xCC, 0x07, 0xA3, 0xCE, 0xBD, 0x78, 0x40, 0x6E, \
  77. 0x81, 0x62, 0x60, 0x20, 0xAF, 0xB8, 0x8D, 0x17}
  78. //
  79. // ------------------------------------------------------ Data Type Definitions
  80. //
  81. /*++
  82. Structure Description:
  83. This structure defines the standard partition table entry format for MBR
  84. formatted disks.
  85. Members:
  86. BootIndicator - Stores either 0 (not the boot partition) or 0x80 (the
  87. active/boot partition).
  88. StartingHead - Stores the head number of the first sector of the partition
  89. in legacy CHS geometry.
  90. StartingSector - Stores the sector number of the first sector of the
  91. partition in legacy CHS geometry. Actually bits 0-5 stores the
  92. sector number, bits 6 and 7 are the high bits of the starting cylinder
  93. number.
  94. StartingCylinder - Stores the cylinder number of the first sector of the
  95. partition in legacy CHS geometry. Actually this really stores the low
  96. 8 bits, the high 2 bits are in the upper bits of the starting sector.
  97. SystemId - Stores the wild west system ID byte. No standard ever came for
  98. this byte.
  99. EndingHead - Stores the head number of hte last sector of the partition
  100. (inclusive) in legacy CHS geometry.
  101. EndingSector - Stores the sector number of the last sector of the partition
  102. (inclusive) in legacy CHS geometry. Bits 0-5 store the sector, bits
  103. 6 and 7 stores the lowest 2 bits of the ending cylinder.
  104. EndingCylinder - Stores the cylinder number of the last cylinder of the
  105. partition (inclusive) in legacy CHS geometry. This is actually the
  106. low 8 bits of the value, the highest two bits are in the upper bits of
  107. the ending sector.
  108. StartingLba - Stores the Logical Block Address of the first sector of the
  109. disk. This is the value everybody uses, and it's also the one that
  110. limits MBR disks to 2TB. This value is relative, but what it's relative
  111. to depends on which table and entry it is.
  112. SectorCount - Stores the number of sectors in the partition. This is the
  113. value everybody uses, but again is limited to 2TB.
  114. --*/
  115. typedef struct _PARTITION_TABLE_ENTRY {
  116. UCHAR BootIndicator;
  117. UCHAR StartingHead;
  118. UCHAR StartingSector;
  119. UCHAR StartingCylinder;
  120. UCHAR SystemId;
  121. UCHAR EndingHead;
  122. UCHAR EndingSector;
  123. UCHAR EndingCylinder;
  124. ULONG StartingLba;
  125. ULONG SectorCount;
  126. } PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
  127. /*++
  128. Structure Description:
  129. This structure defines the header format for GPT disks. Two copies of this
  130. structure exist, one at LBA 1, and one at the last LBA of the disk. LBA
  131. stands for Logical Block Address, it is the indexing used by the disk to
  132. address data.
  133. Members:
  134. Signature - Stores a constant value, set to GPT_HEADER_SIGNATURE
  135. ("EFI PART").
  136. Revision - Stores the revision of the format.
  137. HeaderSize - Stores the size of this structure (usually 0x5C).
  138. HeaderCrc32 - Stores the CRC32 of this header structure (up to header size
  139. bytes). This field is zeroed during calculation.
  140. Reserved - Stores a reserved value, must be set to zero.
  141. CurrentLba - Stores the LBA of this header copy.
  142. BackupLba - Stores the LBA of the other header copy.
  143. FirstUsableLba - Stores the LBA of the first data sector. This is after all
  144. the partition entries.
  145. LastUsableLba - Stores the LBA of the last data sector, inclusive. This is
  146. before all the backup partition entries.
  147. DiskGuid - Stores the unique identifier of the disk.
  148. PartitionEntriesLba - Stores the LBA of the partition entries. This is
  149. always 2 in the primary copy.
  150. PartitionEntryCount - Stores the maximum number of entries in the partition
  151. array.
  152. PartitionEntrySize - Stores the size of one partition entry element. This
  153. is usually 128.
  154. PartitionArrayCrc32 - Stores the CRC32 of the partition array, up to
  155. PartitionEntryCount * PartitionEntrySize bytes. Additional bytes due
  156. to the remainder of the block are ignored.
  157. --*/
  158. typedef struct _GPT_HEADER {
  159. ULONGLONG Signature;
  160. ULONG Revision;
  161. ULONG HeaderSize;
  162. ULONG HeaderCrc32;
  163. ULONG Reserved;
  164. ULONGLONG CurrentLba;
  165. ULONGLONG BackupLba;
  166. ULONGLONG FirstUsableLba;
  167. ULONGLONG LastUsableLba;
  168. UCHAR DiskGuid[GPT_GUID_SIZE];
  169. ULONGLONG PartitionEntriesLba;
  170. ULONG PartitionEntryCount;
  171. ULONG PartitionEntrySize;
  172. ULONG PartitionArrayCrc32;
  173. } PACKED GPT_HEADER, *PGPT_HEADER;
  174. /*++
  175. Structure Description:
  176. This structure defines the format of a partition entry in a GPT disk.
  177. Members:
  178. TypeGuid - Stores the GUID describing the type of the partition.
  179. Guid - Stores the unique GUID for this partition.
  180. FirstLba - Stores the first valid logical block address for this partition
  181. (in little endian format).
  182. LastLba - Stores the last valid logical block address for this partition
  183. (in little endian format), inclusive.
  184. Attributes - Stores a bitfield of attributes about the partition.
  185. Name - Stores a UTF-16LE human readable name for the partition.
  186. --*/
  187. typedef struct _GPT_PARTITION_ENTRY {
  188. UCHAR TypeGuid[GPT_GUID_SIZE];
  189. UCHAR Guid[GPT_GUID_SIZE];
  190. ULONGLONG FirstLba;
  191. ULONGLONG LastLba;
  192. ULONGLONG Attributes;
  193. USHORT Name[36];
  194. } PACKED GPT_PARTITION_ENTRY, *PGPT_PARTITION_ENTRY;
  195. /*++
  196. Structure Description:
  197. This structure defines a mapping between a system ID byte and a partition
  198. type.
  199. Members:
  200. SystemId - Stores the system ID byte.
  201. PartitionType - Stores the partition type corresponding to this system ID
  202. value.
  203. --*/
  204. typedef struct _PARTITION_SYSTEM_ID_MAPPING {
  205. UCHAR SystemId;
  206. PARTITION_TYPE PartitionType;
  207. } PARTITION_SYSTEM_ID_MAPPING, *PPARTITION_SYSTEM_ID_MAPPING;
  208. /*++
  209. Structure Description:
  210. This structure defines a mapping between a partition type ID and the type
  211. enum.
  212. Members:
  213. TypeGuid - Stores the partition type GUID.
  214. PartitionType - Stores the partition type corresponding to this partition
  215. type GUID.
  216. --*/
  217. typedef struct _PARTITION_TYPE_GUID_MAPPING {
  218. UCHAR TypeGuid[GPT_GUID_SIZE];
  219. PARTITION_TYPE PartitionType;
  220. } PARTITION_TYPE_GUID_MAPPING, *PPARTITION_TYPE_GUID_MAPPING;
  221. //
  222. // -------------------------------------------------------------------- Globals
  223. //
  224. //
  225. // -------------------------------------------------------- Function Prototypes
  226. //
  227. PVOID
  228. PartpAllocateIo (
  229. PPARTITION_CONTEXT Context,
  230. UINTN Size,
  231. PVOID *AlignedAllocation
  232. );
  233. /*++
  234. Routine Description:
  235. This routine allocates a region that will be used for I/O.
  236. Arguments:
  237. Context - Supplies a pointer to the initialized partition context.
  238. Size - Supplies the required size of the allocation.
  239. AlignedAllocation - Supplies a pointer where the aligned buffer will be
  240. returned.
  241. Return Value:
  242. Returns the actual buffer to be passed to the free function on success.
  243. NULL on failure.
  244. --*/
  245. BOOL
  246. PartpGptIsProtectiveMbr (
  247. PARTITION_TABLE_ENTRY Entry[PARTITION_TABLE_SIZE]
  248. );
  249. /*++
  250. Routine Description:
  251. This routine determines if the given partition table is a protective MBR
  252. for a GPT disk.
  253. Arguments:
  254. Entry - Supplies the array of MBR partition table entries.
  255. Return Value:
  256. TRUE if this is a GPT disk.
  257. FALSE if this is not a GPT disk.
  258. --*/
  259. KSTATUS
  260. PartpGptEnumeratePartitions (
  261. PPARTITION_CONTEXT Context
  262. );
  263. /*++
  264. Routine Description:
  265. This routine is called to read the partition information from the
  266. GPT-formatted disk and enumerate the list of partitions.
  267. Arguments:
  268. Context - Supplies a pointer to the initialized context.
  269. Return Value:
  270. STATUS_SUCCESS if the partition information could be determined. There
  271. could still be zero partitions in this case.
  272. STATUS_NO_ELIGIBLE_DEVICES if the partition table is invalid.
  273. Error codes on device read or allocation failure.
  274. --*/
  275. KSTATUS
  276. PartpGptWritePartitionLayout (
  277. PPARTITION_CONTEXT Context,
  278. PPARTITION_INFORMATION Partitions,
  279. ULONG PartitionCount,
  280. BOOL CleanMbr
  281. );
  282. /*++
  283. Routine Description:
  284. This routine writes a GPT partition layout to the disk. This usually wipes
  285. out all data on the disk.
  286. Arguments:
  287. Context - Supplies a pointer to the partition context.
  288. Partitions - Supplies a pointer to the new partition layout.
  289. PartitionCount - Supplies the number of partitions in the new layout.
  290. CleanMbr - Supplies a boolean indicating if only the partition entries of
  291. the MBR should be modified (FALSE) or if the whole MBR should be
  292. zeroed before being written (TRUE).
  293. Return Value:
  294. Status code.
  295. --*/
  296. PARTITION_TYPE
  297. PartpGptConvertTypeGuidToPartitionType (
  298. UCHAR TypeGuid[GPT_GUID_SIZE]
  299. );
  300. /*++
  301. Routine Description:
  302. This routine converts a partition type GUID into a partition type to the
  303. best of its abilities.
  304. Arguments:
  305. TypeGuid - Supplies a pointer to the partition type GUID.
  306. Return Value:
  307. Returns a partition type for this type GUID.
  308. --*/