3 Copyright 2006 - 2009, 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
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>
33 #define UTILITY_NAME "GnuGenBootSector"
36 // Utility version information
38 #define UTILITY_MAJOR_VERSION 0
39 #define UTILITY_MINOR_VERSION 1
42 #define PARTITION_TABLE_OFFSET 0x1BE
44 #define SIZE_OF_PARTITION_ENTRY 0x10
46 #define PARTITION_ENTRY_STARTLBA_OFFSET 8
48 #define PARTITION_ENTRY_NUM 4
50 #define DRIVE_UNKNOWN 0
51 #define DRIVE_NO_ROOT_DIR 1
52 #define DRIVE_REMOVABLE 2
54 #define DRIVE_REMOTE 4
56 #define DRIVE_RAMDISK 6
58 typedef struct _DRIVE_TYPE_DESC
{
63 #define DRIVE_TYPE_ITEM(x) {x, #x}
65 DRIVE_TYPE_DESC DriveTypeDesc
[] = {
66 DRIVE_TYPE_ITEM (DRIVE_UNKNOWN
),
67 DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR
),
68 DRIVE_TYPE_ITEM (DRIVE_REMOVABLE
),
69 DRIVE_TYPE_ITEM (DRIVE_FIXED
),
70 DRIVE_TYPE_ITEM (DRIVE_REMOTE
),
71 DRIVE_TYPE_ITEM (DRIVE_CDROM
),
72 DRIVE_TYPE_ITEM (DRIVE_RAMDISK
),
76 typedef struct _DRIVE_INFO
{
78 DRIVE_TYPE_DESC
*DriveType
;
90 typedef struct _PATH_INFO
{
92 CHAR8 PhysicalPath
[260];
106 CHAR8
*ErrorStatusDesc
[] = {
108 "Failed to create files",
109 "Failed to read/write files",
111 "Failed to detect Fat type",
116 //UnSupported Windows API functions.
117 UINTN
GetLogicalDrives(void) { return 1; }
122 Get path information, including physical path for Linux platform.
124 @param PathInfo Point to PATH_INFO structure.
126 @return whether path is valid.
135 if (strncmp(PathInfo
->Path
, "/dev/", 5) == 0) {
137 // Process disk path here.
140 // Process floppy disk
141 if (PathInfo
->Path
[5] == 'f' && PathInfo
->Path
[6] == 'd' && PathInfo
->Path
[8] == '\0') {
142 PathInfo
->Type
= PathFloppy
;
143 strcpy (PathInfo
->PhysicalPath
, PathInfo
->Path
);
147 // Other disk types is not supported yet.
148 fprintf (stderr
, "ERROR: It's not a floppy disk!\n");
152 // Try to open the device.
153 f
= fopen(PathInfo
->Path
,"r");
155 printf ("error :open device failed!\n");
162 // Process file path here.
163 PathInfo
->Type
= PathFile
;
164 if (PathInfo
->Input
) {
165 // If path is file path, check whether file is valid.
166 printf("Path = %s\n",PathInfo
->Path
);
167 f
= fopen (PathInfo
->Path
, "r");
169 fprintf (stderr
, "Test error E2003: File was not provided!\n");
175 strcpy(PathInfo
->PhysicalPath
, PathInfo
->Path
);
185 printf("-l or -list not supported!\n");
189 Writing or reading boot sector or MBR according to the argument.
191 @param InputInfo PATH_INFO instance for input path
192 @param OutputInfo PATH_INFO instance for output path
193 @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector
199 PATH_INFO
*InputInfo
,
200 PATH_INFO
*OutputInfo
,
204 CHAR8 FirstSector
[0x200] = {0};
205 CHAR8 FirstSectorBackup
[0x200] = {0};
211 InputFile
= fopen(InputInfo
->PhysicalPath
, "r");
212 if (InputFile
== NULL
) {
213 return ErrorFileReadWrite
;
216 if (0x200 != fread(FirstSector
, 1, 0x200, InputFile
)) {
218 return ErrorFileReadWrite
;
223 //Not support USB and IDE.
224 if (InputInfo
->Type
== PathUsb
) {
225 printf("USB has not been supported yet!");
229 if (InputInfo
->Type
== PathIde
) {
230 printf("IDE has not been supported yet!");
234 //Process Floppy Disk
235 OutputFile
= fopen(OutputInfo
->PhysicalPath
, "w");
236 if (OutputFile
== NULL
) {
237 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 -Utility to retrieve and update the boot sector or MBR.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
273 printf ("Copyright (c) 2007-2009 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\
306 EFI_STATUS EfiStatus
;
307 PATH_INFO InputPathInfo
;
308 PATH_INFO OutputPathInfo
;
311 SetUtilityName (UTILITY_NAME
);
313 ZeroMem(&InputPathInfo
, sizeof(PATH_INFO
));
314 ZeroMem(&OutputPathInfo
, sizeof(PATH_INFO
));
328 // Parse command line
330 for (Index
= 0; Index
< argc
; Index
++) {
331 if ((stricmp (argv
[Index
], "-l") == 0) || (stricmp (argv
[Index
], "--list") == 0)) {
336 if ((stricmp (argv
[Index
], "-m") == 0) || (stricmp (argv
[Index
], "--mbr") == 0)) {
341 if ((stricmp (argv
[Index
], "-i") == 0) || (stricmp (argv
[Index
], "--input") == 0)) {
342 InputPathInfo
.Path
= argv
[Index
+ 1];
343 InputPathInfo
.Input
= TRUE
;
344 if (InputPathInfo
.Path
== NULL
) {
345 Error (NULL
, 0, 1003, "Invalid option value", "Input file name can't be NULL");
348 if (InputPathInfo
.Path
[0] == '-') {
349 Error (NULL
, 0, 1003, "Invalid option value", "Input file is missing");
356 if ((stricmp (argv
[Index
], "-o") == 0) || (stricmp (argv
[Index
], "--output") == 0)) {
357 OutputPathInfo
.Path
= argv
[Index
+ 1];
358 OutputPathInfo
.Input
= FALSE
;
359 if (OutputPathInfo
.Path
== NULL
) {
360 Error (NULL
, 0, 1003, "Invalid option value", "Output file name can't be NULL");
363 if (OutputPathInfo
.Path
[0] == '-') {
364 Error (NULL
, 0, 1003, "Invalid option value", "Output file is missing");
371 if ((stricmp (argv
[Index
], "-h") == 0) || (stricmp (argv
[Index
], "--help") == 0)) {
376 if (stricmp (argv
[Index
], "--version") == 0) {
381 if ((stricmp (argv
[Index
], "-v") == 0) || (stricmp (argv
[Index
], "--verbose") == 0)) {
385 if ((stricmp (argv
[Index
], "-q") == 0) || (stricmp (argv
[Index
], "--quiet") == 0)) {
389 if ((stricmp (argv
[Index
], "-d") == 0) || (stricmp (argv
[Index
], "--debug") == 0)) {
390 EfiStatus
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &LogLevel
);
391 if (EFI_ERROR (EfiStatus
)) {
392 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[Index
], argv
[Index
+ 1]);
396 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", LogLevel
);
399 SetPrintLevel (LogLevel
);
400 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[Index
+ 1]);
406 // Don't recognize the parameter.
408 Error (NULL
, 0, 1000, "Unknown option", "%s", argv
[Index
]);
412 if (InputPathInfo
.Path
== NULL
) {
413 Error (NULL
, 0, 1001, "Missing options", "Input file is missing");
417 if (OutputPathInfo
.Path
== NULL
) {
418 Error (NULL
, 0, 1001, "Missing options", "Output file is missing");
422 if (GetPathInfo(&InputPathInfo
) != ErrorSuccess
) {
423 Error (NULL
, 0, 1003, "Invalid option value", "Input file can't be found.");
427 if (GetPathInfo(&OutputPathInfo
) != ErrorSuccess
) {
428 Error (NULL
, 0, 1003, "Invalid option value", "Output file can't be found.");
433 // Process DBR (Patch or Read)
435 Status
= ProcessBsOrMbr (&InputPathInfo
, &OutputPathInfo
, ProcessMbr
);
437 if (Status
== ErrorSuccess
) {
440 "%s %s: successful!\n",
441 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
442 ProcessMbr
? "MBR" : "DBR"
448 "%s: %s %s: failed - %s (LastError: 0x%x)!\n",
449 (Status
== ErrorNoMbr
) ? "WARNING" : "ERROR",
450 (OutputPathInfo
.Type
!= PathFile
) ? "Write" : "Read",
451 ProcessMbr
? "MBR" : "DBR",
452 ErrorStatusDesc
[Status
],