]> code.delx.au - refind/commitdiff
Worked around bug/quirk in some EFIs that prevented filesystem drivers
authorsrs5694 <srs5694@users.sourceforge.net>
Mon, 25 Jan 2016 14:39:13 +0000 (09:39 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Mon, 25 Jan 2016 14:39:13 +0000 (09:39 -0500)
from accessing their filesystems.

Makefile
NEWS.txt
debian/copyright
refind-install
refind/driver_support.c
refind/driver_support.h
refind/global.h
refind/main.c

index 360102810430d00c0568b085d20e8a4fc8fcd1f0..588fe2df072ffc9af2ba0cec4d29299e6d401c97 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ MOK_DIR=mok
 GPTSYNC_DIR=gptsync
 EFILIB_DIR=EfiLib
 export EDK2BASE=/usr/local/UDK2014/MyWorkSpace
-export REFIND_VERSION='L"0.10.1.2"'
+export REFIND_VERSION='L"0.10.1.3"'
 
 # The "all" target builds with the TianoCore library if possible, but falls
 # back on the more easily-installed GNU-EFI library if TianoCore isn't
index 79f651ece562639fb9e202af854c149a8dcce170..183d7615d74cd84f79283e7bb0613c8ae665ec73 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,7 +1,16 @@
 0.10.2 (?/??/2016):
 -------------------
 
-- Fixed bug that caused custom volume badges (vol_????.png) to be read only
+- Worked around bug/quirk in some EFIs (in HP ProBook 6470b laptop, at
+  least) that prevented EFI filesystem drivers from working. (Drivers would
+  load but not provide access to filesystems.)
+
+- Fixed refind-install bug that caused --usedefault option to not work in OS
+  X. (This bug did not affect Linux.)
+
+- Improved Secure Boot detection in refind-install in Linux.
+
+- Fixed bug that caused custom volume badges (vol_*.png) to be read only
   from default location ("icons" subdirectory), effectively eliminating the
   ability to adjust them.
 
index 21fab0de85247d0f05b91a421fcd98d9288b8496..a38d0e43ea8be7e08bb7d445b65c19a7af96bc50 100644 (file)
@@ -5,11 +5,11 @@ Source: http://www.rodsbooks.com/refind
 
 Files: *
 Copyright: 2006 Christoph Pfisterer
-           2012 Roderick W. Smith
+           2012-2016 Roderick W. Smith
 License: BSD-3-clause and GPL-3+
 
 Files: debian/*
-Copyright: 2014 Roderick W. Smith
+Copyright: 2014-2016 Roderick W. Smith
            2015 Tianon Gravi
 License: GPL-3+
 
@@ -52,7 +52,7 @@ Files: refind/*
        libeg/image.c
        libeg/screen.c
 Copyright: 2006-2010 Christoph Pfisterer
-           2012-2015 Roderick W. Smith
+           2012-2016 Roderick W. Smith
 License: BSD-3-clause and GPL-3+
 
 Files: refind/icns.c
@@ -72,7 +72,12 @@ License: unrestricted-crc32
  without restriction.
 
 Files: refind/driver_support.[ch]
-       libeg/efiConsoleControl.h
+Copyright: 2006-2011 Intel Corporation
+           2006-2010 Christoph Pfisterer
+           2012-2016 Roderick W. Smith
+License: BSD-2-clause and BSD-3-clause and GPL-3+
+
+Files: libeg/efiConsoleControl.h
        libeg/efiUgaDraw.h
 Copyright: 2006-2011 Intel Corporation
 License: BSD-2-clause
index 37fa8110f176526da9d04fca3a951c5f9fd9eeef..84d661509479bfa0ec29764d4b43268384e06c71 100755 (executable)
@@ -39,6 +39,7 @@
 
 # Revision history:
 #
+# 0.10.2  -- Improved Secure Boot detection in Linux & fixed --usedefault in OS X.
 # 0.10.1  -- Improve extraction of default kernel options from /proc/cmdline.
 #            Add support for AMD64 (aka AARCH64, aa64) platform. Added
 #            warning when --alldrivers used without --usedefault.
index a547d654d25e6f2b9fc3f08f9234b3191a1cdfcd..3faf9846ee68f6b26baf51cbb13d4d4b432a6e40 100644 (file)
@@ -1,12 +1,7 @@
 /*
- * File to implement LibScanHandleDatabase(), which is used by rEFInd's
- * driver-loading code (inherited from rEFIt), but which has not been
- * implemented in GNU-EFI and seems to have been dropped from current
- * versions of the Tianocore library. This function was taken from a git
- * site with EFI code, but some of the constants it uses were taken from
- * a more recent EDK2 package (see below for details). The original files
- * bore the following copyright notice:
- *
+ * Functions related to drivers. Original copyright notices below....
+ */
+/*
  * Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
  * This program and the accompanying materials are licensed and made available under
  * the terms and conditions of the BSD License that accompanies this distribution.
  * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  *
  */
+/*
+ * refit/main.c
+ * Main code for the boot menu
+ *
+ * Copyright (c) 2006-2010 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Modifications copyright (c) 2012-2016 Roderick W. Smith
+ *
+ * Modifications distributed under the terms of the GNU General Public
+ * License (GPL) version 3 (GPLv3), or (at your option) any later version.
+ *
+ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #include "driver_support.h"
 #include "lib.h"
+#include "mystrings.h"
+#include "screen.h"
 #include "../include/refit_call_wrapper.h"
 
+#if defined (EFIX64)
+#define DRIVER_DIRS             L"drivers,drivers_x64"
+#elif defined (EFI32)
+#define DRIVER_DIRS             L"drivers,drivers_ia32"
+#elif defined (EFIAARCH64)
+#define DRIVER_DIRS             L"drivers,drivers_aa64"
+#endif
+
 #ifdef __MAKEWITH_GNUEFI
 // Following "global" constants are from EDK2's AutoGen.c....
 EFI_GUID gEfiLoadedImageProtocolGuid = { 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
@@ -33,22 +94,64 @@ EFI_GUID gEfiDriverDiagnostics2ProtocolGuid = { 0x4D330321, 0x025F, 0x4AAC, { 0x
 EFI_GUID gEfiComponentNameProtocolGuid = { 0x107A772C, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }};
 EFI_GUID gEfiComponentName2ProtocolGuid = { 0x6A7A5CFF, 0xE8D9, 0x4F70, { 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14 }};
 EFI_GUID gEfiDevicePathProtocolGuid = { 0x09576E91, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
-#endif
+EFI_GUID gEfiDiskIoProtocolGuid = { 0xCE345171, 0xBA0B, 0x11D2, { 0x8E, 0x4F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+EFI_GUID gEfiBlockIoProtocolGuid = { 0x964E5B21, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+EFI_GUID gEfiSimpleFileSystemProtocolGuid = { 0x964E5B22, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+
+struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
+struct EFI_FILE_PROTOCOL;
 
-// Below is from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec;
-// Seems to have been replaced by ParseHandleDatabaseByRelationshipWithType(), but the latter isn't working for me....
+typedef
 EFI_STATUS
-LibScanHandleDatabase (
-  EFI_HANDLE  DriverBindingHandle, OPTIONAL
-  UINT32      *DriverBindingHandleIndex, OPTIONAL
-  EFI_HANDLE  ControllerHandle, OPTIONAL
-  UINT32      *ControllerHandleIndex, OPTIONAL
-  UINTN       *HandleCount,
-  EFI_HANDLE  **HandleBuffer,
-  UINT32      **HandleType
-  )
+(EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)(
+  IN struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *This,
+  OUT struct EFI_FILE_PROTOCOL                 **Root
+  );
 
-{
+typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
+  UINT64                                      Revision;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;
+} EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
+
+typedef struct _EFI_FILE_PROTOCOL {
+  UINT64                Revision;
+  EFI_FILE_OPEN         Open;
+  EFI_FILE_CLOSE        Close;
+  EFI_FILE_DELETE       Delete;
+  EFI_FILE_READ         Read;
+  EFI_FILE_WRITE        Write;
+  EFI_FILE_GET_POSITION GetPosition;
+  EFI_FILE_SET_POSITION SetPosition;
+  EFI_FILE_GET_INFO     GetInfo;
+  EFI_FILE_SET_INFO     SetInfo;
+  EFI_FILE_FLUSH        Flush;
+} EFI_FILE_PROTOCOL;
+
+typedef struct _EFI_BLOCK_IO_PROTOCOL {
+  UINT64             Revision;
+  EFI_BLOCK_IO_MEDIA *Media;
+  EFI_BLOCK_RESET    Reset;
+  EFI_BLOCK_READ     ReadBlocks;
+  EFI_BLOCK_WRITE    WriteBlocks;
+  EFI_BLOCK_FLUSH    FlushBlocks;
+} EFI_BLOCK_IO_PROTOCOL;
+#endif
+
+/* LibScanHandleDatabase() is used by rEFInd's driver-loading code (inherited
+ * from rEFIt), but has not been implemented in GNU-EFI and seems to have been
+ * dropped from current versions of the Tianocore library. This function was
+ * taken from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec,
+ * The original files are copyright 2006-2011 Intel and BSD-licensed. Minor
+ * modifications by Roderick Smith are GPLv3.
+ */
+EFI_STATUS
+LibScanHandleDatabase (EFI_HANDLE  DriverBindingHandle, OPTIONAL
+                       UINT32      *DriverBindingHandleIndex, OPTIONAL
+                       EFI_HANDLE  ControllerHandle, OPTIONAL
+                       UINT32      *ControllerHandleIndex, OPTIONAL
+                       UINTN       *HandleCount,
+                       EFI_HANDLE  **HandleBuffer,
+                       UINT32      **HandleType) {
   EFI_STATUS                          Status;
   UINTN                               HandleIndex;
   EFI_GUID                            **ProtocolGuidArray;
@@ -59,14 +162,12 @@ LibScanHandleDatabase (
   UINTN                               OpenInfoIndex;
   UINTN                               ChildIndex;
   BOOLEAN                             DriverBindingHandleIndexValid;
-//  BOOLEAN                             ControllerHandleIndexValid;
 
   DriverBindingHandleIndexValid = FALSE;
   if (DriverBindingHandleIndex != NULL) {
     *DriverBindingHandleIndex = 0xffffffff;
   }
 
-//  ControllerHandleIndexValid = FALSE;
   if (ControllerHandleIndex != NULL) {
     *ControllerHandleIndex = 0xffffffff;
   }
@@ -111,7 +212,6 @@ LibScanHandleDatabase (
 
     if (ControllerHandle != NULL && ControllerHandleIndex != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
       *ControllerHandleIndex      = (UINT32) HandleIndex;
-//      ControllerHandleIndexValid  = TRUE;
     }
 
   }
@@ -249,3 +349,249 @@ Error:
 
   return Status;
 } /* EFI_STATUS LibScanHandleDatabase() */
+
+#ifdef __MAKEWITH_GNUEFI
+/* Modified from EDK2 function of a similar name; original copyright Intel &
+ * BSD-licensed; modifications by Roderick Smith are GPLv3. */
+EFI_STATUS ConnectAllDriversToAllControllers(VOID)
+{
+    EFI_STATUS           Status;
+    UINTN                AllHandleCount;
+    EFI_HANDLE           *AllHandleBuffer;
+    UINTN                Index;
+    UINTN                HandleCount;
+    EFI_HANDLE           *HandleBuffer;
+    UINT32               *HandleType;
+    UINTN                HandleIndex;
+    BOOLEAN              Parent;
+    BOOLEAN              Device;
+
+    Status = LibLocateHandle(AllHandles,
+                             NULL,
+                             NULL,
+                             &AllHandleCount,
+                             &AllHandleBuffer);
+    if (EFI_ERROR(Status))
+        return Status;
+
+    for (Index = 0; Index < AllHandleCount; Index++) {
+        //
+        // Scan the handle database
+        //
+        Status = LibScanHandleDatabase(NULL,
+                                       NULL,
+                                       AllHandleBuffer[Index],
+                                       NULL,
+                                       &HandleCount,
+                                       &HandleBuffer,
+                                       &HandleType);
+        if (EFI_ERROR (Status))
+            goto Done;
+
+        Device = TRUE;
+        if (HandleType[Index] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE)
+            Device = FALSE;
+        if (HandleType[Index] & EFI_HANDLE_TYPE_IMAGE_HANDLE)
+            Device = FALSE;
+
+        if (Device) {
+            Parent = FALSE;
+            for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+                if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE)
+                    Parent = TRUE;
+            } // for
+
+            if (!Parent) {
+                if (HandleType[Index] & EFI_HANDLE_TYPE_DEVICE_HANDLE) {
+                   Status = refit_call4_wrapper(BS->ConnectController,
+                                                AllHandleBuffer[Index],
+                                                NULL,
+                                                NULL,
+                                                TRUE);
+                }
+            }
+        }
+
+        MyFreePool (HandleBuffer);
+        MyFreePool (HandleType);
+    }
+
+Done:
+    MyFreePool (AllHandleBuffer);
+    return Status;
+} /* EFI_STATUS ConnectAllDriversToAllControllers() */
+#else
+EFI_STATUS ConnectAllDriversToAllControllers(VOID) {
+    BdsLibConnectAllDriversToAllControllers();
+    return 0;
+}
+#endif
+
+/*
+ * ConnectFilesystemDriver() is modified from DisconnectInvalidDiskIoChildDrivers()
+ * in Clover (https://sourceforge.net/projects/cloverefiboot/), which is derived
+ * from rEFIt. The refit/main.c file from which this function was taken continues
+ * to bear rEFIt's original copyright/licence notice (BSD); modifications by
+ * Roderick Smith (2016) are GPLv3.
+ */
+/**
+ * Some UEFI's (like HPQ EFI from HP notebooks) have DiskIo protocols
+ * opened BY_DRIVER (by Partition driver in HP case) even when no file system
+ * is produced from this DiskIo. This then blocks our FS drivers from connecting
+ * and producing file systems.
+ * To fix it: we will disconnect drivers that connected to DiskIo BY_DRIVER
+ * if this is partition volume and if those drivers did not produce file system,
+ * then try to connect every unconnected device to the driver whose handle is
+ * passed to us.
+ */
+VOID ConnectFilesystemDriver(EFI_HANDLE DriverHandle) {
+    EFI_STATUS                            Status;
+    UINTN                                 HandleCount = 0;
+    UINTN                                 Index;
+    UINTN                                 OpenInfoIndex;
+    EFI_HANDLE                            *Handles = NULL;
+    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL       *Fs;
+    EFI_BLOCK_IO_PROTOCOL                 *BlockIo;
+    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY   *OpenInfo;
+    UINTN                                 OpenInfoCount;
+    EFI_HANDLE                            DriverHandleList[2];
+
+    //
+    // Get all DiskIo handles
+    //
+    Status = refit_call5_wrapper(gBS->LocateHandleBuffer,
+                                 ByProtocol,
+                                 &gEfiDiskIoProtocolGuid,
+                                 NULL,
+                                 &HandleCount,
+                                 &Handles);
+    if (EFI_ERROR(Status) || HandleCount == 0)
+        return;
+
+    //
+    // Check every DiskIo handle
+    //
+    for (Index = 0; Index < HandleCount; Index++) {
+        //
+        // If this is not partition - skip it.
+        // This is then whole disk and DiskIo
+        // should be opened here BY_DRIVER by Partition driver
+        // to produce partition volumes.
+        //
+        Status = refit_call3_wrapper(gBS->HandleProtocol,
+                                     Handles[Index],
+                                     &gEfiBlockIoProtocolGuid,
+                                     (VOID **) &BlockIo);
+        if (EFI_ERROR (Status))
+            continue;
+        if (BlockIo->Media == NULL || !BlockIo->Media->LogicalPartition)
+            continue;
+
+        //
+        // If SimpleFileSystem is already produced - skip it, this is ok
+        //
+        Status = refit_call3_wrapper(gBS->HandleProtocol,
+                                    Handles[Index],
+                                    &gEfiSimpleFileSystemProtocolGuid,
+                                    (VOID **) &Fs);
+        if (Status == EFI_SUCCESS)
+            continue;
+
+        //
+        // If no SimpleFileSystem on this handle but DiskIo is opened BY_DRIVER
+        // then disconnect this connection and try to connect our driver to it
+        //
+        Status = refit_call4_wrapper(gBS->OpenProtocolInformation,
+                                     Handles[Index],
+                                     &gEfiDiskIoProtocolGuid,
+                                     &OpenInfo,
+                                     &OpenInfoCount);
+        if (EFI_ERROR (Status))
+            continue;
+        DriverHandleList[1] = NULL;
+        for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+            if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+                Status = refit_call3_wrapper(gBS->DisconnectController,
+                                             Handles[Index],
+                                             OpenInfo[OpenInfoIndex].AgentHandle,
+                                             NULL);
+                if (!(EFI_ERROR(Status))) {
+                    DriverHandleList[0] = DriverHandle;
+                    refit_call4_wrapper(gBS->ConnectController,
+                                        Handles[Index],
+                                        DriverHandleList,
+                                        NULL,
+                                        FALSE);
+                } // if
+            } // if
+        } // for
+        FreePool (OpenInfo);
+    }
+    FreePool(Handles);
+} // VOID ConnectFilesystemDriver()
+
+// Scan a directory for drivers.
+// Originally from rEFIt's main.c (BSD), but modified since then (GPLv3).
+static UINTN ScanDriverDir(IN CHAR16 *Path)
+{
+    EFI_STATUS              Status;
+    REFIT_DIR_ITER          DirIter;
+    UINTN                   NumFound = 0;
+    EFI_FILE_INFO           *DirEntry;
+    CHAR16                  FileName[256];
+
+    CleanUpPathNameSlashes(Path);
+    // look through contents of the directory
+    DirIterOpen(SelfRootDir, Path, &DirIter);
+    while (DirIterNext(&DirIter, 2, LOADER_MATCH_PATTERNS, &DirEntry)) {
+        if (DirEntry->FileName[0] == '.')
+            continue;   // skip this
+
+        SPrint(FileName, 255, L"%s\\%s", Path, DirEntry->FileName);
+        NumFound++;
+        Status = StartEFIImage(FileDevicePath(SelfLoadedImage->DeviceHandle, FileName),
+                               L"", TYPE_EFI, DirEntry->FileName, 0, NULL, FALSE, TRUE);
+    }
+    Status = DirIterClose(&DirIter);
+    if ((Status != EFI_NOT_FOUND) && (Status != EFI_INVALID_PARAMETER)) {
+        SPrint(FileName, 255, L"while scanning the %s directory", Path);
+        CheckError(Status, FileName);
+    }
+    return (NumFound);
+} // static UINTN ScanDriverDir()
+
+
+// Load all EFI drivers from rEFInd's "drivers" subdirectory and from the
+// directories specified by the user in the "scan_driver_dirs" configuration
+// file line.
+// Originally from rEFIt's main.c (BSD), but modified since then (GPLv3).
+VOID LoadDrivers(VOID) {
+    CHAR16        *Directory, *SelfDirectory;
+    UINTN         i = 0, Length, NumFound = 0;
+
+    // load drivers from the subdirectories of rEFInd's home directory specified
+    // in the DRIVER_DIRS constant.
+    while ((Directory = FindCommaDelimited(DRIVER_DIRS, i++)) != NULL) {
+        SelfDirectory = SelfDirPath ? StrDuplicate(SelfDirPath) : NULL;
+        CleanUpPathNameSlashes(SelfDirectory);
+        MergeStrings(&SelfDirectory, Directory, L'\\');
+        NumFound += ScanDriverDir(SelfDirectory);
+        MyFreePool(Directory);
+        MyFreePool(SelfDirectory);
+    }
+
+    // Scan additional user-specified driver directories....
+    i = 0;
+    while ((Directory = FindCommaDelimited(GlobalConfig.DriverDirs, i++)) != NULL) {
+        CleanUpPathNameSlashes(Directory);
+        Length = StrLen(Directory);
+        if (Length > 0) {
+            NumFound += ScanDriverDir(Directory);
+        } // if
+        MyFreePool(Directory);
+    } // while
+
+    // connect all devices
+    if (NumFound > 0)
+        ConnectAllDriversToAllControllers();
+} /* VOID LoadDrivers() */
index bf4c0e73941fdf7009a0d979dd643e26d0b873da..fa9ba60a69ad9bab230eb45cb39648e9480cfc69 100644 (file)
  *
  */
 
