EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

BaseTools/Source/C/GnuGenBootSector/GnuGenBootSector.c

Go to the documentation of this file.
00001 
00024 #include "CommonLib.h"
00025 #include <errno.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <Common/UefiBaseTypes.h>
00029 
00030 #include "ParseInf.h"
00031 #include "EfiUtilityMsgs.h"
00032 
00033 //
00034 // Utility Name
00035 //
00036 #define UTILITY_NAME  "GnuGenBootSector"
00037 
00038 //
00039 // Utility version information
00040 //
00041 #define UTILITY_MAJOR_VERSION 0
00042 #define UTILITY_MINOR_VERSION 1
00043 
00044 #define MAX_DRIVE                             26
00045 #define PARTITION_TABLE_OFFSET                0x1BE
00046 
00047 #define SIZE_OF_PARTITION_ENTRY               0x10
00048 
00049 #define PARTITION_ENTRY_STARTLBA_OFFSET       8
00050 
00051 #define PARTITION_ENTRY_NUM                   4
00052 
00053 #define DRIVE_UNKNOWN     0
00054 #define DRIVE_NO_ROOT_DIR 1
00055 #define DRIVE_REMOVABLE   2
00056 #define DRIVE_FIXED       3
00057 #define DRIVE_REMOTE      4
00058 #define DRIVE_CDROM       5
00059 #define DRIVE_RAMDISK     6
00060 
00061 typedef struct _DRIVE_TYPE_DESC {
00062   UINTN  Type;
00063   CHAR8  *Description;
00064 } DRIVE_TYPE_DESC;
00065 
00066 #define DRIVE_TYPE_ITEM(x) {x, #x}
00067 
00068 DRIVE_TYPE_DESC DriveTypeDesc[] = {
00069   DRIVE_TYPE_ITEM (DRIVE_UNKNOWN),
00070   DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR),
00071   DRIVE_TYPE_ITEM (DRIVE_REMOVABLE),
00072   DRIVE_TYPE_ITEM (DRIVE_FIXED),
00073   DRIVE_TYPE_ITEM (DRIVE_REMOTE),
00074   DRIVE_TYPE_ITEM (DRIVE_CDROM),
00075   DRIVE_TYPE_ITEM (DRIVE_RAMDISK),
00076   {(UINTN) -1, NULL}
00077 };
00078 
00079 typedef struct _DRIVE_INFO {
00080   CHAR8             VolumeLetter;
00081   DRIVE_TYPE_DESC   *DriveType;
00082   UINTN             DiskNumber;
00083 } DRIVE_INFO;
00084 
00085 typedef enum {
00086   PathUnknown,
00087   PathFile,
00088   PathFloppy,
00089   PathUsb,
00090   PathIde
00091 } PATH_TYPE;
00092 
00093 typedef struct _PATH_INFO {
00094   CHAR8            *Path;
00095   CHAR8            PhysicalPath[260];
00096   PATH_TYPE        Type;
00097   BOOLEAN          Input;
00098 } PATH_INFO;
00099 
00100 typedef enum {
00101   ErrorSuccess,
00102   ErrorFileCreate,
00103   ErrorFileReadWrite,
00104   ErrorNoMbr,
00105   ErrorFatType,
00106   ErrorPath,
00107 } ERROR_STATUS;
00108 
00109 CHAR8 *ErrorStatusDesc[] = {
00110   "Success",
00111   "Failed to create files",
00112   "Failed to read/write files",
00113   "No MBR exists",
00114   "Failed to detect Fat type",
00115   "Inavlid path"
00116 };
00117 
00118 
00119 //UnSupported Windows API functions.
00120 UINTN GetLogicalDrives(void) { return 1; }
00121 
00122 
00123 
00131 ERROR_STATUS
00132 GetPathInfo (
00133   PATH_INFO   *PathInfo
00134   )
00135 {
00136   FILE        *f;
00137 
00138   if (strncmp(PathInfo->Path, "/dev/", 5) == 0) {
00139     //
00140     // Process disk path here.
00141     // 
00142     
00143     // Process floppy disk
00144     if (PathInfo->Path[5] == 'f' && PathInfo->Path[6] == 'd' && PathInfo->Path[8] == '\0') {
00145       PathInfo->Type = PathFloppy;
00146       strcpy (PathInfo->PhysicalPath, PathInfo->Path);
00147       
00148       return ErrorSuccess;
00149     } else {
00150     // Other disk types is not supported yet.
00151     fprintf (stderr, "ERROR: It's not a floppy disk!\n");
00152     return ErrorPath;
00153     }  
00154      
00155     // Try to open the device.   
00156     f = fopen(PathInfo->Path,"r");
00157     if (f == NULL) {
00158       printf ("error :open device failed!\n");
00159       return ErrorPath;
00160     }
00161     fclose (f);
00162     return ErrorSuccess;
00163   }
00164  
00165   // Process file path here.
00166   PathInfo->Type = PathFile;
00167   if (PathInfo->Input) {
00168     // If path is file path, check whether file is valid.
00169     printf("Path = %s\n",PathInfo->Path);
00170     f = fopen (PathInfo->Path, "r");
00171     if (f == NULL) {
00172       fprintf (stderr, "Test error E2003: File was not provided!\n");
00173       return ErrorPath;
00174     }
00175     fclose (f);
00176   }
00177 
00178   strcpy(PathInfo->PhysicalPath, PathInfo->Path);
00179   return ErrorSuccess;
00180 
00181 }
00182 
00183 VOID
00184 ListDrive (
00185   VOID
00186   )
00187 {
00188   printf("-l or -list not supported!\n");
00189 }
00190 
00200 ERROR_STATUS
00201 ProcessBsOrMbr (
00202   PATH_INFO     *InputInfo,
00203   PATH_INFO     *OutputInfo,
00204   BOOLEAN       ProcessMbr
00205   )
00206 {
00207   CHAR8 FirstSector[0x200] = {0};
00208   CHAR8 FirstSectorBackup[0x200] = {0};
00209   
00210   FILE *InputFile;
00211   FILE *OutputFile;
00212   
00213   
00214   InputFile = fopen(InputInfo->PhysicalPath, "r");
00215   if (InputFile == NULL) {
00216     return ErrorFileReadWrite;
00217   }
00218    
00219   if (0x200 != fread(FirstSector, 1, 0x200, InputFile)) {
00220     fclose(InputFile);
00221     return ErrorFileReadWrite;
00222   }
00223   
00224   fclose(InputFile);
00225   
00226   //Not support USB and IDE.
00227   if (InputInfo->Type == PathUsb) {
00228     printf("USB has not been supported yet!");
00229     return ErrorSuccess;
00230   }
00231   
00232   if (InputInfo->Type == PathIde) {
00233     printf("IDE has not been supported yet!");
00234     return ErrorSuccess;
00235   } 
00236   
00237   //Process Floppy Disk
00238   OutputFile = fopen(OutputInfo->PhysicalPath, "r+");
00239   if (OutputFile == NULL) {
00240     OutputFile = fopen(OutputInfo->PhysicalPath, "w");
00241     if (OutputFile == NULL) {
00242       return ErrorFileReadWrite;
00243     }
00244   }
00245   
00246   if (OutputInfo->Type != PathFile) {
00247     if (ProcessMbr) {
00248       //
00249       // Use original partition table
00250       //
00251       if (0x200 != fread (FirstSectorBackup, 1, 0x200, OutputFile)) {
00252         fclose(OutputFile);
00253         return ErrorFileReadWrite; 
00254         }
00255       memcpy (FirstSector + 0x1BE, FirstSectorBackup + 0x1BE, 0x40);  
00256     }
00257   }
00258   if(0x200 != fwrite(FirstSector, 1, 0x200, OutputFile)) {
00259     fclose(OutputFile);
00260     return ErrorFileReadWrite;
00261   }
00262   
00263   fclose(OutputFile);
00264   return ErrorSuccess;
00265 }
00266 
00267 
00273 VOID
00274 Version (
00275   VOID
00276   )
00277 {
00278   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);
00279   printf ("Copyright (c) 2007-2010 Intel Corporation. All rights reserved.\n");
00280 }
00281 
00282 
00283 VOID
00284 PrintUsage (
00285   VOID
00286     )
00287 {
00288   Version();
00289   printf ("\nUsage: \n\
00290    GenBootSector\n\
00291      [-l, --list list disks]\n\
00292      [-i, --input Filename]\n\
00293      [-o, --output Filename]\n\
00294      [-m, --mbr process the MBR also]\n\
00295      [-v, --verbose]\n\
00296      [--version]\n\
00297      [-q, --quiet disable all messages except fatal errors]\n\
00298      [-d, --debug[#]\n\
00299      [-h, --help]\n");
00300 }
00301 
00302 int
00303 main (
00304   int  argc,
00305   char *argv[]
00306   )
00307 {
00308   INTN           Index;
00309   BOOLEAN        ProcessMbr;
00310   ERROR_STATUS   Status;
00311   EFI_STATUS     EfiStatus;
00312   PATH_INFO      InputPathInfo;
00313   PATH_INFO      OutputPathInfo;
00314   UINT64         LogLevel;
00315 
00316   SetUtilityName (UTILITY_NAME);
00317   
00318   ZeroMem(&InputPathInfo, sizeof(PATH_INFO));
00319   ZeroMem(&OutputPathInfo, sizeof(PATH_INFO));
00320   
00321   argv ++;
00322   argc --;
00323   
00324   ProcessMbr    = FALSE;
00325 
00326   if (argc == 0) {
00327     PrintUsage();
00328     return 0;
00329   }
00330    
00331   //
00332   // Parse command line
00333   //
00334   for (Index = 0; Index < argc; Index ++) {
00335     if ((stricmp (argv[Index], "-l") == 0) || (stricmp (argv[Index], "--list") == 0)) {
00336       ListDrive ();
00337       return 0;
00338     } 
00339     
00340     if ((stricmp (argv[Index], "-m") == 0) || (stricmp (argv[Index], "--mbr") == 0)) {
00341       ProcessMbr = TRUE;
00342       continue;
00343     }
00344     
00345     if ((stricmp (argv[Index], "-i") == 0) || (stricmp (argv[Index], "--input") == 0)) {
00346       InputPathInfo.Path  = argv[Index + 1];
00347       InputPathInfo.Input = TRUE;
00348       if (InputPathInfo.Path == NULL) {
00349         Error (NULL, 0, 1003, "Invalid option value", "Input file name can't be NULL");
00350         return 1;
00351       } 
00352       if (InputPathInfo.Path[0] == '-') {
00353         Error (NULL, 0, 1003, "Invalid option value", "Input file is missing");
00354         return 1;       
00355       }
00356       ++Index;
00357       continue;
00358     }
00359     
00360     if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {
00361       OutputPathInfo.Path  = argv[Index + 1];
00362       OutputPathInfo.Input = FALSE;
00363       if (OutputPathInfo.Path == NULL) {
00364         Error (NULL, 0, 1003, "Invalid option value", "Output file name can't be NULL");
00365         return 1;
00366       } 
00367       if (OutputPathInfo.Path[0] == '-') {
00368         Error (NULL, 0, 1003, "Invalid option value", "Output file is missing");
00369         return 1;       
00370       }
00371       ++Index;
00372       continue;
00373     }
00374     
00375     if ((stricmp (argv[Index], "-h") == 0) || (stricmp (argv[Index], "--help") == 0)) {
00376       PrintUsage ();
00377       return 0;
00378     }
00379     
00380     if (stricmp (argv[Index], "--version") == 0) {
00381       Version ();
00382       return 0;
00383     } 
00384     
00385     if ((stricmp (argv[Index], "-v") == 0) || (stricmp (argv[Index], "--verbose") == 0)) {
00386       continue;
00387     } 
00388     
00389     if ((stricmp (argv[Index], "-q") == 0) || (stricmp (argv[Index], "--quiet") == 0)) {
00390       continue;
00391     } 
00392     
00393     if ((stricmp (argv[Index], "-d") == 0) || (stricmp (argv[Index], "--debug") == 0)) {
00394       EfiStatus = AsciiStringToUint64 (argv[Index + 1], FALSE, &LogLevel);
00395       if (EFI_ERROR (EfiStatus)) {
00396         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[Index], argv[Index + 1]);
00397         return 1;
00398       }
00399       if (LogLevel > 9) {
00400         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);
00401         return 1;
00402       }
00403       SetPrintLevel (LogLevel);
00404       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[Index + 1]);
00405       ++Index;
00406       continue;
00407     }
00408 
00409     //
00410     // Don't recognize the parameter.
00411     //
00412     Error (NULL, 0, 1000, "Unknown option", "%s", argv[Index]);
00413     return 1;
00414   }
00415   
00416   if (InputPathInfo.Path == NULL) {
00417     Error (NULL, 0, 1001, "Missing options", "Input file is missing");
00418     return 1;
00419   }
00420 
00421   if (OutputPathInfo.Path == NULL) {
00422     Error (NULL, 0, 1001, "Missing options", "Output file is missing");
00423     return 1;
00424   }
00425   
00426   if (GetPathInfo(&InputPathInfo) != ErrorSuccess) {
00427     Error (NULL, 0, 1003, "Invalid option value", "Input file can't be found.");
00428     return 1;
00429   }
00430 
00431   if (GetPathInfo(&OutputPathInfo) != ErrorSuccess) {
00432     Error (NULL, 0, 1003, "Invalid option value", "Output file can't be found.");
00433     return 1;
00434   }
00435   
00436   //
00437   // Process DBR (Patch or Read)
00438   //
00439   Status = ProcessBsOrMbr (&InputPathInfo, &OutputPathInfo, ProcessMbr);
00440 
00441   if (Status == ErrorSuccess) {
00442     fprintf (
00443       stdout, 
00444       "%s %s: successful!\n", 
00445       (OutputPathInfo.Type != PathFile) ? "Write" : "Read", 
00446       ProcessMbr ? "MBR" : "DBR"
00447       );
00448     return 0;
00449   } else {
00450     fprintf (
00451       stderr, 
00452       "%s: %s %s: failed - %s (LastError: 0x%x)!\n",
00453       (Status == ErrorNoMbr) ? "WARNING" : "ERROR",
00454       (OutputPathInfo.Type != PathFile) ? "Write" : "Read", 
00455       ProcessMbr ? "MBR" : "DBR", 
00456       ErrorStatusDesc[Status],
00457       errno 
00458       );
00459     return 1;
00460   }
00461 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines