CloverBootloader/rEFIt_UEFI/Platform/Self.cpp
SergeySlice 76bf6321a6 release compilation should never panic on bad user input, use DEBUG for testing
Signed-off-by: SergeySlice <sergey.slice@gmail.com>
2021-02-21 16:49:09 +03:00

150 lines
4.8 KiB
C++

/*
* Self.cpp
*
* Created on: Sep 28, 2020
* Author: jief
*/
#include "Self.h"
#include <Platform.h>
#include "../refit/lib.h"
#ifndef DEBUG_ALL
#define DEBUG_SELF 1
#else
#define DEBUG_SELF DEBUG_ALL
#endif
#if DEBUG_SELF == 0
#define DBG(...)
#else
#define DBG(...) DebugLog(DEBUG_SELF, __VA_ARGS__)
#endif
Self self;
constexpr const LStringW THEMES_DIRNAME(L"Themes");
EFI_STATUS Self::_openDir(const XStringW& path, bool* b, EFI_FILE** efiDir)
{
EFI_STATUS Status;
Status = m_CloverDir->Open(m_CloverDir, efiDir, path.wc_str(), EFI_FILE_MODE_READ, 0);
if ( EFI_ERROR(Status) ) {
DBG("Error when opening dir '%ls\\%ls' : %s\n", m_CloverDirFullPath.wc_str(), path.wc_str(), efiStrError(Status));
*efiDir = NULL;
*b = false;
}else{
*b = true;
}
return Status;
}
EFI_STATUS Self::_initialize()
{
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
#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_efiFileName = m_CloverDirFullPath.basename();
// History : if this Clover was started as BootX64.efi, redirect to /EFI/CLOVER
if ( m_CloverDirFullPath.equalIC("\\EFI\\Boot\\BootX64.efi") ) {
m_CloverDirFullPath.takeValueFrom("\\EFI\\CLOVER\\CloverX64.efi");
}
#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()");
_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)
{
m_SelfImageHandle = ImageHandle;
return _initialize();
}
EFI_STATUS Self::reInitialize()
{
closeHandle();
return _initialize();
}
void Self::closeHandle(void)
{
// called before running external programs to close open file handles
if (m_CloverDir != NULL) {
m_CloverDir->Close(m_CloverDir);
m_CloverDir = NULL;
}
if (m_SelfVolumeRootDir != NULL) {
m_SelfVolumeRootDir->Close(m_SelfVolumeRootDir);
m_SelfVolumeRootDir = NULL;
}
}