]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/BootSectImage/bootsectimage.c
d8dc8907a5efb7f700c76281c4f87239bd5a81f3
[mirror_edk2.git] / BaseTools / Source / C / BootSectImage / bootsectimage.c
1 /** @file
2
3 Abstract:
4 Patch the BPB information in boot sector image file.
5 Patch the MBR code in MBR image file.
6
7 Copyright 2006 - 2008, Intel Corporation
8 All rights reserved. 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
12
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.
15
16 **/
17
18 #include <stdio.h>
19 #include <string.h>
20 #include "fat.h"
21 #include "mbr.h"
22 #include "EfiUtilityMsgs.h"
23
24 #define DEBUG_WARN 0x1
25 #define DEBUG_ERROR 0x2
26
27 //
28 // Utility Name
29 //
30 #define UTILITY_NAME "BootSectImage"
31
32 //
33 // Utility version information
34 //
35 #define UTILITY_MAJOR_VERSION 0
36 #define UTILITY_MINOR_VERSION 1
37
38 void
39 Version (
40 void
41 )
42 /*++
43
44 Routine Description:
45
46 Displays the standard utility information to SDTOUT
47
48 Arguments:
49
50 None
51
52 Returns:
53
54 None
55
56 --*/
57 {
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-2007 Intel Corporation. All rights reserved.\n");
60 }
61
62 void
63 Usage (
64 void
65 )
66 /*++
67
68 Routine Description:
69
70 GC_TODO: Add function description
71
72 Arguments:
73
74
75 Returns:
76
77 GC_TODO: add return values
78
79 --*/
80 {
81 Version();
82 printf ("\nUsage: \n\
83 BootSectImage\n\
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\
89 [-v, --verbose]\n\
90 [--version]\n\
91 [-q, --quiet disable all messages except fatal errors]\n\
92 [-d, --debug[#]\n\
93 [-h, --help]\n\
94 [SrcImageFile]\n");
95 }
96
97 int WriteToFile (
98 void *BootSector,
99 char *FileName
100 )
101 /*++
102 Routine Description:
103 Write 512 bytes boot sector to file.
104
105 Arguments:
106 BootSector - point to a buffer containing 512 bytes boot sector to write
107 FileName - file to write to
108
109 Return:
110 int - number of bytes wrote,
111 512 indicates write successful
112 0 indicates write failure
113 --*/
114 {
115 FILE *FileHandle;
116 int result;
117
118 FileHandle = fopen (FileName, "r+b");
119 if (FileHandle == NULL) {
120 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);
121 return 0;
122 }
123 fseek (FileHandle, 0, SEEK_SET);
124
125 result = fwrite (BootSector, 1, 512, FileHandle);
126 if (result != 512) {
127 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName);
128 result = 0;
129 }
130
131 fclose (FileHandle);
132 return result;
133 }
134
135 int ReadFromFile (
136 void *BootSector,
137 char *FileName
138 )
139 /*++
140 Routine Description:
141 Read first 512 bytes from file.
142
143 Arguments:
144 BootSector - point to a buffer receiving the first 512 bytes data from file
145 FileName - file to read from
146
147 Return:
148 int - number of bytes read,
149 512 indicates read successful
150 0 indicates read failure
151 --*/
152 {
153 FILE *FileHandle;
154 int result;
155
156 FileHandle = fopen (FileName, "rb");
157 if (FileHandle == NULL) {
158 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0001: Error opening file: %s", FileName);
159 return 0;
160 }
161
162 result = fread (BootSector, 1, 512, FileHandle);
163 if (result != 512) {
164 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0004: Error reading file: %s", FileName);
165 result = 0;
166 }
167
168 fclose (FileHandle);
169 return result;
170 }
171
172 char *
173 FatTypeToString (
174 IN FAT_TYPE FatType
175 )
176 /*++
177 Routine Description:
178 Convert enum type of FatType to string
179 --*/
180 {
181 switch (FatType) {
182 case FatTypeFat12:
183 return "FAT12";
184 case FatTypeFat16:
185 return "FAT16";
186 case FatTypeFat32:
187 return "FAT32";
188 default:
189 break;
190 }
191 return "FAT Unknown";
192 }
193
194 FAT_TYPE
195 GetFatType (
196 IN FAT_BPB_STRUCT *FatBpb
197 )
198 /*++
199 Routine Description:
200 Determine the FAT type according to BIOS Paramater Block (BPB) data
201
202 Arguments:
203 FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes
204
205 Return:
206 FatTypeUnknown - Cannot determine the FAT type
207 FatTypeFat12 - FAT12
208 FatTypeFat16 - FAT16
209 FatTypeFat32 - FAT32
210 --*/
211 {
212 FAT_TYPE FatType;
213 UINTN RootDirSectors;
214 UINTN FATSz;
215 UINTN TotSec;
216 UINTN DataSec;
217 UINTN CountOfClusters;
218 CHAR8 FilSysType[9];
219
220 FatType = FatTypeUnknown;
221
222 //
223 // Simple check
224 //
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;
229 }
230
231 //
232 // Check according to FAT spec
233 //
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;
239 }
240
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;
248 }
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);
252 }
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;
264 }
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;
269 }
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;
274 }
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);
278 }
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;
291 }
292
293 //
294 // Algo in FAT spec
295 //
296 RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) +
297 (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) /
298 FatBpb->Fat12_16.BPB_BytsPerSec;
299
300 if (FatBpb->Fat12_16.BPB_FATSz16 != 0) {
301 FATSz = FatBpb->Fat12_16.BPB_FATSz16;
302 } else {
303 FATSz = FatBpb->Fat32.BPB_FATSz32;
304 }
305 if (FATSz == 0) {
306 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_FATSz16, BPB_FATSz32 - 0, expected: Non-Zero Value");
307 return FatTypeUnknown;
308 }
309
310 if (FatBpb->Fat12_16.BPB_TotSec16 != 0) {
311 TotSec = FatBpb->Fat12_16.BPB_TotSec16;
312 } else {
313 TotSec = FatBpb->Fat12_16.BPB_TotSec32;
314 }
315 if (TotSec == 0) {
316 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_TotSec16, BPB_TotSec32 - 0, expected: Non-Zero Value");
317 return FatTypeUnknown;
318 }
319
320 DataSec = TotSec - (
321 FatBpb->Fat12_16.BPB_RsvdSecCnt +
322 FatBpb->Fat12_16.BPB_NumFATs * FATSz +
323 RootDirSectors
324 );
325
326 CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus;
327
328 if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) {
329 FatType = FatTypeFat12;
330 } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) {
331 FatType = FatTypeFat16;
332 } else {
333 FatType = FatTypeFat32;
334 }
335 //
336 // Check according to FAT spec
337 //
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);
342 }
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);
347 }
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);
352 }
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;
358 }
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;
364 }
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;
370 }
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;
376 }
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;
382 }
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);
387 }
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);
392 }
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);
397 }
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);
402 }
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;
421 }
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;
427 }
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;
433 }
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;
439 }
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;
445 }
446
447 if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) {
448 memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8);
449 FilSysType[8] = 0;
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);
455 }
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);
461 }
462 }
463 if (FatType == FatTypeFat32) {
464 memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8);
465 FilSysType[8] = 0;
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);
469 }
470 }
471
472 //
473 // pass all check, get FAT type
474 //
475 return FatType;
476 }
477
478
479 void
480 ParseBootSector (
481 char *FileName
482 )
483 {
484 FAT_BPB_STRUCT FatBpb;
485 FAT_TYPE FatType;
486
487 if (ReadFromFile ((void *)&FatBpb, FileName) == 0) {
488 return ;
489 }
490
491 FatType = GetFatType (&FatBpb);
492 if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) {
493 printf ("ERROR: E3002: Unknown FAT Type!\n");
494 return;
495 }
496
497 printf ("\nBoot Sector %s:\n", FatTypeToString (FatType));
498 printf ("\n");
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]);
514 printf ("\n");
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);
528 printf ("\n");
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]);
555 printf ("\n");
556 } else {
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]);
577 printf ("\n");
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]);
603 printf ("\n");
604 }
605 printf (" 1FE Signature %04x\n", FatBpb.Fat12_16.Signature);
606 printf ("\n");
607
608
609 return ;
610 }
611
612 void
613 PatchBootSector (
614 char *DestFileName,
615 char *SourceFileName,
616 BOOLEAN ForcePatch
617 )
618 /*++
619 Routine Description:
620 Patch destination file according to the information from source file.
621 Only patch BPB data but leave boot code un-touched.
622
623 Arguments:
624 DestFileName - Destination file to patch
625 SourceFileName - Source file where patch from
626 --*/
627 {
628 FAT_BPB_STRUCT DestFatBpb;
629 FAT_BPB_STRUCT SourceFatBpb;
630 FAT_TYPE DestFatType;
631 FAT_TYPE SourceFatType;
632 CHAR8 VolLab[11];
633 CHAR8 FilSysType[8];
634
635 if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) {
636 return ;
637 }
638 if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) {
639 return ;
640 }
641
642 DestFatType = GetFatType (&DestFatBpb);
643 SourceFatType = GetFatType (&SourceFatBpb);
644
645 if (DestFatType != SourceFatType) {
646 //
647 // FAT type mismatch
648 //
649 if (ForcePatch) {
650 DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
651 FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
652 } else {
653 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
654 FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
655 return ;
656 }
657 }
658
659 if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) {
660 DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3002: Unknown FAT Type!\n");
661 return;
662 }
663
664 //
665 // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb
666 //
667 printf ("Patching %s BPB: ", FatTypeToString (SourceFatType));
668 if (SourceFatType != FatTypeFat32) {
669 memcpy (
670 &DestFatBpb.Fat12_16.BPB_BytsPerSec,
671 &SourceFatBpb.Fat12_16.BPB_BytsPerSec,
672 ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec)
673 );
674 } else {
675 memcpy (
676 &DestFatBpb.Fat32.BPB_BytsPerSec,
677 &SourceFatBpb.Fat32.BPB_BytsPerSec,
678 ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec)
679 );
680 }
681
682 //
683 // Set BS_VolLab and BS_FilSysType of DestFatBpb
684 //
685 // BS_VolLab BS_FilSysType
686 // FAT12: EFI FAT12 FAT12
687 // FAT16: EFI FAT16 FAT16
688 // FAT32: EFI FAT32 FAT32
689 //
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));
696 } else {
697 memcpy (VolLab, "EFI FAT12 ", sizeof(VolLab));
698 memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType));
699 }
700 if (SourceFatType != FatTypeFat32) {
701 memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab));
702 memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType));
703 } else {
704 memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab));
705 memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType));
706 }
707
708 //
709 // Set Signature of DestFatBpb to 55AA
710 //
711 DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE;
712
713 //
714 // Write DestFatBpb
715 //
716 if (WriteToFile ((void *)&DestFatBpb, DestFileName)) {
717 printf ("successful!\n");
718 } else {
719 printf ("failed!\n");
720 }
721
722 return ;
723 }
724
725 void
726 ParseMbr (
727 char *FileName
728 )
729 {
730 MASTER_BOOT_RECORD Mbr;
731
732 if (ReadFromFile ((void *)&Mbr, FileName) == 0) {
733 return ;
734 }
735
736 printf ("\nMaster Boot Record:\n");
737 printf ("\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);
742 printf ("\n");
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);
754 printf ("\n");
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);
766 printf ("\n");
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);
778 printf ("\n");
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);
790 printf ("\n");
791 printf (" 1FE Signature %04x\n", Mbr.Signature);
792 printf ("\n");
793
794 return ;
795 }
796
797 void
798 PatchMbr (
799 char *DestFileName,
800 char *SourceFileName
801 )
802 {
803 MASTER_BOOT_RECORD DestMbr;
804 MASTER_BOOT_RECORD SourceMbr;
805
806 if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) {
807 return ;
808 }
809 if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) {
810 return ;
811 }
812
813 if (SourceMbr.Signature != MBR_SIGNATURE) {
814 printf ("ERROR: E3000: Invalid MBR!\n");
815 return;
816 }
817
818 printf ("Patching MBR:\n");
819 memcpy (
820 &DestMbr.PartitionRecord[0],
821 &SourceMbr.PartitionRecord[0],
822 sizeof(DestMbr.PartitionRecord)
823 );
824
825 DestMbr.Signature = MBR_SIGNATURE;
826
827
828 if (WriteToFile ((void *)&DestMbr, DestFileName)) {
829 printf ("\tsuccessful!\n");
830 }
831
832 return ;
833 }
834
835
836 int
837 main (
838 int argc,
839 char *argv[]
840 )
841 {
842 char *SrcImage;
843 char *DstImage;
844 BOOLEAN ForcePatch; // -f
845 BOOLEAN ProcessMbr; // -m
846 BOOLEAN DoParse; // -p SrcImage or -g SrcImage DstImage
847 BOOLEAN Verbose; // -v
848
849 SrcImage = DstImage = NULL;
850 ForcePatch = FALSE;
851 ProcessMbr = FALSE;
852 DoParse = TRUE;
853 Verbose = FALSE;
854
855 SetUtilityName ("bootsectimage");
856
857 argc--; argv++;
858
859 if (argc == 0) {
860 Usage ();
861 return -1;
862 }
863
864 while (argc != 0) {
865 if (strcmp (*argv, "-f") == 0 || strcmp (*argv, "--force") == 0) {
866 ForcePatch = TRUE;
867 } else if (strcmp (*argv, "-p") == 0 || strcmp (*argv, "--parse") == 0) {
868 DoParse = TRUE;
869 argc--; argv++;
870 if (argc < 1) {
871 Usage ();
872 return -1;
873 }
874 SrcImage = *argv;
875 } else if (strcmp (*argv, "-g") == 0 || strcmp (*argv, "--patch") == 0) {
876 DoParse = FALSE;
877 argc--; argv++;
878 if (argc < 2) {
879 Usage ();
880 return -1;
881 }
882 SrcImage = *argv;
883 argc--; argv++;
884 DstImage = *argv;
885 } else if (strcmp (*argv, "-m") == 0 || strcmp (*argv, "--mbr") == 0) {
886 ProcessMbr = TRUE;
887 } else if (strcmp (*argv, "-v") == 0 || strcmp (*argv, "--verbose") == 0) {
888 Verbose = TRUE;
889 } else {
890 Usage ();
891 return -1;
892 }
893
894 argc--; argv++;
895 }
896
897 if (ForcePatch && DoParse) {
898 printf ("ERROR: E1002: Conflicting options: -f, -p. Cannot apply force(-f) to parse(-p)!\n");
899 Usage ();
900 return -1;
901 }
902 if (ForcePatch && !DoParse && ProcessMbr) {
903 printf ("ERROR: E1002: Conflicting options: -f, -g -m. Cannot apply force(-f) to processing MBR (-g -m)!\n");
904 Usage ();
905 return -1;
906 }
907
908 if (Verbose) {
909 SetPrintLevel (VERBOSE_LOG_LEVEL);
910 } else {
911 SetPrintLevel (KEY_LOG_LEVEL);
912 }
913
914 if (DoParse) {
915 if (ProcessMbr) {
916 ParseMbr (SrcImage);
917 } else {
918 ParseBootSector (SrcImage);
919 }
920 } else {
921 if (ProcessMbr) {
922 PatchMbr (DstImage, SrcImage);
923 } else {
924 PatchBootSector (DstImage, SrcImage, ForcePatch);
925 }
926 }
927
928 return 0;
929 }
930