--- /dev/null
+/** @file\r
+\r
+ Fat file system structure and definition.\r
+\r
+Copyright 2006 - 2008, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+--*/\r
+\r
+#ifndef _FAT_BPB_H_\r
+#define _FAT_BPB_H_\r
+\r
+#include "CommonLib.h"\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ //\r
+ // Fat common field\r
+ //\r
+ UINT8 BS_jmpBoot[3];\r
+ CHAR8 BS_OEMName[8];\r
+ UINT16 BPB_BytsPerSec;\r
+ UINT8 BPB_SecPerClus;\r
+ UINT16 BPB_RsvdSecCnt;\r
+ UINT8 BPB_NumFATs;\r
+ UINT16 BPB_RootEntCnt;\r
+ UINT16 BPB_TotSec16;\r
+ UINT8 BPB_Media;\r
+ UINT16 BPB_FATSz16;\r
+ UINT16 BPB_SecPerTrk;\r
+ UINT16 BPB_NumHeads;\r
+ UINT32 BPB_HiddSec;\r
+ UINT32 BPB_TotSec32;\r
+\r
+ //\r
+ // Fat12/16 specific field\r
+ //\r
+ UINT8 BS_DrvNum;\r
+ UINT8 BS_Reserved1;\r
+ UINT8 BS_BootSig;\r
+ UINT32 BS_VolID;\r
+ CHAR8 BS_VolLab[11];\r
+ CHAR8 BS_FilSysType[8];\r
+\r
+ //\r
+ // Boot Code and Data\r
+ //\r
+ UINT8 Reserved[448];\r
+\r
+ //\r
+ // Fat common signature - 0xAA55\r
+ //\r
+ UINT16 Signature;\r
+} FAT12_16_BPB_STRUCT;\r
+\r
+typedef struct {\r
+ //\r
+ // Fat common field\r
+ //\r
+ UINT8 BS_jmpBoot[3];\r
+ CHAR8 BS_OEMName[8];\r
+ UINT16 BPB_BytsPerSec;\r
+ UINT8 BPB_SecPerClus;\r
+ UINT16 BPB_RsvdSecCnt;\r
+ UINT8 BPB_NumFATs;\r
+ UINT16 BPB_RootEntCnt;\r
+ UINT16 BPB_TotSec16;\r
+ UINT8 BPB_Media;\r
+ UINT16 BPB_FATSz16;\r
+ UINT16 BPB_SecPerTrk;\r
+ UINT16 BPB_NumHeads;\r
+ UINT32 BPB_HiddSec;\r
+ UINT32 BPB_TotSec32;\r
+\r
+ //\r
+ // Fat32 specific field\r
+ //\r
+ UINT32 BPB_FATSz32;\r
+ UINT16 BPB_ExtFlags;\r
+ UINT16 BPB_FSVer;\r
+ UINT32 BPB_RootClus;\r
+ UINT16 BPB_FSInfo;\r
+ UINT16 BPB_BkBootSec;\r
+ UINT8 BPB_Reserved[12];\r
+ UINT8 BS_DrvNum;\r
+ UINT8 BS_Reserved1;\r
+ UINT8 BS_BootSig;\r
+ UINT32 BS_VolID;\r
+ CHAR8 BS_VolLab[11];\r
+ CHAR8 BS_FilSysType[8];\r
+\r
+ //\r
+ // Boot Code and Data\r
+ //\r
+ UINT8 Reserved[420];\r
+\r
+ //\r
+ // Fat common signature - 0xAA55\r
+ //\r
+ UINT16 Signature;\r
+} FAT32_BPB_STRUCT;\r
+\r
+typedef union {\r
+ FAT12_16_BPB_STRUCT Fat12_16;\r
+ FAT32_BPB_STRUCT Fat32;\r
+} FAT_BPB_STRUCT;\r
+\r
+typedef enum {\r
+ FatTypeUnknown,\r
+ FatTypeFat12,\r
+ FatTypeFat16,\r
+ FatTypeFat32,\r
+ FatTypeMax\r
+} FAT_TYPE;\r
+\r
+typedef struct {\r
+ CHAR8 DIR_Name[11];\r
+ UINT8 DIR_Attr;\r
+ UINT8 DIR_NTRes;\r
+ UINT8 DIR_CrtTimeTenth;\r
+ UINT16 DIR_CrtTime;\r
+ UINT16 DIR_CrtDate;\r
+ UINT16 DIR_LstAccDate;\r
+ UINT16 DIR_FstClusHI;\r
+ UINT16 DIR_WrtTime;\r
+ UINT16 DIR_WrtDate;\r
+ UINT16 DIR_FstClusLO;\r
+ UINT32 DIR_FileSize;\r
+} FAT_DIRECTORY_ENTRY;\r
+\r
+#pragma pack()\r
+\r
+#define FAT_MAX_FAT12_CLUSTER 0xFF5\r
+#define FAT_MAX_FAT16_CLUSTER 0xFFF5\r
+\r
+#define FAT_BS_SIGNATURE 0xAA55\r
+#define FAT_BS_BOOTSIG 0x29\r
+#define FAT_BS_JMP1 0xEB\r
+#define FAT_BS_JMP2 0xE9\r
+#define FAT_FILSYSTYPE "FAT "\r
+#define FAT12_FILSYSTYPE "FAT12 "\r
+#define FAT16_FILSYSTYPE "FAT16 "\r
+#define FAT32_FILSYSTYPE "FAT32 "\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+\r
+Copyright 2006 - 2009, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ GnuGenBootSector.c\r
+ \r
+Abstract:\r
+ Reading/writing MBR/DBR.\r
+ NOTE:\r
+ If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.\r
+ If we process DBR, we will patch MBR to set first partition active if no active partition exists.\r
+\r
+**/\r
+\r
+#include "CommonLib.h"\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+//\r
+// Utility Name\r
+//\r
+#define UTILITY_NAME "GnuGenBootSector"\r
+\r
+//\r
+// Utility version information\r
+//\r
+#define UTILITY_MAJOR_VERSION 0\r
+#define UTILITY_MINOR_VERSION 1\r
+\r
+#define MAX_DRIVE 26\r
+#define PARTITION_TABLE_OFFSET 0x1BE\r
+\r
+#define SIZE_OF_PARTITION_ENTRY 0x10\r
+\r
+#define PARTITION_ENTRY_STARTLBA_OFFSET 8\r
+\r
+#define PARTITION_ENTRY_NUM 4\r
+\r
+#define DRIVE_UNKNOWN 0\r
+#define DRIVE_NO_ROOT_DIR 1\r
+#define DRIVE_REMOVABLE 2\r
+#define DRIVE_FIXED 3\r
+#define DRIVE_REMOTE 4\r
+#define DRIVE_CDROM 5\r
+#define DRIVE_RAMDISK 6\r
+\r
+typedef struct _DRIVE_TYPE_DESC {\r
+ UINTN Type;\r
+ CHAR8 *Description;\r
+} DRIVE_TYPE_DESC;\r
+\r
+#define DRIVE_TYPE_ITEM(x) {x, #x}\r
+\r
+DRIVE_TYPE_DESC DriveTypeDesc[] = {\r
+ DRIVE_TYPE_ITEM (DRIVE_UNKNOWN),\r
+ DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR),\r
+ DRIVE_TYPE_ITEM (DRIVE_REMOVABLE),\r
+ DRIVE_TYPE_ITEM (DRIVE_FIXED),\r
+ DRIVE_TYPE_ITEM (DRIVE_REMOTE),\r
+ DRIVE_TYPE_ITEM (DRIVE_CDROM),\r
+ DRIVE_TYPE_ITEM (DRIVE_RAMDISK),\r
+ {(UINTN) -1, NULL}\r
+};\r
+\r
+typedef struct _DRIVE_INFO {\r
+ CHAR8 VolumeLetter;\r
+ DRIVE_TYPE_DESC *DriveType;\r
+ UINTN DiskNumber;\r
+} DRIVE_INFO;\r
+\r
+typedef enum {\r
+ PathUnknown,\r
+ PathFile,\r
+ PathFloppy,\r
+ PathUsb,\r
+ PathIde\r
+} PATH_TYPE;\r
+\r
+typedef struct _PATH_INFO {\r
+ CHAR8 *Path;\r
+ CHAR8 PhysicalPath[260];\r
+ PATH_TYPE Type;\r
+ BOOLEAN Input;\r
+} PATH_INFO;\r
+\r
+typedef enum {\r
+ ErrorSuccess,\r
+ ErrorFileCreate,\r
+ ErrorFileReadWrite,\r
+ ErrorNoMbr,\r
+ ErrorFatType,\r
+ ErrorPath,\r
+} ERROR_STATUS;\r
+\r
+CHAR8 *ErrorStatusDesc[] = {\r
+ "Success",\r
+ "Failed to create files",\r
+ "Failed to read/write files",\r
+ "No MBR exists",\r
+ "Failed to detect Fat type",\r
+ "Inavlid path"\r
+};\r
+\r
+\r
+//UnSupported Windows API functions.\r
+UINTN GetLogicalDrives(void) { return 1; }\r
+\r
+\r
+\r
+/**\r
+ Get path information, including physical path for Linux platform.\r
+\r
+ @param PathInfo Point to PATH_INFO structure.\r
+\r
+ @return whether path is valid.\r
+**/\r
+ERROR_STATUS\r
+GetPathInfo (\r
+ PATH_INFO *PathInfo\r
+ )\r
+{\r
+ FILE *f;\r
+\r
+ if (strncmp(PathInfo->Path, "/dev/", 5) == 0) {\r
+ //\r
+ // Process disk path here.\r
+ // \r
+ \r
+ // Process floppy disk\r
+ if (PathInfo->Path[5] == 'f' && PathInfo->Path[6] == 'd' && PathInfo->Path[8] == '\0') {\r
+ PathInfo->Type = PathFloppy;\r
+ strcpy (PathInfo->PhysicalPath, PathInfo->Path);\r
+ \r
+ return ErrorSuccess;\r
+ } else {\r
+ // Other disk types is not supported yet.\r
+ fprintf (stderr, "ERROR: It's not a floppy disk!\n");\r
+ return ErrorPath;\r
+ } \r
+ \r
+ // Try to open the device. \r
+ f = fopen(PathInfo->Path,"r");\r
+ if (f == NULL) {\r
+ printf ("error :open device failed!\n");\r
+ return ErrorPath;\r
+ }\r
+ fclose (f);\r
+ return ErrorSuccess;\r
+ }\r
+ \r
+ // Process file path here.\r
+ PathInfo->Type = PathFile;\r
+ if (PathInfo->Input) {\r
+ // If path is file path, check whether file is valid.\r
+ printf("Path = %s\n",PathInfo->Path);\r
+ f = fopen (PathInfo->Path, "r");\r
+ if (f == NULL) {\r
+ fprintf (stderr, "Test error E2003: File was not provided!\n");\r
+ return ErrorPath;\r
+ }\r
+ fclose (f);\r
+ }\r
+\r
+ strcpy(PathInfo->PhysicalPath, PathInfo->Path);\r
+ return ErrorSuccess;\r
+\r
+}\r
+\r
+VOID\r
+ListDrive (\r
+ VOID\r
+ )\r
+{\r
+ printf("-l or -list not supported!\n");\r
+}\r
+\r
+/**\r
+ Writing or reading boot sector or MBR according to the argument. \r
+ \r
+ @param InputInfo PATH_INFO instance for input path\r
+ @param OutputInfo PATH_INFO instance for output path\r
+ @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector\r
+ \r
+ @return ERROR_STATUS\r
+ **/\r
+ERROR_STATUS\r
+ProcessBsOrMbr (\r
+ PATH_INFO *InputInfo,\r
+ PATH_INFO *OutputInfo,\r
+ BOOLEAN ProcessMbr\r
+ )\r
+{\r
+ CHAR8 FirstSector[0x200] = {0};\r
+ CHAR8 FirstSectorBackup[0x200] = {0};\r
+ \r
+ FILE *InputFile;\r
+ FILE *OutputFile;\r
+ \r
+ \r
+ InputFile = fopen(InputInfo->PhysicalPath, "r");\r
+ if (InputFile == NULL) {\r
+ return ErrorFileReadWrite;\r
+ }\r
+ \r
+ if (0x200 != fread(FirstSector, 1, 0x200, InputFile)) {\r
+ fclose(InputFile);\r
+ return ErrorFileReadWrite;\r
+ }\r
+ \r
+ fclose(InputFile);\r
+ \r
+ //Not support USB and IDE.\r
+ if (InputInfo->Type == PathUsb) {\r
+ printf("USB has not been supported yet!");\r
+ return ErrorSuccess;\r
+ }\r
+ \r
+ if (InputInfo->Type == PathIde) {\r
+ printf("IDE has not been supported yet!");\r
+ return ErrorSuccess;\r
+ } \r
+ \r
+ //Process Floppy Disk\r
+ OutputFile = fopen(OutputInfo->PhysicalPath, "w");\r
+ if (OutputFile == NULL) {\r
+ return ErrorFileReadWrite;\r
+ } \r
+ \r
+ if (OutputInfo->Type != PathFile) {\r
+ if (ProcessMbr) {\r
+ //\r
+ // Use original partition table\r
+ //\r
+ if (0x200 != fread (FirstSectorBackup, 1, 0x200, OutputFile)) {\r
+ fclose(OutputFile);\r
+ return ErrorFileReadWrite; \r
+ }\r
+ memcpy (FirstSector + 0x1BE, FirstSectorBackup + 0x1BE, 0x40); \r
+ }\r
+ }\r
+ if(0x200 != fwrite(FirstSector, 1, 0x200, OutputFile)) {\r
+ fclose(OutputFile);\r
+ return ErrorFileReadWrite;\r
+ }\r
+ \r
+ fclose(OutputFile);\r
+ return ErrorSuccess;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Displays the standard utility information to SDTOUT\r
+\r
+**/\r
+VOID\r
+Version (\r
+ VOID\r
+ )\r
+{\r
+ printf ("%s v%d.%d -Utility to retrieve and update the boot sector or MBR.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+ printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");\r
+}\r
+\r
+\r
+VOID\r
+PrintUsage (\r
+ VOID\r
+ )\r
+{\r
+ Version();\r
+ printf ("\nUsage: \n\\r
+ GenBootSector\n\\r
+ [-l, --list list disks]\n\\r
+ [-i, --input Filename]\n\\r
+ [-o, --output Filename]\n\\r
+ [-m, --mbr process the MBR also]\n\\r
+ [-v, --verbose]\n\\r
+ [--version]\n\\r
+ [-q, --quiet disable all messages except fatal errors]\n\\r
+ [-d, --debug[#]\n\\r
+ [-h, --help]\n");\r
+}\r
+\r
+INTN\r
+main (\r
+ INTN argc,\r
+ CHAR8 *argv[]\r
+ )\r
+{\r
+ CHAR8 *AppName;\r
+ INTN Index;\r
+ BOOLEAN ProcessMbr;\r
+ ERROR_STATUS Status;\r
+ PATH_INFO InputPathInfo;\r
+ PATH_INFO OutputPathInfo;\r
+ \r
+ ZeroMem(&InputPathInfo, sizeof(PATH_INFO));\r
+ ZeroMem(&OutputPathInfo, sizeof(PATH_INFO));\r
+ \r
+ AppName = *argv;\r
+ argv ++;\r
+ argc --;\r
+ \r
+ ProcessMbr = FALSE;\r
+\r
+ if (argc == 0) {\r
+ PrintUsage();\r
+ return 0;\r
+ }\r
+ \r
+ //\r
+ // Parse command line\r
+ //\r
+ for (Index = 0; Index < argc; Index ++) {\r
+ if ((stricmp (argv[Index], "-l") == 0) || (stricmp (argv[0], "--list") == 0)) {\r
+ ListDrive ();\r
+ return 0;\r
+ }\r
+ else if ((stricmp (argv[Index], "-m") == 0) || (stricmp (argv[Index], "--mbr") == 0)) {\r
+ ProcessMbr = TRUE;\r
+ }\r
+ else if ((stricmp (argv[Index], "-i") == 0) || (stricmp (argv[Index], "--input") == 0)) {\r
+ InputPathInfo.Path = argv[Index + 1];\r
+ InputPathInfo.Input = TRUE;\r
+ ++Index;\r
+ }\r
+ else if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {\r
+ OutputPathInfo.Path = argv[Index + 1];\r
+ OutputPathInfo.Input = FALSE;\r
+ ++Index;\r
+ }\r
+ else {\r
+ PrintUsage ();\r
+ return 1;\r
+ }\r
+ }\r
+\r
+\r
+ if ((GetPathInfo(&InputPathInfo) != ErrorSuccess) ||\r
+ (GetPathInfo(&OutputPathInfo) != ErrorSuccess)) {\r
+ return 1;\r
+ }\r
+ \r
+ //\r
+ // Process DBR (Patch or Read)\r
+ //\r
+ Status = ProcessBsOrMbr (&InputPathInfo, &OutputPathInfo, ProcessMbr);\r
+\r
+ if (Status == ErrorSuccess) {\r
+ fprintf (\r
+ stdout, \r
+ "%s %s: successful!\n", \r
+ (OutputPathInfo.Type != PathFile) ? "Write" : "Read", \r
+ ProcessMbr ? "MBR" : "DBR"\r
+ );\r
+ return 0;\r
+ } else {\r
+ fprintf (\r
+ stderr, \r
+ "%s: %s %s: failed - %s (LastError: 0x%x)!\n",\r
+ (Status == ErrorNoMbr) ? "WARNING" : "ERROR",\r
+ (OutputPathInfo.Type != PathFile) ? "Write" : "Read", \r
+ ProcessMbr ? "MBR" : "DBR", \r
+ ErrorStatusDesc[Status],\r
+ errno \r
+ );\r
+ return 1;\r
+ }\r
+}\r