4 Patch the BPB information in boot sector image file.
5 Patch the MBR code in MBR image file.
7 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include "EfiUtilityMsgs.h"
24 #define DEBUG_WARN 0x1
25 #define DEBUG_ERROR 0x2
30 #define UTILITY_NAME "BootSectImage"
33 // Utility version information
35 #define UTILITY_MAJOR_VERSION 0
36 #define UTILITY_MINOR_VERSION 1
46 Displays the standard utility information to SDTOUT
58 printf ("%s v%d.%d - Utility to break a file into two pieces at the specified offset.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
59 printf ("Copyright (c) 1999-2010 Intel Corporation. All rights reserved.\n");
70 GC_TODO: Add function description
77 GC_TODO: add return values
84 [-f, --force force patch even if the FAT type of SrcImage and DstImage mismatch]\n\
85 [-m, --mbr process MBR instead of boot sector]\n\
86 [-p, --parse parse SrcImageFile]\n\
87 [-o, --output DstImage]\n\
88 [-g, --patch patch DstImage using data from SrcImageFile]\n\
91 [-q, --quiet disable all messages except fatal errors]\n\
103 Write 512 bytes boot sector to file.
106 BootSector - point to a buffer containing 512 bytes boot sector to write
107 FileName - file to write to
110 int - number of bytes wrote,
111 512 indicates write successful
112 0 indicates write failure
118 FileHandle
= fopen (FileName
, "r+b");
119 if (FileHandle
== NULL
) {
120 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "Open file: %s", FileName
);
123 fseek (FileHandle
, 0, SEEK_SET
);
125 result
= fwrite (BootSector
, 1, 512, FileHandle
);
127 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "Write file: %s", FileName
);
141 Read first 512 bytes from file.
144 BootSector - point to a buffer receiving the first 512 bytes data from file
145 FileName - file to read from
148 int - number of bytes read,
149 512 indicates read successful
150 0 indicates read failure
156 FileHandle
= fopen (FileName
, "rb");
157 if (FileHandle
== NULL
) {
158 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E0001: Error opening file: %s", FileName
);
162 result
= fread (BootSector
, 1, 512, FileHandle
);
164 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E0004: Error reading file: %s", FileName
);
178 Convert enum type of FatType to string
191 return "FAT Unknown";
196 IN FAT_BPB_STRUCT
*FatBpb
200 Determine the FAT type according to BIOS Paramater Block (BPB) data
203 FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes
206 FatTypeUnknown - Cannot determine the FAT type
213 UINTN RootDirSectors
;
217 UINTN CountOfClusters
;
220 FatType
= FatTypeUnknown
;
225 if (FatBpb
->Fat12_16
.Signature
!= FAT_BS_SIGNATURE
) {
226 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - Signature Invalid - %04x, expected: %04x",
227 FatBpb
->Fat12_16
.Signature
, FAT_BS_SIGNATURE
);
228 return FatTypeUnknown
;
232 // Check according to FAT spec
234 if ((FatBpb
->Fat12_16
.BS_jmpBoot
[0] != FAT_BS_JMP1
) &&
235 (FatBpb
->Fat12_16
.BS_jmpBoot
[0] != FAT_BS_JMP2
)) {
236 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BS_jmpBoot - %02x, expected: %02x or %02x",
237 FatBpb
->Fat12_16
.BS_jmpBoot
[0], FAT_BS_JMP1
, FAT_BS_JMP2
);
238 return FatTypeUnknown
;
241 if ((FatBpb
->Fat12_16
.BPB_BytsPerSec
!= 512) &&
242 (FatBpb
->Fat12_16
.BPB_BytsPerSec
!= 1024) &&
243 (FatBpb
->Fat12_16
.BPB_BytsPerSec
!= 2048) &&
244 (FatBpb
->Fat12_16
.BPB_BytsPerSec
!= 4096)) {
245 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_BytsPerSec - %04x, expected: %04x, %04x, %04x, or %04x",
246 FatBpb
->Fat12_16
.BPB_BytsPerSec
, 512, 1024, 2048, 4096);
247 return FatTypeUnknown
;
249 if (FatBpb
->Fat12_16
.BPB_BytsPerSec
!= 512) {
250 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT - BPB_BytsPerSec - %04x, expected: %04x",
251 FatBpb
->Fat12_16
.BPB_BytsPerSec
, 512);
253 if ((FatBpb
->Fat12_16
.BPB_SecPerClus
!= 1) &&
254 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 2) &&
255 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 4) &&
256 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 8) &&
257 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 16) &&
258 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 32) &&
259 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 64) &&
260 (FatBpb
->Fat12_16
.BPB_SecPerClus
!= 128)) {
261 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_SecPerClus - %02x, expected: %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",
262 FatBpb
->Fat12_16
.BPB_BytsPerSec
, 1, 2, 4, 8, 16, 32, 64, 128);
263 return FatTypeUnknown
;
265 if (FatBpb
->Fat12_16
.BPB_BytsPerSec
* FatBpb
->Fat12_16
.BPB_SecPerClus
> 32 * 1024) {
266 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_BytsPerSec * BPB_SecPerClus - %08x, expected: <= %08x",
267 FatBpb
->Fat12_16
.BPB_BytsPerSec
* FatBpb
->Fat12_16
.BPB_SecPerClus
, 32 * 1024);
268 return FatTypeUnknown
;
270 if (FatBpb
->Fat12_16
.BPB_RsvdSecCnt
== 0) {
271 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_RsvdSecCnt - %04x, expected: Non-Zero Value",
272 FatBpb
->Fat12_16
.BPB_RsvdSecCnt
);
273 return FatTypeUnknown
;
275 if (FatBpb
->Fat12_16
.BPB_NumFATs
!= 2) {
276 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT - BPB_NumFATs - %02x, expected: %02x",
277 FatBpb
->Fat12_16
.BPB_NumFATs
, 2);
279 if ((FatBpb
->Fat12_16
.BPB_Media
!= 0xF0) &&
280 (FatBpb
->Fat12_16
.BPB_Media
!= 0xF8) &&
281 (FatBpb
->Fat12_16
.BPB_Media
!= 0xF9) &&
282 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFA) &&
283 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFB) &&
284 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFC) &&
285 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFD) &&
286 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFE) &&
287 (FatBpb
->Fat12_16
.BPB_Media
!= 0xFF)) {
288 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_Media - %02x, expected: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",
289 FatBpb
->Fat12_16
.BPB_Media
, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF);
290 return FatTypeUnknown
;
296 RootDirSectors
= ((FatBpb
->Fat12_16
.BPB_RootEntCnt
* sizeof(FAT_DIRECTORY_ENTRY
)) +
297 (FatBpb
->Fat12_16
.BPB_BytsPerSec
- 1)) /
298 FatBpb
->Fat12_16
.BPB_BytsPerSec
;
300 if (FatBpb
->Fat12_16
.BPB_FATSz16
!= 0) {
301 FATSz
= FatBpb
->Fat12_16
.BPB_FATSz16
;
303 FATSz
= FatBpb
->Fat32
.BPB_FATSz32
;
306 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_FATSz16, BPB_FATSz32 - 0, expected: Non-Zero Value");
307 return FatTypeUnknown
;
310 if (FatBpb
->Fat12_16
.BPB_TotSec16
!= 0) {
311 TotSec
= FatBpb
->Fat12_16
.BPB_TotSec16
;
313 TotSec
= FatBpb
->Fat12_16
.BPB_TotSec32
;
316 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT - BPB_TotSec16, BPB_TotSec32 - 0, expected: Non-Zero Value");
317 return FatTypeUnknown
;
321 FatBpb
->Fat12_16
.BPB_RsvdSecCnt
+
322 FatBpb
->Fat12_16
.BPB_NumFATs
* FATSz
+
326 CountOfClusters
= DataSec
/ FatBpb
->Fat12_16
.BPB_SecPerClus
;
328 if (CountOfClusters
< FAT_MAX_FAT12_CLUSTER
) {
329 FatType
= FatTypeFat12
;
330 } else if (CountOfClusters
< FAT_MAX_FAT16_CLUSTER
) {
331 FatType
= FatTypeFat16
;
333 FatType
= FatTypeFat32
;
336 // Check according to FAT spec
338 if (((FatType
== FatTypeFat12
) || (FatType
== FatTypeFat16
)) &&
339 (FatBpb
->Fat12_16
.BPB_RsvdSecCnt
!= 1)) {
340 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT12_16 - BPB_RsvdSecCnt - %04x, expected: %04x",
341 FatBpb
->Fat12_16
.BPB_RsvdSecCnt
, 1);
343 if ((FatType
== FatTypeFat32
) &&
344 (FatBpb
->Fat12_16
.BPB_RsvdSecCnt
!= 32)) {
345 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BPB_RsvdSecCnt - %04x, expected: %04x",
346 FatBpb
->Fat12_16
.BPB_RsvdSecCnt
, 32);
348 if ((FatType
== FatTypeFat16
) &&
349 (FatBpb
->Fat12_16
.BPB_RootEntCnt
!= 512)) {
350 printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n",
351 FatBpb
->Fat12_16
.BPB_RootEntCnt
, 512);
353 if ((FatType
== FatTypeFat32
) &&
354 (FatBpb
->Fat12_16
.BPB_RootEntCnt
!= 0)) {
355 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_RootEntCnt - %04x, expected: %04x",
356 FatBpb
->Fat12_16
.BPB_RootEntCnt
, 0);
357 return FatTypeUnknown
;
359 if ((FatType
== FatTypeFat32
) &&
360 (FatBpb
->Fat12_16
.BPB_TotSec16
!= 0)) {
361 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_TotSec16 - %04x, expected: %04x",
362 FatBpb
->Fat12_16
.BPB_TotSec16
, 0);
363 return FatTypeUnknown
;
365 if ((FatType
== FatTypeFat32
) &&
366 (FatBpb
->Fat12_16
.BPB_FATSz16
!= 0)) {
367 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_FATSz16 - %04x, expected: %04x",
368 FatBpb
->Fat12_16
.BPB_FATSz16
, 0);
369 return FatTypeUnknown
;
371 if ((FatType
== FatTypeFat32
) &&
372 (FatBpb
->Fat12_16
.BPB_TotSec32
== 0)) {
373 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_TotSec32 - %04x, expected: Non-Zero",
374 (unsigned) FatBpb
->Fat12_16
.BPB_TotSec32
);
375 return FatTypeUnknown
;
377 if ((FatType
== FatTypeFat32
) &&
378 (FatBpb
->Fat32
.BPB_FATSz32
== 0)) {
379 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_FATSz32 - %08x, expected: Non-Zero",
380 (unsigned) FatBpb
->Fat32
.BPB_FATSz32
);
381 return FatTypeUnknown
;
383 if ((FatType
== FatTypeFat32
) &&
384 (FatBpb
->Fat32
.BPB_FSVer
!= 0)) {
385 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BPB_FSVer - %08x, expected: %04x",
386 FatBpb
->Fat32
.BPB_FSVer
, 0);
388 if ((FatType
== FatTypeFat32
) &&
389 (FatBpb
->Fat32
.BPB_RootClus
!= 2)) {
390 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BPB_RootClus - %08x, expected: %04x",
391 (unsigned) FatBpb
->Fat32
.BPB_RootClus
, 2);
393 if ((FatType
== FatTypeFat32
) &&
394 (FatBpb
->Fat32
.BPB_FSInfo
!= 1)) {
395 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BPB_FSInfo - %08x, expected: %04x",
396 FatBpb
->Fat32
.BPB_FSInfo
, 1);
398 if ((FatType
== FatTypeFat32
) &&
399 (FatBpb
->Fat32
.BPB_BkBootSec
!= 6)) {
400 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BPB_BkBootSec - %08x, expected: %04x",
401 FatBpb
->Fat32
.BPB_BkBootSec
, 6);
403 if ((FatType
== FatTypeFat32
) &&
404 ((*(UINT32
*)FatBpb
->Fat32
.BPB_Reserved
!= 0) ||
405 (*((UINT32
*)FatBpb
->Fat32
.BPB_Reserved
+ 1) != 0) ||
406 (*((UINT32
*)FatBpb
->Fat32
.BPB_Reserved
+ 2) != 0))) {
407 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BPB_Reserved - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x, expected: 0",
408 FatBpb
->Fat32
.BPB_Reserved
[0],
409 FatBpb
->Fat32
.BPB_Reserved
[1],
410 FatBpb
->Fat32
.BPB_Reserved
[2],
411 FatBpb
->Fat32
.BPB_Reserved
[3],
412 FatBpb
->Fat32
.BPB_Reserved
[4],
413 FatBpb
->Fat32
.BPB_Reserved
[5],
414 FatBpb
->Fat32
.BPB_Reserved
[6],
415 FatBpb
->Fat32
.BPB_Reserved
[7],
416 FatBpb
->Fat32
.BPB_Reserved
[8],
417 FatBpb
->Fat32
.BPB_Reserved
[9],
418 FatBpb
->Fat32
.BPB_Reserved
[10],
419 FatBpb
->Fat32
.BPB_Reserved
[11]);
420 return FatTypeUnknown
;
422 if (((FatType
== FatTypeFat12
) || (FatType
== FatTypeFat16
)) &&
423 (FatBpb
->Fat12_16
.BS_Reserved1
!= 0)) {
424 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT12_16 - BS_Reserved1 - %02x, expected: 0\n",
425 FatBpb
->Fat12_16
.BS_Reserved1
);
426 return FatTypeUnknown
;
428 if ((FatType
== FatTypeFat32
) &&
429 (FatBpb
->Fat32
.BS_Reserved1
!= 0)) {
430 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BS_Reserved1 - %02x, expected: 0\n",
431 FatBpb
->Fat32
.BS_Reserved1
);
432 return FatTypeUnknown
;
434 if (((FatType
== FatTypeFat12
) || (FatType
== FatTypeFat16
)) &&
435 (FatBpb
->Fat12_16
.BS_BootSig
!= FAT_BS_BOOTSIG
)) {
436 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT12_16 - BS_BootSig - %02x, expected: %02x\n",
437 FatBpb
->Fat12_16
.BS_BootSig
, FAT_BS_BOOTSIG
);
438 return FatTypeUnknown
;
440 if ((FatType
== FatTypeFat32
) &&
441 (FatBpb
->Fat32
.BS_BootSig
!= FAT_BS_BOOTSIG
)) {
442 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3003: FAT32 - BS_BootSig - %02x, expected: %02x\n",
443 FatBpb
->Fat32
.BS_BootSig
, FAT_BS_BOOTSIG
);
444 return FatTypeUnknown
;
447 if ((FatType
== FatTypeFat12
) || (FatType
== FatTypeFat16
)) {
448 memcpy (FilSysType
, FatBpb
->Fat12_16
.BS_FilSysType
, 8);
450 if ((FatType
== FatTypeFat12
) &&
451 (strcmp (FilSysType
, FAT12_FILSYSTYPE
) != 0) &&
452 (strcmp (FilSysType
, FAT_FILSYSTYPE
) != 0)) {
453 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT12 - BS_FilSysType - %s, expected: %s, or %s\n",
454 FilSysType
, FAT12_FILSYSTYPE
, FAT_FILSYSTYPE
);
456 if ((FatType
== FatTypeFat16
) &&
457 (strcmp (FilSysType
, FAT16_FILSYSTYPE
) != 0) &&
458 (strcmp (FilSysType
, FAT_FILSYSTYPE
) != 0)) {
459 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT16 - BS_FilSysType - %s, expected: %s, or %s\n",
460 FilSysType
, FAT16_FILSYSTYPE
, FAT_FILSYSTYPE
);
463 if (FatType
== FatTypeFat32
) {
464 memcpy (FilSysType
, FatBpb
->Fat32
.BS_FilSysType
, 8);
466 if (strcmp (FilSysType
, FAT32_FILSYSTYPE
) != 0) {
467 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3003: FAT32 - BS_FilSysType - %s, expected: %s\n",
468 FilSysType
, FAT32_FILSYSTYPE
);
473 // pass all check, get FAT type
484 FAT_BPB_STRUCT FatBpb
;
487 if (ReadFromFile ((void *)&FatBpb
, FileName
) == 0) {
491 FatType
= GetFatType (&FatBpb
);
492 if (FatType
<= FatTypeUnknown
|| FatType
>= FatTypeMax
) {
493 printf ("ERROR: E3002: Unknown FAT Type!\n");
497 printf ("\nBoot Sector %s:\n", FatTypeToString (FatType
));
499 printf (" Offset Title Data\n");
500 printf ("==================================================================\n");
501 printf (" 0 JMP instruction %02x %02x %02x\n",
502 FatBpb
.Fat12_16
.BS_jmpBoot
[0],
503 FatBpb
.Fat12_16
.BS_jmpBoot
[1],
504 FatBpb
.Fat12_16
.BS_jmpBoot
[2]);
505 printf (" 3 OEM %c%c%c%c%c%c%c%c\n",
506 FatBpb
.Fat12_16
.BS_OEMName
[0],
507 FatBpb
.Fat12_16
.BS_OEMName
[1],
508 FatBpb
.Fat12_16
.BS_OEMName
[2],
509 FatBpb
.Fat12_16
.BS_OEMName
[3],
510 FatBpb
.Fat12_16
.BS_OEMName
[4],
511 FatBpb
.Fat12_16
.BS_OEMName
[5],
512 FatBpb
.Fat12_16
.BS_OEMName
[6],
513 FatBpb
.Fat12_16
.BS_OEMName
[7]);
515 printf ("BIOS Parameter Block\n");
516 printf (" B Bytes per sector %04x\n", FatBpb
.Fat12_16
.BPB_BytsPerSec
);
517 printf (" D Sectors per cluster %02x\n", FatBpb
.Fat12_16
.BPB_SecPerClus
);
518 printf (" E Reserved sectors %04x\n", FatBpb
.Fat12_16
.BPB_RsvdSecCnt
);
519 printf (" 10 Number of FATs %02x\n", FatBpb
.Fat12_16
.BPB_NumFATs
);
520 printf (" 11 Root entries %04x\n", FatBpb
.Fat12_16
.BPB_RootEntCnt
);
521 printf (" 13 Sectors (under 32MB) %04x\n", FatBpb
.Fat12_16
.BPB_TotSec16
);
522 printf (" 15 Media descriptor %02x\n", FatBpb
.Fat12_16
.BPB_Media
);
523 printf (" 16 Sectors per FAT (small vol.) %04x\n", FatBpb
.Fat12_16
.BPB_FATSz16
);
524 printf (" 18 Sectors per track %04x\n", FatBpb
.Fat12_16
.BPB_SecPerTrk
);
525 printf (" 1A Heads %04x\n", FatBpb
.Fat12_16
.BPB_NumHeads
);
526 printf (" 1C Hidden sectors %08x\n", (unsigned) FatBpb
.Fat12_16
.BPB_HiddSec
);
527 printf (" 20 Sectors (over 32MB) %08x\n", (unsigned) FatBpb
.Fat12_16
.BPB_TotSec32
);
529 if (FatType
!= FatTypeFat32
) {
530 printf (" 24 BIOS drive %02x\n", FatBpb
.Fat12_16
.BS_DrvNum
);
531 printf (" 25 (Unused) %02x\n", FatBpb
.Fat12_16
.BS_Reserved1
);
532 printf (" 26 Ext. boot signature %02x\n", FatBpb
.Fat12_16
.BS_BootSig
);
533 printf (" 27 Volume serial number %08x\n", (unsigned) FatBpb
.Fat12_16
.BS_VolID
);
534 printf (" 2B Volume lable %c%c%c%c%c%c%c%c%c%c%c\n",
535 FatBpb
.Fat12_16
.BS_VolLab
[0],
536 FatBpb
.Fat12_16
.BS_VolLab
[1],
537 FatBpb
.Fat12_16
.BS_VolLab
[2],
538 FatBpb
.Fat12_16
.BS_VolLab
[3],
539 FatBpb
.Fat12_16
.BS_VolLab
[4],
540 FatBpb
.Fat12_16
.BS_VolLab
[5],
541 FatBpb
.Fat12_16
.BS_VolLab
[6],
542 FatBpb
.Fat12_16
.BS_VolLab
[7],
543 FatBpb
.Fat12_16
.BS_VolLab
[8],
544 FatBpb
.Fat12_16
.BS_VolLab
[9],
545 FatBpb
.Fat12_16
.BS_VolLab
[10]);
546 printf (" 36 File system %c%c%c%c%c%c%c%c\n",
547 FatBpb
.Fat12_16
.BS_FilSysType
[0],
548 FatBpb
.Fat12_16
.BS_FilSysType
[1],
549 FatBpb
.Fat12_16
.BS_FilSysType
[2],
550 FatBpb
.Fat12_16
.BS_FilSysType
[3],
551 FatBpb
.Fat12_16
.BS_FilSysType
[4],
552 FatBpb
.Fat12_16
.BS_FilSysType
[5],
553 FatBpb
.Fat12_16
.BS_FilSysType
[6],
554 FatBpb
.Fat12_16
.BS_FilSysType
[7]);
557 printf ("FAT32 Section\n");
558 printf (" 24 Sectors per FAT (large vol.) %08x\n", (unsigned) FatBpb
.Fat32
.BPB_FATSz32
);
559 printf (" 28 Flags %04x\n", FatBpb
.Fat32
.BPB_ExtFlags
);
560 printf (" 2A Version %04x\n", FatBpb
.Fat32
.BPB_FSVer
);
561 printf (" 2C Root dir 1st cluster %08x\n", (unsigned) FatBpb
.Fat32
.BPB_RootClus
);
562 printf (" 30 FSInfo sector %04x\n", FatBpb
.Fat32
.BPB_FSInfo
);
563 printf (" 32 Backup boot sector %04x\n", FatBpb
.Fat32
.BPB_BkBootSec
);
564 printf (" 34 (Reserved) %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
565 FatBpb
.Fat32
.BPB_Reserved
[0],
566 FatBpb
.Fat32
.BPB_Reserved
[1],
567 FatBpb
.Fat32
.BPB_Reserved
[2],
568 FatBpb
.Fat32
.BPB_Reserved
[3],
569 FatBpb
.Fat32
.BPB_Reserved
[4],
570 FatBpb
.Fat32
.BPB_Reserved
[5],
571 FatBpb
.Fat32
.BPB_Reserved
[6],
572 FatBpb
.Fat32
.BPB_Reserved
[7],
573 FatBpb
.Fat32
.BPB_Reserved
[8],
574 FatBpb
.Fat32
.BPB_Reserved
[9],
575 FatBpb
.Fat32
.BPB_Reserved
[10],
576 FatBpb
.Fat32
.BPB_Reserved
[11]);
578 printf (" 40 BIOS drive %02x\n", FatBpb
.Fat32
.BS_DrvNum
);
579 printf (" 41 (Unused) %02x\n", FatBpb
.Fat32
.BS_Reserved1
);
580 printf (" 42 Ext. boot signature %02x\n", FatBpb
.Fat32
.BS_BootSig
);
581 printf (" 43 Volume serial number %08x\n", (unsigned) FatBpb
.Fat32
.BS_VolID
);
582 printf (" 47 Volume lable %c%c%c%c%c%c%c%c%c%c%c\n",
583 FatBpb
.Fat32
.BS_VolLab
[0],
584 FatBpb
.Fat32
.BS_VolLab
[1],
585 FatBpb
.Fat32
.BS_VolLab
[2],
586 FatBpb
.Fat32
.BS_VolLab
[3],
587 FatBpb
.Fat32
.BS_VolLab
[4],
588 FatBpb
.Fat32
.BS_VolLab
[5],
589 FatBpb
.Fat32
.BS_VolLab
[6],
590 FatBpb
.Fat32
.BS_VolLab
[7],
591 FatBpb
.Fat32
.BS_VolLab
[8],
592 FatBpb
.Fat32
.BS_VolLab
[9],
593 FatBpb
.Fat32
.BS_VolLab
[10]);
594 printf (" 52 File system %c%c%c%c%c%c%c%c\n",
595 FatBpb
.Fat32
.BS_FilSysType
[0],
596 FatBpb
.Fat32
.BS_FilSysType
[1],
597 FatBpb
.Fat32
.BS_FilSysType
[2],
598 FatBpb
.Fat32
.BS_FilSysType
[3],
599 FatBpb
.Fat32
.BS_FilSysType
[4],
600 FatBpb
.Fat32
.BS_FilSysType
[5],
601 FatBpb
.Fat32
.BS_FilSysType
[6],
602 FatBpb
.Fat32
.BS_FilSysType
[7]);
605 printf (" 1FE Signature %04x\n", FatBpb
.Fat12_16
.Signature
);
615 char *SourceFileName
,
620 Patch destination file according to the information from source file.
621 Only patch BPB data but leave boot code un-touched.
624 DestFileName - Destination file to patch
625 SourceFileName - Source file where patch from
628 FAT_BPB_STRUCT DestFatBpb
;
629 FAT_BPB_STRUCT SourceFatBpb
;
630 FAT_TYPE DestFatType
;
631 FAT_TYPE SourceFatType
;
635 if (ReadFromFile ((void *)&DestFatBpb
, DestFileName
) == 0) {
638 if (ReadFromFile ((void *)&SourceFatBpb
, SourceFileName
) == 0) {
642 DestFatType
= GetFatType (&DestFatBpb
);
643 SourceFatType
= GetFatType (&SourceFatBpb
);
645 if (DestFatType
!= SourceFatType
) {
650 DebugMsg (NULL
, 0, DEBUG_WARN
, NULL
, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
651 FatTypeToString(SourceFatType
), FatTypeToString(DestFatType
));
653 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
654 FatTypeToString(SourceFatType
), FatTypeToString(DestFatType
));
659 if (SourceFatType
<= FatTypeUnknown
|| SourceFatType
>= FatTypeMax
) {
660 DebugMsg (NULL
, 0, DEBUG_ERROR
, NULL
, "ERROR: E3002: Unknown FAT Type!\n");
665 // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb
667 printf ("Patching %s BPB: ", FatTypeToString (SourceFatType
));
668 if (SourceFatType
!= FatTypeFat32
) {
670 &DestFatBpb
.Fat12_16
.BPB_BytsPerSec
,
671 &SourceFatBpb
.Fat12_16
.BPB_BytsPerSec
,
672 ((UINTN
)&DestFatBpb
.Fat12_16
.Reserved
- (UINTN
)&DestFatBpb
.Fat12_16
.BPB_BytsPerSec
)
676 &DestFatBpb
.Fat32
.BPB_BytsPerSec
,
677 &SourceFatBpb
.Fat32
.BPB_BytsPerSec
,
678 ((UINTN
)&DestFatBpb
.Fat32
.Reserved
- (UINTN
)&DestFatBpb
.Fat32
.BPB_BytsPerSec
)
683 // Set BS_VolLab and BS_FilSysType of DestFatBpb
685 // BS_VolLab BS_FilSysType
686 // FAT12: EFI FAT12 FAT12
687 // FAT16: EFI FAT16 FAT16
688 // FAT32: EFI FAT32 FAT32
690 if (SourceFatType
== FatTypeFat32
) {
691 memcpy (VolLab
, "EFI FAT32 ", sizeof(VolLab
));
692 memcpy (FilSysType
, FAT32_FILSYSTYPE
, sizeof(FilSysType
));
693 } else if (SourceFatType
== FatTypeFat16
) {
694 memcpy (VolLab
, "EFI FAT16 ", sizeof(VolLab
));
695 memcpy (FilSysType
, FAT16_FILSYSTYPE
, sizeof(FilSysType
));
697 memcpy (VolLab
, "EFI FAT12 ", sizeof(VolLab
));
698 memcpy (FilSysType
, FAT12_FILSYSTYPE
, sizeof(FilSysType
));
700 if (SourceFatType
!= FatTypeFat32
) {
701 memcpy (DestFatBpb
.Fat12_16
.BS_VolLab
, VolLab
, sizeof(VolLab
));
702 memcpy (DestFatBpb
.Fat12_16
.BS_FilSysType
, FilSysType
, sizeof(FilSysType
));
704 memcpy (DestFatBpb
.Fat32
.BS_VolLab
, VolLab
, sizeof(VolLab
));
705 memcpy (DestFatBpb
.Fat32
.BS_FilSysType
, FilSysType
, sizeof(FilSysType
));
709 // Set Signature of DestFatBpb to 55AA
711 DestFatBpb
.Fat12_16
.Signature
= FAT_BS_SIGNATURE
;
716 if (WriteToFile ((void *)&DestFatBpb
, DestFileName
)) {
717 printf ("successful!\n");
719 printf ("failed!\n");
730 MASTER_BOOT_RECORD Mbr
;
732 if (ReadFromFile ((void *)&Mbr
, FileName
) == 0) {
736 printf ("\nMaster Boot Record:\n");
738 printf (" Offset Title Value\n");
739 printf ("==================================================================\n");
740 printf (" 0 Master bootstrap loader code (not list)\n");
741 printf (" 1B8 Windows disk signature %08x\n", (unsigned) Mbr
.UniqueMbrSignature
);
743 printf ("Partition Table Entry #1\n");
744 printf (" 1BE 80 = active partition %02x\n", Mbr
.PartitionRecord
[0].BootIndicator
);
745 printf (" 1BF Start head %02x\n", Mbr
.PartitionRecord
[0].StartHead
);
746 printf (" 1C0 Start sector %02x\n", Mbr
.PartitionRecord
[0].StartSector
);
747 printf (" 1C1 Start cylinder %02x\n", Mbr
.PartitionRecord
[0].StartTrack
);
748 printf (" 1C2 Partition type indicator %02x\n", Mbr
.PartitionRecord
[0].OSType
);
749 printf (" 1C3 End head %02x\n", Mbr
.PartitionRecord
[0].EndHead
);
750 printf (" 1C4 End sector %02x\n", Mbr
.PartitionRecord
[0].EndSector
);
751 printf (" 1C5 End cylinder %02x\n", Mbr
.PartitionRecord
[0].EndTrack
);
752 printf (" 1C6 Sectors preceding partition %08x\n", (unsigned) Mbr
.PartitionRecord
[0].StartingLBA
);
753 printf (" 1CA Sectors in partition %08x\n", (unsigned) Mbr
.PartitionRecord
[0].SizeInLBA
);
755 printf ("Partition Table Entry #2\n");
756 printf (" 1CE 80 = active partition %02x\n", Mbr
.PartitionRecord
[1].BootIndicator
);
757 printf (" 1CF Start head %02x\n", Mbr
.PartitionRecord
[1].StartHead
);
758 printf (" 1D0 Start sector %02x\n", Mbr
.PartitionRecord
[1].StartSector
);
759 printf (" 1D1 Start cylinder %02x\n", Mbr
.PartitionRecord
[1].StartTrack
);
760 printf (" 1D2 Partition type indicator %02x\n", Mbr
.PartitionRecord
[1].OSType
);
761 printf (" 1D3 End head %02x\n", Mbr
.PartitionRecord
[1].EndHead
);
762 printf (" 1D4 End sector %02x\n", Mbr
.PartitionRecord
[1].EndSector
);
763 printf (" 1D5 End cylinder %02x\n", Mbr
.PartitionRecord
[1].EndTrack
);
764 printf (" 1D6 Sectors preceding partition %08x\n", (unsigned) Mbr
.PartitionRecord
[1].StartingLBA
);
765 printf (" 1DA Sectors in partition %08x\n", (unsigned) Mbr
.PartitionRecord
[1].SizeInLBA
);
767 printf ("Partition Table Entry #3\n");
768 printf (" 1DE 80 = active partition %02x\n", Mbr
.PartitionRecord
[2].BootIndicator
);
769 printf (" 1DF Start head %02x\n", Mbr
.PartitionRecord
[2].StartHead
);
770 printf (" 1E0 Start sector %02x\n", Mbr
.PartitionRecord
[2].StartSector
);
771 printf (" 1E1 Start cylinder %02x\n", Mbr
.PartitionRecord
[2].StartTrack
);
772 printf (" 1E2 Partition type indicator %02x\n", Mbr
.PartitionRecord
[2].OSType
);
773 printf (" 1E3 End head %02x\n", Mbr
.PartitionRecord
[2].EndHead
);
774 printf (" 1E4 End sector %02x\n", Mbr
.PartitionRecord
[2].EndSector
);
775 printf (" 1E5 End cylinder %02x\n", Mbr
.PartitionRecord
[2].EndTrack
);
776 printf (" 1E6 Sectors preceding partition %08x\n", (unsigned) Mbr
.PartitionRecord
[2].StartingLBA
);
777 printf (" 1EA Sectors in partition %08x\n", (unsigned) Mbr
.PartitionRecord
[2].SizeInLBA
);
779 printf ("Partition Table Entry #4\n");
780 printf (" 1EE 80 = active partition %02x\n", Mbr
.PartitionRecord
[3].BootIndicator
);
781 printf (" 1EF Start head %02x\n", Mbr
.PartitionRecord
[3].StartHead
);
782 printf (" 1F0 Start sector %02x\n", Mbr
.PartitionRecord
[3].StartSector
);
783 printf (" 1F1 Start cylinder %02x\n", Mbr
.PartitionRecord
[3].StartTrack
);
784 printf (" 1F2 Partition type indicator %02x\n", Mbr
.PartitionRecord
[3].OSType
);
785 printf (" 1F3 End head %02x\n", Mbr
.PartitionRecord
[3].EndHead
);
786 printf (" 1F4 End sector %02x\n", Mbr
.PartitionRecord
[3].EndSector
);
787 printf (" 1F5 End cylinder %02x\n", Mbr
.PartitionRecord
[3].EndTrack
);
788 printf (" 1F6 Sectors preceding partition %08x\n", (unsigned) Mbr
.PartitionRecord
[3].StartingLBA
);
789 printf (" 1FA Sectors in partition %08x\n", (unsigned) Mbr
.PartitionRecord
[3].SizeInLBA
);
791 printf (" 1FE Signature %04x\n", Mbr
.Signature
);
803 MASTER_BOOT_RECORD DestMbr
;
804 MASTER_BOOT_RECORD SourceMbr
;
806 if (ReadFromFile ((void *)&DestMbr
, DestFileName
) == 0) {
809 if (ReadFromFile ((void *)&SourceMbr
, SourceFileName
) == 0) {
813 if (SourceMbr
.Signature
!= MBR_SIGNATURE
) {
814 printf ("ERROR: E3000: Invalid MBR!\n");
818 printf ("Patching MBR:\n");
820 &DestMbr
.PartitionRecord
[0],
821 &SourceMbr
.PartitionRecord
[0],
822 sizeof(DestMbr
.PartitionRecord
)
825 DestMbr
.Signature
= MBR_SIGNATURE
;
828 if (WriteToFile ((void *)&DestMbr
, DestFileName
)) {
829 printf ("\tsuccessful!\n");
844 BOOLEAN ForcePatch
; // -f
845 BOOLEAN ProcessMbr
; // -m
846 BOOLEAN DoParse
; // -p SrcImage or -g SrcImage DstImage
847 BOOLEAN Verbose
; // -v
849 SrcImage
= DstImage
= NULL
;
855 SetUtilityName ("bootsectimage");
865 if (strcmp (*argv
, "-f") == 0 || strcmp (*argv
, "--force") == 0) {
867 } else if (strcmp (*argv
, "-p") == 0 || strcmp (*argv
, "--parse") == 0) {
875 } else if (strcmp (*argv
, "-g") == 0 || strcmp (*argv
, "--patch") == 0) {
885 } else if (strcmp (*argv
, "-m") == 0 || strcmp (*argv
, "--mbr") == 0) {
887 } else if (strcmp (*argv
, "-v") == 0 || strcmp (*argv
, "--verbose") == 0) {
897 if (ForcePatch
&& DoParse
) {
898 printf ("ERROR: E1002: Conflicting options: -f, -p. Cannot apply force(-f) to parse(-p)!\n");
902 if (ForcePatch
&& !DoParse
&& ProcessMbr
) {
903 printf ("ERROR: E1002: Conflicting options: -f, -g -m. Cannot apply force(-f) to processing MBR (-g -m)!\n");
909 SetPrintLevel (VERBOSE_LOG_LEVEL
);
911 SetPrintLevel (KEY_LOG_LEVEL
);
918 ParseBootSector (SrcImage
);
922 PatchMbr (DstImage
, SrcImage
);
924 PatchBootSector (DstImage
, SrcImage
, ForcePatch
);