Hide dead installer prebooter.

Do not hide installer if there is a main partition.
This commit is contained in:
jief666 2021-02-04 17:04:31 +03:00
parent 3142593e38
commit 333b6ce1ca
21 changed files with 450 additions and 306 deletions

View File

@ -552,8 +552,10 @@ ScanSections64 (
// the alignment field is valid
if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
// if the section address is aligned we must align PE/COFF
UINT32 mCoffOffsetNew = (UINT32) ((shdr->sh_addr + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
/*debug*/NormalMsg("Text section %d %s size=%llu mCoffOffset=%d(0x%x)", i, sectName, shdr->sh_size, mCoffOffset, mCoffOffset);
printf("Section %d %s mCoffOffset=%d(0x%x) mCoffOffsetNew=%d(0x%x) diff=%d(0x%x)\n", i, sectName, mCoffOffset, mCoffOffset, mCoffOffsetNew, mCoffOffsetNew, mCoffOffsetNew-mCoffOffset, mCoffOffsetNew-mCoffOffset);
mCoffOffset=mCoffOffsetNew;
} else {
Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
}
@ -606,8 +608,10 @@ ScanSections64 (
// the alignment field is valid
if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {
// if the section address is aligned we must align PE/COFF
UINT32 mCoffOffsetNew = (UINT32) ((shdr->sh_addr + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));
/*debug*/NormalMsg("Data section %d %s size=%llu mCoffOffset=%d(0x%x)", i, sectName, shdr->sh_size, mCoffOffset, mCoffOffset);
printf("Section %d %s mCoffOffset=%d(0x%x) mCoffOffsetNew=%d(0x%x) diff=%d(0x%x)\n", i, sectName, mCoffOffset, mCoffOffset, mCoffOffsetNew, mCoffOffsetNew, mCoffOffsetNew-mCoffOffset, mCoffOffsetNew-mCoffOffset);
mCoffOffset=mCoffOffsetNew;
} else {
Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");
}

View File

@ -352,6 +352,12 @@
9AC7809A24178F02005CDD5C /* menu_items.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC7809924178F02005CDD5C /* menu_items.cpp */; };
9AC780B32417EE4B005CDD5C /* global_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC780B22417EE4A005CDD5C /* global_test.cpp */; };
9AC780B52417EE53005CDD5C /* global_test.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC780B42417EE53005CDD5C /* global_test.h */; };
9AD1F9B425CBBD3D00EC1BB3 /* Volumes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD1F9B225CBBD3C00EC1BB3 /* Volumes.h */; };
9AD1F9B525CBBD3D00EC1BB3 /* Volumes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD1F9B225CBBD3C00EC1BB3 /* Volumes.h */; };
9AD1F9B625CBBD3D00EC1BB3 /* Volumes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD1F9B225CBBD3C00EC1BB3 /* Volumes.h */; };
9AD1F9B725CBBD3D00EC1BB3 /* Volumes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AD1F9B325CBBD3C00EC1BB3 /* Volumes.cpp */; };
9AD1F9B825CBBD3D00EC1BB3 /* Volumes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AD1F9B325CBBD3C00EC1BB3 /* Volumes.cpp */; };
9AD1F9B925CBBD3D00EC1BB3 /* Volumes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AD1F9B325CBBD3C00EC1BB3 /* Volumes.cpp */; };
9AD469502452B5A600D6D0DB /* Efi.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD4694C2452B5A600D6D0DB /* Efi.h */; };
9AD469512452B5A600D6D0DB /* Devices.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD4694D2452B5A600D6D0DB /* Devices.h */; };
9AD469522452B5A600D6D0DB /* Pci.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AD4694E2452B5A600D6D0DB /* Pci.h */; };
@ -944,6 +950,8 @@
9AC7809924178F02005CDD5C /* menu_items.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu_items.cpp; sourceTree = "<group>"; };
9AC780B22417EE4A005CDD5C /* global_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = global_test.cpp; sourceTree = "<group>"; };
9AC780B42417EE53005CDD5C /* global_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global_test.h; sourceTree = "<group>"; };
9AD1F9B225CBBD3C00EC1BB3 /* Volumes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Volumes.h; sourceTree = "<group>"; };
9AD1F9B325CBBD3C00EC1BB3 /* Volumes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Volumes.cpp; sourceTree = "<group>"; };
9AD4694C2452B5A600D6D0DB /* Efi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Efi.h; sourceTree = "<group>"; };
9AD4694D2452B5A600D6D0DB /* Devices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Devices.h; sourceTree = "<group>"; };
9AD4694E2452B5A600D6D0DB /* Pci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pci.h; sourceTree = "<group>"; };
@ -1147,6 +1155,8 @@
9AC77F1624176C04005CDD5C /* Platform */ = {
isa = PBXGroup;
children = (
9AD1F9B325CBBD3C00EC1BB3 /* Volumes.cpp */,
9AD1F9B225CBBD3C00EC1BB3 /* Volumes.h */,
9AC77F2024176C04005CDD5C /* AcpiPatcher.cpp */,
9A105B4424483AE20006DE06 /* AcpiPatcher.h */,
9AC77F2324176C04005CDD5C /* AmlGenerator.cpp */,
@ -1439,6 +1449,7 @@
9AC44EDD253AE78C00326488 /* MemoryOperation.h in Headers */,
9AC7805924176C04005CDD5C /* nanosvg.h in Headers */,
9AF41566242BAD5600D2644C /* printf_lite-test-cpp_conf.h in Headers */,
9AD1F9B425CBBD3D00EC1BB3 /* Volumes.h in Headers */,
9A105B7624483AE40006DE06 /* stdint.h in Headers */,
9AC7806124176C04005CDD5C /* CloverDB.h in Headers */,
9AD469532452B5A600D6D0DB /* OneLinerMacros.h in Headers */,
@ -1571,6 +1582,7 @@
9AF415A0242CD75C00D2644C /* printlib-test-cpp_conf.h in Headers */,
9A36E5C324F5616F007A1107 /* TagFloat.h in Headers */,
9AF415A1242CD75C00D2644C /* XStringArray.h in Headers */,
9AD1F9B525CBBD3D00EC1BB3 /* Volumes.h in Headers */,
9A09863C2438A15400826276 /* shared_with_menu.h in Headers */,
9A4185B72439F29D00BEAFB8 /* LoadOptions_test.h in Headers */,
9AF415A3242CD75C00D2644C /* strcmp_test.h in Headers */,
@ -1672,6 +1684,7 @@
9AF4167D242CDA5800D2644C /* printlib-test-cpp_conf.h in Headers */,
9A36E5C424F5616F007A1107 /* TagFloat.h in Headers */,
9AF4167E242CDA5800D2644C /* XStringArray.h in Headers */,
9AD1F9B625CBBD3D00EC1BB3 /* Volumes.h in Headers */,
9A09863D2438A15400826276 /* shared_with_menu.h in Headers */,
9A4185B82439F29D00BEAFB8 /* LoadOptions_test.h in Headers */,
9AF41680242CDA5800D2644C /* strcmp_test.h in Headers */,
@ -1929,6 +1942,7 @@
9AC7800A24176C04005CDD5C /* StateGenerator.cpp in Sources */,
9AC7805C24176C04005CDD5C /* XImage.cpp in Sources */,
9A36E59224F5616F007A1107 /* TagBool.cpp in Sources */,
9AD1F9B725CBBD3D00EC1BB3 /* Volumes.cpp in Sources */,
9A014999244091B200B37399 /* printlib-test.cpp in Sources */,
9AC7802B24176C04005CDD5C /* platformdata.cpp in Sources */,
9AC7805724176C04005CDD5C /* XPointer.cpp in Sources */,
@ -2069,6 +2083,7 @@
9AF41616242CD75C00D2644C /* load_icns.cpp in Sources */,
9AF41617242CD75C00D2644C /* egemb_font.cpp in Sources */,
9A4F68622449D4CB004B2F7E /* APFS.cpp in Sources */,
9AD1F9B825CBBD3D00EC1BB3 /* Volumes.cpp in Sources */,
9AF41618242CD75C00D2644C /* securemenu.cpp in Sources */,
9AF41619242CD75C00D2644C /* text.cpp in Sources */,
9AF4161A242CD75C00D2644C /* AmlGenerator.cpp in Sources */,
@ -2191,6 +2206,7 @@
9AF416F3242CDA5800D2644C /* load_icns.cpp in Sources */,
9AF416F4242CDA5800D2644C /* egemb_font.cpp in Sources */,
9A4F68652449D533004B2F7E /* APFS.cpp in Sources */,
9AD1F9B925CBBD3D00EC1BB3 /* Volumes.cpp in Sources */,
9AF416F5242CDA5800D2644C /* securemenu.cpp in Sources */,
9AF416F6242CDA5800D2644C /* text.cpp in Sources */,
9AF416F7242CDA5800D2644C /* AmlGenerator.cpp in Sources */,

View File

@ -14,6 +14,7 @@
#include "APFS.h"
#include "Nvram.h"
#include "BootOptions.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_HIB 1
@ -397,13 +398,13 @@ GetSleepImageLocation(IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume,
if (EFI_ERROR(Status)) {
Status = egLoadFile(Volume->RootDir, PrefName2, &PrefBuffer, &PrefBufferLen);
if (!EFI_ERROR(Status)) {
DBG(" read prefs %ls status=%s\n", PrefName2, efiStrError(Status));
DBG(" read prefs %ls status=%s\n", PrefName2, efiStrError(Status));
}
} else {
DBG(" read prefs %ls status=%s\n", PrefName3.wc_str(), efiStrError(Status));
DBG(" read prefs %ls status=%s\n", PrefName3.wc_str(), efiStrError(Status));
}
} else {
DBG(" read prefs %ls status=%s\n", PrefName, efiStrError(Status));
DBG(" read prefs %ls status=%s\n", PrefName, efiStrError(Status));
}
}
@ -462,7 +463,7 @@ GetSleepImageLocation(IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume,
if (SleepImageName.isEmpty()) {
SleepImageName = SWPrintf("\\private\\var\\vm\\sleepimage");
DBG(" using default sleep image name = %ls\n", SleepImageName.wc_str());
DBG(" using default sleep image name = %ls\n", SleepImageName.wc_str());
}
if (PrefBuffer) {
FreePool(PrefBuffer); //allocated by egLoadFile
@ -495,7 +496,7 @@ GetSleepImagePosition (IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume)
}
if (Volume->WholeDiskBlockIO == NULL) {
DBG(" no disk BlockIo\n");
DBG(" no disk BlockIo\n");
return 0;
}
@ -505,7 +506,7 @@ GetSleepImagePosition (IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume)
// Update caller's SleepImageVolume when requested
GetSleepImageLocation(Volume, SleepImageVolume, &ImageName);
}
DBG(" returning previously calculated offset: %llx\n", Volume->SleepImageOffset);
DBG(" returning previously calculated offset: %llx\n", Volume->SleepImageOffset);
return Volume->SleepImageOffset;
}
@ -516,7 +517,7 @@ GetSleepImagePosition (IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume)
// Open sleepimage
Status = ImageVolume->RootDir->Open(ImageVolume->RootDir, &File, ImageName.wc_str(), EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status)) {
DBG(" sleepimage not found -> %s\n", efiStrError(Status));
DBG(" cannot open sleepimage -> %s\n", efiStrError(Status));
return 0;
}
}
@ -525,14 +526,14 @@ GetSleepImagePosition (IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume)
BufferSize = 512;
Buffer = (__typeof__(Buffer))AllocatePool(BufferSize);
if (Buffer == NULL) {
DBG(" could not allocate buffer for sleepimage\n");
DBG(" could not allocate buffer for sleepimage\n");
return 0;
}
// DBG(" Reading first %d bytes of sleepimage ...\n", BufferSize);
if (!ImageVolume->WholeDiskBlockIO) {
DBG(" can not get whole disk\n");
DBG(" can not get whole disk\n");
if (Buffer) {
FreePool(Buffer);
}
@ -563,16 +564,16 @@ GetSleepImagePosition (IN REFIT_VOLUME *Volume, REFIT_VOLUME **SleepImageVolume)
}
if (EFI_ERROR(Status)) {
DBG(" can not read sleepimage -> %s\n", efiStrError(Status));
DBG(" can not read sleepimage -> %s\n", efiStrError(Status));
return 0;
}
// We store SleepImageOffset, in case our BlockIoRead does not execute again on next read due to driver caching.
if (gSleepImageOffset != 0) {
DBG(" sleepimage offset acquired successfully: %llx\n", gSleepImageOffset);
DBG(" sleepimage offset acquired successfully: %llx\n", gSleepImageOffset);
ImageVolume->SleepImageOffset = gSleepImageOffset;
} else {
DBG(" sleepimage offset could not be acquired\n");
DBG(" sleepimage offset could not be acquired\n");
}
if (SleepImageVolume != NULL) {
@ -658,7 +659,7 @@ IsSleepImageValidBySignature (IN REFIT_VOLUME *Volume)
// We'll have to detect offset here also in case driver caches
// some data and stops us from detecting offset later.
// So, make first call to GetSleepImagePosition() now.
DBG(" Check sleep image 'by signature':\n");
DBG(" Check sleep image 'by signature':\n");
return (GetSleepImagePosition (Volume, NULL) != 0);
}
@ -815,21 +816,21 @@ IsOsxHibernated (IN LOADER_ENTRY *Entry)
return FALSE;
}
DBG(" Check if volume Is Hibernated:\n");
DBG(" Check if volume Is Hibernated:\n");
if (!gSettings.Boot.StrictHibernate) {
// CloverEFI or UEFI with EmuVariable
if (IsSleepImageValidBySignature(Volume)) {
if ((gSleepTime == 0) || IsSleepImageValidBySleepTime(Volume)) {
DBG(" hibernated: yes\n");
DBG(" hibernated: yes\n");
ret = TRUE;
} else {
DBG(" hibernated: no - time\n");
DBG(" hibernated: no - time\n");
return FALSE;
}
// IsHibernate = TRUE;
} else {
DBG(" hibernated: no - sign\n");
DBG(" hibernated: no - sign\n");
return FALSE; //test
}
}

