/** This code gets the pointer to the variable name. @param Variable Pointer to the Variable Header. @param AuthFlag Authenticated variable flag. @return A CHAR16* pointer to Variable Name. **/ CHAR16 * GetVariableNamePtr ( IN VARIABLE_HEADER *Variable, IN BOOLEAN AuthFlag ) { return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize (AuthFlag)); }
/** Variable Driver main entry point. The Variable driver places the 4 EFI runtime services in the EFI System Table and installs arch protocols for variable read and write services being available. It also registers a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS Variable service successfully initialized. **/ EFI_STATUS EFIAPI VariableServiceInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE VariableHandle; VOID *SmmFtwRegistration; VOID *SmmEndOfDxeRegistration; // // Variable initialize. // Status = VariableCommonInitialize (); ASSERT_EFI_ERROR (Status); // // Install the Smm Variable Protocol on a new handle. // VariableHandle = NULL; Status = gSmst->SmmInstallProtocolInterface ( &VariableHandle, &gEfiSmmVariableProtocolGuid, EFI_NATIVE_INTERFACE, &gSmmVariable ); ASSERT_EFI_ERROR (Status); Status = gSmst->SmmInstallProtocolInterface ( &VariableHandle, &gEdkiiSmmVarCheckProtocolGuid, EFI_NATIVE_INTERFACE, &mSmmVarCheck ); ASSERT_EFI_ERROR (Status); mVariableBufferPayloadSize = GetNonVolatileMaxVariableSize () + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - GetVariableHeaderSize (); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, mVariableBufferPayloadSize, (VOID **)&mVariableBufferPayload ); ASSERT_EFI_ERROR (Status); /// /// Register SMM variable SMI handler /// VariableHandle = NULL; Status = gSmst->SmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle); ASSERT_EFI_ERROR (Status); // // Notify the variable wrapper driver the variable service is ready // Status = SystemTable->BootServices->InstallProtocolInterface ( &mVariableHandle, &gEfiSmmVariableProtocolGuid, EFI_NATIVE_INTERFACE, &gSmmVariable ); ASSERT_EFI_ERROR (Status); // // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function. // Status = gSmst->SmmRegisterProtocolNotify ( &gEfiSmmEndOfDxeProtocolGuid, SmmEndOfDxeCallback, &SmmEndOfDxeRegistration ); ASSERT_EFI_ERROR (Status); // // Register FtwNotificationEvent () notify function. // Status = gSmst->SmmRegisterProtocolNotify ( &gEfiSmmFaultTolerantWriteProtocolGuid, SmmFtwNotificationEvent, &SmmFtwRegistration ); ASSERT_EFI_ERROR (Status); SmmFtwNotificationEvent (NULL, NULL, NULL); return EFI_SUCCESS; }
/** Get variable header that has consecutive content. @param StoreInfo Pointer to variable store info structure. @param Variable Pointer to the Variable Header. @param VariableHeader Pointer to Pointer to the Variable Header that has consecutive content. @retval TRUE Variable header is valid. @retval FALSE Variable header is not valid. **/ BOOLEAN GetVariableHeader ( IN VARIABLE_STORE_INFO *StoreInfo, IN VARIABLE_HEADER *Variable, OUT VARIABLE_HEADER **VariableHeader ) { EFI_PHYSICAL_ADDRESS TargetAddress; EFI_PHYSICAL_ADDRESS SpareAddress; EFI_HOB_GUID_TYPE *GuidHob; UINTN PartialHeaderSize; if (Variable == NULL) { return FALSE; } // // First assume variable header pointed by Variable is consecutive. // *VariableHeader = Variable; if (StoreInfo->FtwLastWriteData != NULL) { TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; if (((UINTN) Variable > (UINTN) SpareAddress) && (((UINTN) Variable - (UINTN) SpareAddress + (UINTN) TargetAddress) >= (UINTN) GetEndPointer (StoreInfo->VariableStoreHeader))) { // // Reach the end of variable store. // return FALSE; } if (((UINTN) Variable < (UINTN) TargetAddress) && (((UINTN) Variable + GetVariableHeaderSize (StoreInfo->AuthFlag)) > (UINTN) TargetAddress)) { // // Variable header pointed by Variable is inconsecutive, // create a guid hob to combine the two partial variable header content together. // GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob != NULL) { *VariableHeader = (VARIABLE_HEADER *) GET_GUID_HOB_DATA (GuidHob); } else { *VariableHeader = (VARIABLE_HEADER *) BuildGuidHob (&gEfiCallerIdGuid, GetVariableHeaderSize (StoreInfo->AuthFlag)); PartialHeaderSize = (UINTN) TargetAddress - (UINTN) Variable; // // Partial content is in NV storage. // CopyMem ((UINT8 *) *VariableHeader, (UINT8 *) Variable, PartialHeaderSize); // // Another partial content is in spare block. // CopyMem ((UINT8 *) *VariableHeader + PartialHeaderSize, (UINT8 *) (UINTN) SpareAddress, GetVariableHeaderSize (StoreInfo->AuthFlag) - PartialHeaderSize); } } } else { if (Variable >= GetEndPointer (StoreInfo->VariableStoreHeader)) { // // Reach the end of variable store. // return FALSE; } } return IsValidVariableHeader (*VariableHeader); }