+#ifndef _DRIVER_SUPPORT
+#define _DRIVER_SUPPORT
+
 #ifdef __MAKEWITH_GNUEFI
 #include <efi.h>
-//#include <efi/efilib.h>
 #else
 #include "../include/tiano_includes.h"
 #endif
 #include "global.h"
 
-#ifndef _DRIVER_SUPPORT
-#define _DRIVER_SUPPORT
+#define EFI_HANDLE_TYPE_UNKNOWN                     0x000
+#define EFI_HANDLE_TYPE_IMAGE_HANDLE                0x001
+#define EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE       0x002
+#define EFI_HANDLE_TYPE_DEVICE_DRIVER               0x004
+#define EFI_HANDLE_TYPE_BUS_DRIVER                  0x008
+#define EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE 0x010
+#define EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE   0x020
+#define EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE       0x040
+#define EFI_HANDLE_TYPE_DEVICE_HANDLE               0x080
+#define EFI_HANDLE_TYPE_PARENT_HANDLE               0x100
+#define EFI_HANDLE_TYPE_CONTROLLER_HANDLE           0x200
+#define EFI_HANDLE_TYPE_CHILD_HANDLE                0x400
 
 // Below is from http://git.etherboot.org/?p=mirror/efi/shell/.git;a=commitdiff;h=b1b0c63423cac54dc964c2930e04aebb46a946ec;
 // Seems to have been replaced by ParseHandleDatabaseByRelationshipWithType(), but the latter isn't working for me....
