1 /******************************************************************************
2 * vtoygpt.c ---- ventoy gpt util
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include <sys/types.h>
29 #include <sys/ioctl.h>
31 #include <sys/types.h>
37 #define UINT64 unsigned long long
38 #define UINT32 unsigned int
39 #define UINT16 unsigned short
40 #define CHAR16 unsigned short
41 #define UINT8 unsigned char
43 UINT32
VtoyCrc32(VOID
*Buffer
, UINT32 Length
);
45 #define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1]
49 typedef struct PART_TABLE
54 UINT16 StartSector
: 6;
55 UINT16 StartCylinder
: 10;
61 UINT16 EndCylinder
: 10;
67 typedef struct MBR_HEAD
70 PART_TABLE PartTbl
[4];
83 typedef struct VTOY_GPT_HDR
85 CHAR Signature
[8]; /* EFI PART */
92 UINT64 PartAreaStartLBA
;
93 UINT64 PartAreaEndLBA
;
95 UINT64 PartTblStartLBA
;
97 UINT32 PartTblEntryLen
;
102 COMPILE_ASSERT(sizeof(VTOY_GPT_HDR
) == 512);
104 typedef struct VTOY_GPT_PART_TBL
113 COMPILE_ASSERT(sizeof(VTOY_GPT_PART_TBL
) == 128);
115 typedef struct VTOY_GPT_INFO
119 VTOY_GPT_PART_TBL PartTbl
[128];
122 typedef struct VTOY_BK_GPT_INFO
124 VTOY_GPT_PART_TBL PartTbl
[128];
128 COMPILE_ASSERT(sizeof(VTOY_GPT_INFO
) == 512 * 34);
129 COMPILE_ASSERT(sizeof(VTOY_BK_GPT_INFO
) == 512 * 33);
133 void DumpGuid(const char *prefix
, GUID
*guid
)
135 printf("%s: %08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
137 guid
->data1
, guid
->data2
, guid
->data3
,
138 guid
->data4
[0], guid
->data4
[1], guid
->data4
[2], guid
->data4
[3],
139 guid
->data4
[4], guid
->data4
[5], guid
->data4
[6], guid
->data4
[7]
143 void DumpHead(VTOY_GPT_HDR
*pHead
)
148 printf("Signature:<%s>\n", pHead
->Signature
);
149 printf("Version:<%02x %02x %02x %02x>\n", pHead
->Version
[0], pHead
->Version
[1], pHead
->Version
[2], pHead
->Version
[3]);
150 printf("Length:%u\n", pHead
->Length
);
151 printf("Crc:0x%08x\n", pHead
->Crc
);
152 printf("EfiStartLBA:%lu\n", pHead
->EfiStartLBA
);
153 printf("EfiBackupLBA:%lu\n", pHead
->EfiBackupLBA
);
154 printf("PartAreaStartLBA:%lu\n", pHead
->PartAreaStartLBA
);
155 printf("PartAreaEndLBA:%lu\n", pHead
->PartAreaEndLBA
);
156 DumpGuid("DiskGuid", &pHead
->DiskGuid
);
158 printf("PartTblStartLBA:%lu\n", pHead
->PartTblStartLBA
);
159 printf("PartTblTotNum:%u\n", pHead
->PartTblTotNum
);
160 printf("PartTblEntryLen:%u\n", pHead
->PartTblEntryLen
);
161 printf("PartTblCrc:0x%08x\n", pHead
->PartTblCrc
);
163 CrcRead
= pHead
->Crc
;
165 CrcCalc
= VtoyCrc32(pHead
, pHead
->Length
);
167 if (CrcCalc
!= CrcRead
)
169 printf("Head CRC Check Failed\n");
173 printf("Head CRC Check SUCCESS [%x] [%x]\n", CrcCalc
, CrcRead
);
176 CrcRead
= pHead
->PartTblCrc
;
177 CrcCalc
= VtoyCrc32(pHead
+ 1, pHead
->PartTblEntryLen
* pHead
->PartTblTotNum
);
178 if (CrcCalc
!= CrcRead
)
180 printf("Part Table CRC Check Failed\n");
184 printf("Part Table CRC Check SUCCESS [%x] [%x]\n", CrcCalc
, CrcRead
);
188 void DumpPartTable(VTOY_GPT_PART_TBL
*Tbl
)
192 DumpGuid("PartType", &Tbl
->PartType
);
193 DumpGuid("PartGuid", &Tbl
->PartGuid
);
194 printf("StartLBA:%lu\n", Tbl
->StartLBA
);
195 printf("LastLBA:%lu\n", Tbl
->LastLBA
);
196 printf("Attr:0x%lx\n", Tbl
->Attr
);
199 for (i
= 0; i
< 36 && Tbl
->Name
[i
]; i
++)
201 printf("%c", (CHAR
)(Tbl
->Name
[i
]));
206 void DumpMBR(MBR_HEAD
*pMBR
)
210 for (i
= 0; i
< 4; i
++)
212 printf("=========== Partition Table %d ============\n", i
+ 1);
213 printf("PartTbl.Active = 0x%x\n", pMBR
->PartTbl
[i
].Active
);
214 printf("PartTbl.FsFlag = 0x%x\n", pMBR
->PartTbl
[i
].FsFlag
);
215 printf("PartTbl.StartSectorId = %u\n", pMBR
->PartTbl
[i
].StartSectorId
);
216 printf("PartTbl.SectorCount = %u\n", pMBR
->PartTbl
[i
].SectorCount
);
217 printf("PartTbl.StartHead = %u\n", pMBR
->PartTbl
[i
].StartHead
);
218 printf("PartTbl.StartSector = %u\n", pMBR
->PartTbl
[i
].StartSector
);
219 printf("PartTbl.StartCylinder = %u\n", pMBR
->PartTbl
[i
].StartCylinder
);
220 printf("PartTbl.EndHead = %u\n", pMBR
->PartTbl
[i
].EndHead
);
221 printf("PartTbl.EndSector = %u\n", pMBR
->PartTbl
[i
].EndSector
);
222 printf("PartTbl.EndCylinder = %u\n", pMBR
->PartTbl
[i
].EndCylinder
);
226 int DumpGptInfo(VTOY_GPT_INFO
*pGptInfo
)
230 DumpMBR(&pGptInfo
->MBR
);
231 DumpHead(&pGptInfo
->Head
);
233 for (i
= 0; i
< 128; i
++)
235 if (pGptInfo
->PartTbl
[i
].StartLBA
== 0)
240 printf("=====Part %d=====\n", i
);
241 DumpPartTable(pGptInfo
->PartTbl
+ i
);
247 #define VENTOY_EFI_PART_ATTR 0xC000000000000001ULL
249 int main(int argc
, const char **argv
)
255 VTOY_GPT_INFO
*pMainGptInfo
= NULL
;
256 VTOY_BK_GPT_INFO
*pBackGptInfo
= NULL
;
260 printf("usage: vtoygpt -f /dev/sdb\n");
264 fd
= open(argv
[2], O_RDWR
);
267 printf("Failed to open %s\n", argv
[2]);
271 pMainGptInfo
= malloc(sizeof(VTOY_GPT_INFO
));
272 pBackGptInfo
= malloc(sizeof(VTOY_BK_GPT_INFO
));
273 if (NULL
== pMainGptInfo
|| NULL
== pBackGptInfo
)
279 read(fd
, pMainGptInfo
, sizeof(VTOY_GPT_INFO
));
281 if (argv
[1][0] == '-' && argv
[1][1] == 'd')
283 DumpGptInfo(pMainGptInfo
);
287 DiskSize
= lseek(fd
, 0, SEEK_END
);
288 lseek(fd
, DiskSize
- 33 * 512, SEEK_SET
);
289 read(fd
, pBackGptInfo
, sizeof(VTOY_BK_GPT_INFO
));
291 Name
= pMainGptInfo
->PartTbl
[1].Name
;
292 if (Name
[0] == 'V' && Name
[1] == 'T' && Name
[2] == 'O' && Name
[3] == 'Y')
294 pMainGptInfo
->PartTbl
[1].Attr
= VENTOY_EFI_PART_ATTR
;
295 pMainGptInfo
->Head
.PartTblCrc
= VtoyCrc32(pMainGptInfo
->PartTbl
, sizeof(pMainGptInfo
->PartTbl
));
296 pMainGptInfo
->Head
.Crc
= 0;
297 pMainGptInfo
->Head
.Crc
= VtoyCrc32(&pMainGptInfo
->Head
, pMainGptInfo
->Head
.Length
);
299 pBackGptInfo
->PartTbl
[1].Attr
= VENTOY_EFI_PART_ATTR
;
300 pBackGptInfo
->Head
.PartTblCrc
= VtoyCrc32(pBackGptInfo
->PartTbl
, sizeof(pBackGptInfo
->PartTbl
));
301 pBackGptInfo
->Head
.Crc
= 0;
302 pBackGptInfo
->Head
.Crc
= VtoyCrc32(&pBackGptInfo
->Head
, pBackGptInfo
->Head
.Length
);
304 lseek(fd
, 512, SEEK_SET
);
305 write(fd
, (UINT8
*)pMainGptInfo
+ 512, sizeof(VTOY_GPT_INFO
) - 512);
307 lseek(fd
, DiskSize
- 33 * 512, SEEK_SET
);
308 write(fd
, pBackGptInfo
, sizeof(VTOY_BK_GPT_INFO
));