]> code.delx.au - refind/blobdiff - refind/lib.c
Improved submenu and information menu appearance over a full-screen
[refind] / refind / lib.c
index b04b2d41975b9a238f0c7a25312ce58a27d71d58..8235feab84d444375ef9febda95084f447f7008d 100644 (file)
@@ -93,8 +93,8 @@ UINTN            VolumesCount = 0;
 #define SAMPLE_SIZE 69632 /* 68 KiB -- ReiserFS superblock begins at 64 KiB */
 
 // Default names for volume badges (mini-icon to define disk type) and icons
-#define VOLUME_BADGE_NAME L".VolumeBadge.icns"
-#define VOLUME_ICON_NAME L".VolumeIcon.icns"
+#define VOLUME_BADGE_NAMES L".VolumeBadge.icns,.VolumeBadge.png"
+#define VOLUME_ICON_NAMES L".VolumeIcon.icns,.VolumeIcon.png"
 
 // functions
 
@@ -849,11 +849,10 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
     Volume->VolName = GetVolumeName(Volume);
 
     // get custom volume icon if present
-    if (FileExists(Volume->RootDir, VOLUME_BADGE_NAME))
-        Volume->VolBadgeImage = LoadIcns(Volume->RootDir, VOLUME_BADGE_NAME, 32);
-    if (FileExists(Volume->RootDir, VOLUME_ICON_NAME)) {
-       Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAME, 128);
-    }
+    if (!Volume->VolBadgeImage)
+       Volume->VolBadgeImage = LoadIcns(Volume->RootDir, VOLUME_BADGE_NAMES, 32);
+    if (!Volume->VolIconImage)
+       Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAMES, 128);
 } // ScanVolume()
 
 static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_INFO *MbrEntry)
@@ -921,15 +920,15 @@ static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_I
 VOID ScanVolumes(VOID)
 {
     EFI_STATUS              Status;
-    UINTN                   HandleCount = 0;
-    UINTN                   HandleIndex;
     EFI_HANDLE              *Handles;
     REFIT_VOLUME            *Volume, *WholeDiskVolume;
-    UINTN                   VolumeIndex, VolumeIndex2;
     MBR_PARTITION_INFO      *MbrTable;
+    UINTN                   HandleCount = 0;
+    UINTN                   HandleIndex;
+    UINTN                   VolumeIndex, VolumeIndex2;
     UINTN                   PartitionIndex;
+    UINTN                   SectorSum, i, VolNumber = 0;
     UINT8                   *SectorBuffer1, *SectorBuffer2;
-    UINTN                   SectorSum, i;
 
     MyFreePool(Volumes);
     Volumes = NULL;
@@ -949,6 +948,10 @@ VOID ScanVolumes(VOID)
         Volume = AllocateZeroPool(sizeof(REFIT_VOLUME));
         Volume->DeviceHandle = Handles[HandleIndex];
         ScanVolume(Volume);
+        if (Volume->IsReadable)
+           Volume->VolNumber = VolNumber++;
+        else
+           Volume->VolNumber = VOL_UNREADABLE;
 
         AddListElement((VOID ***) &Volumes, &VolumesCount, Volume);
 
@@ -1316,20 +1319,22 @@ CHAR16 * Basename(IN CHAR16 *Path)
     return FileName;
 }
 
-// Replaces a filename extension of ".efi" with the specified string
-// (Extension). If the input Path doesn't end in ".efi", Extension
-// is added to the existing filename.
-VOID ReplaceEfiExtension(IN OUT CHAR16 *Path, IN CHAR16 *Extension)
-{
-    UINTN PathLen;
-
-    PathLen = StrLen(Path);
-    // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
-    if ((PathLen >= 4) && ((StriCmp(&Path[PathLen - 4], L".efi") == 0) || (StriCmp(&Path[PathLen - 4], L".EFI") == 0))) {
-       Path[PathLen - 4] = 0;
-    } // if
-    StrCat(Path, Extension);
-} // VOID ReplaceEfiExtension()
+// Remove the .efi extension from FileName -- for instance, if FileName is
+// "fred.efi", returns "fred". If the filename contains no .efi extension,
+// returns a copy of the original input.
+CHAR16 * StripEfiExtension(CHAR16 *FileName) {
+   UINTN  Length;
+   CHAR16 *Copy = NULL;
+
+   if ((FileName != NULL) && ((Copy = StrDuplicate(FileName)) != NULL)) {
+      Length = StrLen(Copy);
+      // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
+      if ((Length >= 4) && ((StriCmp(&Copy[Length - 4], L".efi") == 0) || (StriCmp(&Copy[Length - 4], L".EFI") == 0))) {
+         Copy[Length - 4] = 0;
+      } // if
+   } // if
+   return Copy;
+} // CHAR16 * StripExtension()
 
 //
 // memory string search
@@ -1520,6 +1525,39 @@ VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **Devi
    MyFreePool(DeviceString);
 } // VOID FindVolumeAndFilename()
 
+// Splits a volume/filename string (e.g., "fs0:\EFI\BOOT") into separate
+// volume and filename components (e.g., "fs0" and "\EFI\BOOT"), returning
+// the filename component in the original *Path variable and the split-off
+// volume component in the *VolName variable.
+// Returns TRUE if both components are found, FALSE otherwise.
+BOOLEAN SplitVolumeAndFilename(IN OUT CHAR16 **Path, OUT CHAR16 **VolName) {
+   UINTN i = 0, Length;
+   CHAR16 *Filename;
+
+   if (*Path == NULL)
+      return FALSE;
+
+   if (*VolName != NULL) {
+      MyFreePool(*VolName);
+      *VolName = NULL;
+   }
+
+   Length = StrLen(*Path);
+   while ((i < Length) && ((*Path)[i] != L':')) {
+      i++;
+   } // while
+
+   if (i < Length) {
+      Filename = StrDuplicate((*Path) + i + 1);
+      (*Path)[i] = 0;
+      *VolName = *Path;
+      *Path = Filename;
+      return TRUE;
+   } else {
+      return FALSE;
+   }
+} // BOOLEAN SplitVolumeAndFilename()
+
 // Returns all the digits in the input string, including intervening
 // non-digit characters. For instance, if InString is "foo-3.3.4-7.img",
 // this function returns "3.3.4-7". If InString contains no digits,
@@ -1603,7 +1641,7 @@ BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) {
 
 // Implement FreePool the way it should have been done to begin with, so that
 // it doesn't throw an ASSERT message if fed a NULL pointer....
-VOID MyFreePool(IN OUT VOID *Pointer) {
+VOID MyFreePool(IN VOID *Pointer) {
    if (Pointer != NULL)
       FreePool(Pointer);
 }