mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2025-02-15 00:51:35 +01:00
Move global variable textfaces in XTheme. Move global variable fontsDB in XTheme. Remove XTheme member SVGParser. SVGParser is deleted just after use. Remove XTheme members ImageSVG and ImageSVGnight. All images are rasterized at load, so no need to keep that. Remove XIcon setFilled because XIcon knows if it's filled or not by checking Image & ImageNight
3411 lines
137 KiB
C++
3411 lines
137 KiB
C++
/*
|
||
* 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.
|
||
*/
|
||
|
||
#include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
|
||
#include <cpp_util/globals_ctor.h>
|
||
#include <cpp_util/globals_dtor.h>
|
||
|
||
#include "../cpp_foundation/XString.h"
|
||
#include "../cpp_unit_test/all_tests.h"
|
||
|
||
#include "../entry_scan/entry_scan.h"
|
||
#include "../libeg/nanosvg.h"
|
||
#include "../gui/menu_items/menu_globals.h"
|
||
#include "menu.h"
|
||
#include "../Platform/Settings.h"
|
||
#include "../Platform/DataHubCpu.h"
|
||
#include "../Platform/Events.h"
|
||
#include "screen.h"
|
||
#include "../entry_scan/bootscreen.h"
|
||
#include "../Platform/Nvram.h"
|
||
#include "../entry_scan/common.h"
|
||
#include "../gui/shared_with_menu.h"
|
||
#include "../Platform/platformdata.h"
|
||
#include "../Platform/guid.h"
|
||
#include "../Platform/APFS.h"
|
||
#include "../Platform/cpu.h"
|
||
#include "../Platform/smbios.h"
|
||
#include "../Platform/AcpiPatcher.h"
|
||
#include "../Platform/Hibernate.h"
|
||
#include "../Platform/LegacyBoot.h"
|
||
#include "../Platform/PlatformDriverOverride.h"
|
||
#include "../Platform/Edid.h"
|
||
#include "../Platform/Console.h"
|
||
#include "../Platform/spd.h"
|
||
#include "../Platform/Injectors.h"
|
||
#include "../Platform/StartupSound.h"
|
||
#include "../Platform/BootOptions.h"
|
||
#include "../Platform/boot.h"
|
||
#include "../Platform/kext_inject.h"
|
||
#include "../Platform/KextList.h"
|
||
#include "../gui/REFIT_MENU_SCREEN.h"
|
||
#include "../gui/REFIT_MAINMENU_SCREEN.h"
|
||
#include "../Settings/Self.h"
|
||
#include "../Settings/SelfOem.h"
|
||
#include "../Platform/BasicIO.h"
|
||
#include "../include/OSTypes.h"
|
||
#include "../include/OSFlags.h"
|
||
#include "../libeg/XTheme.h"
|
||
#include "../Settings/ConfigManager.h"
|
||
#include "../Platform/CloverVersion.h"
|
||
#include "../Platform/SmbiosFillPatchingValues.h"
|
||
|
||
#include "../include/OC.h"
|
||
|
||
|
||
|
||
#ifndef DEBUG_ALL
|
||
# ifdef DEBUG_ERALY_CRASH
|
||
# define DEBUG_MAIN 2
|
||
# else
|
||
# define DEBUG_MAIN 1
|
||
# endif
|
||
#else
|
||
# define DEBUG_MAIN DEBUG_ALL
|
||
#endif
|
||
|
||
#if DEBUG_MAIN == 0
|
||
#define DBG(...)
|
||
#else
|
||
#define DBG(...) DebugLog(DEBUG_MAIN, __VA_ARGS__)
|
||
#endif
|
||
|
||
#ifndef HIBERNATE
|
||
#define HIBERNATE 0
|
||
#endif
|
||
|
||
|
||
#ifndef CHECK_SMC
|
||
#define CHECK_SMC 0
|
||
#endif
|
||
|
||
|
||
#define PCAT_RTC_ADDRESS_REGISTER 0x70
|
||
#define PCAT_RTC_DATA_REGISTER 0x71
|
||
|
||
|
||
// variables
|
||
|
||
XBool gGuiIsReady = false;
|
||
XBool gThemeNeedInit = true;
|
||
XBool DoHibernateWake = false;
|
||
UINT32 mCurrentColor;
|
||
|
||
extern UINT32 gFakeCPUID;
|
||
|
||
|
||
EFI_HANDLE AudioDriverHandle;
|
||
XStringW OpenRuntimeEfiName;
|
||
|
||
extern void HelpRefit(void);
|
||
extern void AboutRefit(void);
|
||
extern EFI_AUDIO_IO_PROTOCOL *AudioIo;
|
||
extern EFI_DXE_SERVICES *gDS;
|
||
|
||
|
||
static EFI_STATUS LoadEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
|
||
IN CONST XStringW& ImageTitle,
|
||
OUT UINTN *ErrorInStep,
|
||
OUT EFI_HANDLE *NewImageHandle)
|
||
{
|
||
EFI_STATUS Status, ReturnStatus;
|
||
EFI_HANDLE ChildImageHandle = 0;
|
||
UINTN DevicePathIndex;
|
||
|
||
DBG("Loading %ls", ImageTitle.wc_str());
|
||
if (ErrorInStep != NULL) {
|
||
*ErrorInStep = 0;
|
||
}
|
||
if (NewImageHandle != NULL) {
|
||
*NewImageHandle = NULL;
|
||
}
|
||
|
||
// load the image into memory
|
||
ReturnStatus = Status = EFI_NOT_FOUND; // in case the list is empty
|
||
for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
|
||
ReturnStatus = Status = gBS->LoadImage(false, self.getSelfImageHandle(), DevicePaths[DevicePathIndex], NULL, 0, &ChildImageHandle);
|
||
DBG(" status=%s", efiStrError(Status));
|
||
if (ReturnStatus != EFI_NOT_FOUND)
|
||
break;
|
||
}
|
||
XStringW ErrorInfo = SWPrintf(" while loading %ls", ImageTitle.wc_str());
|
||
if (CheckError(Status, ErrorInfo.wc_str())) {
|
||
if (ErrorInStep != NULL)
|
||
*ErrorInStep = 1;
|
||
PauseForKey(NullXString8);
|
||
goto bailout;
|
||
}else{
|
||
DBG("\n");
|
||
#ifdef JIEF_DEBUG
|
||
DBG("ChildImaheHandle=%llx\n", uintptr_t(ChildImageHandle));
|
||
#endif
|
||
}
|
||
|
||
if (!EFI_ERROR(ReturnStatus)) { //why unload driver?!
|
||
if (NewImageHandle != NULL) {
|
||
*NewImageHandle = ChildImageHandle;
|
||
}
|
||
#ifdef JIEF_DEBUG
|
||
EFI_LOADED_IMAGE_PROTOCOL* loadedBootImage = NULL;
|
||
if (!EFI_ERROR(Status = gBS->HandleProtocol(ChildImageHandle, &gEfiLoadedImageProtocolGuid, (void**)(&loadedBootImage)))) {
|
||
DBG("%ls : Image base = 0x%llx\n", ImageTitle.wc_str(), (uintptr_t)loadedBootImage->ImageBase); // Jief : Do not change this, it's used by grep to feed the debugger
|
||
}else{
|
||
DBG("Can't get loaded image protocol\n");
|
||
}
|
||
#endif
|
||
goto bailout;
|
||
}
|
||
|
||
// unload the image, we don't care if it works or not...
|
||
Status = gBS->UnloadImage(ChildImageHandle);
|
||
bailout:
|
||
return ReturnStatus;
|
||
}
|
||
|
||
|
||
static EFI_STATUS StartEFILoadedImage(IN EFI_HANDLE ChildImageHandle,
|
||
IN CONST XString8Array& LoadOptions, IN CONST XStringW& LoadOptionsPrefix,
|
||
IN CONST XStringW& ImageTitle,
|
||
OUT UINTN *ErrorInStep)
|
||
{
|
||
EFI_STATUS Status, ReturnStatus;
|
||
EFI_LOADED_IMAGE_PROTOCOL *ChildLoadedImage;
|
||
CHAR16 ErrorInfo[256];
|
||
|
||
XStringW loadOptionsW; // This has to be declared here, so it's not be freed before calling StartImage
|
||
|
||
// DBG("Starting %ls\n", ImageTitle);
|
||
if (ErrorInStep != NULL) {
|
||
*ErrorInStep = 0;
|
||
}
|
||
ReturnStatus = Status = EFI_NOT_FOUND; // in case no image handle was specified
|
||
if (ChildImageHandle == NULL) {
|
||
if (ErrorInStep != NULL) *ErrorInStep = 1;
|
||
goto bailout;
|
||
}
|
||
|
||
// set load options
|
||
if (!LoadOptions.isEmpty()) {
|
||
ReturnStatus = Status = gBS->HandleProtocol(ChildImageHandle, &gEfiLoadedImageProtocolGuid, (void **) &ChildLoadedImage);
|
||
if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
|
||
if (ErrorInStep != NULL)
|
||
*ErrorInStep = 2;
|
||
goto bailout_unload;
|
||
}
|
||
|
||
if ( LoadOptionsPrefix.notEmpty() ) {
|
||
// NOTE: That last space is also added by the EFI shell and seems to be significant
|
||
// when passing options to Apple's boot.efi...
|
||
loadOptionsW = SWPrintf("%ls %s ", LoadOptionsPrefix.wc_str(), LoadOptions.ConcatAll(" "_XS8).c_str());
|
||
}else{
|
||
loadOptionsW = SWPrintf("%s ", LoadOptions.ConcatAll(" "_XS8).c_str()); // Jief : should we add a space ? Wasn't the case before big refactoring. Yes, a space required.
|
||
}
|
||
// NOTE: We also include the terminating null in the length for safety.
|
||
ChildLoadedImage->LoadOptionsSize = (UINT32)loadOptionsW.sizeInBytes() + sizeof(wchar_t);
|
||
ChildLoadedImage->LoadOptions = loadOptionsW.wc_str(); //will it be deleted after the procedure exit? Yes, if we don't copy loadOptionsW, so it'll be freed at the end of method
|
||
|
||
DBG("start image '%ls'\n", ImageTitle.s());
|
||
DBG("Using load options '%ls'\n", (CHAR16*)ChildLoadedImage->LoadOptions);
|
||
|
||
}
|
||
|
||
// close open file handles
|
||
UninitRefitLib();
|
||
|
||
// turn control over to the image
|
||
//
|
||
// Before calling the image, enable the Watchdog Timer for
|
||
// the 5 Minute period - Slice - NO! For slow driver and slow disk we need more
|
||
//
|
||
gBS->SetWatchdogTimer (600, 0x0000, 0x00, NULL);
|
||
|
||
ReturnStatus = Status = gBS->StartImage(ChildImageHandle, NULL, NULL);
|
||
//
|
||
// Clear the Watchdog Timer after the image returns
|
||
//
|
||
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
|
||
|
||
|
||
ReinitRefitLib();
|
||
// control returns here when the child image calls Exit()
|
||
if (ImageTitle.notEmpty()) {
|
||
snwprintf(ErrorInfo, 512, "returned from %ls", ImageTitle.s());
|
||
}
|
||
|
||
if (CheckError(Status, ErrorInfo)) {
|
||
if (ErrorInStep != NULL)
|
||
*ErrorInStep = 3;
|
||
}
|
||
if (!EFI_ERROR(ReturnStatus)) { //why unload driver?!
|
||
goto bailout;
|
||
}
|
||
|
||
bailout_unload:
|
||
// unload the image, we don't care if it works or not...
|
||
Status = gBS->UnloadImage(ChildImageHandle);
|
||
bailout:
|
||
return ReturnStatus;
|
||
}
|
||
|
||
|
||
static EFI_STATUS LoadEFIImage(IN EFI_DEVICE_PATH *DevicePath,
|
||
IN CONST XStringW& ImageTitle,
|
||
OUT UINTN *ErrorInStep,
|
||
OUT EFI_HANDLE *NewImageHandle)
|
||
{
|
||
EFI_DEVICE_PATH *DevicePaths[2];
|
||
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
// Verify secure boot policy
|
||
if (GlobalConfig.SecureBoot && GlobalConfig.SecureBootSetupMode) {
|
||
// Only verify if in forced secure boot mode
|
||
EFI_STATUS Status = VerifySecureBootImage(DevicePath);
|
||
if (EFI_ERROR(Status)) {
|
||
return Status;
|
||
}
|
||
}
|
||
#endif // ENABLE_SECURE_BOOT
|
||
|
||
// Load the image now
|
||
DevicePaths[0] = DevicePath;
|
||
DevicePaths[1] = NULL;
|
||
return LoadEFIImageList(DevicePaths, ImageTitle, ErrorInStep, NewImageHandle);
|
||
}
|
||
|
||
|
||
static EFI_STATUS StartEFIImage(IN EFI_DEVICE_PATH *DevicePath,
|
||
IN CONST XString8Array& LoadOptions, IN CONST XStringW& LoadOptionsPrefix,
|
||
IN CONST XStringW& ImageTitle,
|
||
OUT UINTN *ErrorInStep,
|
||
OUT EFI_HANDLE *NewImageHandle)
|
||
{
|
||
EFI_STATUS Status;
|
||
EFI_HANDLE ChildImageHandle = NULL;
|
||
|
||
Status = LoadEFIImage(DevicePath, ImageTitle, ErrorInStep, &ChildImageHandle);
|
||
if (!EFI_ERROR(Status)) {
|
||
Status = StartEFILoadedImage(ChildImageHandle, LoadOptions, LoadOptionsPrefix, ImageTitle, ErrorInStep);
|
||
}
|
||
|
||
if (NewImageHandle != NULL) {
|
||
*NewImageHandle = ChildImageHandle;
|
||
}
|
||
return Status;
|
||
}
|
||
|
||
|
||
#ifdef DUMP_KERNEL_KEXT_PATCHES
|
||
void DumpKernelAndKextPatches(KERNEL_AND_KEXT_PATCHES *Patches)
|
||
{
|
||
if (!Patches) {
|
||
DBG("Kernel and Kext Patches null pointer\n");
|
||
return;
|
||
}
|
||
DBG("Kernel and Kext Patches at %llx:\n", (uintptr_t)Patches);
|
||
DBG("\tAllowed: %c\n", GlobalConfig.KextPatchesAllowed ? 'y' : 'n');
|
||
DBG("\tDebug: %c\n", Patches->KPDebug ? 'y' : 'n');
|
||
// DBG("\tKernelCpu: %c\n", Patches->KPKernelCpu ? 'y' : 'n');
|
||
DBG("\tKernelLapic: %c\n", Patches->KPKernelLapic ? 'y' : 'n');
|
||
DBG("\tKernelXCPM: %c\n", Patches->KPKernelXCPM ? 'y' : 'n');
|
||
DBG("\tKernelPm: %c\n", Patches->KPKernelPm ? 'y' : 'n');
|
||
DBG("\tAppleIntelCPUPM: %c\n", Patches->KPAppleIntelCPUPM ? 'y' : 'n');
|
||
DBG("\tAppleRTC: %c\n", Patches->KPAppleRTC ? 'y' : 'n');
|
||
// Dell smbios truncate fix
|
||
DBG("\tDellSMBIOSPatch: %c\n", Patches->KPDELLSMBIOS ? 'y' : 'n');
|
||
DBG("\tFakeCPUID: 0x%X\n", Patches->FakeCPUID);
|
||
DBG("\tATIController: %s\n", Patches->KPATIConnectorsController.isEmpty() ? "(null)": Patches->KPATIConnectorsController.c_str());
|
||
DBG("\tATIDataLength: %zu\n", Patches->KPATIConnectorsData.size());
|
||
DBG("\t%zu Kexts to load\n", Patches->ForceKextsToLoad.size());
|
||
if (Patches->ForceKextsToLoad.size()) {
|
||
size_t i = 0;
|
||
for (; i < Patches->ForceKextsToLoad.size(); ++i) {
|
||
DBG("\t KextToLoad[%zu]: %ls\n", i, Patches->ForceKextsToLoad[i].wc_str());
|
||
}
|
||
}
|
||
DBG("\t%zu Kexts to patch\n", Patches->KextPatches.size());
|
||
if (Patches->KextPatches.size()) {
|
||
size_t i = 0;
|
||
for (; i < Patches->KextPatches.size(); ++i) {
|
||
if (Patches->KextPatches[i].IsPlistPatch) {
|
||
DBG("\t KextPatchPlist[%zu]: %zu bytes, %s\n", i, Patches->KextPatches[i].Data.size(), Patches->KextPatches[i].Name.c_str());
|
||
} else {
|
||
DBG("\t KextPatch[%zu]: %zu bytes, %s\n", i, Patches->KextPatches[i].Data.size(), Patches->KextPatches[i].Name.c_str());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
void LOADER_ENTRY::FilterKextPatches()
|
||
{
|
||
if ( GlobalConfig.KextPatchesAllowed && KernelAndKextPatches.KextPatches.size() > 0 ) {
|
||
DBG("Filtering KextPatches:\n");
|
||
for (size_t i = 0; i < KernelAndKextPatches.KextPatches.size(); i++) {
|
||
DBG(" - [%02zu]: %s :: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s]",
|
||
i,
|
||
KernelAndKextPatches.KextPatches[i].Label.c_str(),
|
||
KernelAndKextPatches.KextPatches[i].IsPlistPatch ? "PlistPatch" : "BinPatch",
|
||
macOSVersion.asString().c_str(),
|
||
KernelAndKextPatches.KextPatches[i].MatchOS.notEmpty() ? KernelAndKextPatches.KextPatches[i].MatchOS.c_str() : "All",
|
||
KernelAndKextPatches.KextPatches[i].MatchBuild.notEmpty() ? KernelAndKextPatches.KextPatches[i].MatchBuild.c_str() : "All"
|
||
);
|
||
if (!gSettings.KernelAndKextPatches.KextPatches[i].MenuItem.BValue) {
|
||
KernelAndKextPatches.KextPatches[i].MenuItem.BValue = false;
|
||
DBG(" ==> disabled by user\n");
|
||
continue;
|
||
}
|
||
KernelAndKextPatches.KextPatches[i].MenuItem.BValue = true;
|
||
if ((BuildVersion.notEmpty()) && (KernelAndKextPatches.KextPatches[i].MatchBuild.notEmpty())) {
|
||
KernelAndKextPatches.KextPatches[i].MenuItem.BValue = KernelAndKextPatches.KextPatches[i].IsPatchEnabledByBuildNumber(BuildVersion);
|
||
DBG(" ==> %s\n", KernelAndKextPatches.KextPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
continue;
|
||
}
|
||
|
||
KernelAndKextPatches.KextPatches[i].MenuItem.BValue = KernelAndKextPatches.KextPatches[i].IsPatchEnabled(macOSVersion);
|
||
DBG(" ==> %s\n", KernelAndKextPatches.KextPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
}
|
||
}
|
||
}
|
||
|
||
void LOADER_ENTRY::FilterKernelPatches()
|
||
{
|
||
if ( GlobalConfig.KernelPatchesAllowed && KernelAndKextPatches.KernelPatches.notEmpty() ) {
|
||
DBG("Filtering KernelPatches:\n");
|
||
for (size_t i = 0; i < KernelAndKextPatches.KernelPatches.size(); ++i) {
|
||
DBG(" - [%02zu]: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s]",
|
||
i,
|
||
KernelAndKextPatches.KernelPatches[i].Label.c_str(),
|
||
macOSVersion.asString().c_str(),
|
||
KernelAndKextPatches.KernelPatches[i].MatchOS.notEmpty() ? KernelAndKextPatches.KernelPatches[i].MatchOS.c_str() : "All",
|
||
KernelAndKextPatches.KernelPatches[i].MatchBuild.notEmpty() ? KernelAndKextPatches.KernelPatches[i].MatchBuild.c_str() : "All"
|
||
);
|
||
if (!gSettings.KernelAndKextPatches.KernelPatches[i].MenuItem.BValue) {
|
||
KernelAndKextPatches.KernelPatches[i].MenuItem.BValue = false;
|
||
DBG(" ==> disabled by user\n");
|
||
continue;
|
||
}
|
||
KernelAndKextPatches.KernelPatches[i].MenuItem.BValue = true;
|
||
if ((BuildVersion.notEmpty()) && (KernelAndKextPatches.KernelPatches[i].MatchBuild.notEmpty())) {
|
||
KernelAndKextPatches.KernelPatches[i].MenuItem.BValue = KernelAndKextPatches.KernelPatches[i].IsPatchEnabledByBuildNumber(BuildVersion);
|
||
DBG(" ==> %s by build\n", KernelAndKextPatches.KernelPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
continue;
|
||
}
|
||
|
||
KernelAndKextPatches.KernelPatches[i].MenuItem.BValue = KernelAndKextPatches.KernelPatches[i].IsPatchEnabled(macOSVersion);
|
||
DBG(" ==> %s by OS\n", KernelAndKextPatches.KernelPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
}
|
||
}
|
||
}
|
||
|
||
void LOADER_ENTRY::FilterBootPatches()
|
||
{
|
||
if ( KernelAndKextPatches.BootPatches.notEmpty() ) {
|
||
DBG("Filtering BootPatches:\n");
|
||
for (size_t i = 0; i < KernelAndKextPatches.BootPatches.size(); ++i) {
|
||
DBG(" - [%02zu]: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s]",
|
||
i,
|
||
KernelAndKextPatches.BootPatches[i].Label.c_str(),
|
||
macOSVersion.asString().c_str(),
|
||
KernelAndKextPatches.BootPatches[i].MatchOS.notEmpty() ? KernelAndKextPatches.BootPatches[i].MatchOS.c_str() : "All",
|
||
KernelAndKextPatches.BootPatches[i].MatchBuild.notEmpty() ? KernelAndKextPatches.BootPatches[i].MatchBuild.c_str() : "All"
|
||
);
|
||
if (!gSettings.KernelAndKextPatches.BootPatches[i].MenuItem.BValue) {
|
||
DBG(" ==> disabled by user\n");
|
||
continue;
|
||
}
|
||
KernelAndKextPatches.BootPatches[i].MenuItem.BValue = true;
|
||
if ((BuildVersion.notEmpty()) && (KernelAndKextPatches.BootPatches[i].MatchBuild.notEmpty())) {
|
||
KernelAndKextPatches.BootPatches[i].MenuItem.BValue = KernelAndKextPatches.BootPatches[i].IsPatchEnabledByBuildNumber(BuildVersion);
|
||
DBG(" ==> %s by build\n", KernelAndKextPatches.BootPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
continue;
|
||
}
|
||
|
||
KernelAndKextPatches.BootPatches[i].MenuItem.BValue = KernelAndKextPatches.BootPatches[i].IsPatchEnabled(macOSVersion);
|
||
DBG(" ==> %s by OS\n", KernelAndKextPatches.BootPatches[i].MenuItem.BValue ? "allowed" : "not allowed");
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Null ConOut OutputString() implementation - for blocking
|
||
// text output from boot.efi when booting in graphics mode
|
||
//
|
||
EFI_STATUS EFIAPI
|
||
NullConOutOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *, IN CONST CHAR16 *) {
|
||
return EFI_SUCCESS;
|
||
}
|
||
|
||
|
||
void CheckEmptyFB()
|
||
{
|
||
XBool EmptyFB = (GlobalConfig.IgPlatform == 0x00050000) ||
|
||
(GlobalConfig.IgPlatform == 0x01620007) ||
|
||
(GlobalConfig.IgPlatform == 0x04120004) ||
|
||
(GlobalConfig.IgPlatform == 0x19120001) ||
|
||
(GlobalConfig.IgPlatform == 0x59120003) ||
|
||
(GlobalConfig.IgPlatform == 0x9BC80003) ||
|
||
(GlobalConfig.IgPlatform == 0x3E910003);
|
||
if (EmptyFB) {
|
||
gSettings.Smbios.gPlatformFeature |= PT_FEATURE_HAS_HEADLESS_GPU;
|
||
} else {
|
||
gSettings.Smbios.gPlatformFeature &= ~PT_FEATURE_HAS_HEADLESS_GPU;
|
||
}
|
||
}
|
||
|
||
size_t setKextAtPos(XObjArray<SIDELOAD_KEXT>* kextArrayPtr, const XString8& kextName, size_t pos)
|
||
{
|
||
XObjArray<SIDELOAD_KEXT>& kextArray = *kextArrayPtr;
|
||
|
||
for (size_t kextIdx = 0 ; kextIdx < kextArray.size() ; kextIdx++ ) {
|
||
if ( kextArray[kextIdx].FileName.contains(kextName) ) {
|
||
#ifdef JIEF_DEBUG
|
||
if ( pos >= kextArray.size() ) panic("pos >= kextArray.size()");
|
||
#else
|
||
//it is impossible
|
||
#endif
|
||
if ( pos == kextIdx ) return pos+1;
|
||
if ( pos > kextIdx ) pos -= 1;
|
||
SIDELOAD_KEXT* kextToMove = &kextArray[kextIdx];
|
||
kextArray.RemoveWithoutFreeingAtIndex(kextIdx);
|
||
kextArray.InsertRef(kextToMove, pos, false);
|
||
return pos+1;
|
||
}
|
||
}
|
||
return pos;
|
||
}
|
||
|
||
static XStringW getDriversPath()
|
||
{
|
||
#if defined(MDE_CPU_X64)
|
||
if (gFirmwareClover) {
|
||
if (FileExists(&self.getCloverDir(), L"drivers\\BIOS")) {
|
||
return L"drivers\\BIOS"_XSW;
|
||
} else {
|
||
return L"drivers64"_XSW; //backward compatibility
|
||
}
|
||
} else if (FileExists(&self.getCloverDir(), L"drivers\\5142")) { // can be excluded as obsolete
|
||
return L"drivers\\5142"_XSW;
|
||
} else if (FileExists(&self.getCloverDir(), L"drivers\\UEFI")) {
|
||
return L"drivers\\UEFI"_XSW;
|
||
} else {
|
||
return L"drivers64UEFI"_XSW;
|
||
}
|
||
#else
|
||
return L"drivers32"_XSW;
|
||
#endif
|
||
}
|
||
|
||
#ifdef JIEF_DEBUG
|
||
void debugStartImageWithOC()
|
||
{
|
||
MsgLog("debugStartImageWithOC\n");
|
||
UINT64 CPUFrequencyFromART;
|
||
InternalCalculateARTFrequencyIntel(&CPUFrequencyFromART, NULL, 1);
|
||
|
||
EFI_LOADED_IMAGE* OcLoadedImage;
|
||
EFI_STATUS Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (void **) &OcLoadedImage);
|
||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileSystem = OcLocateFileSystem(OcLoadedImage->DeviceHandle, OcLoadedImage->FilePath);
|
||
Status = OcStorageInitFromFs(&mOpenCoreStorage, FileSystem, NULL, NULL, self.getCloverDirFullPath().wc_str(), NULL);
|
||
|
||
Status = ClOcReadConfigurationFile(&mOpenCoreStorage, L"config-oc.plist", &mOpenCoreConfiguration);
|
||
if ( EFI_ERROR(Status) ) panic("ClOcReadConfigurationFile");
|
||
|
||
mOpenCoreConfiguration.Misc.Debug.Target = 0;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Misc.Boot.PickerMode, "Builtin");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Misc.Security.DmgLoading, "Any");
|
||
mOpenCoreConfiguration.Uefi.Quirks.IgnoreInvalidFlexRatio = 0;
|
||
|
||
mOpenCoreConfiguration.Uefi.Quirks.TscSyncTimeout = 0;
|
||
|
||
OcMain(&mOpenCoreStorage, NULL);
|
||
|
||
XStringW devicePathToLookFor;
|
||
// devicePathToLookFor.takeValueFrom("PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x0,0x0)/HD(4,GPT,CA224585-830E-4274-5826-1ACB6DA08A4E,0x299F000,0x4AE6310)/VenMedia(BE74FCF7-0B7C-49F3-9147-01F4042E6842,1ABE434C8D0357398516CFDF0A9DD7EF)"); // Jief High Sierra DevicePath
|
||
devicePathToLookFor.takeValueFrom("PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x0,0x0)/HD(2,GPT,D8C7DA82-1E4C-4579-BA7C-6737A5D43464,0x64028,0x1BF08E8)"); // Jief Big Sur Install device path
|
||
UINTN HandleCount = 0;
|
||
EFI_HANDLE *Handles = NULL;
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
|
||
UINTN HandleIndex = 0;
|
||
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
|
||
EFI_DEVICE_PATH_PROTOCOL* DevicePath = DevicePathFromHandle(Handles[HandleIndex]);
|
||
CHAR16* UnicodeDevicePath = ConvertDevicePathToText(DevicePath, false, false);
|
||
MsgLog("debugStartImageWithOC : path %ls\n", UnicodeDevicePath);
|
||
if ( StrCmp(devicePathToLookFor.wc_str(), UnicodeDevicePath) == 0 ) break;
|
||
}
|
||
if ( HandleIndex < HandleCount )
|
||
{
|
||
EFI_DEVICE_PATH_PROTOCOL* jfkImagePath = FileDevicePath(Handles[HandleIndex], L"\\System\\Library\\CoreServices\\boot.efi");
|
||
CHAR16* UnicodeDevicePath = ConvertDevicePathToText (jfkImagePath, false, false); (void)UnicodeDevicePath;
|
||
|
||
EFI_HANDLE EntryHandle = NULL;
|
||
|
||
// point to InternalEfiLoadImage from OC
|
||
Status = gBS->LoadImage (
|
||
false,
|
||
gImageHandle,
|
||
jfkImagePath,
|
||
NULL,
|
||
0,
|
||
&EntryHandle
|
||
);
|
||
if ( EFI_ERROR(Status) ) return; // TODO message ?
|
||
|
||
EFI_LOADED_IMAGE *LoadedImage = NULL;
|
||
EFI_STATUS OptionalStatus = gBS->HandleProtocol (
|
||
EntryHandle,
|
||
&gEfiLoadedImageProtocolGuid,
|
||
(void **) &LoadedImage
|
||
);
|
||
if ( EFI_ERROR(OptionalStatus) ) return; // TODO message ?
|
||
|
||
// XStringW LoadOptionsAsXStringW = SWPrintf("%s ", LoadOptions.ConcatAll(" "_XS8).c_str());
|
||
XStringW LoadOptionsAsXStringW = SWPrintf("boot.efi -v -no_compat_check slide=0 kext-dev-mode=1 keepsyms=1 -wegdbg igfxgl=1 bpr_probedelay=200 bpr_initialdelay=400 bpr_postresetdelay=400 ");
|
||
LoadedImage->LoadOptions = (void*)LoadOptionsAsXStringW.wc_str();
|
||
LoadedImage->LoadOptionsSize = (UINT32)LoadOptionsAsXStringW.sizeInBytesIncludingTerminator();
|
||
|
||
// point to OcStartImage from OC
|
||
Status = gBS->StartImage (EntryHandle, 0, NULL);
|
||
if ( EFI_ERROR(Status) ) return; // TODO message ?
|
||
}else{
|
||
MsgLog("debugStartImageWithOC : not found\n");
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
void LOADER_ENTRY::DelegateKernelPatches()
|
||
{
|
||
XObjArray<ABSTRACT_KEXT_OR_KERNEL_PATCH> selectedPathArray;
|
||
for (size_t kextPatchIdx = 0 ; kextPatchIdx < KernelAndKextPatches.KextPatches.size() ; kextPatchIdx++ )
|
||
{
|
||
if ( KernelAndKextPatches.KextPatches[kextPatchIdx].MenuItem.BValue )
|
||
selectedPathArray.AddReference(&KernelAndKextPatches.KextPatches[kextPatchIdx], false);
|
||
}
|
||
for (size_t kernelPatchIdx = 0 ; kernelPatchIdx < KernelAndKextPatches.KernelPatches.size() ; kernelPatchIdx++ )
|
||
{
|
||
if ( KernelAndKextPatches.KernelPatches[kernelPatchIdx].MenuItem.BValue )
|
||
selectedPathArray.AddReference(&KernelAndKextPatches.KernelPatches[kernelPatchIdx], false);
|
||
}
|
||
mOpenCoreConfiguration.Kernel.Patch.Count = (UINT32)selectedPathArray.size();
|
||
mOpenCoreConfiguration.Kernel.Patch.AllocCount = mOpenCoreConfiguration.Kernel.Patch.Count;
|
||
mOpenCoreConfiguration.Kernel.Patch.ValueSize = sizeof(__typeof_am__(**mOpenCoreConfiguration.Kernel.Patch.Values));
|
||
mOpenCoreConfiguration.Kernel.Patch.Values = (__typeof_am__(*mOpenCoreConfiguration.Kernel.Patch.Values)*)malloc(mOpenCoreConfiguration.Kernel.Patch.AllocCount*sizeof(__typeof_am__(*mOpenCoreConfiguration.Kernel.Patch.Values)));
|
||
memset(mOpenCoreConfiguration.Kernel.Patch.Values, 0, mOpenCoreConfiguration.Kernel.Patch.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Patch.Values));
|
||
|
||
UINT32 FakeCPUID = gSettings.Smbios.SFakeCPU;
|
||
if (FakeCPUID != 0) gFakeCPUID = FakeCPUID;
|
||
DBG("Set FakeCPUID: 0x%X\n", gFakeCPUID);
|
||
|
||
memset(mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Data, 0, sizeof(mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Data));
|
||
memset(mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Mask, 0, sizeof(mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Mask));
|
||
mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Data[0] = gFakeCPUID;
|
||
mOpenCoreConfiguration.Kernel.Emulate.Cpuid1Mask[0] = 0xFFFFFFFF;
|
||
|
||
for (size_t kextPatchIdx = 0 ; kextPatchIdx < selectedPathArray.size() ; kextPatchIdx++ )
|
||
{
|
||
const ABSTRACT_KEXT_OR_KERNEL_PATCH& kextPatch = selectedPathArray[kextPatchIdx]; //as well as kernel patches
|
||
DBG("Bridge %s patch to OC : %s\n", kextPatch.getName().c_str(), kextPatch.Label.c_str());
|
||
mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx] = (__typeof_am__(*mOpenCoreConfiguration.Kernel.Patch.Values))AllocateZeroPool(mOpenCoreConfiguration.Kernel.Patch.ValueSize); // sizeof(OC_KERNEL_ADD_ENTRY) == 680
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Arch, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Scheme.KernelArch));
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Base, kextPatch.ProcedureName.c_str());
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Comment, kextPatch.Label.c_str());
|
||
mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Count = (UINT32)kextPatch.Count;
|
||
mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Enabled = 1;
|
||
|
||
OC_DATA_ASSIGN_N(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Find, kextPatch.Find.data(), kextPatch.Find.size());
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Identifier, kextPatch.getName().c_str());
|
||
mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Limit = (UINT32)kextPatch.SearchLen;
|
||
OC_DATA_ASSIGN_N(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Mask, kextPatch.MaskFind.data(), kextPatch.MaskFind.size());
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->MaxKernel, ""); // it has been filtered, so we don't need to set Min and MaxKernel
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->MinKernel, "");
|
||
OC_DATA_ASSIGN_N(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Replace, kextPatch.Replace.data(), kextPatch.Replace.size());
|
||
OC_DATA_ASSIGN_N(mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->ReplaceMask, kextPatch.MaskReplace.data(), kextPatch.MaskReplace.size());
|
||
mOpenCoreConfiguration.Kernel.Patch.Values[kextPatchIdx]->Skip = (UINT32)kextPatch.Skip;
|
||
#ifdef JIEF_DEBUG
|
||
if ( kextPatch.Label == "algrey - cpuid_set_info - ryzen cores and logicals count - part 3 - 10.14"_XS8 ) {
|
||
DEBUG (( DEBUG_INFO, "" ));
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void LOADER_ENTRY::StartLoader()
|
||
{
|
||
EFI_STATUS Status;
|
||
EFI_TEXT_STRING ConOutOutputString = 0;
|
||
EFI_HANDLE ImageHandle = NULL;
|
||
EFI_LOADED_IMAGE *LoadedImage = NULL;
|
||
CONST CHAR8 *InstallerVersion;
|
||
|
||
DbgHeader("StartLoader");
|
||
|
||
DBG("Starting %ls\n", FileDevicePathToXStringW(DevicePath).wc_str());
|
||
displayFreeMemory("LOADER_ENTRY::StartLoader()"_XS8);
|
||
// while ( OcCountFreePages(NULL) > 300000 && AllocatePages(100) ) /*DBG("Free memory : %lld\n", OcCountFreePages(NULL))*/;
|
||
// displayFreeMemory();
|
||
|
||
if (Settings.notEmpty()) {
|
||
DBG(" Settings: %ls\n", Settings.wc_str());
|
||
Status = gConf.ReLoadConfig(Settings);
|
||
if (!EFI_ERROR(Status)) {
|
||
DBG(" - found custom settings for this entry: %ls\n", Settings.wc_str());
|
||
} else {
|
||
DBG(" - [!] LoadUserSettings failed: %s\n", efiStrError(Status));
|
||
/* we are not sure of the state of gSettings here... try to boot anyway */
|
||
}
|
||
}
|
||
|
||
DBG("Finally: ExternalClock=%lluMHz BusSpeed=%llukHz CPUFreq=%uMHz",
|
||
DivU64x32(gCPUStructure.ExternalClock + Kilo - 1, Kilo),
|
||
DivU64x32(gCPUStructure.FSBFrequency + Kilo - 1, Kilo),
|
||
gCPUStructure.MaxSpeed);
|
||
if (gSettings.CPU.QPI) {
|
||
DBG(" QPI: hw.busfrequency=%lluHz\n", MultU64x32(gSettings.CPU.QPI, Mega));
|
||
} else {
|
||
// to match the value of hw.busfrequency in the terminal
|
||
DBG(" PIS: hw.busfrequency=%lluHz\n", MultU64x32(LShiftU64(DivU64x32(gCPUStructure.ExternalClock + Kilo - 1, Kilo), 2), Mega));
|
||
}
|
||
|
||
//Free memory
|
||
ConfigsList.setEmpty();
|
||
DsdtsList.setEmpty();
|
||
|
||
OptionMenu.FreeMenu();
|
||
//there is a place to free memory
|
||
// GuiAnime
|
||
// mainParser
|
||
// BuiltinIcons
|
||
// OSIcons
|
||
|
||
delete ThemeX;
|
||
ThemeX = NULL;
|
||
|
||
|
||
#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE
|
||
if ( nsvg__nbDanglingPtr() > 0 ) {
|
||
DBG("There is %zu dangling ptr from SVG subsytem\n", nsvg__nbDanglingPtr());
|
||
nsvg__outputDanglingPtr();
|
||
}
|
||
#endif
|
||
#ifdef JIEF_DEBUG
|
||
displayFreeMemory("LOADER_ENTRY::StartLoader() atfer ThemeX deleted"_XS8);
|
||
#endif
|
||
|
||
|
||
if ( OSTYPE_IS_OSX(LoaderType) || OSTYPE_IS_OSX_RECOVERY(LoaderType) || OSTYPE_IS_OSX_INSTALLER(LoaderType) ) {
|
||
|
||
// if OC is NOT initialized with OcMain, we need the following
|
||
// OcConfigureLogProtocol (
|
||
// 9,
|
||
// 0,
|
||
// 2151678018,
|
||
// 2147483648,
|
||
// OPEN_CORE_LOG_PREFIX_PATH,
|
||
// mOpenCoreStorage.FileSystem
|
||
// );
|
||
// DEBUG ((DEBUG_INFO, "OC: Log initialized...\n"));
|
||
// OcAppleDebugLogInstallProtocol(0);
|
||
|
||
DBG("Beginning OC\n");
|
||
|
||
EFI_LOADED_IMAGE* OcLoadedImage;
|
||
Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &OcLoadedImage);
|
||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileSystem = OcLocateFileSystem(OcLoadedImage->DeviceHandle, OcLoadedImage->FilePath);
|
||
Status = OcStorageInitFromFs(&mOpenCoreStorage, FileSystem, NULL, NULL, self.getCloverDirFullPath().wc_str(), NULL);
|
||
|
||
/*
|
||
* Define READ_FROM_OC to have mOpenCoreConfiguration initialized from config-oc.plist
|
||
* The boot should work.
|
||
* Next, comment out the next lines one by one. Once the boot failed, we got the section that
|
||
* holds the setting that makes a difference.
|
||
*/
|
||
//#define USE_OC_SECTION_Acpi
|
||
//#define USE_OC_SECTION_Booter
|
||
//#define USE_OC_SECTION_DeviceProperties
|
||
//#define USE_OC_SECTION_Kernel
|
||
//#define USE_OC_SECTION_Misc
|
||
//#define USE_OC_SECTION_Nvram
|
||
//#define USE_OC_SECTION_PlatformInfo
|
||
//#define USE_OC_SECTION_Uefi
|
||
|
||
#if !defined(USE_OC_SECTION_Acpi) && !defined(USE_OC_SECTION_Booter) && !defined(USE_OC_SECTION_DeviceProperties) && !defined(USE_OC_SECTION_Kernel) && !defined(USE_OC_SECTION_Misc) && \
|
||
!defined(USE_OC_SECTION_Nvram) && !defined(USE_OC_SECTION_PlatformInfo) && !defined(USE_OC_SECTION_Uefi)
|
||
|
||
memset(&mOpenCoreConfiguration, 0, sizeof(mOpenCoreConfiguration));
|
||
// DBG("config-oc.plist isn't used at all\n");
|
||
|
||
#else
|
||
Status = ClOcReadConfigurationFile(&mOpenCoreStorage, L"config-oc.plist", &mOpenCoreConfiguration);
|
||
if ( EFI_ERROR(Status) ) panic("ClOcReadConfigurationFile");
|
||
|
||
#ifndef USE_OC_SECTION_Acpi
|
||
memset(&mOpenCoreConfiguration.Acpi, 0, sizeof(mOpenCoreConfiguration.Acpi));
|
||
DBG("Erase mOpenCoreConfiguration.Acpi\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Acpi\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Booter
|
||
memset(&mOpenCoreConfiguration.Booter, 0, sizeof(mOpenCoreConfiguration.Booter));
|
||
DBG("Erase mOpenCoreConfiguration.Booter\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Booter\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_DeviceProperties
|
||
memset(&mOpenCoreConfiguration.DeviceProperties, 0, sizeof(mOpenCoreConfiguration.DeviceProperties));
|
||
DBG("Erase mOpenCoreConfiguration.DeviceProperties\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.DeviceProperties\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Kernel
|
||
memset(&mOpenCoreConfiguration.Kernel, 0, sizeof(mOpenCoreConfiguration.Kernel));
|
||
DBG("Erase mOpenCoreConfiguration.Kernel\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Kernel\n");
|
||
for ( size_t i = 0 ; i < mOpenCoreConfiguration.Kernel.Add.Count ; i ++ ) {
|
||
OC_KERNEL_ADD_ENTRY* entry = mOpenCoreConfiguration.Kernel.Add.Values[i];
|
||
OC_STRING_ASSIGN(entry->BundlePath, S8Printf("Kexts\\%s", OC_BLOB_GET(&entry->BundlePath)).c_str());
|
||
}
|
||
|
||
// DBG("mOpenCoreConfiguration.Kernel.Add.Count=%d\n", mOpenCoreConfiguration.Kernel.Add.Count);
|
||
// for ( size_t i = 0 ; i < mOpenCoreConfiguration.Kernel.Add.Count ; i++ )
|
||
// {
|
||
// DBG("mOpenCoreConfiguration.Kernel.Add.Values[%zd]->Identifier=%s\n", i, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Add.Values[i]->Identifier));
|
||
// DBG("mOpenCoreConfiguration.Kernel.Add.Values[%zd]->BundlePath=%s\n", i, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Add.Values[i]->BundlePath));
|
||
// DBG("mOpenCoreConfiguration.Kernel.Add.Values[%zd]->PlistPath=%s\n", i, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Add.Values[i]->PlistPath));
|
||
// }
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Misc
|
||
memset(&mOpenCoreConfiguration.Misc, 0, sizeof(mOpenCoreConfiguration.Misc));
|
||
DBG("Erase mOpenCoreConfiguration.Misc\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Misc\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Nvram
|
||
memset(&mOpenCoreConfiguration.Nvram, 0, sizeof(mOpenCoreConfiguration.Nvram));
|
||
DBG("Erase mOpenCoreConfiguration.Nvram\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Nvram\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_PlatformInfo
|
||
memset(&mOpenCoreConfiguration.PlatformInfo, 0, sizeof(mOpenCoreConfiguration.PlatformInfo));
|
||
DBG("Erase mOpenCoreConfiguration.PlatformInfo\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.PlatformInfo\n");
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Uefi
|
||
memset(&mOpenCoreConfiguration.Uefi, 0, sizeof(mOpenCoreConfiguration.Uefi));
|
||
DBG("Erase mOpenCoreConfiguration.Uefi\n");
|
||
#else
|
||
DBG("Keep mOpenCoreConfiguration.Uefi\n");
|
||
// memset(&mOpenCoreConfiguration.Uefi.Apfs, 0, sizeof(mOpenCoreConfiguration.Uefi.Apfs));
|
||
// memset(&mOpenCoreConfiguration.Uefi.Audio, 0, sizeof(mOpenCoreConfiguration.Uefi.Audio));
|
||
// memset(&mOpenCoreConfiguration.Uefi.ConnectDrivers, 0, sizeof(mOpenCoreConfiguration.Uefi.ConnectDrivers));
|
||
// memset(&mOpenCoreConfiguration.Uefi.Drivers, 0, sizeof(mOpenCoreConfiguration.Uefi.Drivers));
|
||
// memset(&mOpenCoreConfiguration.Uefi.Input, 0, sizeof(mOpenCoreConfiguration.Uefi.Input));
|
||
// memset(&mOpenCoreConfiguration.Uefi.Output, 0, sizeof(mOpenCoreConfiguration.Uefi.Output));
|
||
// memset(&mOpenCoreConfiguration.Uefi.ProtocolOverrides, 0, sizeof(mOpenCoreConfiguration.Uefi.ProtocolOverrides));
|
||
// memset(&mOpenCoreConfiguration.Uefi.Quirks, 0, sizeof(mOpenCoreConfiguration.Uefi.Quirks));
|
||
// memset(&mOpenCoreConfiguration.Uefi.ReservedMemory, 0, sizeof(mOpenCoreConfiguration.Uefi.ReservedMemory)); // doesn't matter
|
||
#endif
|
||
|
||
#endif
|
||
|
||
|
||
|
||
if ( gSettings.Boot.DebugLog ) {
|
||
mOpenCoreConfiguration.Misc.Debug.AppleDebug = true;
|
||
mOpenCoreConfiguration.Misc.Debug.ApplePanic = true;
|
||
|
||
#ifndef LESS_DEBUG
|
||
mOpenCoreConfiguration.Misc.Debug.DisplayLevel = 0x80400042;
|
||
#else
|
||
mOpenCoreConfiguration.Misc.Debug.DisplayLevel = 0x80000042;
|
||
#endif
|
||
mOpenCoreConfiguration.Misc.Debug.Target = 0x41;
|
||
} else {
|
||
#ifdef JIEF_DEBUG
|
||
egSetGraphicsModeEnabled(false);
|
||
mOpenCoreConfiguration.Misc.Debug.ApplePanic = true;
|
||
mOpenCoreConfiguration.Misc.Debug.DisplayLevel = 0x80000042;
|
||
mOpenCoreConfiguration.Misc.Debug.Target = 0x3;
|
||
#endif
|
||
}
|
||
|
||
#ifndef USE_OC_SECTION_Misc
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Misc.Security.SecureBootModel, "Disabled");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Misc.Security.Vault, "Optional");
|
||
#endif
|
||
#ifdef USE_OC_SECTION_Nvram
|
||
mOpenCoreConfiguration.Nvram.WriteFlash = true;
|
||
#endif
|
||
#ifndef USE_OC_SECTION_Uefi
|
||
mOpenCoreConfiguration.Uefi.Quirks.ForceOcWriteFlash = gSettings.Quirks.OcBooterQuirks.ForceOcWriteFlash;
|
||
#endif
|
||
|
||
#ifndef USE_OC_SECTION_Booter
|
||
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Count = (UINT32)gSettings.Quirks.mmioWhiteListArray.size();
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.AllocCount = mOpenCoreConfiguration.Booter.MmioWhitelist.Count;
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.ValueSize = sizeof(__typeof_am__(**mOpenCoreConfiguration.Booter.MmioWhitelist.Values)); // sizeof(OC_KERNEL_ADD_ENTRY) == 680
|
||
if ( mOpenCoreConfiguration.Booter.MmioWhitelist.Count > 0 ) {
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Values = (OC_BOOTER_WL_ENTRY**)AllocatePool(mOpenCoreConfiguration.Booter.MmioWhitelist.AllocCount * sizeof(*mOpenCoreConfiguration.Booter.MmioWhitelist.Values)); // sizeof(OC_KERNEL_ADD_ENTRY) == 680
|
||
} else {
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Values = NULL;
|
||
}
|
||
for ( size_t idx = 0 ; idx < gSettings.Quirks.mmioWhiteListArray.size() ; idx++ ) {
|
||
const SETTINGS_DATA::QuirksClass::MMIOWhiteList& entry = gSettings.Quirks.mmioWhiteListArray[idx];
|
||
DBG("Bridge mmioWhiteList[%zu] to OC : comment=%s\n", idx, entry.comment.c_str());
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Values[idx] = (__typeof_am__(*mOpenCoreConfiguration.Booter.MmioWhitelist.Values))AllocatePool(mOpenCoreConfiguration.Booter.MmioWhitelist.ValueSize);
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Values[idx]->Address = entry.address;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Booter.MmioWhitelist.Values[idx]->Comment, entry.comment.c_str());
|
||
mOpenCoreConfiguration.Booter.MmioWhitelist.Values[idx]->Enabled = entry.enabled;
|
||
}
|
||
|
||
// It's possible to memcpy the whole struct instead of assigning individual member. But that would be relying on internel C++ binary structure,
|
||
// and worse, if a field is added by OC, everything could be shifted.
|
||
memset(&mOpenCoreConfiguration.Booter.Quirks, 0, sizeof(mOpenCoreConfiguration.Booter.Quirks));
|
||
mOpenCoreConfiguration.Booter.Quirks.AvoidRuntimeDefrag = gSettings.Quirks.OcBooterQuirks.AvoidRuntimeDefrag;
|
||
mOpenCoreConfiguration.Booter.Quirks.DevirtualiseMmio = gSettings.Quirks.OcBooterQuirks.DevirtualiseMmio;
|
||
mOpenCoreConfiguration.Booter.Quirks.DisableSingleUser = gSettings.Quirks.OcBooterQuirks.DisableSingleUser;
|
||
mOpenCoreConfiguration.Booter.Quirks.DisableVariableWrite = gSettings.Quirks.OcBooterQuirks.DisableVariableWrite;
|
||
mOpenCoreConfiguration.Booter.Quirks.DiscardHibernateMap = gSettings.Quirks.OcBooterQuirks.DiscardHibernateMap;
|
||
mOpenCoreConfiguration.Booter.Quirks.EnableSafeModeSlide = gSettings.Quirks.OcBooterQuirks.EnableSafeModeSlide;
|
||
mOpenCoreConfiguration.Booter.Quirks.EnableWriteUnprotector = gSettings.Quirks.OcBooterQuirks.EnableWriteUnprotector;
|
||
mOpenCoreConfiguration.Booter.Quirks.ForceExitBootServices = gSettings.Quirks.OcBooterQuirks.ForceExitBootServices;
|
||
mOpenCoreConfiguration.Booter.Quirks.ProtectMemoryRegions = gSettings.Quirks.OcBooterQuirks.ProtectMemoryRegions;
|
||
mOpenCoreConfiguration.Booter.Quirks.ProtectSecureBoot = gSettings.Quirks.OcBooterQuirks.ProtectSecureBoot;
|
||
mOpenCoreConfiguration.Booter.Quirks.ProtectUefiServices = gSettings.Quirks.OcBooterQuirks.ProtectUefiServices;
|
||
mOpenCoreConfiguration.Booter.Quirks.ProvideCustomSlide = gSettings.Quirks.OcBooterQuirks.ProvideCustomSlide;
|
||
mOpenCoreConfiguration.Booter.Quirks.ProvideMaxSlide = gSettings.Quirks.OcBooterQuirks.ProvideMaxSlide;
|
||
mOpenCoreConfiguration.Booter.Quirks.RebuildAppleMemoryMap = gSettings.Quirks.OcBooterQuirks.RebuildAppleMemoryMap;
|
||
mOpenCoreConfiguration.Booter.Quirks.ResizeAppleGpuBars = gSettings.Quirks.OcBooterQuirks.ResizeAppleGpuBars;
|
||
mOpenCoreConfiguration.Booter.Quirks.SetupVirtualMap = gSettings.Quirks.OcBooterQuirks.SetupVirtualMap;
|
||
mOpenCoreConfiguration.Booter.Quirks.SignalAppleOS = false; //gSettings.Quirks.OcBooterQuirks.SignalAppleOS;
|
||
mOpenCoreConfiguration.Booter.Quirks.SyncRuntimePermissions = gSettings.Quirks.OcBooterQuirks.SyncRuntimePermissions;
|
||
|
||
|
||
#endif
|
||
|
||
|
||
FillOCCpuInfo(&mOpenCoreCpuInfo);
|
||
|
||
mOpenCoreConfiguration.Uefi.Quirks.TscSyncTimeout = gSettings.Quirks.OcBooterQuirks.TscSyncTimeout;
|
||
|
||
#ifndef USE_OC_SECTION_Kernel
|
||
|
||
XObjArray<SIDELOAD_KEXT> kextArray;
|
||
if (!DoHibernateWake) {
|
||
AddKextsInArray(&kextArray);
|
||
}
|
||
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Scheme.KernelArch, "x86_64");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Scheme.KernelCache, gSettings.Quirks.OcKernelCache.c_str());
|
||
mOpenCoreConfiguration.Kernel.Scheme.FuzzyMatch = gSettings.Quirks.FuzzyMatch;
|
||
|
||
memset(&mOpenCoreConfiguration.Kernel.Quirks, 0, sizeof(mOpenCoreConfiguration.Kernel.Quirks));
|
||
mOpenCoreConfiguration.Kernel.Quirks.SetApfsTrimTimeout = -1; // Jief: Slice modified OcConfigurationLib.h to set -1 by default instead of 999. I prefer the modification here to minimize commts in OC submodule. Makes it easier to upgrade submodule.
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleCpuPmCfgLock = GlobalConfig.KPAppleIntelCPUPM;
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmCfgLock = GlobalConfig.KPKernelPm;
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmExtraMsrs = gSettings.Quirks.OcKernelQuirks.AppleXcpmExtraMsrs;
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmForceBoost = gSettings.Quirks.OcKernelQuirks.AppleXcpmForceBoost;
|
||
#ifndef USE_OC_SECTION_PlatformInfo
|
||
mOpenCoreConfiguration.Kernel.Quirks.CustomSmbiosGuid = gSettings.KernelAndKextPatches.KPDELLSMBIOS;
|
||
#endif
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableIoMapper = gSettings.Quirks.OcKernelQuirks.DisableIoMapper;
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableLinkeditJettison = gSettings.Quirks.OcKernelQuirks.DisableLinkeditJettison;
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableRtcChecksum = gSettings.KernelAndKextPatches.KPAppleRTC;
|
||
mOpenCoreConfiguration.Kernel.Emulate.DummyPowerManagement = gSettings.Quirks.OcKernelQuirks.DummyPowerManagement;
|
||
mOpenCoreConfiguration.Kernel.Quirks.ExtendBTFeatureFlags = gSettings.Quirks.OcKernelQuirks.ExtendBTFeatureFlags;
|
||
mOpenCoreConfiguration.Kernel.Quirks.ExternalDiskIcons = gSettings.Quirks.OcKernelQuirks.ExternalDiskIcons;
|
||
mOpenCoreConfiguration.Kernel.Quirks.IncreasePciBarSize = gSettings.Quirks.OcKernelQuirks.IncreasePciBarSize;
|
||
mOpenCoreConfiguration.Kernel.Quirks.LapicKernelPanic = gSettings.KernelAndKextPatches.KPKernelLapic;
|
||
mOpenCoreConfiguration.Kernel.Quirks.PanicNoKextDump = gSettings.KernelAndKextPatches.KPPanicNoKextDump;
|
||
mOpenCoreConfiguration.Kernel.Quirks.PowerTimeoutKernelPanic = gSettings.Quirks.OcKernelQuirks.PowerTimeoutKernelPanic;
|
||
mOpenCoreConfiguration.Kernel.Quirks.ThirdPartyDrives = gSettings.Quirks.OcKernelQuirks.ThirdPartyDrives;
|
||
mOpenCoreConfiguration.Kernel.Quirks.XhciPortLimit = gSettings.Quirks.OcKernelQuirks.XhciPortLimit;
|
||
mOpenCoreConfiguration.Kernel.Quirks.ProvideCurrentCpuInfo = gSettings.Quirks.OcKernelQuirks.ProvideCurrentCpuInfo;
|
||
|
||
mOpenCoreConfiguration.Kernel.Add.Count = (UINT32)kextArray.size();
|
||
mOpenCoreConfiguration.Kernel.Add.AllocCount = mOpenCoreConfiguration.Kernel.Add.Count;
|
||
mOpenCoreConfiguration.Kernel.Add.ValueSize = sizeof(__typeof_am__(**mOpenCoreConfiguration.Kernel.Add.Values)); // sizeof(OC_KERNEL_ADD_ENTRY) == 680
|
||
mOpenCoreConfiguration.Kernel.Add.Values = (OC_KERNEL_ADD_ENTRY**)malloc(mOpenCoreConfiguration.Kernel.Add.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Add.Values)); // sizeof(OC_KERNEL_ADD_ENTRY*) == sizeof(ptr)
|
||
memset(mOpenCoreConfiguration.Kernel.Add.Values, 0, mOpenCoreConfiguration.Kernel.Add.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Add.Values));
|
||
|
||
// Seems that Lilu must be first.
|
||
size_t pos = setKextAtPos(&kextArray, "Lilu.kext"_XS8, 0);
|
||
pos = setKextAtPos(&kextArray, "VirtualSMC.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "FakeSMC.kext"_XS8, pos);
|
||
// pos = setKextAtPos(&kextArray, "vecLib.kext"_XS8, pos);
|
||
// pos = setKextAtPos(&kextArray, "IOAudioFamily.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "IOSkywalkFamily.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "FakePCIID.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "FakePCIID_XHCIMux.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "AMDRyzenCPUPowerManagement.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "SMCAMDProcessor.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "WhateverGreen.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "AppleALC.kext"_XS8, pos);
|
||
// pos = setKextAtPos(&kextArray, "IntelMausi.kext"_XS8, pos); // not needed special order?
|
||
pos = setKextAtPos(&kextArray, "SMCProcessor.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "SMCSuperIO.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "USBPorts.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooGPIO.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooI2CServices.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooI2C.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooI2CHID.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooSMBus.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "VoodooRMI.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "BrcmFirmwareData.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "BrcmPatchRAM2.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "BrcmPatchRAM3.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "IO80211FamilyLegacy.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "HS80211Family.kext"_XS8, pos);
|
||
pos = setKextAtPos(&kextArray, "AirPortAtheros40.kext"_XS8, pos);
|
||
|
||
for (size_t kextIdx = 0 ; kextIdx < kextArray.size() ; kextIdx++ ) {
|
||
const SIDELOAD_KEXT& KextEntry = kextArray[kextIdx];
|
||
DBG("Bridge kext to OC : Path=%ls\n", KextEntry.FileName.wc_str());
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx] = (__typeof_am__(*mOpenCoreConfiguration.Kernel.Add.Values))malloc(mOpenCoreConfiguration.Kernel.Add.ValueSize);
|
||
memset(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx], 0, mOpenCoreConfiguration.Kernel.Add.ValueSize);
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Enabled = 1;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Arch, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Scheme.KernelArch));
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Comment, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->MaxKernel, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->MinKernel, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->Identifier, "");
|
||
|
||
assert( selfOem.isKextsDirFound() ); // be sure before calling getKextsPathRelToSelfDir()
|
||
XStringW dirPath = SWPrintf("%ls\\%ls", selfOem.getKextsDirPathRelToSelfDir().wc_str(), KextEntry.KextDirNameUnderOEMPath.wc_str());
|
||
|
||
XString8 bundlePath = S8Printf("%ls\\%ls", dirPath.wc_str(), KextEntry.FileName.wc_str());
|
||
if ( FileExists(&self.getCloverDir(), bundlePath) ) {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->BundlePath, bundlePath.c_str());
|
||
} else {
|
||
DBG("Cannot find kext bundlePath at '%s'\n", bundlePath.c_str());
|
||
}
|
||
#if 1
|
||
//CFBundleExecutable
|
||
XBool NoContents = false;
|
||
XStringW infoPlistPath = getKextPlist(&self.getCloverDir(), dirPath, KextEntry.FileName, &NoContents); //it will be fullPath, including dir
|
||
DBG("InfoPlistPath=%ls\n", infoPlistPath.wc_str());
|
||
TagDict* dict = getInfoPlist(&self.getCloverDir(), infoPlistPath);
|
||
// XBool inject = checkOSBundleRequired(dict);
|
||
XBool inject = true;
|
||
if (inject) {
|
||
if ( infoPlistPath.notEmpty()) {
|
||
if (NoContents) {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistPath, "Info.plist");
|
||
} else {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistPath, "Contents/Info.plist");
|
||
}
|
||
} else {
|
||
DBG("Cannot find kext info.plist at '%ls'\n", KextEntry.FileName.wc_str());
|
||
}
|
||
XString8 execpath = getKextExecPath(&self.getCloverDir(), dirPath, KextEntry.FileName, dict, NoContents);
|
||
if (execpath.notEmpty()) {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ExecutablePath, execpath.c_str());
|
||
DBG("assign executable as '%s'\n", execpath.c_str());
|
||
}
|
||
}
|
||
|
||
#else
|
||
XStringW execpath = S8Printf("Contents\\MacOS\\%ls", KextEntry.FileName.subString(0, KextEntry.FileName.rindexOf(".")).wc_str());
|
||
XStringW fullPath = SWPrintf("%s\\%ls", OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->BundlePath), execpath.wc_str());
|
||
if ( FileExists(&self.getCloverDir(), fullPath) ) {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ExecutablePath, S8Printf("Contents\\MacOS\\%ls", KextEntry.FileName.subString(0, KextEntry.FileName.rindexOf(".")).wc_str()).c_str());
|
||
}
|
||
XStringW infoPlistPath = SWPrintf("%s\\Contents\\Info.plist", OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->BundlePath));
|
||
if (FileExists(&self.getCloverDir(), infoPlistPath)) {
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistPath, "Contents/Info.plist"); // TODO : is always Contents/Info.plist ?
|
||
} else {
|
||
DBG("Cannot find kext info.plist at '%ls'\n", infoPlistPath.wc_str());
|
||
}
|
||
#endif
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ImageData = NULL;
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->ImageDataSize = 0;
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistData = NULL;
|
||
mOpenCoreConfiguration.Kernel.Add.Values[kextIdx]->PlistDataSize = 0;
|
||
|
||
} // for (size_t kextIdx
|
||
|
||
|
||
mOpenCoreConfiguration.Kernel.Force.Count = (UINT32)KernelAndKextPatches.ForceKextsToLoad.size();
|
||
mOpenCoreConfiguration.Kernel.Force.AllocCount = mOpenCoreConfiguration.Kernel.Force.Count;
|
||
mOpenCoreConfiguration.Kernel.Force.ValueSize = sizeof(__typeof_am__(**mOpenCoreConfiguration.Kernel.Force.Values)); // sizeof(OC_KERNEL_FORCE_ENTRY)
|
||
int valuesSize = mOpenCoreConfiguration.Kernel.Force.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Force.Values);
|
||
mOpenCoreConfiguration.Kernel.Force.Values = (OC_KERNEL_ADD_ENTRY**)malloc(valuesSize); // sizeof(OC_KERNEL_FORCE_ENTRY*) == sizeof(ptr)
|
||
memset(mOpenCoreConfiguration.Kernel.Force.Values, 0, valuesSize);
|
||
|
||
|
||
|
||
for (size_t kextIdx = 0; kextIdx < KernelAndKextPatches.ForceKextsToLoad.size(); kextIdx++) {
|
||
const XStringW& forceKext = KernelAndKextPatches.ForceKextsToLoad[kextIdx];
|
||
|
||
DBG("Force kext to OC : Path=%ls\n", forceKext.wc_str());
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx] = (__typeof_am__(*mOpenCoreConfiguration.Kernel.Force.Values))malloc(mOpenCoreConfiguration.Kernel.Force.ValueSize);
|
||
memset(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx], 0, mOpenCoreConfiguration.Kernel.Force.ValueSize);
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->Enabled = 1;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->Arch, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Scheme.KernelArch));
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->Comment, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->MaxKernel, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->MinKernel, "");
|
||
// OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->Identifier, "");
|
||
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->ImageData = NULL;
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->ImageDataSize = 0;
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->PlistData = NULL;
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->PlistDataSize = 0;
|
||
|
||
REFIT_VOLUME * SystemVolume = Volume;
|
||
EFI_FILE* SysRoot = Volume->RootDir;
|
||
|
||
|
||
if (Volume->ApfsRole == APPLE_APFS_VOLUME_ROLE_PREBOOT) {
|
||
//search for other partition
|
||
DBG("boot from Preboot, index=%llu\n", Volume->Index);
|
||
size_t numbers = Volumes.size();
|
||
size_t sysIndex = 0;
|
||
for (sysIndex=Volume->Index+1; sysIndex < numbers; sysIndex++) {
|
||
SystemVolume = &Volumes[sysIndex];
|
||
SysRoot = SystemVolume->RootDir;
|
||
|
||
DBG("test volume %zd, name %ls:\n", sysIndex, SystemVolume->VolName.wc_str());
|
||
|
||
if (FileExists(SysRoot, L"\\System\\Library\\CoreServices\\boot.efi")) {
|
||
DBG("boot.efi found on %zd\n", sysIndex);
|
||
}
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry = NULL;
|
||
DirIterOpen(SysRoot, L"\\System\\Library\\Extensions\\AMDSupport.kext\\Contents\\MacOS\\", &DirIter);
|
||
while (DirIterNext(&DirIter, 1, L"*", &DirEntry)) {
|
||
if (DirEntry->FileName[0] == '.') {
|
||
DBG("Skip dot entries: %ls\n", DirEntry->FileName);
|
||
continue;
|
||
}
|
||
DBG("%ls attr=%llu\n", DirEntry->FileName, DirEntry->Attribute);
|
||
}
|
||
DirIterClose(&DirIter);
|
||
if (FileExists(SysRoot, L"\\System\\Library\\Extensions\\AMDSupport.kext\\Contents\\MacOS\\AMDSupport")) {
|
||
DBG("AMDSupport found on %zd\n", sysIndex); //never found
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->ImageData = (UINT8*)SysRoot;
|
||
|
||
size_t i1 = forceKext.rindexOf("\\") + 1;
|
||
size_t i2 = forceKext.rindexOf(".");
|
||
XStringW identifier = forceKext.subString(i1, i2 - i1);
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->Identifier, S8Printf("%ls", identifier.wc_str()).c_str());
|
||
|
||
XString8 execpath = S8Printf("Contents\\MacOS\\%ls", identifier.wc_str());
|
||
DBG("calculated execpath=%s\n", execpath.c_str());
|
||
|
||
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->BundlePath, S8Printf("%ls",forceKext.wc_str()).c_str());
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->PlistPath, "Contents\\Info.plist");
|
||
|
||
//then we have to find executablePath and plistPath
|
||
DBG("bundle path=%s\n", mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->BundlePath.Value);
|
||
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->ExecutablePath, execpath.c_str());
|
||
DBG("assign executable as '%s'\n", mOpenCoreConfiguration.Kernel.Force.Values[kextIdx]->ExecutablePath.Value);
|
||
|
||
}
|
||
if (gSettings.KernelAndKextPatches.BlockSkywalk) {
|
||
mOpenCoreConfiguration.Kernel.Block.Count = 1;
|
||
mOpenCoreConfiguration.Kernel.Block.AllocCount = 1;
|
||
mOpenCoreConfiguration.Kernel.Block.ValueSize = sizeof(__typeof_am__(**mOpenCoreConfiguration.Kernel.Block.Values));
|
||
valuesSize = mOpenCoreConfiguration.Kernel.Block.AllocCount*sizeof(*mOpenCoreConfiguration.Kernel.Block.Values);
|
||
mOpenCoreConfiguration.Kernel.Block.Values = (OC_KERNEL_BLOCK_ENTRY**)malloc(valuesSize);
|
||
|
||
memset(mOpenCoreConfiguration.Kernel.Block.Values, 0, valuesSize);
|
||
|
||
mOpenCoreConfiguration.Kernel.Block.Values[0] = (__typeof_am__(*mOpenCoreConfiguration.Kernel.Block.Values))malloc(mOpenCoreConfiguration.Kernel.Block.ValueSize);
|
||
memset(mOpenCoreConfiguration.Kernel.Block.Values[0], 0, mOpenCoreConfiguration.Kernel.Block.ValueSize);
|
||
mOpenCoreConfiguration.Kernel.Block.Values[0]->Enabled = 1;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->Arch, OC_BLOB_GET(&mOpenCoreConfiguration.Kernel.Scheme.KernelArch));
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->Comment, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->MaxKernel, "");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->MinKernel, "23");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->Identifier, "com.apple.iokit.IOSkywalkFamily");
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Kernel.Block.Values[0]->Strategy, "Exclude");
|
||
}
|
||
#endif
|
||
|
||
mOpenCoreConfiguration.Uefi.Output.ProvideConsoleGop = gSettings.GUI.ProvideConsoleGop;
|
||
OC_STRING_ASSIGN(mOpenCoreConfiguration.Uefi.Output.Resolution, XString8(gSettings.GUI.ScreenResolution).c_str());
|
||
|
||
|
||
if ( OpenRuntimeEfiName.notEmpty() ) {
|
||
XStringW FileName = SWPrintf("%ls\\%ls\\%ls", self.getCloverDirFullPath().wc_str(), getDriversPath().wc_str(), OpenRuntimeEfiName.wc_str());
|
||
EFI_HANDLE DriverHandle;
|
||
Status = gBS->LoadImage(false, gImageHandle, FileDevicePath(self.getSelfLoadedImage().DeviceHandle, FileName), NULL, 0, &DriverHandle);
|
||
if ( !EFI_ERROR(Status) ) {
|
||
Status = gBS->StartImage(DriverHandle, 0, 0);
|
||
DBG("Start '%ls' : Status %s\n", OpenRuntimeEfiName.wc_str(), efiStrError(Status));
|
||
|
||
if ( !EFI_ERROR(Status) )
|
||
{
|
||
OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime;
|
||
Status = gBS->LocateProtocol (
|
||
gOcFirmwareRuntimeProtocolGuid,
|
||
NULL,
|
||
(VOID **) &FwRuntime
|
||
);
|
||
|
||
if (!EFI_ERROR (Status)) {
|
||
if (FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) {
|
||
} else {
|
||
DEBUG ((
|
||
DEBUG_ERROR,
|
||
"OCABC: Incompatible OpenRuntime r%u, require r%u\n",
|
||
(UINT32) FwRuntime->Revision,
|
||
(UINT32) OC_FIRMWARE_RUNTIME_REVISION
|
||
));
|
||
DBG("Incompatible OpenRuntime r%llu, require r%u\n", FwRuntime->Revision, OC_FIRMWARE_RUNTIME_REVISION);
|
||
}
|
||
}
|
||
}
|
||
}else{
|
||
DBG("Error when loading '%ls' : Status %s.\n", OpenRuntimeEfiName.wc_str(), efiStrError(Status));
|
||
}
|
||
}else{
|
||
DBG("No OpenRuntime driver. This is ok, OpenRuntime is not mandatory.\n");
|
||
}
|
||
|
||
OcMain(&mOpenCoreStorage, NULL);
|
||
|
||
XStringW DevicePathAsString = DevicePathToXStringW(DevicePath);
|
||
if ( DevicePathAsString.rindexOf(".dmg") == MAX_XSIZE )
|
||
{
|
||
// point to InternalEfiLoadImage from OC
|
||
Status = gBS->LoadImage (
|
||
false,
|
||
gImageHandle,
|
||
DevicePath,
|
||
NULL,
|
||
0,
|
||
&ImageHandle
|
||
);
|
||
if ( EFI_ERROR(Status) ) {
|
||
DBG("LoadImage at '%ls' failed. Status = %s\n", DevicePathAsString.wc_str(), efiStrError(Status));
|
||
return;
|
||
}
|
||
DBG("ImageHandle = %llx\n", uintptr_t(ImageHandle));
|
||
} else {
|
||
// NOTE : OpenCore ignore the name of the dmg.
|
||
// InternalLoadDmg calls InternalFindFirstDmgFileName to find the dmg file name.
|
||
// So be careful that, if an other dmg exists in the dir, that might boot on the wrong one.
|
||
|
||
EFI_DEVICE_PATH_PROTOCOL* DevicePathCopy = DuplicateDevicePath(DevicePath);
|
||
|
||
EFI_DEVICE_PATH_PROTOCOL* PreviousNode = NULL;
|
||
EFI_DEVICE_PATH_PROTOCOL* Node = DevicePathCopy;
|
||
while (!IsDevicePathEnd(Node)) {
|
||
if ( Node->Type == MEDIA_DEVICE_PATH && Node->SubType == MEDIA_FILEPATH_DP ) {
|
||
PreviousNode = Node;
|
||
break;
|
||
}
|
||
|
||
PreviousNode = Node;
|
||
Node = NextDevicePathNode(Node);
|
||
}
|
||
SetDevicePathEndNode(PreviousNode);
|
||
|
||
EFI_DEVICE_PATH_PROTOCOL* LoaderPathBasenameNode = ConvertTextToDeviceNode(LoaderPath.dirname().wc_str());
|
||
EFI_DEVICE_PATH_PROTOCOL* DevicePathToDmgDir = AppendDevicePathNode(DevicePathCopy, LoaderPathBasenameNode);
|
||
DBG("DevicePathToDmgDir = %ls\n", DevicePathToXStringW(DevicePathToDmgDir).wc_str());
|
||
|
||
INTERNAL_DMG_LOAD_CONTEXT DmgLoadContext = {0,0,0};
|
||
DmgLoadContext.DevicePath = DevicePathToDmgDir;
|
||
EFI_DEVICE_PATH_PROTOCOL* BootEfiFromDmgDevicePath = InternalLoadDmg(&DmgLoadContext, OcDmgLoadingAnyImage);
|
||
DBG("DevicePath of dmg = %ls\n", DevicePathToXStringW(BootEfiFromDmgDevicePath).wc_str());
|
||
|
||
// point to InternalEfiLoadImage from OC
|
||
Status = gBS->LoadImage (
|
||
false,
|
||
gImageHandle,
|
||
BootEfiFromDmgDevicePath,
|
||
NULL,
|
||
0,
|
||
&ImageHandle
|
||
);
|
||
if ( EFI_ERROR(Status) ) {
|
||
DBG("LoadImage at '%ls' failed. Status = %s\n", DevicePathToXStringW(BootEfiFromDmgDevicePath).wc_str(), efiStrError(Status));
|
||
return;
|
||
}
|
||
}
|
||
|
||
EFI_STATUS OptionalStatus = gBS->HandleProtocol (
|
||
ImageHandle,
|
||
&gEfiLoadedImageProtocolGuid,
|
||
(void **) &LoadedImage
|
||
);
|
||
if ( EFI_ERROR(OptionalStatus) ) return; // TODO message ?
|
||
} else {
|
||
// Load image into memory (will be started later)
|
||
Status = LoadEFIImage(DevicePath, LoaderPath.basename(), NULL, &ImageHandle);
|
||
if (EFI_ERROR(Status)) {
|
||
DBG("Image is not loaded, status=%s\n", efiStrError(Status));
|
||
return; // no reason to continue if loading image failed
|
||
}
|
||
}
|
||
|
||
egClearScreen(&BootBgColor); //if not set then it is already MenuBackgroundPixel
|
||
|
||
// KillMouse();
|
||
|
||
// if (LoaderType == OSTYPE_OSX) {
|
||
if (OSTYPE_IS_OSX(LoaderType) ||
|
||
OSTYPE_IS_OSX_RECOVERY(LoaderType) ||
|
||
OSTYPE_IS_OSX_INSTALLER(LoaderType)) {
|
||
|
||
// To display progress bar properly (especially in FV2 mode) boot.efi needs to be in graphics mode.
|
||
// Unfortunately many UEFI implementations change the resolution when SetMode happens.
|
||
// This is not what boot.efi expects, and it freely calls SetMode at its will.
|
||
// As a result we see progress bar at improper resolution and the background is also missing (10.12.x+).
|
||
//
|
||
// libeg already has a workaround for SetMode behaviour, so we extend it for boot.efi support.
|
||
// The approach tries to be follows:
|
||
// 1. Ensure we have graphics mode set (since it is a must in the future).
|
||
// 2. Request text mode for boot.efi, which it expects by default (here a SetMode libeg hack will trigger
|
||
// on problematic UEFI implementations like AMI).
|
||
egSetGraphicsModeEnabled(true);
|
||
egSetGraphicsModeEnabled(false);
|
||
|
||
DBG("GetOSVersion:");
|
||
|
||
//needed for boot.efi patcher
|
||
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (void **) &LoadedImage);
|
||
// Correct OSVersion if it was not found
|
||
// This should happen only for 10.7-10.9 OSTYPE_OSX_INSTALLER
|
||
// For these cases, take OSVersion from loaded boot.efi image in memory
|
||
if ( macOSVersion.isEmpty()) {
|
||
|
||
if (!EFI_ERROR(Status)) {
|
||
// version in boot.efi appears as "Mac OS X 10.?"
|
||
/*
|
||
Start OSName Mac OS X 10.12 End OSName Start OSVendor Apple Inc. End
|
||
*/
|
||
|
||
InstallerVersion = AsciiStrStr((CHAR8*)LoadedImage->ImageBase, "Mac OS X ");
|
||
int location = 9;
|
||
if (InstallerVersion == NULL) {
|
||
InstallerVersion = AsciiStrStr((CHAR8*)LoadedImage->ImageBase, "macOS ");
|
||
location = 7;
|
||
}
|
||
if (InstallerVersion != NULL) { // string was found
|
||
InstallerVersion += location; // advance to version location
|
||
|
||
if (strncmp(InstallerVersion, "10.7", 4) &&
|
||
strncmp(InstallerVersion, "10.8", 4) &&
|
||
strncmp(InstallerVersion, "10.9", 4) &&
|
||
strncmp(InstallerVersion, "10.10", 5) &&
|
||
strncmp(InstallerVersion, "10.11", 5) &&
|
||
strncmp(InstallerVersion, "10.12", 5) &&
|
||
strncmp(InstallerVersion, "10.13", 5) &&
|
||
strncmp(InstallerVersion, "10.14", 5) &&
|
||
strncmp(InstallerVersion, "10.15", 5) &&
|
||
strncmp(InstallerVersion, "10.16", 5) &&
|
||
strncmp(InstallerVersion, "11.", 3) &&
|
||
strncmp(InstallerVersion, "12.", 3) &&
|
||
strncmp(InstallerVersion, "13.", 3) &&
|
||
strncmp(InstallerVersion, "14.", 3)
|
||
) {
|
||
InstallerVersion = NULL; // flag known version was not found
|
||
}
|
||
if (InstallerVersion != NULL) { // known version was found in image
|
||
macOSVersion = InstallerVersion;
|
||
DBG("Corrected OSVersion: %s\n", macOSVersion.asString().c_str());
|
||
}
|
||
}
|
||
}
|
||
BuildVersion.setEmpty();
|
||
}
|
||
|
||
if (BuildVersion.notEmpty()) {
|
||
DBG(" %s (%s)\n", macOSVersion.asString().c_str(), BuildVersion.c_str());
|
||
} else {
|
||
DBG(" %s\n", macOSVersion.asString().c_str());
|
||
}
|
||
|
||
if ( macOSVersion >= MacOsVersion("10.11"_XS8) ) {
|
||
if (OSFLAG_ISSET(Flags, OSFLAG_NOSIP)) {
|
||
gSettings.RtVariables.CsrActiveConfig = (UINT32)0xBEF;
|
||
gSettings.RtVariables.BooterConfig = 0x28;
|
||
}
|
||
}
|
||
|
||
FilterKextPatches();
|
||
FilterKernelPatches();
|
||
FilterBootPatches();
|
||
if (LoadedImage && !BooterPatch((UINT8*)LoadedImage->ImageBase, LoadedImage->ImageSize)) {
|
||
DBG("Will not patch boot.efi\n");
|
||
}
|
||
gConf.ReloadSmbios(OSName);
|
||
DelegateKernelPatches();
|
||
|
||
// Set boot argument for kernel if no caches, this should force kernel loading
|
||
if ( OSFLAG_ISSET(Flags, OSFLAG_NOCACHES) && !LoadOptions.containsStartWithIC("Kernel=") ) {
|
||
XString8 KernelLocation;
|
||
|
||
if ( macOSVersion.notEmpty() && macOSVersion <= MacOsVersion("10.9"_XS8) ) {
|
||
KernelLocation.S8Printf("\"Kernel=/mach_kernel\"");
|
||
} else {
|
||
// used for 10.10, 10.11, and new version. Jief : also for unknown version.
|
||
KernelLocation.S8Printf("\"Kernel=/System/Library/Kernels/kernel\"");
|
||
}
|
||
LoadOptions.AddID(KernelLocation);
|
||
}
|
||
|
||
// first patchACPI and find PCIROOT and RTC
|
||
// but before ACPI patch we need smbios patch
|
||
CheckEmptyFB();
|
||
|
||
|
||
SmbiosFillPatchingValues(GlobalConfig.SetTable132, GlobalConfig.EnabledCores, g_SmbiosDiscoveredSettings.RamSlotCount, gConf.SlotDeviceArray, gSettings, gCPUStructure, &g_SmbiosInjectedSettings);
|
||
PatchSmbios(g_SmbiosInjectedSettings);
|
||
|
||
#ifdef USE_OC_SECTION_Acpi
|
||
// If we use the ACPI section form config-oc.plist, let's also delegate the acpi patching to OC
|
||
#else
|
||
PatchACPI(Volume, macOSVersion);
|
||
#endif
|
||
|
||
#ifdef JIEF_DEBUG
|
||
//SaveOemTables();
|
||
#endif
|
||
//
|
||
|
||
DbgHeader("RestSetup macOS");
|
||
SetDevices(this);
|
||
SetVariablesForOSX(this);
|
||
// Jief : if we want to use our FixUSBOwnership, we need our OnExitBootServices
|
||
EventsInitialize(this);
|
||
FinalizeSmbios(g_SmbiosInjectedSettings);
|
||
|
||
SetCPUProperties(); //very special procedure
|
||
|
||
if (OSFLAG_ISSET(Flags, OSFLAG_HIBERNATED)) {
|
||
DoHibernateWake = PrepareHibernation(Volume);
|
||
}
|
||
SetupDataForOSX(DoHibernateWake);
|
||
|
||
|
||
if ( gDriversFlags.AptioFixLoaded &&
|
||
!DoHibernateWake &&
|
||
!LoadOptions.containsStartWithIC("slide=") ) {
|
||
// Add slide=0 argument for ML+ if not present
|
||
LoadOptions.AddID("slide=0"_XS8);
|
||
}
|
||
|
||
|
||
/**
|
||
* syscl - append "-xcpm" argument conditionally if set KernelXCPM on Intel Haswell+ low-end CPUs
|
||
*/
|
||
if (KernelAndKextPatches.KPKernelXCPM &&
|
||
gCPUStructure.Vendor == CPU_VENDOR_INTEL && gCPUStructure.Model >= CPU_MODEL_HASWELL &&
|
||
(gCPUStructure.BrandString.contains("Celeron") || gCPUStructure.BrandString.contains("Pentium")) &&
|
||
macOSVersion >= MacOsVersion("10.8.5"_XS8) && macOSVersion < MacOsVersion("10.12"_XS8) &&
|
||
(!LoadOptions.containsIC("-xcpm"))) {
|
||
// add "-xcpm" argv if not present on Haswell+ Celeron/Pentium
|
||
LoadOptions.AddID("-xcpm"_XS8);
|
||
}
|
||
|
||
// add -xcpm on Ivy Bridge if set KernelXCPM and system version is 10.8.5 - 10.11.x
|
||
if (KernelAndKextPatches.KPKernelXCPM &&
|
||
gCPUStructure.Model == CPU_MODEL_IVY_BRIDGE &&
|
||
macOSVersion >= MacOsVersion("10.8.5"_XS8) && macOSVersion < MacOsVersion("10.12"_XS8) &&
|
||
(!LoadOptions.containsIC("-xcpm"))) {
|
||
// add "-xcpm" argv if not present on Ivy Bridge
|
||
LoadOptions.AddID("-xcpm"_XS8);
|
||
}
|
||
|
||
if (AudioIo) {
|
||
AudioIo->StopPlayback(AudioIo);
|
||
// CheckSyncSound(true);
|
||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding = NULL;
|
||
Status = gBS->HandleProtocol(AudioDriverHandle, &gEfiDriverBindingProtocolGuid, (void **)&DriverBinding);
|
||
if (DriverBinding) {
|
||
DriverBinding->Stop(DriverBinding, AudioDriverHandle, 0, NULL);
|
||
}
|
||
}
|
||
|
||
|
||
// blocking boot.efi output if -v is not specified
|
||
// note: this blocks output even if -v is specified in
|
||
// /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
|
||
// which is wrong
|
||
// apianti - only block console output if using graphics
|
||
// but don't block custom boot logo
|
||
if (LoadOptions.containsIC("-v")) {
|
||
Flags = OSFLAG_UNSET(Flags, OSFLAG_USEGRAPHICS);
|
||
}
|
||
}
|
||
else if (OSTYPE_IS_WINDOWS(LoaderType)) {
|
||
|
||
if (AudioIo) {
|
||
AudioIo->StopPlayback(AudioIo);
|
||
}
|
||
|
||
DBG("Closing events for Windows\n");
|
||
gBS->CloseEvent (OnReadyToBootEvent);
|
||
gBS->CloseEvent (ExitBootServiceEvent);
|
||
gBS->CloseEvent (mSimpleFileSystemChangeEvent);
|
||
|
||
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
PatchACPI_OtherOS(L"Windows", false);
|
||
|
||
}
|
||
else if (OSTYPE_IS_LINUX(LoaderType) || (LoaderType == OSTYPE_LINEFI)) {
|
||
|
||
DBG("Closing events for Linux\n");
|
||
gBS->CloseEvent (OnReadyToBootEvent);
|
||
gBS->CloseEvent (ExitBootServiceEvent);
|
||
gBS->CloseEvent (mSimpleFileSystemChangeEvent);
|
||
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
PatchACPI_OtherOS(L"Linux", false);
|
||
}
|
||
|
||
if (gSettings.Boot.LastBootedVolume) {
|
||
if ( APFSTargetUUID.notNull() ) {
|
||
// Jief : we need to LoaderPath. If not, GUI can't know which target was selected.
|
||
SetStartupDiskVolume(Volume, LoaderPath);
|
||
}else{
|
||
// Jief : I'm not sure why NullXStringW was given if LoaderType == OSTYPE_OSX.
|
||
// Let's do it like it was before when not in case of APFSTargetUUID
|
||
SetStartupDiskVolume(Volume, LoaderType == OSTYPE_OSX ? NullXStringW : LoaderPath);
|
||
}
|
||
} else if (gSettings.Boot.DefaultVolume.notEmpty()) {
|
||
// DefaultVolume specified in Config.plist or in Boot Option
|
||
// we'll remove macOS Startup Disk vars which may be present if it is used
|
||
// to reboot into another volume
|
||
RemoveStartupDiskVolume();
|
||
}
|
||
/*
|
||
{
|
||
// UINT32 machineSignature = 0;
|
||
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer = NULL;
|
||
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs = NULL;
|
||
|
||
// DBG("---dump hibernations data---\n");
|
||
FadtPointer = GetFadt();
|
||
if (FadtPointer != NULL) {
|
||
Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE*)(UINTN)(FadtPointer->FirmwareCtrl);
|
||
|
||
DBG(" Firmware wake address=%08lx\n", Facs->FirmwareWakingVector);
|
||
DBG(" Firmware wake 64 addr=%16llx\n", Facs->XFirmwareWakingVector);
|
||
DBG(" Hardware signature =%08lx\n", Facs->HardwareSignature);
|
||
DBG(" GlobalLock =%08lx\n", Facs->GlobalLock);
|
||
DBG(" Flags =%08lx\n", Facs->Flags);
|
||
DBG(" HS at offset 0x%08X\n", OFFSET_OF(EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, HardwareSignature));
|
||
// machineSignature = Facs->HardwareSignature;
|
||
}
|
||
}
|
||
*/
|
||
|
||
BeginExternalScreen(OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)/*, L"Booting OS"*/);
|
||
|
||
if (!OSTYPE_IS_WINDOWS(LoaderType) && !OSTYPE_IS_LINUX(LoaderType)) {
|
||
if (OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)) {
|
||
// save orig OutputString and replace it with
|
||
// null implementation
|
||
ConOutOutputString = gST->ConOut->OutputString;
|
||
gST->ConOut->OutputString = NullConOutOutputString;
|
||
}
|
||
|
||
// Initialize the boot screen
|
||
if (EFI_ERROR(Status = InitBootScreen(this))) {
|
||
if (Status != EFI_ABORTED) DBG("Failed to initialize custom boot screen: %s!\n", efiStrError(Status));
|
||
}
|
||
else if (EFI_ERROR(Status = LockBootScreen())) {
|
||
DBG("Failed to lock custom boot screen: %s!\n", efiStrError(Status));
|
||
}
|
||
} // !OSTYPE_IS_WINDOWS
|
||
|
||
if (OSTYPE_IS_OSX(LoaderType) ||
|
||
OSTYPE_IS_OSX_RECOVERY(LoaderType) ||
|
||
OSTYPE_IS_OSX_INSTALLER(LoaderType)) {
|
||
|
||
if (DoHibernateWake) {
|
||
DBG("Closing events for wake\n");
|
||
gBS->CloseEvent (OnReadyToBootEvent);
|
||
// gBS->CloseEvent (ExitBootServiceEvent); // Jief : we don't need that anymore, if we continue to use OC onExtBootService event
|
||
gBS->CloseEvent (mSimpleFileSystemChangeEvent);
|
||
|
||
// When doing hibernate wake, save to DataHub only up to initial size of log
|
||
SavePreBootLog = false;
|
||
} else {
|
||
// delete boot-switch-vars if exists
|
||
Status = gRT->SetVariable(L"boot-switch-vars", gEfiAppleBootGuid,
|
||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||
0, NULL);
|
||
DeleteNvramVariable(L"IOHibernateRTCVariables", gEfiAppleBootGuid);
|
||
DeleteNvramVariable(L"boot-image", gEfiAppleBootGuid);
|
||
|
||
}
|
||
SetupBooterLog(!DoHibernateWake);
|
||
|
||
XStringW LoadOptionsAsXStringW = SWPrintf("%ls %s ", Basename(LoaderPath.wc_str()), LoadOptions.ConcatAll(" "_XS8).c_str());
|
||
LoadedImage->LoadOptions = (void*)LoadOptionsAsXStringW.wc_str();
|
||
LoadedImage->LoadOptionsSize = (UINT32)LoadOptionsAsXStringW.sizeInBytesIncludingTerminator();
|
||
|
||
DBG("Kernel quirks\n");
|
||
DBG("ACPCL %d AXCL %d AXEM %d AXFB %d CSG %d DIM %d DLJ %d DRC %d DPM %d EBTFF %d EDI %d IPBS %d LKP %d PNKD %d PTKP %d TPD %d XPL %d PCC %d\n",
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleCpuPmCfgLock,
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmCfgLock,
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmExtraMsrs,
|
||
mOpenCoreConfiguration.Kernel.Quirks.AppleXcpmForceBoost,
|
||
mOpenCoreConfiguration.Kernel.Quirks.CustomSmbiosGuid,
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableIoMapper,
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableLinkeditJettison,
|
||
mOpenCoreConfiguration.Kernel.Quirks.DisableRtcChecksum,
|
||
mOpenCoreConfiguration.Kernel.Emulate.DummyPowerManagement,
|
||
mOpenCoreConfiguration.Kernel.Quirks.ExtendBTFeatureFlags,
|
||
mOpenCoreConfiguration.Kernel.Quirks.ExternalDiskIcons,
|
||
mOpenCoreConfiguration.Kernel.Quirks.IncreasePciBarSize,
|
||
mOpenCoreConfiguration.Kernel.Quirks.LapicKernelPanic,
|
||
mOpenCoreConfiguration.Kernel.Quirks.PanicNoKextDump,
|
||
mOpenCoreConfiguration.Kernel.Quirks.PowerTimeoutKernelPanic,
|
||
mOpenCoreConfiguration.Kernel.Quirks.ThirdPartyDrives,
|
||
mOpenCoreConfiguration.Kernel.Quirks.XhciPortLimit,
|
||
mOpenCoreConfiguration.Kernel.Quirks.ProvideCurrentCpuInfo);
|
||
|
||
DBG("Closing log\n");
|
||
if (SavePreBootLog) {
|
||
Status = SaveBooterLog(&self.getCloverDir(), PREBOOT_LOG);
|
||
}
|
||
|
||
displayFreeMemory("Just before lauching image"_XS8);
|
||
|
||
Status = gBS->StartImage (ImageHandle, 0, NULL); // point to OcStartImage from OC
|
||
|
||
if ( EFI_ERROR(Status) ) {
|
||
// Ideally, we would return to the menu, displaying an error message
|
||
// Truth is that we get a black screen before seeing the menu again.
|
||
// If I remember well, we get a freeze in BdsLibConnectAllEfi()
|
||
// I'm guessing there is a lot of patching done for booting.
|
||
// To be able to go back to the menu and boot another thing,
|
||
// we must undo all the patching...
|
||
// Here is a quick, not as bad as a black screen solution : a text message and a reboot !
|
||
DBG("StartImage failed : %s\n", efiStrError(Status));
|
||
SaveBooterLog(&self.getCloverDir(), PREBOOT_LOG);
|
||
egSetGraphicsModeEnabled(false);
|
||
printf("StartImage failed : %s\n", efiStrError(Status));
|
||
PauseForKey("Reboot needed."_XS8);
|
||
// Attempt warm reboot
|
||
gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||
// Warm reboot may not be supported attempt cold reboot
|
||
gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||
// Terminate the screen and just exit
|
||
|
||
return;
|
||
}
|
||
|
||
}else{
|
||
|
||
StartEFILoadedImage(ImageHandle, LoadOptions, NullXStringW, LoaderPath.basename(), NULL);
|
||
}
|
||
// Unlock boot screen
|
||
if (EFI_ERROR(Status = UnlockBootScreen())) {
|
||
DBG("Failed to unlock custom boot screen: %s!\n", efiStrError(Status));
|
||
}
|
||
if (OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)) {
|
||
// return back orig OutputString
|
||
gST->ConOut->OutputString = ConOutOutputString;
|
||
}
|
||
|
||
|
||
FinishExternalScreen();
|
||
|
||
}
|
||
|
||
|
||
void LEGACY_ENTRY::StartLegacy()
|
||
{
|
||
EFI_STATUS Status = EFI_UNSUPPORTED;
|
||
|
||
// Unload EmuVariable before booting legacy.
|
||
// This is not needed in most cases, but it seems to interfere with legacy OS
|
||
// booted on some UEFI bioses, such as Phoenix UEFI 2.0
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
if (gSettings.Boot.LastBootedVolume) {
|
||
SetStartupDiskVolume(Volume, NullXStringW);
|
||
} else if (gSettings.Boot.DefaultVolume.notEmpty()) {
|
||
// DefaultVolume specified in Config.plist:
|
||
// we'll remove macOS Startup Disk vars which may be present if it is used
|
||
// to reboot into another volume
|
||
RemoveStartupDiskVolume();
|
||
}
|
||
|
||
|
||
egClearScreen(&MenuBackgroundPixel);
|
||
BeginExternalScreen(true/*, L"Booting Legacy OS"*/);
|
||
XImage BootLogoX;
|
||
BootLogoX.LoadXImage(&ThemeX->getThemeDir(), Volume->LegacyOS->IconName);
|
||
BootLogoX.Draw((UGAWidth - BootLogoX.GetWidth()) >> 1,
|
||
(UGAHeight - BootLogoX.GetHeight()) >> 1);
|
||
|
||
//try my LegacyBoot
|
||
switch (Volume->BootType) {
|
||
case BOOTING_BY_CD:
|
||
Status = bootElTorito(Volume);
|
||
break;
|
||
case BOOTING_BY_MBR:
|
||
Status = bootMBR(Volume);
|
||
break;
|
||
case BOOTING_BY_PBR:
|
||
if (gSettings.Boot.LegacyBoot == "LegacyBiosDefault"_XS8) {
|
||
Status = bootLegacyBiosDefault(gSettings.Boot.LegacyBiosDefaultEntry);
|
||
} else if (gSettings.Boot.LegacyBoot == "PBRtest"_XS8) {
|
||
Status = bootPBRtest(Volume);
|
||
} else if (gSettings.Boot.LegacyBoot == "PBRsata"_XS8) {
|
||
Status = bootPBR(Volume, true);
|
||
} else {
|
||
// default
|
||
Status = bootPBR(Volume, false);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
CheckError(Status, L"while LegacyBoot");
|
||
|
||
FinishExternalScreen();
|
||
}
|
||
|
||
//
|
||
// pre-boot tool functions
|
||
//
|
||
|
||
void REFIT_MENU_ENTRY_LOADER_TOOL::StartTool()
|
||
{
|
||
DBG("Start Tool: %ls\n", LoaderPath.wc_str());
|
||
egClearScreen(&MenuBackgroundPixel);
|
||
// assumes "Start <title>" as assigned below
|
||
BeginExternalScreen(OSFLAG_ISSET(Flags, OSFLAG_USEGRAPHICS)/*, &Entry->Title[6]*/); // Shouldn't we check that length of Title is at least 6 ?
|
||
StartEFIImage(DevicePath, LoadOptions, NullXStringW, LoaderPath.basename(), NULL, NULL);
|
||
FinishExternalScreen();
|
||
}
|
||
|
||
//
|
||
// pre-boot driver functions
|
||
//
|
||
|
||
static void ScanDriverDir(IN CONST CHAR16 *Path, OUT EFI_HANDLE **DriversToConnect, OUT UINTN *DriversToConnectNum)
|
||
{
|
||
EFI_STATUS Status;
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry;
|
||
EFI_HANDLE DriverHandle;
|
||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||
UINTN DriversArrSize;
|
||
UINTN DriversArrNum;
|
||
EFI_HANDLE *DriversArr;
|
||
XBool Skip;
|
||
UINT8 AptioBlessed;
|
||
STATIC CHAR16 CONST * CONST AptioNames[] = {
|
||
L"AptioMemoryFix",
|
||
L"AptioFix3Drv",
|
||
L"AptioFix2Drv",
|
||
L"AptioFixDrv",
|
||
L"LowMemFix"
|
||
};
|
||
STATIC UINT8 CONST AptioIndices[] = {
|
||
OFFSET_OF(DRIVERS_FLAGS, AptioMemFixLoaded),
|
||
OFFSET_OF(DRIVERS_FLAGS, AptioFix3Loaded),
|
||
OFFSET_OF(DRIVERS_FLAGS, AptioFix2Loaded),
|
||
OFFSET_OF(DRIVERS_FLAGS, AptioFixLoaded),
|
||
OFFSET_OF(DRIVERS_FLAGS, MemFixLoaded)
|
||
};
|
||
|
||
DriversArrSize = 0;
|
||
DriversArrNum = 0;
|
||
DriversArr = NULL;
|
||
// OpenRuntimeEfiName.setEmpty();
|
||
|
||
//only one driver with highest priority will obtain status "Loaded"
|
||
DirIterOpen(&self.getCloverDir(), Path, &DirIter);
|
||
#define BOOLEAN_AT_INDEX(k) (*(XBool*)((UINTN)&gDriversFlags + AptioIndices[(k)]))
|
||
for (size_t i = 0; i != ARRAY_SIZE(AptioIndices); ++i)
|
||
BOOLEAN_AT_INDEX(i) = false;
|
||
AptioBlessed = (UINT8) ARRAY_SIZE(AptioNames);
|
||
while (DirIterNext(&DirIter, 2, L"*.efi", &DirEntry)) {
|
||
size_t i;
|
||
for (i = 0; i != ARRAY_SIZE(AptioNames); ++i)
|
||
if (StrStr(DirEntry->FileName, AptioNames[i]) != NULL)
|
||
break;
|
||
if (((UINT8) i) >= AptioBlessed)
|
||
continue;
|
||
AptioBlessed = (UINT8) i;
|
||
if (!i)
|
||
break;
|
||
}
|
||
DirIterClose(&DirIter);
|
||
|
||
// look through contents of the directory
|
||
DirIterOpen(&self.getCloverDir(), Path, &DirIter);
|
||
while (DirIterNext(&DirIter, 2, L"*.efi", &DirEntry)) {
|
||
Skip = (DirEntry->FileName[0] == L'.');
|
||
for (size_t i=0; i<gSettings.DisabledDriverArray.size(); i++) {
|
||
if (StrStr(DirEntry->FileName, gSettings.DisabledDriverArray[i].wc_str()) != NULL) {
|
||
Skip = true; // skip this
|
||
break;
|
||
}
|
||
}
|
||
if (Skip) {
|
||
continue;
|
||
}
|
||
if ( LStringW(DirEntry->FileName).startWith("._") ) {
|
||
continue;
|
||
}
|
||
if ( LStringW(DirEntry->FileName).containsIC("OcQuirks") ) {
|
||
continue;
|
||
}
|
||
if ( LStringW(DirEntry->FileName).containsIC("AptioMemoryFix") ) {
|
||
continue;
|
||
}
|
||
|
||
if ( LStringW(DirEntry->FileName).containsIC("OpenRuntime") ) {
|
||
if (!OpenRuntimeEfiName.isEmpty()) {
|
||
DBG(" - OpenRuntime already detected\n");
|
||
continue;
|
||
}
|
||
if ( LStringW(DirEntry->FileName).isEqualIC("OpenRuntime-v12.efi") && LString8(OPEN_CORE_VERSION).isEqual("0.7.5") ) {
|
||
OpenRuntimeEfiName.takeValueFrom(DirEntry->FileName);
|
||
DBG(" - OpenRuntime-v12 for 075 taken from %ls\n", getDriversPath().wc_str());
|
||
}else
|
||
if ( LStringW(DirEntry->FileName).isEqualIC("OpenRuntime-v12.efi") && LString8(OPEN_CORE_VERSION).isEqual("0.7.3") ) {
|
||
OpenRuntimeEfiName.takeValueFrom(DirEntry->FileName);
|
||
DBG(" - OpenRuntime-v12 for 073 taken from %ls\n", getDriversPath().wc_str());
|
||
}else
|
||
if ( LStringW(DirEntry->FileName).isEqualIC("OpenRuntime-v11.efi") && LString8(OPEN_CORE_VERSION).isEqual("0.6.5") ) {
|
||
OpenRuntimeEfiName.takeValueFrom(DirEntry->FileName);
|
||
DBG(" - OpenRuntime-v11 for 065 taken from %ls\n", getDriversPath().wc_str());
|
||
}else
|
||
if ( LStringW(DirEntry->FileName).isEqualIC("OpenRuntime-v11.efi") && LString8(OPEN_CORE_VERSION).isEqual("0.6.1") ) {
|
||
OpenRuntimeEfiName.takeValueFrom(DirEntry->FileName);
|
||
DBG(" - OpenRuntime-v11 for 061 taken from %ls\n", getDriversPath().wc_str());
|
||
}else
|
||
if ( OpenRuntimeEfiName.isEmpty() ) {
|
||
OpenRuntimeEfiName.takeValueFrom(DirEntry->FileName);
|
||
}
|
||
continue;
|
||
}
|
||
{
|
||
size_t i;
|
||
// either AptioMem, AptioFix* or LowMemFix exclusively
|
||
for (i = 0; i != ARRAY_SIZE(AptioNames); ++i)
|
||
if (StrStr(DirEntry->FileName, AptioNames[i]) != NULL)
|
||
break;
|
||
if (i != ARRAY_SIZE(AptioNames)) {
|
||
if (((UINT8) i) != AptioBlessed)
|
||
continue;
|
||
if (AptioBlessed < (UINT8) ARRAY_SIZE(AptioIndices))
|
||
BOOLEAN_AT_INDEX(AptioBlessed) = true;
|
||
AptioBlessed = (UINT8) ARRAY_SIZE(AptioNames);
|
||
}
|
||
}
|
||
#undef BOOLEAN_AT_INDEX
|
||
|
||
XStringW FileName = SWPrintf("%ls\\%ls\\%ls", self.getCloverDirFullPath().wc_str(), Path, DirEntry->FileName);
|
||
Status = StartEFIImage(FileDevicePath(self.getSelfLoadedImage().DeviceHandle, FileName), NullXString8Array, LStringW(DirEntry->FileName), XStringW().takeValueFrom(DirEntry->FileName), NULL, &DriverHandle);
|
||
if (EFI_ERROR(Status)) {
|
||
continue;
|
||
}
|
||
if ( FileName.containsIC("AudioDxe") ) {
|
||
AudioDriverHandle = DriverHandle;
|
||
}
|
||
if ( FileName.containsIC("EmuVariable") ) {
|
||
gDriversFlags.EmuVariableLoaded = true;
|
||
} else if ( FileName.containsIC("Video") ) {
|
||
gDriversFlags.VideoLoaded = true;
|
||
} else if ( FileName.containsIC("Partition") ) {
|
||
gDriversFlags.PartitionLoaded = true;
|
||
} else if ( FileName.containsIC("HFS") ) {
|
||
gDriversFlags.HFSLoaded = true;
|
||
} else if ( FileName.containsIC("apfs") ) {
|
||
gDriversFlags.APFSLoaded = true;
|
||
}
|
||
if (DriverHandle != NULL && DriversToConnectNum != NULL && DriversToConnect != NULL) {
|
||
// driver loaded - check for EFI_DRIVER_BINDING_PROTOCOL
|
||
Status = gBS->HandleProtocol(DriverHandle, &gEfiDriverBindingProtocolGuid, (void **) &DriverBinding);
|
||
if (!EFI_ERROR(Status) && DriverBinding != NULL) {
|
||
DBG(" - driver needs connecting\n");
|
||
// standard UEFI driver - we would reconnect after loading - add to array
|
||
if (DriversArrSize == 0) {
|
||
// new array
|
||
DriversArrSize = 16;
|
||
DriversArr = (__typeof__(DriversArr))AllocateZeroPool(sizeof(EFI_HANDLE) * DriversArrSize);
|
||
} else if (DriversArrNum + 1 == DriversArrSize) {
|
||
// extend array
|
||
DriversArr = (__typeof__(DriversArr))ReallocatePool(DriversArrSize, DriversArrSize + 16, DriversArr);
|
||
DriversArrSize += 16;
|
||
}
|
||
DriversArr[DriversArrNum] = DriverHandle;
|
||
// DBG(" driver %ls included with Binding=%X\n", FileName, DriverBinding);
|
||
DriversArrNum++;
|
||
// we'll make array terminated
|
||
DriversArr[DriversArrNum] = NULL;
|
||
}
|
||
}
|
||
}
|
||
Status = DirIterClose(&DirIter);
|
||
if (Status != EFI_NOT_FOUND) {
|
||
CheckError(Status, SWPrintf( "while scanning the %ls directory", Path).wc_str());
|
||
}
|
||
|
||
if (DriversToConnectNum != NULL && DriversToConnect != NULL) {
|
||
*DriversToConnectNum = DriversArrNum;
|
||
*DriversToConnect = DriversArr;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 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.
|
||
*/
|
||
void DisconnectInvalidDiskIoChildDrivers(void)
|
||
{
|
||
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;
|
||
XBool Found;
|
||
|
||
DBG("Searching for invalid DiskIo BY_DRIVER connects:");
|
||
|
||
//
|
||
// Get all DiskIo handles
|
||
//
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &HandleCount, &Handles);
|
||
if (EFI_ERROR(Status) || HandleCount == 0) {
|
||
DBG(" no DiskIo handles\n");
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Check every DiskIo handle
|
||
//
|
||
Found = false;
|
||
for (Index = 0; Index < HandleCount; Index++) {
|
||
//DBG("\n");
|
||
//DBG(" - Handle %p:", Handles[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 = gBS->HandleProtocol (
|
||
Handles[Index],
|
||
&gEfiBlockIoProtocolGuid,
|
||
(void **) &BlockIo
|
||
);
|
||
if (EFI_ERROR(Status)) {
|
||
//DBG(" BlockIo: %s - skipping\n", efiStrError(Status));
|
||
continue;
|
||
}
|
||
if (BlockIo->Media == NULL) {
|
||
//DBG(" BlockIo: no media - skipping\n");
|
||
continue;
|
||
|
||
}
|
||
if (!BlockIo->Media->LogicalPartition) {
|
||
//DBG(" BlockIo: whole disk - skipping\n");
|
||
continue;
|
||
|
||
}
|
||
//DBG(" BlockIo: partition");
|
||
|
||
//
|
||
// If SimpleFileSystem is already produced - skip it, this is ok
|
||
//
|
||
Status = gBS->HandleProtocol (
|
||
Handles[Index],
|
||
&gEfiSimpleFileSystemProtocolGuid,
|
||
(void **) &Fs
|
||
);
|
||
if (Status == EFI_SUCCESS) {
|
||
//DBG(" FS: ok - skipping\n");
|
||
continue;
|
||
}
|
||
//DBG(" FS: no");
|
||
|
||
//
|
||
// If no SimpleFileSystem on this handle but DiskIo is opened BY_DRIVER
|
||
// then disconnect this connection
|
||
//
|
||
Status = gBS->OpenProtocolInformation (
|
||
Handles[Index],
|
||
&gEfiDiskIoProtocolGuid,
|
||
&OpenInfo,
|
||
&OpenInfoCount
|
||
);
|
||
if (EFI_ERROR(Status)) {
|
||
//DBG(" OpenInfo: no - skipping\n");
|
||
continue;
|
||
}
|
||
//DBG(" OpenInfo: %d", OpenInfoCount);
|
||
for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
|
||
if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
|
||
if (!Found) {
|
||
DBG("\n");
|
||
}
|
||
Found = true;
|
||
Status = gBS->DisconnectController (Handles[Index], OpenInfo[OpenInfoIndex].AgentHandle, NULL);
|
||
//DBG(" BY_DRIVER Agent: %p, Disconnect: %s", OpenInfo[OpenInfoIndex].AgentHandle, efiStrError(Status));
|
||
DBG(" - Handle %llx with DiskIo, is Partition, no Fs, BY_DRIVER Agent: %llx, Disconnect: %s\n", (uintptr_t)Handles[Index], (uintptr_t)(OpenInfo[OpenInfoIndex].AgentHandle), efiStrError(Status));
|
||
}
|
||
}
|
||
FreePool(OpenInfo);
|
||
}
|
||
FreePool(Handles);
|
||
|
||
if (!Found) {
|
||
DBG(" not found, all ok\n");
|
||
}
|
||
}
|
||
|
||
void DisconnectSomeDevices(void)
|
||
{
|
||
EFI_STATUS Status;
|
||
UINTN HandleCount;
|
||
UINTN Index, Index2;
|
||
EFI_HANDLE *Handles ;
|
||
EFI_HANDLE *ControllerHandles;
|
||
UINTN ControllerHandleCount;
|
||
EFI_BLOCK_IO_PROTOCOL *BlockIo = NULL;
|
||
// EFI_DISK_IO_PROTOCOL *DiskIo = NULL;
|
||
EFI_PCI_IO_PROTOCOL *PciIo = NULL;
|
||
// EFI_FILE_PROTOCOL *RootFP = NULL;
|
||
// EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *VolumeFS = NULL;
|
||
PCI_TYPE00 Pci;
|
||
CHAR16 *DriverName = NULL;
|
||
EFI_COMPONENT_NAME_PROTOCOL *CompName = NULL;
|
||
|
||
if (gDriversFlags.PartitionLoaded) {
|
||
DBG("Partition driver loaded: ");
|
||
// get all BlockIo handles
|
||
HandleCount = 0;
|
||
Handles = NULL;
|
||
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &Handles);
|
||
if (Status == EFI_SUCCESS) {
|
||
for (Index = 0; Index < HandleCount; Index++) {
|
||
Status = gBS->HandleProtocol(Handles[Index], &gEfiBlockIoProtocolGuid, (void **) &BlockIo);
|
||
if (EFI_ERROR(Status)) {
|
||
continue;
|
||
}
|
||
if (BlockIo->Media->BlockSize == 2048) {
|
||
// disconnect CD controller
|
||
Status = gBS->DisconnectController(Handles[Index], NULL, NULL);
|
||
DBG("CD disconnect %s", efiStrError(Status));
|
||
}
|
||
}
|
||
/* for (Index = 0; Index < HandleCount; Index++) {
|
||
Status = gBS->DisconnectController(Handles[Index], NULL, NULL);
|
||
} */
|
||
FreePool(Handles);
|
||
}
|
||
DBG("\n");
|
||
}
|
||
|
||
if ((gDriversFlags.HFSLoaded) || (gDriversFlags.APFSLoaded)) {
|
||
if (gDriversFlags.HFSLoaded) {
|
||
DBG("HFS+ driver loaded\n");
|
||
}
|
||
if (gDriversFlags.APFSLoaded) {
|
||
DBG("APFS driver loaded\n");
|
||
}
|
||
|
||
// get all FileSystem handles
|
||
ControllerHandleCount = 0;
|
||
ControllerHandles = NULL;
|
||
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &ControllerHandleCount, &ControllerHandles);
|
||
/* if (!EFI_ERROR(Status)) {
|
||
for (Index2 = 0; Index2 < ControllerHandleCount; Index2++) {
|
||
Status = gBS->DisconnectController(ControllerHandles[Index2],
|
||
NULL, NULL);
|
||
DBG("Driver [%d] disconnect %s\n", Index2, efiStrError(Status));
|
||
}
|
||
} */
|
||
|
||
HandleCount = 0;
|
||
Handles = NULL;
|
||
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, NULL, &HandleCount, &Handles);
|
||
if (!EFI_ERROR(Status)) {
|
||
for (Index = 0; Index < HandleCount; Index++) {
|
||
Status = gBS->OpenProtocol(
|
||
Handles[Index],
|
||
gEfiComponentNameProtocolGuid,
|
||
(void**)&CompName,
|
||
gImageHandle,
|
||
NULL,
|
||
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||
|
||
if (EFI_ERROR(Status)) {
|
||
// DBG("CompName %s\n", efiStrError(Status));
|
||
continue;
|
||
}
|
||
// 2021-05, Jief : PG7 had a crash. In some cases, CompName->GetDriverName == NULL.
|
||
if ( CompName->GetDriverName == NULL ) {
|
||
DBG("DisconnectSomeDevices: GetDriverName CompName=%lld, CompName->GetDriverName=NULL\n", uintptr_t(CompName));
|
||
continue;
|
||
}
|
||
Status = CompName->GetDriverName(CompName, "eng", &DriverName);
|
||
if (EFI_ERROR(Status)) {
|
||
continue;
|
||
}
|
||
if ((StriStr(DriverName, L"HFS")) || (StriStr(DriverName, L"apfs"))) {
|
||
for (Index2 = 0; Index2 < ControllerHandleCount; Index2++) {
|
||
Status = gBS->DisconnectController(ControllerHandles[Index2],
|
||
Handles[Index], NULL);
|
||
//DBG("Disconnect [%ls] from %llX: %s\n", DriverName, uintptr_t(ControllerHandles[Index2]), efiStrError(Status));
|
||
}
|
||
}
|
||
}
|
||
FreePool(Handles);
|
||
}
|
||
// DBG("\n");
|
||
FreePool(ControllerHandles);
|
||
}
|
||
|
||
|
||
if (gDriversFlags.VideoLoaded) {
|
||
DBG("Video driver loaded: ");
|
||
// get all PciIo handles
|
||
HandleCount = 0;
|
||
Handles = NULL;
|
||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiPciIoProtocolGuid, NULL, &HandleCount, &Handles);
|
||
if (Status == EFI_SUCCESS) {
|
||
for (Index = 0; Index < HandleCount; Index++) {
|
||
Status = gBS->HandleProtocol(Handles[Index], &gEfiPciIoProtocolGuid, (void **) &PciIo);
|
||
if (EFI_ERROR(Status)) {
|
||
continue;
|
||
}
|
||
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);
|
||
if (!EFI_ERROR(Status)) {
|
||
if(IS_PCI_VGA(&Pci) == true) {
|
||
// disconnect VGA
|
||
Status = gBS->DisconnectController(Handles[Index], NULL, NULL);
|
||
DBG("disconnect %s", efiStrError(Status));
|
||
}
|
||
}
|
||
}
|
||
FreePool(Handles);
|
||
}
|
||
DBG("\n");
|
||
}
|
||
|
||
if (!gFirmwareClover) {
|
||
DisconnectInvalidDiskIoChildDrivers();
|
||
}
|
||
}
|
||
|
||
|
||
void PatchVideoBios(UINT8 *Edid)
|
||
{
|
||
|
||
if ( gSettings.Graphics.PatchVBiosBytes.notEmpty() ) {
|
||
VideoBiosPatchBytes(gSettings.Graphics.PatchVBiosBytes.getVBIOS_PATCH_BYTES(), gSettings.Graphics.PatchVBiosBytes.getVBIOS_PATCH_BYTES_count());
|
||
}
|
||
|
||
if (gSettings.Graphics.PatchVBios) {
|
||
VideoBiosPatchNativeFromEdid(Edid);
|
||
}
|
||
}
|
||
|
||
|
||
static void LoadDrivers(void)
|
||
{
|
||
EFI_STATUS Status;
|
||
EFI_HANDLE *DriversToConnect = NULL;
|
||
UINTN DriversToConnectNum = 0;
|
||
UINT8 *Edid;
|
||
UINTN VarSize = 0;
|
||
XBool VBiosPatchNeeded;
|
||
|
||
DbgHeader("LoadDrivers");
|
||
|
||
// load drivers from /efi/drivers
|
||
#if defined(MDE_CPU_X64)
|
||
if (gFirmwareClover) {
|
||
if (FileExists(&self.getCloverDir(), L"drivers\\BIOS")) {
|
||
ScanDriverDir(L"drivers\\BIOS", &DriversToConnect, &DriversToConnectNum);
|
||
} else {
|
||
ScanDriverDir(L"drivers64", &DriversToConnect, &DriversToConnectNum);
|
||
}
|
||
} else {
|
||
OpenRuntimeEfiName.setEmpty();
|
||
if (FileExists(&self.getCloverDir(), L"drivers\\5142")) {
|
||
ScanDriverDir(L"drivers\\5142", &DriversToConnect, &DriversToConnectNum);
|
||
}
|
||
if (FileExists(&self.getCloverDir(), L"drivers\\UEFI")) {
|
||
ScanDriverDir(L"drivers\\UEFI", &DriversToConnect, &DriversToConnectNum);
|
||
} else {
|
||
ScanDriverDir(L"drivers64UEFI", &DriversToConnect, &DriversToConnectNum);
|
||
}
|
||
}
|
||
#else
|
||
ScanDriverDir(L"drivers32", &DriversToConnect, &DriversToConnectNum);
|
||
#endif
|
||
|
||
VBiosPatchNeeded = gSettings.Graphics.PatchVBios || gSettings.Graphics.PatchVBiosBytes.getVBIOS_PATCH_BYTES_count() > 0;
|
||
if (VBiosPatchNeeded) {
|
||
// check if it is already done in CloverEFI BiosVideo
|
||
Status = gRT->GetVariable (
|
||
L"CloverVBiosPatchDone",
|
||
gEfiGlobalVariableGuid,
|
||
NULL,
|
||
&VarSize,
|
||
NULL
|
||
);
|
||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||
// var exists - it's done - let's not do it again
|
||
VBiosPatchNeeded = false;
|
||
}
|
||
}
|
||
|
||
if ( (gSettings.Graphics.EDID.CustomEDID.notEmpty() && gFirmwareClover) || (VBiosPatchNeeded && !gDriversFlags.VideoLoaded)) {
|
||
// we have video bios patch - force video driver reconnect
|
||
DBG("Video bios patch requested or CustomEDID - forcing video reconnect\n");
|
||
gDriversFlags.VideoLoaded = true;
|
||
DriversToConnectNum++;
|
||
}
|
||
|
||
UninitRefitLib();
|
||
if (DriversToConnectNum > 0) {
|
||
DBG("%llu drivers needs connecting ...\n", DriversToConnectNum);
|
||
// note: our platform driver protocol
|
||
// will use DriversToConnect - do not release it
|
||
RegisterDriversToHighestPriority(DriversToConnect);
|
||
if (VBiosPatchNeeded) {
|
||
if (gSettings.Graphics.EDID.CustomEDID.notEmpty()) {
|
||
Edid = gSettings.Graphics.EDID.CustomEDID.data();
|
||
} else {
|
||
Edid = getCurrentEdid();
|
||
}
|
||
DisconnectSomeDevices();
|
||
PatchVideoBios(Edid);
|
||
if (gSettings.Graphics.EDID.CustomEDID.isEmpty()) {
|
||
FreePool(Edid);
|
||
}
|
||
} else {
|
||
DisconnectSomeDevices();
|
||
}
|
||
BdsLibConnectAllDriversToAllControllers();
|
||
|
||
// Boot speedup: remove temporary "BiosVideoBlockSwitchMode" RT var
|
||
// to unlock mode switching in CsmVideo
|
||
gRT->SetVariable(L"BiosVideoBlockSwitchMode", gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, 0, NULL);
|
||
}else{
|
||
BdsLibConnectAllEfi(); // jief : without any driver loaded, i couldn't see my CD, unless I call BdsLibConnectAllEfi
|
||
}
|
||
ReinitRefitLib();
|
||
}
|
||
|
||
|
||
INTN FindDefaultEntry(void)
|
||
{
|
||
INTN Index = -1;
|
||
REFIT_VOLUME *Volume;
|
||
XBool SearchForLoader;
|
||
|
||
// DBG("FindDefaultEntry ...\n");
|
||
//DbgHeader("FindDefaultEntry");
|
||
|
||
//
|
||
// try to detect volume set by Startup Disk or previous Clover selection
|
||
// with broken nvram this requires emulation to be installed.
|
||
// enable emulation to determin efi-boot-device-data
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->InstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
Index = FindStartupDiskVolume(&MainMenu);
|
||
|
||
if (Index >= 0) {
|
||
DBG("Boot redirected to Entry %lld. '%ls'\n", Index, MainMenu.Entries[Index].Title.s());
|
||
// we got boot-device-data, no need to keep emulating anymore
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
return Index;
|
||
}
|
||
|
||
//
|
||
// if not found, then try DefaultVolume from config.plist
|
||
// if not null or empty, search volume that matches gSettings.Boot.DefaultVolume
|
||
//
|
||
if (gSettings.Boot.DefaultVolume.notEmpty()) {
|
||
|
||
// if not null or empty, also search for loader that matches gSettings.Boot.DefaultLoader
|
||
SearchForLoader = gSettings.Boot.DefaultLoader.notEmpty();
|
||
/*
|
||
if (SearchForLoader) {
|
||
DBG("Searching for DefaultVolume '%ls', DefaultLoader '%ls' ...\n", gSettings.Boot.DefaultVolume, gSettings.Boot.DefaultLoader);
|
||
} else {
|
||
DBG("Searching for DefaultVolume '%ls' ...\n", gSettings.Boot.DefaultVolume);
|
||
}
|
||
*/
|
||
for (Index = 0; Index < (INTN)MainMenu.Entries.size() && MainMenu.Entries[Index].getLOADER_ENTRY() && MainMenu.Entries[Index].getLOADER_ENTRY()->Row == 0 ; Index++) {
|
||
|
||
LOADER_ENTRY& Entry = *MainMenu.Entries[Index].getLOADER_ENTRY();
|
||
if (!Entry.Volume) {
|
||
continue;
|
||
}
|
||
|
||
Volume = Entry.Volume;
|
||
if ( (Volume->VolName.isEmpty() || Volume->VolName != gSettings.Boot.DefaultVolume) &&
|
||
!Volume->DevicePathString.contains(gSettings.Boot.DefaultVolume) ) {
|
||
continue;
|
||
}
|
||
|
||
// we alreday know that Entry.isLoader
|
||
if (SearchForLoader && (/*Entry.Tag != TAG_LOADER ||*/ !Entry.LoaderPath.containsIC(gSettings.Boot.DefaultLoader))) {
|
||
continue;
|
||
}
|
||
|
||
DBG(" - found entry %lld. '%ls', Volume '%ls', DevicePath '%ls'\n", Index, Entry.Title.s(), Volume->VolName.wc_str(), Entry.DevicePathString.wc_str());
|
||
// if first method failed and second succeeded - uninstall emulation
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
return Index;
|
||
}
|
||
|
||
}
|
||
|
||
DBG("Default boot entry not found\n");
|
||
// if both methods to determine default boot entry have failed - uninstall emulation before GUI
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void SetVariablesFromNvram()
|
||
{
|
||
CHAR8 *tmpString;
|
||
UINTN Size = 0;
|
||
UINTN index = 0, index2, i;
|
||
CHAR8 *arg = NULL;
|
||
|
||
// DbgHeader("SetVariablesFromNvram");
|
||
|
||
tmpString = (__typeof__(tmpString))GetNvramVariable(L"boot-args", gEfiAppleBootGuid, NULL, &Size);
|
||
if (tmpString && (Size <= 0x1000) && (Size > 0)) {
|
||
DBG("found boot-args in NVRAM:%s, size=%llu\n", tmpString, Size);
|
||
// use and forget old one
|
||
// DeleteNvramVariable(L"boot-args", &gEfiAppleBootGuid);
|
||
Size = AsciiStrLen(tmpString); // some EFI implementations include '\0' in Size, and others don't, so update Size to string length
|
||
arg = (__typeof__(arg))AllocatePool(Size+1);
|
||
|
||
/* if (AsciiStrStr(tmpString, "nvda_drv=1")) { //found substring
|
||
gSettings.NvidiaWeb = true;
|
||
} */
|
||
//first we will find new args that is not present in main args
|
||
index = 0;
|
||
while ((index < Size) && (tmpString[index] != 0x0)) {
|
||
ZeroMem(arg, Size+1);
|
||
index2 = 0;
|
||
if (tmpString[index] != '\"') {
|
||
// DBG("search space index=%d\n", index);
|
||
while ((index < Size) && (tmpString[index] != 0x20) && (tmpString[index] != 0x0)) {
|
||
arg[index2++] = tmpString[index++];
|
||
}
|
||
DBG("...found arg:%s\n", arg);
|
||
} else {
|
||
index++;
|
||
// DBG("search quote index=%d\n", index);
|
||
while ((index < Size) && (tmpString[index] != '\"') && (tmpString[index] != 0x0)) {
|
||
arg[index2++] = tmpString[index++];
|
||
}
|
||
if (tmpString[index] == '\"') {
|
||
index++;
|
||
}
|
||
DBG("...found quoted arg:\n"/*, arg*/);
|
||
}
|
||
while (tmpString[index] == 0x20) {
|
||
index++;
|
||
}
|
||
// For the moment only arg -s must be ignored
|
||
if (AsciiStrCmp(arg, "-s") == 0) {
|
||
DBG("...ignoring arg:%s\n", arg);
|
||
continue;
|
||
}
|
||
if (!gSettings.Boot.BootArgs.contains(arg)) {
|
||
//this arg is not present will add
|
||
DBG("...adding arg:%s\n", arg);
|
||
gSettings.Boot.BootArgs.trim();
|
||
gSettings.Boot.BootArgs += ' ';
|
||
for (i = 0; i < index2; i++) {
|
||
gSettings.Boot.BootArgs += arg[i];
|
||
}
|
||
gSettings.Boot.BootArgs += ' ';
|
||
}
|
||
}
|
||
FreePool(arg);
|
||
}
|
||
if (tmpString) {
|
||
FreePool(tmpString);
|
||
}
|
||
|
||
tmpString = (__typeof__(tmpString))GetNvramVariable(L"nvda_drv", gEfiAppleBootGuid, NULL, NULL);
|
||
if (tmpString && AsciiStrCmp(tmpString, "1") == 0) {
|
||
gSettings.SystemParameters.NvidiaWeb = true;
|
||
}
|
||
if (tmpString) {
|
||
FreePool(tmpString);
|
||
}
|
||
|
||
}
|
||
|
||
void
|
||
GetListOfConfigs()
|
||
{
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry;
|
||
|
||
ConfigsList.setEmpty();
|
||
OldChosenConfig = 0;
|
||
|
||
DirIterOpen(&selfOem.getConfigDir(), NULL, &DirIter);
|
||
DbgHeader("Found config plists");
|
||
while (DirIterNext(&DirIter, 2, L"config*.plist", &DirEntry)) {
|
||
if (DirEntry->FileName[0] == L'.') {
|
||
continue;
|
||
}
|
||
if (StriCmp(DirEntry->FileName, L"config.plist") == 0) {
|
||
OldChosenConfig = ConfigsList.size(); // DirEntry->FileName is not yet inserted into ConfigsList. So its index will be ConfigsList.size()
|
||
}
|
||
size_t NameLen = wcslen(DirEntry->FileName) - 6; //without ".plist"
|
||
if ( NameLen <= MAX_INTN ) {
|
||
ConfigsList.AddReference(SWPrintf("%.*ls", (int)NameLen, DirEntry->FileName).forgetDataWithoutFreeing(), true); // this avoid to reallocate and copy memory
|
||
DBG("- %ls\n", DirEntry->FileName);
|
||
}else{
|
||
DBG("- bug!, NameLen > MAX_INTN");
|
||
}
|
||
}
|
||
DirIterClose(&DirIter);
|
||
}
|
||
|
||
void
|
||
GetListOfDsdts()
|
||
{
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry;
|
||
|
||
DsdtsList.setEmpty();
|
||
OldChosenDsdt = 0xFFFF;
|
||
|
||
DirIterOpen(&selfOem.getConfigDir(), L"ACPI\\patched", &DirIter);
|
||
DbgHeader("Found DSDT tables");
|
||
while (DirIterNext(&DirIter, 2, L"DSDT*.aml", &DirEntry)) {
|
||
if (DirEntry->FileName[0] == L'.') {
|
||
continue;
|
||
}
|
||
if ( gSettings.ACPI.DSDT.DsdtName.isEqualIC(DirEntry->FileName) ) {
|
||
OldChosenDsdt = DsdtsList.size(); // DirEntry->FileName is not yet inserted into DsdtsList. So its index will be DsdtsList.size()
|
||
}
|
||
size_t NameLen = wcslen(DirEntry->FileName); //with ".aml"
|
||
DsdtsList.AddReference(SWPrintf("%.*ls", (int)NameLen, DirEntry->FileName).forgetDataWithoutFreeing(), true); // this avoid to reallocate and copy memory
|
||
DBG("- %ls\n", DirEntry->FileName);
|
||
}
|
||
DirIterClose(&DirIter);
|
||
}
|
||
|
||
void
|
||
GetListOfACPI()
|
||
{
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry = NULL;
|
||
|
||
// XStringW AcpiPath = SWPrintf("%ls\\ACPI\\patched", OEMPath.wc_str());
|
||
// DBG("Get list of ACPI at path %ls\n", AcpiPath.wc_str());
|
||
ACPIPatchedAML.setEmpty();
|
||
DirIterOpen(&selfOem.getConfigDir(), L"ACPI\\patched", &DirIter);
|
||
|
||
while (DirIterNext(&DirIter, 2, L"*.aml", &DirEntry)) {
|
||
// DBG("next entry is %ls\n", DirEntry->FileName);
|
||
if (DirEntry->FileName[0] == L'.') {
|
||
continue;
|
||
}
|
||
if (StriStr(DirEntry->FileName, L"DSDT")) {
|
||
continue;
|
||
}
|
||
// DBG("Found name %ls\n", DirEntry->FileName);
|
||
XBool ACPIDisabled = false;
|
||
ACPI_PATCHED_AML* ACPIPatchedAMLTmp = new ACPI_PATCHED_AML;
|
||
ACPIPatchedAMLTmp->FileName.takeValueFrom(DirEntry->FileName);
|
||
|
||
INTN Count = gSettings.ACPI.DisabledAML.size();
|
||
for (INTN i = 0; i < Count; i++) {
|
||
if ( gSettings.ACPI.DisabledAML[i].isEqualIC(ACPIPatchedAMLTmp->FileName) ) {
|
||
// if ((gSettings.ACPI.DisabledAML[i] != NULL) &&
|
||
// (StriCmp(ACPIPatchedAMLTmp->FileName, gSettings.ACPI.DisabledAML[i]) == 0)
|
||
// ) {
|
||
ACPIDisabled = true;
|
||
break;
|
||
}
|
||
}
|
||
ACPIPatchedAMLTmp->MenuItem.BValue = ACPIDisabled;
|
||
ACPIPatchedAML.AddReference(ACPIPatchedAMLTmp, true);
|
||
}
|
||
|
||
DirIterClose(&DirIter);
|
||
}
|
||
|
||
void
|
||
GetListOfThemes ()
|
||
{
|
||
EFI_STATUS Status = EFI_NOT_FOUND;
|
||
REFIT_DIR_ITER DirIter;
|
||
EFI_FILE_INFO *DirEntry;
|
||
XStringW ThemeTestPath;
|
||
EFI_FILE *ThemeTestDir = NULL;
|
||
UINT8 *ThemePtr = NULL;
|
||
UINTN Size = 0;
|
||
|
||
DbgHeader("GetListOfThemes");
|
||
|
||
ThemeNameArray.setEmpty();
|
||
if ( !self.themesDirExists() ) {
|
||
DBG("No theme dir was discovered\n");
|
||
return;
|
||
}
|
||
DirIterOpen(&self.getThemesDir(), NULL, &DirIter);
|
||
while (DirIterNext(&DirIter, 1, L"*", &DirEntry)) {
|
||
if (DirEntry->FileName[0] == '.') {
|
||
//DBG("Skip theme: %ls\n", DirEntry->FileName);
|
||
continue;
|
||
}
|
||
//DBG("Found theme directory: %ls", DirEntry->FileName);
|
||
DBG("- [%02zu]: %ls", ThemeNameArray.size(), DirEntry->FileName);
|
||
Status = self.getThemesDir().Open(&self.getThemesDir(), &ThemeTestDir, DirEntry->FileName, EFI_FILE_MODE_READ, 0);
|
||
if (!EFI_ERROR(Status)) {
|
||
Status = egLoadFile(ThemeTestDir, CONFIG_THEME_FILENAME, &ThemePtr, &Size);
|
||
if (EFI_ERROR(Status) || (ThemePtr == NULL) || (Size == 0)) {
|
||
Status = egLoadFile(ThemeTestDir, CONFIG_THEME_SVG, &ThemePtr, &Size);
|
||
if (EFI_ERROR(Status)) {
|
||
Status = EFI_NOT_FOUND;
|
||
DBG(" - bad theme because %ls nor %ls can't be load", CONFIG_THEME_FILENAME, CONFIG_THEME_SVG);
|
||
}
|
||
}
|
||
if (!EFI_ERROR(Status)) {
|
||
//we found a theme
|
||
if ((StriCmp(DirEntry->FileName, L"embedded") == 0) ||
|
||
(StriCmp(DirEntry->FileName, L"random") == 0)) {
|
||
ThemePtr = NULL;
|
||
} else {
|
||
ThemeNameArray.Add(DirEntry->FileName);
|
||
}
|
||
}
|
||
}
|
||
DBG("\n");
|
||
if (ThemePtr) {
|
||
FreePool(ThemePtr);
|
||
}
|
||
}
|
||
DirIterClose(&DirIter);
|
||
}
|
||
|
||
//
|
||
// main entry point
|
||
//
|
||
EFI_STATUS
|
||
EFIAPI
|
||
RefitMain (IN EFI_HANDLE ImageHandle,
|
||
IN EFI_SYSTEM_TABLE *SystemTable)
|
||
{
|
||
EFI_STATUS Status;
|
||
XBool MainLoopRunning = true;
|
||
XBool ReinitDesktop = true;
|
||
XBool AfterTool = false;
|
||
REFIT_ABSTRACT_MENU_ENTRY *ChosenEntry = NULL;
|
||
REFIT_ABSTRACT_MENU_ENTRY *DefaultEntry = NULL;
|
||
REFIT_ABSTRACT_MENU_ENTRY *OptionEntry = NULL;
|
||
INTN DefaultIndex;
|
||
UINTN MenuExit;
|
||
UINTN i;
|
||
EFI_TIME Now;
|
||
XBool HaveDefaultVolume;
|
||
REFIT_MENU_SCREEN BootScreen;
|
||
BootScreen.isBootScreen = true; //other screens will be constructed as false
|
||
|
||
MemLogInit();
|
||
|
||
// bootstrap
|
||
gST = SystemTable;
|
||
gImageHandle = ImageHandle;
|
||
gBS = SystemTable->BootServices;
|
||
gRT = SystemTable->RuntimeServices;
|
||
/*Status = */EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (void **) &gDS);
|
||
|
||
InitBooterLog();
|
||
|
||
// ConsoleInHandle = SystemTable->ConsoleInHandle;
|
||
|
||
//#define DEBUG_ERALY_CRASH
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step1");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
|
||
#ifdef DEBUG_ON_SERIAL_PORT
|
||
SerialPortInitialize();
|
||
#endif
|
||
|
||
{
|
||
EFI_LOADED_IMAGE* LoadedImage;
|
||
Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (void **) &LoadedImage);
|
||
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step2");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
|
||
// if ( !EFI_ERROR(Status) ) {
|
||
// XString8 msg = S8Printf("CloverX64 : Image base = 0x%llX\n", (uintptr_t)LoadedImage->ImageBase); // do not change, it's used by grep to feed the debugger
|
||
// SerialPortWrite((UINT8*)msg.c_str(), msg.length());
|
||
// }
|
||
if ( !EFI_ERROR(Status) ) {
|
||
DBG("CloverX64 : Image base = 0x%llX\n", (uintptr_t)LoadedImage->ImageBase); // do not change, it's used by grep to feed the debugger
|
||
DBG("Clover ImageHandle = %llx\n", (uintptr_t)ImageHandle);
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step3");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
}
|
||
#ifdef JIEF_DEBUG
|
||
gBS->Stall(2500000); // to give time to gdb to connect
|
||
// PauseForKey("press\n"_XS8);
|
||
#endif
|
||
}
|
||
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step4");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
|
||
#ifdef CLOVER_BUILD
|
||
// BE CAREFUL. construct_globals_objects will call ctor on every static struct and classes.
|
||
// For example, if you do "gCPUStructure.TSCCalibr = GetMemLogTscTicksPerSecond();" before this point, it will be erased by construct_globals_objects()
|
||
construct_globals_objects(gImageHandle);
|
||
#endif
|
||
|
||
gCPUStructure.TSCCalibr = GetMemLogTscTicksPerSecond(); //ticks for 1second
|
||
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step5");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
|
||
#ifdef JIEF_DEBUG
|
||
// all_tests();
|
||
// PauseForKey(L"press\n");
|
||
#endif
|
||
|
||
gRT->GetTime(&Now, NULL);
|
||
|
||
Status = InitRefitLib(gImageHandle); // From here, debug.log starts to be saved because InitRefitLib call self.initialize()
|
||
if (EFI_ERROR(Status))
|
||
return Status;
|
||
|
||
#ifdef DEBUG_ERALY_CRASH
|
||
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Step6");
|
||
PauseForKey("press any key\n"_XS8);
|
||
#endif
|
||
|
||
// firmware detection
|
||
gFirmwareClover = StrCmp(gST->FirmwareVendor, L"CLOVER") == 0;
|
||
if (!gFirmwareRevision) {
|
||
// gFirmwareRevision = P__oolPrint(L"%d", gST->FirmwareRevision);
|
||
}
|
||
DataHubInstall (ImageHandle, SystemTable);
|
||
InitializeConsoleSim();
|
||
|
||
DbgHeader("Starting Clover");
|
||
if (Now.TimeZone < -1440 || Now.TimeZone > 1440) {
|
||
MsgLog("Now is %02d.%02d.%d, %02d:%02d:%02d (GMT)\n",
|
||
Now.Day, Now.Month, Now.Year, Now.Hour, Now.Minute, Now.Second);
|
||
} else {
|
||
MsgLog("Now is %02d.%02d.%d, %02d:%02d:%02d (GMT+%d)\n",
|
||
Now.Day, Now.Month, Now.Year, Now.Hour, Now.Minute, Now.Second, gSettings.GUI.Timezone);
|
||
}
|
||
//MsgLog("Starting Clover rev %ls on %ls EFI\n", gFirmwareRevision, gST->FirmwareVendor);
|
||
MsgLog("Starting %s on %ls EFI\n", gRevisionStr, gST->FirmwareVendor);
|
||
MsgLog("Build id: %s\n", gBuildId.c_str());
|
||
if ( gBuildInfo ) DBG("Build with: [%s]\n", gBuildInfo);
|
||
|
||
displayFreeMemory(""_XS8);
|
||
|
||
|
||
//dumping SETTING structure
|
||
// if you change something in Platform.h, please uncomment and test that all offsets
|
||
// are natural aligned i.e. pointers are 8 bytes aligned
|
||
/*
|
||
DBG("Settings offsets:\n");
|
||
DBG(" OEMProduct: %X\n", OFFSET_OF(SETTINGS_DATA, OEMProduct));
|
||
DBG(" DefaultVolume: %X\n", OFFSET_OF(SETTINGS_DATA, DefaultVolume));
|
||
DBG(" DefaultLoader: %X\n", OFFSET_OF(SETTINGS_DATA, DefaultLoader));
|
||
DBG(" ResetAddr: %X\n", OFFSET_OF(SETTINGS_DATA, ResetAddr));
|
||
DBG(" FixDsdt: %X\n", OFFSET_OF(SETTINGS_DATA, FixDsdt));
|
||
DBG(" FakeATI: %X\n", OFFSET_OF(SETTINGS_DATA, FakeATI));
|
||
DBG(" PatchVBiosBytes:%X\n", OFFSET_OF(SETTINGS_DATA, PatchVBiosBytes));
|
||
DBG(" VRAM: %X\n", OFFSET_OF(SETTINGS_DATA, VRAM));
|
||
DBG(" SecureBootWhiteListCount: %X\n", OFFSET_OF(SETTINGS_DATA, SecureBootWhiteListCount));
|
||
DBG(" LegacyBoot: %X\n", OFFSET_OF(SETTINGS_DATA, LegacyBoot));
|
||
DBG(" HVHideStrings: %X\n", OFFSET_OF(SETTINGS_DATA, HVHideStrings));
|
||
DBG(" PointerSpeed: %X\n", OFFSET_OF(SETTINGS_DATA, PointerSpeed));
|
||
DBG(" RtMLB: %X\n", OFFSET_OF(SETTINGS_DATA, RtMLB));
|
||
DBG(" ConfigName: %X\n", OFFSET_OF(SETTINGS_DATA, ConfigName));
|
||
DBG(" PointerSpeed: %X\n", OFFSET_OF(SETTINGS_DATA, PointerSpeed));
|
||
DBG(" PatchDsdtNum: %X\n", OFFSET_OF(SETTINGS_DATA, PatchDsdtNum));
|
||
DBG(" LenToReplace: %X\n", OFFSET_OF(SETTINGS_DATA, LenToReplace));
|
||
DBG(" ACPIDropTables: %X\n", OFFSET_OF(SETTINGS_DATA, ACPIDropTables));
|
||
DBG(" CustomEntries: %X\n", OFFSET_OF(SETTINGS_DATA, CustomEntries));
|
||
DBG(" CustomTool: %X\n", OFFSET_OF(SETTINGS_DATA, CustomTool));
|
||
DBG(" AddProperties: %X\n", OFFSET_OF(SETTINGS_DATA, AddProperties));
|
||
DBG(" BlockKexts: %X\n", OFFSET_OF(SETTINGS_DATA, BlockKexts));
|
||
*/
|
||
|
||
// disable EFI watchdog timer
|
||
gBS->SetWatchdogTimer(0x0000, 0x0000, 0x0000, NULL);
|
||
// ZeroMem((void*)&gSettings, sizeof(SETTINGS_DATA));
|
||
|
||
Status = InitializeUnicodeCollationProtocol();
|
||
if (EFI_ERROR(Status)) {
|
||
DBG("UnicodeCollation Status=%s\n", efiStrError(Status));
|
||
}
|
||
|
||
// Status = gBS->HandleProtocol(ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (void **)&SimpleTextEx);
|
||
// if ( EFI_ERROR(Status) ) {
|
||
// SimpleTextEx = NULL;
|
||
// }
|
||
// DBG("SimpleTextEx Status=%s\n", efiStrError(Status));
|
||
|
||
gConf.InitialisePlatform();
|
||
|
||
#ifdef JIEF_DEBUG
|
||
DumpNvram();
|
||
#endif
|
||
|
||
/*
|
||
* saving debug.log works from here
|
||
*/
|
||
|
||
|
||
{
|
||
// UINT32 machineSignature = 0;
|
||
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPointer = NULL;
|
||
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs = NULL;
|
||
|
||
// DBG("---dump hibernations data---\n");
|
||
FadtPointer = GetFadt();
|
||
if (FadtPointer != NULL) {
|
||
Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE*)(UINTN)(FadtPointer->FirmwareCtrl);
|
||
/*
|
||
DBG(" Firmware wake address=%08lx\n", Facs->FirmwareWakingVector);
|
||
DBG(" Firmware wake 64 addr=%16llx\n", Facs->XFirmwareWakingVector);
|
||
DBG(" Hardware signature =%08lx\n", Facs->HardwareSignature);
|
||
DBG(" GlobalLock =%08lx\n", Facs->GlobalLock);
|
||
DBG(" Flags =%08lx\n", Facs->Flags);
|
||
*/
|
||
machineSignature = Facs->HardwareSignature;
|
||
}
|
||
#if HIBERNATE_DUMP_DATA
|
||
//------------------------------------------------------
|
||
DumpVariable(L"Boot0082", gEfiGlobalVariableGuid, 8);
|
||
DumpVariable(L"boot-switch-vars", gEfiAppleBootGuid, -1);
|
||
DumpVariable(L"boot-signature", gEfiAppleBootGuid, -1);
|
||
DumpVariable(L"boot-image-key", gEfiAppleBootGuid, -1);
|
||
DumpVariable(L"boot-image", gEfiAppleBootGuid, 0);
|
||
//-----------------------------------------------------------
|
||
|
||
#endif //
|
||
}
|
||
|
||
#if 0
|
||
//testing place
|
||
{
|
||
const CHAR16 aaa[] = L"12345 ";
|
||
const CHAR8 *bbb = "12345 ";
|
||
DBG(" string %ls, size=%lld, len=%lld sizeof=%ld iStrLen=%lld\n", aaa, StrSize(aaa), StrLen(aaa), sizeof(aaa), iStrLen(bbb, 10));
|
||
const CHAR8* ccc = "Выход ";
|
||
DBG(" string %s, size=%lld, len=%lld sizeof=%ld iStrLen=%lld\n", ccc, AsciiStrSize(ccc), AsciiStrLen(ccc), sizeof(ccc), iStrLen(ccc, 10));
|
||
XString8 ddd = "Выход "_XS8;
|
||
// size_t sizex = ddd.allocatedSize();
|
||
DBG(" xstring %s, asize=%ld, sizeinbyte=%ld sizeof=%ld lastcharat=%ld\n", ddd.c_str(), ddd.allocatedSize(), ddd.sizeInBytes(), sizeof(ddd),
|
||
ddd.indexOf(ddd.lastChar()));
|
||
CHAR8 compatible[64];
|
||
UINT32 FakeLAN = 0x0030168c;
|
||
UINT32 FakeID = FakeLAN >> 16;
|
||
UINT32 FakeVendor = FakeLAN & 0xFFFF;
|
||
snprintf(compatible, 64, "pci%x,%x", FakeVendor, FakeID);
|
||
DBG(" FakeLAN = 0x%x\n", FakeLAN);
|
||
DBG(" Compatible=%s strlen=%ld sizeof=%ld iStrLen=%lld\n", compatible,
|
||
strlen(compatible), sizeof(compatible), iStrLen(compatible, 64));
|
||
// LowCase(compatible);
|
||
// DBG(" Low Compatible=%s strlen=%ld sizeof=%ld iStrLen=%lld\n", compatible,
|
||
// strlen(compatible), sizeof(compatible), iStrLen(compatible, 64));
|
||
|
||
DBG("void*=%ld int=%ld long=%ld longlong=%ld enum=%ld\n",
|
||
sizeof(void*), sizeof(int), sizeof(long int), sizeof(long long), sizeof(EFI_ALLOCATE_TYPE));
|
||
/*
|
||
Results
|
||
41:381 0:000 string 12345 , size=16, len=7 sizeof=16 iStrLen=5
|
||
41:381 0:000 string Выход , size=13, len=12 sizeof=8 iStrLen=10
|
||
41:381 0:000 xstring Выход , asize=0, sizeinbyte=11 sizeof=16 lastcharat=5
|
||
41:381 0:000 FakeLAN = 0x30168c
|
||
41:381 0:000 Compatible=pci168c,30 strlen=10 sizeof=64 iStrLen=10
|
||
|
||
*/
|
||
}
|
||
#endif
|
||
if (!GlobalConfig.isFastBoot()) {
|
||
GetListOfThemes();
|
||
GetListOfConfigs();
|
||
// SmbiosList.setEmpty();
|
||
// SmbiosList.AddReference(new XStringW(L"auto"_XSW), true);
|
||
}
|
||
// ThemeX->FillByEmbedded(); //init XTheme before EarlyUserSettings
|
||
{
|
||
void *Value = NULL;
|
||
UINTN Size = 0;
|
||
//read aptiofixflag from nvram for special boot
|
||
Status = GetVariable2(L"aptiofixflag", gEfiAppleBootGuid, &Value, &Size);
|
||
if (!EFI_ERROR(Status)) {
|
||
GlobalConfig.SpecialBootMode = true;
|
||
FreePool(Value);
|
||
DBG("Fast option enabled\n");
|
||
}
|
||
}
|
||
|
||
// for (i=0; i<2; i++) {
|
||
// if (gConfigDict[i]) {
|
||
// GetEarlyUserSettings(gConfigDict[i], gSettings);
|
||
// }
|
||
// }
|
||
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
// Install secure boot shim
|
||
if (EFI_ERROR(Status = InstallSecureBoot())) {
|
||
PauseForKey("Secure boot failure!\n"_XS8);
|
||
return Status;
|
||
}
|
||
#endif // ENABLE_SECURE_BOOT
|
||
|
||
MainMenu.TimeoutSeconds = gSettings.Boot.Timeout >= 0 ? gSettings.Boot.Timeout : 0;
|
||
//DBG("LoadDrivers() start\n");
|
||
LoadDrivers();
|
||
|
||
Status = gBS->LocateProtocol(gEmuVariableControlProtocolGuid, NULL, (void**)&gEmuVariableControl);
|
||
if (EFI_ERROR(Status)) {
|
||
gEmuVariableControl = NULL;
|
||
}
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->InstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
DbgHeader("InitScreen");
|
||
|
||
if (!GlobalConfig.isFastBoot()) {
|
||
// init screen and dump video modes to log
|
||
if (gDriversFlags.VideoLoaded) {
|
||
InitScreen(false);
|
||
} else {
|
||
InitScreen(!gFirmwareClover); // ? false : true);
|
||
}
|
||
//DBG("DBG: setup screen\n");
|
||
SetupScreen();
|
||
} else {
|
||
InitScreen(false);
|
||
}
|
||
|
||
//DBG("ReinitRefitLib\n");
|
||
//Now we have to reinit handles
|
||
Status = ReinitRefitLib();
|
||
if (EFI_ERROR(Status)){
|
||
// DebugLog(2, " %s", efiStrError(Status));
|
||
PauseForKey("Error reinit refit."_XS8);
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
UninstallSecureBoot();
|
||
#endif // ENABLE_SECURE_BOOT
|
||
return Status;
|
||
}
|
||
|
||
ThemeX = new XTheme();
|
||
|
||
// DBG("DBG: messages\n");
|
||
if (!gSettings.Boot.NoEarlyProgress && !GlobalConfig.isFastBoot() && gSettings.Boot.Timeout>0) {
|
||
XStringW Message = SWPrintf(" Welcome to Clover %ls ", gFirmwareRevision);
|
||
BootScreen.DrawTextXY(Message, (UGAWidth >> 1), UGAHeight >> 1, X_IS_CENTER);
|
||
BootScreen.DrawTextXY(L"... testing hardware ..."_XSW, (UGAWidth >> 1), (UGAHeight >> 1) + 20, X_IS_CENTER);
|
||
}
|
||
|
||
// DumpBiosMemoryMap();
|
||
|
||
GuiEventsInitialize();
|
||
|
||
//DBG("ScanSPD() start\n");
|
||
ScanSPD();
|
||
//DBG("ScanSPD() end\n");
|
||
|
||
SetPrivateVarProto();
|
||
// GetDefaultSettings();
|
||
GetAcpiTablesList();
|
||
|
||
|
||
if (!gSettings.Boot.NoEarlyProgress && !GlobalConfig.isFastBoot() && gSettings.Boot.Timeout>0) {
|
||
XStringW Message = SWPrintf("... user settings ...");
|
||
BootScreen.EraseTextXY();
|
||
BootScreen.DrawTextXY(Message, (UGAWidth >> 1), (UGAHeight >> 1) + 20, X_IS_CENTER);
|
||
}
|
||
|
||
afterGetUserSettings(gSettings);
|
||
gFakeCPUID = gSettings.KernelAndKextPatches.FakeCPUID;
|
||
DBG("Set FakeCPUID: 0x%X\n", gFakeCPUID);
|
||
|
||
HaveDefaultVolume = gSettings.Boot.DefaultVolume.notEmpty();
|
||
if (!gFirmwareClover &&
|
||
!gDriversFlags.EmuVariableLoaded &&
|
||
!HaveDefaultVolume &&
|
||
gSettings.Boot.Timeout == 0 && !ReadAllKeyStrokes()) {
|
||
// UEFI boot: get gEfiBootDeviceGuid from NVRAM.
|
||
// if present, ScanVolumes() will skip scanning other volumes
|
||
// in the first run.
|
||
// this speeds up loading of default macOS volume.
|
||
GetEfiBootDeviceFromNvram();
|
||
}
|
||
|
||
if (!gSettings.Boot.NoEarlyProgress && !GlobalConfig.isFastBoot() && gSettings.Boot.Timeout>0) {
|
||
XStringW Message = SWPrintf("... scan entries ...");
|
||
BootScreen.EraseTextXY();
|
||
BootScreen.DrawTextXY(Message, (UGAWidth >> 1), (UGAHeight >> 1) + 20, X_IS_CENTER);
|
||
}
|
||
|
||
AfterTool = false;
|
||
gGuiIsReady = true;
|
||
GlobalConfig.gBootChanged = true;
|
||
GlobalConfig.gThemeChanged = true;
|
||
|
||
do {
|
||
if (GlobalConfig.gBootChanged && GlobalConfig.gThemeChanged) { // config changed
|
||
GetListOfDsdts(); //only after GetUserSettings
|
||
GetListOfACPI(); //ssdt and other tables
|
||
}
|
||
GlobalConfig.gBootChanged = false;
|
||
MainMenu.Entries.setEmpty();
|
||
OptionMenu.Entries.setEmpty();
|
||
InitKextList();
|
||
ScanVolumes();
|
||
|
||
// as soon as we have Volumes, find latest nvram.plist and copy it to RT vars
|
||
if (!AfterTool) {
|
||
if (gFirmwareClover || gDriversFlags.EmuVariableLoaded) {
|
||
PutNvramPlistToRtVars();
|
||
}
|
||
}
|
||
|
||
// log Audio devices in boot-log. This is for clients like Clover.app
|
||
GetOutputs();
|
||
for (i = 0; i < AudioList.size(); i++) {
|
||
if (AudioList[i].Name.notEmpty()) {
|
||
// Never change this log, otherwise clients will stop interpret the output.
|
||
MsgLog("Found Audio Device %ls (%s) at index %llu\n", AudioList[i].Name.wc_str(), AudioOutputNames[AudioList[i].Device], i);
|
||
}
|
||
}
|
||
|
||
if (!GlobalConfig.isFastBoot()) {
|
||
if (gThemeNeedInit) {
|
||
UINTN Size = 0;
|
||
InitTheme((CHAR8*)GetNvramVariable(L"Clover.Theme", gEfiAppleBootGuid, NULL, &Size));
|
||
gThemeNeedInit = false;
|
||
} else if (GlobalConfig.gThemeChanged) {
|
||
DBG("change theme\n");
|
||
InitTheme(NULL);
|
||
AboutMenu.Entries.setEmpty();
|
||
HelpMenu.Entries.setEmpty();
|
||
}
|
||
DBG("theme inited\n");
|
||
if (ThemeX->embedded) {
|
||
DBG("Chosen embedded theme\n");
|
||
} else {
|
||
DBG("Chosen theme %ls\n", ThemeX->Theme.wc_str());
|
||
}
|
||
|
||
//now it is a time to set RtVariables
|
||
SetVariablesFromNvram();
|
||
|
||
XString8Array TmpArgs = Split<XString8Array>(gSettings.Boot.BootArgs, " ");
|
||
DBG("after NVRAM boot-args=%s\n", gSettings.Boot.BootArgs.c_str());
|
||
GlobalConfig.OptionsBits = EncodeOptions(TmpArgs);
|
||
// DBG("initial OptionsBits %X\n", GlobalConfig.OptionsBits);
|
||
FillInputs(true);
|
||
|
||
// scan for loaders and tools, add then to the menu
|
||
if (gSettings.GUI.Scan.LegacyFirst){
|
||
AddCustomLegacy();
|
||
if (!gSettings.GUI.Scan.NoLegacy) {
|
||
ScanLegacy();
|
||
}
|
||
}
|
||
}
|
||
GetSmcKeys(true);
|
||
|
||
// Add custom entries
|
||
AddCustomEntries();
|
||
if (gSettings.GUI.Scan.DisableEntryScan) {
|
||
DBG("Entry scan disabled\n");
|
||
} else {
|
||
ScanLoader();
|
||
}
|
||
|
||
if (!GlobalConfig.isFastBoot()) {
|
||
if (!gSettings.GUI.Scan.LegacyFirst) {
|
||
AddCustomLegacy();
|
||
if (!gSettings.GUI.Scan.NoLegacy) {
|
||
ScanLegacy();
|
||
}
|
||
}
|
||
|
||
// fixed other menu entries
|
||
if (!(ThemeX->HideUIFlags & HIDEUI_FLAG_TOOLS)) {
|
||
AddCustomTool();
|
||
if (!gSettings.GUI.Scan.DisableToolScan) {
|
||
ScanTool();
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
// Check for secure boot setup mode
|
||
AddSecureBootTool();
|
||
#endif // ENABLE_SECURE_BOOT
|
||
}
|
||
}
|
||
|
||
MenuEntryOptions.Image = ThemeX->GetIcon(BUILTIN_ICON_FUNC_OPTIONS);
|
||
// DBG("Options: IconID=%lld name=%s empty=%s\n", MenuEntryOptions.Image.Id, MenuEntryOptions.Image.Name.c_str(),
|
||
if (gSettings.Boot.DisableCloverHotkeys)
|
||
MenuEntryOptions.ShortcutLetter = 0x00;
|
||
MainMenu.AddMenuEntry(&MenuEntryOptions, false);
|
||
|
||
MenuEntryAbout.Image = ThemeX->GetIcon((INTN)BUILTIN_ICON_FUNC_ABOUT);
|
||
// DBG("About: IconID=%lld name=%s empty=%s\n", MenuEntryAbout.Image.Id, MenuEntryAbout.Image.Name.c_str(),
|
||
|
||
if (gSettings.Boot.DisableCloverHotkeys)
|
||
MenuEntryAbout.ShortcutLetter = 0x00;
|
||
MainMenu.AddMenuEntry(&MenuEntryAbout, false);
|
||
|
||
if (!(ThemeX->HideUIFlags & HIDEUI_FLAG_FUNCS) || MainMenu.Entries.size() == 0) {
|
||
if (gSettings.Boot.DisableCloverHotkeys)
|
||
MenuEntryReset.ShortcutLetter = 0x00;
|
||
MenuEntryReset.Image = ThemeX->GetIcon(BUILTIN_ICON_FUNC_RESET);
|
||
MainMenu.AddMenuEntry(&MenuEntryReset, false);
|
||
if (gSettings.Boot.DisableCloverHotkeys)
|
||
MenuEntryShutdown.ShortcutLetter = 0x00;
|
||
MenuEntryShutdown.Image = ThemeX->GetIcon(BUILTIN_ICON_FUNC_EXIT);
|
||
MainMenu.AddMenuEntry(&MenuEntryShutdown, false);
|
||
}
|
||
|
||
}
|
||
// wait for user ACK when there were errors
|
||
FinishTextScreen(false);
|
||
#if CHECK_SMC
|
||
DumpSmcKeys();
|
||
#endif
|
||
|
||
DefaultIndex = FindDefaultEntry();
|
||
// DBG("DefaultIndex=%lld and MainMenu.Entries.size()=%llu\n", DefaultIndex, MainMenu.Entries.size());
|
||
if ((DefaultIndex >= 0) && (DefaultIndex < (INTN)MainMenu.Entries.size())) {
|
||
DefaultEntry = &MainMenu.Entries[DefaultIndex];
|
||
} else {
|
||
DefaultEntry = NULL;
|
||
}
|
||
|
||
MainLoopRunning = true;
|
||
if (DefaultEntry && (GlobalConfig.isFastBoot() ||
|
||
(gSettings.Boot.SkipHibernateTimeout &&
|
||
DefaultEntry->getLOADER_ENTRY()
|
||
&& OSFLAG_ISSET(DefaultEntry->getLOADER_ENTRY()->Flags, OSFLAG_HIBERNATED)))) {
|
||
if (DefaultEntry->getLOADER_ENTRY()) {
|
||
DefaultEntry->StartLoader();
|
||
} else if (DefaultEntry->getLEGACY_ENTRY()){
|
||
DefaultEntry->StartLegacy();
|
||
}
|
||
gSettings.Boot.FastBoot = false; //Hmm... will never be here
|
||
}
|
||
#ifdef JIEF_DEBUG
|
||
MainMenu.TimeoutSeconds=60;
|
||
#endif
|
||
AfterTool = false;
|
||
gEvent = 0; //clear to cancel loop
|
||
while (MainLoopRunning) {
|
||
if (gSettings.Boot.Timeout == 0 && DefaultEntry != NULL && !ReadAllKeyStrokes()) {
|
||
// go strait to DefaultVolume loading
|
||
MenuExit = MENU_EXIT_TIMEOUT;
|
||
} else {
|
||
MainMenu.GetAnime();
|
||
if (GlobalConfig.gThemeChanged) {
|
||
GlobalConfig.gThemeChanged = false;
|
||
ThemeX->ClearScreen();
|
||
}
|
||
displayFreeMemory("Before RunMainMenu"_XS8);
|
||
MenuExit = MainMenu.RunMainMenu(DefaultIndex, &ChosenEntry);
|
||
}
|
||
// DBG("exit from MainMenu %llu\n", MenuExit); //MENU_EXIT_ENTER=(1) MENU_EXIT_DETAILS=3
|
||
// disable default boot - have sense only in the first run
|
||
gSettings.Boot.Timeout = -1;
|
||
if ((DefaultEntry != NULL) && (MenuExit == MENU_EXIT_TIMEOUT)) {
|
||
if (DefaultEntry->getLOADER_ENTRY()) {
|
||
DefaultEntry->StartLoader();
|
||
} else if (DefaultEntry->getLEGACY_ENTRY()){
|
||
DefaultEntry->StartLegacy();
|
||
}
|
||
// if something goes wrong - break main loop to reinit volumes
|
||
break;
|
||
}
|
||
|
||
if (MenuExit == MENU_EXIT_OPTIONS){
|
||
GlobalConfig.gBootChanged = false;
|
||
OptionsMenu(&OptionEntry);
|
||
if (GlobalConfig.gBootChanged) {
|
||
AfterTool = true;
|
||
MainLoopRunning = false;
|
||
break;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if (MenuExit == MENU_EXIT_HELP){
|
||
HelpRefit();
|
||
continue;
|
||
}
|
||
|
||
// EjectVolume
|
||
if (MenuExit == MENU_EXIT_EJECT){
|
||
Status = EFI_SUCCESS;
|
||
if (ChosenEntry->getLOADER_ENTRY() ) {
|
||
Status = EjectVolume(ChosenEntry->getLOADER_ENTRY()->Volume);
|
||
}
|
||
if ( ChosenEntry->getLEGACY_ENTRY() ) {
|
||
Status = EjectVolume(ChosenEntry->getLEGACY_ENTRY()->Volume);
|
||
}
|
||
if (!EFI_ERROR(Status)) {
|
||
break; //main loop is broken so Reinit all
|
||
}
|
||
continue;
|
||
}
|
||
|
||
// Hide toggle
|
||
if (MenuExit == MENU_EXIT_HIDE_TOGGLE) {
|
||
MainMenu.Entries.includeHidden = !MainMenu.Entries.includeHidden;
|
||
continue;
|
||
}
|
||
|
||
// We don't allow exiting the main menu with the Escape key.
|
||
if (MenuExit == MENU_EXIT_ESCAPE){
|
||
break; //refresh main menu
|
||
// continue;
|
||
}
|
||
|
||
if ( ChosenEntry->getREFIT_MENU_ITEM_RESET() ) { // Restart
|
||
if (MenuExit == MENU_EXIT_DETAILS) {
|
||
|
||
//do clear cmos as for AMI BIOS
|
||
// not sure for more robust method
|
||
IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, 0x10);
|
||
IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
|
||
IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, 0x11);
|
||
IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
|
||
// or may be
|
||
// IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, 0x17);
|
||
// IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x17);
|
||
|
||
// }
|
||
}
|
||
// Attempt warm reboot
|
||
gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||
// Warm reboot may not be supported attempt cold reboot
|
||
gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||
// Terminate the screen and just exit
|
||
TerminateScreen();
|
||
MainLoopRunning = false;
|
||
ReinitDesktop = false;
|
||
AfterTool = true;
|
||
}
|
||
|
||
if ( ChosenEntry->getREFIT_MENU_ITEM_SHUTDOWN() ) { // It is not Shut Down, it is Exit from Clover
|
||
TerminateScreen();
|
||
// gRT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
|
||
MainLoopRunning = false; // just in case we get this far
|
||
ReinitDesktop = false;
|
||
AfterTool = true;
|
||
}
|
||
if ( ChosenEntry->getREFIT_MENU_ITEM_OPTIONS() ) { // Options like KernelFlags, DSDTname etc.
|
||
GlobalConfig.gBootChanged = false;
|
||
OptionsMenu(&OptionEntry);
|
||
if (GlobalConfig.gBootChanged)
|
||
AfterTool = true;
|
||
if (GlobalConfig.gBootChanged || GlobalConfig.gThemeChanged) // If theme has changed reinit the desktop
|
||
MainLoopRunning = false;
|
||
}
|
||
if ( ChosenEntry->getREFIT_MENU_ITEM_ABOUT() ) { // About rEFIt
|
||
AboutRefit();
|
||
}
|
||
|
||
/* -- not passed here
|
||
// case TAG_HELP:
|
||
HelpRefit();
|
||
break;
|
||
*/
|
||
if ( ChosenEntry->getLOADER_ENTRY() ) { // Boot OS via .EFI loader
|
||
SetBootCurrent(ChosenEntry->getLOADER_ENTRY());
|
||
ChosenEntry->StartLoader();
|
||
//if boot.efi failed we should somehow exit from the loop
|
||
TerminateScreen();
|
||
MainLoopRunning = false;
|
||
ReinitDesktop = false;
|
||
AfterTool = true;
|
||
}
|
||
if ( ChosenEntry->getLEGACY_ENTRY() ) { // Boot legacy OS
|
||
if (StrCmp(gST->FirmwareVendor, L"Phoenix Technologies Ltd.") == 0 &&
|
||
gST->Hdr.Revision >> 16 == 2 && (gST->Hdr.Revision & ((1 << 16) - 1)) == 0){
|
||
// Phoenix SecureCore Tiano 2.0 can't properly initiate LegacyBios protocol when called externally
|
||
// which results in "Operating System not found" message coming from BIOS
|
||
// in this case just quit Clover to enter BIOS again
|
||
TerminateScreen();
|
||
MainLoopRunning = false;
|
||
ReinitDesktop = false;
|
||
AfterTool = true;
|
||
} else {
|
||
SetBootCurrent(ChosenEntry->getLEGACY_ENTRY());
|
||
ChosenEntry->StartLegacy();
|
||
}
|
||
}
|
||
if ( ChosenEntry->getREFIT_MENU_ENTRY_LOADER_TOOL() ) { // Start a EFI tool
|
||
ChosenEntry->StartTool();
|
||
TerminateScreen(); //does not happen
|
||
// return EFI_SUCCESS;
|
||
// BdsLibConnectAllDriversToAllControllers();
|
||
// PauseForKey(L"Returned from StartTool\n");
|
||
MainLoopRunning = false;
|
||
AfterTool = true;
|
||
}
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
log_technical_bug("not done yet");
|
||
// if ( ChosenEntry->getREFIT_MENU_ENTRY_SECURE_BOOT() ) { // Try to enable secure boot
|
||
// EnableSecureBoot();
|
||
// MainLoopRunning = false;
|
||
// AfterTool = true;
|
||
// }
|
||
//
|
||
// if ( ChosenEntry->getREFIT_MENU_ENTRY_SECURE_BOOT_CONFIG() ) { // Configure secure boot
|
||
// MainLoopRunning = !ConfigureSecureBoot();
|
||
// AfterTool = true;
|
||
// }
|
||
#endif // ENABLE_SECURE_BOOT
|
||
// DBG("come to Clover entry with letter %c\n", ChosenEntry->ShortcutLetter);
|
||
REFIT_MENU_ENTRY_CLOVER* LoaderEntry = ChosenEntry->getREFIT_MENU_ENTRY_CLOVER();
|
||
if ((ChosenEntry->ShortcutLetter == 'C') || LoaderEntry != NULL ) { // Clover options
|
||
// DBG("enter Clover entry\n");
|
||
|
||
if (LoaderEntry->LoadOptions.notEmpty()) {
|
||
|
||
// we are uninstalling in case user selected Clover Options and EmuVar is installed
|
||
// because adding bios boot option requires access to real nvram
|
||
//Slice: sure?
|
||
/* if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
*/
|
||
// DBG(" Clover entry not empty\n");
|
||
if ( LoaderEntry->LoadOptions.contains(L"BO-ADD") ) {
|
||
// DBG(" BO-ADD");
|
||
XStringW Description;
|
||
CONST CHAR16 *LoaderName;
|
||
INTN EntryIndex, NameSize, Name2Size;
|
||
LOADER_ENTRY *Entry;
|
||
UINT8 *OptionalData;
|
||
UINTN OptionalDataSize;
|
||
UINTN BootNum;
|
||
// EFI_HANDLE UsedHandle = 0;
|
||
|
||
PrintBootOptions(false);
|
||
|
||
for (EntryIndex = 0; EntryIndex < (INTN)MainMenu.Entries.size(); EntryIndex++) {
|
||
if (MainMenu.Entries[EntryIndex].Row != 0) {
|
||
continue;
|
||
}
|
||
if (!MainMenu.Entries[EntryIndex].getLOADER_ENTRY()) {
|
||
continue;
|
||
}
|
||
|
||
Entry = (LOADER_ENTRY *)MainMenu.Entries[EntryIndex].getLOADER_ENTRY();
|
||
XStringW& VolName = Entry->Volume->VolName;
|
||
DBG("add entry for volume %ls\n", VolName.wc_str());
|
||
if (VolName.isEmpty()) {
|
||
VolName = NullXStringW;
|
||
}
|
||
NameSize = VolName.sizeInBytes();
|
||
Name2Size = 0;
|
||
if (Entry->LoaderPath.notEmpty()) {
|
||
LoaderName = Basename(Entry->LoaderPath.wc_str());
|
||
} else {
|
||
LoaderName = NULL; //legacy boot
|
||
}
|
||
if (LoaderName != NULL) {
|
||
Name2Size = StrSize(LoaderName);
|
||
}
|
||
|
||
Description = SWPrintf("Clover UEFI");
|
||
OptionalDataSize = NameSize + Name2Size + 4 + 2; //signature + VolNameSize
|
||
OptionalData = (__typeof__(OptionalData))AllocateZeroPool(OptionalDataSize);
|
||
if (OptionalData == NULL) {
|
||
break;
|
||
}
|
||
CopyMem(OptionalData, "Clvr", 4); //signature = 0x72766c43
|
||
CopyMem(OptionalData + 4, &NameSize, 2);
|
||
CopyMem(OptionalData + 6, VolName.wc_str(), VolName.sizeInBytes());
|
||
if (Name2Size != 0) {
|
||
CopyMem(OptionalData + 6 + NameSize, LoaderName, Name2Size);
|
||
}
|
||
// UsedHandle = LoaderEntry->Volume->DeviceHandle;
|
||
Status = AddBootOptionForFile (
|
||
LoaderEntry->Volume->DeviceHandle,
|
||
LoaderEntry->LoaderPath,
|
||
true,
|
||
Description.wc_str(),
|
||
OptionalData,
|
||
OptionalDataSize,
|
||
EntryIndex,
|
||
(UINT16*)&BootNum
|
||
);
|
||
if (!EFI_ERROR(Status)) {
|
||
DBG("Entry %lld assigned option %04llX\n", EntryIndex, BootNum);
|
||
Entry->BootNum = BootNum;
|
||
}
|
||
FreePool(OptionalData);
|
||
break;
|
||
} //for (EntryIndex
|
||
|
||
|
||
PrintBootOptions(false);
|
||
} else if ( LoaderEntry->LoadOptions.contains(L"BO-REMOVE") ) {
|
||
PrintBootOptions(false);
|
||
Status = DeleteBootOptionForFile (LoaderEntry->Volume->DeviceHandle,
|
||
LoaderEntry->LoaderPath
|
||
);
|
||
PrintBootOptions(false);
|
||
} else if ( LoaderEntry->LoadOptions.contains(L"BO-PRINT") ) {
|
||
PrintBootOptions(true);
|
||
}
|
||
|
||
}
|
||
MainLoopRunning = false;
|
||
AfterTool = true;
|
||
}
|
||
} //MainLoopRunning
|
||
UninitRefitLib();
|
||
if (!AfterTool) {
|
||
// PauseForKey(L"After uninit");
|
||
//reconnectAll
|
||
if (!gFirmwareClover) {
|
||
BdsLibConnectAllEfi();
|
||
}
|
||
else {
|
||
DBG("ConnectAll after refresh menu\n");
|
||
BdsLibConnectAllDriversToAllControllers();
|
||
}
|
||
// ReinitRefitLib();
|
||
// PauseForKey(L"After ReinitRefitLib");
|
||
}
|
||
if (ReinitDesktop) {
|
||
DBG("ReinitRefitLib after theme change\n");
|
||
ReinitRefitLib();
|
||
}
|
||
// PauseForKey(L"After ReinitRefitLib");
|
||
} while (ReinitDesktop);
|
||
|
||
// If we end up here, things have gone wrong. Try to reboot, and if that
|
||
// fails, go into an endless loop.
|
||
//Slice - NO!!! Return to EFI GUI
|
||
// gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||
// EndlessIdleLoop();
|
||
|
||
#ifdef ENABLE_SECURE_BOOT
|
||
UninstallSecureBoot();
|
||
#endif // ENABLE_SECURE_BOOT
|
||
|
||
// Unload EmuVariable before returning to EFI GUI, as it should not be present when booting other Operating Systems.
|
||
// This seems critical in some UEFI implementations, such as Phoenix UEFI 2.0
|
||
if (gEmuVariableControl != NULL) {
|
||
gEmuVariableControl->UninstallEmulation(gEmuVariableControl);
|
||
}
|
||
|
||
UninitializeConsoleSim ();
|
||
|
||
#ifdef CLOVER_BUILD
|
||
destruct_globals_objects(NULL);
|
||
#endif
|
||
|
||
return EFI_SUCCESS;
|
||
}
|
||
|
||
|