mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2025-02-01 22:41:28 +01:00
Fix partition name when there is more than 1 system partition in
container. printf support of "%.*s".
This commit is contained in:
parent
c458db4acd
commit
fafc50e3d0
@ -1,5 +1,5 @@
|
||||
//
|
||||
// printf_lite.hpp
|
||||
// printf_lite.h
|
||||
//
|
||||
// Created by jief the 04 Apr 2019.
|
||||
// Imported in CLover the 24 Feb 2020
|
||||
@ -60,6 +60,14 @@ extern "C"
|
||||
#define PRINTF_CHECK_UNSUPPORTED_STRING_FORMAT 0
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_LITE_DOT_STAR_SUPPORT
|
||||
#define PRINTF_LITE_DOT_STAR_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_LITE_STRING_WIDTH_SPECIFIER_SUPPORT
|
||||
#define PRINTF_LITE_STRING_WIDTH_SPECIFIER_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A buffer is not needed. On some case it could be faster. For example when using semihosting
|
||||
* It's 255 max, because of bufIdx of type uint8_t. It's possible to change it to int if bigger buffer needed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// printf_lite.hpp
|
||||
// printf_lite.c
|
||||
//
|
||||
// Created by jief the 04 Apr 2019.
|
||||
// Imported in CLover the 24 Feb 2020
|
||||
@ -313,8 +313,8 @@ static void print_char32_as_utf8_string(const char32_t utf32_char, PrintfParams*
|
||||
static void output_wchar_string_as_utf8(const wchar_t* s, PrintfParams* printfParams)
|
||||
{
|
||||
if ( !s ) return;
|
||||
int width_specifier = printfParams->width_specifier;
|
||||
while ( *s && (printfParams->width_specifier == 0 || width_specifier--) ) {
|
||||
int precision_specifier = printfParams->precision_specifier;
|
||||
while ( *s && (printfParams->precision_specifier <= 0 || precision_specifier--) ) {
|
||||
// while ( *s ) {
|
||||
#if __WCHAR_MAX__ <= 0xFFFFu
|
||||
const char16_t uc = *s++;
|
||||
@ -367,8 +367,8 @@ UTF8
|
||||
static void output_utf8_string_as_wchar(const char* s, PrintfParams* printfParams)
|
||||
{
|
||||
if ( !s ) return;
|
||||
int width_specifier = printfParams->width_specifier;
|
||||
while ( *s && (printfParams->width_specifier == 0 || width_specifier--) ) {
|
||||
int precision_specifier = printfParams->precision_specifier;
|
||||
while ( *s && (printfParams->precision_specifier == 0 || precision_specifier--) ) {
|
||||
char32_t c;
|
||||
if ( *((unsigned char*)s) & 0x80 ) {
|
||||
if (*(s+1) == 0) {
|
||||
@ -447,8 +447,16 @@ __attribute__((noinline, section(".printf_lite")))
|
||||
static void output_utf8_string_as_utf8(const char* s, PrintfParams* printfParams)
|
||||
{
|
||||
if ( !s ) return;
|
||||
if ( printfParams->width_specifier ) while ( *s && printfParams->width_specifier-- ) print_utf8_char(*s++, printfParams);
|
||||
else while ( *s ) print_utf8_char(*s++, printfParams);
|
||||
//#if PRINTF_LITE_STRING_WIDTH_SPECIFIER_SUPPORT == 1
|
||||
// size_t len = lengt
|
||||
//#endif
|
||||
if ( printfParams->precision_specifier >= 0 ) {
|
||||
while ( *s && printfParams->precision_specifier-- ) print_utf8_char(*s++, printfParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( *s ) print_utf8_char(*s++, printfParams);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEFINE_SECTIONS == 1
|
||||
@ -460,8 +468,11 @@ __attribute__((noinline, section(".printf_lite")))
|
||||
static void output_wchar_string(const wchar_t* s, PrintfParams* printfParams)
|
||||
{
|
||||
if ( !s ) return;
|
||||
if ( printfParams->width_specifier ) while ( *s && printfParams->width_specifier-- ) print_wchar(*s++, printfParams);
|
||||
else while ( *s ) print_wchar(*s++, printfParams);
|
||||
if ( printfParams->precision_specifier >= 0 ) {
|
||||
while ( *s && printfParams->precision_specifier-- ) print_wchar(*s++, printfParams);
|
||||
}else{
|
||||
while ( *s ) print_wchar(*s++, printfParams);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -699,6 +710,7 @@ static void print_double(double number, PrintfParams* printfParams)
|
||||
// prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
#if PRINTF_LITE_FIELDPRECISION_SUPPORT == 1
|
||||
if ( printfParams->precision_specifier < 0 ) printfParams->precision_specifier = 6;
|
||||
for (int i = 0; i < printfParams->precision_specifier; i++) {
|
||||
rounding /= 10.0;
|
||||
}
|
||||
@ -713,7 +725,7 @@ static void print_double(double number, PrintfParams* printfParams)
|
||||
unsigned INT_BIGGEST_TYPE int_part = (unsigned INT_BIGGEST_TYPE)number; // we're sure it's positive number here.
|
||||
double remainder = number - (double)int_part;
|
||||
#if PRINTF_LITE_FIELDWIDTH_SUPPORT == 1
|
||||
int width_specifier = printfParams->width_specifier;
|
||||
int width_specifier = printfParams->width_specifier == -1 ? 6 : 0;
|
||||
#if PRINTF_LITE_FIELDPRECISION_SUPPORT == 1
|
||||
printfParams->width_specifier -= printfParams->precision_specifier + (printfParams->precision_specifier ? 1 : 0); // doesn't matter if width_specifier is negative.
|
||||
#else
|
||||
@ -809,12 +821,37 @@ void printf_handle_format_char(char c, VALIST_PARAM_TYPE valist, PrintfParams* p
|
||||
#if PRINTF_LITE_FALLBACK_FOR_UNSUPPORTED == 1
|
||||
// We just have to ignore field width
|
||||
#else
|
||||
// It's considered a mistake. Get out directive. Nothing will be printed. Harder to debug the format string for the user, but save sapce.
|
||||
// It's considered a mistake. Get out directive. Nothing will be printed. Harder to debug the format string for the user, but save space.
|
||||
printfParams->inDirective = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#ifdef PRINTF_LITE_DOT_STAR_SUPPORT
|
||||
case '*':
|
||||
#if PRINTF_LITE_FIELDPRECISION_SUPPORT == 1 || (PRINTF_LITE_FALLBACK_FOR_UNSUPPORTED == 1 && PRINTF_LITE_FIELDWIDTH_SUPPORT == 1)
|
||||
if ( printfParams->inPrecisionField )
|
||||
{
|
||||
#if PRINTF_LITE_FIELDPRECISION_SUPPORT == 1 // just ignore if we don't support precision field
|
||||
printfParams->precision_specifier = -2;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if PRINTF_LITE_FIELDWIDTH_SUPPORT == 1
|
||||
printfParams->width_specifier = -1;
|
||||
#else
|
||||
#if PRINTF_LITE_FALLBACK_FOR_UNSUPPORTED == 1
|
||||
// We just have to ignore field width
|
||||
#else
|
||||
// It's considered a mistake. Get out directive. Nothing will be printed. Harder to debug the format string for the user, but save space.
|
||||
printfParams->inDirective = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if PRINTF_LITE_FALLBACK_FOR_UNSUPPORTED == 1 || PRINTF_LITE_FIELDPRECISION_SUPPORT == 1
|
||||
case '.':
|
||||
@ -1002,6 +1039,12 @@ void printf_handle_format_char(char c, VALIST_PARAM_TYPE valist, PrintfParams* p
|
||||
#endif //defined(ARDUINO) && PRINTF_LITE_FLASHSTRING_SUPPORT == 1
|
||||
case 's':
|
||||
{
|
||||
#ifdef PRINTF_LITE_DOT_STAR_SUPPORT
|
||||
if ( printfParams->precision_specifier == -2 ) {
|
||||
printfParams->precision_specifier = va_arg(VALIST_ACCESS(valist), int);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PRINTF_CHECK_UNSUPPORTED_STRING_FORMAT == 1 && (PRINTF_UTF8_INPUT_SUPPORT==0 || PRINTF_UNICODE_INPUT_SUPPORT==0)
|
||||
// If both input support disabled, we can't even print "unsupported"
|
||||
# if PRINTF_UTF8_INPUT_SUPPORT == 1 || PRINTF_UNICODE_INPUT_SUPPORT== 1
|
||||
@ -1099,7 +1142,7 @@ void printf_handle_format_char(char c, VALIST_PARAM_TYPE valist, PrintfParams* p
|
||||
printfParams->inPrecisionField = 0;
|
||||
#endif
|
||||
#if PRINTF_LITE_FIELDPRECISION_SUPPORT == 1
|
||||
printfParams->precision_specifier = 6; // 6 digits for float, as specified by ANSI, if I remember well
|
||||
printfParams->precision_specifier = -1; // -1 not specified. -2 specified by parameter.
|
||||
#endif
|
||||
#if PRINTF_LITE_PADCHAR_SUPPORT == 1
|
||||
printfParams->pad_char = ' ';
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// printf_lite.hpp
|
||||
// printf_lite.h
|
||||
//
|
||||
// Created by jief the 04 Apr 2019.
|
||||
// Imported in CLover the 24 Feb 2020
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 0857d5170842cf01d0fce7433eb33c682a4754f7
|
||||
Subproject commit 1ee382fc422ab49e219a00a39a25e4f9b4ce8325
|
@ -582,7 +582,7 @@ STATIC LOADER_ENTRY *CreateLoaderEntry(IN CONST XStringW& LoaderPath,
|
||||
Entry->APFSTargetUUID = APFSTargetUUID;
|
||||
|
||||
Entry->LoaderPath = LoaderPath;
|
||||
Entry->DisplayedVolName = Volume->VolName;
|
||||
Entry->DisplayedVolName = Volume->VolName;
|
||||
Entry->DevicePath = LoaderDevicePath;
|
||||
Entry->DevicePathString = LoaderDevicePathString;
|
||||
Entry->Flags = OSFLAG_SET(Flags, OSFLAG_USEGRAPHICS);
|
||||
@ -1518,6 +1518,7 @@ void ScanLoader(void)
|
||||
le->Hidden = true;
|
||||
}
|
||||
|
||||
//DBG("Volume->ApfsTargetUUIDArray.size()=%zd\n", Volume->ApfsTargetUUIDArray.size());
|
||||
if ( Volume->ApfsTargetUUIDArray.size() > 0 ) {
|
||||
|
||||
for (UINTN i = 0; i < Volume->ApfsTargetUUIDArray.size(); i++)
|
||||
@ -1530,28 +1531,67 @@ void ScanLoader(void)
|
||||
XStringW LoaderTitleInstaller;
|
||||
|
||||
REFIT_VOLUME* targetVolume = NULL;
|
||||
for (UINTN VolumeIndex2 = 0; VolumeIndex2 < Volumes.size(); VolumeIndex2++) {
|
||||
for (size_t VolumeIndex2 = 0; VolumeIndex2 < Volumes.size(); VolumeIndex2++) {
|
||||
REFIT_VOLUME* Volume2 = &Volumes[VolumeIndex2];
|
||||
//DBG("name %ls uuid=%ls \n", Volume2->VolName, Volume2->ApfsFileSystemUUID.wc_str());
|
||||
//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;
|
||||
}
|
||||
}
|
||||
}
|
||||
//DBG("targetVolume=%d\n", targetVolume ? 1 : 0);
|
||||
if ( targetVolume ) {
|
||||
if ( (targetVolume->ApfsRole & APPLE_APFS_VOLUME_ROLE_DATA) != 0 ) {
|
||||
for (UINTN VolumeIndex2 = 0; VolumeIndex2 < Volumes.size(); VolumeIndex2++) {
|
||||
for (size_t VolumeIndex2 = 0; VolumeIndex2 < Volumes.size(); VolumeIndex2++) {
|
||||
REFIT_VOLUME* Volume2 = &Volumes[VolumeIndex2];
|
||||
//DBG("name %ls uuid=%ls \n", Volume2->VolName, Volume2->ApfsFileSystemUUID.wc_str());
|
||||
//DBG("idx=%zu name %ls uuid=%s \n", VolumeIndex2, Volume2->VolName.wc_str(), Volume2->ApfsFileSystemUUID.c_str());
|
||||
if ( Volume2->ApfsContainerUUID == targetVolume->ApfsContainerUUID ) {
|
||||
if ( (Volume2->ApfsRole & APPLE_APFS_VOLUME_ROLE_SYSTEM) != 0 ) {
|
||||
targetVolume = Volume2;
|
||||
if ( !targetVolume ) {
|
||||
targetVolume = Volume2;
|
||||
}else{
|
||||
// More than one system partition in container. I don't know how to select which one is supposed to pair with this
|
||||
targetVolume = NULL; // we'll try .disk_label.contentDetails
|
||||
break; // we need to escape the loop after bootVolume = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//DBG("2) targetVolume=%d\n", targetVolume ? 1 : 0);
|
||||
if ( !targetVolume ) {
|
||||
REFIT_VOLUME* bootVolume = Volume;
|
||||
if ( (Volume->ApfsRole & APPLE_APFS_VOLUME_ROLE_RECOVERY) != 0 ) {
|
||||
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->ApfsRole & APPLE_APFS_VOLUME_ROLE_PREBOOT) != 0 ) {
|
||||
if ( Volume2->ApfsContainerUUID == Volume->ApfsContainerUUID ) {
|
||||
bootVolume = Volume2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( bootVolume ) {
|
||||
XStringW targetNameFile;
|
||||
CHAR8* fileBuffer;
|
||||
UINTN fileLen = 0;
|
||||
targetNameFile.SWPrintf("%s\\System\\Library\\CoreServices\\.disk_label.contentDetails", ApfsTargetUUID.c_str());
|
||||
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());
|
||||
DBG("contentDetails name:%s\n", fileBuffer);
|
||||
FreePool(fileBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( FullTitle.isEmpty() ) {
|
||||
if ( targetVolume ) {
|
||||
FullTitle.SWPrintf("Boot Mac OS X from %ls via %ls", targetVolume->getVolLabelOrOSXVolumeNameOrVolName().wc_str(), Volume->getVolLabelOrOSXVolumeNameOrVolName().wc_str());
|
||||
|
@ -568,25 +568,6 @@ static void ScanVolumeBootcode(IN OUT REFIT_VOLUME *Volume, OUT BOOLEAN *Bootabl
|
||||
FreeAlignedPages((void*)SectorBuffer, EFI_SIZE_TO_PAGES (2048));
|
||||
}
|
||||
|
||||
//Set Entry->VolName to .disk_label.contentDetails if it exists
|
||||
STATIC XStringW GetOSXVolumeName(REFIT_VOLUME *Volume)
|
||||
{
|
||||
XStringW returnValue;
|
||||
EFI_STATUS Status = EFI_NOT_FOUND;
|
||||
CONST CHAR16* targetNameFile = L"\\System\\Library\\CoreServices\\.disk_label.contentDetails";
|
||||
CHAR8* fileBuffer;
|
||||
UINTN fileLen = 0;
|
||||
if(FileExists(Volume->RootDir, targetNameFile)) {
|
||||
Status = egLoadFile(Volume->RootDir, targetNameFile, (UINT8 **)&fileBuffer, &fileLen);
|
||||
if(!EFI_ERROR(Status)) {
|
||||
returnValue.strncpy(fileBuffer, fileLen);
|
||||
FreePool(fileBuffer);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
return NullXStringW;
|
||||
}
|
||||
|
||||
//at start we have only Volume->DeviceHandle
|
||||
static EFI_STATUS ScanVolume(IN OUT REFIT_VOLUME *Volume)
|
||||
{
|
||||
@ -834,10 +815,6 @@ static EFI_STATUS ScanVolume(IN OUT REFIT_VOLUME *Volume)
|
||||
}
|
||||
|
||||
|
||||
Volume->osxVolumeName = GetOSXVolumeName(Volume);
|
||||
DBG(" osxVolumeName=%ls\n", Volume->osxVolumeName.wc_str());
|
||||
|
||||
|
||||
if ( FileExists(Volume->RootDir, L"\\.VolumeLabel.txt") ) {
|
||||
EFI_FILE* FileHandle;
|
||||
Status = Volume->RootDir->Open(Volume->RootDir, &FileHandle, L"\\.VolumeLabel.txt", EFI_FILE_MODE_READ, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user