Prevent "log loop" a better way.

Do not depend on Self instance for opening log file.
Rework on Self to share code with BootLog.cpp.
This commit is contained in:
jief666 2021-05-23 13:20:30 +03:00
parent 36e63bd7f0
commit c0fa72e2ed
5 changed files with 249 additions and 250 deletions

@ -1 +1 @@
Subproject commit 9ecf06dc98cdc6169991d4033417bd3ff0da0355
Subproject commit 704c042bdb9be1e14d207276403127b7b46f4007

View File

@ -15,12 +15,6 @@
#include "../Settings/Self.h"
#include "../Platform/guid.h"
//Slice - if I set NEW_LOG to 0 then I will work with debug.log as in 5103
// but it is not working somehow.
// my purpose is to make debug.log open and close every second to see crashes.
// currently it is not happen. debug.log is not created at crash.
#define NEW_LOG 1
#ifndef DEBUG_ALL
#define DEBUG_BOOTLOG 0
#else
@ -82,6 +76,8 @@ static XStringW debugLogFileName;
static EFI_FILE_PROTOCOL* gLogFile = NULL;
// Do not keep a pointer to MemLogBuffer. Because a reallocation, it could become invalid.
int g_OpeningLogFile = 0;
// Avoid debug looping. TO be able to call DBG from inside function that DBG calls, we need to suspend callback to avoid a loop.
// Just instanciante this, the destructor will restore the callback.
@ -99,7 +95,6 @@ public:
#if DEBUG_BOOTLOG == 0
#define DGB_nbCallback(...)
#else
//Slice - it crashes at legacy boot
#define DGB_nbCallback(...) do { SuspendMemLogCallback smc; DBG(__VA_ARGS__); } while (0)
#endif
@ -116,7 +111,13 @@ void closeDebugLog()
//DGB_nbCallback("closeDebugLog() -> %s\n", efiStrError(Status));
}
#if NEW_LOG
/*
* Use (or not) self.getCloverDir() to open log file.
* Not using self has the advantage of being able to generate a log even after uninitreflib().
* The only thing needed is gImageHandle. But because it's a parameter to main entry point, value can't be wrong.
* Drawback is that code to find current working directory has to be duplicated.
*/
//#define USE_SELF_INSTANCE
static UINTN GetDebugLogFile()
{
EFI_STATUS Status;
@ -124,21 +125,11 @@ static UINTN GetDebugLogFile()
if ( gLogFile ) return 0;
// // get RootDir from device we are loaded from
// Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
// if (EFI_ERROR(Status)) {
// DGB_nbCallback(" GetDebugLogFile() -> HandleProtocol : %s\n", efiStrError(Status));
// }
// RootDir = EfiLibOpenRoot(LoadedImage->DeviceHandle);
// if (RootDir == NULL) {
// DGB_nbCallback(" GetDebugLogFile() -> EfiLibOpenRoot : %s\n", efiStrError(Status));
// }
//
// // Open log file from current root
// Status = RootDir->Open(RootDir, &LogFile, SWPrintf("%ls\\%ls", self.getCloverDirFullPath().wc_str(), DEBUG_LOG).wc_str(),
// EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
#ifdef USE_SELF_INSTANCE
if ( !self.isInitialized() ) return 0;
#endif
if ( !self.isInitialized() ) return 0;
g_OpeningLogFile = 1;
EFI_TIME Now;
Status = gRT->GetTime(&Now, NULL);
@ -146,27 +137,40 @@ static UINTN GetDebugLogFile()
DBG("GetTime return %s\n", efiStrError(Status));
}
#ifdef USE_SELF_INSTANCE
const EFI_FILE_PROTOCOL& CloverDir = self.getCloverDir();
const XString& efiFileName = self.getCloverEfiFileName();
#else
XStringW efiFileName;
const EFI_FILE_PROTOCOL* CloverDirPtr = Self::getCloverDirAndEfiFileName(gImageHandle, &efiFileName);
if ( CloverDirPtr == NULL ) return 0;
const EFI_FILE_PROTOCOL& CloverDir = *CloverDirPtr;
#endif
if ( debugLogFileName.isEmpty() )
{
debugLogFileName = S8Printf("misc\\%04d-%02d-%02d_%02d-%02d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, self.getCloverEfiFileName().wc_str());
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
debugLogFileName = S8Printf("misc\\%04d-%02d-%02d_%02d-%02d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, efiFileName.wc_str());
Status = CloverDir.Open(&CloverDir, &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
if ( !EFI_ERROR(Status) ) LogFile->Close(LogFile); // DO NOT modify Status here.
INTN i=1;
while ( Status != EFI_NOT_FOUND && (i < MAX_INTN) ) {
debugLogFileName = S8Printf("misc\\%04d-%02d-%02d_%02d-%02d_%ls(%lld).log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, self.getCloverEfiFileName().wc_str(), i);
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
debugLogFileName = S8Printf("misc\\%04d-%02d-%02d_%02d-%02d_%ls(%lld).log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, efiFileName.wc_str(), i);
Status = CloverDir.Open(&CloverDir, &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
if ( !EFI_ERROR(Status) ) LogFile->Close(LogFile); // DO NOT modify Status here.
}
if ( Status != EFI_NOT_FOUND ) {
DBG("Cannot find a free debug log file name\n"); // I can't imagine that to happen...
debugLogFileName.setEmpty(); // To allow to retry at the next call
g_OpeningLogFile = 0;
return 0;
}
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
Status = CloverDir.Open(&CloverDir, &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
gLogFile = LogFile;
g_OpeningLogFile = 0;
return 0;
}else{
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
Status = CloverDir.Open(&CloverDir, &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
g_OpeningLogFile = 0;
//// Jief : Instead of EfiLibFileInfo, let's use SetPosition to get the size.
// if (!EFI_ERROR(Status)) {
@ -200,79 +204,7 @@ static UINTN GetDebugLogFile()
return 0;
}
}
#else
EFI_FILE_PROTOCOL* GetDebugLogFile()
{
EFI_STATUS Status;
EFI_LOADED_IMAGE *LoadedImage;
EFI_FILE_PROTOCOL *RootDir;
EFI_FILE_PROTOCOL *LogFile;
// get RootDir from device we are loaded from
Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
if (EFI_ERROR(Status)) {
return NULL;
}
RootDir = EfiLibOpenRoot(LoadedImage->DeviceHandle);
if (RootDir == NULL) {
return NULL;
}
// Open log file from current root
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
// If the log file is not found try to create it
if (Status == EFI_NOT_FOUND) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
}
RootDir->Close(RootDir);
RootDir = NULL;
if (EFI_ERROR(Status)) {
// try on first EFI partition
Status = egFindESP(&RootDir);
if (!EFI_ERROR(Status)) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
// If the log file is not found try to create it
if (Status == EFI_NOT_FOUND) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
}
RootDir->Close(RootDir);
RootDir = NULL;
}
}
if (EFI_ERROR(Status)) {
LogFile = NULL;
}
return LogFile;
}
// Jief : do we need that ?
// if (EFI_ERROR(Status)) {
// // try on first EFI partition
// Status = egFindESP(&RootDir);
// if (!EFI_ERROR(Status)) {
// Status = RootDir->Open(RootDir, &LogFile, SWPrintf("%ls\\%ls", self.getCloverDirFullPath().wc_str(), DEBUG_LOG).wc_str(),
// EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
// // If the log file is not found try to create it
// if (Status == EFI_NOT_FOUND) {
// Status = RootDir->Open(RootDir, &LogFile, SWPrintf("%ls\\%ls", self.getCloverDirFullPath().wc_str(), DEBUG_LOG).wc_str(),
// EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
// }
// RootDir->Close(RootDir);
// RootDir = NULL;
// }
// }
#endif
#if NEW_LOG
VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
{
EFI_STATUS Status;
@ -308,45 +240,6 @@ VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
// Not all Firmware implements Flush. So we have to close every time to force flush.
closeDebugLog();
}
#else
VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
{
STATIC BOOLEAN FirstTimeSave = TRUE;
// STATIC UINTN Position = 0;
CHAR8 *MemLogBuffer;
UINTN MemLogLen;
CHAR8 *Text;
UINTN TextLen;
EFI_FILE_HANDLE LogFile;
MemLogBuffer = GetMemLogBuffer();
MemLogLen = GetMemLogLen();
Text = LastMessage;
TextLen = AsciiStrLen(LastMessage);
/*UINTN lastWrittenOffset = GetDebugLogFile();*/
LogFile = GetDebugLogFile();
// Write to the log file
if (LogFile != NULL) {
// Advance to the EOF so we append
EFI_FILE_INFO *Info = EfiLibFileInfo(LogFile);
if (Info) {
LogFile->SetPosition(LogFile, Info->FileSize);
// If we haven't had root before this write out whole log
if (FirstTimeSave) {
Text = MemLogBuffer;
TextLen = MemLogLen;
FirstTimeSave = FALSE;
}
// Write out this message
LogFile->Write(LogFile, &TextLen, Text);
}
LogFile->Close(LogFile);
}
}
#endif
void EFIAPI MemLogCallback(IN INTN DebugMode, IN CHAR8 *LastMessage)
{
@ -380,28 +273,12 @@ void EFIAPI DebugLog(IN INTN DebugMode, IN CONST CHAR8 *FormatString, ...)
MemLogfVA(TRUE, DebugMode, FormatString, Marker);
VA_END(Marker);
}
#if NEW_LOG
void InitBooterLog(void)
{
SetMemLogCallback(MemLogCallback);
}
#else
void InitBooterLog(void)
{
EFI_TIME Now;
EFI_STATUS Status;
Status = gRT->GetTime(&Now, NULL);
if (!EFI_ERROR(Status)) {
debugLogFileName = SWPrintf("misc\\%d-%d-%d_%d-%d-%d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, Now.Second, self.getCloverEfiFileName().wc_str());
} else {
debugLogFileName = L"misc\\debug.log"_XSW;
}
SetMemLogCallback(MemLogCallback);
}
#endif
EFI_STATUS SetupBooterLog(BOOLEAN AllowGrownSize)
{

View File

@ -526,7 +526,11 @@ EFI_STATUS LoadPlist(const XStringW& ConfName, C* plist)
XmlLiteParser xmlLiteParser;
bool parsingOk = plist->parse((const CHAR8*)ConfigPtr, Size, ""_XS8, &xmlLiteParser);
if ( xmlLiteParser.getErrorsAndWarnings().size() ) {
DebugLog(2, "There is problems in plist '%ls'\n", configPlistPath.wc_str());
if ( xmlLiteParser.getErrorsAndWarnings().size() > 1 ) {
DebugLog(2, "There are problems in plist '%ls'\n", configPlistPath.wc_str());
}else{
DebugLog(2, "There is a problem in plist '%ls'\n", configPlistPath.wc_str());
}
for ( size_t idx = 0 ; idx < xmlLiteParser.getErrorsAndWarnings().size() ; idx++ ) {
const XmlParserMessage& xmlMsg = xmlLiteParser.getErrorsAndWarnings()[idx];
DebugLog(2, "%s: %s\n", xmlMsg.isError ? "Error" : "Warning", xmlMsg.msg.c_str());

View File

@ -21,6 +21,106 @@
#define DBG(...) DebugLog(DEBUG_SELF, __VA_ARGS__)
#endif
EFI_STATUS Self::__initialize(EFI_HANDLE SelfImageHandle, EFI_LOADED_IMAGE** SelfLoadedImagePtr, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL** SelfSimpleVolumePtr, EFI_FILE** SelfVolumeRootDirPtr, XStringW* CloverDirFullPathPtr, XStringW* efiFileNamePtr, EFI_FILE** CloverDirPtr)
{
EFI_STATUS Status;
Status = gBS->HandleProtocol(SelfImageHandle, &gEfiLoadedImageProtocolGuid, (void **)SelfLoadedImagePtr);
if ( EFI_ERROR(Status) ) {
*SelfLoadedImagePtr = NULL;
return RETURN_LOAD_ERROR;
}
EFI_LOADED_IMAGE* SelfLoadedImage = *SelfLoadedImagePtr;
if ( SelfLoadedImage->DeviceHandle == NULL ) {
*SelfLoadedImagePtr = NULL;
return RETURN_LOAD_ERROR;
}
Status = gBS->HandleProtocol(SelfLoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (void**)SelfSimpleVolumePtr);
if ( EFI_ERROR(Status) ) {
*SelfSimpleVolumePtr = NULL;
return RETURN_LOAD_ERROR;
}
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SelfSimpleVolume = *SelfSimpleVolumePtr;
Status = SelfSimpleVolume->OpenVolume(SelfSimpleVolume, SelfVolumeRootDirPtr);
if ( EFI_ERROR(Status) ) {
*SelfVolumeRootDirPtr = NULL;
return RETURN_LOAD_ERROR;
}
EFI_FILE* SelfVolumeRootDir = *SelfVolumeRootDirPtr;
#ifdef JIEF_DEBUG
DBG("SelfVolumeRootDir = %lld\n", uintptr_t(SelfVolumeRootDir));
#endif
// find the current directory
*CloverDirFullPathPtr = FileDevicePathToXStringW(SelfLoadedImage->FilePath);
if ( CloverDirFullPathPtr->isEmpty() ) {
return RETURN_LOAD_ERROR;
}
XStringW& CloverDirFullPath = *CloverDirFullPathPtr;
// Do this before the next check.
if ( !CloverDirFullPath.startWith('\\') ) {
// Some firmware seems to not put a '\' at the begining. Do not panic anymore, just add it.
CloverDirFullPath.insertAtPos('\\', 0);
}
*efiFileNamePtr = CloverDirFullPath.basename();
XStringW& efiFileName = *efiFileNamePtr;
#ifdef JIEF_DEBUG
DBG("efiFileName=%ls\n", efiFileName.wc_str());
#endif
// History : if this Clover was started as BootX64.efi, redirect to /EFI/CLOVER
if ( CloverDirFullPath.isEqualIC("\\EFI\\Boot\\BootX64.efi") ) { // keep getCloverDir() in sync !
CloverDirFullPath.takeValueFrom("\\EFI\\CLOVER\\CloverX64.efi"); // keep getCloverDir() in sync !
}
if ( CloverDirFullPath.lastChar() == U'\\' ) { // keep getCloverDir() in sync !
log_technical_bug("CloverDirFullPath.lastChar() == U'\\'"); // Just to see if that happens.
CloverDirFullPath.deleteCharsAtPos(CloverDirFullPath.length()-1, 1);
}
size_t i = CloverDirFullPath.rindexOf(U'\\', SIZE_T_MAX-1); // keep getCloverDir() in sync !
if ( i != SIZE_T_MAX && i > 0 ) CloverDirFullPath.deleteCharsAtPos(i, SIZE_T_MAX); // keep getCloverDir() in sync !
#ifdef JIEF_DEBUG
DBG("SelfDirPath = %ls\n", CloverDirFullPath.wc_str());
#endif
Status = SelfVolumeRootDir->Open(SelfVolumeRootDir, CloverDirPtr, CloverDirFullPath.wc_str(), EFI_FILE_MODE_READ, 0);
if ( EFI_ERROR(Status) ) {
*CloverDirPtr = NULL;
return RETURN_LOAD_ERROR;
}
EFI_FILE* CloverDir = *CloverDirPtr;
#ifdef JIEF_DEBUG
DBG("CloverDir = %lld\n", uintptr_t(CloverDir));
#endif
return EFI_SUCCESS;
}
const EFI_FILE_PROTOCOL* Self::getCloverDirAndEfiFileName(EFI_HANDLE ImageHandle, XStringW* efiFileName)
{
EFI_LOADED_IMAGE* SelfLoadedImage; // this efi.
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SelfSimpleVolume; // Volume containing this efi.
EFI_FILE* SelfVolumeRootDir; // Root dir of the volume containing this efi.
XStringW CloverDirFullPath; // full path of folder containing this efi.
EFI_FILE* CloverDir; // opened folder containing this efi
/*EFI_STATUS Status = */__initialize(ImageHandle, &SelfLoadedImage, &SelfSimpleVolume, &SelfVolumeRootDir, &CloverDirFullPath, efiFileName, &CloverDir);
if ( efiFileName->isEmpty() ) {
if ( CloverDir != NULL ) CloverDir->Close(CloverDir);
return NULL;
}
return CloverDir;
}
Self self;
@ -42,84 +142,106 @@ EFI_STATUS Self::_openDir(const XStringW& path, bool* b, EFI_FILE** efiDir)
EFI_STATUS Self::_initialize()
{
EFI_STATUS Status;
// EFI_STATUS Status;
Status = gBS->HandleProtocol(m_SelfImageHandle, &gEfiLoadedImageProtocolGuid, (void **)&m_SelfLoadedImage);
#ifdef DEBUG
if ( EFI_ERROR(Status) ) panic("Cannot get SelfLoadedImage");
if ( m_SelfLoadedImage->DeviceHandle == NULL ) panic("m_SelfLoadedImage->DeviceHandle == NULL");
m_SelfDevicePath = DuplicateDevicePath(DevicePathFromHandle(m_SelfLoadedImage->DeviceHandle));
if ( m_SelfDevicePath == NULL ) panic("m_SelfDevicePath == NULL");
#else
if ( EFI_ERROR(Status) ) return Status;
if ( m_SelfLoadedImage->DeviceHandle == NULL ) return EFI_NOT_FOUND;
m_SelfDevicePath = DuplicateDevicePath(DevicePathFromHandle(m_SelfLoadedImage->DeviceHandle));
if ( m_SelfDevicePath == NULL ) return EFI_NOT_FOUND;
#endif
/*Status = */__initialize(m_SelfImageHandle, &m_SelfLoadedImage, &m_SelfSimpleVolume, &m_SelfVolumeRootDir, &m_CloverDirFullPath, &m_efiFileName, &m_CloverDir);
if ( m_SelfLoadedImage == NULL ) log_technical_bug("Cannot get SelfLoadedImage");
if ( m_SelfLoadedImage->DeviceHandle == NULL ) log_technical_bug("m_SelfLoadedImage->DeviceHandle == NULL");
if ( m_SelfSimpleVolume == NULL ) log_technical_bug("Cannot get m_SelfSimpleVolume");
if ( m_SelfVolumeRootDir == NULL ) log_technical_bug("Cannot get m_SelfVolumeRootDir");
if ( m_CloverDirFullPath.isEmpty() ) log_technical_bug("Cannot get m_CloverDirFullPath");
if ( m_efiFileName.isEmpty() ) log_technical_bug("Cannot get m_efiFileName");
if ( m_CloverDir == NULL ) panic("Cannot open getSelfRootDir()"); // We have to panic, nothing would work without m_CloverDir
#ifdef JIEF_DEBUG
DBG("Self DevicePath()=%ls @%llX\n", FileDevicePathToXStringW(m_SelfDevicePath).wc_str(), (uintptr_t)m_SelfLoadedImage->DeviceHandle);
#endif
Status = gBS->HandleProtocol(m_SelfLoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (void**)&m_SelfSimpleVolume);
#ifdef DEBUG
if ( EFI_ERROR(Status) ) panic("Cannot get m_SelfSimpleVolume");
Status = m_SelfSimpleVolume->OpenVolume(m_SelfSimpleVolume, &m_SelfVolumeRootDir);
if ( EFI_ERROR(Status) ) panic("Cannot get m_SelfRootDir");
#else
if ( EFI_ERROR(Status) ) return Status;
Status = m_SelfSimpleVolume->OpenVolume(m_SelfSimpleVolume, &m_SelfVolumeRootDir);
if ( EFI_ERROR(Status) ) return Status;
#endif
// find the current directory
m_CloverDirFullPath = FileDevicePathToXStringW(m_SelfLoadedImage->FilePath);
// Do this before the next check.
if ( !m_CloverDirFullPath.startWith('\\') ) {
//CHAR16* f = ConvertDevicePathToText(m_SelfLoadedImage->FilePath, TRUE, TRUE);
//panic("Bad format for m_CloverDirFullPath(%ls). It must start with a '\\'.\nConvertDevicePathToText=%ls", m_CloverDirFullPath.wc_str(), f);
//
// Somefirmware seems to not put a '\' at the begining. Do not panic anymore, just add it.
m_CloverDirFullPath.insertAtPos('\\', 0);
m_SelfDevicePath = NULL;
if ( m_SelfLoadedImage && m_SelfLoadedImage->DeviceHandle ) {
m_SelfDevicePath = FileDevicePath(m_SelfLoadedImage->DeviceHandle, m_CloverDirFullPath + '\\' + m_efiFileName);
}
m_efiFileName = m_CloverDirFullPath.basename();
#ifdef JIEF_DEBUG
DBG("m_efiFileName=%ls\n", m_efiFileName.wc_str());
#endif
// History : if this Clover was started as BootX64.efi, redirect to /EFI/CLOVER
if ( m_CloverDirFullPath.isEqualIC("\\EFI\\Boot\\BootX64.efi") ) {
m_CloverDirFullPath.takeValueFrom("\\EFI\\CLOVER\\CloverX64.efi");
if ( m_SelfDevicePath == NULL ) {
log_technical_bug("m_SelfDevicePath == NULL"); // not sure what can work without m_SelfDevicePath
}else{
#ifdef JIEF_DEBUG
DBG("Self DevicePath()=%ls @%llX\n", FileDevicePathToXStringW(m_SelfDevicePath).wc_str(), (uintptr_t)m_SelfLoadedImage->DeviceHandle);
#endif
}
#ifdef DEBUG
if ( m_CloverDirFullPath.isEmpty() ) panic("m_CloverDirFullPath.isEmpty()");
#else
if ( m_CloverDirFullPath.isEmpty() ) return EFI_NOT_FOUND;
#endif
m_SelfDevicePath = FileDevicePath(m_SelfLoadedImage->DeviceHandle, m_CloverDirFullPath);
m_SelfDevicePathAsXStringW = FileDevicePathToXStringW(m_SelfDevicePath);
#ifdef DEBUG
if ( m_CloverDirFullPath.lastChar() == U'\\' ) panic("m_CloverDirFullPath.lastChar() == U'\\'");
//if ( m_CloverDirFullPath.endsWith('\\') ) panic("m_CloverDirFullPath.endsWith('\\')");
#else
if ( m_CloverDirFullPath.lastChar() == U'\\' ) return EFI_NOT_FOUND;
#endif
size_t i = m_CloverDirFullPath.rindexOf(U'\\', SIZE_T_MAX-1);
if ( i != SIZE_T_MAX && i > 0 ) m_CloverDirFullPath.deleteCharsAtPos(i, SIZE_T_MAX);
#ifdef JIEF_DEBUG
DBG("SelfDirPath = %ls\n", m_CloverDirFullPath.wc_str());
#endif
Status = m_SelfVolumeRootDir->Open(m_SelfVolumeRootDir, &m_CloverDir, m_CloverDirFullPath.wc_str(), EFI_FILE_MODE_READ, 0);
if ( EFI_ERROR(Status) ) panic("Cannot open getSelfRootDir()");
// m_SelfDevicePathAsXStringW = FileDevicePathToXStringW(m_SelfDevicePath);
_openDir(THEMES_DIRNAME, &m_ThemesDirExists, &m_ThemesDir); // don't need to check returned status as it's ok to not have a themes dir.
return EFI_SUCCESS;
//
//
// Status = gBS->HandleProtocol(m_SelfImageHandle, &gEfiLoadedImageProtocolGuid, (void **)&m_SelfLoadedImage);
// if ( EFI_ERROR(Status) ) panic("Cannot get SelfLoadedImage"); // We have to panic, nothing would work without m_CloverDir, and m_SelfImageHandle is needed to get it
// if ( m_SelfLoadedImage->DeviceHandle == NULL ) panic("m_SelfLoadedImage->DeviceHandle == NULL"); // We have to panic, nothing would work without m_CloverDir, and m_SelfLoadedImage->DeviceHandle is needed to get it
// m_SelfDevicePath = DuplicateDevicePath(DevicePathFromHandle(m_SelfLoadedImage->DeviceHandle));
// if ( m_SelfDevicePath == NULL ) {
// log_technical_bug("m_SelfDevicePath == NULL"); // not sure what can work without m_SelfDevicePath
// }
//
//#ifdef JIEF_DEBUG
// DBG("Self DevicePath()=%ls @%llX\n", FileDevicePathToXStringW(m_SelfDevicePath).wc_str(), (uintptr_t)m_SelfLoadedImage->DeviceHandle);
//#endif
//
// Status = gBS->HandleProtocol(m_SelfLoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (void**)&m_SelfSimpleVolume);
// if ( EFI_ERROR(Status) ) panic("Cannot get m_SelfSimpleVolume"); // We have to panic, nothing would work without m_CloverDir, and m_SelfSimpleVolume is needed to get it
// Status = m_SelfSimpleVolume->OpenVolume(m_SelfSimpleVolume, &m_SelfVolumeRootDir);
// if ( EFI_ERROR(Status) ) panic("Cannot get m_SelfVolumeRootDir"); // We have to panic, nothing would work without m_CloverDir, and m_SelfVolumeRootDir is needed to get it
//
//#ifdef JIEF_DEBUG
// DBG("m_SelfVolumeRootDir = %lld\n", uintptr_t(m_SelfVolumeRootDir));
//#endif
//
// // find the current directory
// m_CloverDirFullPath = FileDevicePathToXStringW(m_SelfLoadedImage->FilePath);
//
// // Do this before the next check.
// if ( !m_CloverDirFullPath.startWith('\\') ) {
// //CHAR16* f = ConvertDevicePathToText(m_SelfLoadedImage->FilePath, TRUE, TRUE);
// //panic("Bad format for m_CloverDirFullPath(%ls). It must start with a '\\'.\nConvertDevicePathToText=%ls", m_CloverDirFullPath.wc_str(), f);
// //
// // Some firmware seems to not put a '\' at the begining. Do not panic anymore, just add it.
// m_CloverDirFullPath.insertAtPos('\\', 0);
// }
//
// m_efiFileName = m_CloverDirFullPath.basename();
//#ifdef JIEF_DEBUG
// DBG("m_efiFileName=%ls\n", m_efiFileName.wc_str());
//#endif
//
// // Code to find m_CloverDirFullPath is duplicated in BootLog.cpp in case USE_SELF_INSTANCE is not defined
//
// // History : if this Clover was started as BootX64.efi, redirect to /EFI/CLOVER
// if ( m_CloverDirFullPath.isEqualIC("\\EFI\\Boot\\BootX64.efi") ) { // keep getCloverDir() in sync !
// m_CloverDirFullPath.takeValueFrom("\\EFI\\CLOVER\\CloverX64.efi"); // keep getCloverDir() in sync !
// }
// if ( m_CloverDirFullPath.isEmpty() ) log_technical_bug("m_CloverDirFullPath.isEmpty()");
// m_SelfDevicePath = FileDevicePath(m_SelfLoadedImage->DeviceHandle, m_CloverDirFullPath);
//// m_SelfDevicePathAsXStringW = FileDevicePathToXStringW(m_SelfDevicePath);
//
// if ( m_CloverDirFullPath.lastChar() == U'\\' ) { // keep getCloverDir() in sync !
// log_technical_bug("m_CloverDirFullPath.lastChar() == U'\\'"); // Just to see if that happens.
// m_CloverDirFullPath.deleteCharsAtPos(m_CloverDirFullPath.length()-1, 1);
// }
//
// size_t i = m_CloverDirFullPath.rindexOf(U'\\', SIZE_T_MAX-1); // keep getCloverDir() in sync !
// if ( i != SIZE_T_MAX && i > 0 ) m_CloverDirFullPath.deleteCharsAtPos(i, SIZE_T_MAX); // keep getCloverDir() in sync !
//
//#ifdef JIEF_DEBUG
// DBG("SelfDirPath = %ls\n", m_CloverDirFullPath.wc_str());
//#endif
// Status = m_SelfVolumeRootDir->Open(m_SelfVolumeRootDir, &m_CloverDir, m_CloverDirFullPath.wc_str(), EFI_FILE_MODE_READ, 0);
// if ( EFI_ERROR(Status) ) panic("Cannot open getSelfRootDir()"); // We have to panic, nothing would work without m_CloverDir
//#ifdef JIEF_DEBUG
// DBG("m_CloverDir = %lld\n", uintptr_t(m_CloverDir));
//#endif
//
//
// _openDir(THEMES_DIRNAME, &m_ThemesDirExists, &m_ThemesDir); // don't need to check returned status as it's ok to not have a themes dir.
//
// return EFI_SUCCESS;
}
EFI_STATUS Self::initialize(EFI_HANDLE ImageHandle)

View File

@ -18,34 +18,34 @@ extern "C" {
class Self
{
// Class method, usable even without any instance of Self.
protected:
EFI_HANDLE m_SelfImageHandle; // this efi.
EFI_LOADED_IMAGE* m_SelfLoadedImage; // this efi.
EFI_DEVICE_PATH* m_SelfDevicePath; // path to device containing this efi.
XStringW m_SelfDevicePathAsXStringW; // path to device containing this efi.
static EFI_STATUS __initialize(EFI_HANDLE m_SelfImageHandle, EFI_LOADED_IMAGE** m_SelfLoadedImage, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL** m_SelfSimpleVolumePtr, EFI_FILE** m_SelfVolumeRootDirPtr, XStringW* m_CloverDirFullPathPtr, XStringW* m_efiFileNamePtr, EFI_FILE** m_CloverDirPtr);
public:
static const EFI_FILE_PROTOCOL* getCloverDirAndEfiFileName(EFI_HANDLE ImageHandle, XStringW* efiFileName);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *m_SelfSimpleVolume; // Volume containing this efi.
EFI_FILE* m_SelfVolumeRootDir; // Root dir of the volume containing this efi.
protected:
EFI_HANDLE m_SelfImageHandle {}; // this efi.
EFI_LOADED_IMAGE* m_SelfLoadedImage {}; // this efi.
EFI_DEVICE_PATH* m_SelfDevicePath {}; // path to device containing this efi.
// XStringW m_SelfDevicePathAsXStringW; // path to device containing this efi.
XStringW m_efiFileName = L""_XSW;
EFI_DEVICE_PATH* m_CloverDirFullDevicePath; // full path, including device, of the folder containing this efi.
EFI_FILE* m_CloverDir; // opened folder containing this efi
XStringW m_CloverDirFullPath; // full path of folder containing this efi.
// XStringW m_CloverDirPath; // dirname containing this efi (contains just the dir, not the device path)
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* m_SelfSimpleVolume {}; // Volume containing this efi.
EFI_FILE* m_SelfVolumeRootDir {}; // Root dir of the volume containing this efi.
// bool m_OemDirExists;
// EFI_FILE *m_OemDir;
XStringW m_efiFileName = {};
EFI_DEVICE_PATH* m_CloverDirFullDevicePath {}; // full path, including device, of the folder containing this efi.
EFI_FILE* m_CloverDir {}; // opened folder containing this efi
XStringW m_CloverDirFullPath {}; // full path of folder containing this efi.
bool m_ThemesDirExists;
EFI_FILE *m_ThemesDir;
bool m_ThemesDirExists {};
EFI_FILE *m_ThemesDir {};
EFI_STATUS _openDir(const XStringW& path, bool* b, EFI_FILE** efiDir);
EFI_STATUS _initialize();
public:
Self () : m_SelfImageHandle(NULL), m_SelfLoadedImage(NULL), m_SelfDevicePath(NULL), m_SelfDevicePathAsXStringW(),
m_SelfSimpleVolume(NULL), m_SelfVolumeRootDir(NULL),
m_CloverDirFullDevicePath(NULL), m_CloverDir(NULL), m_CloverDirFullPath()/*, m_CloverDirPath()*/, m_ThemesDirExists(false), m_ThemesDir(0) {};
Self () {};
Self(const Self&) = delete;
Self& operator = (const Self&) = delete;
@ -77,10 +77,6 @@ public:
const EFI_DEVICE_PATH& getCloverDirFullDevicePath() { checkInitialized(); return *m_CloverDirFullDevicePath; }
const EFI_FILE& getCloverDir() { checkInitialized(); return *m_CloverDir; }
const XStringW& getCloverDirFullPath() { checkInitialized(); return m_CloverDirFullPath; }
// const XStringW& getCloverDirPath() { checkInitialized(); return m_CloverDirPath; } // returns path containing this efi. Like \\EFI\\CLOVER
// bool oemDirExists() { checkInitialized(); return m_OemDirExists; }
// const EFI_FILE& getOemDir() { checkInitialized(); return *m_OemDir; } // Oem dir name under SelfDir. Like "OEM\\MyBoard"
bool themesDirExists() { checkInitialized(); return m_ThemesDirExists; }
const EFI_FILE& getThemesDir() { checkInitialized(); return *m_ThemesDir; }