]> code.delx.au - refind/blobdiff - refind/lib.c
Protection against loading invalid EFI drivers; bug fix for using
[refind] / refind / lib.c
index 601038c741f63100dfd847df5d06cda4ba839b28..f0b0e6f169fd0dd882cf650090d75bd65be1e195 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 /*
- * Modifications copyright (c) 2012 Roderick W. Smith
+ * Modifications copyright (c) 2012-2013 Roderick W. Smith
  * 
  * Modifications distributed under the terms of the GNU General Public
  * License (GPL) version 3 (GPLv3), a copy of which must be distributed
  * with this source code or binaries made from it.
- * 
+ *
  */
 
 #include "global.h"
@@ -73,6 +73,7 @@ EFI_DEVICE_PATH EndDevicePath[] = {
 #define REISERFS_SUPER_MAGIC_STRING      "ReIsErFs"
 #define REISER2FS_SUPER_MAGIC_STRING     "ReIsEr2Fs"
 #define REISER2FS_JR_SUPER_MAGIC_STRING  "ReIsEr3Fs"
+#define BTRFS_SIGNATURE                  "_BHRfS_M"
 
 // variables
 
@@ -114,10 +115,11 @@ static VOID UninitVolumes(VOID);
 // isn't present.
 VOID CleanUpPathNameSlashes(IN OUT CHAR16 *PathName) {
    CHAR16   *NewName;
-   UINTN    i, FinalChar = 0;
+   UINTN    i, Length, FinalChar = 0;
    BOOLEAN  LastWasSlash = FALSE;
 
-   NewName = AllocateZeroPool(sizeof(CHAR16) * (StrLen(PathName) + 2));
+   Length = StrLen(PathName);
+   NewName = AllocateZeroPool(sizeof(CHAR16) * (Length + 2));
    if (NewName != NULL) {
       for (i = 0; i < StrLen(PathName); i++) {
          if ((PathName[i] == L'/') || (PathName[i] == L'\\')) {
@@ -407,6 +409,9 @@ static CHAR16 *FSTypeName(IN UINT32 TypeCode) {
       case FS_TYPE_REISERFS:
          retval = L" ReiserFS";
          break;
+      case FS_TYPE_BTRFS:
+         retval = L" Btrfs";
+         break;
       case FS_TYPE_ISO9660:
          retval = L" ISO-9660";
          break;
@@ -458,6 +463,12 @@ static UINT32 IdentifyFilesystemType(IN UINT8 *Buffer, IN UINTN BufferSize) {
          } // if
       } // search for ReiserFS magic
 
+      if (BufferSize >= (65536 + 64 + 8)) {
+         MagicString = (char*) (Buffer + 65536 + 64);
+         if (CompareMem(MagicString, BTRFS_SIGNATURE, 8) == 0)
+            return FS_TYPE_BTRFS;
+      } // search for Btrfs magic
+
       if (BufferSize >= (1024 + 2)) {
          Magic16 = (UINT16*) (Buffer + 1024);
          if ((*Magic16 == HFSPLUS_MAGIC1) || (*Magic16 == HFSPLUS_MAGIC2)) {
@@ -467,7 +478,7 @@ static UINT32 IdentifyFilesystemType(IN UINT8 *Buffer, IN UINTN BufferSize) {
    } // if (Buffer != NULL)
 
    return FoundType;
-}
+} // UINT32 IdentifyFilesystemType()
 
 static VOID ScanVolumeBootcode(REFIT_VOLUME *Volume, BOOLEAN *Bootable)
 {
@@ -626,21 +637,27 @@ static VOID ScanVolumeBootcode(REFIT_VOLUME *Volume, BOOLEAN *Bootable)
     }
 } /* VOID ScanVolumeBootcode() */
 
-// default volume badge icon based on disk kind
-static VOID ScanVolumeDefaultIcon(IN OUT REFIT_VOLUME *Volume)
+// Set default volume badge icon based on /.VolumeBadge.{icns|png} file or disk kind
+static VOID SetVolumeBadgeIcon(IN OUT REFIT_VOLUME *Volume)
 {
-    switch (Volume->DiskKind) {
-       case DISK_KIND_INTERNAL:
-          Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_INTERNAL);
-          break;
-       case DISK_KIND_EXTERNAL:
-          Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_EXTERNAL);
-          break;
-       case DISK_KIND_OPTICAL:
-          Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_OPTICAL);
-          break;
-    } // switch()
-}
+   if (Volume->VolBadgeImage == NULL) {
+      Volume->VolBadgeImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeBadge", 128);
+   }
+
+   if (Volume->VolBadgeImage == NULL) {
+      switch (Volume->DiskKind) {
+          case DISK_KIND_INTERNAL:
+             Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_INTERNAL);
+             break;
+          case DISK_KIND_EXTERNAL:
+             Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_EXTERNAL);
+             break;
+          case DISK_KIND_OPTICAL:
+             Volume->VolBadgeImage = BuiltinIcon(BUILTIN_ICON_VOL_OPTICAL);
+             break;
+      } // switch()
+   }
+} // VOID SetVolumeBadgeIcon()
 
 // Return a string representing the input size in IEEE-1541 units.
 // The calling function is responsible for freeing the allocated memory.
@@ -834,9 +851,6 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
         Volume->HasBootCode = FALSE;
     }
 
-    // default volume icon based on disk kind
-    ScanVolumeDefaultIcon(Volume);
-
     // open the root directory of the volume
     Volume->RootDir = LibOpenRoot(Volume->DeviceHandle);
     if (Volume->RootDir == NULL) {
@@ -848,9 +862,10 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
 
     Volume->VolName = GetVolumeName(Volume);
 
-    // get custom volume icon if present
-    if (!Volume->VolBadgeImage)
-       Volume->VolBadgeImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeBadge", 32);
+    // Set volume icon based on .VolumeBadge icon or disk kind
+    SetVolumeBadgeIcon(Volume);
+
+    // get custom volume icons if present
     if (!Volume->VolIconImage)
        Volume->VolIconImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeIcon", 128);
 } // ScanVolume()
@@ -908,7 +923,7 @@ static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_I
                 if (!Bootable)
                     Volume->HasBootCode = FALSE;
 
-                ScanVolumeDefaultIcon(Volume);
+                SetVolumeBadgeIcon(Volume);
 
                 AddListElement((VOID ***) &Volumes, &VolumesCount, Volume);
 
@@ -1429,7 +1444,7 @@ VOID MergeStrings(IN OUT CHAR16 **First, IN CHAR16 *Second, CHAR16 AddChar) {
 CHAR16 *FindExtension(IN CHAR16 *Path) {
    CHAR16     *Extension;
    BOOLEAN    Found = FALSE, FoundSlash = FALSE;
-   UINTN       i;
+   INTN       i;
 
    Extension = AllocateZeroPool(sizeof(CHAR16));
    if (Path) {