fsvariable.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,279 行 · 第 1/3 页
C
1,279 行
/*++
Copyright (c) 2006, Intel Corporation
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.
Module Name:
FSVariable.c
Abstract:
Provide support functions for variable services.
--*/
#include "FSVariable.h"
#include "EfiRuntimeLib.h"
#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
#include EFI_ARCH_PROTOCOL_DEFINITION (VariableWrite)
#include "PatchVariable.h"
VARIABLE_STORE_HEADER mValidStoreHeaderTemplate = {
VARIABLE_STORE_SIGNATURE,
VARIABLE_STORE_SIZE,
VARIABLE_STORE_FORMATTED,
VARIABLE_STORE_HEALTHY,
0,
0
};
//
// Don't use module globals after the SetVirtualAddress map is signaled
//
VARIABLE_GLOBAL *mGlobal;
VOID *mSFSRegistration;
STATIC
VOID
EFIAPI
OnVirtualAddressChange (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
VOID
EFIAPI
OnSimpleFileSystemInstall (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
BOOLEAN
IsValidVariableHeader (
IN VARIABLE_HEADER *Variable
)
/*++
Routine Description:
This code checks if variable header is valid or not.
Arguments:
Variable Pointer to the Variable Header.
Returns:
TRUE Variable header is valid.
FALSE Variable header is not valid.
--*/
{
if (Variable == NULL ||
Variable->StartId != VARIABLE_DATA ||
(sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE
) {
return FALSE;
}
return TRUE;
}
STATIC
VARIABLE_STORE_STATUS
GetVariableStoreStatus (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
/*++
Routine Description:
This code gets the current status of Variable Store.
Arguments:
VarStoreHeader Pointer to the Variable Store Header.
Returns:
EfiRaw Variable store status is raw
EfiValid Variable store status is valid
EfiInvalid Variable store status is invalid
--*/
{
if (EfiCompareMem (VarStoreHeader, &mValidStoreHeaderTemplate, sizeof (*VarStoreHeader)) == 0) {
return EfiValid;
} else if (VarStoreHeader->Signature == VAR_DEFAULT_VALUE_32 &&
VarStoreHeader->Size == VAR_DEFAULT_VALUE_32 &&
VarStoreHeader->Format == VAR_DEFAULT_VALUE &&
VarStoreHeader->State == VAR_DEFAULT_VALUE
) {
return EfiRaw;
} else {
return EfiInvalid;
}
}
STATIC
UINT8 *
GetVariableDataPtr (
IN VARIABLE_HEADER *Variable
)
/*++
Routine Description:
This code gets the pointer to the variable data.
Arguments:
Variable Pointer to the Variable Header.
Returns:
UINT8* Pointer to Variable Data
--*/
{
//
// Be careful about pad size for alignment
//
return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));
}
STATIC
VARIABLE_HEADER *
GetNextVariablePtr (
IN VARIABLE_HEADER *Variable
)
/*++
Routine Description:
This code gets the pointer to the next variable header.
Arguments:
Variable Pointer to the Variable Header.
Returns:
VARIABLE_HEADER* Pointer to next variable header.
--*/
{
if (!IsValidVariableHeader (Variable)) {
return NULL;
}
//
// Be careful about pad size for alignment
//
return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
}
STATIC
VARIABLE_HEADER *
GetEndPointer (
IN VARIABLE_STORE_HEADER *VarStoreHeader
)
/*++
Routine Description:
This code gets the pointer to the last variable memory pointer byte
Arguments:
VarStoreHeader Pointer to the Variable Store Header.
Returns:
VARIABLE_HEADER* Pointer to last unavailable Variable Header
--*/
{
//
// The end of variable store
//
return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size);
}
STATIC
EFI_STATUS
Reclaim (
IN VARIABLE_STORAGE_TYPE StorageType,
IN VARIABLE_HEADER *CurrentVariable OPTIONAL
)
/*++
Routine Description:
Variable store garbage collection and reclaim operation
Arguments:
IsVolatile The variable store is volatile or not,
if it is non-volatile, need FTW
CurrentVairable If it is not NULL, it means not to process
current variable for Reclaim.
Returns:
EFI STATUS
--*/
{
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *NextVariable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT8 *ValidBuffer;
UINTN ValidBufferSize;
UINTN VariableSize;
UINT8 *CurrPtr;
EFI_STATUS Status;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) mGlobal->VariableBase[StorageType];
//
// Start Pointers for the variable.
//
Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if ((Variable->State == VAR_ADDED) ||
((Variable != CurrentVariable) &&
(Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)))) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
ValidBufferSize += VariableSize;
}
Variable = NextVariable;
}
Status = gBS->AllocatePool (
EfiBootServicesData,
ValidBufferSize,
&ValidBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
CurrPtr = ValidBuffer;
//
// Copy variable store header
//
EfiCopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
CurrPtr += sizeof (VARIABLE_STORE_HEADER);
//
// Start Pointers for the variable.
//
Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if ((Variable->State == VAR_ADDED) ||
((Variable != CurrentVariable) &&
(Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)))) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
EfiCopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
//
// Mark all variable as VAR_ADDED
//
((VARIABLE_HEADER *)CurrPtr)->State = VAR_ADDED;
CurrPtr += VariableSize;
}
Variable = NextVariable;
}
//
// TODO: cannot restore to original state, basic FTW needed
//
Status = mGlobal->VariableStore[StorageType]->Erase (
mGlobal->VariableStore[StorageType]
);
Status = mGlobal->VariableStore[StorageType]->Write (
mGlobal->VariableStore[StorageType],
0,
ValidBufferSize,
ValidBuffer
);
// ASSERT_EFI_ERROR (Status);
mGlobal->LastVariableOffset[StorageType] = ValidBufferSize;
gBS->FreePool (ValidBuffer);
return Status;
}
STATIC
EFI_STATUS
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack
)
/*++
Routine Description:
This code finds variable in storage blocks (Volatile or Non-Volatile)
Arguments:
VariableName Name of the variable to be found
VendorGuid Vendor GUID to be found.
PtrTrack Variable Track Pointer structure that contains
Variable Information.
Contains the pointer of Variable header.
Returns:
EFI STATUS
--*/
{
VARIABLE_HEADER *Variable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN Index;
VARIABLE_HEADER *InDeleteVariable;
UINTN InDeleteIndex;
if (VariableName[0] != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
InDeleteVariable = NULL;
InDeleteIndex = (UINTN)-1;
for (Index = 0; Index < MaxType; Index ++) {
//
// 0: Non-Volatile, 1: Volatile
//
VariableStoreHeader = (VARIABLE_STORE_HEADER *) mGlobal->VariableBase[Index];
//
// Start Pointers for the variable.
// Actual Data Pointer where data can be written.
//
Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
//
// Find the variable by walk through non-volatile and volatile variable store
//
PtrTrack->StartPtr = Variable;
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable) && (Variable < PtrTrack->EndPtr)) {
if (Variable->State == VAR_ADDED) {
if (!EfiAtRuntime () || (Variable->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
if (VariableName[0] == 0) {
PtrTrack->CurrPtr = Variable;
PtrTrack->Type = (VARIABLE_STORAGE_TYPE) Index;
return EFI_SUCCESS;
} else {
if (EfiCompareGuid (VendorGuid, &Variable->VendorGuid)) {
if (!EfiCompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), EfiStrSize (VariableName))) {
PtrTrack->CurrPtr = Variable;
PtrTrack->Type = (VARIABLE_STORAGE_TYPE) Index;
return EFI_SUCCESS;
}
}
}
}
} else if (Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) {
//
// VAR_IN_DELETED_TRANSITION should also be checked.
//
if (!EfiAtRuntime () || (Variable->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
if (VariableName[0] == 0) {
InDeleteVariable = Variable;
InDeleteIndex = Index;
} else {
if (EfiCompareGuid (VendorGuid, &Variable->VendorGuid)) {
if (!EfiCompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), EfiStrSize (VariableName))) {
InDeleteVariable = Variable;
InDeleteIndex = Index;
}
}
}
}
}
Variable = GetNextVariablePtr (Variable);
}
//
// While (...)
//
}
//
// for (...)
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?