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