preliminary include OpenRuntime from OC

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-07-07 22:25:29 +03:00
parent b0444eac74
commit c1f2f96041
26 changed files with 9816 additions and 492 deletions

View File

@ -589,6 +589,7 @@
MemoryFix/OsxAptioFixDrv/OsxAptioFix3Drv.inf
MemoryFix/OsxLowMemFixDrv/OsxLowMemFixDrv.inf
MemoryFix/AptioMemoryFix/AptioMemoryFix.inf
MemoryFix/OpenRuntime/OpenRuntime.inf
!ifdef DEBUG_ON_SERIAL_PORT
MemoryFix/OsxAptioFixDrv/OsxAptioFixDrv.inf {
#

View File

@ -77,29 +77,29 @@
gApplePlatformInfoKeyboardGuid = {0x51871CB9, 0xE25D, 0x44B4, {0x96, 0x99, 0x0E, 0xE8, 0x64, 0x4C, 0xED, 0x69}}
gAppleOsLoadedNamedEventGuid = {0xC5C5DA95, 0x7D5C, 0x45E6, {0x83, 0x72, 0x89, 0xBD, 0x52, 0x6D, 0xE9, 0x56}}
gBootChimeVendorVariableGuid = {0x89D4F995, 0x67E3, 0x4895, {0x8F, 0x18, 0x45, 0x4B, 0x65, 0x1D, 0x92, 0x15}}
# Include/Guid/AppleVariable.h
gAppleCoreStorageVariableGuid = { 0x8D63D4FE, 0xBD3C, 0x4AAD, { 0x88, 0x1D, 0x86, 0xFD, 0x97, 0x4B, 0xC1, 0xDF }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootVariableGuid = { 0x5D62B28D, 0x6ED2, 0x40B4, { 0xA5, 0x60, 0x6C, 0xD7, 0x9B, 0x93, 0xD3, 0x66 }}
# Include/Guid/AppleVariable.h
gAppleWirelessNetworkVariableGuid = { 0x36C28AB5, 0x6566, 0x4C50, { 0x9E, 0xBD, 0xCB, 0xB9, 0x20, 0xF8, 0x38, 0x43 }}
# Include/Guid/AppleVariable.h
gApplePersonalizationVariableGuid = { 0xFA4CE28D, 0xB62F, 0x4C99, { 0x9C, 0xC3, 0x68, 0x15, 0x68, 0x6E, 0x30, 0xF9 }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootSecureVariableGuid = { 0xF68DA75E, 0x1B55, 0x4E70, { 0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootEfiUserVariableGuid = { 0x4E8023FF, 0xA79A, 0x47D1, { 0xA3, 0x42, 0x75, 0x24, 0xCF, 0xC9, 0x6D, 0xC4 }}
# Include/Guid/AppleVariable.h
gAppleNetbootVariableGuid = { 0x37BCBEC7, 0xA645, 0x4215, { 0x97, 0x9E, 0xF5, 0xAE, 0x4D, 0x11, 0x5F, 0x13 }}
# Include/Guid/AppleVariable.h
gAppleSecureBootVariableGuid = { 0x94B73556, 0x2197, 0x4702, { 0x82, 0xA8, 0x3E, 0x13, 0x37, 0xDA, 0xFB, 0xFB }}
# Include/Guid/AppleVariable.h
gAppleCoreStorageVariableGuid = { 0x8D63D4FE, 0xBD3C, 0x4AAD, { 0x88, 0x1D, 0x86, 0xFD, 0x97, 0x4B, 0xC1, 0xDF }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootVariableGuid = { 0x5D62B28D, 0x6ED2, 0x40B4, { 0xA5, 0x60, 0x6C, 0xD7, 0x9B, 0x93, 0xD3, 0x66 }}
# Include/Guid/AppleVariable.h
gAppleWirelessNetworkVariableGuid = { 0x36C28AB5, 0x6566, 0x4C50, { 0x9E, 0xBD, 0xCB, 0xB9, 0x20, 0xF8, 0x38, 0x43 }}
# Include/Guid/AppleVariable.h
gApplePersonalizationVariableGuid = { 0xFA4CE28D, 0xB62F, 0x4C99, { 0x9C, 0xC3, 0x68, 0x15, 0x68, 0x6E, 0x30, 0xF9 }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootSecureVariableGuid = { 0xF68DA75E, 0x1B55, 0x4E70, { 0xB4, 0x1B, 0xA7, 0xB7, 0xA5, 0xB7, 0x58, 0xEA }}
# Include/Guid/AppleVariable.h
gAppleTamperResistantBootEfiUserVariableGuid = { 0x4E8023FF, 0xA79A, 0x47D1, { 0xA3, 0x42, 0x75, 0x24, 0xCF, 0xC9, 0x6D, 0xC4 }}
# Include/Guid/AppleVariable.h
gAppleNetbootVariableGuid = { 0x37BCBEC7, 0xA645, 0x4215, { 0x97, 0x9E, 0xF5, 0xAE, 0x4D, 0x11, 0x5F, 0x13 }}
# Include/Guid/AppleVariable.h
gAppleSecureBootVariableGuid = { 0x94B73556, 0x2197, 0x4702, { 0x82, 0xA8, 0x3E, 0x13, 0x37, 0xDA, 0xFB, 0xFB }}
# Include/Protocol/ApplePartitionInfo.h
gAppleApfsPartitionTypeGuid = {0x7C3457EF, 0x0000, 0x11AA, {0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC}}
@ -112,6 +112,9 @@
gOcVendorVariableGuid = {0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 }}
gOcReadOnlyVariableGuid = {0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A }}
gOcWriteOnlyVariableGuid = {0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 }}
## Include/Microsoft/Guid/MicrosoftVariable.h
gMicrosoftVariableGuid = {0x77FA9ABD, 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B }}
@ -124,7 +127,7 @@
gMsgLogProtocolGuid = {0x511CE018, 0x0018, 0x4002, {0x20, 0x12, 0x17, 0x38, 0x05, 0x01, 0x02, 0x03 }}
## Include/Protocol/EmuVariableControl.h
gEmuVariableControlProtocolGuid = {0x21f41e73, 0xd214, 0x4fcd, {0x85, 0x50, 0x0d, 0x11, 0x51, 0xcf, 0x8e, 0xfb }}
gEmuVariableControlProtocolGuid = {0x21F41E73, 0xD214, 0x4FCD, {0x85, 0x50, 0x0D, 0x11, 0x51, 0xCF, 0x8E, 0xFB}}
#Apple's protocols
gEfiConsoleControlProtocolGuid = {0xF42F7782, 0x012E, 0x4C12, {0x99, 0x56, 0x49, 0xF9, 0x43, 0x04, 0xF7, 0x21}}
@ -134,9 +137,8 @@
gAppleDevicePropertyProtocolGuid = {0x91BD12FE, 0xF6C3, 0x44FB, {0xA5, 0xB7, 0x51, 0x22, 0xAB, 0x30, 0x3A, 0xE0}}
gAppleFirmwarePasswordProtocolGuid = {0x8FFEEB3A, 0x4C98, 0x4630, {0x80, 0x3F, 0x74, 0x0F, 0x95, 0x67, 0x09, 0x1D}}
gAppleKeyStateProtocolGuid = {0x5B213447, 0x6E73, 0x4901, {0xA4, 0xF1, 0xB8, 0x64, 0xF3, 0xB7, 0xA1, 0x72}}
gAppleKeyStateProtocolGuid = {0x5B213447, 0x6E73, 0x4901, {0xA4, 0xF1, 0xB8, 0x64, 0xF3, 0xB7, 0xA1, 0x72}}
gAppleNetBootProtocolGuid = {0x78EE99FB, 0x6A5E, 0x4186, {0x97, 0xDE, 0xCD, 0x0A, 0xBA, 0x34, 0x5A, 0x74}}
gAppleSMCProtocolGuid = {0x17407e5a, 0xaf6c, 0x4ee8, {0x98, 0xa8, 0x00, 0x21, 0x04, 0x53, 0xcd, 0xd9}}
gAppleNetBootProtocolGuid = {0x78EE99FB, 0x6A5E, 0x4186, {0x97, 0xDE, 0xCD, 0x0A, 0xBA, 0x34, 0x5A, 0x74}}
gAppleSMCProtocolGuid = {0x17407E5A, 0xAF6C, 0x4EE8, {0x98, 0xA8, 0x00, 0x21, 0x04, 0x53, 0xCD, 0xD9}}
gAppleSMCStateProtocolGuid = {0x5301FE59, 0x1770, 0x4166, {0xA1, 0x69, 0x00, 0xC4, 0xBD, 0xE4, 0xA1, 0x62}}
gEfiOSInfoProtocolGuid = {0xC5C5DA95, 0x7D5C, 0x45E6, {0xB2, 0xF1, 0x3F, 0xD5, 0x2B, 0xB1, 0x00, 0x77}}
gAppleUserInterfaceThemeProtocolGuid = {0xD5B0AC65, 0x9A2D, 0x4D2A, {0xBB, 0xD6, 0xE8, 0x71, 0xA9, 0x5E, 0x04, 0x35}}
@ -149,15 +151,17 @@
# gEfiHashAlgorithmSha1Guid = {0x2AE9D80F, 0x3fB2, 0x4095, {0xB7, 0xB1, 0xE9, 0x31, 0x57, 0xB9, 0x46, 0xB6}}
gEfiHdaControllerInfoProtocolGuid = { 0xE5FC2CAF, 0x0291, 0x46F2, { 0x87, 0xF8, 0x10, 0xC7, 0x58, 0x72, 0x58, 0x04 }}
gEfiHdaIoProtocolGuid = { 0xA090D7F9, 0xB50A, 0x4EA1, { 0xBD, 0xE9, 0x1A, 0xA5, 0xE9, 0x81, 0x2F, 0x45 }}
gEfiHdaCodecInfoProtocolGuid = { 0x6C9CDDE1, 0xE8A5, 0x43E5, { 0xBE, 0x88, 0xDA, 0x15, 0xBC, 0x1C, 0x02, 0x50 }}
gEfiAudioIoProtocolGuid = { 0xF05B559C, 0x1971, 0x4AF5, { 0xB2, 0xAE, 0xD6, 0x08, 0x08, 0xF7, 0x4F, 0x70 }}
gEfiHdaControllerInfoProtocolGuid = {0xE5FC2CAF, 0x0291, 0x46F2, {0x87, 0xF8, 0x10, 0xC7, 0x58, 0x72, 0x58, 0x04}}
gEfiHdaIoProtocolGuid = {0xA090D7F9, 0xB50A, 0x4EA1, {0xBD, 0xE9, 0x1A, 0xA5, 0xE9, 0x81, 0x2F, 0x45}}
gEfiHdaCodecInfoProtocolGuid = {0x6C9CDDE1, 0xE8A5, 0x43E5, {0xBE, 0x88, 0xDA, 0x15, 0xBC, 0x1C, 0x02, 0x50}}
gEfiAudioIoProtocolGuid = {0xF05B559C, 0x1971, 0x4AF5, {0xB2, 0xAE, 0xD6, 0x08, 0x08, 0xF7, 0x4F, 0x70}}
## Aptio Fix
gAptioMemoryFixProtocolGuid = { 0xC7CBA84E, 0xCC77, 0x461D, { 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } }
gAmiEfiPointerProtocolGuid = { 0x15A10CE7, 0xEAB5, 0x43BF, { 0x90, 0x42, 0x74, 0x43, 0x2E, 0x69, 0x63, 0x77 } }
gAmiEfiKeycodeProtocolGuid = { 0x0ADFB62D, 0xFF74, 0x484C, { 0x89, 0x44, 0xF8, 0x5C, 0x4B, 0xEA, 0x87, 0xA8 } }
gAptioMemoryFixProtocolGuid = {0xC7CBA84E, 0xCC77, 0x461D, {0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1}}
gAmiEfiPointerProtocolGuid = {0x15A10CE7, 0xEAB5, 0x43BF, {0x90, 0x42, 0x74, 0x43, 0x2E, 0x69, 0x63, 0x77}}
gAmiEfiKeycodeProtocolGuid = {0x0ADFB62D, 0xFF74, 0x484C, {0x89, 0x44, 0xF8, 0x5C, 0x4B, 0xEA, 0x87, 0xA8}}
gOcFirmwareRuntimeProtocolGuid = {0x570332E4, 0xFC50, 0x4B21, {0xAB, 0xE8, 0xAE, 0x72, 0xF0, 0x5B, 0x4F, 0xF7}}

View File

@ -0,0 +1,55 @@
/** @file
Declare the GUID that is expected:
- as EFI_SIGNATURE_DATA.SignatureOwner GUID in association with X509 and
RSA2048 Secure Boot certificates issued by/for Microsoft,
- as UEFI variable vendor GUID in association with (unspecified)
Microsoft-owned variables.
Copyright (C) 2014-2019, Red Hat, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Specification Reference:
- MSDN: System.Fundamentals.Firmware at
<https://msdn.microsoft.com/en-us/ie/dn932805(v=vs.94)>.
**/
#ifndef MICROSOFT_VARIABLE_H
#define MICROSOFT_VARIABLE_H
#include <Uefi/UefiBaseType.h>
//
// The following test cases of the Secure Boot Logo Test in the Microsoft
// Hardware Certification Kit:
//
// - Microsoft.UefiSecureBootLogo.Tests.OutOfBoxVerifyMicrosoftKEKpresent
// - Microsoft.UefiSecureBootLogo.Tests.OutOfBoxConfirmMicrosoftSignatureInDB
//
// expect the EFI_SIGNATURE_DATA.SignatureOwner GUID to be
// 77FA9ABD-0359-4D32-BD60-28F4E78F784B, when the
// EFI_SIGNATURE_DATA.SignatureData field carries any of the following X509
// certificates:
//
// - "Microsoft Corporation KEK CA 2011" (in KEK)
// - "Microsoft Windows Production PCA 2011" (in db)
// - "Microsoft Corporation UEFI CA 2011" (in db)
//
// This is despite the fact that the UEFI specification requires
// EFI_SIGNATURE_DATA.SignatureOwner to reflect the agent (i.e., OS,
// application or driver) that enrolled and therefore owns
// EFI_SIGNATURE_DATA.SignatureData, and not the organization that issued
// EFI_SIGNATURE_DATA.SignatureData.
//
#define MICROSOFT_VENDOR_GUID \
{ 0x77fa9abd, \
0x0359, \
0x4d32, \
{ 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b }, \
}
extern EFI_GUID gMicrosoftVariableGuid;
#endif /* MICROSOFT_VARIABLE_H */

121
Include/Guid/OcVariable.h Normal file
View File

@ -0,0 +1,121 @@
/** @file
Lilu & OpenCore specific GUIDs for UEFI Variable Storage, version 1.0.
Copyright (c) 2019, vit9696. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_VARIABLE_H
#define OC_VARIABLE_H
//
// Variable used for OpenCore log storage (if enabled).
//
#define OC_LOG_VARIABLE_NAME L"boot-log"
//
// Variable used for OpenCore boot path (if enabled).
//
#define OC_LOG_VARIABLE_PATH L"boot-path"
//
// Variable used for OpenCore request to redirect NVRAM Boot variable write.
// Boot Services only.
// See: https://github.com/acidanthera/bugtracker/issues/308.
//
#define OC_BOOT_REDIRECT_VARIABLE_NAME L"boot-redirect"
//
// Variable used for exposing OpenCore Security -> LoadPolicy.
// Boot Services only.
//
#define OC_LOAD_POLICY_VARIABLE_NAME L"load-policy"
//
// Variable used for exposing OpenCore Security -> ScanPolicy.
// Boot Services only.
//
#define OC_SCAN_POLICY_VARIABLE_NAME L"scan-policy"
//
// Variable used to report boot protection.
//
#define OC_BOOT_PROTECT_VARIABLE_NAME L"boot-protect"
//
// Boot protection guids.
//
#define OC_BOOT_PROTECT_VARIABLE_BOOTSTRAP BIT0
#define OC_BOOT_PROTECT_VARIABLE_NAMESPACE BIT1
//
// Variable used to report OpenCore version in the following format:
// REL-001-2019-01-01. This follows versioning style of Lilu and plugins.
//
#define OC_VERSION_VARIABLE_NAME L"opencore-version"
//
// Variable used to report OEM product from SMBIOS Type1 ProductName.
//
#define OC_OEM_PRODUCT_VARIABLE_NAME L"oem-product"
//
// Variable used to report OEM board vendor from SMBIOS Type2 Manufacturer.
//
#define OC_OEM_VENDOR_VARIABLE_NAME L"oem-vendor"
//
// Variable used to report OEM board vendor from SMBIOS Type2 ProductName.
//
#define OC_OEM_BOARD_VARIABLE_NAME L"oem-board"
//
// Variable used to share CPU frequency calculated from ACPI between the drivers.
//
#define OC_ACPI_CPU_FREQUENCY_VARIABLE_NAME L"acpi-cpu-frequency"
//
// Variable used to mark blacklisted RTC values.
//
#define OC_RTC_BLACKLIST_VARIABLE_NAME L"rtc-blacklist"
//
// 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102
// This GUID is specifically used for normal variable access by Lilu kernel extension and its plugins.
//
#define OC_VENDOR_VARIABLE_GUID \
{ 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 } }
//
// E09B9297-7928-4440-9AAB-D1F8536FBF0A
// This GUID is specifically used for reading variables by Lilu kernel extension and its plugins.
// Any writes to this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES.
// The expected return code on variable write is EFI_SECURITY_VIOLATION.
//
#define OC_READ_ONLY_VARIABLE_GUID \
{ 0xE09B9297, 0x7928, 0x4440, { 0x9A, 0xAB, 0xD1, 0xF8, 0x53, 0x6F, 0xBF, 0x0A } }
//
// F0B9AF8F-2222-4840-8A37-ECF7CC8C12E1
// This GUID is specifically used for reading variables by Lilu and plugins.
// Any reads from this GUID should be prohibited via EFI_RUNTIME_SERVICES after EXIT_BOOT_SERVICES.
// The expected return code on variable read is EFI_SECURITY_VIOLATION.
//
#define OC_WRITE_ONLY_VARIABLE_GUID \
{ 0xF0B9AF8F, 0x2222, 0x4840, { 0x8A, 0x37, 0xEC, 0xF7, 0xCC, 0x8C, 0x12, 0xE1 } }
//
// External global variables with GUID values.
//
extern EFI_GUID gOcVendorVariableGuid;
extern EFI_GUID gOcReadOnlyVariableGuid;
extern EFI_GUID gOcWriteOnlyVariableGuid;
#endif // OC_VARIABLE_H

View File

@ -0,0 +1,144 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_AFTER_BOOT_COMPAT_LIB_H
#define OC_AFTER_BOOT_COMPAT_LIB_H
/**
Apple Boot Compatibility layer configuration.
**/
typedef struct OC_ABC_SETTINGS_ {
///
/// Protect from boot.efi from defragmenting runtime memory. This fixes UEFI runtime services
/// (date and time, NVRAM, power control, etc.) support on many firmwares.
/// Needed basically by everyone that uses SMM implementation of variable services.
///
BOOLEAN AvoidRuntimeDefrag;
///
/// Setup virtual memory mapping after SetVirtualAddresses call. This fixes crashes in many
/// firmwares at early boot as they accidentally access virtual addresses after ExitBootServices.
///
BOOLEAN SetupVirtualMap;
///
/// Provide custom Apple KASLR slide calculation for firmwares with polluted low memory ranges.
/// This also ensures that slide= argument is never passed to the operating system.
///
BOOLEAN ProvideCustomSlide;
///
/// Provide max KASLR slide for firmwares with polluted higher memory ranges.
///
UINT8 ProvideMaxSlide;
///
/// Remove runtime flag from MMIO areas and prevent virtual address assignment for known
/// MMIO regions. This may improve the amount of slides available, but may not work on
/// unknown configurations.
///
BOOLEAN DevirtualiseMmio;
///
/// Disable passing -s to operating system through key presses, to simulate T2 Mac behaviour.
/// Ref: https://support.apple.com/HT201573
///
BOOLEAN DisableSingleUser;
///
/// Discard UEFI memory map after waking from hibernation and preserve the original mapping.
///
BOOLEAN DiscardHibernateMap;
///
/// Try to patch Apple bootloader to have KASLR enabled even in SafeMode.
///
BOOLEAN EnableSafeModeSlide;
///
/// Attempt to protect certain memory regions from being incorrectly mapped:
/// - CSM region could get used by the kernel due to being BS data,
/// which caused caused wake issues on older firmwares.
/// - MMIO regions can be marked as reserved memory and be thus unmapped,
/// which caused boot failures when accessing NVRAM.
///
BOOLEAN ProtectMemoryRegions;
///
/// Rebuild memory map to be compatible with Apple kernel.
/// - Apply memory attributes and split RT entries into code and data.
/// - Reduce memory map entries through grouping to fit into 4KB.
///
BOOLEAN RebuildAppleMemoryMap;
///
/// Ensure that ExitBootServices call succeeds even with outdated MemoryMap key.
///
BOOLEAN ForceExitBootServices;
///
/// Disable NVRAM variable write support to protect from malware or to prevent
/// buggy NVRAM implementations cause system issues.
///
BOOLEAN DisableVariableWrite;
///
/// Protect secure boot variables.
///
BOOLEAN ProtectSecureBoot;
///
/// Permit writing to executable memory in UEFI runtime services. Fixes crashes
/// on many APTIO V firmwares.
///
BOOLEAN EnableWriteUnprotector;
///
/// Signal OSInfo protocol that every loaded non-macOS OS is macOS.
/// Works around disabled IGPU in Windows and Linux on Apple laptops.
///
BOOLEAN SignalAppleOS;
///
/// CoreImage may update and restore GetMemoryMap during loading (see InsertImageRecord)
/// as it needs this for segment splitting. Unfortunately it assumes nobody else
/// changes GetMemoryMap, and thus restores to its own CoreGetMemoryMap instead of
/// the previous value. Fix it here.
/// To make it worse VMware also replaces GetMemoryMap pointer in MacMisc, which CoreDxe
/// effectively trashes when we load drivers. As a result without this hack VMware Fusion
/// may show "Your Mac OS guest might run unreliably with more than one virtual core."
/// message when running OpenCore.
///
BOOLEAN ProtectUefiServices;
///
/// Fix OpenRuntime permissions in the memory map and memory attributes.
///
BOOLEAN SyncRuntimePermissions;
///
/// List of physical addresses to not be devirtualised by DevirtualiseMmio.
///
EFI_PHYSICAL_ADDRESS *MmioWhitelist;
///
/// Size of list of physical addresses to not be devirtualised by DevirtualiseMmio.
///
UINTN MmioWhitelistSize;
///
/// List of NULL-terminated handlers for TPL_APPLICATION execution within ExitBootServices.
///
EFI_EVENT_NOTIFY *ExitBootServicesHandlers;
///
/// List of handler contexts for ExitBootServicesHandlers.
///
VOID **ExitBootServicesHandlerContexts;
} OC_ABC_SETTINGS;
/**
Initialize Apple Boot Compatibility layer. This layer is needed on partially
incompatible firmwares to prevent boot failure and UEFI services breakage.
@param[in] Settings Compatibility layer configuration.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcAbcInitialize (
IN OC_ABC_SETTINGS *Settings
);
#endif // OC_AFTER_BOOT_COMPAT_LIB_H

View File

@ -0,0 +1,188 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_APPLE_BOOT_POLICY_LIB_H
#define OC_APPLE_BOOT_POLICY_LIB_H
#include <Protocol/AppleBootPolicy.h>
/**
Install and initialise Apple Boot policy protocol.
@param[in] Reinstall Overwrite installed protocol.
@retval installed or located protocol or NULL.
**/
APPLE_BOOT_POLICY_PROTOCOL *
OcAppleBootPolicyInstallProtocol (
IN BOOLEAN Reinstall
);
EFI_STATUS
OcGetBooterFromPredefinedPathList (
IN EFI_HANDLE Device,
IN EFI_FILE_PROTOCOL *Root,
IN CONST CHAR16 **PredefinedPaths,
IN UINTN NumPredefinedPaths,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL,
IN CHAR16 *Prefix OPTIONAL
);
/**
Locates the bootable file of the given volume. Prefered are the values
blessed, though if unavailable, hard-coded names are being verified and used
if existing.
The blessed paths are to be determined by the HFS Driver via
EFI_FILE_PROTOCOL.GetInfo(). The related identifier definitions are to be
found in AppleBless.h.
@param[in] Device Thed device's Handle to perform the search on.
@param[in] PredefinedPaths An array of file paths to scan for if no file
was blessed.
@param[in] NumPredefinedPaths The number of paths in PredefinedPaths.
@param[out] FilePath A pointer to the device path pointer to set to
the file path of the boot file.
@retval EFI_NOT_FOUND A bootable file could not be found on the given
volume.
@retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation
could not be allocated.
@retval EFI_SUCCESS The operation completed successfully and the
BootFilePath Buffer has been filled.
@retval other The status of an operation used to complete
this operation is returned.
**/
EFI_STATUS
OcBootPolicyGetBootFile (
IN EFI_HANDLE Device,
IN CONST CHAR16 **PredefinedPaths,
IN UINTN NumPredefinedPaths,
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
);
/**
Please refer to OcBootPolicyGetBootFile. This function extends the
functionality by supporting the APFS Preboot scheme.
@param[in] Device Thed device's Handle to perform the search on.
@param[in] PredefinedPaths An array of file paths to scan for if no file
was blessed.
@param[in] NumPredefinedPaths The number of paths in PredefinedPaths.
@param[out] FilePath A pointer to the device path pointer to set to
the file path of the boot file.
@retval EFI_NOT_FOUND A bootable file could not be found on the given
volume.
@retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation
could not be allocated.
@retval EFI_SUCCESS The operation completed successfully and the
BootFilePath Buffer has been filled.
@retval other The status of an operation used to complete
this operation is returned.
**/
EFI_STATUS
OcBootPolicyGetBootFileEx (
IN EFI_HANDLE Device,
IN CONST CHAR16 **PredefinedPaths,
IN UINTN NumPredefinedPaths,
OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
);
/**
Retrieves information about DevicePath.
@param[in] DevicePath The device path to describe.
@param[out] BootPathName A pointer into which the folder portion of
DevicePath is returned.
@param[out] Device A pointer into which the device handle of
DevicePath is returned.
@retval EFI_SUCCESS The operation has been completed successfully.
@retval other DevicePath is not a valid file path.
**/
EFI_STATUS
OcBootPolicyDevicePathToDirPath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT CHAR16 **BootPathName,
OUT EFI_HANDLE *Device
);
/**
Retrieves path info for the APFS Recovery volume associated with the APFS
volume given by DevicePath.
@param[in] DevicePath The device path to the APFS recovery volume.
@param[in] PathName The file path to open.
@param[in] PredefinedPaths An array of file paths to scan for if no file
was blessed.
@param[in] NumPredefinedPaths The number of paths in PredefinedPaths.
@param[out] FullPathName A pointer into which the full file path for
DevicePath and PathName is returned.
@param[out] Root A pointer into which the opened Recovery
volume root protocol is returned.
@param[out] DeviceHandle A pointer into which the device handle of
DevicePath is returned.
@retval EFI_SUCCESS The operation has been completed successfully.
@retval EFI_NOT_FOUND The file path could not be found.
@retval other An unexpected error has occured.
**/
EFI_STATUS
OcBootPolicyGetApfsRecoveryFilePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST CHAR16 *PathName,
IN CONST CHAR16 **PredefinedPaths,
IN UINTN NumPredefinedPaths,
OUT CHAR16 **FullPathName,
OUT EFI_FILE_PROTOCOL **Root,
OUT EFI_HANDLE *DeviceHandle
);
/*
Retrieves all valid APFS Recovery instances on the system.
The APFS Recovery instance associated with the APFS volume referenced by
Handle is moved to index 0, if present.
@param[in] Handle If given, the Recovery instance associated with
this handle is added first.
@param[out] Volumes A pointer the APFS Recovery instances info is
returned into.
@param[out] NumberOfEntries A pointer into which the number of entries in
Volumes is returned.
@retval EFI_SUCCESS The operation has been completed successfully.
@retval EFI_NOT_FOUND No valid APFS Recovery instance could be found.
@retval other An unexpected error has occured.
*/
EFI_STATUS
OcBootPolicyGetAllApfsRecoveryFilePath (
IN EFI_HANDLE Handle OPTIONAL,
OUT VOID **Volumes,
OUT UINTN *NumberOfEntries
);
extern CONST CHAR16 *gAppleBootPolicyPredefinedPaths[];
///
/// All Apple Boot Policy predefined booter paths.
///
extern CONST UINTN gAppleBootPolicyNumPredefinedPaths;
///
/// Core Apple Boot Policy predefined booter paths.
///
extern CONST UINTN gAppleBootPolicyCoreNumPredefinedPaths;
#endif // OC_APPLE_BOOT_POLICY_LIB_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,541 @@
/** @file
OcCryptoLib
Copyright (c) 2018, savvas
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_CRYPTO_LIB_H
#define OC_CRYPTO_LIB_H
#include <Library/OcGuardLib.h>
//
// Default to 128-bit key length for AES.
//
#ifndef CONFIG_AES_KEY_SIZE
#define CONFIG_AES_KEY_SIZE 16
#endif
//
// Digest sizes.
//
#define MD5_DIGEST_SIZE 16
#define SHA1_DIGEST_SIZE 20
#define SHA256_DIGEST_SIZE 32
#define SHA384_DIGEST_SIZE 48
#define SHA512_DIGEST_SIZE 64
#define OC_MAX_SHA_DIGEST_SIZE SHA512_DIGEST_SIZE
//
// Block sizes.
//
#define SHA256_BLOCK_SIZE 64
#define SHA512_BLOCK_SIZE 128
#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE
//
// Derived parameters.
//
#define AES_BLOCK_SIZE 16
//
// Support all AES key sizes.
//
#if CONFIG_AES_KEY_SIZE == 32
#define AES_KEY_EXP_SIZE 240
#elif CONFIG_AES_KEY_SIZE == 24
#define AES_KEY_EXP_SIZE 208
#elif CONFIG_AES_KEY_SIZE == 16
#define AES_KEY_EXP_SIZE 176
#else
#error "Only AES-128, AES-192, and AES-256 are supported!"
#endif
//
// ChaCha key size.
//
#define CHACHA_KEY_SIZE 32
//
// ChaCha IV size.
//
#define CHACHA_IV_SIZE 12
//
// Possible RSA algorithm types supported by OcCryptoLib
// for RSA digital signature verification
// PcdOcCryptoAllowedSigHashTypes MUST be kept in sync with changes!
//
typedef enum OC_SIG_HASH_TYPE_ {
OcSigHashTypeSha256,
OcSigHashTypeSha384,
OcSigHashTypeSha512,
OcSigHashTypeMax
} OC_SIG_HASH_TYPE;
typedef struct AES_CONTEXT_ {
UINT8 RoundKey[AES_KEY_EXP_SIZE];
UINT8 Iv[AES_BLOCK_SIZE];
} AES_CONTEXT;
typedef struct CHACHA_CONTEXT_ {
UINT32 Input[16];
} CHACHA_CONTEXT;
typedef struct MD5_CONTEXT_ {
UINT8 Data[64];
UINT32 DataLen;
UINT64 BitLen;
UINT32 State[4];
} MD5_CONTEXT;
typedef struct SHA1_CONTEXT_ {
UINT8 Data[64];
UINT32 DataLen;
UINT64 BitLen;
UINT32 State[5];
UINT32 K[4];
} SHA1_CONTEXT;
typedef struct SHA256_CONTEXT_ {
UINT8 Data[64];
UINT32 DataLen;
UINT64 BitLen;
UINT32 State[8];
} SHA256_CONTEXT;
typedef struct SHA512_CONTEXT_ {
UINT64 TotalLength;
UINTN Length;
UINT8 Block[2 * SHA512_BLOCK_SIZE];
UINT64 State[8];
} SHA512_CONTEXT;
typedef SHA512_CONTEXT SHA384_CONTEXT;
#pragma pack(push, 1)
///
/// The structure describing the RSA Public Key format.
/// The exponent is always 65537.
///
typedef PACKED struct {
///
/// The number of 64-bit values of N and RSqrMod each.
///
UINT16 NumQwords;
///
/// Padding for 64-bit alignment. Must be 0 to allow future extensions.
///
UINT8 Reserved[6];
///
/// The Montgomery Inverse in 64-bit space: -1 / N[0] mod 2^64.
///
UINT64 N0Inv;
} OC_RSA_PUBLIC_KEY_HDR;
typedef PACKED struct {
///
/// The RSA Public Key header structure.
///
OC_RSA_PUBLIC_KEY_HDR Hdr;
///
/// The Modulus and Montgomery's R^2 mod N in little endian byte order.
///
UINT64 Data[];
} OC_RSA_PUBLIC_KEY;
#pragma pack(pop)
//
// Functions prototypes
//
VOID
AesInitCtxIv (
OUT AES_CONTEXT *Context,
IN CONST UINT8 *Key,
IN CONST UINT8 *Iv
);
VOID
AesSetCtxIv (
OUT AES_CONTEXT *Context,
IN CONST UINT8 *Iv
);
//
// Data size MUST be mutiple of AES_BLOCK_SIZE;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for Padding scheme
// NOTES: you need to set Iv in Context via AesInitCtxIv() or AesSetCtxIv()
// no Iv should ever be reused with the same key
//
VOID
AesCbcEncryptBuffer (
IN OUT AES_CONTEXT *Context,
IN OUT UINT8 *Data,
IN UINT32 Len
);
VOID
AesCbcDecryptBuffer (
IN OUT AES_CONTEXT *Context,
IN OUT UINT8 *Data,
IN UINT32 Len
);
//
// Same function for encrypting as for decrypting.
// Iv is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for Padding scheme
// NOTES: you need to set Iv in Context via AesInitCtxIv() or AesSetCtxIv()
// no Iv should ever be reused with the same key
//
VOID
AesCtrXcryptBuffer (
IN OUT AES_CONTEXT *Context,
IN OUT UINT8 *Data,
IN UINT32 Len
);
/**
Setup ChaCha context (IETF variant).
@param[out] Context ChaCha context.
@param[in] Key ChaCha 256-bit key.
@param[in] Iv ChaCha 96-bit initialisation vector.
@param[in] Counter ChaCha 32-bit counter.
**/
VOID
ChaChaInitCtx (
OUT CHACHA_CONTEXT *Context,
IN CONST UINT8 *Key,
IN CONST UINT8 *Iv,
IN UINT32 Counter
);
/**
Perform ChaCha encryption/decryption.
Source may match Destination.
@param[in,out] Context ChaCha context.
@param[in] Source Data for transformation.
@param[out] Destination Resulting data.
@param[in] Length Data and ciphertext lengths.
**/
VOID
ChaChaCryptBuffer (
IN OUT CHACHA_CONTEXT *Context,
IN CONST UINT8 *Source,
OUT UINT8 *Destination,
IN UINT32 Length
);
VOID
Md5Init (
MD5_CONTEXT *Context
);
VOID
Md5Update (
MD5_CONTEXT *Context,
CONST UINT8 *Data,
UINTN Len
);
VOID
Md5Final (
MD5_CONTEXT *Context,
UINT8 *Hash
);
VOID
Md5 (
UINT8 *Hash,
UINT8 *Data,
UINTN Len
);
VOID
Sha1Init (
SHA1_CONTEXT *Context
);
VOID
Sha1Update (
SHA1_CONTEXT *Context,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha1Final (
SHA1_CONTEXT *Context,
UINT8 *Hash
);
VOID
Sha1 (
UINT8 *Hash,
UINT8 *Data,
UINTN Len
);
VOID
Sha256Init (
SHA256_CONTEXT *Context
);
VOID
Sha256Update (
SHA256_CONTEXT *Context,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha256Final (
SHA256_CONTEXT *Context,
UINT8 *HashDigest
);
VOID
Sha256 (
UINT8 *Hash,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha512Init (
SHA512_CONTEXT *Context
);
VOID
Sha512Update (
SHA512_CONTEXT *Context,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha512Final (
SHA512_CONTEXT *Context,
UINT8 *HashDigest
);
VOID
Sha512 (
UINT8 *Hash,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha384Init (
SHA384_CONTEXT *Context
);
VOID
Sha384Update (
SHA384_CONTEXT *Context,
CONST UINT8 *Data,
UINTN Len
);
VOID
Sha384Final (
SHA384_CONTEXT *Context,
UINT8 *HashDigest
);
VOID
Sha384 (
UINT8 *Hash,
CONST UINT8 *Data,
UINTN Len
);
/**
Verifies Data against Hash with the appropiate SHA2 algorithm for HashSize.
@param[in] Data The data to verify the hash of.
@param[in] DataSize The, in bytes, of Data.
@param[in] Hash The reference hash to verify against.
@param[in] HashSize The size, in bytes, of Hash.
@return 0 All HashSize bytes of the two buffers are identical.
@retval Non-zero If HashSize is not a valid SHA2 digest size, -1. Otherwise,
the first mismatched byte in Data's hash subtracted from
the first mismatched byte in Hash.
**/
INTN
SigVerifyShaHashBySize (
IN CONST VOID *Data,
IN UINTN DataSize,
IN CONST UINT8 *Hash,
IN UINTN HashSize
);
/**
Verify a RSA PKCS1.5 signature against an expected hash.
The exponent is always 65537 as per the format specification.
@param[in] Key The RSA Public Key.
@param[in] Signature The RSA signature to be verified.
@param[in] SignatureSize Size, in bytes, of Signature.
@param[in] Hash The Hash digest of the signed data.
@param[in] HashSize Size, in bytes, of Hash.
@param[in] Algorithm The RSA algorithm used.
@returns Whether the signature has been successfully verified as valid.
**/
BOOLEAN
RsaVerifySigHashFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Hash,
IN UINTN HashSize,
IN OC_SIG_HASH_TYPE Algorithm
);
/**
Verify RSA PKCS1.5 signed data against its signature.
The modulus' size must be a multiple of the configured BIGNUM word size.
This will be true for any conventional RSA, which use two's potencies.
@param[in] Modulus The RSA modulus byte array.
@param[in] ModulusSize The size, in bytes, of Modulus.
@param[in] Exponent The RSA exponent.
@param[in] Signature The RSA signature to be verified.
@param[in] SignatureSize Size, in bytes, of Signature.
@param[in] Data The signed data to verify.
@param[in] DataSize Size, in bytes, of Data.
@param[in] Algorithm The RSA algorithm used.
@returns Whether the signature has been successfully verified as valid.
**/
BOOLEAN
RsaVerifySigDataFromData (
IN CONST UINT8 *Modulus,
IN UINTN ModulusSize,
IN UINT32 Exponent,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
);
/**
Verify RSA PKCS1.5 signed data against its signature.
The modulus' size must be a multiple of the configured BIGNUM word size.
This will be true for any conventional RSA, which use two's potencies.
The exponent is always 65537 as per the format specification.
@param[in] Key The RSA Public Key.
@param[in] Signature The RSA signature to be verified.
@param[in] SignatureSize Size, in bytes, of Signature.
@param[in] Data The signed data to verify.
@param[in] DataSize Size, in bytes, of Data.
@param[in] Algorithm The RSA algorithm used.
@returns Whether the signature has been successfully verified as valid.
**/
BOOLEAN
RsaVerifySigDataFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
);
/**
Performs a cryptographically secure comparison of the contents of two
buffers.
This function compares Length bytes of SourceBuffer to Length bytes of
DestinationBuffer in a cryptographically secure fashion. This especially
implies that different lengths of the longest shared prefix do not change
execution time in a way relevant to security.
If Length > 0 and DestinationBuffer is NULL, then ASSERT().
If Length > 0 and SourceBuffer is NULL, then ASSERT().
If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
@param DestinationBuffer The pointer to the destination buffer to compare.
@param SourceBuffer The pointer to the source buffer to compare.
@param Length The number of bytes to compare.
@return 0 All Length bytes of the two buffers are identical.
@retval -1 The two buffers are not identical within Length
bytes.
**/
INTN
SecureCompareMem (
IN CONST VOID *DestinationBuffer,
IN CONST VOID *SourceBuffer,
IN UINTN Length
);
/**
Performs a cryptographically secure memory zeroing.
If Length > 0 and Buffer is NULL, then ASSERT().
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
@param[out] Buffer The pointer to the destination buffer to zero.
@param[in] Length The number of bytes to zero.
@return Buffer.
**/
VOID *
SecureZeroMem (
OUT VOID *Buffer,
IN UINTN Length
);
/**
Verify Password and Salt against RefHash. The used hash function is SHA-512,
thus the caller must ensure RefHash is at least 64 bytes in size.
@param[in] Password The entered password to verify.
@param[in] PasswordSize The size, in bytes, of Password.
@param[in] Salt The cryptographic salt appended to Password on hash.
@param[in] SaltSize The size, in bytes, of Salt.
@param[in] RefHash The SHA-512 hash of the reference password and Salt.
@returns Whether Password and Salt cryptographically match RefHash.
**/
BOOLEAN
OcVerifyPasswordSha512 (
IN CONST UINT8 *Password,
IN UINT32 PasswordSize,
IN CONST UINT8 *Salt,
IN UINT32 SaltSize,
IN CONST UINT8 *RefHash
);
#endif // OC_CRYPTO_LIB_H

305
Include/Library/OcDevicePathLib.h Executable file
View File

@ -0,0 +1,305 @@
/** @file
Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_DEVICE_PATH_LIB_H
#define OC_DEVICE_PATH_LIB_H
/**
Append file name to device path.
@param[in] DevicePath The device path which to append the file path.
@param[in] FileName The file name to append to the device path.
@retval EFI_SUCCESS The defaults were initialized successfully.
@retval EFI_INVALID_PARAMETER The parameters passed were invalid.
@retval EFI_OUT_OF_RESOURCES The system ran out of memory.
**/
EFI_DEVICE_PATH_PROTOCOL *
AppendFileNameDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CHAR16 *FileName
);
/**
Locate the node inside the device path specified by Type an SubType values.
@param[in] DevicePath The device path used in the search.
@param[in] Type The Type field of the device path node specified by Node.
@param[in] SubType The SubType field of the device path node specified by Node.
@return Returned is the first Device Path Node with the given type.
**/
EFI_DEVICE_PATH_PROTOCOL *
FindDevicePathNodeWithType (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN UINT8 Type,
IN UINT8 SubType OPTIONAL
);
/**
Check whether device paths are equal.
@param[in] DevicePath1 The first device path protocol to compare.
@param[in] DevicePath2 The second device path protocol to compare.
@retval TRUE The device paths matched
@retval FALSE The device paths were different
**/
BOOLEAN
EFIAPI
IsDevicePathEqual (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
);
/**
Check whether File Device Paths are equal.
@param[in] FilePath1 The first device path protocol to compare.
@param[in] FilePath2 The second device path protocol to compare.
@retval TRUE The device paths matched
@retval FALSE The device paths were different
**/
BOOLEAN
FileDevicePathsEqual (
IN FILEPATH_DEVICE_PATH *FilePath1,
IN FILEPATH_DEVICE_PATH *FilePath2
);
/**
Check whether one device path exists in the other.
@param[in] ParentPath The parent device path protocol to check against.
@param[in] ChildPath The device path protocol of the child device to compare.
@retval TRUE The child device path contains the parent device path.
@retval FALSE The device paths were different
**/
BOOLEAN
EFIAPI
IsDevicePathChild (
IN EFI_DEVICE_PATH_PROTOCOL *ParentPath,
IN EFI_DEVICE_PATH_PROTOCOL *ChildPath
);
/**
Get absolute device path.
@param[in] Handle Device handle.
@param[in] RelativePath Relative device path to handle, optional.
@retval New device path or NULL.
**/
EFI_DEVICE_PATH_PROTOCOL *
AbsoluteDevicePath (
IN EFI_HANDLE Handle,
IN EFI_DEVICE_PATH_PROTOCOL *RelativePath OPTIONAL
);
/**
Get trailed (slash-appended) device path for booter paths.
This way \\smth.efi gets NULL and \\smth gives \\smth\\.
@param[in] DevicePath Device path.
@retval New device path or NULL.
**/
EFI_DEVICE_PATH_PROTOCOL *
TrailedBooterDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
/**
Returns the size of PathName.
@param[in] FilePath The file Device Path node to inspect.
@retval Name size in bytes.
**/
UINTN
OcFileDevicePathNameSize (
IN CONST FILEPATH_DEVICE_PATH *FilePath
);
/**
Returns the length of PathName.
@param[in] FilePath The file Device Path node to inspect.
@retval Name length in characters (without trailing zero).
**/
UINTN
OcFileDevicePathNameLen (
IN CONST FILEPATH_DEVICE_PATH *FilePath
);
/**
Retrieve the size of the full file path described by DevicePath.
@param[in] DevicePath The Device Path to inspect.
@returns The size of the full file path.
@retval 0 DevicePath does not start with a File Path node or contains
non-terminating nodes that are not File Path nodes.
**/
UINTN
OcFileDevicePathFullNameSize (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
/**
Retrieve the full file path described by FilePath.
The caller is expected to call OcFileDevicePathFullNameSize() or ensure its
guarantees are met.
@param[out] PathName On output, the full file path of FilePath.
@param[in] FilePath The File Device Path to inspect.
@param[in] PathNameSize The size, in bytes, of PathnName. Must equal the
actual fill file path size.
**/
VOID
OcFileDevicePathFullName (
OUT CHAR16 *PathName,
IN CONST FILEPATH_DEVICE_PATH *FilePath,
IN UINTN PathNameSize
);
/**
Duplicate device path with DevicePathInstance appended if it is not present.
@param[in] DevicePath Device Path to append new instance to, optional.
@param[in] DevicePathInstance Device Path instance to append.
@retval New Device Path or NULL.
**/
EFI_DEVICE_PATH_PROTOCOL *
OcAppendDevicePathInstanceDedupe (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
);
/**
Calculate number of device path instances.
@param[in] DevicePath Device Path to calculate instances in.
@retval Number of instances in device path.
**/
UINTN
OcGetNumDevicePathInstances (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
///
/// Used to store information on how to restore a node patched by
/// OcFixAppleBootDevicePathNode().
///
typedef union {
struct {
UINT16 PortMultiplierPortNumber;
} Sata;
struct {
UINT8 SubType;
} SasExNvme;
struct {
UINT32 HID;
UINT32 UID;
} Acpi;
struct {
UINT32 HID;
UINT32 CID;
} ExtendedAcpi;
} APPLE_BOOT_DP_PATCH_CONTEXT;
/**
Fix Apple Boot Device Path node to be compatible with conventional UEFI
implementations.
@param[in,out] DevicePathNode A pointer to the device path node to fix.
@param[out] RestoreContext A pointer to a context that can be used to
restore DevicePathNode's original content in
the case of failure.
@retval -1 DevicePathNode could not be fixed.
@retval 0 DevicePathNode was not modified and may be valid.
@retval 1 DevicePathNode was fixed and may be valid.
**/
INTN
OcFixAppleBootDevicePathNode (
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
OUT APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext OPTIONAL
);
/**
Restore the original content of DevicePathNode before calling
OcFixAppleBootDevicePathNode() with RestoreContext.
@param[in,out] DevicePathNode A pointer to the device path node to restore.
@param[out] RestoreContext A pointer to a context that was used to call
OcFixAppleBootDevicePathNode().
**/
VOID
OcFixAppleBootDevicePathNodeRestore (
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
IN CONST APPLE_BOOT_DP_PATCH_CONTEXT *RestoreContext
);
/**
Fix Apple Boot Device Path to be compatible with conventional UEFI
implementations. In case -1 is returned and the first node could not be
located or fixed, DevicePath's original state will be preserved. In all other
cases, it may be destroyed.
@param[in,out] DevicePath On input, a pointer to the device path to fix.
On output, the device path pointer is modified to
point to the remaining part of the device path.
@retval -1 *DevicePath could not be fixed.
@retval 0 *DevicePath was not modified and may be valid.
@retval 1 *DevicePath was fixed and may be valid.
**/
INTN
OcFixAppleBootDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
);
/**
Get the next possible full path pointing to the load option.
The routine doesn't guarantee the returned full path points to an existing
file, and it also doesn't guarantee the existing file is a valid load option.
@param FilePath The device path pointing to a load option.
It could be a short-form device path.
@param FullPath The full path returned by the routine in last call.
Set to NULL in first call.
@return The next possible full path pointing to the load option.
Caller is responsible to free the memory.
**/
EFI_DEVICE_PATH_PROTOCOL *
OcGetNextLoadOptionDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_DEVICE_PATH_PROTOCOL *FullPath
);
#endif // OC_DEVICE_PATH_LIB_H

424
Include/Library/OcFileLib.h Executable file
View File

@ -0,0 +1,424 @@
/** @file
Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_FILE_LIB_H
#define OC_FILE_LIB_H
// Include the abstracted protocol for its definitions
#include <Guid/FileInfo.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/DevicePath.h>
#include <Protocol/BlockIo.h>
#include <Protocol/BlockIo2.h>
/**
Maximum safe volume label size.
**/
#define OC_MAX_VOLUME_LABEL_SIZE 64
/**
Locate file system from Device handle or path.
@param[in] DeviceHandle Device handle.
@param[in] FilePath Device path.
@retval simple file system protocol or NULL.
**/
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *
LocateFileSystem (
IN EFI_HANDLE DeviceHandle OPTIONAL,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL
);
/**
Locate root volume from Device handle or path.
@param[in] DeviceHandle Device handle.
@param[in] FilePath Device path.
@retval opened file protocol or NULL.
**/
EFI_FILE_PROTOCOL *
LocateRootVolume (
IN EFI_HANDLE DeviceHandle OPTIONAL,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL
);
/**
Locate file system from GUID.
@param[in] Guid GUID of the volume to locate.
@retval simple file system protocol or NULL.
**/
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *
LocateFileSystemByGuid (
IN CONST GUID *Guid
);
/**
Retrieves volume label.
@param[in] FileSystem A pointer to the file system protocol of the volume.
@retval A pointer to the NULL terminated unicode volume label.
**/
CHAR16 *
GetVolumeLabel (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem
);
/**
Opens a new file relative to the source file's location.
This function is equivalent to EFI_FILE_OPEN but has additional restrictions
to provide board compatibility. Currently the only restriction is
no trailing slash in the filename due to issues in FAT drivers.
- Multiple boards, namely ASUS P8H61-M and P8H61-M LX2 will not
open directories with trailing slash. It is irrelevant whether
front slash is present for them.
For example, it means that L"EFI\\OC\\" or L"\\EFI\\OC\\" will both
fail to open, while L"EFI\\OC" and L"\\EFI\\OC" will open fine.
- Most newer boards on APTIO IV do handle directories with trailing
slash, however, their driver will modify passed string by removing
the slash by \0.
@param Protocol File protocol instance.
@param NewHandle Pointer for returned handle.
@param FileName Null-terminated file name.
@param OpenMode File open mode.
@param Attributes Attributes for the newly created file.
@retval EFI_SUCCESS for successfully opened file.
*/
EFI_STATUS
SafeFileOpen (
IN EFI_FILE_PROTOCOL *Protocol,
OUT EFI_FILE_PROTOCOL **NewHandle,
IN CONST CHAR16 *FileName,
IN UINT64 OpenMode,
IN UINT64 Attributes
);
/**
Read file from device path with implicit double (2 byte) null termination.
Null termination does not affect the returned file size.
Depending on the implementation 0 byte files may return null.
@param[in] FileSystem A pointer to the file system protocol of the volume.
@param[in] FilePath The full path to the file on the device.
@param[out] FileSize The size of the file read (optional).
@param[in] MaxFileSize Upper file size bound (optional).
@retval A pointer to a buffer containing file read or NULL.
**/
VOID *
ReadFile (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
IN CONST CHAR16 *FilePath,
OUT UINT32 *FileSize OPTIONAL,
IN UINT32 MaxFileSize OPTIONAL
);
/**
Determine file size if it is less than 4 GB.
@param[in] FileSystem A pointer to the file system protocol of the volume.
@param[in] FilePath The full path to the file on the device.
@param[out] Size 32-bit file size.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
ReadFileSize (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
IN CONST CHAR16 *FilePath,
OUT UINT32 *Size
);
/**
Read exact amount of bytes from EFI_FILE_PROTOCOL at specified position.
@param[in] File A pointer to the file protocol.
@param[in] Position Position to read data from.
@param[in] Size The size of the data read.
@param[out] Buffer A pointer to previously allocated buffer to read data to.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
GetFileData (
IN EFI_FILE_PROTOCOL *File,
IN UINT32 Position,
IN UINT32 Size,
OUT UINT8 *Buffer
);
/**
Write exact amount of bytes to a newly created file in EFI_FILE_PROTOCOL.
Please note, that several filesystems (or drivers) may limit file name length.
@param[in] WritableFs A pointer to the file protocol, any will be tried if NULL.
@param[in] FileName File name (possibly with path) to write.
@param[in] Buffer A pointer with the data to be written.
@param[in] Size Amount of data to be written.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
SetFileData (
IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL,
IN CONST CHAR16 *FileName,
IN CONST VOID *Buffer,
IN UINT32 Size
);
/**
Get file information of specified type.
@param[in] File A pointer to file handle.
@param[in] InformationType A pointer to file info GUID.
@param[in] MinFileInfoSize Minimal size of the info provided.
@param[out] RealFileInfoSize Actual info size read (optional).
@retval read file info or NULL.
**/
VOID *
GetFileInfo (
IN EFI_FILE_PROTOCOL *File,
IN EFI_GUID *InformationType,
IN UINTN MinFileInfoSize,
OUT UINTN *RealFileInfoSize OPTIONAL
);
/**
Determine file size if it is less than 4 GB.
@param[in] File A pointer to the file protocol.
@param[out] Size 32-bit file size.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
GetFileSize (
IN EFI_FILE_PROTOCOL *File,
OUT UINT32 *Size
);
/**
Determine file modification time.
@param[in] File A pointer to the file protocol.
@param[out] Time Modification time.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
GetFileModifcationTime (
IN EFI_FILE_PROTOCOL *File,
OUT EFI_TIME *Time
);
/**
Determine writeable filesystem.
@param[in,out] WritableFs First found writeable file system.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
FindWritableFileSystem (
IN OUT EFI_FILE_PROTOCOL **WritableFs
);
/**
Open a file or directory by file system handle and path.
See OcOpenFileByDevicePath() for more details.
@param[in] FileSystemHandle File System handle.
@param[in] RemainingDevicePath The remaining Device Path (must be all file
path nodes).
@param[out] File Resulting file protocol.
@param[in] OpenMode File open mode.
@param[in] Attributes File attributes.
@retval EFI_SUCCESS on succesful open.
**/
EFI_STATUS
EFIAPI
OcOpenFileByRemainingDevicePath (
IN EFI_HANDLE FileSystemHandle,
IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
OUT EFI_FILE_PROTOCOL **File,
IN UINT64 OpenMode,
IN UINT64 Attributes
);
/**
Open a file or directory by device path. This is a modified
version of EfiOpenFileByDevicePath function, which handles paths
with trailing slashes, that cause Open failure on old firmwares.
EfiOpenFileByDevicePath is additionally not available in UDK.
See more details at:
https://github.com/tianocore/edk2/commit/768b611136d0f2b99a99e446c089d1a30c3fa5d5
@param[in,out] FilePath Device path protocol.
@param[out] File Resulting file protocol.
@param[in] OpenMode File open mode.
@param[in] Attributes File attributes.
@retval EFI_SUCCESS on succesful open.
**/
EFI_STATUS
EFIAPI
OcOpenFileByDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
OUT EFI_FILE_PROTOCOL **File,
IN UINT64 OpenMode,
IN UINT64 Attributes
);
/**
Retrieve the disk's device handle from a partition's Device Path.
@param[in] HdDevicePath The Device Path of the partition.
@retval device handle or NULL
**/
EFI_HANDLE
OcPartitionGetDiskHandle (
IN EFI_DEVICE_PATH_PROTOCOL *HdDevicePath
);
/**
Locate the disk's EFI System Partition.
@param[in] DiskDevicePath The Device Path of the disk to scan.
@param[out] EspDevicePathSize The size of the returned Device Path.
@param[out] EspDeviceHandle Device handle of the returned partition.
**/
EFI_DEVICE_PATH_PROTOCOL *
OcDiskFindSystemPartitionPath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DiskDevicePath,
OUT UINTN *EspDevicePathSize,
OUT EFI_HANDLE *EspDeviceHandle
);
/**
Disk I/O context.
**/
typedef struct {
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
UINT32 MediaId;
UINT32 BlockSize;
} OC_DISK_CONTEXT;
/**
Initialize disk I/O context.
@param[out] Context Disk I/O context to intialize.
@param[in] DiskHandle Disk handle with protocols.
@param[in] UseBlockIo2 Try to use BlockIo2 protocol if available.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcDiskInitializeContext (
OUT OC_DISK_CONTEXT *Context,
IN EFI_HANDLE DiskHandle,
IN BOOLEAN UseBlockIo2
);
/**
Read information from disk.
@param[in] Context Disk I/O context.
@param[in] Lba LBA number to read from.
@param[in] BufferSize Buffer size allocated in Buffer.
@param[out] Buffer Buffer to store data in.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcDiskRead (
IN OC_DISK_CONTEXT *Context,
IN UINT64 Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
OC partition list.
**/
typedef struct {
UINT32 NumPartitions;
UINT32 PartitionEntrySize;
EFI_PARTITION_ENTRY FirstEntry[];
} OC_PARTITION_ENTRIES;
/**
Retrieve the disk GPT partitions, if applicable.
@param[in] DiskHandle Disk device handle to retrive partition table from.
@param[in] UseBlockIo2 Use 2nd revision of Block I/O if available.
@retval partition entry list or NULL.
**/
CONST OC_PARTITION_ENTRIES *
OcGetDiskPartitions (
IN EFI_HANDLE DiskHandle,
IN BOOLEAN UseBlockIo2
);
/**
Retrieve the partition's GPT information, if applicable.
Calls to this function undergo internal lazy caching.
@param[in] FsHandle The device handle of the partition to retrieve info of.
@retval partition entry or NULL
**/
CONST EFI_PARTITION_ENTRY *
OcGetGptPartitionEntry (
IN EFI_HANDLE FsHandle
);
/**
Unblocks all partition handles without a File System protocol attached from
driver connection, if applicable.
**/
VOID
OcUnblockUnmountedPartitions (
VOID
);
/**
Creates a device path for a firmware file.
@param[in] FileGuid Firmware file GUID.
@retval device path allocated from pool on success.
@retval NULL on failure (e.g. when a file is not present).
**/
EFI_DEVICE_PATH_PROTOCOL *
CreateFvFileDevicePath (
IN EFI_GUID *FileGuid
);
#endif // OC_FILE_LIB_H

View File

@ -0,0 +1,337 @@
/** @file
OcSerializeLib
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_SERIALIZE_LIB_H
#define OC_SERIALIZE_LIB_H
#include <Library/OcXmlLib.h>
#include <Library/OcTemplateLib.h>
typedef struct OC_SCHEMA_ OC_SCHEMA;
typedef union OC_SCHEMA_INFO_ OC_SCHEMA_INFO;
//
// Generic applier interface that knows how to provide Info with data from Node.
//
typedef
VOID
(*OC_APPLY) (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// OC_SCHEMA_INFO for nested dictionaries
//
typedef struct {
//
// Nested schema list.
//
OC_SCHEMA *Schema;
//
// Nested schema list size.
//
UINT32 SchemaSize;
} OC_SCHEMA_DICT;
//
// OC_SCHEMA_INFO for static values
//
typedef enum OC_SCHEMA_VALUE_TYPE_ {
OC_SCHEMA_VALUE_BOOLEAN,
OC_SCHEMA_VALUE_INTEGER,
OC_SCHEMA_VALUE_DATA,
OC_SCHEMA_VALUE_STRING,
OC_SCHEMA_VALUE_MDATA
} OC_SCHEMA_VALUE_TYPE;
typedef struct {
//
// Value pointer.
//
UINTN Field;
//
// Value size.
//
UINT32 FieldSize;
//
// Source type.
//
OC_SCHEMA_VALUE_TYPE Type;
} OC_SCHEMA_VALUE;
//
// OC_SCHEMA_INFO for blob values
//
typedef enum OC_SCHEMA_BLOB_TYPE_ {
OC_SCHEMA_BLOB_DATA,
OC_SCHEMA_BLOB_STRING,
OC_SCHEMA_BLOB_MDATA
} OC_SCHEMA_BLOB_TYPE;
typedef struct {
//
// Blob pointer.
//
UINTN Field;
//
// Source type.
//
OC_SCHEMA_BLOB_TYPE Type;
} OC_SCHEMA_BLOB;
//
// OC_SCHEMA_INFO for array/map lists
//
typedef struct {
//
// List pointer.
//
UINTN Field;
//
// List entry schema.
//
OC_SCHEMA *Schema;
} OC_SCHEMA_LIST;
//
// All standard variants of schema info
//
union OC_SCHEMA_INFO_ {
OC_SCHEMA_DICT Dict;
OC_SCHEMA_VALUE Value;
OC_SCHEMA_BLOB Blob;
OC_SCHEMA_LIST List;
};
//
// Schema context, allowing node recursion.
//
struct OC_SCHEMA_ {
//
// Key name to match against in the dictionary.
//
CONST CHAR8 *Name;
//
// Node type required to match to be able to call Apply.
// PLIST_NODE_TYPE_ANY could be specified if Apply does the validation.
//
PLIST_NODE_TYPE Type;
//
// Apply handler that will merge Node data into object.
//
OC_APPLY Apply;
//
// Information about Node to object bridge.
//
OC_SCHEMA_INFO Info;
};
//
// Find schema in a sorted list
//
OC_SCHEMA *
LookupConfigSchema (
IN OC_SCHEMA *SortedList,
IN UINT32 Size,
IN CONST CHAR8 *Name
);
//
// Apply interface to parse serialized dictionaries
//
VOID
ParseSerializedDict (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// Apply interface to parse serialized OC_SCHEMA_VALUE_TYPE.
//
VOID
ParseSerializedValue (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// Apply interface to parse serialized OC_SCHEMA_BLOB_TYPE.
//
VOID
ParseSerializedBlob (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// Apply interface to parse serialized array
//
VOID
ParseSerializedArray (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// Apply interface to parse serialized map with arbitrary values,
// and OC_STRING strings.
//
VOID
ParseSerializedMap (
OUT VOID *Serialized,
IN XML_NODE *Node,
IN OC_SCHEMA_INFO *Info,
IN CONST CHAR8 *Context OPTIONAL
);
//
// Main interface for parsing serialized data.
// PlistBuffer will be modified during the execution.
//
BOOLEAN
ParseSerialized (
OUT VOID *Serialized,
IN OC_SCHEMA_INFO *RootSchema,
IN VOID *PlistBuffer,
IN UINT32 PlistSize
);
//
// Retrieve typed field pointer from offset
//
#define OC_SCHEMA_FIELD(Base, Type, Offset) \
((Type *)(((UINT8 *) (Base)) + (Offset)))
//
// Smart declaration base macros, see usage below.
//
#define OC_SCHEMA_VALUE(Name, Offset, Type, SourceType) \
{(Name), PLIST_NODE_TYPE_ANY, ParseSerializedValue, \
{.Value = {Offset, sizeof (Type), SourceType}}}
#define OC_SCHEMA_BLOB(Name, Offset, SourceType) \
{(Name), PLIST_NODE_TYPE_ANY, ParseSerializedBlob, \
{.Blob = {Offset, SourceType}}}
//
// Smart declaration macros for builtin appliers,
// which point straight to types.
//
// Name represents dictionary name if any (otherwise NULL).
// Type represents value or value type for size calculation.
// Schema represents element schema.
//
// M prefix stands for Meta, which means meta data type casting is used.
// F suffix stands for Fixed, which means fixed file size is assumed.
//
#define OC_SCHEMA_DICT(Name, Schema) \
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedDict, \
{.Dict = {(Schema), ARRAY_SIZE (Schema)}}}
#define OC_SCHEMA_BOOLEAN(Name) \
OC_SCHEMA_VALUE (Name, 0, BOOLEAN, OC_SCHEMA_VALUE_BOOLEAN)
#define OC_SCHEMA_INTEGER(Name, Type) \
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_INTEGER)
#define OC_SCHEMA_STRING(Name) \
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_STRING)
#define OC_SCHEMA_STRINGF(Name, Type) \
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_STRING)
#define OC_SCHEMA_DATA(Name) \
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_DATA)
#define OC_SCHEMA_DATAF(Name, Type) \
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_DATA)
#define OC_SCHEMA_MDATA(Name) \
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_MDATA)
#define OC_SCHEMA_MDATAF(Name, Type) \
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_MDATA)
#define OC_SCHEMA_ARRAY(Name, ChildSchema) \
{(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \
{.List = {0, ChildSchema}}}
#define OC_SCHEMA_MAP(Name, ChildSchema) \
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \
{.List = {0, ChildSchema}}}
//
// Smart declaration macros for builtin appliers,
// which point to structures, containing these types.
//
// Name represents dictionary name if any (otherwise NULL).
// Type represents container structure type for this value.
// Field represents item in the container type.
// Schema represents element schema.
//
#define OC_SCHEMA_BOOLEAN_IN(Name, Type, Field) \
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
OC_SCHEMA_VALUE_BOOLEAN)
#define OC_SCHEMA_INTEGER_IN(Name, Type, Field) \
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
OC_SCHEMA_VALUE_INTEGER)
#define OC_SCHEMA_STRING_IN(Name, Type, Field) \
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_STRING)
#define OC_SCHEMA_STRINGF_IN(Name, Type, Field) \
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
OC_SCHEMA_VALUE_STRING)
#define OC_SCHEMA_DATA_IN(Name, Type, Field) \
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_DATA)
#define OC_SCHEMA_DATAF_IN(Name, Type, Field) \
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
OC_SCHEMA_VALUE_DATA)
#define OC_SCHEMA_MDATA_IN(Name, Type, Field) \
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_MDATA)
#define OC_SCHEMA_MDATAF_IN(Name, Type, Field) \
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
OC_SCHEMA_VALUE_MDATA)
#define OC_SCHEMA_ARRAY_IN(Name, Type, Field, ChildSchema) \
{(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \
{.List = {OFFSET_OF (Type, Field), ChildSchema}}}
#define OC_SCHEMA_MAP_IN(Name, Type, Field, ChildSchema) \
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \
{.List = {OFFSET_OF (Type, Field), ChildSchema}}}
#endif // OC_SERIALIZE_LIB_H

View File

@ -0,0 +1,155 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_STORAGE_LIB_H
#define OC_STORAGE_LIB_H
#include <Library/OcCryptoLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcFileLib.h>
#include <Library/OcSerializeLib.h>
/**
Storage vault file containing a dictionary with SHA-256 hashes for all files.
**/
#define OC_STORAGE_VAULT_PATH L"vault.plist"
/**
RSA-2048 signature of SHA-256 hash of vault.plist.
**/
#define OC_STORAGE_VAULT_SIGNATURE_PATH L"vault.sig"
/**
Storage vault version declaring vault compatibility.
**/
#define OC_STORAGE_VAULT_VERSION 1
/**
Safe maximum file path in the storage.
**/
#define OC_STORAGE_SAFE_PATH_MAX 128
/**
Structure declaration for valult file.
**/
#define OC_STORAGE_VAULT_HASH_FIELDS(_, __) \
_(UINT8 , Hash , [SHA256_DIGEST_SIZE] , {0} , () )
OC_DECLARE (OC_STORAGE_VAULT_HASH)
#define OC_STORAGE_VAULT_FILES_FIELDS(_, __) \
OC_MAP (OC_STRING, OC_STORAGE_VAULT_HASH, _, __)
OC_DECLARE (OC_STORAGE_VAULT_FILES)
#define OC_STORAGE_VAULT_FIELDS(_, __) \
_(UINT32 , Version , , 0 , () ) \
_(OC_STORAGE_VAULT_FILES , Files , , OC_CONSTR (OC_STORAGE_VAULT_FILES, _, __) , OC_DESTR (OC_STORAGE_VAULT_FILES))
OC_DECLARE (OC_STORAGE_VAULT)
/**
Storage abstraction context
**/
typedef struct {
///
/// Storage file system if any.
///
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
///
/// Storage root owned by context.
///
EFI_FILE_PROTOCOL *StorageRoot;
///
/// Device handle with storage (dummy) device path for loading.
///
EFI_HANDLE StorageHandle;
///
/// Dummy file path for file storage.
///
EFI_DEVICE_PATH_PROTOCOL *DummyDevicePath;
///
/// Dummy file path relative to storage.
///
EFI_DEVICE_PATH_PROTOCOL *DummyFilePath;
///
/// Vault context.
///
OC_STORAGE_VAULT Vault;
///
/// Vault status.
///
BOOLEAN HasVault;
} OC_STORAGE_CONTEXT;
/**
Create storage context from UEFI file system at specified path.
@param[out] Context Resulting storage context.
@param[in] FileSystem Storage file system.
@param[in] Path Storage file system path (e.g. L"\\").
@param[in] StorageKey Storage signature verification key, optional.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcStorageInitFromFs (
OUT OC_STORAGE_CONTEXT *Context,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
IN CONST CHAR16 *Path,
IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL
);
/**
Free storage context resources.
@param[in,out] Context Storage context.
**/
VOID
OcStorageFree (
IN OUT OC_STORAGE_CONTEXT *Context
);
/**
Check whether file exists.
@param[in] Context Storage context.
@param[in] FilePath The full path to the file on the device.
@retval TRUE if file is present in vault or ondisk.
**/
BOOLEAN
OcStorageExistsFileUnicode (
IN OC_STORAGE_CONTEXT *Context,
IN CONST CHAR16 *FilePath
);
/**
Read file from storage with implicit double (2 byte) null termination.
Null termination does not affect the returned file size.
Depending on the implementation 0 byte files may return null.
If storage context was created with valid storage key, then signature
checking will be performed
@param[in] Context Storage context.
@param[in] FilePath The full path to the file on the device.
@param[out] FileSize The size of the file read (optional).
@retval A pointer to a buffer containing file read or NULL.
**/
VOID *
OcStorageReadFileUnicode (
IN OC_STORAGE_CONTEXT *Context,
IN CONST CHAR16 *FilePath,
OUT UINT32 *FileSize OPTIONAL
);
#endif // OC_STORAGE_LIB_H

View File

@ -0,0 +1,290 @@
/** @file
OcTemplateLib
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_TEMPLATE_LIB_H
#define OC_TEMPLATE_LIB_H
#include <Library/BaseMemoryLib.h>
//
// Common structor prototype.
//
typedef
VOID
(*OC_STRUCTOR) (
VOID *Ptr,
UINT32 Size
);
//
// Private primitives for type generations
//
#define PRIV_OC_STRUCTOR_IGNORE(...)
#define PRIV_OC_STRUCTOR_EXPAND(...) __VA_ARGS__
#define PRIV_OC_SELECT_NEXT_INNER(Dummy, Next, ...) Next
//
// Without this layer of indirection, MSVC evaluates __VA_ARGS__ early and
// PRIV_OC_SELECT_NEXT_INNER receives only two arguments, the second always
// being Unused as per PRIV_OC_SELECT_NEXT.
//
#define PRIV_OC_SELECT_NEXT_INNER_INDIR(...) PRIV_OC_SELECT_NEXT_INNER __VA_ARGS__
#define PRIV_OC_SELECT_NEXT(...) PRIV_OC_SELECT_NEXT_INNER_INDIR((__VA_ARGS__, Unused))
#define PRIV_OC_REMOVE_NEXT(...) , do { } while (0),
#define PRIV_OC_DECLARE_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \
Type Name Suffix;
#define PRIV_OC_CONSTRUCT_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \
.Name = Constructor,
#define PRIV_OC_DESTRUCT_STRUCT_MEMBER(Type, Name, Suffix, Constructor, Destructor) \
PRIV_OC_SELECT_NEXT(PRIV_OC_REMOVE_NEXT Destructor, Destructor(&Obj->Name, sizeof (Type Suffix)));
#define PRIV_OC_INVOKE_DESTRUCTOR(Destructor, Obj, Size) \
PRIV_OC_SELECT_NEXT(PRIV_OC_REMOVE_NEXT Destructor, Destructor(Obj, Size))
#define PRIV_NO_KEY_TYPE UINT8
//
// Declare structure type NAME. Construction and destruction interfaces will also be
// available with corresponding prototypes:
// VOID NAME_CONSTRUCT(Void *Ptr, UINTN Size);
// VOID NAME_DESTRUCT(Void *Ptr, UINTN Size);
//
// Field information will be retrieved from NAME_FIELDS X-Macro, written as follows:
#if 0
#define NAME_FIELDS(_, __) \
_(Type, Name, Type Suffix, __(Constant Initializer), Destructor Function) \
_(Type, Name, Type Suffix, OC_CONSTR(Type, _, __), OC_DESTR(Type))
#endif
//
#define OC_DECLARE(Name) \
typedef struct Name ## _ { \
Name ## _FIELDS (PRIV_OC_DECLARE_STRUCT_MEMBER, PRIV_OC_STRUCTOR_IGNORE) \
} Name; \
VOID Name ## _CONSTRUCT(VOID *Ptr, UINT32 Size); \
VOID Name ## _DESTRUCT(VOID *Ptr, UINT32 Size);
//
// Generate constructors and destructors for structure type NAME.
// Second argument permits to do extra actions prior to field destruction.
// Pass () to the second argument to ignore this option.
//
#define OC_STRUCTORS(Name, Destructor) \
VOID Name ## _CONSTRUCT(VOID *Ptr, UINT32 Size) { \
STATIC Name Obj = { \
Name ## _FIELDS(PRIV_OC_CONSTRUCT_STRUCT_MEMBER, PRIV_OC_STRUCTOR_EXPAND) \
}; \
CopyMem (Ptr, &Obj, sizeof (Name)); \
} \
VOID Name ## _DESTRUCT(VOID *Ptr, UINT32 Size) { \
Name *Obj = (Name *) Ptr; (VOID) Obj; \
PRIV_OC_INVOKE_DESTRUCTOR(Destructor, Obj, sizeof (Name)); \
Name ## _FIELDS(PRIV_OC_DESTRUCT_STRUCT_MEMBER, PRIV_OC_STRUCTOR_EXPAND) \
}
//
// Use previously defined structure constructor or destructor
// FIXME: We need to use these recursively, and normally one would implement
// it with deferred execution, like this:
// #define OC_CONSTR_REAL(A, _, __) ({A ## _FIELDS(_, __)})
// #define OC_CONSTR_REAL_ID() OC_CONSTR_REAL
// #define OC_CONSTR DEFER(OC_CONSTR_REAL_ID)()
// However, this will not work in this exact case, as _, which itself is a macro,
// changes the expansion order. The right fix here is to entirely remove the mess
// and use external tool for template generation.
//
#define OC_CONSTR(A, _, __) {A ## _FIELDS(_, __)}
#define OC_CONSTR1(A, _, __) {A ## _FIELDS(_, __)}
#define OC_CONSTR2(A, _, __) {A ## _FIELDS(_, __)}
#define OC_CONSTR3(A, _, __) {A ## _FIELDS(_, __)}
#define OC_CONSTR5(A, _, __) {A ## _FIELDS(_, __)}
#define OC_DESTR(A) A ## _DESTRUCT
//
// Generate array-like blob (string, data, metadata) of type Type,
// Count static size, MaxSize is real size, and default value Default.
//
#define OC_BLOB(Type, Count, Default, _, __) \
_(UINT32 , Size , , 0 , OcZeroField ) \
_(UINT32 , MaxSize , , sizeof (Type Count) , OcZeroField ) \
_(Type * , DynValue , , NULL , OcFreePointer ) \
_(Type , Value , Count , __(Default) , () )
#define OC_BLOB_STRUCTORS(Name) \
OC_STRUCTORS(Name, ())
#define OC_BLOB_CONSTR(Type, Constructor, SizeConstructor, _, __) \
__({.Size = SizeConstructor, .MaxSize = sizeof (((Type *)0)->Value), .DynValue = NULL, .Value = Constructor})
//
// Generate map-like container with key elements of type KeyType, OC_BLOB derivative,
// value types of Type constructed by Constructor and destructed by Destructor:
#if 0
#define CONT_FIELDS(_, __) \
OC_MAP (KEY, ELEM, _, __)
OC_DECLARE (CONT)
#endif
//
#define OC_MAP(KeyType, Type, _, __) \
_(UINT32 , Count , , 0 , () ) \
_(UINT32 , AllocCount , , 0 , () ) \
_(OC_STRUCTOR , Construct , , Type ## _CONSTRUCT , () ) \
_(OC_STRUCTOR , Destruct , , Type ## _DESTRUCT , () ) \
_(Type ** , Values , , NULL , () ) \
_(UINT32 , ValueSize , , sizeof (Type) , () ) \
_(UINT32 , KeySize , , sizeof (KeyType) , () ) \
_(OC_STRUCTOR , KeyConstruct , , KeyType ## _CONSTRUCT , () ) \
_(OC_STRUCTOR , KeyDestruct , , KeyType ## _DESTRUCT , () ) \
_(KeyType ** , Keys , , NULL , () )
#define OC_MAP_STRUCTORS(Name) \
OC_STRUCTORS(Name, OcFreeMap)
//
// Generate array-like container with elements of type Type, constructed
// by Constructor and destructed by Destructor.
#if 0
#define CONT_FIELDS(_, __) \
OC_ARRAY (ELEM, _, __)
OC_DECLARE (CONT)
#endif
//
#define OC_ARRAY(Type, _, __) \
_(UINT32 , Count , , 0 , () ) \
_(UINT32 , AllocCount , , 0 , () ) \
_(OC_STRUCTOR , Construct , , Type ## _CONSTRUCT , () ) \
_(OC_STRUCTOR , Destruct , , Type ## _DESTRUCT , () ) \
_(Type ** , Values , , NULL , () ) \
_(UINT32 , ValueSize , , sizeof (Type) , () )
#define OC_ARRAY_STRUCTORS(Name) \
OC_STRUCTORS(Name, OcFreeArray)
//
// Free dynamically allocated memory if non NULL.
// Note, that the first argument is actually VOID **.
//
VOID
OcFreePointer (
VOID *Pointer,
UINT32 Size
);
//
// Zero field memory.
//
VOID
OcZeroField (
VOID *Pointer,
UINT32 Size
);
//
// Do not invoke any actions at destruction.
//
VOID
OcDestructEmpty (
VOID *Pointer,
UINT32 Size
);
//
// OC_MAP-like destructor.
//
VOID
OcFreeMap (
VOID *Pointer,
UINT32 Size
);
//
// OC_ARRAY-like destructor.
//
VOID
OcFreeArray (
VOID *Pointer,
UINT32 Size
);
//
// Prepare memory for blob at Pointer to contain Size bytes.
// Assignable size may be returned via OutSize.
// This method guarantees not to overwrite "Default" value,
// but may destroy the previous value.
// NULL is returned on allocation failure.
//
VOID *
OcBlobAllocate (
VOID *Pointer,
UINT32 Size,
UINT32 **OutSize OPTIONAL
);
//
// Obtain blob value
//
#define OC_BLOB_GET(Blob) (((Blob)->DynValue) != NULL ? ((Blob)->DynValue) : ((Blob)->Value))
//
// Insert new empty element into the OC_MAP or OC_ARRAY, depending
// on Key value.
//
BOOLEAN
OcListEntryAllocate (
VOID *Pointer,
VOID **Value,
VOID **Key
);
//
// Some useful generic types
// OC_STRING - implements support for resizable ASCII strings.
// OC_DATA - implements support for resizable data blobs.
// OC_ASSOC - implements support for maps with ASCII keys and data values.
//
#define OC_STRING_FIELDS(_, __) \
OC_BLOB (CHAR8, [64], {0}, _, __)
OC_DECLARE (OC_STRING)
#define OC_STRING_CONSTR(Constructor, _, __) \
OC_BLOB_CONSTR (OC_STRING, __(Constructor), sizeof (Constructor), _, __)
#define OC_ESTRING_CONSTR(_, __) \
OC_BLOB_CONSTR (OC_STRING, __(""), 0, _, __)
#define OC_DATA_FIELDS(_, __) \
OC_BLOB (UINT8, [64], {0}, _, __)
OC_DECLARE (OC_DATA)
#define OC_EDATA_CONSTR(_, __) \
OC_BLOB_CONSTR (OC_DATA, __({0}), 0, _, __)
#define OC_DATA_CONSTR(Constructor, _, __) \
OC_BLOB_CONSTR (OC_DATA, __(Constructor), sizeof ((UINT8[]) Constructor), _, __)
#define OC_ASSOC_FIELDS(_, __) \
OC_MAP (OC_STRING, OC_DATA, _, __)
OC_DECLARE (OC_ASSOC)
#endif // OC_TEMPLATE_LIB_H

388
Include/Library/OcXmlLib.h Executable file
View File

@ -0,0 +1,388 @@
/** @file
OcXmlLib
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
//
// Copyright (c) 2012 ooxi/xml.c
// https://github.com/ooxi/xml.c
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software in a
// product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#ifndef OC_XML_LIB_H
#define OC_XML_LIB_H
#include <Library/OcGuardLib.h>
//
// Maximum nest level.
// XML_PARSER_NEST_LEVEL is required to fit into INT32.
//
#ifndef XML_PARSER_NEST_LEVEL
#define XML_PARSER_NEST_LEVEL 32ULL
#endif
//
// Maximum child node count
// XML_PARSER_NODE_COUNT*2 is required to fit into INT32.
//
#ifndef XML_PARSER_NODE_COUNT
#define XML_PARSER_NODE_COUNT 32768ULL
#endif
//
// Maximum reference count.
// XML_PARSER_MAX_REFERENCE_COUNT*2 is required to fit into INT32.
//
#ifndef XML_PARSER_MAX_REFERENCE_COUNT
#define XML_PARSER_MAX_REFERENCE_COUNT (32ULL*1024)
#endif
//
// Maximum input data size, currently 32 MB.
// XML_PARSER_MAX_SIZE is required to fit into INT32.
//
#ifndef XML_PARSER_MAX_SIZE
#define XML_PARSER_MAX_SIZE (32ULL*1024*1024)
#endif
//
// Debug controls
//
//#define XML_PARSER_VERBOSE
//#define XML_PRINT_ERRORS
//
// Plist node types.
//
typedef enum PLIST_NODE_TYPE_ {
PLIST_NODE_TYPE_ANY,
PLIST_NODE_TYPE_ARRAY,
PLIST_NODE_TYPE_DICT,
PLIST_NODE_TYPE_KEY,
PLIST_NODE_TYPE_STRING,
PLIST_NODE_TYPE_DATA,
PLIST_NODE_TYPE_DATE,
PLIST_NODE_TYPE_TRUE,
PLIST_NODE_TYPE_FALSE,
PLIST_NODE_TYPE_REAL,
PLIST_NODE_TYPE_INTEGER,
PLIST_NODE_TYPE_MAX
} PLIST_NODE_TYPE;
//
// Opaque structure holding the parsed xml document.
//
struct XML_DOCUMENT_;
struct XML_NODE_;
typedef struct XML_DOCUMENT_ XML_DOCUMENT;
typedef struct XML_NODE_ XML_NODE;
//
// Tries to parse the XML fragment in buffer
// References in the document to allow deduplicated node reading:
// <integer ID="0" size="64">0x0</integer>
// <integer IDREF="0" size="64"/>
//
// @param Buffer Chunk to parse
// @param Length Size of the buffer
// @param WithRef Enable reference lookup support
//
// @warning `Buffer` will be referenced by the document, you may not free it
// until you free the XML_DOCUMENT
// @warning You have to call XmlDocumentFree after you finished using the
// document
// @warning `Buffer` contents are permanently modified during parsing
//
// @return The parsed xml fragment iff parsing was successful, 0 otherwise
//
XML_DOCUMENT *
XmlDocumentParse (
CHAR8 *Buffer,
UINT32 Length,
BOOLEAN WithRefs
);
//
// Exports parsed document into the buffer.
//
// @param Document XML_DOCUMENT to export
// @param Length Resulting length of the buffer without trailing \0 (optional)
// @param Skip N root levels before exporting, normally 0.
//
// @return Exported buffer allocated from pool or NULL.
//
CHAR8 *
XmlDocumentExport (
XML_DOCUMENT *Document,
UINT32 *Length,
UINT32 Skip
);
//
// Frees all resources associated with the document. All XML_NODE
// references obtained through the document will be invalidated.
//
// @param Document XML_DOCUMENT to free
//
VOID
XmlDocumentFree (
XML_DOCUMENT *Document
);
//
// @return XML_NODE representing the document root.
//
XML_NODE *
XmlDocumentRoot (
XML_DOCUMENT *Document
);
//
// @return The XML_NODE's tag name.
//
CONST CHAR8 *
XmlNodeName (
XML_NODE *Node
);
//
// @return The XML_NODE's string content (if available, otherwise NULL).
//
CONST CHAR8 *
XmlNodeContent (
XML_NODE *Node
);
//
// @return Number of child nodes.
//
UINT32
XmlNodeChildren (
XML_NODE *Node
);
//
// @return The n-th child, behaviour is undefined if out of range.
//
XML_NODE *
XmlNodeChild (
XML_NODE *Node,
UINT32 Child
);
//
// @return The node described by the path or NULL if child cannot be found.
// @warning Each element on the way must be unique.
// @warning Last argument must be NULL.
//
XML_NODE *
EFIAPI
XmlEasyChild (
XML_NODE *Node,
CONST CHAR8 *Child,
...
);
//
// Append new node to current node.
//
// @param Node Current node.
// @param Name Name of the new node.
// @param Attributes Attributes of the new node (optional).
// @param Content New node content (optional).
//
// @return Newly created node or NULL.
//
// @warning Name, Attributes, and Content must stay valid till XmlDocumentFree.
//
XML_NODE *
XmlNodeAppend (
XML_NODE *Node,
CONST CHAR8 *Name,
CONST CHAR8 *Attributes,
CONST CHAR8 *Content
);
//
// Prepend new node to current node.
// Otherwise equivalent to XmlNodeAppend.
//
XML_NODE *
XmlNodePrepend (
XML_NODE *Node,
CONST CHAR8 *Name,
CONST CHAR8 *Attributes,
CONST CHAR8 *Content
);
//
// @return XML_NODE representing plist root or NULL.
// @warning Only a subset of plist is supported.
// @warning No validation of plist format is performed.
//
XML_NODE *
PlistDocumentRoot (
XML_DOCUMENT *Document
);
//
// Performs basic type casting (up to PLIST_NODE_TYPE_MAX).
// Guarantees that node represents passed type.
// Guarantees that arrays and dicts have valid amount of children, while others have 0.
// Guarantees that keys have names and integers have values.
//
// @return Node if it is not NULL and represents passed Type or NULL.
// @warning It is not guaranteed that Node has valid data for data or integer types.
//
XML_NODE *
PlistNodeCast (
XML_NODE *Node,
PLIST_NODE_TYPE Type
);
//
// @return Number of plist dictionary entries.
//
UINT32
PlistDictChildren (
XML_NODE *Node
);
//
// @return The n-th dictionary key, behaviour is undefined if out of range.
//
XML_NODE *
PlistDictChild (
XML_NODE *Node,
UINT32 Child,
XML_NODE **Value OPTIONAL
);
//
// @return key value for valid type or NULL.
//
CONST CHAR8 *
PlistKeyValue (
XML_NODE *Node
);
//
// @return string value for valid type or empty string ("").
//
BOOLEAN
PlistStringValue (
XML_NODE *Node,
CHAR8 *Value,
UINT32 *Size
);
//
// Decodes data content for valid type or sets *Size to 0.
//
// @param Buffer output buffer.
// @param Size size of buffer.
//
BOOLEAN
PlistDataValue (
XML_NODE *Node,
UINT8 *Buffer,
UINT32 *Size
);
//
// @return boolean value for valid type or FALSE.
//
BOOLEAN
PlistBooleanValue (
XML_NODE *Node,
BOOLEAN *Value
);
//
// @return integral value for valid type or 0.
//
BOOLEAN
PlistIntegerValue (
XML_NODE *Node,
VOID *Value,
UINT32 Size,
BOOLEAN Hex
);
//
// Decodes data content for valid type or sets *Size to 0.
// Valid type for MetaData is DATA itself, STRING, INTEGER,
// or BOOLEAN (as 1 byte with 1 or 0 value).
//
// @param Buffer output buffer.
// @param Size size of buffer.
// @warn Integer must fit 32-bit UNSIGNED.
// @warn Buffer must be at least 1 byte long.
//
BOOLEAN
PlistMetaDataValue (
XML_NODE *Node,
VOID *Buffer,
UINT32 *Size
);
//
// Estimates string content size.
//
BOOLEAN
PlistStringSize (
XML_NODE *Node,
UINT32 *Size
);
//
// Estimates data content size.
//
BOOLEAN
PlistDataSize (
XML_NODE *Node,
UINT32 *Size
);
//
// Estimates meta data content size.
//
BOOLEAN
PlistMetaDataSize (
XML_NODE *Node,
UINT32 *Size
);
#endif // OC_XML_LIB_H

View File

@ -0,0 +1,76 @@
/** @file
Copyright (C) 2014 - 2016, Download-Fritz. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APPLE_BEEP_GEN_H
#define APPLE_BEEP_GEN_H
/**
Apple Beep Generator protocol
C32332DF-FC56-4FE1-9358-BA0D529B24CD
**/
#define APPLE_BEEP_GEN_PROTOCOL_GUID \
{ 0xC32332DF, 0xFC56, 0x4FE1, \
{ 0x93, 0x58, 0xBA, 0x0D, 0x52, 0x9B, 0x24, 0xCD } }
/**
Note, ToneLength and SilenceLength were in microseconds for older models:
- MacBookPro1,1
- MacBookPro1,1
- MacBookPro1,2
- MacBookPro2,1
- MacBookPro2,2
- MacBookP1,1
- MacBookP1,2
- MacBookP2,1
- MacBookP2,2
- MacBook1,1
- MacBook2,1
- Macmini1,1
- Macmini2,1
- iMac4,1
- iMac4,2
- iMac5,1
- iMac5,2
- iMac6,1
- MacPro1,1
- MacPro2,1
- XServe1,1
**/
/**
Generate cycles of beep signals with silence afterwards, blocking.
@param[in] ToneCount Number of signals to produce.
@param[in] ToneLength Signal length in milliseconds.
@param[in] SilenceLength Silence length in milliseconds.
@retval EFI_SUCCESS after signal completion.
@retval EFI_SUCCESS if ToneCount is 0.
**/
typedef
EFI_STATUS
(EFIAPI *APPLE_BEEP_GEN_BEEP) (
IN UINT32 ToneCount,
IN UINTN ToneLength,
IN UINTN SilenceLength
);
/**
All protocol members are optional and can be NULL.
**/
typedef struct {
APPLE_BEEP_GEN_BEEP GenBeep; ///< Can be NULL.
} APPLE_BEEP_GEN_PROTOCOL;
extern EFI_GUID gAppleBeepGenProtocolGuid;
#endif // APPLE_BEEP_GEN_H

View File

@ -0,0 +1,139 @@
/** @file
Copyright (C) 2014 - 2017, Download-Fritz. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APPLE_BOOT_POLICY_H
#define APPLE_BOOT_POLICY_H
#include <Protocol/SimpleFileSystem.h>
#define APPLE_BOOT_POLICY_PROTOCOL_REVISION 0x00000003
///
/// The GUID of the APPLE_BOOT_POLICY_PROTOCOL.
///
#define APPLE_BOOT_POLICY_PROTOCOL_GUID \
{ 0x62257758, 0x350C, 0x4D0A, \
{ 0xB0, 0xBD, 0xF6, 0xBE, 0x2E, 0x1E, 0x27, 0x2C } }
// BOOT_POLICY_GET_BOOT_FILE
/** Locates the bootable file of the given volume. Prefered are the values
blessed, though if unavailable, hard-coded names are being verified and
used if existing.
The blessed paths are to be determined by the HFS Driver via
EFI_FILE_PROTOCOL.GetInfo(). The related identifier definitions are to be
found in AppleBless.h.
@param[in] Device The Device's Handle to perform the search on.
@param[out] FilePath A pointer to the device path pointer to set to the file
path of the boot file.
@retval EFI_NOT_FOUND A bootable file could not be found on the given
volume.
@retval EFI_OUT_OF_RESOURCES The memory necessary to complete the operation
could not be allocated.
@retval EFI_SUCCESS The operation completed successfully and the
BootFilePath Buffer has been filled.
@retval other The status of an operation used to complete
this operation is returned.
**/
typedef
EFI_STATUS
(EFIAPI *BOOT_POLICY_GET_BOOT_FILE) (
IN EFI_HANDLE Device,
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
);
//
// Neither is used at this moment.
// https://opensource.apple.com/source/kext_tools/kext_tools-528.220.8/KextAudit/efi_smc.h.auto.html
//
typedef enum {
// Boot Policy not valid retry.
BootPolicyNotReady,
// Boot Selected macOS.
BootPolicyOk,
// Boot Recovery OS, update bridgeOS.
BootPolicyUpdate,
// Full system reboot, boot selected macOS.
BootPolicyReboot,
// Version unknown boot to recovery OS to get more info.
BootPolicyUnknown,
// Update failed take the failure path.
BootPolicyBridgeOSUpdateFailed,
// Boot Recovery OS to change security policy.
BootPolicyRecoverySecurityPolicyUpdate,
// Valid values will be less that this version.
BootPolicyMaxValue
} BOOT_POLICY_ACTION;
typedef
EFI_STATUS
(EFIAPI *BOOT_POLICY_GET_BOOT_FILE_EX) (
IN EFI_HANDLE Device,
IN BOOT_POLICY_ACTION Action,
OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
);
typedef
EFI_STATUS
(EFIAPI *BOOT_POLICY_DEVICE_PATH_TO_DIR_PATH) (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT CHAR16 **BootPathName,
OUT EFI_HANDLE *Device,
OUT EFI_HANDLE *ApfsVolumeHandle
);
typedef
EFI_STATUS
(EFIAPI *BOOT_POLICY_GET_APFS_RECOVERY_FILE_PATH) (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST CHAR16 *PathName,
OUT CHAR16 **FullPathName,
OUT VOID **Reserved,
OUT EFI_FILE_PROTOCOL **Root,
OUT EFI_HANDLE *DeviceHandle
);
typedef
EFI_STATUS
(EFIAPI *BOOT_POLICY_GET_ALL_APFS_RECOVERY_FILE_PATH) (
IN EFI_HANDLE Handle,
OUT VOID **Volumes,
OUT UINTN *NumberOfEntries
);
///
/// The structure exposed by the APPLE_BOOT_POLICY_PROTOCOL.
///
typedef struct {
UINTN Revision; ///< The revision of the installed protocol.
BOOT_POLICY_GET_BOOT_FILE GetBootFile; ///< Present as of Revision 1.
BOOT_POLICY_GET_BOOT_FILE_EX GetBootFileEx; ///< Present as of Revision 3.
BOOT_POLICY_DEVICE_PATH_TO_DIR_PATH DevicePathToDirPath; ///< Present as of Revision 3.
BOOT_POLICY_GET_APFS_RECOVERY_FILE_PATH GetApfsRecoveryFilePath; ///< Present as of Revision 3.
BOOT_POLICY_GET_ALL_APFS_RECOVERY_FILE_PATH GetAllApfsRecoveryFilePath; ///< Present as of Revision 3.
} APPLE_BOOT_POLICY_PROTOCOL;
///
/// A global variable storing the GUID of the APPLE_BOOT_POLICY_PROTOCOL.
///
extern EFI_GUID gAppleBootPolicyProtocolGuid;
#endif // APPLE_BOOT_POLICY_H

View File

@ -0,0 +1,94 @@
/** @file
Copyright (C) 2014 - 2016, Download-Fritz. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APPLE_KEY_MAP_AGGREGATOR_H
#define APPLE_KEY_MAP_AGGREGATOR_H
#include <IndustryStandard/AppleHid.h>
// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION
#define APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_REVISION 0x00010000
// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_GUID
#define APPLE_KEY_MAP_AGGREGATOR_PROTOCOL_GUID \
{ 0x5B213447, 0x6E73, 0x4901, \
{ 0xA4, 0xF1, 0xB8, 0x64, 0xF3, 0xB7, 0xA1, 0x72 } }
typedef
struct APPLE_KEY_MAP_AGGREGATOR_PROTOCOL
APPLE_KEY_MAP_AGGREGATOR_PROTOCOL;
// KEY_MAP_GET_KEY_STROKES
/** Returns all pressed keys and key modifiers into the appropiate buffers.
@param[in] This Protocol instance pointer.
@param[out] Modifiers The modifiers manipulating the given keys.
@param[out] NumberOfKeyCodes On input the number of keys allocated.
On output the number of keys returned into
KeyCodes.
@param[out] KeyCodes A Pointer to a caller-allocated the pressed
keys get returned in.
@retval EFI_SUCCESS The pressed keys have been returned into
KeyCodes.
@retval EFI_BUFFER_TOO_SMALL The memory required to return the value exceeds
the size of the allocated Buffer.
The required number of keys to allocate to
complete the operation has been returned into
NumberOfKeyCodes.
@retval other An error returned by a sub-operation.
**/
typedef
EFI_STATUS
(EFIAPI *KEY_MAP_GET_KEY_STROKES)(
IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This,
OUT APPLE_MODIFIER_MAP *Modifiers,
OUT UINTN *NumberOfKeyCodes,
OUT APPLE_KEY *KeyCodes
);
// KEY_MAP_CONTAINS_KEY_STROKES
/** Returns whether or not a list of keys and their modifiers are part of the
database of pressed keys.
@param[in] This Protocol instance pointer.
@param[in] Modifiers The modifiers manipulating the given keys.
@param[in] NumberOfKeyCodes The number of keys present in KeyCodes.
@param[in,out] KeyCodes The list of keys to check for. The
children may be sorted in the process.
@param[in] ExactMatch Specifies whether Modifiers and KeyCodes
should be exact matches or just contained.
@retval EFI_SUCCESS The queried keys are part of the database.
@retval EFI_NOT_FOUND The queried keys could not be found.
**/
typedef
EFI_STATUS
(EFIAPI *KEY_MAP_CONTAINS_KEY_STROKES)(
IN APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *This,
IN APPLE_MODIFIER_MAP Modifiers,
IN UINTN NumberOfKeyCodes,
IN OUT APPLE_KEY *KeyCodes,
IN BOOLEAN ExactMatch
);
// APPLE_KEY_MAP_AGGREGATOR_PROTOCOL
struct APPLE_KEY_MAP_AGGREGATOR_PROTOCOL {
UINTN Revision;
KEY_MAP_GET_KEY_STROKES GetKeyStrokes;
KEY_MAP_CONTAINS_KEY_STROKES ContainsKeyStrokes;
};
// gAppleKeyMapAggregatorProtocolGuid
extern EFI_GUID gAppleKeyMapAggregatorProtocolGuid;
#endif // APPLE_KEY_MAP_AGGREGATOR_H

View File

@ -0,0 +1,181 @@
/** @file
Apple VoiceOver Audio protocol.
Copyright (C) 2020, vit9696. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef APPLE_VO_AUDIO_H
#define APPLE_VO_AUDIO_H
/**
Apple VoiceOver Audio protocol GUID.
This protocol is present on Gibraltar Macs (ones with T1/T2 and custom HDA).
F4CB0B78-243B-11E7-A524-B8E8562CBAFA
**/
#define APPLE_VOICE_OVER_AUDIO_PROTOCOL_GUID \
{ 0xF4CB0B78, 0x243B, 0x11E7, \
{ 0xA5, 0x24, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
typedef struct APPLE_VOICE_OVER_AUDIO_PROTOCOL_ APPLE_VOICE_OVER_AUDIO_PROTOCOL;
/**
Apple VoiceOver Audio protocol revision.
**/
#define APPLE_VOICE_OVER_AUDIO_PROTOCOL_REVISION 0x10000
/**
These files can be found either on BridgeOS volume:
/System/Library/PrivateFrameworks/BridgeAccessibilitySupport.framework/AXEFIAudio_[ru]_[VoiceOverOn].aiff
Here language code (ru) can be both full (ru_RU) and short (ru).
For unlocalised files language code can be missing entirely, e.g. AXEFIAudio_Beep.aiff.
Or in /Volumes/Preboot/.../System/Library/Caches/com.apple.corestorage/EFILoginLocalizations/sound.efires
For preboot the file format is sound_SCREFIAudio.VoiceOverOn.
Files marked with * are only present on BridgeOS.
**/
typedef enum {
AppleVoiceOverAudioFileVoiceOverOn = 0x01, ///< VoiceOverOn
AppleVoiceOverAudioFileVoiceOverOff = 0x02, ///< VoiceOverOff
AppleVoiceOverAudioFileUsername = 0x03, ///< Username
AppleVoiceOverAudioFilePassword = 0x04, ///< Password
AppleVoiceOverAudioFileUsernameOrPasswordIncorrect = 0x05, ///< UsernameOrPasswordIncorrect
AppleVoiceOverAudioFileAccountLockedTryLater = 0x06, ///< AccountLockedTryLater (*)
AppleVoiceOverAudioFileAccountLocked = 0x07, ///< AccountLocked (*)
AppleVoiceOverAudioFileVoiceOverBoot = 0x3B, ///< VoiceOver_Boot (*)
AppleVoiceOverAudioFileVoiceOverBoot2 = 0x3C, ///< VoiceOver_Boot (*)
AppleVoiceOverAudioFileClick = 0x3D, ///< Click (*)
AppleVoiceOverAudioFileBeep = 0x3E, ///< Beep
AppleVoiceOverAudioFileMax = 0x3F,
} APPLE_VOICE_OVER_AUDIO_FILE;
/**
VoiceOver language codes.
**/
typedef enum {
AppleVoiceOverLanguageAr = 0x01, ///< ar
AppleVoiceOverLanguageCa = 0x02, ///< ca
AppleVoiceOverLanguageCs = 0x03, ///< cs
AppleVoiceOverLanguageDa = 0x04, ///< da
AppleVoiceOverLanguageDe = 0x05, ///< de
AppleVoiceOverLanguageEl = 0x06, ///< el
AppleVoiceOverLanguageEn = 0x07, ///< en
AppleVoiceOverLanguageEs = 0x08, ///< es
AppleVoiceOverLanguageEs419 = 0x09, ///< es-419
AppleVoiceOverLanguageEsMx = 0x0A, ///< es-MX
AppleVoiceOverLanguageFi = 0x0B, ///< fi
AppleVoiceOverLanguageFr = 0x0C, ///< fr
AppleVoiceOverLanguageHe = 0x0D, ///< he
AppleVoiceOverLanguageHi = 0x0E, ///< hi
AppleVoiceOverLanguageHr = 0x0F, ///< hr
AppleVoiceOverLanguageHu = 0x10, ///< hu
AppleVoiceOverLanguageId = 0x11, ///< id
AppleVoiceOverLanguageIt = 0x12, ///< it
AppleVoiceOverLanguageJa = 0x13, ///< ja
AppleVoiceOverLanguageKo = 0x14, ///< ko
AppleVoiceOverLanguageNl = 0x15, ///< nl
AppleVoiceOverLanguageNo = 0x16, ///< no
AppleVoiceOverLanguageMy = 0x17, ///< my
AppleVoiceOverLanguagePl = 0x18, ///< pl
AppleVoiceOverLanguagePt = 0x19, ///< pt
AppleVoiceOverLanguagePtPt = 0x1A, ///< pt-PT
AppleVoiceOverLanguageRo = 0x1B, ///< ro
AppleVoiceOverLanguageRu = 0x1C, ///< ru
AppleVoiceOverLanguageSk = 0x1D, ///< sk
AppleVoiceOverLanguageSv = 0x1E, ///< sv
AppleVoiceOverLanguageTh = 0x1F, ///< th
AppleVoiceOverLanguageTr = 0x20, ///< tr
AppleVoiceOverLanguageUk = 0x21, ///< uk
AppleVoiceOverLanguageVi = 0x22, ///< vi
AppleVoiceOverLanguageZhHans = 0x23, ///< zh-Hans
AppleVoiceOverLanguageZhHant = 0x24, ///< zh-Hant
} APPLE_VOICE_OVER_LANGUAGE_CODE;
/**
Play audio file.
@param[in] This VoiceOver protocol instance.
@param[in] File File to play.
@retval EFI_SUCCESS on successful playback startup.
@retval EFI_NOT_FOUND when audio device is missing.
@retval EFI_INVALID_PARAMETER when audio file is not valid.
**/
typedef
EFI_STATUS
(EFIAPI *APPLE_VOICE_OVER_AUDIO_PLAY) (
IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This,
IN UINT8 File
);
/**
Set language for VoiceOver support via code.
@param[in] This VoiceOver protocol instance.
@param[in] LanguageCode Language code (e.g. AppleVoiceOverLanguageEn).
@retval EFI_SUCCESS on successful language update.
@retval EFI_INVALID_PARAMETER when the language is unsupported.
**/
typedef
EFI_STATUS
(EFIAPI *APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_CODE) (
IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This,
IN UINT8 LanguageCode
);
/**
Set language for VoiceOver support via string.
@param[in] This VoiceOver protocol instance.
@param[in] LanguageString Language string (e.g. ru or ru-RU).
@retval EFI_SUCCESS on successful language update.
@retval EFI_INVALID_PARAMETER when the language is unsupported.
**/
typedef
EFI_STATUS
(EFIAPI *APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_STRING) (
IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This,
IN CONST CHAR8 *LanguageString
);
/**
Get current VoiceOver language.
@param[in] This VoiceOver protocol instance.
@param[out] LanguageCode Current language code (e.g. AppleVoiceOverLanguageRu).
@param[out] LanguageString Current language string (e.g. ru) or NULL.
@retval EFI_SUCCESS on successful language update.
@retval EFI_INVALID_PARAMETER when the language is unsupported.
**/
typedef
EFI_STATUS
(EFIAPI *APPLE_VOICE_OVER_AUDIO_GET_LANGUAGE) (
IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This,
OUT UINT8 *LanguageCode,
OUT CONST CHAR8 **LanguageString
);
/**
VoiceOver protocol.
**/
struct APPLE_VOICE_OVER_AUDIO_PROTOCOL_ {
UINTN Revision;
APPLE_VOICE_OVER_AUDIO_PLAY Play;
APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_CODE SetLanguageCode;
APPLE_VOICE_OVER_AUDIO_SET_LANGUAGE_STRING SetLanguageString;
APPLE_VOICE_OVER_AUDIO_GET_LANGUAGE GetLanguage;
};
extern EFI_GUID gAppleVOAudioProtocolGuid;
#endif // APPLE_VO_AUDIO_H

View File

@ -0,0 +1,37 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_AFTER_BOOT_COMPAT_PROTOCOL_H
#define OC_AFTER_BOOT_COMPAT_PROTOCOL_H
#define OC_AFTER_BOOT_COMPAT_PROTOCOL_REVISION 0x010000
//
// OC_AFTER_BOOT_COMPAT_PROTOCOL_GUID
// C7CBA84E-CC77-461D-9E3C-6BE0CB79A7C1
//
#define OC_AFTER_BOOT_COMPAT_PROTOCOL_GUID \
{ 0xC7CBA84E, 0xCC77, 0x461D, \
{ 0x9E, 0x3C, 0x6B, 0xE0, 0xCB, 0x79, 0xA7, 0xC1 } }
//
// Includes a revision for debugging reasons
//
typedef struct {
UINTN Revision;
} OC_AFTER_BOOT_COMPAT_PROTOCOL;
extern EFI_GUID gOcAfterBootCompatProtocolGuid;
#endif // OC_AFTER_BOOT_COMPAT_PROTOCOL_H

234
Include/Protocol/OcAudio.h Normal file
View File

@ -0,0 +1,234 @@
/** @file
Copyright (C) 2020, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_AUDIO_PROTOCOL_H
#define OC_AUDIO_PROTOCOL_H
#include <Protocol/AppleVoiceOver.h>
#include <Protocol/DevicePath.h>
#define OC_AUDIO_PROTOCOL_REVISION 0x010000
//
// OC_AUDIO_PROTOCOL_GUID
// 4B228577-6274-4A48-82AE-0713A1171987
//
#define OC_AUDIO_PROTOCOL_GUID \
{ 0x4B228577, 0x6274, 0x4A48, \
{ 0x82, 0xAE, 0x07, 0x13, 0xA1, 0x17, 0x19, 0x87 } }
typedef struct OC_AUDIO_PROTOCOL_ OC_AUDIO_PROTOCOL;
/**
Custom OpenCore audio files.
**/
typedef enum {
OcVoiceOverAudioFileBase = 0x1000,
OcVoiceOverAudioFileIndexBase = 0x1000,
OcVoiceOverAudioFile1 = 0x1001,
OcVoiceOverAudioFile2 = 0x1002,
OcVoiceOverAudioFile3 = 0x1003,
OcVoiceOverAudioFile4 = 0x1004,
OcVoiceOverAudioFile5 = 0x1005,
OcVoiceOverAudioFile6 = 0x1006,
OcVoiceOverAudioFile7 = 0x1007,
OcVoiceOverAudioFile8 = 0x1008,
OcVoiceOverAudioFile9 = 0x1009,
OcVoiceOverAudioFileIndexAlphabetical = 0x100A,
OcVoiceOverAudioFileLetterA = 0x100A,
OcVoiceOverAudioFileLetterB = 0x100B,
OcVoiceOverAudioFileLetterC = 0x100C,
OcVoiceOverAudioFileLetterD = 0x100D,
OcVoiceOverAudioFileLetterE = 0x100E,
OcVoiceOverAudioFileLetterF = 0x100F,
OcVoiceOverAudioFileLetterG = 0x1010,
OcVoiceOverAudioFileLetterH = 0x1011,
OcVoiceOverAudioFileLetterI = 0x1012,
OcVoiceOverAudioFileLetterJ = 0x1013,
OcVoiceOverAudioFileLetterK = 0x1014,
OcVoiceOverAudioFileLetterL = 0x1015,
OcVoiceOverAudioFileLetterM = 0x1016,
OcVoiceOverAudioFileLetterN = 0x1017,
OcVoiceOverAudioFileLetterO = 0x1018,
OcVoiceOverAudioFileLetterP = 0x1019,
OcVoiceOverAudioFileLetterQ = 0x101A,
OcVoiceOverAudioFileLetterR = 0x101B,
OcVoiceOverAudioFileLetterS = 0x101C,
OcVoiceOverAudioFileLetterT = 0x101D,
OcVoiceOverAudioFileLetterU = 0x101E,
OcVoiceOverAudioFileLetterV = 0x101F,
OcVoiceOverAudioFileLetterW = 0x1020,
OcVoiceOverAudioFileLetterX = 0x1021,
OcVoiceOverAudioFileLetterY = 0x1022,
OcVoiceOverAudioFileLetterZ = 0x1023,
OcVoiceOverAudioFileIndexMax = 0x1023,
OcVoiceOverAudioFileAbortTimeout = 0x1030,
OcVoiceOverAudioFileChooseOS = 0x1031,
OcVoiceOverAudioFileDefault = 0x1032,
OcVoiceOverAudioFileDiskImage = 0x1033,
OcVoiceOverAudioFileEnterPassword = 0x1034,
OcVoiceOverAudioFileExecutionFailure = 0x1035,
OcVoiceOverAudioFileExecutionSuccessful = 0x1036,
OcVoiceOverAudioFileExternal = 0x1037,
OcVoiceOverAudioFileExternalOS = 0x1038,
OcVoiceOverAudioFileExternalTool = 0x1039,
OcVoiceOverAudioFileLoading = 0x103A,
OcVoiceOverAudioFilemacOS = 0x103B,
OcVoiceOverAudioFilemacOS_Recovery = 0x103C,
OcVoiceOverAudioFilemacOS_TimeMachine = 0x103D,
OcVoiceOverAudioFilemacOS_UpdateFw = 0x103E,
OcVoiceOverAudioFileOtherOS = 0x103F,
OcVoiceOverAudioFilePasswordAccepted = 0x1040,
OcVoiceOverAudioFilePasswordIncorrect = 0x1041,
OcVoiceOverAudioFilePasswordRetryLimit = 0x1042,
OcVoiceOverAudioFileReloading = 0x1043,
OcVoiceOverAudioFileResetNVRAM = 0x1044,
OcVoiceOverAudioFileSelected = 0x1045,
OcVoiceOverAudioFileShowAuxiliary = 0x1046,
OcVoiceOverAudioFileTimeout = 0x1047,
OcVoiceOverAudioFileUEFI_Shell = 0x1048,
OcVoiceOverAudioFileWelcome = 0x1049,
OcVoiceOverAudioFileWindows = 0x104A,
OcVoiceOverAudioFileMax = 0x104B,
} OC_VOICE_OVER_AUDIO_FILE;
//STATIC_ASSERT (OcVoiceOverAudioFileIndexMax - OcVoiceOverAudioFileIndexBase == 9 + 26, "Invalid index count");
/**
Connect to Audio I/O.
@param[in,out] This Audio protocol instance.
@param[in] DevicePath Controller device path, optional.
@param[in] CodecAddress Codec address, optional.
@param[in] OutputIndex Output index, optional.
@param[in] Volume Raw volume level from 0 to 100.
@retval EFI_SUCESS on success.
@retval EFI_NOT_FOUND when missing.
@retval EFI_UNSUPPORTED on failure.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_CONNECT) (
IN OUT OC_AUDIO_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
IN UINT8 CodecAddress OPTIONAL,
IN UINT8 OutputIndex OPTIONAL,
IN UINT8 Volume
);
/**
Retrive file contents callback.
@param[in,out] Context Externally specified context.
@param[in] File File identifier, see APPLE_VOICE_OVER_AUDIO_FILE.
@paran[in] LanguageCode Language code for the file.
@param[out] Buffer Pointer to buffer.
@param[out] BufferSize Pointer to buffer size.
@retval EFI_SUCCESS on successful file lookup.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_PROVIDER_ACQUIRE) (
IN VOID *Context,
IN UINT32 File,
IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode,
OUT UINT8 **Buffer,
OUT UINT32 *BufferSize
);
/**
Release file contents given by acquire callback.
@param[in,out] Context Externally specified context.
@param[out] Buffer Pointer to buffer.
@retval EFI_SUCCESS on successful release.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_PROVIDER_RELEASE) (
IN VOID *Context,
IN UINT8 *Buffer
);
/**
Set resource provider.
@param[in,out] This Audio protocol instance.
@param[in] Acquire Resource acquire handler.
@param[in] Release Resource release handler, optional.
@param[in] Context Resource handler context.
@retval EFI_SUCCESS on successful provider update.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_SET_PROVIDER) (
IN OUT OC_AUDIO_PROTOCOL *This,
IN OC_AUDIO_PROVIDER_ACQUIRE Acquire,
IN OC_AUDIO_PROVIDER_RELEASE Release OPTIONAL,
IN VOID *Context
);
/**
Play file.
@param[in,out] This Audio protocol instance.
@param[in] File File to play.
@param[in] Wait Wait for completion of the previous track.
@retval EFI_SUCCESS on successful playback startup.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_PLAY_FILE) (
IN OUT OC_AUDIO_PROTOCOL *This,
IN UINT32 File,
IN BOOLEAN Wait
);
/**
Stop playback.
@param[in,out] This Audio protocol instance.
@param[in] Wait Wait for audio completion.
@retval EFI_SUCCESS on successful playback stop.
**/
typedef
EFI_STATUS
(EFIAPI* OC_AUDIO_STOP_PLAYBACK) (
IN OUT OC_AUDIO_PROTOCOL *This,
IN BOOLEAN Wait
);
//
// Includes a revision for debugging reasons.
//
struct OC_AUDIO_PROTOCOL_ {
UINTN Revision;
OC_AUDIO_CONNECT Connect;
OC_AUDIO_SET_PROVIDER SetProvider;
OC_AUDIO_PLAY_FILE PlayFile;
OC_AUDIO_STOP_PLAYBACK StopPlayback;
};
extern EFI_GUID gOcAudioProtocolGuid;
#endif // OC_AUDIO_PROTOCOL_H

View File

@ -0,0 +1,145 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_FIRMWARE_RUNTIME_PROTOCOL_H
#define OC_FIRMWARE_RUNTIME_PROTOCOL_H
#include <Uefi.h>
#define OC_FIRMWARE_RUNTIME_REVISION 11
/**
OC_FIRMWARE_RUNTIME_PROTOCOL_GUID
570332E4-FC50-4B21-ABE8-AE72F05B4FF7
**/
#define OC_FIRMWARE_RUNTIME_PROTOCOL_GUID \
{ 0x570332E4, 0xFC50, 0x4B21, \
{ 0xAB, 0xE8, 0xAE, 0x72, 0xF0, 0x5B, 0x4F, 0xF7 } }
/**
Configuration request to change firmware runtime behaviour.
**/
typedef struct OC_FWRT_CONFIG_ {
///
/// Enforce restricted access to OpenCore read-only and write-only GUIDs.
///
BOOLEAN RestrictedVariables;
///
/// Enforce BootXXXX variable redirection to OpenCore vendor GUID.
///
BOOLEAN BootVariableRedirect;
///
/// Make SetVariable do nothing and always return EFI_SECURITY_VIOLATION.
/// When we do not want variables to be stored in NVRAM or NVRAM implementation
/// is buggy we can disable variable writing.
///
BOOLEAN WriteProtection;
///
/// Make UEFI runtime services drop CR0 WP bit on calls to allow writing
/// to read only memory. This workarounds a bug in many APTIO firmwares
/// that do not survive W^X.
/// Latest Windows brings Virtualization-based security and monitors
/// CR0 by launching itself under a hypevisor. Since we need WP disable
/// on macOS to let NVRAM work, and for the time being no other OS
/// requires it, here we decide to use it for macOS exclusively.
///
BOOLEAN WriteUnprotector;
///
/// Secure boot variable protection.
///
BOOLEAN ProtectSecureBoot;
} OC_FWRT_CONFIG;
/**
Get current used configuration data.
@param[out] Config Current configuration to store.
**/
typedef
VOID
(EFIAPI *OC_FWRT_GET_CURRENT_CONFIG) (
OUT OC_FWRT_CONFIG *Config
);
/**
Set main configuration.
@param[in] Config Runtime services configuration to apply.
**/
typedef
VOID
(EFIAPI *OC_FWRT_SET_MAIN_CONFIG) (
IN CONST OC_FWRT_CONFIG *Config
);
/**
Perform configuration override, NULL Config implies disable override.
@param[in] Config Runtime services configuration to apply, optional.
**/
typedef
VOID
(EFIAPI *OC_FWRT_SET_OVERRIDE_CONFIG) (
IN CONST OC_FWRT_CONFIG *Config OPTIONAL
);
/**
Set GetVariable override for customising values.
@param[in] GetVariable GetVariable to call on each call.
@param[out] OrgGetVariable Original GetVariable to call from GetVariable.
@retval EFI_SUCCESS on successful override.
**/
typedef
EFI_STATUS
(EFIAPI *OC_FWRT_ON_GET_VARIABLE) (
IN EFI_GET_VARIABLE GetVariable,
OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL
);
/**
Obtain area that needs to be executable in OS runtime.
@param[out] BaseAddress Executable area start.
@param[out] Pages Number of executable pages.
@retval EFI_SUCCESS on success.
@retval EFI_UNSUPPORTED not required.
**/
typedef
EFI_STATUS
(EFIAPI *OC_FWRT_GET_EXEC_AREA) (
OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINTN *Pages
);
/**
Firmware runtime protocol instance.
Check for revision to ensure binary compatibility.
**/
typedef struct {
UINTN Revision;
OC_FWRT_GET_CURRENT_CONFIG GetCurrent;
OC_FWRT_SET_MAIN_CONFIG SetMain;
OC_FWRT_SET_OVERRIDE_CONFIG SetOverride;
OC_FWRT_ON_GET_VARIABLE OnGetVariable;
OC_FWRT_GET_EXEC_AREA GetExecArea;
} OC_FIRMWARE_RUNTIME_PROTOCOL;
/**
Firmware runtime protocol GUID.
**/
extern EFI_GUID gOcFirmwareRuntimeProtocolGuid;
#endif // OC_FIRMWARE_RUNTIME_PROTOCOL_H

View File

@ -0,0 +1,130 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OpenRuntimePrivate.h"
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/OcFirmwareRuntime.h>
STATIC
VOID
EFIAPI
FwGetCurrent (
OUT OC_FWRT_CONFIG *Config
)
{
CopyMem (Config, gCurrentConfig, sizeof (*Config));
}
STATIC
VOID
EFIAPI
FwSetMain (
IN CONST OC_FWRT_CONFIG *Config
)
{
CopyMem (&gMainConfig, Config, sizeof (gMainConfig));
}
STATIC
VOID
EFIAPI
FwSetOverride (
IN CONST OC_FWRT_CONFIG *Config
)
{
if (Config != NULL) {
CopyMem (&gOverrideConfig, Config, sizeof (gOverrideConfig));
gCurrentConfig = &gOverrideConfig;
} else {
gCurrentConfig = &gMainConfig;
}
}
STATIC
EFI_STATUS
EFIAPI
FwGetExecArea (
OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
OUT UINTN *Pages
)
{
//
// FIXME: This is not accurate, but it does not need to be for now.
//
*BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) FwGetCurrent;
*Pages = 1;
return EFI_SUCCESS;
}
STATIC
OC_FIRMWARE_RUNTIME_PROTOCOL
mOcFirmwareRuntimeProtocol = {
OC_FIRMWARE_RUNTIME_REVISION,
FwGetCurrent,
FwSetMain,
FwSetOverride,
FwOnGetVariable,
FwGetExecArea
};
EFI_STATUS
EFIAPI
UefiEntrypoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VOID *Interface;
EFI_HANDLE Handle;
Status = gBS->LocateProtocol (
&gOcFirmwareRuntimeProtocolGuid,
NULL,
&Interface
);
if (!EFI_ERROR (Status)) {
//
// In case for whatever reason one tried to reload the driver.
//
return EFI_ALREADY_STARTED;
}
//
// Activate main configuration.
//
gCurrentConfig = &gMainConfig;
RedirectRuntimeServices ();
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gOcFirmwareRuntimeProtocolGuid,
&mOcFirmwareRuntimeProtocol,
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,56 @@
## @file
# UEFI runtime services driver support for OpenCore and others.
#
# Copyright (c) 2019, vit9696. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OpenRuntime
FILE_GUID = E0BA9DEF-0478-462E-BF46-908EB0EFC7E0
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = UefiEntrypoint
[Packages]
CloverPkg.dec
# OpenCorePkg/OpenCorePkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
CloverEFI/UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
[Sources]
UefiRuntimeServices.c
OpenRuntime.c
OpenRuntimePrivate.h
[Guids]
gEfiGlobalVariableGuid ## CONSUMES
gEfiImageSecurityDatabaseGuid ## CONSUMES
gOcReadOnlyVariableGuid ## CONSUMES
gOcWriteOnlyVariableGuid ## CONSUMES
gOcVendorVariableGuid ## CONSUMES
gEfiAppleBootGuid ## SOMETIMES_CONSUMES
gMicrosoftVariableGuid ## SOMETIMES_CONSUMES
[Protocols]
gOcFirmwareRuntimeProtocolGuid ## SOMETIMES_PRODUCES
[Depex]
TRUE

View File

@ -0,0 +1,51 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OPEN_RUNTIME_PRIVATE_H
#define OPEN_RUNTIME_PRIVATE_H
#include <Uefi.h>
#include <Protocol/OcFirmwareRuntime.h>
/**
Main runtime services configuration.
**/
extern OC_FWRT_CONFIG gMainConfig;
/**
Override runtime services configuration.
**/
extern OC_FWRT_CONFIG gOverrideConfig;
/**
Current active runtime services configuration (main or override).
**/
extern OC_FWRT_CONFIG *gCurrentConfig;
#define OC_GL_BOOT_OPTION_START 0xF000
VOID
RedirectRuntimeServices (
VOID
);
EFI_STATUS
EFIAPI
FwOnGetVariable (
IN EFI_GET_VARIABLE GetVariable,
OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL
);
#endif // FIRMWARE_RUNTIME_SERVICES_PRIVATE_H

View File

@ -0,0 +1,724 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OpenRuntimePrivate.h"
#include <Guid/OcVariable.h>
#include <Guid/GlobalVariable.h>
#include <Guid/ImageAuthentication.h>
#include <Guid/MicrosoftVariable.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcDevicePathLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcStringLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
/**
Runtime accessible variables (all read only).
**/
STATIC EFI_GET_TIME mStoredGetTime;
STATIC EFI_SET_TIME mStoredSetTime;
STATIC EFI_GET_WAKEUP_TIME mStoredGetWakeupTime;
STATIC EFI_SET_WAKEUP_TIME mStoredSetWakeupTime;
STATIC EFI_GET_VARIABLE mStoredGetVariable;
STATIC EFI_GET_NEXT_VARIABLE_NAME mStoredGetNextVariableName;
STATIC EFI_SET_VARIABLE mStoredSetVariable;
STATIC EFI_GET_NEXT_HIGH_MONO_COUNT mStoredGetNextHighMonotonicCount;
STATIC EFI_RESET_SYSTEM mStoredResetSystem;
/**
Configurations to use.
**/
OC_FWRT_CONFIG gMainConfig;
OC_FWRT_CONFIG gOverrideConfig;
OC_FWRT_CONFIG *gCurrentConfig;
/**
Boot phase accessible variables.
**/
STATIC EFI_EVENT mTranslateEvent;
STATIC EFI_GET_VARIABLE mCustomGetVariable;
STATIC BOOLEAN mKernelStarted;
STATIC
VOID
WriteUnprotectorPrologue (
OUT BOOLEAN *Ints,
OUT BOOLEAN *Wp
)
{
IA32_CR0 Cr0;
if (gCurrentConfig->WriteUnprotector) {
*Ints = SaveAndDisableInterrupts ();
Cr0.UintN = AsmReadCr0 ();
if (Cr0.Bits.WP == 1) {
*Wp = TRUE;
Cr0.Bits.WP = 0;
AsmWriteCr0 (Cr0.UintN);
} else {
*Wp = FALSE;
}
} else {
*Ints = FALSE;
*Wp = FALSE;
}
}
STATIC
VOID
WriteUnprotectorEpilogue (
IN BOOLEAN Ints,
IN BOOLEAN Wp
)
{
IA32_CR0 Cr0;
if (gCurrentConfig->WriteUnprotector) {
if (Wp) {
Cr0.UintN = AsmReadCr0 ();
Cr0.Bits.WP = 1;
AsmWriteCr0 (Cr0.UintN);
}
if (Ints) {
EnableInterrupts ();
}
}
}
STATIC
BOOLEAN
IsEfiBootVar (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
if (!CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
return FALSE;
}
if (StrnCmp (L"Boot", VariableName, L_STR_LEN (L"Boot")) != 0) {
return FALSE;
}
return TRUE;
}
STATIC
BOOLEAN
IsOcBootVar (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
if (!CompareGuid (VendorGuid, &gOcVendorVariableGuid)) {
return FALSE;
}
if (StrnCmp (L"Boot", VariableName, L_STR_LEN (L"Boot")) != 0) {
return FALSE;
}
return TRUE;
}
STATIC
EFI_STATUS
EFIAPI
WrapGetTime (
OUT EFI_TIME *Time,
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredGetTime (
Time,
Capabilities
);
if (!EFI_ERROR (Status)) {
//
// On old AMI firmwares (like the one found in GA-Z87X-UD4H) there is a chance
// of getting 2047 (EFI_UNSPECIFIED_TIMEZONE) from GetTime. This is valid,
// yet is disliked by some software including but not limited to UEFI Shell.
// See the patch: https://lists.01.org/pipermail/edk2-devel/2018-May/024534.html
// As a workaround we make sure this does not happen at all.
//
if (Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
Time->TimeZone = 0;
}
}
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapSetTime (
IN EFI_TIME *Time
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredSetTime (
Time
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapGetWakeupTime (
OUT BOOLEAN *Enabled,
OUT BOOLEAN *Pending,
OUT EFI_TIME *Time
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredGetWakeupTime (
Enabled,
Pending,
Time
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapSetWakeupTime (
IN BOOLEAN Enable,
IN EFI_TIME *Time OPTIONAL
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredSetWakeupTime (
Enable,
Time
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapGetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data OPTIONAL
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
//
// Perform early checks for speedup.
//
if (VariableName == NULL
|| VendorGuid == NULL
|| DataSize == NULL
|| (Data == NULL && *DataSize != 0)) {
return EFI_INVALID_PARAMETER;
}
//
// Abort access to write-only variables.
//
if (gCurrentConfig->RestrictedVariables
&& mKernelStarted
&& CompareGuid (VendorGuid, &gOcWriteOnlyVariableGuid)) {
return EFI_SECURITY_VIOLATION;
}
//
// Redirect Boot-prefixed variables to our own GUID.
//
if (gCurrentConfig->BootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) {
VendorGuid = &gOcVendorVariableGuid;
}
WriteUnprotectorPrologue (&Ints, &Wp);
Status = (mCustomGetVariable != NULL ? mCustomGetVariable : mStoredGetVariable) (
VariableName,
VendorGuid,
Attributes,
DataSize,
Data
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapGetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
{
EFI_STATUS Status;
UINTN Index;
UINTN Size;
CHAR16 TempName[256];
EFI_GUID TempGuid;
BOOLEAN StartBootVar;
BOOLEAN Ints;
BOOLEAN Wp;
//
// Perform initial checks as per spec. Last check is part of:
// Null-terminator is not found in the first VariableNameSize
// bytes of the input VariableName buffer.
//
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Checking that VariableName never exceeds *VariableNameSize and is always null-terminated.
//
Size = 0;
for (Index = 0; Index < *VariableNameSize; ++Index) {
if (VariableName[Index] == L'\0') {
Size = (Index + 1) * sizeof (CHAR16);
break;
}
}
//
// Also assume that too large variables do not exist, as we cannot work with them anyway.
//
if (Size == 0 || Size > sizeof (TempName)) {
return EFI_INVALID_PARAMETER;
}
WriteUnprotectorPrologue (&Ints, &Wp);
//
// In case we do not redirect, simply do nothing.
//
if (!gCurrentConfig->BootVariableRedirect) {
Status = mStoredGetNextVariableName (VariableNameSize, VariableName, VendorGuid);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
//
// Copy vendor and variable name to internal buffer.
//
CopyGuid (&TempGuid, VendorGuid);
StrnCpyS (TempName, ARRAY_SIZE (TempName), VariableName, StrLen (VariableName));
StartBootVar = FALSE;
//
// In case we are not yet iterating EfiBoot variables,
// then go through the whole variable list and return
// variables except EfiBoot.
//
if (!IsEfiBootVar (TempName, &TempGuid)) {
while (TRUE) {
//
// Request for variables.
//
Size = sizeof (TempName);
Status = mStoredGetNextVariableName (&Size, TempName, &TempGuid);
if (!EFI_ERROR (Status)) {
if (!IsEfiBootVar (TempName, &TempGuid)) {
Size = StrSize (TempName); ///< Not guaranteed to be updated with EFI_SUCCESS.
if (*VariableNameSize >= Size) {
//
// Return this variable.
//
CopyGuid (VendorGuid, &TempGuid);
StrnCpyS (
VariableName,
*VariableNameSize / sizeof (CHAR16),
TempName,
StrLen (TempName)
);
*VariableNameSize = Size; ///< This is NOT explicitly required by the spec.
Status = EFI_SUCCESS;
} else {
//
// Request more space.
//
*VariableNameSize = Size;
Status = EFI_BUFFER_TOO_SMALL;
}
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
} else {
//
// EfiBoot variables are handled outside of this loop.
//
}
} else if (Status == EFI_BUFFER_TOO_SMALL) {
//
// This means sizeof (TempName) is too small for this system.
// At this step we cannot do anything, but let's replace error
// with something sensible.
//
WriteUnprotectorEpilogue (Ints, Wp);
return EFI_DEVICE_ERROR;
} else if (Status == EFI_NOT_FOUND) {
//
// End of normal variable list.
// This means it is the time for boot variables to be searched
// from the beginning.
//
StartBootVar = TRUE;
break;
} else {
//
// We got EFI_UNSUPPORTED, EFI_DEVICE_ERROR or EFI_INVALID_PARAMETER.
// Return as is.
//
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
}
}
//
// Handle EfiBoot variables now.
// When StartBootVar is TRUE we start from the beginning.
// Otherwise we have boot variable in TempGuid/TempName.
//
if (StartBootVar) {
//
// It is not required to zero guid, but let's do it just in case.
//
TempName[0] = L'\0';
ZeroMem (&TempGuid, sizeof (TempGuid));
} else {
//
// Switch to real GUID as stored in variable storage.
//
CopyGuid (&TempGuid, &gOcVendorVariableGuid);
}
//
// Find next EfiBoot variable.
//
while (TRUE) {
Size = sizeof (TempName);
Status = mStoredGetNextVariableName (&Size, TempName, &TempGuid);
if (!EFI_ERROR (Status)) {
if (IsOcBootVar (TempName, &TempGuid)) {
Size = StrSize (TempName); ///< Not guaranteed to be updated with EFI_SUCCESS.
if (*VariableNameSize >= Size) {
//
// Return this variable.
//
CopyGuid (VendorGuid, &gEfiGlobalVariableGuid);
StrnCpyS (
VariableName,
*VariableNameSize / sizeof (CHAR16),
TempName,
StrLen (TempName)
);
*VariableNameSize = Size; ///< This is NOT explicitly required by the spec.
Status = EFI_SUCCESS;
} else {
//
// Request more space.
//
*VariableNameSize = Size;
Status = EFI_BUFFER_TOO_SMALL;
}
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
} else {
//
// This is some error, but let us not care which and just exit cleanly.
//
break;
}
}
//
// Report this is the end.
//
WriteUnprotectorEpilogue (Ints, Wp);
return EFI_NOT_FOUND;
}
STATIC
EFI_STATUS
EFIAPI
WrapSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
//
// Abort access when running with read-only NVRAM.
//
if (gCurrentConfig->WriteProtection && (Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
return EFI_SECURITY_VIOLATION;
}
//
// Abort access to read-only variables.
//
if (gCurrentConfig->RestrictedVariables
&& mKernelStarted
&& CompareGuid (VendorGuid, &gOcReadOnlyVariableGuid)) {
return EFI_SECURITY_VIOLATION;
}
//
// Abort access to SecureBoot variables.
//
if (gCurrentConfig->ProtectSecureBoot) {
if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
if (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0
|| StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0) {
return EFI_SECURITY_VIOLATION;
}
} else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0
|| StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0
|| StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0
|| StrCmp (VariableName, L"dbr" /* EFI_IMAGE_SECURITY_DATABASE3 */) == 0) {
return EFI_SECURITY_VIOLATION;
}
} else if (CompareGuid (VendorGuid, &gMicrosoftVariableGuid)) {
//
// CurrentActivePolicy, CurrentPolicy, RevocationList, WindowsBootChainSvn, whatever.
//
return EFI_SECURITY_VIOLATION;
}
}
//
// Redirect Boot-prefixed variables to our own GUID.
//
if (gCurrentConfig->BootVariableRedirect
&& IsEfiBootVar (VariableName, VendorGuid)) {
VendorGuid = &gOcVendorVariableGuid;
}
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredSetVariable (
VariableName,
VendorGuid,
Attributes,
DataSize,
Data
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
WrapGetNextHighMonotonicCount (
OUT UINT32 *Count
)
{
EFI_STATUS Status;
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
Status = mStoredGetNextHighMonotonicCount (
Count
);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
}
STATIC
VOID
EFIAPI
WrapResetSystem (
IN EFI_RESET_TYPE ResetType,
IN EFI_STATUS ResetStatus,
IN UINTN DataSize,
IN VOID *ResetData OPTIONAL
)
{
BOOLEAN Ints;
BOOLEAN Wp;
WriteUnprotectorPrologue (&Ints, &Wp);
mStoredResetSystem (
ResetType,
ResetStatus,
DataSize,
ResetData
);
WriteUnprotectorEpilogue (Ints, Wp);
}
EFI_STATUS
EFIAPI
FwOnGetVariable (
IN EFI_GET_VARIABLE GetVariable,
OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL
)
{
if (mCustomGetVariable != NULL) {
return EFI_ALREADY_STARTED;
}
mCustomGetVariable = GetVariable;
if (OrgGetVariable != NULL) {
*OrgGetVariable = mStoredGetVariable;
}
return EFI_SUCCESS;
}
STATIC
VOID
EFIAPI
TranslateAddressesHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
{
gRT->ConvertPointer (0, (VOID **) &mStoredGetTime);
gRT->ConvertPointer (0, (VOID **) &mStoredSetTime);
gRT->ConvertPointer (0, (VOID **) &mStoredGetWakeupTime);
gRT->ConvertPointer (0, (VOID **) &mStoredSetWakeupTime);
gRT->ConvertPointer (0, (VOID **) &mStoredGetVariable);
gRT->ConvertPointer (0, (VOID **) &mStoredGetNextVariableName);
gRT->ConvertPointer (0, (VOID **) &mStoredSetVariable);
gRT->ConvertPointer (0, (VOID **) &mStoredGetNextHighMonotonicCount);
gRT->ConvertPointer (0, (VOID **) &mStoredResetSystem);
gRT->ConvertPointer (0, (VOID **) &gCurrentConfig);
mCustomGetVariable = NULL;
//
// Ideally we do that from ExitBootServices, but VirtualAddressChange is fine as well.
//
mKernelStarted = TRUE;
}
VOID
RedirectRuntimeServices (
VOID
)
{
EFI_STATUS Status;
mStoredGetTime = gRT->GetTime;
mStoredSetTime = gRT->SetTime;
mStoredGetWakeupTime = gRT->GetWakeupTime;
mStoredSetWakeupTime = gRT->SetWakeupTime;
mStoredGetVariable = gRT->GetVariable;
mStoredGetNextVariableName = gRT->GetNextVariableName;
mStoredSetVariable = gRT->SetVariable;
mStoredGetNextHighMonotonicCount = gRT->GetNextHighMonotonicCount;
mStoredResetSystem = gRT->ResetSystem;
gRT->GetTime = WrapGetTime;
gRT->SetTime = WrapSetTime;
gRT->GetWakeupTime = WrapGetWakeupTime;
gRT->SetWakeupTime = WrapSetWakeupTime;
gRT->GetVariable = WrapGetVariable;
gRT->GetNextVariableName = WrapGetNextVariableName;
gRT->SetVariable = WrapSetVariable;
gRT->GetNextHighMonotonicCount = WrapGetNextHighMonotonicCount;
gRT->ResetSystem = WrapResetSystem;
gRT->Hdr.CRC32 = 0;
gBS->CalculateCrc32 (gRT, gRT->Hdr.HeaderSize, &gRT->Hdr.CRC32);
Status = gBS->CreateEvent (
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
TPL_CALLBACK,
TranslateAddressesHandler,
NULL,
&mTranslateEvent
);
ASSERT_EFI_ERROR (Status);
}

File diff suppressed because it is too large Load Diff