]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - vtoygpt/vtoygpt.c
Update German translation (#2612)
[Ventoy.git] / vtoygpt / vtoygpt.c
1 /******************************************************************************
2 * vtoygpt.c ---- ventoy gpt util
3 *
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 */
20 #include <stdio.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/mman.h>
29 #include <sys/ioctl.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <linux/fs.h>
33 #include <dirent.h>
34
35 #define VOID void
36 #define CHAR char
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
42
43 UINT32 VtoyCrc32(VOID *Buffer, UINT32 Length);
44
45 #define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1]
46
47 #pragma pack(1)
48
49 typedef struct PART_TABLE
50 {
51 UINT8 Active;
52
53 UINT8 StartHead;
54 UINT16 StartSector : 6;
55 UINT16 StartCylinder : 10;
56
57 UINT8 FsFlag;
58
59 UINT8 EndHead;
60 UINT16 EndSector : 6;
61 UINT16 EndCylinder : 10;
62
63 UINT32 StartSectorId;
64 UINT32 SectorCount;
65 }PART_TABLE;
66
67 typedef struct MBR_HEAD
68 {
69 UINT8 BootCode[446];
70 PART_TABLE PartTbl[4];
71 UINT8 Byte55;
72 UINT8 ByteAA;
73 }MBR_HEAD;
74
75 typedef struct GUID
76 {
77 UINT32 data1;
78 UINT16 data2;
79 UINT16 data3;
80 UINT8 data4[8];
81 }GUID;
82
83 typedef struct VTOY_GPT_HDR
84 {
85 CHAR Signature[8]; /* EFI PART */
86 UINT8 Version[4];
87 UINT32 Length;
88 UINT32 Crc;
89 UINT8 Reserved1[4];
90 UINT64 EfiStartLBA;
91 UINT64 EfiBackupLBA;
92 UINT64 PartAreaStartLBA;
93 UINT64 PartAreaEndLBA;
94 GUID DiskGuid;
95 UINT64 PartTblStartLBA;
96 UINT32 PartTblTotNum;
97 UINT32 PartTblEntryLen;
98 UINT32 PartTblCrc;
99 UINT8 Reserved2[420];
100 }VTOY_GPT_HDR;
101
102 COMPILE_ASSERT(sizeof(VTOY_GPT_HDR) == 512);
103
104 typedef struct VTOY_GPT_PART_TBL
105 {
106 GUID PartType;
107 GUID PartGuid;
108 UINT64 StartLBA;
109 UINT64 LastLBA;
110 UINT64 Attr;
111 CHAR16 Name[36];
112 }VTOY_GPT_PART_TBL;
113 COMPILE_ASSERT(sizeof(VTOY_GPT_PART_TBL) == 128);
114
115 typedef struct VTOY_GPT_INFO
116 {
117 MBR_HEAD MBR;
118 VTOY_GPT_HDR Head;
119 VTOY_GPT_PART_TBL PartTbl[128];
120 }VTOY_GPT_INFO;
121
122 typedef struct VTOY_BK_GPT_INFO
123 {
124 VTOY_GPT_PART_TBL PartTbl[128];
125 VTOY_GPT_HDR Head;
126 }VTOY_BK_GPT_INFO;
127
128 COMPILE_ASSERT(sizeof(VTOY_GPT_INFO) == 512 * 34);
129 COMPILE_ASSERT(sizeof(VTOY_BK_GPT_INFO) == 512 * 33);
130
131 #pragma pack()
132
133 void DumpGuid(const char *prefix, GUID *guid)
134 {
135 printf("%s: %08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
136 prefix,
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]
140 );
141 }
142
143 void DumpHead(VTOY_GPT_HDR *pHead)
144 {
145 UINT32 CrcRead;
146 UINT32 CrcCalc;
147
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);
157
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);
162
163 CrcRead = pHead->Crc;
164 pHead->Crc = 0;
165 CrcCalc = VtoyCrc32(pHead, pHead->Length);
166
167 if (CrcCalc != CrcRead)
168 {
169 printf("Head CRC Check Failed\n");
170 }
171 else
172 {
173 printf("Head CRC Check SUCCESS [%x] [%x]\n", CrcCalc, CrcRead);
174 }
175
176 CrcRead = pHead->PartTblCrc;
177 CrcCalc = VtoyCrc32(pHead + 1, pHead->PartTblEntryLen * pHead->PartTblTotNum);
178 if (CrcCalc != CrcRead)
179 {
180 printf("Part Table CRC Check Failed\n");
181 }
182 else
183 {
184 printf("Part Table CRC Check SUCCESS [%x] [%x]\n", CrcCalc, CrcRead);
185 }
186 }
187
188 void DumpPartTable(VTOY_GPT_PART_TBL *Tbl)
189 {
190 int i;
191
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);
197 printf("Name:");
198
199 for (i = 0; i < 36 && Tbl->Name[i]; i++)
200 {
201 printf("%c", (CHAR)(Tbl->Name[i]));
202 }
203 printf("\n");
204 }
205
206 void DumpMBR(MBR_HEAD *pMBR)
207 {
208 int i;
209
210 for (i = 0; i < 4; i++)
211 {
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);
223 }
224 }
225
226 int DumpGptInfo(VTOY_GPT_INFO *pGptInfo)
227 {
228 int i;
229
230 DumpMBR(&pGptInfo->MBR);
231 DumpHead(&pGptInfo->Head);
232
233 for (i = 0; i < 128; i++)
234 {
235 if (pGptInfo->PartTbl[i].StartLBA == 0)
236 {
237 break;
238 }
239
240 printf("=====Part %d=====\n", i);
241 DumpPartTable(pGptInfo->PartTbl + i);
242 }
243
244 return 0;
245 }
246
247 #define VENTOY_EFI_PART_ATTR 0xC000000000000001ULL
248
249 int main(int argc, const char **argv)
250 {
251 int i;
252 int fd;
253 UINT64 DiskSize;
254 CHAR16 *Name = NULL;
255 VTOY_GPT_INFO *pMainGptInfo = NULL;
256 VTOY_BK_GPT_INFO *pBackGptInfo = NULL;
257
258 if (argc != 3)
259 {
260 printf("usage: vtoygpt -f /dev/sdb\n");
261 return 1;
262 }
263
264 fd = open(argv[2], O_RDWR);
265 if (fd < 0)
266 {
267 printf("Failed to open %s\n", argv[2]);
268 return 1;
269 }
270
271 pMainGptInfo = malloc(sizeof(VTOY_GPT_INFO));
272 pBackGptInfo = malloc(sizeof(VTOY_BK_GPT_INFO));
273 if (NULL == pMainGptInfo || NULL == pBackGptInfo)
274 {
275 close(fd);
276 return 1;
277 }
278
279 read(fd, pMainGptInfo, sizeof(VTOY_GPT_INFO));
280
281 if (argv[1][0] == '-' && argv[1][1] == 'd')
282 {
283 DumpGptInfo(pMainGptInfo);
284 }
285 else
286 {
287 DiskSize = lseek(fd, 0, SEEK_END);
288 lseek(fd, DiskSize - 33 * 512, SEEK_SET);
289 read(fd, pBackGptInfo, sizeof(VTOY_BK_GPT_INFO));
290
291 Name = pMainGptInfo->PartTbl[1].Name;
292 if (Name[0] == 'V' && Name[1] == 'T' && Name[2] == 'O' && Name[3] == 'Y')
293 {
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);
298
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);
303
304 lseek(fd, 512, SEEK_SET);
305 write(fd, (UINT8 *)pMainGptInfo + 512, sizeof(VTOY_GPT_INFO) - 512);
306
307 lseek(fd, DiskSize - 33 * 512, SEEK_SET);
308 write(fd, pBackGptInfo, sizeof(VTOY_BK_GPT_INFO));
309
310 fsync(fd);
311 }
312 }
313
314 free(pMainGptInfo);
315 free(pBackGptInfo);
316 close(fd);
317
318 return 0;
319 }
320