/*
- * 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 }};
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;
UINTN OpenInfoIndex;
UINTN ChildIndex;
BOOLEAN DriverBindingHandleIndexValid;
-// BOOLEAN ControllerHandleIndexValid;
DriverBindingHandleIndexValid = FALSE;
if (DriverBindingHandleIndex != NULL) {
*DriverBindingHandleIndex = 0xffffffff;
}
-// ControllerHandleIndexValid = FALSE;
if (ControllerHandleIndex != NULL) {
*ControllerHandleIndex = 0xffffffff;
}
if (ControllerHandle != NULL && ControllerHandleIndex != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {
*ControllerHandleIndex = (UINT32) HandleIndex;
-// ControllerHandleIndexValid = TRUE;
}
}
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() */
#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
#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
#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
#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.
if (ErrorInStep != NULL)
*ErrorInStep = 3;
}
+ if (IsDriver)
+ ConnectFilesystemDriver(ChildImageHandle);
// re-open file handles
ReinitRefitLib();
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];
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;
ConnectAllDriversToAllControllers();
ScanVolumes();
ReadConfig(GlobalConfig.ConfigFilename);
+ SetVolumeIcons();
ScanForBootloaders();
ScanForTools();
SetupScreen();