Fix partition name when there is more than 1 system partition in

container.
printf support of "%.*s".
This commit is contained in:
jief666 2020-10-26 23:37:32 +03:00
parent c458db4acd
commit fafc50e3d0
6 changed files with 112 additions and 44 deletions

View File

@ -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.

View File

@ -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 = ' ';

View File

@ -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

View File

@ -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());

View File

@ -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);