0.5.0 (??/??/2012):
-------------------
+- Changed refind.conf-sample to uncomment the scan_all_linux_kernels
+ option by default. If this option is deleted or commented out, the
+ program default remains to not scan all Linux kernels; but with
+ increasing numbers of distributions shipping with kernels that include
+ EFI stub loader support, setting the configuration file default to scan
+ for them makes sense.
+
- Modified the "resolution" token so that it affects text mode as well
as graphics mode. On my systems, though, the actual text area is still
restricted to an 80x25 area. (This seems to be a firmware limitation; my
<tr>
<td><tt>scan_all_linux_kernels</tt></td>
<td>None</td>
- <td>When set, causes rEFInd to add Linux kernels (files with names that begin with <tt>vmlinuz</tt> or <tt>bzImage</tt>) to the list of EFI boot loaders, even if they lack <tt>.efi</tt> filename extensions. The hope is that this will simplify use of rEFInd on distributions that provide kernels with EFI stub loader support but that don't give those kernels names that end in <tt>.efi</tt>. Of course, the kernels must still be stored on a filesystem that rEFInd can read, and in a directory that it scans. (<a href="drivers.html">Drivers</a> and the <tt>also_scan_dirs</tt> options can help with those issues.) Note that this option can cause unwanted files to be improperly detected and given loader tags, such as older kernels without EFI stub loader support. For this reason, it's disabled by default, but that may change in the future.</td>
+ <td>When set, causes rEFInd to add Linux kernels (files with names that begin with <tt>vmlinuz</tt> or <tt>bzImage</tt>) to the list of EFI boot loaders, even if they lack <tt>.efi</tt> filename extensions. The hope is that this will simplify use of rEFInd on distributions that provide kernels with EFI stub loader support but that don't give those kernels names that end in <tt>.efi</tt>. Of course, the kernels must still be stored on a filesystem that rEFInd can read, and in a directory that it scans. (<a href="drivers.html">Drivers</a> and the <tt>also_scan_dirs</tt> options can help with those issues.) Note that this option can cause unwanted files to be improperly detected and given loader tags, such as older kernels without EFI stub loader support. Versions of rEFInd prior to 0.5.0 left this option commented out in the <tt>refind.conf-sample</tt> file, but as of version 0.5.0, this option is enabled in the default configuration file. The program default remains to not scan for such kernels, though, so you can delete or uncomment this option to keep them from appearing in your boot menu.</td>
</tr>
<tr>
<td><tt>default_selection</tt></td>
<ul>
+ <li>When in Secure Boot mode, rEFInd can launch just one driver that's
+ signed with a shim key or MOK. The second and later drivers
+ generate "access denied" errors. <!-- I think this is because of
+ the fast-and-loose sample code I borrowed from shim, which re-uses
+ rEFInd's own image handle (the <tt>image_handle</tt> variable in
+ <tt>start_image()</tt>) for launching shim/MOK-signed binaries. The
+ result is that when the second driver is loaded, it can't register
+ itself with the firmware because the firmware believes it's already
+ been registered. The solution is likely to involve creating a child
+ image handle rather than re-using rEFInd's own image handle, but
+ this is likely to be tedious to do—see
+ <tt>/usr/local/UDK2010/MyWorkSpace/MdeModulePkg/Core/Dxe/Image/Image.c</tt>
+ for the reference UEFI implementation. --> </li>
+
<li>The <a href="http://www.rodsbooks.com/gb-hybrid-efi/">Gigabyte
Hybrid EFI</a> has a bug that causes the allegedly case-insensitive
<tt>StriCmp()</tt> function to perform a case-sensitive comparison.
/** Helper macro for stringification. */
#define FSW_EFI_STRINGIFY(x) #x
/** Expands to the EFI driver name given the file system type name. */
-#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.4.6 " FSW_EFI_STRINGIFY(t) L" File System Driver"
+#define FSW_EFI_DRIVER_NAME(t) L"rEFInd 0.5.0 " FSW_EFI_STRINGIFY(t) L" File System Driver"
// function prototypes
#
# Usage:
#
-# ./install.sh [esp]
+# ./install.sh [options]
+#
+# options include:
+# "--esp" to install to the ESP rather than to the system's root
+# filesystem. This is the default on Linux
+# "--usedefault {devicefile}" to install as default
+# (/EFI/BOOT/BOOTX64.EFI and similar) to the specified
+# device (/dev/sdd1 or whatever) without registering with
+# the NVRAM
+# "--drivers" to install drivers along with regular files
#
# The "esp" option is valid only on Mac OS X; it causes
# installation to the EFI System Partition (ESP) rather than
# reboot - a tag to reboot the computer
# Default is shell,apple_recovery,mok_tool,about,shutdown,reboot
#
-#showtools shell, about, reboot
+#showtools shell, mok_tool, about, reboot, exit
# Directories in which to search for EFI drivers. These drivers can
# provide filesystem support, give access to hard disks on plug-in
# option will cause the icon file to show up as a non-functional loader tag.
# Default is to NOT scan for kernels without ".efi" extensions.
#
-#scan_all_linux_kernels
+scan_all_linux_kernels
# Set the maximum number of tags that can be displayed on the screen at
# any time. If more loaders are discovered than this value, rEFInd shows
MyFreePool(GlobalConfig.DontScanDirs);
GlobalConfig.DontScanDirs = StrDuplicate(SelfDirPath);
MyFreePool(GlobalConfig.DontScanFiles);
- GlobalConfig.DontScanFiles = DONT_SCAN_FILES;
+ GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES);
for (;;) {
TokenCount = ReadTokenLine(&File, &TokenList);
} // if allocation OK
} // CleanUpPathNameSlashes()
+// Splits an EFI device path into device and filename components. For instance, if InString is
+// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)/\bzImage-3.5.1.efi,
+// this function will truncate that input to
+// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)
+// and return bzImage-3.5.1.efi as its return value.
+// It does this by searching for the last ")" character in InString, copying everything
+// after that string (after some cleanup) as the return value, and truncating the original
+// input value.
+// If InString contains no ")" character, this function leaves the original input string
+// unmodified and also returns that string.
+static CHAR16* SplitDeviceString(IN OUT CHAR16 *InString) {
+ INTN i;
+ CHAR16 *FileName = NULL;
+ BOOLEAN Found = FALSE;
+
+ i = StrLen(InString) - 1;
+ while ((i >= 0) && (!Found)) {
+ if (InString[i] == L')') {
+ Found = TRUE;
+ FileName = StrDuplicate(&InString[i + 1]);
+ CleanUpPathNameSlashes(FileName);
+ InString[i + 1] = '\0';
+ } // if
+ i--;
+ } // while
+ if (FileName == NULL)
+ FileName = StrDuplicate(InString);
+ return FileName;
+} // static CHAR16* SplitDeviceString()
+
EFI_STATUS InitRefitLib(IN EFI_HANDLE ImageHandle)
{
EFI_STATUS Status;
- CHAR16 *DevicePathAsString;
+ CHAR16 *DevicePathAsString, *Temp;
SelfImageHandle = ImageHandle;
Status = refit_call3_wrapper(BS->HandleProtocol, SelfImageHandle, &LoadedImageProtocol, (VOID **) &SelfLoadedImage);
DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath);
CleanUpPathNameSlashes(DevicePathAsString);
MyFreePool(SelfDirPath);
- SelfDirPath = FindPath(DevicePathAsString);
+ Temp = FindPath(DevicePathAsString);
+ SelfDirPath = SplitDeviceString(Temp);
MyFreePool(DevicePathAsString);
+ MyFreePool(Temp);
return FinishInitRefitLib();
}
// get the handle for that path
RemainingDevicePath = DiskDevicePath;
- //Print(L" * looking at %s\n", DevicePathToStr(RemainingDevicePath));
Status = refit_call3_wrapper(BS->LocateDevicePath, &BlockIoProtocol, &RemainingDevicePath, &WholeDiskHandle);
- //Print(L" * remaining: %s\n", DevicePathToStr(RemainingDevicePath));
FreePool(DiskDevicePath);
if (!EFI_ERROR(Status)) {
return (PathOnly);
}
-// Splits an EFI device path into device and filename components. For instance, if InString is
-// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)/\bzImage-3.5.1.efi,
-// this function will truncate that input to
-// PciRoot(0x0)/Pci(0x1f,0x2)/Ata(Secondary,Master,0x0)/HD(2,GPT,8314ae90-ada3-48e9-9c3b-09a88f80d921,0x96028,0xfa000)
-// and return bzImage-3.5.1.efi as its return value.
-// It does this by searching for the last ")" character in InString, copying everything
-// after that string (after some cleanup) as the return value, and truncating the original
-// input value.
-// If InString contains no ")" character, this function leaves the original input string
-// unmodified and returns a NULL value.
-static CHAR16* SplitDeviceString(IN OUT CHAR16 *InString) {
- INTN i;
- CHAR16 *FileName = NULL;
- BOOLEAN Found = FALSE;
-
- i = StrLen(InString) - 1;
- while ((i >= 0) && (!Found)) {
- if (InString[i] == L')') {
- Found = TRUE;
- FileName = StrDuplicate(&InString[i + 1]);
- CleanUpPathNameSlashes(FileName);
- InString[i + 1] = '\0';
- } // if
- i--;
- } // while
- return FileName;
-} // static CHAR16* SplitDeviceString()
-
// Takes an input loadpath, splits it into disk and filename components, finds a matching
// DeviceVolume, and returns that and the filename (*loader).
VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **DeviceVolume, OUT CHAR16 **loader) {
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.9");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.10");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
#if defined(EFI32)
AddMenuInfoLine(&AboutMenu, L" Platform: x86 (32 bit)");
#elif defined(EFIX64)
- AddMenuInfoLine(&AboutMenu, L" Platform: x86_64 (64 bit)");
+ TempStr = AllocateZeroPool(256 * sizeof(CHAR16));
+ SPrint(TempStr, 255, L" Platform: x86_64 (64 bit); Secure Boot %s", secure_mode() ? L"active" : L"inactive");
+ AddMenuInfoLine(&AboutMenu, TempStr);
#else
AddMenuInfoLine(&AboutMenu, L" Platform: unknown");
#endif
RunMenu(&AboutMenu, NULL);
} /* VOID AboutrEFInd() */
+// Launch an EFI binary.
static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
IN CHAR16 *LoadOptions, IN CHAR16 *LoadOptionsPrefix,
IN CHAR16 *ImageTitle, IN CHAR8 OSType,
CHAR16 ErrorInfo[256];
CHAR16 *FullLoadOptions = NULL;
CHAR16 *loader = NULL;
- BOOLEAN UseMok = FALSE;
+ BOOLEAN UseMok = FALSE, SecureMode;
if (ErrorInStep != NULL)
*ErrorInStep = 0;
if (Verbose)
Print(L"Starting %s\nUsing load options '%s'\n", ImageTitle, FullLoadOptions);
- // load the image into memory (and execute it, in the case of a MOK image).
+ // load the image into memory (and execute it, in the case of a shim/MOK image).
ReturnStatus = Status = EFI_NOT_FOUND; // in case the list is empty
+ SecureMode = secure_mode();
+// SecureMode = TRUE;
for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
- ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
- NULL, 0, &ChildImageHandle);
+ // NOTE: Below commented-out line could simplify logic by loading the image once, but
+ // it doesn't work on my 32-bit Mac Mini or my 64-bit Intel box when launching a
+ // Linux kernel; the kernel returns a "Failed to handle fs_proto" error message.
+ // TODO: Track down the cause of this error and fix it, if possible.
// ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
// ImageData, ImageSize, &ChildImageHandle);
- // TODO: Commented-out version above is more efficient if the below FindVolumeAndFilename()
- // and ReadFile() calls (and surrounding logic) are moved earlier; however, this causes
- // some computers, including my 32-bit Mac Mini and 64-bit Intel machine, to fail when
- // launching a Linux kernel, with a "Failed to handle fs_proto" error message from the
- // kernel. Find out what's causing this and fix it.
- if (ReturnStatus == EFI_ACCESS_DENIED) {
- // TODO: I originally had the next few lines a
+ // In Secure Boot mode, try to use shim/MOK-style loading first, and if
+ // that fails, try the standard EFI system call (LoadImage()). This is
+ // done for efficiency, to prevent loading a binary twice, which can
+ // take several seconds to load a Linux kernel with EFI stub support on
+ // some systems. Linux kernels are likely to be shim/MOK signed, so
+ // this is quickest for them; and delays for most other boot loaders
+ // will be unnoticeably short. To prevent delays or failures in case
+ // of buggy shim/MOK code on non-SB systems, skip that attempt and
+ // call LoadImage() directly when not in SB mode.
+ if (SecureMode) {
FindVolumeAndFilename(DevicePaths[DevicePathIndex], &DeviceVolume, &loader);
if (DeviceVolume != NULL) {
Status = ReadFile(DeviceVolume->RootDir, loader, &File, &ImageSize);
Status = EFI_NOT_FOUND;
Print(L"Error: device volume not found!\n");
} // if/else
- ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions, DeviceVolume);
+ if (Status != EFI_NOT_FOUND) {
+ ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions,
+ DeviceVolume, DevicePaths[DevicePathIndex]);
+ }
if (ReturnStatus == EFI_SUCCESS) {
UseMok = TRUE;
} // if
- }
+ // If shim/MOK load fails, try regular EFI load, in case it's an unsupported
+ // binary type....
+ if (!UseMok) {
+ ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
+ NULL, 0, &ChildImageHandle);
+ } // if (!UseMok)
+ } else { // Secure Boot inactive; only do standard call....
+ ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
+ NULL, 0, &ChildImageHandle);
+ } // if/else (SecureMode)
if (ReturnStatus != EFI_NOT_FOUND) {
break;
}
goto bailout;
}
- if (!UseMok) {
- ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol,
- (VOID **) &ChildLoadedImage);
- if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
+ if (!UseMok) {
+ ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol,
+ (VOID **) &ChildLoadedImage);
+ if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
+ if (ErrorInStep != NULL)
+ *ErrorInStep = 2;
+ goto bailout_unload;
+ }
+ ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
+ ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
+ // turn control over to the image
+ // TODO: (optionally) re-enable the EFI watchdog timer!
+
+ // close open file handles
+ UninitRefitLib();
+ ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
+ // control returns here when the child image calls Exit()
+ SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
+ if (CheckError(Status, ErrorInfo)) {
if (ErrorInStep != NULL)
- *ErrorInStep = 2;
- goto bailout_unload;
- }
- }
-
- if (!UseMok) {
- ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
- ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
- // turn control over to the image
- // TODO: (optionally) re-enable the EFI watchdog timer!
-
- // close open file handles
- UninitRefitLib();
- ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
- // control returns here when the child image calls Exit()
- SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
- if (CheckError(Status, ErrorInfo)) {
- if (ErrorInStep != NULL)
- *ErrorInStep = 3;
- }
+ *ErrorInStep = 3;
+ }
- // re-open file handles
- ReinitRefitLib();
+ // re-open file handles
+ ReinitRefitLib();
} // if
bailout_unload:
// unload the image, we don't care if it works or not...
if (!UseMok)
Status = refit_call1_wrapper(BS->UnloadImage, ChildImageHandle);
+
bailout:
MyFreePool(FullLoadOptions);
return ReturnStatus;
static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
-/*
- * The vendor certificate used for validating the second stage loader
- */
-extern UINT8 vendor_cert[];
-extern UINT32 vendor_cert_size;
-extern UINT32 vendor_dbx_size;
+// /*
+// * The vendor certificate used for validating the second stage loader
+// */
+// extern UINT8 vendor_cert[];
+// extern UINT32 vendor_cert_size;
+// extern UINT32 vendor_dbx_size;
#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
UINT8 *Mok;
} MokListNode;
+
+static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, UINTN *size, VOID **buffer)
+{
+ EFI_STATUS efi_status;
+ char allocate = !(*size);
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, buffer);
+
+ if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) {
+ return efi_status;
+ }
+
+ *buffer = AllocatePool(*size);
+
+ if (!*buffer) {
+ Print(L"Unable to allocate variable buffer\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, *buffer);
+
+ return efi_status;
+} // get_variable()
+
+/*
+ * Check whether we're in Secure Boot and user mode
+ */
+BOOLEAN secure_mode (VOID)
+{
+ EFI_STATUS status;
+ EFI_GUID global_var = EFI_GLOBAL_VARIABLE;
+ UINTN charsize = sizeof(char);
+ UINT8 sb, setupmode;
+ UINT32 attributes;
+
+ status = get_variable(L"SecureBoot", global_var, &attributes, &charsize, (VOID *)&sb);
+
+ /* FIXME - more paranoia here? */
+ if (status != EFI_SUCCESS || sb != 1) {
+ return FALSE;
+ }
+
+ status = get_variable(L"SetupMode", global_var, &attributes, &charsize, (VOID *)&setupmode);
+
+ if (status == EFI_SUCCESS && setupmode == 1) {
+ return FALSE;
+ }
+
+ return TRUE;
+} // secure_mode()
+
+/*
+ * Currently, shim/MOK only works on x86-64 (X64) systems, and some of this code
+ * generates warnings on x86 (IA32) builds, so don't bother compiling it at all
+ * on such systems.
+ *
+ */
+
+#if defined(EFIX64)
+
/*
* Perform basic bounds checking of the intra-image pointers
*/
/*
* Perform the actual relocation
*/
-static EFI_STATUS relocate_coff (GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context,
- void *data)
+static EFI_STATUS relocate_coff (GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context, void *data)
{
EFI_IMAGE_BASE_RELOCATION *RelocBase, *RelocBaseEnd;
UINT64 Adjust;
context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)data;
- if (context->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
- Print(L"Image has no relocation entry\n");
- return EFI_UNSUPPORTED;
- }
-
// Linux kernels with EFI stub support don't have relocation information, so
// we can skip all this stuff....
if (((context->RelocDir->VirtualAddress == 0) && (context->RelocDir->Size == 0)) ||
return EFI_SUCCESS;
}
+ if (context->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ Print(L"Image has no relocation entry\n");
+ return EFI_UNSUPPORTED;
+ }
+
RelocBase = ImageAddress(data, size, context->RelocDir->VirtualAddress);
RelocBaseEnd = ImageAddress(data, size, context->RelocDir->VirtualAddress + context->RelocDir->Size - 1);
}
return EFI_SUCCESS;
-}
+} /* relocate_coff() */
/*
* Read the binary header and grab appropriate information from it
/*
* Once the image has been loaded it needs to be validated and relocated
*/
-static EFI_STATUS handle_image (void *data, unsigned int datasize,
- EFI_LOADED_IMAGE *li, CHAR16 *Options, REFIT_VOLUME *DeviceVolume)
+static EFI_STATUS handle_image (void *data, unsigned int datasize, EFI_LOADED_IMAGE *li,
+ CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN EFI_DEVICE_PATH *DevicePath)
{
EFI_STATUS efi_status;
char *buffer;
* grub needs to know its location and size in memory, its location on
* disk, and its load options, so fix up the loaded image protocol values
*/
- li->ImageBase = buffer;
- li->ImageSize = context.ImageSize;
li->DeviceHandle = DeviceVolume->DeviceHandle;
- li->FilePath = DeviceVolume->DevicePath;
- li->LoadOptions = (VOID *)Options;
+ li->FilePath = DevicePath;
li->LoadOptionsSize = ((UINT32)StrLen(Options) + 1) * sizeof(CHAR16);
+ li->LoadOptions = (VOID *)Options;
+ li->ImageBase = buffer;
+ li->ImageSize = context.ImageSize;
if (!entry_point) {
Print(L"Invalid entry point\n");
return EFI_SUCCESS;
}
+#endif /* defined(EFIX64) */
+
/*
- * Load and run an EFI executable
+ * Load and run an EFI executable.
+ * Note that most of this function compiles only on x86-64 (X64) systems, since
+ * shim/MOK works only on those systems. I'm leaving just enough to get the
+ * function to return EFI_ACCESS_DENIED on x86 (IA32) systems, which should
+ * let the calling function work in case it somehow ends up calling this
+ * function inappropriately.
*/
EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath, VOID *data, UINTN datasize,
- CHAR16 *Options, REFIT_VOLUME *DeviceVolume)
+ CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN EFI_DEVICE_PATH *DevicePath)
{
+ EFI_STATUS efi_status = EFI_ACCESS_DENIED;
+#if defined(EFIX64)
EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
- EFI_STATUS efi_status;
EFI_LOADED_IMAGE *li, li_bak;
CHAR16 *PathName = NULL;
* We need to refer to the loaded image protocol on the running
* binary in order to find our path
*/
- efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
- &loaded_image_protocol, (void **)&li);
+ efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, &loaded_image_protocol, (void **)&li);
if (efi_status != EFI_SUCCESS) {
Print(L"Unable to init protocol\n");
/*
* Verify and, if appropriate, relocate and execute the executable
*/
- efi_status = handle_image(data, datasize, li, Options, DeviceVolume);
+ efi_status = handle_image(data, datasize, li, Options, DeviceVolume, DevicePath);
if (efi_status != EFI_SUCCESS) {
Print(L"Failed to load image\n");
*/
efi_status = refit_call2_wrapper(entry_point, image_handle, ST);
+// efi_status = refit_call1_wrapper(BS->UnloadImage, li);
+
/*
* Restore our original loaded image values
*/
if (data)
FreePool(data);
+#endif
return efi_status;
-}
+} // EFI_STATUS start_image()
#define SHIM_LOCK_GUID \
{ 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
-//#define INTERFACE_DECL(x)
-
-// INTERFACE_DECL(_SHIM_LOCK);
-//
-// typedef
-// EFI_STATUS
-// (*EFI_SHIM_LOCK_VERIFY) (
-// IN VOID *buffer,
-// IN UINT32 size
-// );
-//
-// typedef
-// EFI_STATUS
-// (*EFI_SHIM_LOCK_HASH) (
-// IN char *data,
-// IN int datasize,
-// GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context,
-// UINT8 *sha256hash,
-// UINT8 *sha1hash
-// );
-//
-// typedef
-// EFI_STATUS
-// (*EFI_SHIM_LOCK_CONTEXT) (
-// IN VOID *data,
-// IN unsigned int datasize,
-// GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context
-// );
-//
-// typedef struct _SHIM_LOCK {
-// EFI_SHIM_LOCK_VERIFY Verify;
-// EFI_SHIM_LOCK_HASH Hash;
-// EFI_SHIM_LOCK_CONTEXT Context;
-// } SHIM_LOCK;
+#if defined(EFIX64)
typedef struct _SHIM_LOCK
{
GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context);
} SHIM_LOCK;
+#endif
+
+BOOLEAN secure_mode (VOID);
EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath, VOID *data, UINTN datasize,
- CHAR16 *Options, REFIT_VOLUME *DeviceVolume);
+ CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN EFI_DEVICE_PATH *DevicePath);