]> code.delx.au - refind/blobdiff - refind/main.c
Applied old rEFIt commits r467 and r472, which improve Mac legacy
[refind] / refind / main.c
index 9e653b49109ad9e5f30311e02475c4f64184773c..76241e52d8df3279104d3b49c3316e4c45ed89eb 100644 (file)
@@ -76,7 +76,8 @@
 //
 // constants
 
-#define MACOSX_LOADER_PATH      L"System\\Library\\CoreServices\\boot.efi"
+#define MACOSX_LOADER_DIR      L"System\\Library\\CoreServices"
+#define MACOSX_LOADER_PATH      ( MACOSX_LOADER_DIR L"\\boot.efi" )
 #if defined (EFIX64)
 #define SHELL_NAMES             L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellx64.efi,\\shell.efi,\\shellx64.efi"
 #define GPTSYNC_NAMES           L"\\EFI\\tools\\gptsync.efi,\\EFI\\tools\\gptsync_x64.efi"
@@ -175,7 +176,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.3.4");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.4.2");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith");
@@ -1035,42 +1036,10 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo
    MyFreePool(PathOnly);
 } // VOID SetLoaderDefaults()
 
-// // Add a network (PXE) EFI boot loader to the list, using automatic settings
-// // for icons, options, etc.
-// LOADER_ENTRY * AddNetbootLoaderEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Volume) {
-//    LOADER_ENTRY      *Entry;
-// 
-//    Print(L"Adding iPXE entry for '%s'\n", LoaderTitle);
-//    PauseForKey();
-//    CleanUpPathNameSlashes(LoaderPath);
-//    Entry = InitializeLoaderEntry(NULL);
-//    if (Entry != NULL) {
-//       Entry->Title = StrDuplicate((LoaderTitle != NULL) ? LoaderTitle : LoaderPath);
-//       Entry->me.Title = AllocateZeroPool(sizeof(CHAR16) * 256);
-//       // Extra space at end of Entry->me.Title enables searching on Volume->VolName even if another volume
-//       // name is identical except for something added to the end (e.g., VolB1 vs. VolB12).
-//       SPrint(Entry->me.Title, 255, L"NetBoot %s", (LoaderTitle != NULL) ? LoaderTitle : LoaderPath);
-//       Entry->me.Row = 0;
-//       if ((LoaderPath != NULL) && (LoaderPath[0] != L'\\')) {
-//          Entry->LoaderPath = StrDuplicate(L"\\");
-//       } else {
-//          Entry->LoaderPath = NULL;
-//       }
-//       MergeStrings(&(Entry->LoaderPath), LoaderPath, 0);
-//       Entry->VolName = Volume->VolName;
-//       Entry->DevicePath = FileDevicePath(Volume->DeviceHandle, Entry->LoaderPath);
-//       SetLoaderDefaults(Entry, LoaderPath, Volume);
-//       GenerateSubScreen(Entry, Volume);
-//       AddMenuEntry(&MainMenu, (REFIT_MENU_ENTRY *)Entry);
-//    }
-// 
-//    return(Entry);
-// } // LOADER_ENTRY * AddLoaderEntry()
-
 // Add a specified EFI boot loader to the list, using automatic settings
 // for icons, options, etc.
 LOADER_ENTRY * AddLoaderEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Volume) {
-   LOADER_ENTRY      *Entry;
+   LOADER_ENTRY  *Entry;
 
    CleanUpPathNameSlashes(LoaderPath);
    Entry = InitializeLoaderEntry(NULL);
@@ -1406,17 +1375,15 @@ CHAR16* RuniPXEDiscover(EFI_HANDLE Volume)
    EFI_STATUS       Status;
    EFI_DEVICE_PATH  *FilePath;
    EFI_HANDLE       iPXEHandle;
-   CHAR16           *boot_info;
-   UINTN            boot_info_size = 256 * sizeof(CHAR16);
+   CHAR16           *boot_info = NULL;
+   UINTN            boot_info_size = 0;
 
    FilePath = FileDevicePath (Volume, IPXE_DISCOVER_NAME);
    Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, FilePath,
                                 NULL, 0, &iPXEHandle);
-   if (Status != 0) {
+   if (Status != 0)
       return NULL;
-   } // if
 
-   boot_info = AllocatePool(256 * sizeof(CHAR16));
    Status = refit_call3_wrapper(BS->StartImage, iPXEHandle, &boot_info_size, &boot_info);
 
    return boot_info;
@@ -1463,9 +1430,9 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) {
          MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
 
       // check for Mac OS X boot loader
-      if (ShouldScan(Volume, L"System\\Library\\CoreServices")) {
+      if (ShouldScan(Volume, MACOSX_LOADER_DIR)) {
          StrCpy(FileName, MACOSX_LOADER_PATH);
-         if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"boot.efi", GlobalConfig.DontScanFiles)) {
+         if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, MACOSX_LOADER_DIR, L"boot.efi", GlobalConfig.DontScanFiles)) {
             AddLoaderEntry(FileName, L"Mac OS X", Volume);
             if (DuplicatesFallback(Volume, FileName))
                ScanFallbackLoader = FALSE;
@@ -1473,7 +1440,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) {
 
          // check for XOM
          StrCpy(FileName, L"System\\Library\\CoreServices\\xom.efi");
-         if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"boot.efi", GlobalConfig.DontScanFiles)) {
+         if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, MACOSX_LOADER_DIR, L"xom.efi", GlobalConfig.DontScanFiles)) {
             AddLoaderEntry(FileName, L"Windows XP (XoM)", Volume);
             if (DuplicatesFallback(Volume, FileName))
                ScanFallbackLoader = FALSE;
@@ -1483,7 +1450,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) {
       // check for Microsoft boot loader/menu
       if (ShouldScan(Volume, L"EFI\\Microsoft\\Boot")) {
          StrCpy(FileName, L"EFI\\Microsoft\\Boot\\bkpbootmgfw.efi");
-         if (FileExists(Volume->RootDir, FileName) &&  !FilenameIn(Volume, Directory, L"bkpbootmgfw.efi",
+         if (FileExists(Volume->RootDir, FileName) &&  !FilenameIn(Volume, L"EFI\\Microsoft\\Boot", L"bkpbootmgfw.efi",
              GlobalConfig.DontScanFiles)) {
             AddLoaderEntry(FileName, L"Microsoft EFI boot (Boot Repair backup)", Volume);
             FoundBRBackup = TRUE;
@@ -1491,7 +1458,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) {
                ScanFallbackLoader = FALSE;
          }
          StrCpy(FileName, L"EFI\\Microsoft\\Boot\\bootmgfw.efi");
-         if (FileExists(Volume->RootDir, FileName) &&  !FilenameIn(Volume, Directory, L"bootmgfw.efi", GlobalConfig.DontScanFiles)) {
+         if (FileExists(Volume->RootDir, FileName) &&  !FilenameIn(Volume, L"EFI\\Microsoft\\Boot", L"bootmgfw.efi", GlobalConfig.DontScanFiles)) {
             if (FoundBRBackup)
                AddLoaderEntry(FileName, L"Supposed Microsoft EFI boot (probably GRUB)", Volume);
             else
@@ -1679,6 +1646,21 @@ static EFI_STATUS ActivateMbrPartition(IN EFI_BLOCK_IO *BlockIO, IN UINTN Partit
     return EFI_SUCCESS;
 } /* static EFI_STATUS ActivateMbrPartition() */
 
+static EFI_GUID AppleVariableVendorID = { 0x7C436110, 0xAB2A, 0x4BBB, 0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82 };
+
+static EFI_STATUS WriteBootDiskHint(IN EFI_DEVICE_PATH *WholeDiskDevicePath)
+{
+   EFI_STATUS          Status;
+
+   Status = refit_call5_wrapper(RT->SetVariable, L"BootCampHD", &AppleVariableVendorID,
+                                EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                                GetDevicePathSize(WholeDiskDevicePath), WholeDiskDevicePath);
+   if (EFI_ERROR(Status))
+      return Status;
+
+   return EFI_SUCCESS;
+}
+
 // early 2006 Core Duo / Core Solo models
 static UINT8 LegacyLoaderDevicePath1Data[] = {
     0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
@@ -1752,9 +1734,11 @@ static VOID StartLegacy(IN LEGACY_ENTRY *Entry, IN CHAR16 *SelectionName)
                       (UGAHeight - BootLogoImage->Height) >> 1,
                       &StdBackgroundPixel);
 
-    if (Entry->Volume->IsMbrPartition) {
+    if (Entry->Volume->IsMbrPartition)
         ActivateMbrPartition(Entry->Volume->WholeDiskBlockIO, Entry->Volume->MbrPartitionIndex);
-    }
+
+    if (Entry->Volume->DiskKind != DISK_KIND_OPTICAL && Entry->Volume->WholeDiskDevicePath != NULL)
+       WriteBootDiskHint(Entry->Volume->WholeDiskDevicePath);
 
     ExtractLegacyLoaderPaths(DiscoveredPathList, MAX_DISCOVERED_PATHS, LegacyLoaderList);
 
@@ -2385,7 +2369,8 @@ static VOID FindTool(CHAR16 *Locations, CHAR16 *Names, CHAR16 *Description, UINT
          PathName = StrDuplicate(DirName);
          MergeStrings(&PathName, FileName, (StriCmp(PathName, L"\\") == 0) ? 0 : L'\\');
          for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
-            if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, PathName))) {
+            if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, PathName)) &&
+                IsValidLoader(Volumes[VolumeIndex]->RootDir, PathName)) {
                SPrint(FullDescription, 255, L"%s at %s on %s", Description, PathName, Volumes[VolumeIndex]->VolName);
                AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, PathName, FullDescription, BuiltinIcon(Icon), 'S', FALSE);
             } // if
@@ -2451,7 +2436,7 @@ static VOID ScanForTools(VOID) {
          case TAG_SHELL:
             j = 0;
             while ((FileName = FindCommaDelimited(SHELL_NAMES, j++)) != NULL) {
-               if (FileExists(SelfRootDir, FileName)) {
+               if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
                   AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL),
                                'S', FALSE);
                }
@@ -2462,7 +2447,7 @@ static VOID ScanForTools(VOID) {
          case TAG_GPTSYNC:
             j = 0;
             while ((FileName = FindCommaDelimited(GPTSYNC_NAMES, j++)) != NULL) {
-               if (FileExists(SelfRootDir, FileName)) {
+               if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
                   AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Hybrid MBR tool", BuiltinIcon(BUILTIN_ICON_TOOL_PART),
                                'P', FALSE);
                } // if
@@ -2474,7 +2459,7 @@ static VOID ScanForTools(VOID) {
          case TAG_GDISK:
             j = 0;
             while ((FileName = FindCommaDelimited(GDISK_NAMES, j++)) != NULL) {
-               if (FileExists(SelfRootDir, FileName)) {
+               if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
                   AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"disk partitioning tool",
                                BuiltinIcon(BUILTIN_ICON_TOOL_PART), 'G', FALSE);
                } // if
@@ -2486,7 +2471,7 @@ static VOID ScanForTools(VOID) {
          case TAG_NETBOOT:
             j = 0;
             while ((FileName = FindCommaDelimited(NETBOOT_NAMES, j++)) != NULL) {
-               if (FileExists(SelfRootDir, FileName)) {
+               if (FileExists(SelfRootDir, FileName) && IsValidLoader(SelfRootDir, FileName)) {
                   AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, L"Netboot",
                                BuiltinIcon(BUILTIN_ICON_TOOL_NETBOOT), 'N', FALSE);
                } // if
@@ -2498,7 +2483,8 @@ static VOID ScanForTools(VOID) {
          case TAG_APPLE_RECOVERY:
             FileName = StrDuplicate(L"\\com.apple.recovery.boot\\boot.efi");
             for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
-               if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName))) {
+               if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) &&
+                   IsValidLoader(Volumes[VolumeIndex]->RootDir, FileName)) {
                   SPrint(Description, 255, L"Apple Recovery on %s", Volumes[VolumeIndex]->VolName);
                   AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,
                                BuiltinIcon(BUILTIN_ICON_TOOL_APPLE_RESCUE), 'R', TRUE);
@@ -2514,6 +2500,7 @@ static VOID ScanForTools(VOID) {
                SplitVolumeAndFilename(&FileName, &VolName);
                for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) {
                   if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) &&
+                      IsValidLoader(Volumes[VolumeIndex]->RootDir, FileName) &&
                       ((VolName == NULL) || (StriCmp(VolName, Volumes[VolumeIndex]->VolName) == 0))) {
                      SPrint(Description, 255, L"Microsoft Recovery on %s", Volumes[VolumeIndex]->VolName);
                      AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description,