fix nvram.plist reading

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2021-02-19 23:07:24 +03:00
parent 93196411ad
commit 3fbfaf07eb
3 changed files with 100 additions and 123 deletions

220
rEFIt_UEFI/Platform/Nvram.cpp Normal file → Executable file
View File

@ -184,41 +184,41 @@ SetNvramVariable (
IN CONST void *Data
)
{
//EFI_STATUS Status;
EFI_STATUS Status = EFI_SUCCESS;
void *OldData;
UINTN OldDataSize = 0;
UINT32 OldAttributes = 0;
//DBG("SetNvramVariable (%ls, guid, 0x%X, %d):", VariableName, Attributes, DataSize);
// DBG("SetNvramVariable (%ls, guid, 0x%X, %lld):", VariableName, Attributes, DataSize);
OldData = (__typeof__(OldData))GetNvramVariable(VariableName, VendorGuid, &OldAttributes, &OldDataSize);
if (OldData != NULL) {
// var already exists - check if it equal to new value
//DBG(" exists(0x%X, %d)", OldAttributes, OldDataSize);
// DBG(" exists(0x%X, %lld)", OldAttributes, OldDataSize);
if ((OldAttributes == Attributes) &&
(OldDataSize == DataSize) &&
(CompareMem (OldData, Data, DataSize) == 0)) {
// it's the same - do nothing
//DBG(", equal -> not writing again.\n");
// DBG(", equal -> not writing again.\n");
FreePool(OldData);
return EFI_SUCCESS;
}
//DBG(", not equal\n");
// DBG(", not equal\n");
FreePool(OldData);
// not the same - delete previous one if attributes are different
if (OldAttributes != Attributes) {
DeleteNvramVariable (VariableName, VendorGuid);
//DBG(", diff. attr: deleting old (%s)", efiStrError(Status));
Status = DeleteNvramVariable(VariableName, VendorGuid);
// DBG(", diff. attr: deleting old (%s)", efiStrError(Status));
}
}
//DBG("\n"); // for debug without Status
//DBG(" -> writing new (%s)\n", efiStrError(Status));
//return Status;
return gRT->SetVariable(VariableName, VendorGuid, Attributes, DataSize, (void*)Data); // CONST missing in EFI_SET_VARIABLE->SetVariable
// DBG("\n"); // for debug without Status
Status = gRT->SetVariable(VariableName, VendorGuid, Attributes, DataSize, (void*)Data); // CONST missing in EFI_SET_VARIABLE->SetVariable
// DBG(" -> writing new (%s)\n", efiStrError(Status));
return Status;
}
EFI_STATUS
SetNvramXString8 (
IN CONST CHAR16 *VariableName,
@ -240,19 +240,20 @@ AddNvramVariable (
IN const void *Data
)
{
EFI_STATUS Status;
void *OldData;
//DBG("SetNvramVariable (%ls, guid, 0x%X, %d):\n", VariableName, Attributes, DataSize);
DBG("SetNvramVariable (%ls, guid, 0x%X, %lld):\n", VariableName, Attributes, DataSize);
OldData = (__typeof__(OldData))GetNvramVariable(VariableName, VendorGuid, NULL, NULL);
if (OldData == NULL)
{
if (OldData == NULL) {
// set new value
return gRT->SetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
// DBG(" -> writing new (%s)\n", efiStrError(Status));
} else {
FreePool(OldData);
return EFI_ABORTED;
}
Status = gRT->SetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
DBG(" -> writing new (%s)\n", efiStrError(Status));
} else {
FreePool(OldData);
Status = EFI_ABORTED;
}
return Status;
}
EFI_STATUS
@ -277,7 +278,7 @@ DeleteNvramVariable (
// Delete: attributes and data size = 0
Status = gRT->SetVariable (VariableName, VendorGuid, 0, 0, NULL);
//DBG("DeleteNvramVariable (%ls, guid = %s):\n", VariableName, efiStrError(Status));
DBG("DeleteNvramVariable (%ls, guid = %s):\n", VariableName, efiStrError(Status));
return Status;
}
@ -512,17 +513,17 @@ GetSmcKeys (BOOLEAN WriteToSMC)
Data = (__typeof__(Data))GetNvramVariable(Name, &Guid, NULL, &DataSize);
if (Data) {
/* UINTN Index;
UINTN Index;
DBG(" %ls:", Name);
for (Index = 0; Index < DataSize; Index++) {
DBG("%02hhX ", *((UINT8*)Data + Index));
}
DBG("\n"); */
DBG("\n");
if (gAppleSmc && WriteToSMC) {
Status = gAppleSmc->SmcAddKey(gAppleSmc, KeyFromName(Name), (SMC_DATA_SIZE)DataSize, TypeFromName(Name), 0xC0);
if (!EFI_ERROR(Status)) {
Status = gAppleSmc->SmcWriteValue(gAppleSmc, KeyFromName(Name), (SMC_DATA_SIZE)DataSize, Data);
// DBG("Write to AppleSMC status=%s\n", efiStrError(Status));
DBG("Write to AppleSMC status=%s\n", efiStrError(Status));
}
NumKey++;
}
@ -593,14 +594,14 @@ EFI_GUID
/** detailed debug for BootVolumeDevicePathEqual */
#define DBG_DP(...)
//#define DBG_DP(...) DBG(__VA_ARGS__)
//#define DBG_DP(...)
#define DBG_DP(...) DBG(__VA_ARGS__)
/** Returns TRUE if dev paths are equal. Ignores some differences. */
BOOLEAN
BootVolumeDevicePathEqual (
const EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
const EFI_DEVICE_PATH_PROTOCOL *DevicePath2
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
)
{
BOOLEAN Equal;
@ -615,7 +616,7 @@ BootVolumeDevicePathEqual (
BOOLEAN ForceEqualNodes;
DBG_DP (" BootVolumeDevicePathEqual:\n %s\n %s\n", FileDevicePathToStr (DevicePath1), FileDevicePathToStr (DevicePath2));
// DBG_DP (" BootVolumeDevicePathEqual:\n %ls\n %ls\n", FileDevicePathToStr (DevicePath1), FileDevicePathToStr (DevicePath2));
DBG_DP (" N1: (Type, Subtype, Len) N2: (Type, Subtype, Len)\n");
Equal = FALSE;
@ -630,12 +631,12 @@ BootVolumeDevicePathEqual (
ForceEqualNodes = FALSE;
DBG_DP (" N1: (%d, %d, %d)", Type1, SubType1, Len1);
DBG_DP (" N2: (%d, %d, %d)", Type2, SubType2, Len2);
/*
DBG_DP ("%s\n", DevicePathToStr (DevicePath1));
DBG_DP ("%s\n", DevicePathToStr (DevicePath2));
*/
DBG_DP (" N1: (%d, %d, %lld)", Type1, SubType1, Len1);
DBG_DP (" N2: (%d, %d, %lld)", Type2, SubType2, Len2);
// DBG_DP ("%ls\n", DevicePathToStr (DevicePath1));
// DBG_DP ("%ls\n", DevicePathToStr (DevicePath2));
//
// Some eSata device can have path:
@ -730,8 +731,8 @@ BootVolumeDevicePathEqual (
/** Returns TRUE if dev paths contain the same MEDIA_DEVICE_PATH. */
BOOLEAN
BootVolumeMediaDevicePathNodesEqual (
EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
EFI_DEVICE_PATH_PROTOCOL *DevicePath2
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
)
{
DevicePath1 = Clover_FindDevicePathNodeWithType (DevicePath1, MEDIA_DEVICE_PATH, 0);
@ -776,11 +777,11 @@ GetEfiBootDeviceFromNvram ()
gEfiBootDeviceData = (__typeof__(gEfiBootDeviceData))GetNvramVariable(L"efi-boot-next-data", &gEfiAppleBootGuid, NULL, &Size);
if (gEfiBootDeviceData != NULL) {
// DBG("Got efi-boot-next-data size=%d\n", Size);
DBG("Got efi-boot-next-data size=%lld\n", Size);
if (IsDevicePathValid(gEfiBootDeviceData, Size)) {
// DBG(" - efi-boot-next-data: %ls\n", FileDevicePathToStr (gEfiBootDeviceData));
} else {
// DBG(" - device path for efi-boot-next-data is invalid\n");
DBG(" - device path for efi-boot-next-data is invalid\n");
FreePool(gEfiBootDeviceData);
gEfiBootDeviceData = NULL;
}
@ -797,16 +798,16 @@ GetEfiBootDeviceFromNvram ()
}
if (gEfiBootDeviceData != NULL) {
// DBG("Got efi-boot-device-data size=%d\n", Size);
DBG("Got efi-boot-device-data size=%lld\n", Size);
if (!IsDevicePathValid(gEfiBootDeviceData, Size)) {
// DBG(" - device path for efi-boot-device-data is invalid\n");
DBG(" - device path for efi-boot-device-data is invalid\n");
FreePool(gEfiBootDeviceData);
gEfiBootDeviceData = NULL;
}
}
}
if (gEfiBootDeviceData == NULL) {
// DBG(" - [!] efi-boot-device-data not found\n");
DBG(" - [!] efi-boot-device-data not found\n");
return EFI_NOT_FOUND;
}
@ -906,9 +907,9 @@ LoadNvramPlist(
// parse it into gNvramDict
//
Status = ParseXML((const CHAR8*)NvramPtr, &gNvramDict, Size);
// if(Status != EFI_SUCCESS) {
// DBG(" parsing error\n");
// }
if(Status != EFI_SUCCESS) {
DBG(" parsing error\n");
}
FreePool(NvramPtr);
// we will leave nvram.plist loaded and parsed for later processing
@ -965,14 +966,14 @@ LoadLatestNvramPlist()
// not a GUID partition
DBG(" - not GPT");
} */
// DBG("Volume[%d]\n", Index);
DBG("Volume[%lld]\n", Index);
// check if nvram.plist exists
Status = Volume->RootDir->Open (Volume->RootDir, &FileHandle, L"nvram.plist", EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status)) {
// DBG(" - no nvram.plist - skipping!\n");
DBG(" - no nvram.plist - skipping!\n");
continue;
}
// DBG(" Status=%s\n", efiStrError(Status));
DBG(" Status=%s\n", efiStrError(Status));
if (GlobalConfig.isFastBoot()) {
VolumeWithLatestNvramPlist = Volume;
break;
@ -982,23 +983,23 @@ LoadLatestNvramPlist()
FileInfo = EfiLibFileInfo(FileHandle);
// DBG("got FileInfo=0x%X\n", FileInfo);
if (FileInfo == NULL) {
// DBG(" - no nvram.plist file info - skipping!\n");
DBG(" - no nvram.plist file info - skipping!\n");
FileHandle->Close(FileHandle);
continue;
}
// DBG(" Modified = ");
DBG(" Modified = ");
ModifTimeMs = GetEfiTimeInMs (&(FileInfo->ModificationTime));
/* DBG("%d-%d-%d %d:%d:%d (%ld ms)\n",
DBG("%d-%d-%d %d:%d:%d (%lld ms)\n",
FileInfo->ModificationTime.Year, FileInfo->ModificationTime.Month, FileInfo->ModificationTime.Day,
FileInfo->ModificationTime.Hour, FileInfo->ModificationTime.Minute, FileInfo->ModificationTime.Second,
ModifTimeMs); */
ModifTimeMs);
FreePool(FileInfo);
FileHandle->Close(FileHandle);
// check if newer
if (LastModifTimeMs < ModifTimeMs) {
// DBG(" - newer - will use this one\n");
DBG(" - newer - will use this one\n");
VolumeWithLatestNvramPlist = Volume;
LastModifTimeMs = ModifTimeMs;
}
@ -1031,8 +1032,9 @@ void
PutNvramPlistToRtVars ()
{
// EFI_STATUS Status;
size_t Size;
const void *Value;
// const TagStruct* ValTag;
INTN Size, i;
const VOID *Value;
if (gNvramDict == NULL) {
/*Status = */LoadLatestNvramPlist();
@ -1041,12 +1043,9 @@ PutNvramPlistToRtVars ()
return;
}
}
if ( !gNvramDict->isDict() ) {
DBG("PutNvramPlistToRtVars: MALFORMED PLIST nvram.plist. Root must be a dict\n");
return;
}
DbgHeader("PutNvramPlistToRtVars");
// DBG("PutNvramPlistToRtVars ...\n");
// iterate over dict elements
size_t count = gNvramDict->dictKeyCount(); // ok
for (size_t tagIdx = 0 ; tagIdx < count ; tagIdx++ )
@ -1057,16 +1056,13 @@ PutNvramPlistToRtVars ()
MsgLog("MALFORMED PLIST nvram.plist. A key is expected at pos : %zu\n", tagIdx);
continue;
}
EFI_GUID *VendorGuid = &gEfiAppleBootGuid;
Value = NULL;
if ( tagIdx + 1 < gNvramDict->dictContent().size() && !gNvramDict->dictContent()[tagIdx+1].isKey() ) valueTag = &gNvramDict->dictContent()[tagIdx+1];
EFI_GUID *VendorGuid = &gEfiAppleBootGuid;
// process only valid <key> tags
if ( valueTag == NULL ) {
DBG(" ERROR: ValTag is not NULL\n");
// DBG(" ERROR: ValTag is not NULL\n");
continue;
}
// DBG("tag: %s\n", Tag.stringValue());
// skip OsxAptioFixDrv-RelocBase - appears and causes trouble
// in kernel and kext patcher when mixing UEFI and CloverEFI boot
if ( keyTag->keyStringValue() == "OsxAptioFixDrv-RelocBase"_XS8 ) {
@ -1082,67 +1078,52 @@ PutNvramPlistToRtVars ()
DBG(" Skipping aapl,panic-info\n");
continue;
}
// // key to unicode; check if key buffer is large enough
// if ( Tag.keyValue().length() > sizeof(KeyBuf) - 1 ) {
// DBG(" ERROR: Skipping too large key %s\n", Tag.keyValue().c_str());
// continue;
// }
if ( keyTag->keyStringValue() == "Boot0082"_XS8 || keyTag->keyStringValue() == "BootNext"_XS8 ) {
if (keyTag->keyStringValue() == "Boot0082"_XS8 ||
keyTag->keyStringValue() == "BootNext"_XS8 ) {
VendorGuid = &gEfiGlobalVariableGuid;
// it may happen only in this case
gSettings.Boot.HibernationFixup = TRUE;
}
// AsciiStrToUnicodeStrS(Tag.stringValue(), KeyBuf, 128);
XStringW KeyBuf = keyTag->keyStringValue();
if (!gSettings.Boot.DebugLog) {
DBG(" Adding Key: %ls: ", KeyBuf.wc_str());
}
// process value tag
if (valueTag->isString()) {
// AsciiStrToUnicodeStrS(Tag.stringValue(), KeyBuf, 128);
XStringW KeyBuf = keyTag->keyStringValue();
// if (!gSettings.Boot.DebugLog) {
DBG(" Adding Key: %ls: ", KeyBuf.wc_str());
// }
// process value tag
// <string> element
Value = (void*)valueTag->getString()->stringValue().c_str();
Size = valueTag->getString()->stringValue().length();
if (!gSettings.Boot.DebugLog) {
DBG("String: Size = %zu, Val = '%s'\n", Size, valueTag->getString()->stringValue().c_str());
}
} else if (valueTag->isData()) {
// <data> element
Size = valueTag->getData()->getData()->dataLenValue();
Value = valueTag->getData()->getData()->dataValue();
if (!gSettings.Boot.DebugLog) {
DBG("Size = %zu, Data: ", Size);
for (size_t i = 0; i < Size; i++) {
DBG("%02hhX ", *(((UINT8*)Value) + i));
if (valueTag->isString()) {
// <string> element
Value = (void*)valueTag->getString()->stringValue().c_str();
Size = valueTag->getString()->stringValue().length();
if (!gSettings.Boot.DebugLog) {
DBG("String: Size = %llu, Val = '%s'\n", Size, valueTag->getString()->stringValue().c_str());
}
} else if (valueTag->isData()) {
// <data> element
Size = valueTag->getData()->dataLenValue();
Value = valueTag->getData()->dataValue();
// if (gSettings.Boot.DebugLog) {
// DBG("Size = %llu, Data: ", Size);
// for ( i = 0; i < Size; i++) {
// DBG("%02hhX ", *(((UINT8*)Value) + i));
// }
// }
// if (!gSettings.Boot.DebugLog) {
// DBG("\n");
//
} else {
DBG("ERROR: Unsupported tag type: %s\n", valueTag->getTypeAsXString8().c_str());
continue;
}
if (!gSettings.Boot.DebugLog) {
DBG("\n");
}
} else {
DBG("ERROR: Unsupported tag type: %s\n", valueTag->getTypeAsXString8().c_str());
continue;
}
if (Size == 0 || !Value) {
continue;
}
// set RT var: all vars visible in nvram.plist are gEfiAppleBootGuid
/* Status = gRT->SetVariable (
KeyBuf,
VendorGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
Size,
Value
); */
// set RT var: all vars visible in nvram.plist are gEfiAppleBootGuid
SetNvramVariable (
KeyBuf.wc_str(),
VendorGuid,
@ -1172,10 +1153,6 @@ FindStartupDiskVolume (
XStringW LoaderPath;
XStringW EfiBootVolumeStr;
// DBG("FindStartupDiskVolume ...\n");
//
// search RT vars for efi-boot-device-data
// and try to find that volume
@ -1187,7 +1164,6 @@ FindStartupDiskVolume (
}
DbgHeader("FindStartupDiskVolume");
// DBG("FindStartupDiskVolume searching ...\n");
//
// Check if gEfiBootVolume is disk or partition volume
@ -1213,7 +1189,7 @@ FindStartupDiskVolume (
// case insensitive cmp
if ( LoaderPath.equalIC(gEfiBootLoaderPath) ) {
// that's the one
DBG(" - found entry %lld. '%ls', Volume '%ls', '%ls'\n", Index, LoaderEntry.Title.s(), Volume->VolName.wc_str(), LoaderPath.wc_str());
DBG(" - found entry %lld. '%ls', Volume '%ls', '%ls'\n", Index, LoaderEntry.Title.s(), Volume->VolName.wc_str(), LoaderPath.wc_str());
return Index;
}
}
@ -1234,7 +1210,7 @@ FindStartupDiskVolume (
if (MediaPath) {
EFI_GUID *MediaPathGuid = (EFI_GUID *)&((VENDOR_DEVICE_PATH_WITH_DATA*)MediaPath)->VendorDefinedData;
XStringW MediaPathGuidStr = GuidLEToXStringW(*MediaPathGuid);
// DBG(" checking '%ls'\n", MediaPathGuidStr.wc_str());
DBG(" checking '%ls'\n", MediaPathGuidStr.wc_str());
if (StrStr(gEfiBootLoaderPath, MediaPathGuidStr.wc_str())) {
DBG(" - found entry %lld. '%ls', Volume '%ls', '%ls'\n", Index, LoaderEntry.Title.s(), Volume->VolName.wc_str(), LoaderPath.wc_str());
return Index;

View File

@ -2107,7 +2107,7 @@ EFI_STATUS GetEarlyUserSettings (
const TagStruct* Prop = BootDict->propertyForKey("Timeout");
if (Prop != NULL) {
settingsData.Boot.Timeout = (INT32)GetPropertyAsInteger(Prop, settingsData.Boot.Timeout);
DBG("timeout set to %lld\n", settingsData.Boot.Timeout);
DBG("timeout set to %lld\n", settingsData.Boot.Timeout);
}
Prop = BootDict->propertyForKey("SkipHibernateTimeout");

View File

@ -1018,6 +1018,7 @@ void LOADER_ENTRY::StartLoader()
// Seems that Lilu must be first.
size_t pos = setKextAtPos(&kextArray, "Lilu.kext"_XS8, 0);
pos = setKextAtPos(&kextArray, "VirtualSMC.kext"_XS8, pos);
// pos = setKextAtPos(&kextArray, "FakeSMC.kext"_XS8, pos);
pos = setKextAtPos(&kextArray, "FakePCIID.kext"_XS8, pos);
pos = setKextAtPos(&kextArray, "FakePCIID_XHCIMux.kext"_XS8, pos);
pos = setKextAtPos(&kextArray, "AMDRyzenCPUPowerManagement.kext"_XS8, pos);