@@ -40,19 +52,8 @@ LibScanHandleDatabase (
   EFI_HANDLE  **HandleBuffer,
   UINT32      **HandleType
   );
-
-
-#define EFI_HANDLE_TYPE_UNKNOWN                     0x000
-#define EFI_HANDLE_TYPE_IMAGE_HANDLE                0x001
-#define EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE       0x002
-#define EFI_HANDLE_TYPE_DEVICE_DRIVER               0x004
-#define EFI_HANDLE_TYPE_BUS_DRIVER                  0x008
-#define EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE 0x010
-#define EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE   0x020
-#define EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE       0x040
-#define EFI_HANDLE_TYPE_DEVICE_HANDLE               0x080
-#define EFI_HANDLE_TYPE_PARENT_HANDLE               0x100
-#define EFI_HANDLE_TYPE_CONTROLLER_HANDLE           0x200
-#define EFI_HANDLE_TYPE_CHILD_HANDLE                0x400
+EFI_STATUS ConnectAllDriversToAllControllers(VOID);
+VOID ConnectFilesystemDriver(EFI_HANDLE DriverHandle);
+VOID LoadDrivers(VOID);
 
 #endif
index 8acbf7dc603457f26fb857624010f33c24fcf5af..d35f9b0677ae9572273218690ec449ea55f7ceaa 100644 (file)
 // Files that may be Windows recovery files
 #define WINDOWS_RECOVERY_FILES  L"EFI\\Microsoft\\Boot\\LrsBootmgr.efi,Recovery:\\EFI\\BOOT\\bootx64.efi,Recovery:\\EFI\\BOOT\\bootia32.efi"
 