View File

@ -11,6 +11,7 @@
#include "BootOptions.h"
#include "guid.h"
#include "../gui/REFIT_MENU_SCREEN.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_SET 1

View File

@ -38,6 +38,7 @@
#include "Net.h"
#include "MacOsVersion.h"
#include "../include/OsType.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
@ -1836,6 +1837,7 @@ FillinCustomEntry (
(Prop->getString()->stringValue().equalIC("Always"))) {
Entry->Flags = OSFLAG_SET(Entry->Flags, OSFLAG_DISABLED);
} else if (IsPropertyNotNullAndTrue(Prop)) {
DBG(" hiding entry because Hidden flag is YES\n");
Entry->Hidden = true;
} else {
Entry->Hidden = false;
@ -2086,6 +2088,7 @@ FillingCustomLegacy (
(Prop->getString()->stringValue().equalIC("Always"))) {
Entry->Flags = OSFLAG_SET(Entry->Flags, OSFLAG_DISABLED);
} else if (IsPropertyNotNullAndTrue(Prop)) {
DBG(" hiding entry because Hidden flag is YES\n");
Entry->Hidden = true;
} else {
Entry->Hidden = false;
@ -2184,6 +2187,7 @@ FillingCustomTool (IN OUT CUSTOM_TOOL_ENTRY *Entry, const TagDict* DictPointer)
(Prop->getString()->stringValue().equalIC("Always"))) {
Entry->Flags = OSFLAG_SET(Entry->Flags, OSFLAG_DISABLED);
} else if (IsPropertyNotNullAndTrue(Prop)) {
DBG(" hiding entry because Hidden flag is YES\n");
Entry->Hidden = true;
} else {
Entry->Hidden = false;
@ -6283,6 +6287,84 @@ static CONST CHAR8 *SearchString(
return NULL;
}
*/
XString8 GetAuthRootDmg(const EFI_FILE& dir, const XStringW& path)
{
XString8 returnValue;
XStringW plist = SWPrintf("%ls\\com.apple.Boot.plist", path.wc_str());
if ( !FileExists(dir, plist) ) return NullXString8;
CHAR8* PlistBuffer = NULL;
UINTN PlistLen;
TagDict* Dict = NULL;
const TagStruct* Prop = NULL;
EFI_STATUS Status = egLoadFile(&dir, plist.wc_str(), (UINT8 **)&PlistBuffer, &PlistLen);
if (!EFI_ERROR(Status) && PlistBuffer != NULL && ParseXML(PlistBuffer, &Dict, 0) == EFI_SUCCESS)
{
Prop = Dict->propertyForKey("Kernel Flags");
if ( Prop != NULL ) {
if ( !Prop->isString() ) {
MsgLog("ATTENTION : Kernel Flags not string in ProductVersion\n");
}else{
if( Prop->getString()->stringValue().notEmpty() ) {
const XString8& kernelFlags = Prop->getString()->stringValue();
size_t idx = kernelFlags.indexOf("auth-root-dmg");
if ( idx == MAX_XSIZE ) return NullXString8;
idx += strlen("auth-root-dmg");
while ( idx < kernelFlags.length() && IS_BLANK(kernelFlags[idx]) ) ++idx;
if ( kernelFlags[idx] == '=' ) ++idx;
else return NullXString8;
while ( idx < kernelFlags.length() && IS_BLANK(kernelFlags[idx]) ) ++idx;
if ( kernelFlags.equalAtIC(idx, "file://"_XS8) ) idx += strlen("file://");
size_t idxEnd = idx;
while ( idxEnd < kernelFlags.length() && !IS_BLANK(kernelFlags[idxEnd]) ) ++idxEnd;
returnValue = kernelFlags.subString(idx, idxEnd - idx);
}
}
}
}
if ( PlistBuffer ) FreePool(PlistBuffer);
return returnValue;
}
MacOsVersion GetMacOSVersionFromFolder(const EFI_FILE& dir, const XStringW& path)
{
MacOsVersion macOSVersion;
XStringW plist = SWPrintf("%ls\\SystemVersion.plist", path.wc_str());
if ( !FileExists(dir, plist) ) {
plist = SWPrintf("%ls\\ServerVersion.plist", path.wc_str());
if ( !FileExists(dir, plist) ) {
plist.setEmpty();
}
}
if ( plist.notEmpty() ) { // found macOS System
CHAR8* PlistBuffer = NULL;
UINTN PlistLen;
TagDict* Dict = NULL;
const TagStruct* Prop = NULL;
EFI_STATUS Status = egLoadFile(&dir, plist.wc_str(), (UINT8 **)&PlistBuffer, &PlistLen);
if (!EFI_ERROR(Status) && PlistBuffer != NULL && ParseXML(PlistBuffer, &Dict, 0) == EFI_SUCCESS) {
Prop = Dict->propertyForKey("ProductVersion");
if ( Prop != NULL ) {
if ( !Prop->isString() ) {
MsgLog("ATTENTION : property not string in ProductVersion\n");
}else{
if( Prop->getString()->stringValue().notEmpty() ) {
macOSVersion = Prop->getString()->stringValue();
}
}
}
}
if ( PlistBuffer ) FreePool(PlistBuffer);
}
return macOSVersion;
}
MacOsVersion GetOSVersion(int LoaderType, const XStringW& APFSTargetUUID, const REFIT_VOLUME* Volume, XString8* BuildVersionPtr)
{
XString8 OSVersion;

View File

@ -943,7 +943,9 @@ SetDevices (
void
SetBootCurrent(REFIT_MENU_ITEM_BOOTNUM *LoadedEntry);
XString8 GetAuthRootDmg(const EFI_FILE& dir, const XStringW& path);
MacOsVersion GetMacOSVersionFromFolder(const EFI_FILE& dir, const XStringW& path);
MacOsVersion GetOSVersion(int LoaderType, const XStringW& APFSTargetUUID, const REFIT_VOLUME* Volume, XString8* BuildVersionPtr);
inline MacOsVersion GetOSVersion (IN LOADER_ENTRY *Entry) { return GetOSVersion(Entry->LoaderType, Entry->APFSTargetUUID, Entry->Volume, &Entry->BuildVersion); };

View File

@ -32,6 +32,7 @@
#define IS_ALFA(x) (((x >= 'a') && (x <='z')) || ((x >= 'A') && (x <='Z')))
#define IS_ASCII(x) ((x>=0x20) && (x<=0x7F))
#define IS_PUNCT(x) ((x == '.') || (x == '-'))
#define IS_BLANK(x) ((x == ' ') || (x == '\t'))
inline bool isPathSeparator(char32_t c) { return c == '/' || c == '\\'; }

View File

@ -0,0 +1,52 @@
/*
* Volumes.cpp
*
* Created on: Feb 4, 2021
* Author: jief
*/
#include "Volumes.h"
REFIT_VOLUME *SelfVolume = NULL;
VolumesArrayClass Volumes;
//REFIT_VOLUME* VolumesArrayClass::getApfsPartitionWithUUID(const XString8& ApfsContainerUUID, const XString8& APFSTargetUUID)
//{
//}
REFIT_VOLUME* VolumesArrayClass::getVolumeWithApfsContainerUUIDAndFileSystemUUID(const XString8& ApfsContainerUUID, const XString8& ApfsFileSystemUUID)
{
for (size_t VolumeIndex = 0; VolumeIndex < Volumes.size(); VolumeIndex++) {
REFIT_VOLUME* Volume = &Volumes[VolumeIndex];
//DBG("idx=%zu name %ls uuid=%s \n", VolumeIndex2, Volume2->VolName.wc_str(), Volume2->ApfsFileSystemUUID.c_str());
if ( Volume->ApfsContainerUUID == ApfsContainerUUID ) {
if ( Volume->ApfsFileSystemUUID == ApfsFileSystemUUID ) {
return Volume;
}
}
}
return NULL;
}
REFIT_VOLUME* VolumesArrayClass::getVolumeWithApfsContainerUUIDAndRole(const XString8& ApfsContainerUUID, APPLE_APFS_VOLUME_ROLE roleMask)
{
REFIT_VOLUME* targetVolume = NULL;
for (size_t VolumeIndex = 0; VolumeIndex < Volumes.size(); VolumeIndex++) {
REFIT_VOLUME* Volume = &Volumes[VolumeIndex];
//DBG("idx=%zu name %ls uuid=%s \n", VolumeIndex2, Volume2->VolName.wc_str(), Volume2->ApfsFileSystemUUID.c_str());
if ( Volume->ApfsContainerUUID == ApfsContainerUUID ) {
if ( (Volume->ApfsRole & roleMask) != 0 ) {
if ( !targetVolume ) {
targetVolume = Volume;
}else{
// More than one partition with this role in container.
return NULL;
}
}
}
}
return targetVolume;
}

View File

@ -0,0 +1,81 @@
/*
* Volumes.h
*
* Created on: Feb 4, 2021
* Author: jief
*/
#ifndef PLATFORM_VOLUMES_H_
#define PLATFORM_VOLUMES_H_
#include "../include/Efi.h"
#include "../cpp_foundation/XString.h"
#include "../libeg/libeg.h"
class REFIT_VOLUME {
public:
EFI_DEVICE_PATH *DevicePath;
EFI_HANDLE DeviceHandle;
EFI_FILE *RootDir;
XStringW DevicePathString;
XStringW VolName; // comes from EfiLibFileSystemInfo, EfiLibFileSystemVolumeLabelInfo, "EFI" if gEfiPartTypeSystemPartGuid or "Unknown HD"
XStringW VolLabel; // comes from \\.VolumeLabel.txt, or empty.
UINT8 DiskKind;
LEGACY_OS *LegacyOS;
BOOLEAN Hidden;
UINT8 BootType;
BOOLEAN IsAppleLegacy;
BOOLEAN HasBootCode;
BOOLEAN IsMbrPartition;
UINTN MbrPartitionIndex;
EFI_BLOCK_IO *BlockIO;
UINT64 BlockIOOffset;
EFI_BLOCK_IO *WholeDiskBlockIO;
EFI_DEVICE_PATH *WholeDiskDevicePath;
EFI_HANDLE WholeDiskDeviceHandle;
MBR_PARTITION_INFO *MbrPartitionTable;
UINT32 DriveCRC32;
EFI_GUID RootUUID; //for recovery it is UUID of parent partition
UINT64 SleepImageOffset;
XStringW osxVolumeName = NullXStringW; // comes from \\System\\Library\\CoreServices\\.disk_label.contentDetails, or empty.
XString8 ApfsFileSystemUUID; // apfs file system UUID of that partition. It's not the UUID of subfolder like in Preboot.
XString8 ApfsContainerUUID = NullXString8;
APPLE_APFS_VOLUME_ROLE ApfsRole = 0;
XString8Array ApfsTargetUUIDArray; // this is the array of folders that are named as UUID
REFIT_VOLUME() : DevicePath(0), DeviceHandle(0), RootDir(0), DevicePathString(), VolName(), VolLabel(), DiskKind(0), LegacyOS(0), Hidden(0), BootType(0), IsAppleLegacy(0), HasBootCode(0),
IsMbrPartition(0), MbrPartitionIndex(0), BlockIO(0), BlockIOOffset(0), WholeDiskBlockIO(0), WholeDiskDevicePath(0), WholeDiskDeviceHandle(0),
MbrPartitionTable(0), DriveCRC32(0), RootUUID({0,0,0,{0,0,0,0,0,0,0,0}}), SleepImageOffset(0), ApfsFileSystemUUID(), ApfsTargetUUIDArray()
{}
REFIT_VOLUME(const REFIT_VOLUME& other) = delete; // Can be defined if needed
const REFIT_VOLUME& operator = ( const REFIT_VOLUME & ) = delete; // Can be defined if needed
~REFIT_VOLUME() {}
const XStringW getVolLabelOrOSXVolumeNameOrVolName() {
if ( VolLabel.notEmpty() ) return VolLabel;
if ( osxVolumeName.notEmpty() ) return osxVolumeName;
return VolName;
}
};
class VolumesArrayClass : public XObjArray<REFIT_VOLUME>
{
public:
// REFIT_VOLUME* getApfsPartitionWithUUID(const XString8& ApfsContainerUUID, const XString8& APFSTargetUUID);
REFIT_VOLUME* getVolumeWithApfsContainerUUIDAndFileSystemUUID(const XString8& ApfsContainerUUID, const XString8& ApfsFileSystemUUID);
/*
* Return : NULL if not found OR more than one partition with this role is found in this container
*/
REFIT_VOLUME* getVolumeWithApfsContainerUUIDAndRole(const XString8& ApfsContainerUUID, APPLE_APFS_VOLUME_ROLE roleMask);
};
extern VolumesArrayClass Volumes;
extern REFIT_VOLUME *SelfVolume;
#endif /* PLATFORM_VOLUMES_H_ */

View File

@ -172,7 +172,7 @@ public:
const wchar_t* wc_str() const { return m_data; }
protected:
static void transmitSPrintf(const wchar_t* buf, unsigned int nbchar, void* context)
static void transmitSWPrintf(const wchar_t* buf, unsigned int nbchar, void* context)
{
((XStringW*)(context))->strncat(buf, nbchar);
}
@ -180,7 +180,7 @@ public:
void vSWPrintf(const char* format, va_list va)
{
setEmpty();
vwprintf_with_callback(format, va, transmitSPrintf, this);
vwprintf_with_callback(format, va, transmitSWPrintf, this);
}
void SWPrintf(const char* format, ...) __attribute__((__format__(__printf__, 2, 3)))
{
@ -190,6 +190,18 @@ public:
vSWPrintf(format, va);
va_end(va);
}
void vSWCatf(const char* format, va_list va)
{
vwprintf_with_callback(format, va, transmitSWPrintf, this);
}
void SWCatf(const char* format, ...) __attribute__((__format__(__printf__, 2, 3)))
{
va_list va;
va_start (va, format);
vSWCatf(format, va);
va_end(va);
}
};

View File

@ -468,33 +468,6 @@ public:
return ThisXStringClass();
}
// void insert(const __String<T, ThisXStringClass>& Str, size_t pos);
//{
// if ( pos < size() ) {
// CheckSize(size()+Str.size());
// memmove(_data(pos + Str.size()), data(pos), (size()-pos)*sizeof(T));
// memmove(_data(pos), Str.data(), Str.size()*sizeof(T));
// setLength(size()+Str.size());
// }else{
// StrCat(Str);
// }
//}
// void ToLower(bool FirstCharIsCap = false);
// bool IsLetters() const;
// bool IsLettersNoAccent() const;
// bool IsDigits() const;
//{
// const T *p;
//
// p = data();
// if ( !*p ) return false;
// for ( ; *p ; p+=1 ) {
// if ( *p < '0' ) return false;
// if ( *p > '9' ) return false;
// }
// return true;
//}
// bool IsDigits(size_t pos, size_t count) const;
//{
// const T *p;
@ -513,30 +486,6 @@ public:
// if ( *p > '9' ) return false;
// }
// return true;
//}
// void Replace(T c1, T c2)
// {
// T* p;
//
// p = s();
// while ( *p ) {
// if ( *p == c1 ) *p = c2;
// p += 1;
// }
// }
// __String SubStringReplace(T c1, T c2);
//{
// T* p;
// __String Result;
//
// p = s();
// while ( *p ) {
// if ( *p == c1 ) Result += c2;
// else Result += *p;
// p++;
// }
// return Result;
//}
//---------------------------------------------------------------------
@ -564,6 +513,14 @@ public:
// bool SubStringEqual(size_t Pos, const T* S) const { return (memcmp(data(Pos), S, wcslen(S)) == 0); }
template<typename IntegralType, typename O, class OtherXStringClass>
bool equalAtIC(IntegralType pos, const __String<O, OtherXStringClass>& S) const
{
if ( pos < 0 ) panic("XString::equalAtIC -> i < 0");
if ( (unsigned_type(IntegralType))pos > length() - S.length() ) return false;
return XStringAbstract__ncompare(m_data + (unsigned_type(IntegralType))pos, S.s(), S.length(), true) == 0;
}
public:
// == operator
template<typename O, class OtherXStringClass>
@ -611,7 +568,7 @@ public:
};
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LString xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
template<class T, class ThisXStringClass>
class LString : public __String<T, ThisXStringClass>
@ -681,6 +638,67 @@ template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && is___String(T2))> { typedef typename T2::xs_t type; };
/* ------------ get_char_ptr(x) --------------*/
template<typename T, typename Tdummy=void>
struct _xstringarray__char_type;
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<typename T>
struct _xstringarray__char_type<T*, enable_if_t(is_char(T))>
{
static const T* getCharPtr(T* t) { return t; }
};
//template<typename T>
//struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))>
//{
// static const T* getCharPtr(const T* t) { return t; }
//};
template<typename T>
struct _xstringarray__char_type<const T[]>
{
static const T* getCharPtr(T* t) { return t; }
};
template<typename T, size_t _Np>
struct _xstringarray__char_type<T[_Np]>
{
static const T* getCharPtr(const T* t) { return t; }
};
#ifdef _MSC_VER
// I don't know why it's needed with VS.
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___LString(T))>
{
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<>
struct _xstringarray__char_type<XString8, void>
{
static const typename XString8::char_t* getCharPtr(const XString8& t) { return t.s(); }
};
template<>
struct _xstringarray__char_type<XStringW, void>
{
static const typename XStringW::char_t* getCharPtr(const XStringW& t) { return t.s(); }
};
#endif
#define get_char_ptr(x) _xstringarray__char_type<typeof(x)>::getCharPtr(x)
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

View File

@ -16,63 +16,6 @@
template<typename T, typename Tdummy=void>
struct _xstringarray__char_type;
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<typename T>
struct _xstringarray__char_type<T*, enable_if_t(is_char(T))>
{
static const T* getCharPtr(T* t) { return t; }
};
//template<typename T>
//struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))>
//{
// static const T* getCharPtr(const T* t) { return t; }
//};
template<typename T>
struct _xstringarray__char_type<const T[]>
{
static const T* getCharPtr(T* t) { return t; }
};
template<typename T, size_t _Np>
struct _xstringarray__char_type<T[_Np]>
{
static const T* getCharPtr(const T* t) { return t; }
};
#ifdef _MSC_VER
// I don't know why it's needed with VS.
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___LString(T))>
{
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<>
struct _xstringarray__char_type<XString8, void>
{
static const typename XString8::char_t* getCharPtr(const XString8& t) { return t.s(); }
};
template<>
struct _xstringarray__char_type<XStringW, void>
{
static const typename XStringW::char_t* getCharPtr(const XStringW& t) { return t.s(); }
};
#endif
//#define XStringArraySuper XObjArray<XStringClass>

View File

@ -37,6 +37,7 @@
#include "../refit/screen.h"
#include "../refit/menu.h"
#include "../gui/REFIT_MENU_SCREEN.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_SCAN_LEGACY 1

View File

@ -49,6 +49,7 @@
#include "Self.h"
#include "../include/OsType.h"
#include "../Platform/BootOptions.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_SCAN_LOADER 1
@ -464,7 +465,7 @@ STATIC LOADER_ENTRY *CreateLoaderEntry(IN CONST XStringW& LoaderPath,
// CONST CHAR16 *OSIconName = NULL;
CHAR16 ShortcutLetter;
LOADER_ENTRY *Entry;
CONST CHAR8 *indent = " ";
CONST CHAR8 *indent = " ";
// Check parameters are valid
if ((LoaderPath.isEmpty()) || (Volume == NULL)) {
@ -484,7 +485,7 @@ STATIC LOADER_ENTRY *CreateLoaderEntry(IN CONST XStringW& LoaderPath,
// Ignore this loader if it's self path
XStringW selfDevicePathAsXStringW = FileDevicePathToXStringW(&self.getSelfDevicePath());
if ( selfDevicePathAsXStringW == LoaderDevicePathString ) {
DBG("%s skipped because path `%ls` is self path!\n", indent, LoaderDevicePathString.wc_str());
DBG("%sskipped because path `%ls` is self path!\n", indent, LoaderDevicePathString.wc_str());
return NULL;
}
// DBG("OSType =%d\n", OSType);
@ -502,7 +503,7 @@ STATIC LOADER_ENTRY *CreateLoaderEntry(IN CONST XStringW& LoaderPath,
// Only want loaders
if (MainEntry.getLOADER_ENTRY()) {
if (StriCmp(MainEntry.getLOADER_ENTRY()->DevicePathString.wc_str(), LoaderDevicePathString.wc_str()) == 0) {
DBG("%s skipped because path `%ls` already exists for another entry!\n", indent, LoaderDevicePathString.wc_str());
DBG("%sskipped because path `%ls` already exists for another entry!\n", indent, LoaderDevicePathString.wc_str());
return NULL;
}
}
@ -570,7 +571,7 @@ STATIC LOADER_ENTRY *CreateLoaderEntry(IN CONST XStringW& LoaderPath,
DBG("\n");
} else {
// Custom entry match
DBG("%sSkipped because matching custom entry %llu!\n", indent, CustomIndex);
DBG("%sHidden because matching custom entry %llu!\n", indent, CustomIndex);
Entry->Hidden = true;
}
}
@ -623,7 +624,7 @@ if ( Entry->APFSTargetUUID.startWith("99999999") ) {
}
#endif
Entry->macOSVersion = GetOSVersion(Entry);
DBG(" OSVersion=%s \n", Entry->macOSVersion.asString().c_str());
DBG("%sOSVersion=%s \n", indent, Entry->macOSVersion.asString().c_str());
// detect specific loaders
XStringW OSIconName;
ShortcutLetter = 0;
@ -642,7 +643,7 @@ if ( Entry->APFSTargetUUID.startWith("99999999") ) {
*/
if (OSType == OSTYPE_OSX && IsOsxHibernated(Entry)) {
Entry->Flags = OSFLAG_SET(Entry->Flags, OSFLAG_HIBERNATED);
DBG(" =>set entry as hibernated\n");
DBG("%s =>set entry as hibernated\n", indent);
}
//always unset checkFakeSmc for installer
if (OSType == OSTYPE_OSX_INSTALLER){
@ -670,7 +671,7 @@ if ( Entry->APFSTargetUUID.startWith("99999999") ) {
Entry->LoaderType = OSType;
OSIconName = L"linux"_XSW;
if (Image == nullptr) {
DBG(" linux image not found\n");
DBG("%slinux image not found\n", indent);
OSIconName = LinuxIconNameFromPath(LoaderPath, Volume->RootDir); //something named "issue"
}
ShortcutLetter = 'L';
@ -744,7 +745,7 @@ if ( Entry->APFSTargetUUID.startWith("99999999") ) {
Entry->Image.Image.LoadIcns(Volume->RootDir, L"\\.VolumeIcon.icns", 128);
if (!Entry->Image.Image.isEmpty()) {
Entry->Image.setFilled();
DBG("using VolumeIcon.icns image from Volume\n");
DBG("%susing VolumeIcon.icns image from Volume\n", indent);
}
} else if (Image) {
Entry->Image = *Image; //copy image from temporary storage
@ -763,10 +764,10 @@ if ( Entry->APFSTargetUUID.startWith("99999999") ) {
if (ThemeX.HideBadges & HDBADGES_SHOW) {
if (ThemeX.HideBadges & HDBADGES_SWAP) {
Entry->BadgeImage.Image = XImage(Entry->DriveImage.Image, 0);
DBG(" Show badge as Drive.\n");
DBG("%sShow badge as Drive.\n", indent);
} else {
Entry->BadgeImage.Image = XImage(Entry->Image.Image, 0);
DBG(" Show badge as OSImage.\n");
DBG("%sShow badge as OSImage.\n", indent);
}
if (!Entry->BadgeImage.Image.isEmpty()) {
Entry->BadgeImage.setFilled();
@ -1024,7 +1025,7 @@ LOADER_ENTRY* AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XString8Arr
return NULL;
}
DBG(" AddLoaderEntry for Volume Name=%ls, idx=%zu\n", Volume->VolName.wc_str(), MainMenu.Entries.sizeIncludingHidden());
DBG(" AddLoaderEntry for Volume Name=%ls, idx=%zu\n", Volume->VolName.wc_str(), MainMenu.Entries.sizeIncludingHidden());
if (OSFLAG_ISSET(Flags, OSFLAG_DISABLED)) {
DBG(" skipped because entry is disabled\n");
return NULL;
@ -1042,15 +1043,6 @@ LOADER_ENTRY* AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XString8Arr
// }
// }
// }
if ( Volume->ApfsContainerUUID.notEmpty() ) DBG(" ApfsContainerUUID=%s\n", Volume->ApfsContainerUUID.c_str());
if ( Volume->ApfsFileSystemUUID.notEmpty() ) DBG(" ApfsFileSystemUUID=%s\n", Volume->ApfsFileSystemUUID.c_str());
if ( LoaderPath.length() >= 38 ) {
if ( isPathSeparator(LoaderPath[0]) && isPathSeparator(LoaderPath[37]) ) {
if ( IsValidGuidString(LoaderPath.data(1), 36) ) {
DBG(" APFSTargetUUID=%.*ls\n", 36, LoaderPath.data(1));
}
}
}
Entry = CreateLoaderEntry(LoaderPath, LoaderOptions, FullTitle, LoaderTitle, Volume, Image, NULL, OSType, Flags, 0, MenuBackgroundPixel, CUSTOM_BOOT_DISABLED, NULL, NULL, FALSE);
if (Entry != NULL) {
@ -1069,6 +1061,7 @@ LOADER_ENTRY* AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XString8Arr
}
}
if ( Volume->Hidden ) {
DBG(" hiding entry because volume is hidden: %ls\n", LoaderPath.s());
Entry->Hidden = true;
}else{
for (size_t HVi = 0; HVi < gSettings.HVHideStrings.size(); HVi++) {
@ -1081,7 +1074,7 @@ LOADER_ENTRY* AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XString8Arr
//TODO there is a problem that Entry->Flags is unique while InputItems are global ;(
// InputItems[69].IValue = Entry->Flags;
Entry->AddDefaultMenu();
DBG(" Menu entry added at index %zd\n", MainMenu.Entries.size());
DBG(" Menu entry added at index %zd\n", MainMenu.Entries.sizeIncludingHidden());
MainMenu.AddMenuEntry(Entry, true);
return Entry;
}
@ -1380,6 +1373,10 @@ void ScanLoader(void)
DBG("\n");
if ( Volume->ApfsContainerUUID.notEmpty() ) DBG(" ApfsContainerUUID=%s\n", Volume->ApfsContainerUUID.c_str());
if ( Volume->ApfsFileSystemUUID.notEmpty() ) DBG(" ApfsFileSystemUUID=%s\n", Volume->ApfsFileSystemUUID.c_str());
// check for Mac OS X Install Data
// 1st stage - createinstallmedia
if (FileExists(Volume->RootDir, L"\\.IABootFiles\\boot.efi")) {
@ -1446,40 +1443,12 @@ void ScanLoader(void)
} else if (FileExists(Volume->RootDir, L"\\System\\Library\\CoreServices\\NotificationCenter.app") && !FileExists(Volume->RootDir, L"\\System\\Library\\CoreServices\\Siri.app")) {
AddLoaderEntry(MACOSX_LOADER_PATH, NullXString8Array, L""_XSW, L"OS X"_XSW, Volume, NULL, OSTYPE_OSX, 0); // 10.8 - 10.11
} else {
XString8 OSVersion;
MacOsVersion macOSVersion;
if ( Volume->ApfsFileSystemUUID.notEmpty() && (Volume->ApfsRole & APPLE_APFS_VOLUME_ROLE_SYSTEM) != 0 )
{
XStringW plist = SWPrintf("\\System\\Library\\CoreServices\\SystemVersion.plist");
if ( !FileExists(Volume->RootDir, plist) ) {
plist = SWPrintf("\\System\\Library\\CoreServices\\ServerVersion.plist");
if ( !FileExists(Volume->RootDir, plist) ) {
plist.setEmpty();
}
}
if ( plist.notEmpty() ) { // found macOS System
CHAR8* PlistBuffer = NULL;
UINTN PlistLen;
TagDict* Dict = NULL;
const TagStruct* Prop = NULL;
EFI_STATUS Status = egLoadFile(Volume->RootDir, plist.wc_str(), (UINT8 **)&PlistBuffer, &PlistLen);
if (!EFI_ERROR(Status) && PlistBuffer != NULL && ParseXML(PlistBuffer, &Dict, 0) == EFI_SUCCESS) {
Prop = Dict->propertyForKey("ProductVersion");
if ( Prop != NULL ) {
if ( !Prop->isString() ) {
MsgLog("ATTENTION : property not string in ProductVersion\n");
}else{
if( Prop->getString()->stringValue().notEmpty() ) {
OSVersion = Prop->getString()->stringValue();
}
}
}
}
if ( PlistBuffer ) FreePool(PlistBuffer);
}
macOSVersion = GetMacOSVersionFromFolder(*Volume->RootDir, L"\\System\\Library\\CoreServices"_XSW);
}
if ( MacOsVersion(OSVersion) < MacOsVersion("11"_XS8) ) {
if ( macOSVersion < MacOsVersion("11"_XS8) ) {
AddLoaderEntry(MACOSX_LOADER_PATH, NullXString8Array, L""_XSW, L"macOS"_XSW, Volume, NULL, OSTYPE_OSX, 0); // 10.12+
}
}
@ -1541,12 +1510,18 @@ void ScanLoader(void)
// DBG("search for internal UEFI\n");
if (Volume->DiskKind == DISK_KIND_INTERNAL) {
LOADER_ENTRY* le = AddLoaderEntry(BOOT_LOADER_PATH, NullXString8Array, L""_XSW, L"UEFI internal"_XSW, Volume, NULL, OSTYPE_OTHER, 0);
le->Hidden = true;
if ( le ) {
DBG(" hiding entry because DiskKind is DISK_KIND_INTERNAL: %ls\n", le->LoaderPath.s());
le->Hidden = true;
}
}
// DBG("search for external UEFI\n");
if (Volume->DiskKind == DISK_KIND_EXTERNAL) {
LOADER_ENTRY* le = AddLoaderEntry(BOOT_LOADER_PATH, NullXString8Array, L""_XSW, L"UEFI external"_XSW, Volume, NULL, OSTYPE_OTHER, 0);
le->Hidden = true;
if ( le ) {
DBG(" hiding entry because DiskKind is DISK_KIND_EXTERNAL: %ls\n", le->LoaderPath.s());
le->Hidden = true;
}
}
//DBG("Volume->ApfsTargetUUIDArray.size()=%zd\n", Volume->ApfsTargetUUIDArray.size());
@ -1555,6 +1530,7 @@ void ScanLoader(void)
for (UINTN i = 0; i < Volume->ApfsTargetUUIDArray.size(); i++)
{
const XString8& ApfsTargetUUID = Volume->ApfsTargetUUIDArray[i];
DBG(" APFSTargetUUID=%s\n", ApfsTargetUUID.c_str());
XStringW FullTitle;
XStringW FullTitleRecovery;
XStringW FullTitleInstaller;
@ -1562,16 +1538,7 @@ void ScanLoader(void)
XStringW LoaderTitleInstaller;
// Find the "target" volume.
REFIT_VOLUME* targetVolume = NULL;
for (size_t VolumeIndex2 = 0; VolumeIndex2 < Volumes.size(); VolumeIndex2++) {
REFIT_VOLUME* Volume2 = &Volumes[VolumeIndex2];
//DBG("idx=%zu name %ls uuid=%s \n", VolumeIndex2, Volume2->VolName.wc_str(), Volume2->ApfsFileSystemUUID.c_str());
if ( Volume2->ApfsContainerUUID == Volume->ApfsContainerUUID ) {
if ( Volume2->ApfsFileSystemUUID == ApfsTargetUUID ) {
targetVolume = Volume2;
}
}
}
REFIT_VOLUME* targetVolume = Volumes.getVolumeWithApfsContainerUUIDAndFileSystemUUID(Volume->ApfsContainerUUID, ApfsTargetUUID);
// If targetVolume is found, and it's a data partition, try to find the system partition that goes with it.
//DBG("targetVolume=%d\n", targetVolume ? 1 : 0);
if ( targetVolume ) {
@ -1617,11 +1584,11 @@ void ScanLoader(void)
if ( FileExists(bootVolume->RootDir, targetNameFile) ) {
EFI_STATUS Status = egLoadFile(bootVolume->RootDir, targetNameFile.wc_str(), (UINT8 **)&fileBuffer, &fileLen);
if(!EFI_ERROR(Status)) {
FullTitle.SWPrintf("Boot Mac OS X from %.*s via %ls", (int)fileLen, fileBuffer, Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery for %.*s via %ls", (int)fileLen, fileBuffer, Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleInstaller.SWPrintf("Boot Mac OS X Install for %.*s via %ls", (int)fileLen, fileBuffer, Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitle.SWPrintf("Boot Mac OS X from %.*s", (int)fileLen, fileBuffer);
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery for %.*s", (int)fileLen, fileBuffer);
FullTitleInstaller.SWPrintf("Boot Mac OS X Install for %.*s", (int)fileLen, fileBuffer);
if ( fileLen < MAX_INT32 ) {
DBG(" contentDetails name:%.*s\n", (int)fileLen, fileBuffer);
DBG(" contentDetails name:%.*s\n", (int)fileLen, fileBuffer);
}
FreePool(fileBuffer);
}
@ -1630,27 +1597,60 @@ void ScanLoader(void)
}
if ( FullTitle.isEmpty() ) {
if ( targetVolume ) {
FullTitle.SWPrintf("Boot Mac OS X from %ls via %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str(), Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery for %ls via %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str(), Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleInstaller.SWPrintf("Boot Mac OS X Install for %ls via %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str(), Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitle.SWPrintf("Boot Mac OS X from %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery for %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleInstaller.SWPrintf("Boot Mac OS X Install for %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
}else{
FullTitle.SWPrintf("Boot Mac OS X via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitleInstaller.SWPrintf("Mac OS X Install via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
FullTitle.SWPrintf("Boot Mac OS X");
FullTitleRecovery.SWPrintf("Boot Mac OS X Recovery");
FullTitleInstaller.SWPrintf("Mac OS X Install");
}
}
/*MacOsVersion macOSVersion = GetMacOSVersionFromFolder(*Volume->RootDir, SWPrintf("\\%s\\System\\Library\\CoreServices", ApfsTargetUUID.c_str()));
if ( macOSVersion.notEmpty() && macOSVersion < MacOsVersion("11"_XS8) )*/ FullTitle.SWCatf(" via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
AddLoaderEntry(SWPrintf("\\%s\\System\\Library\\CoreServices\\boot.efi", ApfsTargetUUID.c_str()), NullXString8Array, FullTitle, LoaderTitle, Volume, NULL, OSTYPE_OSX, 0);
//Try to add Recovery APFS entry
/*macOSVersion = GetMacOSVersionFromFolder(*Volume->RootDir, SWPrintf("\\%s", ApfsTargetUUID.c_str()));
if ( macOSVersion.notEmpty() && macOSVersion < MacOsVersion("11"_XS8) )*/ FullTitleRecovery.SWCatf(" via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
if (!AddLoaderEntry(SWPrintf("\\%s\\boot.efi", Volume->ApfsTargetUUIDArray[i].c_str()), NullXString8Array, FullTitleRecovery, L""_XSW, Volume, NULL, OSTYPE_RECOVERY, 0)) {
//Try to add Recovery APFS entry as dmg
AddLoaderEntry(SWPrintf("\\%s\\BaseSystem.dmg", Volume->ApfsTargetUUIDArray[i].c_str()), NullXString8Array, FullTitleRecovery, L""_XSW, Volume, NULL, OSTYPE_RECOVERY, 0);
}
//Try to add macOS install entry
AddLoaderEntry(SWPrintf("\\%s\\com.apple.installer\\boot.efi", Volume->ApfsTargetUUIDArray[i].c_str()), NullXString8Array, FullTitleInstaller, LoaderTitleInstaller, Volume, NULL, OSTYPE_OSX_INSTALLER, 0);
/*macOSVersion = GetMacOSVersionFromFolder(*Volume->RootDir, SWPrintf("\\%s\\com.apple.installer", ApfsTargetUUID.c_str()));
if ( macOSVersion.notEmpty() && macOSVersion < MacOsVersion("11"_XS8) )*/ FullTitleInstaller.SWCatf(" via %ls", Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
XString8 installerPath = SWPrintf("\\%s\\com.apple.installer", Volume->ApfsTargetUUIDArray[i].c_str());
if ( FileExists(Volume->RootDir, installerPath) ) {
XString8 rootDmg = GetAuthRootDmg(*Volume->RootDir, installerPath);
rootDmg.replaceAll("%20"_XS8, " "_XS8);
// while ( rootDmg.notEmpty() && rootDmg.startWith('/') ) rootDmg.deleteCharsAtPos(0, 1);
rootDmg.replaceAll('/', '\\');
REFIT_VOLUME* targetVolume = Volumes.getVolumeWithApfsContainerUUIDAndFileSystemUUID(Volume->ApfsContainerUUID, Volume->ApfsTargetUUIDArray[i]);
if ( targetVolume ) {
if ( rootDmg.isEmpty() || FileExists(*targetVolume->RootDir, rootDmg) ) { // rootDmg empty is accepted, to be compatible with previous code
AddLoaderEntry(SWPrintf("\\%s\\com.apple.installer\\boot.efi", Volume->ApfsTargetUUIDArray[i].c_str()), NullXString8Array, FullTitleInstaller, LoaderTitleInstaller, Volume, NULL, OSTYPE_OSX_INSTALLER, 0);
}else{
DBG(" Dead installer entry found (installer dmg boot file not found : '%s')\n", rootDmg.c_str());
}
}else{
DBG(" Dead installer entry found (target volume not found : '%s')\n", Volume->ApfsTargetUUIDArray[i].c_str());
}
}
}
}
}
DBG("Entries list before ordering\n");
for (size_t idx = 0; idx < MainMenu.Entries.sizeIncludingHidden(); idx++) {
if ( MainMenu.Entries.ElementAt(idx).getLOADER_ENTRY() ) {
DBG(" Entry %zd : %ls%s\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str(), MainMenu.Entries.ElementAt(idx).Hidden ? " (hidden)" : "");
}else{
DBG(" Entry %zd : %ls%s\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str(), MainMenu.Entries.ElementAt(idx).Hidden ? " (hidden)" : "");
}
}
// Hide redundant preboot partition
for (size_t entryIdx1 = 0; entryIdx1 < MainMenu.Entries.sizeIncludingHidden(); entryIdx1++)
{
@ -1660,21 +1660,16 @@ void ScanLoader(void)
if ( ( loaderEntry1.LoaderType == OSTYPE_OSX || loaderEntry1.LoaderType == OSTYPE_OSX_INSTALLER ) && loaderEntry1.APFSTargetUUID.notEmpty() )
{
for ( size_t entryIdx2 = 0 ; entryIdx2 < MainMenu.Entries.sizeIncludingHidden() ; entryIdx2 ++ )
{
if ( MainMenu.Entries.ElementAt(entryIdx2).getLOADER_ENTRY() ) {
LOADER_ENTRY& loaderEntry2 = *MainMenu.Entries.ElementAt(entryIdx2).getLOADER_ENTRY();
if ( loaderEntry2.Volume->ApfsContainerUUID == loaderEntry1.Volume->ApfsContainerUUID ) {
if ( loaderEntry2.Volume->ApfsFileSystemUUID == loaderEntry1.APFSTargetUUID ) {
DBG("Hiding entry %zd because of entry %zd\n", entryIdx1, entryIdx2);
loaderEntry1.Hidden = true;
}
}
}
size_t entryIdx2 = MainMenu.Entries.getApfsLoaderIdx(loaderEntry1.Volume->ApfsContainerUUID, loaderEntry1.APFSTargetUUID, loaderEntry1.LoaderType);
if ( entryIdx2 != SIZE_T_MAX ) {
DBG("Hiding entry %zd because of entry %zd\n", entryIdx1, entryIdx2);
loaderEntry1.Hidden = true;
}
}
}
typedef struct EntryIdx {
size_t idx;
REFIT_ABSTRACT_MENU_ENTRY* entry;
@ -1692,21 +1687,6 @@ void ScanLoader(void)
}
}
DBG("Entries list before ordering\n");
for (size_t idx = 0; idx < MainMenu.Entries.sizeIncludingHidden(); idx++) {
if ( MainMenu.Entries.ElementAt(idx).getLOADER_ENTRY() ) {
DBG(" Entry %zd : %ls\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str());
}else{
DBG(" Entry %zd : %ls\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str());
}
}
// DBG("Entries list before ordering\n");
// for (size_t idx = 0; idx < EntriesArrayTmp.size(); idx++) {
// DBG(" Entry %zd, EntriesArrayTmp %zd : %ls\n", EntriesArrayTmp.ElementAt(idx).idx, idx, EntriesArrayTmp.ElementAt(idx).entry->Title.wc_str());
// }
bool hasMovedSomething;
// Re-order preboot partition
@ -1819,6 +1799,17 @@ void ScanLoader(void)
++idx;
}
} while ( hasMovedSomething );
DBG("Entries after before ordering\n");
for (size_t idx = 0; idx < MainMenu.Entries.sizeIncludingHidden(); idx++) {
if ( MainMenu.Entries.ElementAt(idx).getLOADER_ENTRY() ) {
DBG(" Entry %zd : %ls%s\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str(), MainMenu.Entries.ElementAt(idx).Hidden ? " (hidden)" : "");
}else{
DBG(" Entry %zd : %ls%s\n", idx, MainMenu.Entries.ElementAt(idx).Title.wc_str(), MainMenu.Entries.ElementAt(idx).Hidden ? " (hidden)" : "");
}
}
}
STATIC void AddCustomEntry(IN UINTN CustomIndex,
@ -2172,6 +2163,7 @@ STATIC void AddCustomEntry(IN UINTN CustomIndex,
SubMenu->AddMenuEntry(Entry, true);
else
MainMenu.AddMenuEntry(Entry, true);
DBG(" hiding entry because Custom->Hidden: %ls\n", Entry->LoaderPath.s());
Entry->Hidden = Custom->Hidden;
}
} while (FindCustomPath && Custom->Type == OSTYPE_LINEFI && Custom->KernelScan == KERNEL_SCAN_ALL); // repeat loop only for kernel scanning

View File

@ -40,6 +40,8 @@
#include "../refit/lib.h"
#include "../gui/REFIT_MENU_SCREEN.h"
#include "../Platform/Self.h"
#include "../Platform/Volumes.h"
//
// Clover File location to boot from on removable media devices
//

View File

@ -54,6 +54,7 @@
#include "../refit/screen.h"
#include "../Platform/Events.h"
#include "Self.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_MENU 1

View File

@ -250,11 +250,11 @@ const XIcon& XTheme::LoadOSIcon(const XString8& Full)
const XIcon *ReturnIcon;
UINTN Comma = Full.indexOf(',');
UINTN Size = Full.length();
DBG(" IconName=%s comma=%lld size=%lld\n", Full.c_str(), Comma, Size);
DBG(" IconName=%s comma=%lld size=%lld\n", Full.c_str(), Comma, Size);
if (Comma != MAX_XSIZE) { //Comma
First = "os_"_XS8 + Full.subString(0, Comma);
ReturnIcon = &GetIcon(First);
DBG(" first=%s\n", First.c_str());
DBG(" first=%s\n", First.c_str());
if (!ReturnIcon->isEmpty()) return *ReturnIcon;
//else search second name
Second = "os_"_XS8 + Full.subString(Comma + 1, Size - Comma - 1);
@ -271,11 +271,11 @@ const XIcon& XTheme::LoadOSIcon(const XString8& Full)
ReturnIcon = &GetIcon(Third);
if (!ReturnIcon->isEmpty()) return *ReturnIcon;
}
DBG(" Second=%s\n", Second.c_str());
DBG(" Second=%s\n", Second.c_str());
if (!ReturnIcon->isEmpty()) return *ReturnIcon;
} else {
ReturnIcon = &GetIcon("os_"_XS8 + Full);
DBG(" Full=%s\n", Full.c_str());
DBG(" Full=%s\n", Full.c_str());
if (!ReturnIcon->isEmpty()) return *ReturnIcon;
}
// else something

View File

@ -159,52 +159,6 @@ public:
~LEGACY_OS() {}
} ;
class REFIT_VOLUME {
public:
EFI_DEVICE_PATH *DevicePath;
EFI_HANDLE DeviceHandle;
EFI_FILE *RootDir;
XStringW DevicePathString;
XStringW VolName; // comes from EfiLibFileSystemInfo, EfiLibFileSystemVolumeLabelInfo, "EFI" if gEfiPartTypeSystemPartGuid or "Unknown HD"
XStringW VolLabel; // comes from \\.VolumeLabel.txt, or empty.
UINT8 DiskKind;
LEGACY_OS *LegacyOS;
BOOLEAN Hidden;
UINT8 BootType;
BOOLEAN IsAppleLegacy;
BOOLEAN HasBootCode;
BOOLEAN IsMbrPartition;
UINTN MbrPartitionIndex;
EFI_BLOCK_IO *BlockIO;
UINT64 BlockIOOffset;
EFI_BLOCK_IO *WholeDiskBlockIO;
EFI_DEVICE_PATH *WholeDiskDevicePath;
EFI_HANDLE WholeDiskDeviceHandle;
MBR_PARTITION_INFO *MbrPartitionTable;
UINT32 DriveCRC32;
EFI_GUID RootUUID; //for recovery it is UUID of parent partition
UINT64 SleepImageOffset;
XStringW osxVolumeName = NullXStringW; // comes from \\System\\Library\\CoreServices\\.disk_label.contentDetails, or empty.
XString8 ApfsFileSystemUUID; // apfs file system UUID of that partition. It's not the UUID of subfolder like in Preboot.
XString8 ApfsContainerUUID = NullXString8;
APPLE_APFS_VOLUME_ROLE ApfsRole = 0;
XString8Array ApfsTargetUUIDArray; // this is the array of folders that are named as UUID
REFIT_VOLUME() : DevicePath(0), DeviceHandle(0), RootDir(0), DevicePathString(), VolName(), VolLabel(), DiskKind(0), LegacyOS(0), Hidden(0), BootType(0), IsAppleLegacy(0), HasBootCode(0),
IsMbrPartition(0), MbrPartitionIndex(0), BlockIO(0), BlockIOOffset(0), WholeDiskBlockIO(0), WholeDiskDevicePath(0), WholeDiskDeviceHandle(0),
MbrPartitionTable(0), DriveCRC32(0), RootUUID({0,0,0,{0,0,0,0,0,0,0,0}}), SleepImageOffset(0), ApfsFileSystemUUID(), ApfsTargetUUIDArray()
{}
REFIT_VOLUME(const REFIT_VOLUME& other) = delete; // Can be defined if needed
const REFIT_VOLUME& operator = ( const REFIT_VOLUME & ) = delete; // Can be defined if needed
~REFIT_VOLUME() {}
const XStringW getVolLabelOrOSXVolumeNameOrVolName() {
if ( VolLabel.notEmpty() ) return VolLabel;
if ( osxVolumeName.notEmpty() ) return osxVolumeName;
return VolName;
}
};
class KEXT_PATCH
{
public:

View File

@ -259,8 +259,10 @@
Platform/StartupSound.h
# Platform/sse3_patcher.h
# Platform/sse3_5_patcher.h
Platform/VersionString.cpp
Platform/VersionString.h
Platform/VersionString.cpp
Platform/VersionString.h
Platform/Volumes.cpp
Platform/Volumes.h
../Version.h
cpp_util/globals_ctor.cpp
cpp_util/globals_ctor.h

View File

@ -45,6 +45,7 @@
#include "Self.h"
#include "SelfOem.h"
#include "../include/OC.h"
#include "../Platform/Volumes.h"
#ifndef DEBUG_ALL
#define DEBUG_LIB 1
@ -69,15 +70,6 @@ BOOLEAN gBootChanged = FALSE;
BOOLEAN gThemeOptionsChanged = FALSE;
REFIT_VOLUME *SelfVolume = NULL;
//REFIT_VOLUME **Volumes = NULL;
//UINTN VolumesCount = 0;
VolumesArrayClass Volumes;
//REFIT_VOLUME* VolumesArrayClass::getApfsPartitionWithUUID(const XString8& ApfsContainerUUID, const XString8& APFSTargetUUID)
//{
//}
//
// Unicode collation protocol interface
//

View File

@ -58,6 +58,7 @@
// Experimental <--
#include "../include/Efi.h"
#include "../libeg/libeg.h"
#include "../Platform/Volumes.h"
#ifdef __cplusplus
#include "../cpp_foundation/XObjArray.h"
@ -258,21 +259,7 @@ typedef enum {
#define SCREEN_EDGE_RIGHT 70000
#define SCREEN_EDGE_BOTTOM 80000
extern REFIT_VOLUME *SelfVolume;
#ifdef __cplusplus
class VolumesArrayClass : public XObjArray<REFIT_VOLUME>
{
public:
// REFIT_VOLUME* getApfsPartitionWithUUID(const XString8& ApfsContainerUUID, const XString8& APFSTargetUUID);
};
extern VolumesArrayClass Volumes;
#endif
//extern UINTN VolumesCount;
extern BOOLEAN gThemeChanged;
//extern BOOLEAN gBootArgsChanged;