2 Reading/writing MBR/DBR.
4 If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.
5 If we process DBR, we will patch MBR to set first partition active if no active partition exists.
7 Copyright (c) 2006 - 2014, 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.
18 #include "CommonLib.h"
22 #include <Common/UefiBaseTypes.h>
25 #include "EfiUtilityMsgs.h"
30 #define UTILITY_NAME "GnuGenBootSector"
33 // Utility version information
35 #define UTILITY_MAJOR_VERSION 0
36 #define UTILITY_MINOR_VERSION 1
39 #define PARTITION_TABLE_OFFSET 0x1BE
41 #define SIZE_OF_PARTITION_ENTRY 0x10
43 #define PARTITION_ENTRY_STARTLBA_OFFSET 8
45 #define PARTITION_ENTRY_NUM 4
47 #define DRIVE_UNKNOWN 0
48 #define DRIVE_NO_ROOT_DIR 1
49 #define DRIVE_REMOVABLE 2
51 #define DRIVE_REMOTE 4
53 #define DRIVE_RAMDISK 6
55 typedef struct _DRIVE_TYPE_DESC
{
60 #define DRIVE_TYPE_ITEM(x) {x, #x}
62 DRIVE_TYPE_DESC DriveTypeDesc
[] = {
63 DRIVE_TYPE_ITEM (DRIVE_UNKNOWN
),
64 DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR
),
65 DRIVE_TYPE_ITEM (DRIVE_REMOVABLE
),
66 DRIVE_TYPE_ITEM (DRIVE_FIXED
),
67 DRIVE_TYPE_ITEM (DRIVE_REMOTE
),
68 DRIVE_TYPE_ITEM (DRIVE_CDROM
),
69 DRIVE_TYPE_ITEM (DRIVE_RAMDISK
),
73 typedef struct _DRIVE_INFO
{
75 DRIVE_TYPE_DESC
*DriveType
;
87 typedef struct _PATH_INFO
{
89 CHAR8 PhysicalPath
[260];
103 CHAR8
*ErrorStatusDesc
[] = {
105 "Failed to create files",
106 "Failed to read/write files",
108 "Failed to detect Fat type",
113 //UnSupported Windows API functions.
114 UINTN
GetLogicalDrives(void) { return 1; }
119 Get path information, including physical path for Linux platform.
121 @param PathInfo Point to PATH_INFO structure.
123 @return whether path is valid.
132 if (strncmp(PathInfo
->Path
, "/dev/", 5) == 0) {
134 // Process disk path here.
137 // Process floppy disk
138 if (PathInfo
->Path
[5] == 'f' && PathInfo
->Path
[6] == 'd' && PathInfo
->Path
[8] == '\0') {
139 PathInfo
->Type
= PathFloppy
;
140 strcpy (PathInfo
->PhysicalPath
, PathInfo
->Path
);
144 // Other disk types is not supported yet.
145 fprintf (stderr
, "ERROR: It's not a floppy disk!\n");
149 // Try to open the device.
150 f
= fopen (LongFilePath (PathInfo
->Path
),"r");
152 printf ("error :open device failed!\n");
159 // Process file path here.
160 PathInfo
->Type
= PathFile
;
161 if (PathInfo
->Input
) {
162 // If path is file path, check whether file is valid.
163 printf("Path = %s\n",PathInfo
->Path
);
164 f
= fopen (LongFilePath (PathInfo
->Path
), "r");
166 fprintf (stderr
, "Test error E2003: File was not provided!\n");
172 strcpy(PathInfo
->PhysicalPath
, PathInfo
->Path
);
182 printf("-l or -list not supported!\n");
186 Writing or reading boot sector or MBR according to the argument.
188 @param InputInfo PATH_INFO instance for input path
189 @param OutputInfo PATH_INFO instance for output path
190 @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector
196 PATH_INFO
*InputInfo
,
197 PATH_INFO
*OutputInfo
,
201 CHAR8 FirstSector
[0x200] = {0};
202 CHAR8 FirstSectorBackup
[0x200] = {0};
208 InputFile
= fopen (LongFilePath (InputInfo
->PhysicalPath
), "r");
209 if (InputFile
== NULL
) {
210 return ErrorFileReadWrite
;
213 if (0x200 != fread(FirstSector
, 1, 0x200, InputFile
)) {
215 return ErrorFileReadWrite
;
220 //Not support USB and IDE.
221 if (InputInfo
->Type
== PathUsb
) {
222 printf("USB has not been supported yet!");
226 if (InputInfo
->Type
== PathIde
) {
227 printf("IDE has not been supported yet!");
231 //Process Floppy Disk
232 OutputFile
= fopen (LongFilePath (OutputInfo
->PhysicalPath
), "r+");
233 if (OutputFile
== NULL
) {
234 OutputFile
= fopen (LongFilePath (OutputInfo
->PhysicalPath
), "w");
235 if (OutputFile
== NULL
) {
236 return ErrorFileReadWrite
;
240 if (OutputInfo
->Type
!= PathFile
) {
243 // Use original partition table
245 if (0x200 != fread (FirstSectorBackup
, 1, 0x200, OutputFile
)) {
247 return ErrorFileReadWrite
;
249 memcpy (FirstSector
+ 0x1BE, FirstSectorBackup
+ 0x1BE, 0x40);
252 if(0x200 != fwrite(FirstSector
, 1, 0x200, OutputFile
)) {
254 return ErrorFileReadWrite
;
264 Displays the standard utility information to SDTOUT
272 printf ("%s v%d.%d %s-Utility to retrieve and update the boot sector or MBR.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
273 printf ("Copyright (c) 2007-2014 Intel Corporation. All rights reserved.\n");
283 printf ("\nUsage: \n\
285 [-l, --list list disks]\n\
286 [-i, --input Filename]\n\
287 [-o, --output Filename]\n\
288 [-m, --mbr process the MBR also]\n\
291 [-q, --quiet disable all messages except fatal errors]\n\
305 EFI_STATUS EfiStatus
;
306 PATH_INFO InputPathInfo
;
307 PATH_INFO OutputPathInfo
;
310 SetUtilityName (UTILITY_NAME
);
312 ZeroMem(&InputPathInfo
, sizeof(PATH_INFO
));
313 ZeroMem(&OutputPathInfo
, sizeof(PATH_INFO
));
326 // Parse command line
328 for (Index
= 0; Index
< argc
; Index
++) {
329 if ((stricmp (argv
[Index
], "-l") == 0) || (stricmp (argv
[Index
], "--list") == 0)) {
334 if ((stricmp (argv
[Index
], "-m") == 0) || (stricmp (argv
[Index
], "--mbr") == 0)) {
339 if ((stricmp (argv
[Index
], "-i") == 0) || (stricmp (argv
[Index
], "--input") == 0)) {
340 InputPathInfo
.Path
= argv
[Index
+ 1];
341 InputPathInfo
.Input
= TRUE
;
342 if (InputPathInfo
.Path
== NULL
) {
343 Error (NULL
, 0, 1003, "Invalid option value", "Input file name can't be NULL");
346 if (InputPathInfo
.Path
[0] == '-') {
347 Error (NULL
, 0, 1003, "Invalid option value", "Input file is missing");
354 if ((stricmp (argv
[Index
], "-o") == 0) || (stricmp (argv
[Index
], "--output") == 0)) {
355 OutputPathInfo
.Path
= argv
[Index
+ 1];
356 OutputPathInfo
.Input
= FALSE
;
357 if (OutputPathInfo
.Path
== NULL
) {
358 Error (NULL
, 0, 1003, "Invalid option value", "Output file name can't be NULL");
361 if (OutputPathInfo
.Path
[0] == '-') {
362 Error (NULL
, 0, 1003, "Invalid option value", "Output file is missing");
369 if ((stricmp (argv
[Index
], "-h") == 0) || (stricmp (argv
[Index
], "--help") == 0)) {
374 if (stricmp (argv
[Index
], "--version") == 0) {
379 if ((stricmp (argv
[Index
], "-v") == 0) || (stricmp (argv
[Index
], "--verbose") == 0)) {
383 if ((stricmp (argv
[Index
], "-q") == 0) || (stricmp (argv
[Index
], "--quiet") == 0)) {
387 if ((stricmp (argv
[Index
], "-d") == 0) || (stricmp (argv
[Index
], "--debug") == 0)) {
388 EfiStatus
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &LogLevel
);
389 if (EFI_ERROR (EfiStatus
)) {
390 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[Index
], argv
[Index
+ 1]);
394 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel
);
397 SetPrintLevel (LogLevel
);
398 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[Index
+ 1]);
404 // Don't recognize the parameter.
406 Error (NULL
, 0, 1000, "Unknown option", "%s", argv
[Index
]);
410 if (InputPathInfo
.Path
== NULL
) {
411 Error (NULL
, 0, 1001, "Missing options", "Input file is missing");
415 if (OutputPathInfo
.Path
== NULL
) {
416 Error (NULL
, 0, 1001, "Missing options", "Output file is missing");
420 if (GetPathInfo(&InputPathInfo
) != ErrorSuccess
) {
421 Error (NULL
, 0, 1003, "Invalid option value", "Input file can't be found.");
425 if (GetPathInfo(&OutputPathInfo
) != ErrorSuccess
) {
426 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be found.");
431 // Process DBR (Patch or Read)
433 Status
= ProcessBsOrMbr (&InputPathInfo
, &OutputPathInfo
, ProcessMbr
);
435 if (Status
== ErrorSuccess
) {
438 "%s %s: successful!\n",
439 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
440 ProcessMbr
? "MBR" : "DBR"
446 "%s: %s %s: failed - %s (LastError: 0x%x)!\n",
447 (Status
== ErrorNoMbr
) ? "WARNING" : "ERROR",
448 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
449 ProcessMbr
? "MBR" : "DBR",
450 ErrorStatusDesc
[Status
],