]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / BootsectImage / bootsectimage.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright 2006 - 2007, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 bootsectimage.c\r
15 \r
16Abstract:\r
17 Patch the BPB information in boot sector image file.\r
18 Patch the MBR code in MBR image file.\r
19\r
20--*/\r
21\r
22\r
23#include <windows.h>\r
24#include <stdio.h>\r
25#include "fat.h"\r
26#include "mbr.h"\r
27#include "EfiUtilityMsgs.h"\r
28\r
29#define DEBUG_WARN 0x1\r
30#define DEBUG_ERROR 0x2\r
31int WriteToFile (\r
32 void *BootSector, \r
33 char *FileName\r
34 )\r
35/*++\r
36Routine Description:\r
37 Write 512 bytes boot sector to file.\r
38\r
39Arguments:\r
40 BootSector - point to a buffer containing 512 bytes boot sector to write\r
41 FileName - file to write to\r
42\r
43Return:\r
44 int - number of bytes wrote,\r
45 512 indicates write successful\r
46 0 indicates write failure\r
47--*/\r
48{\r
49 FILE *FileHandle;\r
50 int result;\r
51\r
52 FileHandle = fopen (FileName, "r+b");\r
53 if (FileHandle == NULL) {\r
54 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);\r
55 return 0;\r
56 }\r
57 fseek (FileHandle, 0, SEEK_SET);\r
58\r
59 result = fwrite (BootSector, 1, 512, FileHandle);\r
60 if (result != 512) {\r
61 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName);\r
62 result = 0;\r
63 }\r
64\r
65 fclose (FileHandle);\r
66 return result;\r
67}\r
68\r
69int ReadFromFile (\r
70 void *BootSector, \r
71 char *FileName\r
72 )\r
73/*++\r
74Routine Description:\r
75 Read first 512 bytes from file.\r
76\r
77Arguments:\r
78 BootSector - point to a buffer receiving the first 512 bytes data from file\r
79 FileName - file to read from\r
80\r
81Return:\r
82 int - number of bytes read,\r
83 512 indicates read successful\r
84 0 indicates read failure\r
85--*/\r
86{\r
87 FILE *FileHandle;\r
88 int result;\r
89\r
90 FileHandle = fopen (FileName, "rb");\r
91 if (FileHandle == NULL) {\r
92 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);\r
93 return 0;\r
94 }\r
95\r
96 result = fread (BootSector, 1, 512, FileHandle);\r
97 if (result != 512) {\r
98 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Read file: %s", FileName);\r
99 result = 0;\r
100 }\r
101\r
102 fclose (FileHandle);\r
103 return result;\r
104}\r
105\r
106char *\r
107FatTypeToString (\r
108 IN FAT_TYPE FatType\r
109 )\r
110/*++\r
111Routine Description:\r
112 Convert enum type of FatType to string\r
113--*/\r
114{\r
115 switch (FatType) {\r
116 case FatTypeFat12:\r
117 return "FAT12";\r
118 case FatTypeFat16:\r
119 return "FAT16";\r
120 case FatTypeFat32:\r
121 return "FAT32";\r
122 default:\r
123 break;\r
124 }\r
125 return "FAT Unknown";\r
126}\r
127\r
128FAT_TYPE\r
129GetFatType (\r
130 IN FAT_BPB_STRUCT *FatBpb\r
131 )\r
132/*++\r
133Routine Description:\r
134 Determine the FAT type according to BIOS Paramater Block (BPB) data\r
135\r
136Arguments:\r
137 FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes\r
138\r
139Return:\r
140 FatTypeUnknown - Cannot determine the FAT type\r
141 FatTypeFat12 - FAT12\r
142 FatTypeFat16 - FAT16\r
143 FatTypeFat32 - FAT32\r
144--*/\r
145{\r
146 FAT_TYPE FatType;\r
147 UINTN RootDirSectors;\r
148 UINTN FATSz;\r
149 UINTN TotSec;\r
150 UINTN DataSec;\r
151 UINTN CountOfClusters;\r
152 CHAR8 FilSysType[9];\r
153\r
154 FatType = FatTypeUnknown;\r
155\r
156 //\r
157 // Simple check\r
158 //\r
159 if (FatBpb->Fat12_16.Signature != FAT_BS_SIGNATURE) {\r
160 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: Signature Invalid - %04x, expected - %04x",\r
161 FatBpb->Fat12_16.Signature, FAT_BS_SIGNATURE);\r
162 return FatTypeUnknown;\r
163 }\r
164\r
165 //\r
166 // Check according to FAT spec\r
167 //\r
168 if ((FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP1) &&\r
169 (FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP2)) {\r
170 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BS_jmpBoot - %02x, expected - %02x or %02x",\r
171 FatBpb->Fat12_16.BS_jmpBoot[0], FAT_BS_JMP1, FAT_BS_JMP2);\r
172 return FatTypeUnknown;\r
173 }\r
174\r
175 if ((FatBpb->Fat12_16.BPB_BytsPerSec != 512) &&\r
176 (FatBpb->Fat12_16.BPB_BytsPerSec != 1024) &&\r
177 (FatBpb->Fat12_16.BPB_BytsPerSec != 2048) &&\r
178 (FatBpb->Fat12_16.BPB_BytsPerSec != 4096)) {\r
179 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x, %04x, %04x, or %04x",\r
180 FatBpb->Fat12_16.BPB_BytsPerSec, 512, 1024, 2048, 4096);\r
181 return FatTypeUnknown;\r
182 }\r
183 if (FatBpb->Fat12_16.BPB_BytsPerSec != 512) {\r
184 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x",\r
185 FatBpb->Fat12_16.BPB_BytsPerSec, 512);\r
186 }\r
187 if ((FatBpb->Fat12_16.BPB_SecPerClus != 1) &&\r
188 (FatBpb->Fat12_16.BPB_SecPerClus != 2) &&\r
189 (FatBpb->Fat12_16.BPB_SecPerClus != 4) &&\r
190 (FatBpb->Fat12_16.BPB_SecPerClus != 8) &&\r
191 (FatBpb->Fat12_16.BPB_SecPerClus != 16) &&\r
192 (FatBpb->Fat12_16.BPB_SecPerClus != 32) &&\r
193 (FatBpb->Fat12_16.BPB_SecPerClus != 64) &&\r
194 (FatBpb->Fat12_16.BPB_SecPerClus != 128)) {\r
195 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_SecPerClus - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",\r
196 FatBpb->Fat12_16.BPB_BytsPerSec, 1, 2, 4, 8, 16, 32, 64, 128);\r
197 return FatTypeUnknown;\r
198 }\r
199 if (FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus > 32 * 1024) {\r
200 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec * BPB_SecPerClus - %08x, expected <= %08x",\r
201 FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus, 32 * 1024);\r
202 return FatTypeUnknown;\r
203 }\r
204 if (FatBpb->Fat12_16.BPB_RsvdSecCnt == 0) {\r
205 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_RsvdSecCnt - %04x, expected - Non-Zero",\r
206 FatBpb->Fat12_16.BPB_RsvdSecCnt);\r
207 return FatTypeUnknown;\r
208 }\r
209 if (FatBpb->Fat12_16.BPB_NumFATs != 2) {\r
210 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_NumFATs - %02x, expected - %02x",\r
211 FatBpb->Fat12_16.BPB_NumFATs, 2);\r
212 }\r
213 if ((FatBpb->Fat12_16.BPB_Media != 0xF0) &&\r
214 (FatBpb->Fat12_16.BPB_Media != 0xF8) &&\r
215 (FatBpb->Fat12_16.BPB_Media != 0xF9) &&\r
216 (FatBpb->Fat12_16.BPB_Media != 0xFA) &&\r
217 (FatBpb->Fat12_16.BPB_Media != 0xFB) &&\r
218 (FatBpb->Fat12_16.BPB_Media != 0xFC) &&\r
219 (FatBpb->Fat12_16.BPB_Media != 0xFD) &&\r
220 (FatBpb->Fat12_16.BPB_Media != 0xFE) &&\r
221 (FatBpb->Fat12_16.BPB_Media != 0xFF)) {\r
222 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_Media - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",\r
223 FatBpb->Fat12_16.BPB_Media, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF);\r
224 return FatTypeUnknown;\r
225 }\r
226\r
227 //\r
228 // Algo in FAT spec\r
229 //\r
230 RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) +\r
231 (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) /\r
232 FatBpb->Fat12_16.BPB_BytsPerSec;\r
233\r
234 if (FatBpb->Fat12_16.BPB_FATSz16 != 0) {\r
235 FATSz = FatBpb->Fat12_16.BPB_FATSz16;\r
236 } else {\r
237 FATSz = FatBpb->Fat32.BPB_FATSz32;\r
238 }\r
239 if (FATSz == 0) {\r
240 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero");\r
241 return FatTypeUnknown;\r
242 }\r
243\r
244 if (FatBpb->Fat12_16.BPB_TotSec16 != 0) {\r
245 TotSec = FatBpb->Fat12_16.BPB_TotSec16;\r
246 } else {\r
247 TotSec = FatBpb->Fat12_16.BPB_TotSec32;\r
248 }\r
249 if (TotSec == 0) {\r
250 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero");\r
251 return FatTypeUnknown;\r
252 }\r
253\r
254 DataSec = TotSec - (\r
255 FatBpb->Fat12_16.BPB_RsvdSecCnt +\r
256 FatBpb->Fat12_16.BPB_NumFATs * FATSz +\r
257 RootDirSectors\r
258 );\r
259\r
260 CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus;\r
261\r
262 if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) {\r
263 FatType = FatTypeFat12;\r
264 } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) {\r
265 FatType = FatTypeFat16;\r
266 } else {\r
267 FatType = FatTypeFat32;\r
268 }\r
269 //\r
270 // Check according to FAT spec\r
271 //\r
272 if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
273 (FatBpb->Fat12_16.BPB_RsvdSecCnt != 1)) {\r
274 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12_16: BPB_RsvdSecCnt - %04x, expected - %04x",\r
275 FatBpb->Fat12_16.BPB_RsvdSecCnt, 1);\r
276 }\r
277 if ((FatType == FatTypeFat32) &&\r
278 (FatBpb->Fat12_16.BPB_RsvdSecCnt != 32)) {\r
279 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RsvdSecCnt - %04x, expected - %04x",\r
280 FatBpb->Fat12_16.BPB_RsvdSecCnt, 32);\r
281 }\r
282 if ((FatType == FatTypeFat16) &&\r
283 (FatBpb->Fat12_16.BPB_RootEntCnt != 512)) {\r
284 printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n",\r
285 FatBpb->Fat12_16.BPB_RootEntCnt, 512);\r
286 }\r
287 if ((FatType == FatTypeFat32) &&\r
288 (FatBpb->Fat12_16.BPB_RootEntCnt != 0)) {\r
289 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_RootEntCnt - %04x, expected - %04x",\r
290 FatBpb->Fat12_16.BPB_RootEntCnt, 0);\r
291 return FatTypeUnknown;\r
292 }\r
293 if ((FatType == FatTypeFat32) &&\r
294 (FatBpb->Fat12_16.BPB_TotSec16 != 0)) {\r
295 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec16 - %04x, expected - %04x",\r
296 FatBpb->Fat12_16.BPB_TotSec16, 0);\r
297 return FatTypeUnknown;\r
298 }\r
299 if ((FatType == FatTypeFat32) &&\r
300 (FatBpb->Fat12_16.BPB_FATSz16 != 0)) {\r
301 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz16 - %04x, expected - %04x",\r
302 FatBpb->Fat12_16.BPB_FATSz16, 0);\r
303 return FatTypeUnknown;\r
304 }\r
305 if ((FatType == FatTypeFat32) &&\r
306 (FatBpb->Fat12_16.BPB_TotSec32 == 0)) {\r
307 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec32 - %04x, expected - Non-Zero",\r
308 FatBpb->Fat12_16.BPB_TotSec32);\r
309 return FatTypeUnknown;\r
310 }\r
311 if ((FatType == FatTypeFat32) &&\r
312 (FatBpb->Fat32.BPB_FATSz32 == 0)) {\r
313 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz32 - %08x, expected - Non-Zero",\r
314 FatBpb->Fat32.BPB_FATSz32);\r
315 return FatTypeUnknown;\r
316 }\r
317 if ((FatType == FatTypeFat32) &&\r
318 (FatBpb->Fat32.BPB_FSVer != 0)) {\r
319 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSVer - %08x, expected - %04x",\r
320 FatBpb->Fat32.BPB_FSVer, 0);\r
321 }\r
322 if ((FatType == FatTypeFat32) &&\r
323 (FatBpb->Fat32.BPB_RootClus != 2)) {\r
324 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RootClus - %08x, expected - %04x",\r
325 FatBpb->Fat32.BPB_RootClus, 2);\r
326 }\r
327 if ((FatType == FatTypeFat32) &&\r
328 (FatBpb->Fat32.BPB_FSInfo != 1)) {\r
329 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSInfo - %08x, expected - %04x",\r
330 FatBpb->Fat32.BPB_FSInfo, 1);\r
331 }\r
332 if ((FatType == FatTypeFat32) &&\r
333 (FatBpb->Fat32.BPB_BkBootSec != 6)) {\r
334 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_BkBootSec - %08x, expected - %04x",\r
335 FatBpb->Fat32.BPB_BkBootSec, 6);\r
336 }\r
337 if ((FatType == FatTypeFat32) &&\r
338 ((*(UINT32 *)FatBpb->Fat32.BPB_Reserved != 0) ||\r
339 (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 1) != 0) ||\r
340 (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 2) != 0))) {\r
341 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_Reserved - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x, expected - 0",\r
342 FatBpb->Fat32.BPB_Reserved[0],\r
343 FatBpb->Fat32.BPB_Reserved[1],\r
344 FatBpb->Fat32.BPB_Reserved[2],\r
345 FatBpb->Fat32.BPB_Reserved[3],\r
346 FatBpb->Fat32.BPB_Reserved[4],\r
347 FatBpb->Fat32.BPB_Reserved[5],\r
348 FatBpb->Fat32.BPB_Reserved[6],\r
349 FatBpb->Fat32.BPB_Reserved[7],\r
350 FatBpb->Fat32.BPB_Reserved[8],\r
351 FatBpb->Fat32.BPB_Reserved[9],\r
352 FatBpb->Fat32.BPB_Reserved[10],\r
353 FatBpb->Fat32.BPB_Reserved[11]);\r
354 return FatTypeUnknown;\r
355 }\r
356 if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
357 (FatBpb->Fat12_16.BS_Reserved1 != 0)) {\r
358 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_Reserved1 - %02x, expected - 0\n",\r
359 FatBpb->Fat12_16.BS_Reserved1);\r
360 return FatTypeUnknown;\r
361 }\r
362 if ((FatType == FatTypeFat32) &&\r
363 (FatBpb->Fat32.BS_Reserved1 != 0)) {\r
364 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_Reserved1 - %02x, expected - 0\n",\r
365 FatBpb->Fat32.BS_Reserved1);\r
366 return FatTypeUnknown;\r
367 }\r
368 if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&\r
369 (FatBpb->Fat12_16.BS_BootSig != FAT_BS_BOOTSIG)) {\r
370 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_BootSig - %02x, expected - %02x\n",\r
371 FatBpb->Fat12_16.BS_BootSig, FAT_BS_BOOTSIG);\r
372 return FatTypeUnknown;\r
373 }\r
374 if ((FatType == FatTypeFat32) &&\r
375 (FatBpb->Fat32.BS_BootSig != FAT_BS_BOOTSIG)) {\r
376 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_BootSig - %02x, expected - %02x\n",\r
377 FatBpb->Fat32.BS_BootSig, FAT_BS_BOOTSIG);\r
378 return FatTypeUnknown;\r
379 }\r
380 \r
381 if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) {\r
382 memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8);\r
383 FilSysType[8] = 0;\r
384 if ((FatType == FatTypeFat12) && \r
385 (strcmp (FilSysType, FAT12_FILSYSTYPE) != 0) &&\r
386 (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {\r
387 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12: BS_FilSysType - %s, expected - %s, or %s\n",\r
388 FilSysType, FAT12_FILSYSTYPE, FAT_FILSYSTYPE);\r
389 }\r
390 if ((FatType == FatTypeFat16) && \r
391 (strcmp (FilSysType, FAT16_FILSYSTYPE) != 0) &&\r
392 (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {\r
393 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT16: BS_FilSysType - %s, expected - %s, or %s\n",\r
394 FilSysType, FAT16_FILSYSTYPE, FAT_FILSYSTYPE);\r
395 }\r
396 }\r
397 if (FatType == FatTypeFat32) {\r
398 memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8);\r
399 FilSysType[8] = 0;\r
400 if (strcmp (FilSysType, FAT32_FILSYSTYPE) != 0) {\r
401 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BS_FilSysType - %s, expected - %s\n",\r
402 FilSysType, FAT32_FILSYSTYPE);\r
403 }\r
404 }\r
405\r
406 //\r
407 // pass all check, get FAT type\r
408 //\r
409 return FatType;\r
410}\r
411\r
412\r
413void\r
414ParseBootSector (\r
415 char *FileName\r
416 )\r
417{\r
418 FAT_BPB_STRUCT FatBpb;\r
419 FAT_TYPE FatType;\r
420 \r
421 if (ReadFromFile ((void *)&FatBpb, FileName) == 0) {\r
422 return ;\r
423 }\r
424 \r
425 FatType = GetFatType (&FatBpb);\r
426 if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) {\r
427 printf ("ERROR: Unknown Fat Type!\n");\r
428 return;\r
429 }\r
430\r
431 printf ("\nBoot Sector %s:\n", FatTypeToString (FatType));\r
432 printf ("\n");\r
433 printf (" Offset Title Data\n");\r
434 printf ("==================================================================\n");\r
435 printf (" 0 JMP instruction %02x %02x %02x\n",\r
436 FatBpb.Fat12_16.BS_jmpBoot[0],\r
437 FatBpb.Fat12_16.BS_jmpBoot[1],\r
438 FatBpb.Fat12_16.BS_jmpBoot[2]);\r
439 printf (" 3 OEM %c%c%c%c%c%c%c%c\n",\r
440 FatBpb.Fat12_16.BS_OEMName[0],\r
441 FatBpb.Fat12_16.BS_OEMName[1],\r
442 FatBpb.Fat12_16.BS_OEMName[2],\r
443 FatBpb.Fat12_16.BS_OEMName[3],\r
444 FatBpb.Fat12_16.BS_OEMName[4],\r
445 FatBpb.Fat12_16.BS_OEMName[5],\r
446 FatBpb.Fat12_16.BS_OEMName[6],\r
447 FatBpb.Fat12_16.BS_OEMName[7]);\r
448 printf ("\n");\r
449 printf ("BIOS Parameter Block\n");\r
450 printf (" B Bytes per sector %04x\n", FatBpb.Fat12_16.BPB_BytsPerSec);\r
451 printf (" D Sectors per cluster %02x\n", FatBpb.Fat12_16.BPB_SecPerClus);\r
452 printf (" E Reserved sectors %04x\n", FatBpb.Fat12_16.BPB_RsvdSecCnt);\r
453 printf (" 10 Number of FATs %02x\n", FatBpb.Fat12_16.BPB_NumFATs);\r
454 printf (" 11 Root entries %04x\n", FatBpb.Fat12_16.BPB_RootEntCnt);\r
455 printf (" 13 Sectors (under 32MB) %04x\n", FatBpb.Fat12_16.BPB_TotSec16);\r
456 printf (" 15 Media descriptor %02x\n", FatBpb.Fat12_16.BPB_Media);\r
457 printf (" 16 Sectors per FAT (small vol.) %04x\n", FatBpb.Fat12_16.BPB_FATSz16);\r
458 printf (" 18 Sectors per track %04x\n", FatBpb.Fat12_16.BPB_SecPerTrk);\r
459 printf (" 1A Heads %04x\n", FatBpb.Fat12_16.BPB_NumHeads);\r
460 printf (" 1C Hidden sectors %08x\n", FatBpb.Fat12_16.BPB_HiddSec);\r
461 printf (" 20 Sectors (over 32MB) %08x\n", FatBpb.Fat12_16.BPB_TotSec32);\r
462 printf ("\n");\r
463 if (FatType != FatTypeFat32) {\r
464 printf (" 24 BIOS drive %02x\n", FatBpb.Fat12_16.BS_DrvNum);\r
465 printf (" 25 (Unused) %02x\n", FatBpb.Fat12_16.BS_Reserved1);\r
466 printf (" 26 Ext. boot signature %02x\n", FatBpb.Fat12_16.BS_BootSig);\r
467 printf (" 27 Volume serial number %08x\n", FatBpb.Fat12_16.BS_VolID);\r
468 printf (" 2B Volume lable %c%c%c%c%c%c%c%c%c%c%c\n",\r
469 FatBpb.Fat12_16.BS_VolLab[0],\r
470 FatBpb.Fat12_16.BS_VolLab[1],\r
471 FatBpb.Fat12_16.BS_VolLab[2],\r
472 FatBpb.Fat12_16.BS_VolLab[3],\r
473 FatBpb.Fat12_16.BS_VolLab[4],\r
474 FatBpb.Fat12_16.BS_VolLab[5],\r
475 FatBpb.Fat12_16.BS_VolLab[6],\r
476 FatBpb.Fat12_16.BS_VolLab[7],\r
477 FatBpb.Fat12_16.BS_VolLab[8],\r
478 FatBpb.Fat12_16.BS_VolLab[9],\r
479 FatBpb.Fat12_16.BS_VolLab[10]);\r
480 printf (" 36 File system %c%c%c%c%c%c%c%c\n",\r
481 FatBpb.Fat12_16.BS_FilSysType[0],\r
482 FatBpb.Fat12_16.BS_FilSysType[1],\r
483 FatBpb.Fat12_16.BS_FilSysType[2],\r
484 FatBpb.Fat12_16.BS_FilSysType[3],\r
485 FatBpb.Fat12_16.BS_FilSysType[4],\r
486 FatBpb.Fat12_16.BS_FilSysType[5],\r
487 FatBpb.Fat12_16.BS_FilSysType[6],\r
488 FatBpb.Fat12_16.BS_FilSysType[7]);\r
489 printf ("\n");\r
490 } else {\r
491 printf ("FAT32 Section\n");\r
492 printf (" 24 Sectors per FAT (large vol.) %08x\n", FatBpb.Fat32.BPB_FATSz32);\r
493 printf (" 28 Flags %04x\n", FatBpb.Fat32.BPB_ExtFlags);\r
494 printf (" 2A Version %04x\n", FatBpb.Fat32.BPB_FSVer);\r
495 printf (" 2C Root dir 1st cluster %08x\n", FatBpb.Fat32.BPB_RootClus);\r
496 printf (" 30 FSInfo sector %04x\n", FatBpb.Fat32.BPB_FSInfo);\r
497 printf (" 32 Backup boot sector %04x\n", FatBpb.Fat32.BPB_BkBootSec);\r
498 printf (" 34 (Reserved) %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",\r
499 FatBpb.Fat32.BPB_Reserved[0],\r
500 FatBpb.Fat32.BPB_Reserved[1],\r
501 FatBpb.Fat32.BPB_Reserved[2],\r
502 FatBpb.Fat32.BPB_Reserved[3],\r
503 FatBpb.Fat32.BPB_Reserved[4],\r
504 FatBpb.Fat32.BPB_Reserved[5],\r
505 FatBpb.Fat32.BPB_Reserved[6],\r
506 FatBpb.Fat32.BPB_Reserved[7],\r
507 FatBpb.Fat32.BPB_Reserved[8],\r
508 FatBpb.Fat32.BPB_Reserved[9],\r
509 FatBpb.Fat32.BPB_Reserved[10],\r
510 FatBpb.Fat32.BPB_Reserved[11]);\r
511 printf ("\n");\r
512 printf (" 40 BIOS drive %02x\n", FatBpb.Fat32.BS_DrvNum);\r
513 printf (" 41 (Unused) %02x\n", FatBpb.Fat32.BS_Reserved1);\r
514 printf (" 42 Ext. boot signature %02x\n", FatBpb.Fat32.BS_BootSig);\r
515 printf (" 43 Volume serial number %08x\n", FatBpb.Fat32.BS_VolID);\r
516 printf (" 47 Volume lable %c%c%c%c%c%c%c%c%c%c%c\n",\r
517 FatBpb.Fat32.BS_VolLab[0],\r
518 FatBpb.Fat32.BS_VolLab[1],\r
519 FatBpb.Fat32.BS_VolLab[2],\r
520 FatBpb.Fat32.BS_VolLab[3],\r
521 FatBpb.Fat32.BS_VolLab[4],\r
522 FatBpb.Fat32.BS_VolLab[5],\r
523 FatBpb.Fat32.BS_VolLab[6],\r
524 FatBpb.Fat32.BS_VolLab[7],\r
525 FatBpb.Fat32.BS_VolLab[8],\r
526 FatBpb.Fat32.BS_VolLab[9],\r
527 FatBpb.Fat32.BS_VolLab[10]);\r
528 printf (" 52 File system %c%c%c%c%c%c%c%c\n",\r
529 FatBpb.Fat32.BS_FilSysType[0],\r
530 FatBpb.Fat32.BS_FilSysType[1],\r
531 FatBpb.Fat32.BS_FilSysType[2],\r
532 FatBpb.Fat32.BS_FilSysType[3],\r
533 FatBpb.Fat32.BS_FilSysType[4],\r
534 FatBpb.Fat32.BS_FilSysType[5],\r
535 FatBpb.Fat32.BS_FilSysType[6],\r
536 FatBpb.Fat32.BS_FilSysType[7]);\r
537 printf ("\n");\r
538 }\r
539 printf (" 1FE Signature %04x\n", FatBpb.Fat12_16.Signature);\r
540 printf ("\n");\r
541\r
542 \r
543 return ;\r
544}\r
545\r
546void\r
547PatchBootSector (\r
548 char *DestFileName,\r
549 char *SourceFileName,\r
550 BOOL ForcePatch\r
551 )\r
552/*++\r
553Routine Description:\r
554 Patch destination file according to the information from source file.\r
555 Only patch BPB data but leave boot code un-touched.\r
556\r
557Arguments:\r
558 DestFileName - Destination file to patch\r
559 SourceFileName - Source file where patch from\r
560--*/\r
561{\r
562 FAT_BPB_STRUCT DestFatBpb;\r
563 FAT_BPB_STRUCT SourceFatBpb;\r
564 FAT_TYPE DestFatType;\r
565 FAT_TYPE SourceFatType;\r
566 CHAR8 VolLab[11];\r
567 CHAR8 FilSysType[8];\r
568 \r
569 if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) {\r
570 return ;\r
571 }\r
572 if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) {\r
573 return ;\r
574 }\r
575 \r
576 DestFatType = GetFatType (&DestFatBpb);\r
577 SourceFatType = GetFatType (&SourceFatBpb);\r
578\r
579 if (DestFatType != SourceFatType) {\r
580 //\r
581 // FAT type mismatch\r
582 //\r
583 if (ForcePatch) {\r
584 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT type mismatch: Dest - %s, Source - %s", \r
585 FatTypeToString(DestFatType), FatTypeToString(SourceFatType));\r
586 } else {\r
587 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT type mismatch: Dest - %s, Source - %s", \r
588 FatTypeToString(DestFatType), FatTypeToString(SourceFatType));\r
589 return ;\r
590 }\r
591 }\r
592\r
593 if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) {\r
594 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Unknown Fat Type!\n");\r
595 return;\r
596 }\r
597\r
598 //\r
599 // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb\r
600 //\r
601 printf ("Patching %s BPB: ", FatTypeToString (SourceFatType));\r
602 if (SourceFatType != FatTypeFat32) {\r
603 memcpy (\r
604 &DestFatBpb.Fat12_16.BPB_BytsPerSec,\r
605 &SourceFatBpb.Fat12_16.BPB_BytsPerSec,\r
606 ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec)\r
607 );\r
608 } else {\r
609 memcpy (\r
610 &DestFatBpb.Fat32.BPB_BytsPerSec,\r
611 &SourceFatBpb.Fat32.BPB_BytsPerSec,\r
612 ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec)\r
613 );\r
614 }\r
615\r
616 //\r
617 // Set BS_VolLab and BS_FilSysType of DestFatBpb\r
618 //\r
619 // BS_VolLab BS_FilSysType\r
620 // FAT12: EFI FAT12 FAT12\r
621 // FAT16: EFI FAT16 FAT16\r
622 // FAT32: EFI FAT32 FAT32\r
623 //\r
624 if (SourceFatType == FatTypeFat32) {\r
625 memcpy (VolLab, "EFI FAT32 ", sizeof(VolLab));\r
626 memcpy (FilSysType, FAT32_FILSYSTYPE, sizeof(FilSysType));\r
627 } else if (SourceFatType == FatTypeFat16) {\r
628 memcpy (VolLab, "EFI FAT16 ", sizeof(VolLab));\r
629 memcpy (FilSysType, FAT16_FILSYSTYPE, sizeof(FilSysType));\r
630 } else {\r
631 memcpy (VolLab, "EFI FAT12 ", sizeof(VolLab));\r
632 memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType));\r
633 }\r
634 if (SourceFatType != FatTypeFat32) {\r
635 memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab));\r
636 memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType));\r
637 } else {\r
638 memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab));\r
639 memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType));\r
640 }\r
641 \r
642 //\r
643 // Set Signature of DestFatBpb to 55AA\r
644 //\r
645 DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE;\r
646\r
647 //\r
648 // Write DestFatBpb\r
649 //\r
650 if (WriteToFile ((void *)&DestFatBpb, DestFileName)) {\r
651 printf ("successfully!\n");\r
652 } else {\r
653 printf ("failed!\n");\r
654 }\r
655\r
656 return ;\r
657}\r
658\r
659void\r
660ParseMbr (\r
661 char *FileName\r
662 )\r
663{\r
664 MASTER_BOOT_RECORD Mbr;\r
665 \r
666 if (ReadFromFile ((void *)&Mbr, FileName) == 0) {\r
667 return ;\r
668 }\r
669 \r
670 printf ("\nMaster Boot Record:\n");\r
671 printf ("\n");\r
672 printf (" Offset Title Value\n");\r
673 printf ("==================================================================\n");\r
674 printf (" 0 Master bootstrap loader code (not list)\n");\r
675 printf (" 1B8 Windows disk signature %08x\n", Mbr.UniqueMbrSignature);\r
676 printf ("\n");\r
677 printf ("Partition Table Entry #1\n");\r
678 printf (" 1BE 80 = active partition %02x\n", Mbr.PartitionRecord[0].BootIndicator);\r
679 printf (" 1BF Start head %02x\n", Mbr.PartitionRecord[0].StartHead);\r
680 printf (" 1C0 Start sector %02x\n", Mbr.PartitionRecord[0].StartSector);\r
681 printf (" 1C1 Start cylinder %02x\n", Mbr.PartitionRecord[0].StartTrack);\r
682 printf (" 1C2 Partition type indicator %02x\n", Mbr.PartitionRecord[0].OSType);\r
683 printf (" 1C3 End head %02x\n", Mbr.PartitionRecord[0].EndHead);\r
684 printf (" 1C4 End sector %02x\n", Mbr.PartitionRecord[0].EndSector);\r
685 printf (" 1C5 End cylinder %02x\n", Mbr.PartitionRecord[0].EndTrack);\r
686 printf (" 1C6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[0].StartingLBA);\r
687 printf (" 1CA Sectors in partition %08x\n", Mbr.PartitionRecord[0].SizeInLBA);\r
688 printf ("\n");\r
689 printf ("Partition Table Entry #2\n");\r
690 printf (" 1CE 80 = active partition %02x\n", Mbr.PartitionRecord[1].BootIndicator);\r
691 printf (" 1CF Start head %02x\n", Mbr.PartitionRecord[1].StartHead);\r
692 printf (" 1D0 Start sector %02x\n", Mbr.PartitionRecord[1].StartSector);\r
693 printf (" 1D1 Start cylinder %02x\n", Mbr.PartitionRecord[1].StartTrack);\r
694 printf (" 1D2 Partition type indicator %02x\n", Mbr.PartitionRecord[1].OSType);\r
695 printf (" 1D3 End head %02x\n", Mbr.PartitionRecord[1].EndHead);\r
696 printf (" 1D4 End sector %02x\n", Mbr.PartitionRecord[1].EndSector);\r
697 printf (" 1D5 End cylinder %02x\n", Mbr.PartitionRecord[1].EndTrack);\r
698 printf (" 1D6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[1].StartingLBA);\r
699 printf (" 1DA Sectors in partition %08x\n", Mbr.PartitionRecord[1].SizeInLBA);\r
700 printf ("\n");\r
701 printf ("Partition Table Entry #3\n");\r
702 printf (" 1DE 80 = active partition %02x\n", Mbr.PartitionRecord[2].BootIndicator);\r
703 printf (" 1DF Start head %02x\n", Mbr.PartitionRecord[2].StartHead);\r
704 printf (" 1E0 Start sector %02x\n", Mbr.PartitionRecord[2].StartSector);\r
705 printf (" 1E1 Start cylinder %02x\n", Mbr.PartitionRecord[2].StartTrack);\r
706 printf (" 1E2 Partition type indicator %02x\n", Mbr.PartitionRecord[2].OSType);\r
707 printf (" 1E3 End head %02x\n", Mbr.PartitionRecord[2].EndHead);\r
708 printf (" 1E4 End sector %02x\n", Mbr.PartitionRecord[2].EndSector);\r
709 printf (" 1E5 End cylinder %02x\n", Mbr.PartitionRecord[2].EndTrack);\r
710 printf (" 1E6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[2].StartingLBA);\r
711 printf (" 1EA Sectors in partition %08x\n", Mbr.PartitionRecord[2].SizeInLBA);\r
712 printf ("\n");\r
713 printf ("Partition Table Entry #4\n");\r
714 printf (" 1EE 80 = active partition %02x\n", Mbr.PartitionRecord[3].BootIndicator);\r
715 printf (" 1EF Start head %02x\n", Mbr.PartitionRecord[3].StartHead);\r
716 printf (" 1F0 Start sector %02x\n", Mbr.PartitionRecord[3].StartSector);\r
717 printf (" 1F1 Start cylinder %02x\n", Mbr.PartitionRecord[3].StartTrack);\r
718 printf (" 1F2 Partition type indicator %02x\n", Mbr.PartitionRecord[3].OSType);\r
719 printf (" 1F3 End head %02x\n", Mbr.PartitionRecord[3].EndHead);\r
720 printf (" 1F4 End sector %02x\n", Mbr.PartitionRecord[3].EndSector);\r
721 printf (" 1F5 End cylinder %02x\n", Mbr.PartitionRecord[3].EndTrack);\r
722 printf (" 1F6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[3].StartingLBA);\r
723 printf (" 1FA Sectors in partition %08x\n", Mbr.PartitionRecord[3].SizeInLBA);\r
724 printf ("\n");\r
725 printf (" 1FE Signature %04x\n", Mbr.Signature);\r
726 printf ("\n");\r
727\r
728 return ;\r
729}\r
730\r
731void\r
732PatchMbr (\r
733 char *DestFileName,\r
734 char *SourceFileName\r
735 )\r
736{\r
737 MASTER_BOOT_RECORD DestMbr;\r
738 MASTER_BOOT_RECORD SourceMbr;\r
739 \r
740 if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) {\r
741 return ;\r
742 }\r
743 if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) {\r
744 return ;\r
745 }\r
746 \r
747 if (SourceMbr.Signature != MBR_SIGNATURE) {\r
748 printf ("ERROR: Invalid MBR!\n");\r
749 return;\r
750 }\r
751\r
752 printf ("Patching MBR:\n");\r
753 memcpy (\r
754 &DestMbr.PartitionRecord[0],\r
755 &SourceMbr.PartitionRecord[0],\r
756 sizeof(DestMbr.PartitionRecord)\r
757 );\r
758\r
759 DestMbr.Signature = MBR_SIGNATURE;\r
760\r
761\r
762 if (WriteToFile ((void *)&DestMbr, DestFileName)) {\r
763 printf ("\tsuccessfully!\n");\r
764 }\r
765\r
766 return ;\r
767}\r
768\r
769void\r
770PrintUsage (\r
771 void\r
772 )\r
773{\r
774 printf (\r
775 "Usage:\n"\r
776 "bootsectimage [-m] [-v] -p SrcImage\n"\r
777 "bootsectimage [-m] [-v] [-f] -g SrcImage DstImage\n"\r
778 "where\n"\r
779 " -p: parse SrcImage\n"\r
780 " -g: get info from SrcImage, and patch to DstImage\n"\r
781 " -f: force patch even FAT type of SrcImage and DstImage mismatch\n"\r
782 " -m: process MBR instead of boot sector\n"\r
783 " -v: verbose\n"\r
784 );\r
785}\r
786\r
787int\r
788main (\r
789 int argc,\r
790 char *argv[]\r
791 )\r
792{\r
793 char *SrcImage;\r
794 char *DstImage;\r
795 BOOL ForcePatch; // -f\r
796 BOOL ProcessMbr; // -m\r
797 BOOL DoParse; // -p SrcImage or -g SrcImage DstImage\r
798 BOOL Verbose; // -v\r
799 \r
800 SrcImage = DstImage = NULL;\r
801 ForcePatch = FALSE;\r
802 ProcessMbr = FALSE;\r
803 DoParse = TRUE;\r
804 Verbose = FALSE;\r
805\r
806 SetUtilityName ("bootsectimage");\r
807\r
808 argc--; argv++;\r
809\r
810 if (argc == 0) {\r
811 PrintUsage ();\r
812 return -1;\r
813 }\r
814\r
815 while (argc != 0) {\r
816 if (strcmp (*argv, "-f") == 0) {\r
817 ForcePatch = TRUE;\r
818 } else if (strcmp (*argv, "-p") == 0) {\r
819 DoParse = TRUE;\r
820 argc--; argv++;\r
821 if (argc < 1) {\r
822 PrintUsage ();\r
823 return -1;\r
824 }\r
825 SrcImage = *argv;\r
826 } else if (strcmp (*argv, "-g") == 0) {\r
827 DoParse = FALSE;\r
828 argc--; argv++;\r
829 if (argc < 2) {\r
830 PrintUsage ();\r
831 return -1;\r
832 }\r
833 SrcImage = *argv;\r
834 argc--; argv++;\r
835 DstImage = *argv;\r
836 } else if (strcmp (*argv, "-m") == 0) {\r
837 ProcessMbr = TRUE;\r
838 } else if (strcmp (*argv, "-v") == 0) {\r
839 Verbose = TRUE;\r
840 } else {\r
841 PrintUsage ();\r
842 return -1;\r
843 }\r
844\r
845 argc--; argv++;\r
846 }\r
847\r
848 if (ForcePatch && DoParse) {\r
849 printf ("Cannot apply force(-f) to parse(-p)!\n");\r
850 PrintUsage ();\r
851 return -1;\r
852 }\r
853 if (ForcePatch && !DoParse && ProcessMbr) {\r
854 printf ("Cannot apply force(-f) to processing MBR (-g -m)!\n");\r
855 PrintUsage ();\r
856 return -1;\r
857 }\r
858\r
859 if (Verbose) {\r
860 SetDebugMsgMask (DEBUG_WARN | DEBUG_ERROR);\r
861 } else {\r
862 SetDebugMsgMask (0);\r
863 }\r
864\r
865 if (DoParse) {\r
866 if (ProcessMbr) {\r
867 ParseMbr (SrcImage);\r
868 } else {\r
869 ParseBootSector (SrcImage);\r
870 }\r
871 } else {\r
872 if (ProcessMbr) {\r
873 PatchMbr (DstImage, SrcImage);\r
874 } else {\r
875 PatchBootSector (DstImage, SrcImage, ForcePatch);\r
876 }\r
877 }\r
878\r
879 return 0;\r
880}\r
881\r