X-Git-Url: https://code.delx.au/refind/blobdiff_plain/672b9a0c278036e626685ab3439631c298909a22..6720031b85a48ad6f6a651efb6bb5030c41b610d:/refind/apple.c diff --git a/refind/apple.c b/refind/apple.c index d9ce975..437b523 100644 --- a/refind/apple.c +++ b/refind/apple.c @@ -24,49 +24,51 @@ #include "lib.h" #include "screen.h" #include "apple.h" +#include "mystrings.h" #include "refit_call_wrapper.h" -CHAR16 *gCsrStatus = NULL; +CHAR16 gCsrStatus[256]; // Get CSR (Apple's System Integrity Protection [SIP], or "rootless") status -// byte. Return values: -// -2 = Call succeeded but returned value of unexpected length, so result -// is suspect -// -1 = Call failed; likely not an Apple, or an Apple running OS X version -// that doesn't support CSR/SIP -// 0-127 = Valid values (as of 11/2015) -// 128-255 = High bit set unexpectedly, but value still returned -INTN GetCsrStatus(VOID) { - CHAR8 *CsrValues; - UINTN CsrLength; - EFI_GUID CsrGuid = CSR_GUID; - EFI_STATUS Status; - - Status = EfivarGetRaw(&CsrGuid, L"csr-active-config", &CsrValues, &CsrLength); - if (Status == EFI_SUCCESS) { - if (CsrLength == 4) { - return CsrValues[0]; - } else { - return -2; - } - } else { - return -1; - } +// information. If the variable is not present and the firmware is Apple, fake +// it and claim it's enabled, since that's how OS X 10.11 treats a system with +// the variable absent. +EFI_STATUS GetCsrStatus(UINT32 *CsrStatus) { + UINT32 *ReturnValue = NULL; + UINTN CsrLength; + EFI_GUID CsrGuid = CSR_GUID; + EFI_STATUS Status = EFI_INVALID_PARAMETER; + + if (CsrStatus) { + Status = EfivarGetRaw(&CsrGuid, L"csr-active-config", (CHAR8**) &ReturnValue, &CsrLength); + if (Status == EFI_SUCCESS) { + if (CsrLength == 4) { + *CsrStatus = *ReturnValue; + } else { + Status = EFI_BAD_BUFFER_SIZE; + SPrint(gCsrStatus, 255, L" Unknown System Integrity Protection version"); + } + MyFreePool(ReturnValue); + } else if ((Status == EFI_NOT_FOUND) && (StriSubCmp(L"Apple", ST->FirmwareVendor))) { + *CsrStatus = SIP_ENABLED; + Status = EFI_SUCCESS; + } // if (Status == EFI_SUCCESS) + } // if (CsrStatus) + return Status; } // INTN GetCsrStatus() -// Store string describing CSR status byte in gCsrStatus variable, which appears -// on the Info page. -VOID RecordgCsrStatus(INTN CsrStatus) { - if (gCsrStatus == NULL) - gCsrStatus = AllocateZeroPool(256 * sizeof(CHAR16)); +// Store string describing CSR status value in gCsrStatus variable, which appears +// on the Info page. If DisplayMessage is TRUE, displays the new value of +// gCsrStatus on the screen for three seconds. +VOID RecordgCsrStatus(UINT32 CsrStatus, BOOLEAN DisplayMessage) { + EG_PIXEL BGColor; + + BGColor.b = 255; + BGColor.g = 175; + BGColor.r = 100; + BGColor.a = 0; switch (CsrStatus) { - case -2: - SPrint(gCsrStatus, 255, L" System Integrity Protection status is unrecognized"); - break; - case -1: - SPrint(gCsrStatus, 255, L"System Integrity Protection status is unrecorded"); - break; case SIP_ENABLED: SPrint(gCsrStatus, 255, L" System Integrity Protection is enabled (0x%02x)", CsrStatus); break; @@ -76,64 +78,38 @@ VOID RecordgCsrStatus(INTN CsrStatus) { default: SPrint(gCsrStatus, 255, L" System Integrity Protection status: 0x%02x", CsrStatus); } // switch -} // VOID RecordgCsrStatus + if (DisplayMessage) { + egDisplayMessage(gCsrStatus, &BGColor); + PauseSeconds(3); + } // if +} // VOID RecordgCsrStatus() // Find the current CSR status and reset it to the next one in the // GlobalConfig.CsrValues list, or to the first value if the current // value is not on the list. -// Returns the value to which the CSR is being set. -INTN RotateCsrValue(VOID) { - INTN CurrentValue; - UINTN Index = 0; - CHAR16 *CurrentValueAsString = NULL; - CHAR16 *TargetValueAsString = NULL; - CHAR16 *ListItem; - CHAR8 TargetCsr[4]; - EFI_GUID CsrGuid = CSR_GUID; - EFI_STATUS Status; - EG_PIXEL BGColor; - - BGColor.b = 255; - BGColor.g = 175; - BGColor.r = 100; - BGColor.a = 0; - CurrentValue = GetCsrStatus(); - if ((CurrentValue >= 0) && GlobalConfig.CsrValues) { - CurrentValueAsString = PoolPrint(L"%02x", CurrentValue); - while (TargetValueAsString == NULL) { - ListItem = FindCommaDelimited(GlobalConfig.CsrValues, Index++); - if (ListItem) { - if (MyStriCmp(ListItem, CurrentValueAsString)) { - TargetValueAsString = FindCommaDelimited(GlobalConfig.CsrValues, Index); - if (TargetValueAsString == NULL) - TargetValueAsString = FindCommaDelimited(GlobalConfig.CsrValues, 0); - } - } else { - TargetValueAsString = FindCommaDelimited(GlobalConfig.CsrValues, 0); - } // if/else - MyFreePool(ListItem); - } // while - TargetCsr[0] = (CHAR8) StrToHex(TargetValueAsString, 0, 2); - Status = EfivarSetRaw(&CsrGuid, L"csr-active-config", TargetCsr, 4, TRUE); - if (Status == EFI_SUCCESS) { - switch (TargetCsr[0]) { - case SIP_ENABLED: - egDisplayMessage(PoolPrint(L"Set System Integrity Protection to enabled (0x%x)", (UINTN) TargetCsr[0]), &BGColor); - break; - case SIP_DISABLED: - egDisplayMessage(PoolPrint(L"Set System Integrity Protection status to disabled (0x%x)", (UINTN) TargetCsr[0]), &BGColor); - break; - default: - egDisplayMessage(PoolPrint(L"Set System Integrity Protection status to 0x%x", (UINTN) TargetCsr[0]), &BGColor); - } - RecordgCsrStatus((INTN) TargetCsr[0]); +VOID RotateCsrValue(VOID) { + UINT32 CurrentValue, TargetCsr; + UINT32_LIST *ListItem; + EFI_GUID CsrGuid = CSR_GUID; + EFI_STATUS Status; + + Status = GetCsrStatus(&CurrentValue); + if ((Status == EFI_SUCCESS) && GlobalConfig.CsrValues) { + ListItem = GlobalConfig.CsrValues; + while ((ListItem != NULL) && (ListItem->Value != CurrentValue)) + ListItem = ListItem->Next; + if (ListItem == NULL || ListItem->Next == NULL) { + TargetCsr = GlobalConfig.CsrValues->Value; } else { - egDisplayMessage(L"Error setting System Integrity Protection status", &BGColor); + TargetCsr = ListItem->Next->Value; } - PauseSeconds(3); + Status = EfivarSetRaw(&CsrGuid, L"csr-active-config", (CHAR8 *) &TargetCsr, 4, TRUE); + if (Status == EFI_SUCCESS) + RecordgCsrStatus(TargetCsr, TRUE); + else + SPrint(gCsrStatus, 255, L" Error setting System Integrity Protection code."); } // if - return (INTN) TargetCsr[0]; -} // INTN RotateCsrValue() +} // VOID RotateCsrValue() /* @@ -166,7 +142,7 @@ EFI_STATUS SetAppleOSInfo() { Status = refit_call3_wrapper(BS->LocateProtocol, &apple_set_os_guid, NULL, (VOID**) &SetOs); - // Not a Mac, so ignore the call.... + // If not a Mac, ignore the call.... if ((Status != EFI_SUCCESS) || (!SetOs)) return EFI_SUCCESS; @@ -186,7 +162,7 @@ EFI_STATUS SetAppleOSInfo() { Print(L"Out of resources in SetAppleOSInfo!\n"); } if ((Status == EFI_SUCCESS) && (SetOs->Version == 2)) - Status = refit_call1_wrapper (SetOs->SetOsVendor, "Apple Inc."); + Status = refit_call1_wrapper (SetOs->SetOsVendor, (CHAR8 *) "Apple Inc."); MyFreePool(AppleOSVersion); } // if (AppleOSVersion) } // if