3 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 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
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.
17 Reading/writing MBR/DBR.
19 If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.
20 If we process DBR, we will patch MBR to set first partition active if no active partition exists.
24 #include "CommonLib.h"
28 #include <Common/UefiBaseTypes.h>
31 #include "EfiUtilityMsgs.h"
36 #define UTILITY_NAME "GnuGenBootSector"
39 // Utility version information
41 #define UTILITY_MAJOR_VERSION 0
42 #define UTILITY_MINOR_VERSION 1
45 #define PARTITION_TABLE_OFFSET 0x1BE
47 #define SIZE_OF_PARTITION_ENTRY 0x10
49 #define PARTITION_ENTRY_STARTLBA_OFFSET 8
51 #define PARTITION_ENTRY_NUM 4
53 #define DRIVE_UNKNOWN 0
54 #define DRIVE_NO_ROOT_DIR 1
55 #define DRIVE_REMOVABLE 2
57 #define DRIVE_REMOTE 4
59 #define DRIVE_RAMDISK 6
61 typedef struct _DRIVE_TYPE_DESC
{
66 #define DRIVE_TYPE_ITEM(x) {x, #x}
68 DRIVE_TYPE_DESC DriveTypeDesc
[] = {
69 DRIVE_TYPE_ITEM (DRIVE_UNKNOWN
),
70 DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR
),
71 DRIVE_TYPE_ITEM (DRIVE_REMOVABLE
),
72 DRIVE_TYPE_ITEM (DRIVE_FIXED
),
73 DRIVE_TYPE_ITEM (DRIVE_REMOTE
),
74 DRIVE_TYPE_ITEM (DRIVE_CDROM
),
75 DRIVE_TYPE_ITEM (DRIVE_RAMDISK
),
79 typedef struct _DRIVE_INFO
{
81 DRIVE_TYPE_DESC
*DriveType
;
93 typedef struct _PATH_INFO
{
95 CHAR8 PhysicalPath
[260];
109 CHAR8
*ErrorStatusDesc
[] = {
111 "Failed to create files",
112 "Failed to read/write files",
114 "Failed to detect Fat type",
119 //UnSupported Windows API functions.
120 UINTN
GetLogicalDrives(void) { return 1; }
125 Get path information, including physical path for Linux platform.
127 @param PathInfo Point to PATH_INFO structure.
129 @return whether path is valid.
138 if (strncmp(PathInfo
->Path
, "/dev/", 5) == 0) {
140 // Process disk path here.
143 // Process floppy disk
144 if (PathInfo
->Path
[5] == 'f' && PathInfo
->Path
[6] == 'd' && PathInfo
->Path
[8] == '\0') {
145 PathInfo
->Type
= PathFloppy
;
146 strcpy (PathInfo
->PhysicalPath
, PathInfo
->Path
);
150 // Other disk types is not supported yet.
151 fprintf (stderr
, "ERROR: It's not a floppy disk!\n");
155 // Try to open the device.
156 f
= fopen(PathInfo
->Path
,"r");
158 printf ("error :open device failed!\n");
165 // Process file path here.
166 PathInfo
->Type
= PathFile
;
167 if (PathInfo
->Input
) {
168 // If path is file path, check whether file is valid.
169 printf("Path = %s\n",PathInfo
->Path
);
170 f
= fopen (PathInfo
->Path
, "r");
172 fprintf (stderr
, "Test error E2003: File was not provided!\n");
178 strcpy(PathInfo
->PhysicalPath
, PathInfo
->Path
);
188 printf("-l or -list not supported!\n");
192 Writing or reading boot sector or MBR according to the argument.
194 @param InputInfo PATH_INFO instance for input path
195 @param OutputInfo PATH_INFO instance for output path
196 @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector
202 PATH_INFO
*InputInfo
,
203 PATH_INFO
*OutputInfo
,
207 CHAR8 FirstSector
[0x200] = {0};
208 CHAR8 FirstSectorBackup
[0x200] = {0};
214 InputFile
= fopen(InputInfo
->PhysicalPath
, "r");
215 if (InputFile
== NULL
) {
216 return ErrorFileReadWrite
;
219 if (0x200 != fread(FirstSector
, 1, 0x200, InputFile
)) {
221 return ErrorFileReadWrite
;
226 //Not support USB and IDE.
227 if (InputInfo
->Type
== PathUsb
) {
228 printf("USB has not been supported yet!");
232 if (InputInfo
->Type
== PathIde
) {
233 printf("IDE has not been supported yet!");
237 //Process Floppy Disk
238 OutputFile
= fopen(OutputInfo
->PhysicalPath
, "r+");
239 if (OutputFile
== NULL
) {
240 OutputFile
= fopen(OutputInfo
->PhysicalPath
, "w");
241 if (OutputFile
== NULL
) {
242 return ErrorFileReadWrite
;
246 if (OutputInfo
->Type
!= PathFile
) {
249 // Use original partition table
251 if (0x200 != fread (FirstSectorBackup
, 1, 0x200, OutputFile
)) {
253 return ErrorFileReadWrite
;
255 memcpy (FirstSector
+ 0x1BE, FirstSectorBackup
+ 0x1BE, 0x40);
258 if(0x200 != fwrite(FirstSector
, 1, 0x200, OutputFile
)) {
260 return ErrorFileReadWrite
;
270 Displays the standard utility information to SDTOUT
278 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
);
279 printf ("Copyright (c) 2007-2010 Intel Corporation. All rights reserved.\n");
289 printf ("\nUsage: \n\
291 [-l, --list list disks]\n\
292 [-i, --input Filename]\n\
293 [-o, --output Filename]\n\
294 [-m, --mbr process the MBR also]\n\
297 [-q, --quiet disable all messages except fatal errors]\n\
311 EFI_STATUS EfiStatus
;
312 PATH_INFO InputPathInfo
;
313 PATH_INFO OutputPathInfo
;
316 SetUtilityName (UTILITY_NAME
);
318 ZeroMem(&InputPathInfo
, sizeof(PATH_INFO
));
319 ZeroMem(&OutputPathInfo
, sizeof(PATH_INFO
));
332 // Parse command line
334 for (Index
= 0; Index
< argc
; Index
++) {
335 if ((stricmp (argv
[Index
], "-l") == 0) || (stricmp (argv
[Index
], "--list") == 0)) {
340 if ((stricmp (argv
[Index
], "-m") == 0) || (stricmp (argv
[Index
], "--mbr") == 0)) {
345 if ((stricmp (argv
[Index
], "-i") == 0) || (stricmp (argv
[Index
], "--input") == 0)) {
346 InputPathInfo
.Path
= argv
[Index
+ 1];
347 InputPathInfo
.Input
= TRUE
;
348 if (InputPathInfo
.Path
== NULL
) {
349 Error (NULL
, 0, 1003, "Invalid option value", "Input file name can't be NULL");
352 if (InputPathInfo
.Path
[0] == '-') {
353 Error (NULL
, 0, 1003, "Invalid option value", "Input file is missing");
360 if ((stricmp (argv
[Index
], "-o") == 0) || (stricmp (argv
[Index
], "--output") == 0)) {
361 OutputPathInfo
.Path
= argv
[Index
+ 1];
362 OutputPathInfo
.Input
= FALSE
;
363 if (OutputPathInfo
.Path
== NULL
) {
364 Error (NULL
, 0, 1003, "Invalid option value", "Output file name can't be NULL");
367 if (OutputPathInfo
.Path
[0] == '-') {
368 Error (NULL
, 0, 1003, "Invalid option value", "Output file is missing");
375 if ((stricmp (argv
[Index
], "-h") == 0) || (stricmp (argv
[Index
], "--help") == 0)) {
380 if (stricmp (argv
[Index
], "--version") == 0) {
385 if ((stricmp (argv
[Index
], "-v") == 0) || (stricmp (argv
[Index
], "--verbose") == 0)) {
389 if ((stricmp (argv
[Index
], "-q") == 0) || (stricmp (argv
[Index
], "--quiet") == 0)) {
393 if ((stricmp (argv
[Index
], "-d") == 0) || (stricmp (argv
[Index
], "--debug") == 0)) {
394 EfiStatus
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &LogLevel
);
395 if (EFI_ERROR (EfiStatus
)) {
396 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[Index
], argv
[Index
+ 1]);
400 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel
);
403 SetPrintLevel (LogLevel
);
404 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[Index
+ 1]);
410 // Don't recognize the parameter.
412 Error (NULL
, 0, 1000, "Unknown option", "%s", argv
[Index
]);
416 if (InputPathInfo
.Path
== NULL
) {
417 Error (NULL
, 0, 1001, "Missing options", "Input file is missing");
421 if (OutputPathInfo
.Path
== NULL
) {
422 Error (NULL
, 0, 1001, "Missing options", "Output file is missing");
426 if (GetPathInfo(&InputPathInfo
) != ErrorSuccess
) {
427 Error (NULL
, 0, 1003, "Invalid option value", "Input file can't be found.");
431 if (GetPathInfo(&OutputPathInfo
) != ErrorSuccess
) {
432 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be found.");
437 // Process DBR (Patch or Read)
439 Status
= ProcessBsOrMbr (&InputPathInfo
, &OutputPathInfo
, ProcessMbr
);
441 if (Status
== ErrorSuccess
) {
444 "%s %s: successful!\n",
445 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
446 ProcessMbr
? "MBR" : "DBR"
452 "%s: %s %s: failed - %s (LastError: 0x%x)!\n",
453 (Status
== ErrorNoMbr
) ? "WARNING" : "ERROR",
454 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
455 ProcessMbr
? "MBR" : "DBR",
456 ErrorStatusDesc
[Status
],