diff options
Diffstat (limited to 'Core/CORE_DXE/UefiHii/HiAccessConfig.c')
-rw-r--r-- | Core/CORE_DXE/UefiHii/HiAccessConfig.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/Core/CORE_DXE/UefiHii/HiAccessConfig.c b/Core/CORE_DXE/UefiHii/HiAccessConfig.c new file mode 100644 index 0000000..d165a1e --- /dev/null +++ b/Core/CORE_DXE/UefiHii/HiAccessConfig.c @@ -0,0 +1,322 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c 7 5/04/11 12:08p Artems $ +// +// $Revision: 7 $ +// +// $Date: 5/04/11 12:08p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c $ +// +// 7 5/04/11 12:08p Artems +// Bug fix: when variable is absent attribute state was undefined +// +// 6 1/25/11 4:03p Artems +// EIP 51298: Fixed corruption in buffer size after passing it to +// ConfigToBlock function +// Added check for correct syntax of request string in ExtractConfig +// function +// +// 5 9/30/10 6:12p Artems +// Removed unnecessary service functions +// +// 3 2/19/10 4:01p Felixp +// Debug messages are removed. +// +// 2 11/25/09 11:25a Felixp +// Action parameter of the Callback function is updated based on UEFI +// errata +// +// 1 10/09/09 6:12p Felixp +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: HiiAccessConfig.c +// +// Description: Hii Config Access protocol implementation +// +//<AMI_FHDR_END> +//********************************************************************** + +#pragma warning (disable : 4090) + +#include <AmiDxeLib.h> +#include <Protocol/HiiConfigAccess.h> +#include <Protocol/HiiConfigRouting.h> + +#include "HiiPrivate.h" + +extern const NAME_PATTERN GuidPattern; +extern const NAME_PATTERN NamePattern; +extern const NAME_PATTERN PathPattern; +extern const NAME_PATTERN AltCfgPattern; +extern const NAME_PATTERN OffsetPattern; +extern const NAME_PATTERN WidthPattern; +extern const NAME_PATTERN ValuePattern; +extern const CHAR16 HexDigit[]; + +UINTN EfiStrLen (IN CHAR16 *String); +UINTN EfiStrSize (IN CHAR16 *String); +VOID EfiStrCat (IN CHAR16 *Destination, IN CHAR16 *Source); + +//**************************** Protocol functions implementation *************************** + + +EFI_STATUS HiiAccessExtractConfig( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results +) +{ + EFI_STATUS Status; + UINTN Length; + EFI_GUID Guid; + CHAR16 Name[80]; + CHAR16 *Pointer = Request; + UINT8 *Var = NULL; + EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting; + CHAR16 *ErrorMarker; + + if(Request == NULL) { + *Progress = NULL; + return EFI_INVALID_PARAMETER; + } + + Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting); + if(EFI_ERROR(Status)) + return Status; + +//check syntax for guid + if(!CheckPattern(Request, &GuidPattern)) { + *Progress = Request; + return EFI_INVALID_PARAMETER; + } +//extract guid + ErrorMarker = Pointer; + Pointer += 5; //skip "GUID=" pattern + Length = 32; //length of guid in symbols + StringToBlock(Pointer, Length, (UINT8 *)&Guid); + Pointer += Length; + if(*Pointer != L'&') { + TRACE((TRACE_DXE_CORE, "HII Extract Config: Guid extraction failed\n")); + *Progress = ErrorMarker; + return EFI_INVALID_PARAMETER; + } + +//check syntax for name + if(!CheckPattern(Pointer + 1, &NamePattern)) { + *Progress = Pointer; + return EFI_INVALID_PARAMETER; + } +//extract name + ErrorMarker = Pointer; + Pointer += 6; //skip '&NAME=' pattern + Length = 80; + StringToChar16(Pointer, &Length, Name); + Pointer += (Length * 4); + if(*Pointer != L'&') { + TRACE((TRACE_DXE_CORE, "HII Extract Config: Name extraction failed\n")); + *Progress = ErrorMarker; + return EFI_INVALID_PARAMETER; + } + +//get variable by name and guid from nvram + + Length = 0; + Status = GetEfiVariable(Name, &Guid, NULL, &Length, &Var); + if(EFI_ERROR(Status)) { + *Progress = Request; + return Status; + } + +//find start of OFFSET/WIDTH/VALUE block + Pointer++; //skip '&' + while((*Pointer != L'&') && (*Pointer != 0)) //skip PATH + Pointer++; + + if(*Pointer == 0) { //OFFSET/WIDTH blocks are missed + UINTN TempSize; + CHAR16 *TempString; + CHAR16 *TempString2; + + TempSize = (EfiStrLen(L"&OFFSET=0&WIDTH=") + sizeof(Length) + 1) * sizeof(CHAR16); + TempString = MallocZ(TempSize); + if(TempString == NULL) + return EFI_OUT_OF_RESOURCES; + + Swprintf_s(TempString, TempSize, L"&OFFSET=0&WIDTH=%x", Length); + + TempSize += EfiStrSize(Request); + TempString2 = MallocZ(TempSize); + if(TempString2 == NULL) + return EFI_OUT_OF_RESOURCES; + + EfiStrCat(TempString2, Request); + EfiStrCat(TempString2, TempString); + + Status = ConfigRouting->BlockToConfig(ConfigRouting, TempString2, Var, Length, Results, Progress); + *Progress = Request + EfiStrLen(Request); //set Progress to end of ConfigHdr + pBS->FreePool(TempString); + pBS->FreePool(TempString2); + } else { //OFFSET/WIDTH block found, let's check if it's correct + if(!CheckPattern(Pointer + 1, &OffsetPattern)) { + *Progress = Pointer; + return EFI_INVALID_PARAMETER; + } + Status = ConfigRouting->BlockToConfig(ConfigRouting, Request, Var, Length, Results, Progress); + } + + pBS->FreePool(Var); + + return Status; +} + +EFI_STATUS HiiAccessRouteConfig( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress +) +{ + EFI_STATUS Status; + UINTN Length; + UINTN VarSize; + EFI_GUID Guid; + CHAR16 Name[80]; + CHAR16 *Pointer = Configuration; + UINT8 *Var = NULL; + EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting; + EFI_HANDLE Handle; + UINT32 Attributes; + + if(Configuration == NULL) + { + *Progress = NULL; + return EFI_INVALID_PARAMETER; + } + + Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting); + if(EFI_ERROR(Status)) + return Status; + +//check syntax for guid + if(!CheckPattern(Configuration, &GuidPattern)) + { + *Progress = Configuration; + return EFI_INVALID_PARAMETER; + } + +//check proper device path + Status = FindDeviceHandle(Configuration, &Handle); + if(EFI_ERROR(Status)) + return EFI_NOT_FOUND; + +//extract guid + Pointer += 5; //skip "GUID=" pattern + Length = 32; //length of guid in bytes + StringToBlock(Pointer, Length, (UINT8 *)&Guid); + Pointer += Length; + if(*Pointer != L'&') + { + TRACE((TRACE_DXE_CORE, "HII Route Config: Guid extraction failed\n")); + *Progress = Pointer; + return EFI_INVALID_PARAMETER; + } + +//check syntax for name + if(!CheckPattern(Pointer + 1, &NamePattern)) + { + *Progress = Pointer; + return EFI_INVALID_PARAMETER; + } +//extract name + Pointer += 6; //skip '&NAME=' pattern + Length = 80; + StringToChar16(Pointer, &Length, Name); + Pointer += (Length * 4); + if(*Pointer != L'&') + { + TRACE((TRACE_DXE_CORE, "HII Route Config: Name extraction failed\n")); + *Progress = Pointer; + return EFI_INVALID_PARAMETER; + } + +//get variable by name and guid from nvram + + Length = 0; + Status = GetEfiVariable(Name, &Guid, &Attributes, &Length, &Var); + if(EFI_ERROR(Status)) //requested variable not found + { + Var = NULL; + Length = 0; + Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + } + VarSize = Length; + + Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress); + while(Status == EFI_DEVICE_ERROR) //block not large enough + { + if(Var != NULL) + pBS->FreePool(Var); + + Status = pBS->AllocatePool(EfiBootServicesData, Length, &Var); + if(EFI_ERROR(Status)) + return Status; + + VarSize = Length; + Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress); + } + + if(EFI_ERROR(Status)) + return Status; + + pRS->SetVariable(Name, &Guid, Attributes, VarSize, Var); + + pBS->FreePool(Var); + + return EFI_SUCCESS; +} + +EFI_STATUS HiiAccessFormCallback( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +) +{ + return EFI_UNSUPPORTED; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |