]> code.delx.au - refind/commitdiff
Added support for GPT partition name for display and use in "volume"
authorsrs5694 <srs5694@users.sourceforge.net>
Mon, 28 Apr 2014 02:12:17 +0000 (22:12 -0400)
committersrs5694 <srs5694@users.sourceforge.net>
Mon, 28 Apr 2014 02:12:17 +0000 (22:12 -0400)
in manual boot stanza, in addition to filesystem name.

NEWS.txt
refind/Make.tiano
refind/Makefile
refind/config.c
refind/global.h
refind/lib.c
refind/lib.h
refind/main.c

index a864e8ee22f9f3a062026ba48e348628943686b0..eb424b080e5140c425f65085d765302b42698837 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,13 @@
 0.7.10 (?/??/2014):
 -------------------
 
+- rEFInd now uses the partition's name (as stored in the GPT data
+  structures) as a fallback for the filesystem's name if the latter can't
+  be found. Exceptions are if the partition name is one of three generic
+  names used by GPT fdisk: "Microsoft basic data", "Linux filesystem", or
+  "Apple HFS/HFS+". These are ignored in favor of the descriptive fallback
+  (e.g., "20 GiB Btrfs volume")
+
 - It's now possible to specify a volume by partition GUID number in a
   manual boot stanza. This should be more reliable (albeit also more
   awkward) than using a filesystem number (such as fs0: or fs1:).
index 538b3ddee6394fd376acf56e7cc4b8525075d641..60fe750640be6cee245a547c8bdf5c3cbe0cbe44 100644 (file)
@@ -34,7 +34,7 @@ ALL_EFILIBS     = $(EFILIB)/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevel
 #                /usr/local/UDK2010/MyWorkSpace/Build/MdeModule/RELEASE_GCC46/X64/MdeModulePkg/Core/Dxe/DxeMain/OUTPUT/DxeMain/DxeMain.obj
 
 
-SOURCE_NAMES     = config driver_support icns lib main menu screen AutoGen
+SOURCE_NAMES     = config driver_support icns lib main menu screen gpt AutoGen
 OBJS             = $(SOURCE_NAMES:=.obj)
 
 all: $(BUILDME)
index 9b74ccc985020defac276f53ac2138ab19fe6316..506ee116928b5c3b91b72e4fba4a3dd155a33d0b 100644 (file)
@@ -25,7 +25,7 @@ LOCAL_CPPFLAGS  = -I$(SRCDIR) -I$(SRCDIR)/../include -I$(SRCDIR)/../libeg -I$(SR
 LOCAL_LDFLAGS   = -L$(SRCDIR)/../libeg/ -L$(SRCDIR)/../mok/
 LOCAL_LIBS      = -leg -lmok
 
-OBJS            = main.o config.o menu.o screen.o icns.o lib.o driver_support.o
+OBJS            = main.o config.o menu.o screen.o icns.o gpt.o lib.o driver_support.o
 #OBJS            = main.o config.o menu.o screen.o icns.o lib.o mok.o driver_support.o variables.o sha256.o pecoff.o simple_file.o security_policy.o guid.o
 
 all: $(TARGET)
index c1a7b5df209ca5a3724efe1ddcad6bc4e013fc96..72bffd7f05ef6cbb28be7a17a20fd74409d5c6b3 100644 (file)
@@ -659,9 +659,9 @@ VOID ReadConfig(CHAR16 *FileName)
     MyFreePool(File.Buffer);
 } /* VOID ReadConfig() */
 
-// Finds a volume with the specified Identifier (a volume label or a number
-// followed by a colon, for the moment). If found, sets *Volume to point to
-// that volume. If not, leaves it unchanged.
+// Finds a volume with the specified Identifier (a filesystem label, a
+// partition name, a partition GUID, or a number followed by a colon). If
+// found, sets *Volume to point to that volume. If not, leaves it unchanged.
 // Returns TRUE if a match was found, FALSE if not.
 static BOOLEAN FindVolume(REFIT_VOLUME **Volume, CHAR16 *Identifier) {
    UINTN     i = 0, CountedVolumes = 0, Length;
@@ -687,7 +687,8 @@ static BOOLEAN FindVolume(REFIT_VOLUME **Volume, CHAR16 *Identifier) {
             CountedVolumes++;
          } // if
       } else { // User specified a volume by label or GUID
-         if (StriCmp(Identifier, Volumes[i]->VolName) == 0) {
+         if ((StriCmp(Identifier, Volumes[i]->VolName) == 0) ||
+             (StriCmp(Identifier, Volumes[i]->PartName) == 0)) {
             *Volume = Volumes[i];
             Found = TRUE;
          } // if
index 5058d9d0c9979a36ebea9314adff9da1282242bb..739519201dd251237ae597304ffda17eec4d748c 100644 (file)
@@ -174,6 +174,7 @@ typedef struct {
    EFI_HANDLE          DeviceHandle;
    EFI_FILE            *RootDir;
    CHAR16              *VolName;
+   CHAR16              *PartName;
    EFI_GUID            VolUuid;
    EFI_GUID            PartGuid;
    UINTN               VolNumber;
index 0053c2b51385037d61e5000096470fc26bf51bd5..dc1c1b32db62fde0ff1d825ec053da341fbc4a70 100644 (file)
@@ -48,7 +48,7 @@
 #include "screen.h"
 #include "../include/refit_call_wrapper.h"
 #include "../include/RemovableMedia.h"
-//#include "../include/UsbMass.h"
+#include "gpt.h"
 
 #ifdef __MAKEWITH_GNUEFI
 #define EfiReallocatePool ReallocatePool
@@ -86,6 +86,7 @@ CHAR16           *SelfDirPath;
 REFIT_VOLUME     *SelfVolume = NULL;
 REFIT_VOLUME     **Volumes = NULL;
 UINTN            VolumesCount = 0;
+extern GPT_DATA *gPartitions;
 
 // Maximum size for disk sectors
 #define SECTOR_SIZE 4096
@@ -712,7 +713,7 @@ static CHAR16 *SizeInIEEEUnits(UINT64 SizeInBytes) {
 // this information can be extracted.
 // The calling function is responsible for freeing the memory allocated
 // for the name string.
-static CHAR16 *GetVolumeName(IN REFIT_VOLUME *Volume) {
+static CHAR16 *GetVolumeName(REFIT_VOLUME *Volume) {
    EFI_FILE_SYSTEM_INFO    *FileSystemInfoPtr;
    CHAR16                  *FoundName = NULL;
    CHAR16                  *SISize, *TypeName;
@@ -723,14 +724,21 @@ static CHAR16 *GetVolumeName(IN REFIT_VOLUME *Volume) {
           FoundName = StrDuplicate(FileSystemInfoPtr->VolumeLabel);
        }
 
-       // Special case: rEFInd HFS+ driver always returns label of "HFS+ volume", so wipe
+       // Special case: Old versions of the rEFInd HFS+ driver always returns label of "HFS+ volume", so wipe
        // this so that we can build a new name that includes the size....
        if ((FoundName != NULL) && (StrCmp(FoundName, L"HFS+ volume") == 0) && (Volume->FSType == FS_TYPE_HFSPLUS)) {
           MyFreePool(FoundName);
           FoundName = NULL;
        } // if rEFInd HFS+ driver suspected
 
-       if (FoundName == NULL) { // filesystem has no name, so use fs type and size
+       // If no filesystem name, try to use the partition name....
+       if ((FoundName == NULL) && (Volume->PartName != NULL) && (StrLen(Volume->PartName) > 0) &&
+           !IsIn(Volume->PartName, IGNORE_PARTITION_NAMES)) {
+          FoundName = StrDuplicate(Volume->PartName);
+       } // if use partition name
+
+       // No filesystem or acceptable partition name, so use fs type and size
+       if (FoundName == NULL) {
           FoundName = AllocateZeroPool(sizeof(CHAR16) * 256);
           if (FoundName != NULL) {
              SISize = SizeInIEEEUnits(FileSystemInfoPtr->VolumeSize);
@@ -765,7 +773,7 @@ static CHAR16 *GetVolumeName(IN REFIT_VOLUME *Volume) {
 } // static CHAR16 *GetVolumeName()
 
 // Determine the unique GUID of the volume and store it.
-static VOID SetPartGuid(REFIT_VOLUME *Volume, EFI_DEVICE_PATH_PROTOCOL *DevicePath) {
+static VOID SetPartGuidAndName(REFIT_VOLUME *Volume, EFI_DEVICE_PATH_PROTOCOL *DevicePath) {
    HARDDRIVE_DEVICE_PATH    *HdDevicePath;
 
    if (Volume == NULL)
@@ -773,8 +781,11 @@ static VOID SetPartGuid(REFIT_VOLUME *Volume, EFI_DEVICE_PATH_PROTOCOL *DevicePa
 
    if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
       HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath;
-      Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature);
-   }
+      if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
+         Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature);
+         Volume->PartName = PartNameFromGuid(&(Volume->PartGuid));
+      } // if
+   } // if
 } // VOID SetPartGuid()
 
 VOID ScanVolume(REFIT_VOLUME *Volume)
@@ -819,7 +830,7 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
         NextDevicePath = NextDevicePathNode(DevicePath);
 
         if (DevicePathType(DevicePath) == MEDIA_DEVICE_PATH) {
-           SetPartGuid(Volume, DevicePath);
+           SetPartGuidAndName(Volume, DevicePath);
         }
         if (DevicePathType(DevicePath) == MESSAGING_DEVICE_PATH &&
             (DevicePathSubType(DevicePath) == MSG_USB_DP ||
@@ -861,7 +872,8 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
                 }
 
                 // look at the BlockIO protocol
-                Status = refit_call3_wrapper(BS->HandleProtocol, WholeDiskHandle, &BlockIoProtocol, (VOID **) &Volume->WholeDiskBlockIO);
+                Status = refit_call3_wrapper(BS->HandleProtocol, WholeDiskHandle, &BlockIoProtocol,
+                                             (VOID **) &Volume->WholeDiskBlockIO);
                 if (!EFI_ERROR(Status)) {
 
                     // check the media block size
@@ -987,11 +999,11 @@ VOID ScanVolumes(VOID)
     MyFreePool(Volumes);
     Volumes = NULL;
     VolumesCount = 0;
+    ForgetPartitionTables();
 
     // get all filesystem handles
     Status = LibLocateHandle(ByProtocol, &BlockIoProtocol, NULL, &HandleCount, &Handles);
     UuidList = AllocateZeroPool(sizeof(EFI_GUID) * HandleCount);
-    // was: &FileSystemProtocol
     if (Status == EFI_NOT_FOUND) {
         return;  // no filesystems. strange, but true...
     }
@@ -1002,6 +1014,7 @@ VOID ScanVolumes(VOID)
     for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
         Volume = AllocateZeroPool(sizeof(REFIT_VOLUME));
         Volume->DeviceHandle = Handles[HandleIndex];
+        AddPartitionTable(Volume);
         ScanVolume(Volume);
         if (UuidList) {
            UuidList[HandleIndex] = Volume->VolUuid;
@@ -1097,7 +1110,6 @@ VOID ScanVolumes(VOID)
             MyFreePool(SectorBuffer1);
             MyFreePool(SectorBuffer2);
         }
-
     } // for
 } /* VOID ScanVolumes() */
 
@@ -1961,9 +1973,6 @@ EFI_GUID StringAsGuid(CHAR16 * InString) {
 
 // Returns TRUE if the two GUIDs are equal, FALSE otherwise
 BOOLEAN GuidsAreEqual(EFI_GUID *Guid1, EFI_GUID *Guid2) {
-   return ((Guid1->Data1 == Guid2->Data1) && (Guid1->Data2 == Guid2->Data2) && (Guid1->Data3 == Guid2->Data3) &&
-           (Guid1->Data4[0] == Guid2->Data4[0]) && (Guid1->Data4[1] == Guid2->Data4[1]) &&
-           (Guid1->Data4[2] == Guid2->Data4[2]) && (Guid1->Data4[3] == Guid2->Data4[3]) &&
-           (Guid1->Data4[4] == Guid2->Data4[4]) && (Guid1->Data4[5] == Guid2->Data4[5]) &&
-           (Guid1->Data4[6] == Guid2->Data4[6]) && (Guid1->Data4[7] == Guid2->Data4[7]));
-} // BOOLEAN CompareGuids()
\ No newline at end of file
+   return (CompareMem(Guid1, Guid2, 16) == 0);
+} // BOOLEAN CompareGuids()
+
index bc3454cdbcd7ad913b96d5c08ff8bb4480d6ddbc..8a71249c3264df1e98d03bf531a1f6f1f9bf4c0c 100644 (file)
 #ifdef __MAKEWITH_GNUEFI
 #include "efi.h"
 #include "efilib.h"
-#pragma pack(1)
-
-/**
-  This protocol can be used on any device handle to obtain generic path/location
-  information concerning the physical device or logical device. If the handle does
-  not logically map to a physical device, the handle may not necessarily support
-  the device path protocol. The device path describes the location of the device
-  the handle is for. The size of the Device Path can be determined from the structures
-  that make up the Device Path.
-**/
-typedef struct {
-  UINT8 Type;       ///< 0x01 Hardware Device Path.
-                    ///< 0x02 ACPI Device Path.
-                    ///< 0x03 Messaging Device Path.
-                    ///< 0x04 Media Device Path.
-                    ///< 0x05 BIOS Boot Specification Device Path.
-                    ///< 0x7F End of Hardware Device Path.
-
-  UINT8 SubType;    ///< Varies by Type
-                    ///< 0xFF End Entire Device Path, or
-                    ///< 0x01 End This Instance of a Device Path and start a new
-                    ///< Device Path.
-
-  UINT8 Length[2];  ///< Specific Device Path data. Type and Sub-Type define
-                    ///< type of data. Size of data is included in Length.
-
-} EFI_DEVICE_PATH_PROTOCOL;
-
-#pragma pack()
+#define EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH
 #else
 #include "../include/tiano_includes.h"
 #endif
@@ -106,6 +78,9 @@ typedef struct {
 
 #define IS_EXTENDED_PART_TYPE(type) ((type) == 0x05 || (type) == 0x0f || (type) == 0x85)
 
+// Partition names to be ignored when setting volume name
+#define IGNORE_PARTITION_NAMES L"Microsoft basic data,Linux filesystem,Apple HFS/HFS+"
+
 EFI_STATUS InitRefitLib(IN EFI_HANDLE ImageHandle);
 VOID UninitRefitLib(VOID);
 EFI_STATUS ReinitRefitLib(VOID);
index 25c7a5a1d8c632ad3e56d5ee824f61477da56023..3905d0073d0a785bad642d13c7548a1fa73308be 100644 (file)
@@ -49,6 +49,7 @@
 #include "icns.h"
 #include "menu.h"
 #include "mok.h"
+#include "gpt.h"
 #include "security_policy.h"
 #include "../include/Handle.h"
 #include "../include/refit_call_wrapper.h"
@@ -143,6 +144,8 @@ REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20,
 
 EFI_GUID GlobalGuid = EFI_GLOBAL_VARIABLE;
 
+GPT_DATA *gPartitions = NULL;
+
 // Structure used to hold boot loader filenames and time stamps in
 // a linked list; used to sort entries within a directory.
 struct LOADER_LIST {
@@ -159,7 +162,7 @@ static VOID AboutrEFInd(VOID)
 {
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.9.2");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.9.3");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith");
@@ -1329,11 +1332,11 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) {
    BOOLEAN                 ScanFallbackLoader = TRUE;
    BOOLEAN                 FoundBRBackup = FALSE;
 
-   MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
-   if (GlobalConfig.ScanAllLinux)
-      MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
-
    if ((Volume->RootDir != NULL) && (Volume->VolName != NULL) && (Volume->IsReadable)) {
+      MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
+      if (GlobalConfig.ScanAllLinux)
+         MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
+
       // check for Mac OS X boot loader
       if (ShouldScan(Volume, L"System\\Library\\CoreServices")) {
          StrCpy(FileName, MACOSX_LOADER_PATH);