The previous section implements the extraction of the main GPT header, which continues to extract the entire GPT data, and merges the GPT partition table and MBR partition table into a single module, so that the master function (or the consumer) does not need to care about the partition table type of the disk: it is too low, and does not need too much care.
Continue to look at the section of Figure 1, here does not map, LBA1 's main GPT header gives the total number of partition information, as well as the number of bytes occupied by each partition information, the structure of the partition information is shown in table 1:
Table 1 partition information structure (GPT Entry)
byte offset |
Data Length (bytes) |
Example values |
Data item Description |
0x00 |
16 |
2A C1 1F F8 D2 one BA 4 b xx A0 C9 3E C9 3B |
Partition type represented by GUID |
0x10 |
16 |
7A C8 0E F8 E6 E9 B5 42 |
Partition unique identifier represented by GUID |
0x20 |
8 |
00 08 00 00 00 00 00 00 |
The starting sector of the partition, denoted by the LBA value |
0x28 |
8 |
FF E6 E9 B5 42 |
The end sector (inclusive) of the partition, represented by the LBA value, usually an odd number |
0x30 |
8 |
00 00 00 00 00 00 00 80 |
Attribute flags for this partition |
0x38 |
72 |
|
UTF-16LE encoded human readable partition name, maximum 32 characters |
As you can see, this structure is very concise, with only the start sector, end sector, partition type, GUID, attribute, partition name, and no concern for the head, track, etc.
It is necessary to note that the structure of the entire partition information, that is, from LBA2 to LBA34 (MS is always divided into 128 partition information), is completely continuous, do not rely on any sectors and other information to locate, that is, the nth partition information of the structure of the starting address, just according to the starting address of the LBA2 + Partition bytes *n To determine, the most common is the Microsoft defined 128 partition information, 512 bytes sector, 128 bytes of partition information bytes, so the most common is each sector 4 partition information, dense arrangement of 32 sectors. The correct counting method is however a partition information per 128 bytes, which is densely ranked of 128. When the sector is not 512 bytes (Note that this is not confused with the cluster, I have not seen the memory is not 512-byte sector), each sector storage partition information may not be 4, the following program to circumvent this problem, a new disk read and write function-- Readdiskdata instead of readsectordata--to prevent read partition information from appearing incorrectly.
1 /*******************************************************************************2 3 function Name: Getvolumenumberofgpt4 5 function function: Gets the number of active volumes in a GPT-formatted disk6 7 Input Parameters:8 9 hdisk: Disk handleTen One DPT: Disk DPT A - return parameter: type int, returns the number of valid partitions contained in the DPT (containing unformatted volumes), if the DPT is not a GPT - the partition form, will return-1 - - *******************************************************************************/ - + intGetvolumenumberofgpt (HANDLE Hdisk, dpt_info*DPT) - + { A at if(Dptdetermination (DPT) = =dpt_mbr) - - return-1; - - gptentry_byte Gptebuffer; - in Gptentry_info Gpteinfo; - to Pgpth_info pgpth; + -Getpgpth (Hdisk, &pgpth); the * intValidpartitions =0; $ Panax Notoginseng for(inti =0; I < pgpth. Partitiontables; i++) - the { + A Readdiskdata ( the +Hdisk,//Read disk handle - $Sector_size * pgpth. Partitionstart + i * pgpth. Bytesperpartitiontable,//calculates the gpte position of the read $ -(uint8_t*) (void*) &gptebuffer,//Buffer Address - the sizeof(Gptentry_byte));//Number of bytes - WuyiGetgpteinfo (&gptebuffer, &gpteinfo); the - if(GUIDCMP (& (Gpteinfo.typeguid), (guid_info*) &guid_ptunuse)) Wu - Break; About $ Else - -validpartitions++; - A } + the returnvalidpartitions; - $}
The partition type is stipulated, generally has several kinds of GUID of table 2, the attribute flag also has the stipulation, see table 3.
Table 2:16Byte GUID for partition type
Numerical |
Type description |
00000000-0000-0000-0000-000000000000 |
Not used |
024dee41-33e7-11d3-9d69-0008c781f39f |
MBR partition table |
c12a7328-f81f-11d2-ba4b-00a0c93ec93b |
EFI Systems partition [EFI System partition (ESP)], must be in VFAT format |
bc13c2ff-59e6-4262-a352-b275fd6f7172 |
Extended boot partition, must be VFAT format |
21686148-6449-6e6f-744e-656564454649 |
The corresponding ASCII string for the BIOS boot partition is "hah! Idontneedefi ". |
d3bfe2de-3daf-11df-ba40-e3a556d89593 |
Intel Fast Flash (IFFS) partition (for Intel Rapid Start Technology) |
E3c9e316-0b5c-4db8-817d-f92df00215ae |
Microsoft Reserved Partition |
Ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 |
Basic Data Partitioning |
De94bba4-06d1-4d40-a16a-bfd50179d6ac |
Windows Recovery Environment |
0fc63daf-8483-4772-8e79-3d69d8477de4 |
Data partitioning. Linux used to use the same GUID as the Windows Basic data partition. This new GUID was invented by GPT Fdisk and the GNU Parted developer based on the Linux legacy "8300" Partition code. |
44479540-f297-41b2-9af7-d131d5f0458a |
x86 root partition (/) This is the invention of systemd, which can be used for automatic mounting without fstab |
4f68bce3-e8cd-4db1-96e7-fbcaf984b709 |
X86-64 root partition (/) This is the invention of systemd, which can be used for automatic mounting without fstab |
69dad710-2ce4-4e3c-b16c-21a1d49abed3 |
ARM32 root partition (/) This is the invention of systemd, which can be used for automatic mounting without fstab |
B921b045-1df0-41c3-af44-4c6f280d3fae |
AARCH64 root partition (/) This is the invention of systemd, which can be used for automatic mounting without fstab |
3b8f8425-20e0-4f3b-907f-1a25a76f98e8 |
Server data Partitioning (/SRV) This is the invention of systemd, which can be used for automatic mounting without fstab. |
933ac7e1-2eb4-4f13-b844-0e14e2aef915 |
Home partition (/i) This is the invention of systemd, which can be used for automatic mounting without fstab |
0657fd6d-a4ab-43c4-84e5-0933c84b4f4f |
Swap partition (Swap) is not an invention of systemd, but can also be used for automatic mounting without fstab |
a19d880f-05fc-4d3b-a006-743f0f84911e |
RAID partitions |
e6d6d379-f507-44c2-a23c-238f2a3df928 |
Logical Volume Manager (LVM) partitioning |
8da63339-0007-60c0-c436-083ac8230908 |
Keep |
The above GUID value is interesting, according to the sector data obtained by Winhex, it divides the 16-byte GUID into 5 parts, in many compilers already has the GUID structure body definition is only 4 part, cannot use here, therefore we define a different structure
1 struct 2 3 { 4 5 uint32_t Part1; // 1th Part of the GUID 6
7 uint16_t Part2; // 2nd part of the GUID 8 9 uint16_t Part3; // 3rd part of the GUID Ten One uint16_t Part4; // 4th part of the GUID A - uint48_t Part5; // 5th part of the GUID - }guid_info;
to represent the GUID. And the interesting place is that these 5 parts are not pure big or small end mode, it is mixed, the first three parts are small end, the last two parts is big, we must pay attention to this when reading the structure.
Table 3: Partition Properties
value |
type description |
0 |
system partition |
1 |
efi hidden partition (EFI invisible partition) |
2 |
traditional BIOS bootable partition flag |
60 |
Read only |
62 |
hidden |
63 |
|
The list of attributes above is not complete, at least after my hard disk partition, the type is 0x80. Because there is only one byte of useful information, an enumeration type is sufficient to solve the problem.
Now we actually look at a lba,1 with 4 partition information:
Figure 1 LBA Partition
, the red box is a section of the structure of information, the essence of the part is the pink frame of 72 bytes, it is the UTF16 of the small-end mode encoding, because it involves the Chinese problem, Utf16le decoding is more complex, here we directly use wchar_t to get this structure:
1typedefstruct2 3 {4 5uint8_t typeguid[ -];//partition type represented by GUID6 7uint8_t uniqueguid[ -];//partition unique identifier represented by GUID8 9uint8_t sectorstart[8];//The starting sector of the partition, denoted by the LBA valueTen Oneuint8_t sectorend[8];//The end Sector (inclusive) of the partition, represented by the LBA value, usually an odd number A -uint8_t partitionattrib[8];//attribute flags for this partition - theWCHAR partitionname[ $];//UTF-16LE encoded human readable partition name, maximum 32 characters. - -}gptentry_byte;
Now the GPT structure can be fully read, because the post is done after the completion of the experimental stage, so no (=_= embarrassing).
The next step is to consolidate the GPT and MBR. Since the DPT boot to the GPT and MBR parts can be directly integrated, so the original DPT part of the code can be fixed, but the difference is that the GPT is to read the LBA directly to the start sector of each partition, the end sector, partition type and so on, and MBR mode is first through the DPT to obtain a position less than or equal to 4 boot sectors , and then parses the boot sectors, each of which corresponds to a partition information.
In the use of some other libraries, I was plagued by the problem is that there are too many API functions, there are many libraries have different API features are close, but also a lot of API names are similar but functionally distinct, so in order to avoid this situation, here try to reduce the API. According to this idea, you can construct the approximate process as follows: First, the user extracts the total number of partitions, then the user does malloc operations to create a partitioned list based on the number of partitions, and then, based on the partition list, can find the boot sector location for each partition. In this section, the so-called "partition information" is the partition information for the partition table, in fact, according to the previous sections of the introduction, the volume is not necessarily equal to the partition capacity, so the current code is partition for the partition, and the volume to represent the sub-volume.
Detailed code structure here does not do more interception, about the way the code is called in Main.cpp easy to see. In the compressed package there is a complete project based on the vs2015community environment.
Finally put a complete partition list running results (disk 3 is my mobile hard disk, disk 4 is my 64GB SD card).
Figure 2 Code Run results
Project: Https://files.cnblogs.com/files/Coder-Ku/NTFS5.rar
Implementation of the C language implementation of NTFS 5:GPT partition table on STM32 (2) GPT implementation and uniform read disk partitioning