+// Filename patterns that identify EFI boot loaders. Note that a single case (either L"*.efi" or
+// L"*.EFI") is fine for most systems; but Gigabyte's buggy Hybrid EFI does a case-sensitive
+// comparison when it should do a case-insensitive comparison, so I'm doubling this up. It does
+// no harm on other computers, AFAIK. In theory, every case variation should be done for
+// completeness, but that's ridiculous....
+#define LOADER_MATCH_PATTERNS   L"*.efi,*.EFI"
+
 // Definitions for the "hideui" option in refind.conf
 #define HIDEUI_FLAG_NONE       (0x0000)
 #define HIDEUI_FLAG_BANNER     (0x0001)
@@ -340,6 +347,12 @@ EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
                              OUT UINTN *ErrorInStep,
                              IN BOOLEAN Verbose,
                              IN BOOLEAN IsDriver);
+EFI_STATUS StartEFIImage(IN EFI_DEVICE_PATH *DevicePath,
+                         IN CHAR16 *LoadOptions, IN UINTN LoaderType,
+                         IN CHAR16 *ImageTitle, IN CHAR8 OSType,
+                         OUT UINTN *ErrorInStep,
+                         IN BOOLEAN Verbose,
+                         IN BOOLEAN IsDriver);
 LOADER_ENTRY *InitializeLoaderEntry(IN LOADER_ENTRY *Entry);
 REFIT_MENU_SCREEN *InitializeSubScreen(IN LOADER_ENTRY *Entry);
 VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume, IN BOOLEAN GenerateReturn);
index 881ac38182b9a600e32b54df15efdd646395dbce..69e80fcec41472f09a6f58c6cd3d5bc4441513b4 100644 (file)
@@ -98,7 +98,6 @@
 #define GDISK_NAMES             L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_x64.efi"
 #define NETBOOT_NAMES           L"\\EFI\\tools\\ipxe.efi"
 #define MEMTEST_NAMES           L"memtest86.efi,memtest86_x64.efi,memtest86x64.efi,bootx64.efi"
-#define DRIVER_DIRS             L"drivers,drivers_x64"
 #define FALLBACK_FULLNAME       L"EFI\\BOOT\\bootx64.efi"
 #define FALLBACK_BASENAME       L"bootx64.efi"
 #define EFI_STUB_ARCH           0x8664
@@ -109,7 +108,6 @@ EFI_GUID gFreedesktopRootGuid = { 0x4f68bce3, 0xe8cd, 0x4db1, { 0x96, 0xe7, 0xfb
 #define GDISK_NAMES             L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_ia32.efi"
 #define NETBOOT_NAMES           L"\\EFI\\tools\\ipxe.efi"
 #define MEMTEST_NAMES           L"memtest86.efi,memtest86_ia32.efi,memtest86ia32.efi,bootia32.efi"
-#define DRIVER_DIRS             L"drivers,drivers_ia32"
 #define FALLBACK_FULLNAME       L"EFI\\BOOT\\bootia32.efi"
 #define FALLBACK_BASENAME       L"bootia32.efi"
 #define EFI_STUB_ARCH           0x014c
@@ -120,7 +118,6 @@ EFI_GUID gFreedesktopRootGuid = { 0x44479540, 0xf297, 0x41b2, { 0x9a, 0xf7, 0xd1
 #define GDISK_NAMES             L"\\EFI\\tools\\gdisk.efi,\\EFI\\tools\\gdisk_aa64.efi"
 #define NETBOOT_NAMES           L"\\EFI\\tools\\ipxe.efi"
 #define MEMTEST_NAMES           L"memtest86.efi,memtest86_aa64.efi,memtest86aa64.efi,bootaa64.efi"
-#define DRIVER_DIRS             L"drivers,drivers_aa64"
 #define FALLBACK_FULLNAME       L"EFI\\BOOT\\bootaa64.efi"
 #define FALLBACK_BASENAME       L"bootaa64.efi"
 #define EFI_STUB_ARCH           0xaa64
@@ -142,13 +139,6 @@ EFI_GUID gFreedesktopRootGuid = { 0x69dad710, 0x2ce4, 0x4e3c, { 0xb1, 0x6c, 0x21
 #define IPXE_DISCOVER_NAME      L"\\efi\\tools\\ipxe_discover.efi"
 #define IPXE_NAME               L"\\efi\\tools\\ipxe.efi"
 
-// Filename patterns that identify EFI boot loaders. Note that a single case (either L"*.efi" or
-// L"*.EFI") is fine for most systems; but Gigabyte's buggy Hybrid EFI does a case-sensitive
-// comparison when it should do a case-insensitive comparison, so I'm doubling this up. It does
-// no harm on other computers, AFAIK. In theory, every case variation should be done for
-// completeness, but that's ridiculous....
-#define LOADER_MATCH_PATTERNS   L"*.efi,*.EFI"
-
 // Patterns that identify Linux kernels. Added to the loader match pattern when the
 // scan_all_linux_kernels option is set in the configuration file. Causes kernels WITHOUT
 // a ".efi" extension to be found when scanning for boot loaders.
@@ -420,6 +410,8 @@ EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
         if (ErrorInStep != NULL)
             *ErrorInStep = 3;
     }
+    if (IsDriver)
+        ConnectFilesystemDriver(ChildImageHandle);
 
     // re-open file handles
     ReinitRefitLib();
@@ -434,13 +426,12 @@ bailout:
     return ReturnStatus;
 } /* EFI_STATUS StartEFIImageList() */
 
-static EFI_STATUS StartEFIImage(IN EFI_DEVICE_PATH *DevicePath,
-                                IN CHAR16 *LoadOptions, IN UINTN LoaderType,
-                                IN CHAR16 *ImageTitle, IN CHAR8 OSType,
-                                OUT UINTN *ErrorInStep,
-                                IN BOOLEAN Verbose,
-                                IN BOOLEAN IsDriver
-                               )
+EFI_STATUS StartEFIImage(IN EFI_DEVICE_PATH *DevicePath,
+                         IN CHAR16 *LoadOptions, IN UINTN LoaderType,
+                         IN CHAR16 *ImageTitle, IN CHAR8 OSType,
+                         OUT UINTN *ErrorInStep,
+                         IN BOOLEAN Verbose,
+                         IN BOOLEAN IsDriver)
 {
     EFI_DEVICE_PATH *DevicePaths[2];
 
@@ -1703,149 +1694,6 @@ static LOADER_ENTRY * AddToolEntry(EFI_HANDLE DeviceHandle, IN CHAR16 *LoaderPat
     return Entry;
 } /* static LOADER_ENTRY * AddToolEntry() */
 
-//
-// pre-boot driver functions
-//
-
-static UINTN ScanDriverDir(IN CHAR16 *Path)
-{
-    EFI_STATUS              Status;
-    REFIT_DIR_ITER          DirIter;
-    UINTN                   NumFound = 0;
-    EFI_FILE_INFO           *DirEntry;
-    CHAR16                  FileName[256];
-
-    CleanUpPathNameSlashes(Path);
-    // look through contents of the directory
-    DirIterOpen(SelfRootDir, Path, &DirIter);
-    while (DirIterNext(&DirIter, 2, LOADER_MATCH_PATTERNS, &DirEntry)) {
-        if (DirEntry->FileName[0] == '.')
-            continue;   // skip this
-
-        SPrint(FileName, 255, L"%s\\%s", Path, DirEntry->FileName);
-        NumFound++;
-        Status = StartEFIImage(FileDevicePath(SelfLoadedImage->DeviceHandle, FileName),
-                               L"", TYPE_EFI, DirEntry->FileName, 0, NULL, FALSE, TRUE);
-    }
-    Status = DirIterClose(&DirIter);
-    if ((Status != EFI_NOT_FOUND) && (Status != EFI_INVALID_PARAMETER)) {
-        SPrint(FileName, 255, L"while scanning the %s directory", Path);
-        CheckError(Status, FileName);
-    }
-    return (NumFound);
-}
-
-#ifdef __MAKEWITH_GNUEFI
-static EFI_STATUS ConnectAllDriversToAllControllers(VOID)
-{
-    EFI_STATUS           Status;
-    UINTN                AllHandleCount;
-    EFI_HANDLE           *AllHandleBuffer;
-    UINTN                Index;
-    UINTN                HandleCount;
-    EFI_HANDLE           *HandleBuffer;
-    UINT32               *HandleType;
-    UINTN                HandleIndex;
-    BOOLEAN              Parent;
-    BOOLEAN              Device;
-
-    Status = LibLocateHandle(AllHandles,
-                             NULL,
-                             NULL,
-                             &AllHandleCount,
-                             &AllHandleBuffer);
-    if (EFI_ERROR(Status))
-        return Status;
-
-    for (Index = 0; Index < AllHandleCount; Index++) {
-        //
-        // Scan the handle database
-        //
-        Status = LibScanHandleDatabase(NULL,
-                                       NULL,
-                                       AllHandleBuffer[Index],
-                                       NULL,
-                                       &HandleCount,
-                                       &HandleBuffer,
-                                       &HandleType);
-        if (EFI_ERROR (Status))
-            goto Done;
-
-        Device = TRUE;
-        if (HandleType[Index] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE)
-            Device = FALSE;
-        if (HandleType[Index] & EFI_HANDLE_TYPE_IMAGE_HANDLE)
-            Device = FALSE;
-
-        if (Device) {
-            Parent = FALSE;
-            for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
-                if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE)
-                    Parent = TRUE;
-            } // for
-
-            if (!Parent) {
-                if (HandleType[Index] & EFI_HANDLE_TYPE_DEVICE_HANDLE) {
-                   Status = refit_call4_wrapper(BS->ConnectController,
-                                                AllHandleBuffer[Index],
-                                                NULL,
-                                                NULL,
-                                                TRUE);
-                }
-            }
-        }
-
-        MyFreePool (HandleBuffer);
-        MyFreePool (HandleType);
-    }
-
-Done:
-    MyFreePool (AllHandleBuffer);
-    return Status;
-} /* EFI_STATUS ConnectAllDriversToAllControllers() */
-#else
-static EFI_STATUS ConnectAllDriversToAllControllers(VOID) {
-    BdsLibConnectAllDriversToAllControllers();
-    return 0;
-}
-#endif
-
-// Load all EFI drivers from rEFInd's "drivers" subdirectory and from the
-// directories specified by the user in the "scan_driver_dirs" configuration
-// file line.
-static VOID LoadDrivers(VOID)
-{
-    CHAR16        *Directory, *SelfDirectory;
-    UINTN         i = 0, Length, NumFound = 0;
-
-    // load drivers from the subdirectories of rEFInd's home directory specified
-    // in the DRIVER_DIRS constant.
-    while ((Directory = FindCommaDelimited(DRIVER_DIRS, i++)) != NULL) {
-       SelfDirectory = SelfDirPath ? StrDuplicate(SelfDirPath) : NULL;
-       CleanUpPathNameSlashes(SelfDirectory);
-       MergeStrings(&SelfDirectory, Directory, L'\\');
-       NumFound += ScanDriverDir(SelfDirectory);
-       MyFreePool(Directory);
-       MyFreePool(SelfDirectory);
-    }
-
-    // Scan additional user-specified driver directories....
-    i = 0;
-    while ((Directory = FindCommaDelimited(GlobalConfig.DriverDirs, i++)) != NULL) {
-       CleanUpPathNameSlashes(Directory);
-       Length = StrLen(Directory);
-       if (Length > 0) {
-          NumFound += ScanDriverDir(Directory);
-       } // if
-       MyFreePool(Directory);
-    } // while
-
-    // connect all devices
-    if (NumFound > 0) {
-       ConnectAllDriversToAllControllers();
-    }
-} /* static VOID LoadDrivers() */
-
 // Locates boot loaders. NOTE: This assumes that GlobalConfig.LegacyType is set correctly.
 static VOID ScanForBootloaders(VOID) {
     UINTN    i;
@@ -2100,6 +1948,7 @@ static VOID RescanAll(BOOLEAN DisplayMessage) {
     ConnectAllDriversToAllControllers();
     ScanVolumes();
     ReadConfig(GlobalConfig.ConfigFilename);
+    SetVolumeIcons();
     ScanForBootloaders();
     ScanForTools();
     SetupScreen();