--- /dev/null
+/**@file\r
+ Common header file shared by all source files.\r
+\r
+ This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+ Copyright (c) 2006 - 2007, Intel Corporation.\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/GlobalVariable.h>\r
+#include <Protocol/FrameworkHii.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/FrameworkIfrSupportLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+ IfrCommon.c\r
+\r
+Abstract:\r
+\r
+ Common Library Routines to assist in IFR creation on-the-fly\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+IfrLibConstruct (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetCurrentLanguage (\r
+ OUT CHAR16 *Lang\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determine what is the current language setting\r
+\r
+Arguments:\r
+\r
+ Lang - Pointer of system language\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ UINTN Index;\r
+ CHAR8 Language[4];\r
+\r
+ //\r
+ // Getting the system language and placing it into our Global Data\r
+ //\r
+ Size = sizeof (Language);\r
+\r
+ Status = gRT->GetVariable (\r
+ (CHAR16 *) L"Lang",\r
+ &gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &Size,\r
+ Language\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AsciiStrCpy (Language, "eng");\r
+ }\r
+\r
+ for (Index = 0; Index < 3; Index++) {\r
+ //\r
+ // Bitwise AND ascii value with 0xDF yields an uppercase value.\r
+ // Sign extend into a unicode value\r
+ //\r
+ Lang[Index] = (CHAR16) (Language[Index] & 0xDF);\r
+ }\r
+\r
+ //\r
+ // Null-terminate the value\r
+ //\r
+ Lang[3] = (CHAR16) 0;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+AddString (\r
+ IN VOID *StringBuffer,\r
+ IN CHAR16 *Language,\r
+ IN CHAR16 *String,\r
+ IN OUT STRING_REF *StringToken\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add a string to the incoming buffer and return the token and offset data\r
+\r
+Arguments:\r
+\r
+ StringBuffer - The incoming buffer\r
+\r
+ Language - Currrent language\r
+\r
+ String - The string to be added\r
+\r
+ StringToken - The index where the string placed\r
+\r
+Returns:\r
+\r
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
+\r
+ EFI_SUCCESS - String successfully added to the incoming buffer\r
+\r
+--*/\r
+{\r
+ EFI_HII_STRING_PACK *StringPack;\r
+ EFI_HII_STRING_PACK *StringPackBuffer;\r
+ VOID *NewBuffer;\r
+ RELOFST *PackSource;\r
+ RELOFST *PackDestination;\r
+ UINT8 *Source;\r
+ UINT8 *Destination;\r
+ UINTN Index;\r
+ BOOLEAN Finished;\r
+ UINTN SizeofLanguage;\r
+ UINTN SizeofString;\r
+\r
+ StringPack = (EFI_HII_STRING_PACK *) StringBuffer;\r
+ Finished = FALSE;\r
+\r
+ //\r
+ // Pre-allocate a buffer sufficient for us to work on.\r
+ // We will use it as a destination scratch pad to build data on\r
+ // and when complete shift the data back to the original buffer\r
+ //\r
+ NewBuffer = AllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE);\r
+ if (NewBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ StringPackBuffer = (EFI_HII_STRING_PACK *) NewBuffer;\r
+\r
+ //\r
+ // StringPack is terminated with a length 0 entry\r
+ //\r
+ for (; StringPack->Header.Length != 0;) {\r
+ //\r
+ // If this stringpack's language is same as CurrentLanguage, use it\r
+ //\r
+ if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language, 3) == 0) {\r
+ //\r
+ // We have some data in this string pack, copy the string package up to the string data\r
+ //\r
+ CopyMem (&StringPackBuffer->Header, &StringPack->Header, sizeof (StringPack));\r
+\r
+ //\r
+ // These are references in the structure to tokens, need to increase them by the space occupied by an additional StringPointer\r
+ //\r
+ StringPackBuffer->LanguageNameString = (UINT16) (StringPackBuffer->LanguageNameString + (UINT16) sizeof (RELOFST));\r
+ StringPackBuffer->PrintableLanguageName = (UINT16) (StringPackBuffer->PrintableLanguageName + (UINT16) sizeof (RELOFST));\r
+\r
+ PackSource = (RELOFST *) (StringPack + 1);\r
+ PackDestination = (RELOFST *) (StringPackBuffer + 1);\r
+ for (Index = 0; PackSource[Index] != 0x0000; Index++) {\r
+ //\r
+ // Copy the stringpointers from old to new buffer\r
+ // remember that we are adding a string, so the string offsets will all go up by sizeof (RELOFST)\r
+ //\r
+ PackDestination[Index] = (UINT16) (PackDestination[Index] + sizeof (RELOFST));\r
+ }\r
+\r
+ //\r
+ // Add a new stringpointer in the new buffer since we are adding a string. Null terminate it\r
+ //\r
+ PackDestination[Index] = (UINT16)(PackDestination[Index-1] +\r
+ StrSize((CHAR16 *)((CHAR8 *)(StringPack) + PackSource[Index-1])));\r
+ PackDestination[Index + 1] = (UINT16) 0;\r
+\r
+ //\r
+ // Index is the token value for the new string\r
+ //\r
+ *StringToken = (UINT16) Index;\r
+\r
+ //\r
+ // Source now points to the beginning of the old buffer strings\r
+ // Destination now points to the beginning of the new buffer strings\r
+ //\r
+ Source = (UINT8 *) &PackSource[Index + 1];\r
+ Destination = (UINT8 *) &PackDestination[Index + 2];\r
+\r
+ //\r
+ // This should copy all the strings from the old buffer to the new buffer\r
+ //\r
+ for (; Index != 0; Index--) {\r
+ //\r
+ // Copy Source string to destination buffer\r
+ //\r
+ StrCpy ((CHAR16 *) Destination, (CHAR16 *) Source);\r
+\r
+ //\r
+ // Adjust the source/destination to the next string location\r
+ //\r
+ Destination = Destination + StrSize ((CHAR16 *) Source);\r
+ Source = Source + StrSize ((CHAR16 *) Source);\r
+ }\r
+\r
+ //\r
+ // This copies the new string to the destination buffer\r
+ //\r
+ StrCpy ((CHAR16 *) Destination, (CHAR16 *) String);\r
+\r
+ //\r
+ // Adjust the size of the changed string pack by adding the size of the new string\r
+ // along with the size of the additional offset entry for the new string\r
+ //\r
+ StringPackBuffer->Header.Length = (UINT32) ((UINTN) StringPackBuffer->Header.Length + StrSize (String) + sizeof (RELOFST));\r
+\r
+ //\r
+ // Advance the buffers to point to the next spots.\r
+ //\r
+ StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPackBuffer->Header.Length);\r
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);\r
+ Finished = TRUE;\r
+ continue;\r
+ }\r
+ //\r
+ // This isn't the language of the stringpack we were asked to add a string to\r
+ // so we need to copy it to the new buffer.\r
+ //\r
+ CopyMem (&StringPackBuffer->Header, &StringPack->Header, StringPack->Header.Length);\r
+\r
+ //\r
+ // Advance the buffers to point to the next spots.\r
+ //\r
+ StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPack->Header.Length);\r
+ StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);\r
+ }\r
+\r
+ //\r
+ // If we didn't copy the new data to a stringpack yet\r
+ //\r
+ if (!Finished) {\r
+ PackDestination = (RELOFST *) (StringPackBuffer + 1);\r
+ //\r
+ // Pointing to a new string pack location\r
+ //\r
+ SizeofLanguage = StrSize (Language);\r
+ SizeofString = StrSize (String);\r
+ StringPackBuffer->Header.Length = (UINT32)\r
+ (\r
+ sizeof (EFI_HII_STRING_PACK) -\r
+ sizeof (EFI_STRING) +\r
+ sizeof (RELOFST) +\r
+ sizeof (RELOFST) +\r
+ SizeofLanguage +\r
+ SizeofString\r
+ );\r
+ StringPackBuffer->Header.Type = EFI_HII_STRING;\r
+ StringPackBuffer->LanguageNameString = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);\r
+ StringPackBuffer->PrintableLanguageName = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);\r
+ StringPackBuffer->Attributes = 0;\r
+ PackDestination[0] = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);\r
+ PackDestination[1] = (UINT16) (PackDestination[0] + StrSize (Language));\r
+ PackDestination[2] = (UINT16) 0;\r
+\r
+ //\r
+ // The first string location will be set to destination. The minimum number of strings\r
+ // associated with a stringpack will always be token 0 stored as the languagename (e.g. ENG, SPA, etc)\r
+ // and token 1 as the new string being added and and null entry for the stringpointers\r
+ //\r
+ Destination = (UINT8 *) &PackDestination[3];\r
+\r
+ //\r
+ // Copy the language name string to the new buffer\r
+ //\r
+ StrCpy ((CHAR16 *) Destination, Language);\r
+\r
+ //\r
+ // Advance the destination to the new empty spot\r
+ //\r
+ Destination = Destination + StrSize (Language);\r
+\r
+ //\r
+ // Copy the string to the new buffer\r
+ //\r
+ StrCpy ((CHAR16 *) Destination, String);\r
+\r
+ //\r
+ // Since we are starting with a new string pack - we know the new string is token 1\r
+ //\r
+ *StringToken = (UINT16) 1;\r
+ }\r
+\r
+ //\r
+ // Zero out the original buffer and copy the updated data in the new buffer to the old buffer\r
+ //\r
+ ZeroMem (StringBuffer, DEFAULT_STRING_BUFFER_SIZE);\r
+ CopyMem (StringBuffer, NewBuffer, DEFAULT_STRING_BUFFER_SIZE);\r
+\r
+ //\r
+ // Free the newly created buffer since we don't need it anymore\r
+ //\r
+ gBS->FreePool (NewBuffer);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+AddOpCode (\r
+ IN VOID *FormBuffer,\r
+ IN OUT VOID *OpCodeData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add op-code data to the FormBuffer\r
+\r
+Arguments:\r
+\r
+ FormBuffer - Form buffer to be inserted to\r
+\r
+ OpCodeData - Op-code data to be inserted\r
+\r
+Returns:\r
+\r
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
+\r
+ EFI_SUCCESS - Op-code data successfully inserted\r
+\r
+--*/\r
+{\r
+ EFI_HII_PACK_HEADER *NewBuffer;\r
+ UINT8 *Source;\r
+ UINT8 *Destination;\r
+\r
+ //\r
+ // Pre-allocate a buffer sufficient for us to work on.\r
+ // We will use it as a destination scratch pad to build data on\r
+ // and when complete shift the data back to the original buffer\r
+ //\r
+ NewBuffer = AllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE);\r
+ if (NewBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Source = (UINT8 *) FormBuffer;\r
+ Destination = (UINT8 *) NewBuffer;\r
+\r
+ //\r
+ // Copy the IFR Package header to the new buffer\r
+ //\r
+ CopyMem (Destination, Source, sizeof (EFI_HII_PACK_HEADER));\r
+\r
+ //\r
+ // Advance Source and Destination to next op-code\r
+ //\r
+ Source = Source + sizeof (EFI_HII_PACK_HEADER);\r
+ Destination = Destination + sizeof (EFI_HII_PACK_HEADER);\r
+\r
+ //\r
+ // Copy data to the new buffer until we run into the end_form\r
+ //\r
+ for (; ((EFI_IFR_OP_HEADER *) Source)->OpCode != EFI_IFR_END_FORM_OP;) {\r
+ //\r
+ // If the this opcode is an end_form_set we better be creating and endform\r
+ // Nonetheless, we will add data before the end_form_set. This also provides\r
+ // for interesting behavior in the code we will run, but has no bad side-effects\r
+ // since we will possibly do a 0 byte copy in this particular end-case.\r
+ //\r
+ if (((EFI_IFR_OP_HEADER *) Source)->OpCode == EFI_IFR_END_FORM_SET_OP) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Copy data to new buffer\r
+ //\r
+ CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);\r
+\r
+ //\r
+ // Adjust Source/Destination to next op-code location\r
+ //\r
+ Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;\r
+ Source = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;\r
+ }\r
+\r
+ //\r
+ // Prior to the end_form is where we insert the new op-code data\r
+ //\r
+ CopyMem (Destination, OpCodeData, ((EFI_IFR_OP_HEADER *) OpCodeData)->Length);\r
+ Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+\r
+ NewBuffer->Length = (UINT32) (NewBuffer->Length + (UINT32) (((EFI_IFR_OP_HEADER *) OpCodeData)->Length));\r
+\r
+ //\r
+ // Copy end-form data to new buffer\r
+ //\r
+ CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);\r
+\r
+ //\r
+ // Adjust Source/Destination to next op-code location\r
+ //\r
+ Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;\r
+ Source = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;\r
+\r
+ //\r
+ // Copy end-formset data to new buffer\r
+ //\r
+ CopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);\r
+\r
+ //\r
+ // Zero out the original buffer and copy the updated data in the new buffer to the old buffer\r
+ //\r
+ ZeroMem (FormBuffer, DEFAULT_FORM_BUFFER_SIZE);\r
+ CopyMem (FormBuffer, NewBuffer, DEFAULT_FORM_BUFFER_SIZE);\r
+\r
+ //\r
+ // Free the newly created buffer since we don't need it anymore\r
+ //\r
+ gBS->FreePool (NewBuffer);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetHiiInterface (\r
+ OUT EFI_HII_PROTOCOL **Hii\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the HII protocol interface\r
+\r
+Arguments:\r
+\r
+ Hii - HII protocol interface\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // There should only be one HII protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiProtocolGuid,\r
+ NULL,\r
+ (VOID **) Hii\r
+ );\r
+\r
+ return Status;;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ExtractDataFromHiiHandle (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN OUT UINT16 *ImageLength,\r
+ OUT UINT8 *DefaultImage,\r
+ OUT EFI_GUID *Guid\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Extract information pertaining to the HiiHandle\r
+\r
+Arguments:\r
+\r
+ HiiHandle - Hii handle\r
+\r
+ ImageLength - For input, length of DefaultImage;\r
+ For output, length of actually required\r
+\r
+ DefaultImage - Image buffer prepared by caller\r
+\r
+ Guid - Guid information about the form\r
+\r
+Returns:\r
+\r
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
+\r
+ EFI_BUFFER_TOO_SMALL - DefualtImage has no enough ImageLength\r
+\r
+ EFI_SUCCESS - Successfully extract data from Hii database.\r
+\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PROTOCOL *Hii;\r
+ UINTN DataLength;\r
+ UINT8 *RawData;\r
+ UINT8 *OldData;\r
+ UINTN Index;\r
+ UINTN Temp;\r
+ UINTN SizeOfNvStore;\r
+ UINTN CachedStart;\r
+\r
+ DataLength = DEFAULT_FORM_BUFFER_SIZE;\r
+ SizeOfNvStore = 0;\r
+ CachedStart = 0;\r
+\r
+ Status = GetHiiInterface (&Hii);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate space for retrieval of IFR data\r
+ //\r
+ RawData = AllocateZeroPool (DataLength);\r
+ if (RawData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Get all the forms associated with this HiiHandle\r
+ //\r
+ Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (RawData);\r
+\r
+ //\r
+ // Allocate space for retrieval of IFR data\r
+ //\r
+ RawData = AllocateZeroPool (DataLength);\r
+ if (RawData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Get all the forms associated with this HiiHandle\r
+ //\r
+ Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);\r
+ }\r
+\r
+ OldData = RawData;\r
+\r
+ //\r
+ // Point RawData to the beginning of the form data\r
+ //\r
+ RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER));\r
+\r
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+ switch (RawData[Index]) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ //\r
+ // Copy the GUID information from this handle\r
+ //\r
+ CopyMem (Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ case EFI_IFR_NUMERIC_OP:\r
+ case EFI_IFR_DATE_OP:\r
+ case EFI_IFR_TIME_OP:\r
+ case EFI_IFR_PASSWORD_OP:\r
+ case EFI_IFR_STRING_OP:\r
+ //\r
+ // Remember, multiple op-codes may reference the same item, so let's keep a running\r
+ // marker of what the highest QuestionId that wasn't zero length. This will accurately\r
+ // maintain the Size of the NvStore\r
+ //\r
+ if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) {\r
+ Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;\r
+ if (SizeOfNvStore < Temp) {\r
+ SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;\r
+ }\r
+ }\r
+ }\r
+\r
+ Index = RawData[Index + 1] + Index;\r
+ }\r
+\r
+ //\r
+ // Return an error if buffer is too small\r
+ //\r
+ if (SizeOfNvStore > *ImageLength) {\r
+ gBS->FreePool (OldData);\r
+ *ImageLength = (UINT16) SizeOfNvStore;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (DefaultImage != NULL) {\r
+ ZeroMem (DefaultImage, SizeOfNvStore);\r
+ }\r
+\r
+ //\r
+ // Copy the default image information to the user's buffer\r
+ //\r
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+ switch (RawData[Index]) {\r
+ case EFI_IFR_ONE_OF_OP:\r
+ CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ if (((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Flags & EFI_IFR_FLAG_DEFAULT) {\r
+ CopyMem (&DefaultImage[CachedStart], &((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value, 2);\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId] = ((EFI_IFR_CHECKBOX *) &RawData[Index])->Flags;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ CopyMem (\r
+ &DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId],\r
+ &((EFI_IFR_NUMERIC *) &RawData[Index])->Default,\r
+ 2\r
+ );\r
+ break;\r
+\r
+ }\r
+\r
+ Index = RawData[Index + 1] + Index;\r
+ }\r
+\r
+ *ImageLength = (UINT16) SizeOfNvStore;\r
+\r
+ //\r
+ // Free our temporary repository of form data\r
+ //\r
+ gBS->FreePool (OldData);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_HII_HANDLE\r
+FindHiiHandle (\r
+ IN OUT EFI_HII_PROTOCOL **HiiProtocol, OPTIONAL\r
+ IN EFI_GUID *Guid\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Finds HII handle for given pack GUID previously registered with the HII.\r
+\r
+Arguments:\r
+ HiiProtocol - pointer to pointer to HII protocol interface.\r
+ If NULL, the interface will be found but not returned.\r
+ If it points to NULL, the interface will be found and\r
+ written back to the pointer that is pointed to.\r
+ Guid - The GUID of the pack that registered with the HII.\r
+\r
+Returns:\r
+ Handle to the HII pack previously registered by the memory driver.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ EFI_HII_HANDLE *HiiHandleBuffer;\r
+ EFI_HII_HANDLE HiiHandle;\r
+ UINT16 HiiHandleBufferLength;\r
+ UINT32 NumberOfHiiHandles;\r
+ EFI_GUID HiiGuid;\r
+ EFI_HII_PROTOCOL *HiiProt;\r
+ UINT32 Index;\r
+ UINT16 Length;\r
+\r
+ HiiHandle = 0;\r
+ if ((HiiProtocol != NULL) && (*HiiProtocol != NULL)) {\r
+ //\r
+ // The protocol has been passed in\r
+ //\r
+ HiiProt = *HiiProtocol;\r
+ } else {\r
+ gBS->LocateProtocol (\r
+ &gEfiHiiProtocolGuid,\r
+ NULL,\r
+ (VOID **) &HiiProt\r
+ );\r
+ if (HiiProt == NULL) {\r
+ return HiiHandle;\r
+ }\r
+\r
+ if (HiiProtocol != NULL) {\r
+ //\r
+ // Return back the HII protocol for the caller as promissed\r
+ //\r
+ *HiiProtocol = HiiProt;\r
+ }\r
+ }\r
+ //\r
+ // Allocate buffer\r
+ //\r
+ HiiHandleBufferLength = 10;\r
+ HiiHandleBuffer = AllocatePool (HiiHandleBufferLength);\r
+ ASSERT (HiiHandleBuffer != NULL);\r
+\r
+ //\r
+ // Get the Handles of the packages that were registered with Hii\r
+ //\r
+ Status = HiiProt->FindHandles (\r
+ HiiProt,\r
+ &HiiHandleBufferLength,\r
+ HiiHandleBuffer\r
+ );\r
+\r
+ //\r
+ // Get a bigger bugffer if this one is to small, and try again\r
+ //\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+ gBS->FreePool (HiiHandleBuffer);\r
+\r
+ HiiHandleBuffer = AllocatePool (HiiHandleBufferLength);\r
+ ASSERT (HiiHandleBuffer != NULL);\r
+\r
+ Status = HiiProt->FindHandles (\r
+ HiiProt,\r
+ &HiiHandleBufferLength,\r
+ HiiHandleBuffer\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto lbl_exit;\r
+ }\r
+\r
+ NumberOfHiiHandles = HiiHandleBufferLength / sizeof (EFI_HII_HANDLE);\r
+\r
+ //\r
+ // Iterate Hii handles and look for the one that matches our Guid\r
+ //\r
+ for (Index = 0; Index < NumberOfHiiHandles; Index++) {\r
+\r
+ Length = 0;\r
+ ExtractDataFromHiiHandle (HiiHandleBuffer[Index], &Length, NULL, &HiiGuid);\r
+\r
+ if (CompareGuid (&HiiGuid, Guid)) {\r
+\r
+ HiiHandle = HiiHandleBuffer[Index];\r
+ break;\r
+ }\r
+ }\r
+\r
+lbl_exit:\r
+ gBS->FreePool (HiiHandleBuffer);\r
+ return HiiHandle;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ValidateDataFromHiiHandle (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ OUT BOOLEAN *Results\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Validate that the data associated with the HiiHandle in NVRAM is within\r
+ the reasonable parameters for that FormSet. Values for strings and passwords\r
+ are not verified due to their not having the equivalent of valid range settings.\r
+\r
+Arguments:\r
+\r
+ HiiHandle - Handle of the HII database entry to query\r
+\r
+ Results - If return Status is EFI_SUCCESS, Results provides valid data\r
+ TRUE = NVRAM Data is within parameters\r
+ FALSE = NVRAM Data is NOT within parameters\r
+\r
+Returns:\r
+\r
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
+\r
+ EFI_SUCCESS - Data successfully validated\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PROTOCOL *Hii;\r
+ EFI_GUID Guid;\r
+ UINT8 *RawData;\r
+ UINT8 *OldData;\r
+ UINTN RawDataLength;\r
+ UINT8 *VariableData;\r
+ UINTN Index;\r
+ UINTN Temp;\r
+ UINTN SizeOfNvStore;\r
+ UINTN CachedStart;\r
+ BOOLEAN GotMatch;\r
+\r
+ RawDataLength = DEFAULT_FORM_BUFFER_SIZE;\r
+ SizeOfNvStore = 0;\r
+ CachedStart = 0;\r
+ GotMatch = FALSE;\r
+ *Results = TRUE;\r
+\r
+ Status = GetHiiInterface (&Hii);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate space for retrieval of IFR data\r
+ //\r
+ RawData = AllocateZeroPool (RawDataLength);\r
+ if (RawData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Get all the forms associated with this HiiHandle\r
+ //\r
+ Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (RawData);\r
+\r
+ //\r
+ // Allocate space for retrieval of IFR data\r
+ //\r
+ RawData = AllocateZeroPool (RawDataLength);\r
+ if (RawData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Get all the forms associated with this HiiHandle\r
+ //\r
+ Status = Hii->GetForms (Hii, HiiHandle, 0, &RawDataLength, RawData);\r
+ }\r
+\r
+ OldData = RawData;\r
+\r
+ //\r
+ // Point RawData to the beginning of the form data\r
+ //\r
+ RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER));\r
+\r
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+ if (RawData[Index] == EFI_IFR_FORM_SET_OP) {\r
+ CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
+ break;\r
+ }\r
+\r
+ Index = RawData[Index + 1] + Index;\r
+ }\r
+\r
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+ switch (RawData[Index]) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ case EFI_IFR_NUMERIC_OP:\r
+ case EFI_IFR_DATE_OP:\r
+ case EFI_IFR_TIME_OP:\r
+ case EFI_IFR_PASSWORD_OP:\r
+ case EFI_IFR_STRING_OP:\r
+ //\r
+ // Remember, multiple op-codes may reference the same item, so let's keep a running\r
+ // marker of what the highest QuestionId that wasn't zero length. This will accurately\r
+ // maintain the Size of the NvStore\r
+ //\r
+ if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) {\r
+ Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;\r
+ if (SizeOfNvStore < Temp) {\r
+ SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;\r
+ }\r
+ }\r
+ }\r
+\r
+ Index = RawData[Index + 1] + Index;\r
+ }\r
+\r
+ //\r
+ // Allocate memory for our File Form Tags\r
+ //\r
+ VariableData = AllocateZeroPool (SizeOfNvStore);\r
+ if (VariableData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gRT->GetVariable (\r
+ (CHAR16 *) L"Setup",\r
+ &Guid,\r
+ NULL,\r
+ &SizeOfNvStore,\r
+ (VOID *) VariableData\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ //\r
+ // If there is a variable that exists already and it is larger than what we calculated the\r
+ // storage needs to be, we must assume the variable size from GetVariable is correct and not\r
+ // allow the truncation of the variable. It is very possible that the user who created the IFR\r
+ // we are cracking is not referring to a variable that was in a previous map, however we cannot\r
+ // allow it's truncation.\r
+ //\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ //\r
+ // Free the buffer that was allocated that was too small\r
+ //\r
+ gBS->FreePool (VariableData);\r
+\r
+ VariableData = AllocatePool (SizeOfNvStore);\r
+ if (VariableData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gRT->GetVariable (\r
+ (CHAR16 *) L"Setup",\r
+ &Guid,\r
+ NULL,\r
+ &SizeOfNvStore,\r
+ (VOID *) VariableData\r
+ );\r
+ }\r
+ }\r
+\r
+ //\r
+ // Walk through the form and see that the variable data it refers to is ok.\r
+ // This allows for the possibility of stale (obsoleted) data in the variable\r
+ // can be overlooked without causing an error\r
+ //\r
+ for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+ switch (RawData[Index]) {\r
+ case EFI_IFR_ONE_OF_OP:\r
+ //\r
+ // A one_of has no data, its the option that does - cache the storage Id\r
+ //\r
+ CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ //\r
+ // A one_of_option can be any value\r
+ //\r
+ if (VariableData[CachedStart] == ((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value) {\r
+ GotMatch = TRUE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_END_ONE_OF_OP:\r
+ //\r
+ // At this point lets make sure that the data value in the NVRAM matches one of the options\r
+ //\r
+ if (!GotMatch) {\r
+ *Results = FALSE;\r
+ return EFI_SUCCESS;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ //\r
+ // A checkbox is a boolean, so 0 and 1 are valid\r
+ // Remember, QuestionId corresponds to the offset location of the data in the variable\r
+ //\r
+ if (VariableData[((EFI_IFR_CHECKBOX *) &RawData[Index])->QuestionId] > 1) {\r
+ *Results = FALSE;\r
+ return EFI_SUCCESS;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ if ((VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] < ((EFI_IFR_NUMERIC *)&RawData[Index])->Minimum) ||\r
+ (VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] > ((EFI_IFR_NUMERIC *)&RawData[Index])->Maximum)) {\r
+ *Results = FALSE;\r
+ return EFI_SUCCESS;\r
+ }\r
+ break;\r
+\r
+ }\r
+\r
+ Index = RawData[Index + 1] + Index;\r
+ }\r
+\r
+ //\r
+ // Free our temporary repository of form data\r
+ //\r
+ gBS->FreePool (OldData);\r
+ gBS->FreePool (VariableData);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
--- /dev/null
+/*++\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+ IfrOnTheFly.c\r
+\r
+Abstract:\r
+\r
+ Library Routines to create IFR on-the-fly\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+EFI_STATUS\r
+CreateFormSet (\r
+ IN CHAR16 *FormSetTitle,\r
+ IN EFI_GUID *Guid,\r
+ IN UINT8 Class,\r
+ IN UINT8 SubClass,\r
+ IN OUT VOID **FormBuffer,\r
+ IN OUT VOID **StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a formset\r
+ \r
+Arguments:\r
+ \r
+ FormSetTitle - Title of formset\r
+ \r
+ Guid - Guid of formset\r
+ \r
+ Class - Class of formset\r
+ \r
+ SubClass - Sub class of formset\r
+ \r
+ FormBuffer - Pointer of the formset created\r
+ \r
+ StringBuffer - Pointer of FormSetTitile string created\r
+ \r
+Returns: \r
+\r
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
+ \r
+ EFI_SUCCESS - Formset successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_IFR_PACK IfrPack;\r
+ EFI_IFR_FORM_SET FormSet;\r
+ EFI_IFR_END_FORM_SET EndFormSet;\r
+ UINT8 *Destination;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Pre-allocate a buffer sufficient for us to work from.\r
+ //\r
+ FormBuffer = AllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE);\r
+ if (FormBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Pre-allocate a buffer sufficient for us to work from.\r
+ //\r
+ StringBuffer = AllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE);\r
+ if (StringBuffer == NULL) {\r
+ gBS->FreePool (FormBuffer);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add the FormSetTitle to the string buffer and get the StringToken\r
+ //\r
+ Status = AddString (*StringBuffer, CurrentLanguage, FormSetTitle, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Initialize the Ifr Package header data\r
+ //\r
+ IfrPack.Header.Length = sizeof (EFI_HII_PACK_HEADER) + sizeof (EFI_IFR_FORM_SET) + sizeof (EFI_IFR_END_FORM_SET);\r
+ IfrPack.Header.Type = EFI_HII_IFR;\r
+\r
+ //\r
+ // Initialize FormSet with the appropriate information\r
+ //\r
+ FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;\r
+ FormSet.Header.Length = sizeof (EFI_IFR_FORM_SET);\r
+ FormSet.FormSetTitle = StringToken;\r
+ FormSet.Class = Class;\r
+ FormSet.SubClass = SubClass;\r
+ CopyMem (&FormSet.Guid, Guid, sizeof (EFI_GUID));\r
+\r
+ //\r
+ // Initialize the end formset data\r
+ //\r
+ EndFormSet.Header.Length = sizeof (EFI_IFR_END_FORM_SET);\r
+ EndFormSet.Header.OpCode = EFI_IFR_END_FORM_SET_OP;\r
+\r
+ Destination = (UINT8 *) *FormBuffer;\r
+\r
+ //\r
+ // Copy the formset/endformset data to the form buffer\r
+ //\r
+ CopyMem (Destination, &IfrPack, sizeof (EFI_HII_PACK_HEADER));\r
+\r
+ Destination = Destination + sizeof (EFI_HII_PACK_HEADER);\r
+\r
+ CopyMem (Destination, &FormSet, sizeof (EFI_IFR_FORM_SET));\r
+\r
+ Destination = Destination + sizeof (EFI_IFR_FORM_SET);\r
+\r
+ CopyMem (Destination, &EndFormSet, sizeof (EFI_IFR_END_FORM_SET));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateForm (\r
+ IN CHAR16 *FormTitle,\r
+ IN UINT16 FormId,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a form\r
+ \r
+Arguments:\r
+ \r
+ FormTitle - Title of the form\r
+ \r
+ FormId - Id of the form\r
+ \r
+ FormBuffer - Pointer of the form created\r
+ \r
+ StringBuffer - Pointer of FormTitil string created\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Form successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_FORM Form;\r
+ EFI_IFR_END_FORM EndForm;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ Status = AddString (StringBuffer, CurrentLanguage, FormTitle, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Form.Header.OpCode = EFI_IFR_FORM_OP;\r
+ Form.Header.Length = sizeof (EFI_IFR_FORM);\r
+ Form.FormId = FormId;\r
+ Form.FormTitle = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &Form);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ EndForm.Header.OpCode = EFI_IFR_END_FORM_OP;\r
+ EndForm.Header.Length = sizeof (EFI_IFR_END_FORM);\r
+\r
+ Status = AddOpCode (FormBuffer, &EndForm);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateSubTitle (\r
+ IN CHAR16 *SubTitle,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a SubTitle\r
+ \r
+Arguments:\r
+ \r
+ SubTitle - Sub title to be created\r
+ \r
+ FormBuffer - Where this subtitle to add to\r
+ \r
+ StringBuffer - String buffer created for subtitle\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Subtitle successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_SUBTITLE Subtitle;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ Status = AddString (StringBuffer, CurrentLanguage, SubTitle, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
+ Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
+ Subtitle.SubTitle = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &Subtitle);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateText (\r
+ IN CHAR16 *String,\r
+ IN CHAR16 *String2,\r
+ IN CHAR16 *String3,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a line of text\r
+ \r
+Arguments:\r
+ \r
+ String - First string of the text\r
+ \r
+ String2 - Second string of the text\r
+ \r
+ String3 - Help string of the text\r
+ \r
+ Flags - Flag of the text\r
+ \r
+ Key - Key of the text\r
+ \r
+ FormBuffer - The form where this text adds to\r
+ \r
+ StringBuffer - String buffer created for String, String2 and String3\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Text successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_TEXT Text;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, String, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Text.Header.OpCode = EFI_IFR_TEXT_OP;\r
+ Text.Header.Length = sizeof (EFI_IFR_TEXT);\r
+ Text.Text = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, String2, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Text.TextTwo = StringToken;\r
+\r
+ Text.Flags = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);\r
+ Text.Key = Key;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, String3, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Text.Help = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &Text);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateGoto (\r
+ IN UINT16 FormId,\r
+ IN CHAR16 *Prompt,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a hyperlink\r
+ \r
+Arguments:\r
+ \r
+ FormId - Form ID of the hyperlink\r
+ \r
+ Prompt - Prompt of the hyperlink\r
+ \r
+ FormBuffer - The form where this hyperlink adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Hyperlink successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_REF Hyperlink;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Hyperlink.Header.OpCode = EFI_IFR_REF_OP;\r
+ Hyperlink.Header.Length = sizeof (EFI_IFR_REF);\r
+ Hyperlink.FormId = FormId;\r
+ Hyperlink.Prompt = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &Hyperlink);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateOneOf (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN CHAR16 *Prompt,\r
+ IN CHAR16 *Help,\r
+ IN IFR_OPTION *OptionsList,\r
+ IN UINTN OptionCount,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a one-of question with a set of options to choose from. The\r
+ OptionsList is a pointer to a null-terminated list of option descriptions.\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the one-of box\r
+ \r
+ DataWidth - DataWidth of the one-of box\r
+ \r
+ Prompt - Prompt of the one-of box\r
+ \r
+ Help - Help of the one-of box\r
+ \r
+ OptionsList - Each string in it is an option of the one-of box\r
+ \r
+ OptionCount - Option string count\r
+ \r
+ FormBuffer - The form where this one-of box adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt, Help and Option strings\r
+ \r
+Returns: \r
+\r
+ EFI_DEVICE_ERROR - DataWidth > 2\r
+\r
+ EFI_SUCCESS - One-Of box successfully created.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_IFR_ONE_OF OneOf;\r
+ EFI_IFR_ONE_OF_OPTION OneOfOption;\r
+ EFI_IFR_END_ONE_OF EndOneOf;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // We do not create op-code storage widths for one-of in excess of 16 bits for now\r
+ //\r
+ if (DataWidth > 2) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
+ OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);\r
+ OneOf.QuestionId = QuestionId;\r
+ OneOf.Width = DataWidth;\r
+ OneOf.Prompt = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ OneOf.Help = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &OneOf);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ for (Index = 0; Index < OptionCount; Index++) {\r
+ OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
+ OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);\r
+\r
+ //\r
+ // Add string and get token back\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, OptionsList[Index].OptionString, &StringToken);\r
+\r
+ OneOfOption.Option = StringToken;\r
+ OneOfOption.Value = OptionsList[Index].Value;\r
+ OneOfOption.Flags = (UINT8) (OptionsList[Index].Flags | EFI_IFR_FLAG_CREATED);\r
+ OneOfOption.Key = OptionsList[Index].Key;\r
+\r
+ Status = AddOpCode (FormBuffer, &OneOfOption);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ EndOneOf.Header.Length = sizeof (EFI_IFR_END_ONE_OF);\r
+ EndOneOf.Header.OpCode = EFI_IFR_END_ONE_OF_OP;\r
+\r
+ Status = AddOpCode (FormBuffer, &EndOneOf);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+CreateOrderedList (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 MaxEntries,\r
+ IN CHAR16 *Prompt,\r
+ IN CHAR16 *Help,\r
+ IN IFR_OPTION *OptionsList,\r
+ IN UINTN OptionCount,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a one-of question with a set of options to choose from. The\r
+ OptionsList is a pointer to a null-terminated list of option descriptions.\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the ordered list\r
+ \r
+ MaxEntries - MaxEntries of the ordered list\r
+ \r
+ Prompt - Prompt of the ordered list\r
+ \r
+ Help - Help of the ordered list\r
+ \r
+ OptionsList - Each string in it is an option of the ordered list\r
+ \r
+ OptionCount - Option string count\r
+ \r
+ FormBuffer - The form where this ordered list adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt, Help and Option strings\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Ordered list successfully created.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_IFR_ORDERED_LIST OrderedList;\r
+ EFI_IFR_ONE_OF_OPTION OrderedListOption;\r
+ EFI_IFR_END_ONE_OF EndOrderedList;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
+ OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);\r
+ OrderedList.QuestionId = QuestionId;\r
+ OrderedList.MaxEntries = MaxEntries;\r
+ OrderedList.Prompt = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ OrderedList.Help = StringToken;\r
+\r
+ Status = AddOpCode (FormBuffer, &OrderedList);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ for (Index = 0; Index < OptionCount; Index++) {\r
+ OrderedListOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
+ OrderedListOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);\r
+\r
+ //\r
+ // Add string and get token back\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, OptionsList[Index].OptionString, &StringToken);\r
+\r
+ OrderedListOption.Option = StringToken;\r
+ OrderedListOption.Value = OptionsList[Index].Value;\r
+ OrderedListOption.Flags = (UINT8) (OptionsList[Index].Flags | EFI_IFR_FLAG_CREATED);\r
+ OrderedListOption.Key = OptionsList[Index].Key;\r
+\r
+ Status = AddOpCode (FormBuffer, &OrderedListOption);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ EndOrderedList.Header.Length = sizeof (EFI_IFR_END_ONE_OF);\r
+ EndOrderedList.Header.OpCode = EFI_IFR_END_ONE_OF_OP;\r
+\r
+ Status = AddOpCode (FormBuffer, &EndOrderedList);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateCheckBox (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN CHAR16 *Prompt,\r
+ IN CHAR16 *Help,\r
+ IN UINT8 Flags,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a checkbox\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the check box\r
+ \r
+ DataWidth - DataWidth of the check box\r
+ \r
+ Prompt - Prompt of the check box\r
+ \r
+ Help - Help of the check box\r
+ \r
+ Flags - Flags of the check box\r
+ \r
+ FormBuffer - The form where this check box adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt and Help.\r
+ \r
+Returns: \r
+\r
+ EFI_DEVICE_ERROR - DataWidth > 1\r
+\r
+ EFI_SUCCESS - Check box successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_CHECKBOX CheckBox;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // We do not create op-code storage widths for checkbox in excess of 8 bits for now\r
+ //\r
+ if (DataWidth > 1) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
+ CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX);\r
+ CheckBox.QuestionId = QuestionId;\r
+ CheckBox.Width = DataWidth;\r
+ CheckBox.Prompt = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CheckBox.Help = StringToken;\r
+ CheckBox.Flags = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);\r
+\r
+ Status = AddOpCode (FormBuffer, &CheckBox);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateNumeric (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN CHAR16 *Prompt,\r
+ IN CHAR16 *Help,\r
+ IN UINT16 Minimum,\r
+ IN UINT16 Maximum,\r
+ IN UINT16 Step,\r
+ IN UINT16 Default,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a numeric\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the numeric\r
+ \r
+ DataWidth - DataWidth of the numeric\r
+ \r
+ Prompt - Prompt of the numeric\r
+ \r
+ Help - Help of the numeric\r
+ \r
+ Minimum - Minumun boundary of the numeric\r
+ \r
+ Maximum - Maximum boundary of the numeric\r
+ \r
+ Step - Step of the numeric\r
+ \r
+ Default - Default value\r
+ \r
+ Flags - Flags of the numeric\r
+ \r
+ Key - Key of the numeric\r
+ \r
+ FormBuffer - The form where this numeric adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt and Help.\r
+ \r
+Returns: \r
+\r
+ EFI_DEVICE_ERROR - DataWidth > 2\r
+ \r
+ EFI_SUCCESS - Numeric is successfully created\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_NUMERIC Numeric;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // We do not create op-code storage widths for numerics in excess of 16 bits for now\r
+ //\r
+ if (DataWidth > 2) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
+ Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);\r
+ Numeric.QuestionId = QuestionId;\r
+ Numeric.Width = DataWidth;\r
+ Numeric.Prompt = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Numeric.Help = StringToken;\r
+ Numeric.Minimum = Minimum;\r
+ Numeric.Maximum = Maximum;\r
+ Numeric.Step = Step;\r
+ Numeric.Default = Default;\r
+ Numeric.Flags = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);\r
+ Numeric.Key = Key;\r
+\r
+ Status = AddOpCode (FormBuffer, &Numeric);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateString (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN CHAR16 *Prompt,\r
+ IN CHAR16 *Help,\r
+ IN UINT8 MinSize,\r
+ IN UINT8 MaxSize,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer,\r
+ IN OUT VOID *StringBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a string\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the string\r
+ \r
+ DataWidth - DataWidth of the string\r
+ \r
+ Prompt - Prompt of the string\r
+ \r
+ Help - Help of the string\r
+ \r
+ MinSize - Min size boundary of the string\r
+ \r
+ MaxSize - Max size boundary of the string\r
+ \r
+ Flags - Flags of the string\r
+ \r
+ Key - Key of the string\r
+ \r
+ FormBuffer - The form where this string adds to\r
+ \r
+ StringBuffer - String buffer created for Prompt and Help.\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - String successfully created.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_IFR_STRING String;\r
+ CHAR16 CurrentLanguage[4];\r
+ STRING_REF StringToken;\r
+\r
+ //\r
+ // Obtain current language value\r
+ //\r
+ GetCurrentLanguage (CurrentLanguage);\r
+\r
+ //\r
+ // Add first string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Prompt, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ String.Header.OpCode = EFI_IFR_STRING_OP;\r
+ String.Header.Length = sizeof (EFI_IFR_STRING);\r
+ String.QuestionId = QuestionId;\r
+ String.Width = DataWidth;\r
+ String.Prompt = StringToken;\r
+\r
+ //\r
+ // Add second string, get first string's token\r
+ //\r
+ Status = AddString (StringBuffer, CurrentLanguage, Help, &StringToken);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ String.Help = StringToken;\r
+ String.MinSize = MinSize;\r
+ String.MaxSize = MaxSize;\r
+ String.Flags = (UINT8) (Flags | EFI_IFR_FLAG_CREATED);\r
+ String.Key = Key;\r
+\r
+ Status = AddOpCode (FormBuffer, &String);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+ IfrOpCodeCreation.c\r
+\r
+Abstract:\r
+\r
+ Library Routines to create IFR independent of string data - assume tokens already exist\r
+ Primarily to be used for exporting op-codes at a label in pre-defined forms.\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+EFI_STATUS\r
+CreateSubTitleOpCode (\r
+ IN STRING_REF StringToken,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a SubTitle opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ StringToken - StringToken of the subtitle\r
+ \r
+ FormBuffer - Output of subtitle as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Subtitle created to be a form\r
+\r
+--*/\r
+{\r
+ EFI_IFR_SUBTITLE Subtitle;\r
+\r
+ Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
+ Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
+ Subtitle.SubTitle = StringToken;\r
+\r
+ CopyMem (FormBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateTextOpCode (\r
+ IN STRING_REF StringToken,\r
+ IN STRING_REF StringTokenTwo,\r
+ IN STRING_REF StringTokenThree,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a Text opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ StringToken - First string token of the text\r
+ \r
+ StringTokenTwo - Second string token of the text\r
+ \r
+ StringTokenThree - Help string token of the text\r
+ \r
+ Flags - Flag of the text\r
+ \r
+ Key - Key of the text\r
+ \r
+ FormBuffer - Output of text as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Text created to be a form\r
+\r
+--*/\r
+{\r
+ EFI_IFR_TEXT Text;\r
+\r
+ Text.Header.OpCode = EFI_IFR_TEXT_OP;\r
+ Text.Header.Length = sizeof (EFI_IFR_TEXT);\r
+ Text.Text = StringToken;\r
+\r
+ Text.TextTwo = StringTokenTwo;\r
+ Text.Help = StringTokenThree;\r
+ Text.Flags = Flags;\r
+ Text.Key = Key;\r
+\r
+ CopyMem (FormBuffer, &Text, sizeof (EFI_IFR_TEXT));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateGotoOpCode (\r
+ IN UINT16 FormId,\r
+ IN STRING_REF StringToken,\r
+ IN STRING_REF StringTokenTwo,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a hyperlink opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ FormId - Form ID of the hyperlink\r
+ \r
+ StringToken - Prompt string token of the hyperlink\r
+ \r
+ StringTokenTwo - Help string token of the hyperlink\r
+ \r
+ Flags - Flags of the hyperlink\r
+ \r
+ Key - Key of the hyperlink\r
+ \r
+ FormBuffer - Output of hyperlink as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Hyperlink created to be a form\r
+\r
+--*/\r
+{\r
+ EFI_IFR_REF Hyperlink;\r
+\r
+ Hyperlink.Header.OpCode = EFI_IFR_REF_OP;\r
+ Hyperlink.Header.Length = sizeof (EFI_IFR_REF);\r
+ Hyperlink.FormId = FormId;\r
+ Hyperlink.Prompt = StringToken;\r
+ Hyperlink.Help = StringTokenTwo;\r
+ Hyperlink.Key = Key;\r
+ Hyperlink.Flags = Flags;\r
+\r
+ CopyMem (FormBuffer, &Hyperlink, sizeof (EFI_IFR_REF));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateOneOfOpCode (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN STRING_REF PromptToken,\r
+ IN STRING_REF HelpToken,\r
+ IN IFR_OPTION *OptionsList,\r
+ IN UINTN OptionCount,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a one-of opcode with a set of option op-codes to choose from independent of string creation.\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+\r
+ OptionsList is a pointer to a null-terminated list of option descriptions. Ensure that OptionsList[x].StringToken\r
+ has been filled in since this routine will not generate StringToken values.\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the one-of box\r
+ \r
+ DataWidth - DataWidth of the one-of box\r
+ \r
+ PromptToken - Prompt string token of the one-of box\r
+ \r
+ HelpToken - Help string token of the one-of box\r
+ \r
+ OptionsList - Each string in it is an option of the one-of box\r
+ \r
+ OptionCount - Option string count\r
+ \r
+ FormBuffer - Output of One-Of box as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - One-Of box created to be a form\r
+ \r
+ EFI_DEVICE_ERROR - DataWidth > 2\r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+ EFI_IFR_ONE_OF OneOf;\r
+ EFI_IFR_ONE_OF_OPTION OneOfOption;\r
+ EFI_IFR_END_ONE_OF EndOneOf;\r
+ UINT8 *LocalBuffer;\r
+\r
+ //\r
+ // We do not create op-code storage widths for one-of in excess of 16 bits for now\r
+ //\r
+ if (DataWidth > 2) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
+ OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);\r
+ OneOf.QuestionId = QuestionId;\r
+ OneOf.Width = DataWidth;\r
+ OneOf.Prompt = PromptToken;\r
+\r
+ OneOf.Help = HelpToken;\r
+\r
+ LocalBuffer = (UINT8 *) FormBuffer;\r
+\r
+ CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF));\r
+\r
+ for (Index = 0; Index < OptionCount; Index++) {\r
+ OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
+ OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);\r
+\r
+ OneOfOption.Option = OptionsList[Index].StringToken;\r
+ OneOfOption.Value = OptionsList[Index].Value;\r
+ OneOfOption.Flags = OptionsList[Index].Flags;\r
+ OneOfOption.Key = OptionsList[Index].Key;\r
+\r
+ CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF_OPTION));\r
+ }\r
+\r
+ EndOneOf.Header.Length = sizeof (EFI_IFR_END_ONE_OF);\r
+ EndOneOf.Header.OpCode = EFI_IFR_END_ONE_OF_OP;\r
+\r
+ CopyMem (LocalBuffer, &EndOneOf, sizeof (EFI_IFR_END_ONE_OF));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_END_ONE_OF));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+CreateOrderedListOpCode (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 MaxEntries,\r
+ IN STRING_REF PromptToken,\r
+ IN STRING_REF HelpToken,\r
+ IN IFR_OPTION *OptionsList,\r
+ IN UINTN OptionCount,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a ordered list opcode with a set of option op-codes to choose from independent of string creation.\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+\r
+ OptionsList is a pointer to a null-terminated list of option descriptions. Ensure that OptionsList[x].StringToken\r
+ has been filled in since this routine will not generate StringToken values.\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the ordered list\r
+ \r
+ MaxEntries - MaxEntries of the ordered list\r
+ \r
+ PromptToken - Prompt string token of the ordered list\r
+ \r
+ HelpToken - Help string token of the ordered list\r
+ \r
+ OptionsList - Each string in it is an option of the ordered list\r
+ \r
+ OptionCount - Option string count\r
+ \r
+ FormBuffer - Output of ordered list as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Ordered list created to be a form\r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+ EFI_IFR_ORDERED_LIST OrderedList;\r
+ EFI_IFR_ONE_OF_OPTION OrderedListOption;\r
+ EFI_IFR_END_ONE_OF EndOrderedList;\r
+ UINT8 *LocalBuffer;\r
+\r
+ OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
+ OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);\r
+ OrderedList.QuestionId = QuestionId;\r
+ OrderedList.MaxEntries = MaxEntries;\r
+ OrderedList.Prompt = PromptToken;\r
+\r
+ OrderedList.Help = HelpToken;\r
+\r
+ LocalBuffer = (UINT8 *) FormBuffer;\r
+\r
+ CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ORDERED_LIST));\r
+\r
+ for (Index = 0; Index < OptionCount; Index++) {\r
+ OrderedListOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
+ OrderedListOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);\r
+\r
+ OrderedListOption.Option = OptionsList[Index].StringToken;\r
+ OrderedListOption.Value = OptionsList[Index].Value;\r
+ OrderedListOption.Flags = OptionsList[Index].Flags;\r
+ OrderedListOption.Key = OptionsList[Index].Key;\r
+\r
+ CopyMem (LocalBuffer, &OrderedListOption, sizeof (EFI_IFR_ONE_OF_OPTION));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_ONE_OF_OPTION));\r
+ }\r
+\r
+ EndOrderedList.Header.Length = sizeof (EFI_IFR_END_ONE_OF);\r
+ EndOrderedList.Header.OpCode = EFI_IFR_END_ONE_OF_OP;\r
+\r
+ CopyMem (LocalBuffer, &EndOrderedList, sizeof (EFI_IFR_END_ONE_OF));\r
+\r
+ LocalBuffer = (UINT8 *) (LocalBuffer + sizeof (EFI_IFR_END_ONE_OF));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+CreateCheckBoxOpCode (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN STRING_REF PromptToken,\r
+ IN STRING_REF HelpToken,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a checkbox opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the check box\r
+ \r
+ DataWidth - DataWidth of the check box\r
+ \r
+ PromptToken - Prompt string token of the check box\r
+ \r
+ HelpToken - Help string token of the check box\r
+ \r
+ Flags - Flags of the check box\r
+ \r
+ Key - Key of the check box\r
+ \r
+ FormBuffer - Output of the check box as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Checkbox created to be a form\r
+ \r
+ EFI_DEVICE_ERROR - DataWidth > 1\r
+\r
+--*/\r
+{\r
+ EFI_IFR_CHECKBOX CheckBox;\r
+\r
+ //\r
+ // We do not create op-code storage widths for checkbox in excess of 8 bits for now\r
+ //\r
+ if (DataWidth > 1) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
+ CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX);\r
+ CheckBox.QuestionId = QuestionId;\r
+ CheckBox.Width = DataWidth;\r
+ CheckBox.Prompt = PromptToken;\r
+\r
+ CheckBox.Help = HelpToken;\r
+ CheckBox.Flags = Flags;\r
+ CheckBox.Key = Key;\r
+\r
+ CopyMem (FormBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateNumericOpCode (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN STRING_REF PromptToken,\r
+ IN STRING_REF HelpToken,\r
+ IN UINT16 Minimum,\r
+ IN UINT16 Maximum,\r
+ IN UINT16 Step,\r
+ IN UINT16 Default,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a numeric opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the numeric\r
+ \r
+ DataWidth - DataWidth of the numeric\r
+ \r
+ PromptToken - Prompt string token of the numeric\r
+ \r
+ HelpToken - Help string token of the numeric\r
+ \r
+ Minimum - Minumun boundary of the numeric\r
+ \r
+ Maximum - Maximum boundary of the numeric\r
+ \r
+ Step - Step of the numeric\r
+ \r
+ Default - Default value of the numeric\r
+ \r
+ Flags - Flags of the numeric\r
+ \r
+ Key - Key of the numeric\r
+ \r
+ FormBuffer - Output of the numeric as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - The numeric created to be a form.\r
+ \r
+ EFI_DEVICE_ERROR - DataWidth > 2\r
+\r
+--*/\r
+{\r
+ EFI_IFR_NUMERIC Numeric;\r
+\r
+ //\r
+ // We do not create op-code storage widths for numerics in excess of 16 bits for now\r
+ //\r
+ if (DataWidth > 2) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
+ Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);\r
+ Numeric.QuestionId = QuestionId;\r
+ Numeric.Width = DataWidth;\r
+ Numeric.Prompt = PromptToken;\r
+\r
+ Numeric.Help = HelpToken;\r
+ Numeric.Minimum = Minimum;\r
+ Numeric.Maximum = Maximum;\r
+ Numeric.Step = Step;\r
+ Numeric.Default = Default;\r
+ Numeric.Flags = Flags;\r
+ Numeric.Key = Key;\r
+\r
+ CopyMem (FormBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateStringOpCode (\r
+ IN UINT16 QuestionId,\r
+ IN UINT8 DataWidth,\r
+ IN STRING_REF PromptToken,\r
+ IN STRING_REF HelpToken,\r
+ IN UINT8 MinSize,\r
+ IN UINT8 MaxSize,\r
+ IN UINT8 Flags,\r
+ IN UINT16 Key,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a numeric opcode independent of string creation\r
+ This is used primarily by users who need to create just one particular valid op-code and the string\r
+ data will be assumed to exist in the HiiDatabase already. (Useful when exporting op-codes at a label\r
+ location to pre-defined forms in HII)\r
+ \r
+Arguments:\r
+ \r
+ QuestionId - Question ID of the string\r
+ \r
+ DataWidth - DataWidth of the string\r
+ \r
+ PromptToken - Prompt token of the string\r
+ \r
+ HelpToken - Help token of the string\r
+ \r
+ MinSize - Min size boundary of the string\r
+ \r
+ MaxSize - Max size boundary of the string\r
+ \r
+ Flags - Flags of the string\r
+ \r
+ Key - Key of the string\r
+ \r
+ FormBuffer - Output of the string as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - String created to be a form.\r
+\r
+--*/\r
+{\r
+ EFI_IFR_STRING String;\r
+\r
+ String.Header.OpCode = EFI_IFR_STRING_OP;\r
+ String.Header.Length = sizeof (EFI_IFR_STRING);\r
+ String.QuestionId = QuestionId;\r
+ String.Width = DataWidth;\r
+ String.Prompt = PromptToken;\r
+\r
+ String.Help = HelpToken;\r
+ String.MinSize = MinSize;\r
+ String.MaxSize = MaxSize;\r
+ String.Flags = Flags;\r
+ String.Key = Key;\r
+\r
+ CopyMem (FormBuffer, &String, sizeof (EFI_IFR_STRING));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateBannerOpCode (\r
+ IN UINT16 Title,\r
+ IN UINT16 LineNumber,\r
+ IN UINT8 Alignment,\r
+ IN OUT VOID *FormBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a banner opcode. This is primarily used by the FrontPage implementation from BDS.\r
+ \r
+Arguments:\r
+ \r
+ Title - Title of the banner\r
+ \r
+ LineNumber - LineNumber of the banner\r
+ \r
+ Alignment - Alignment of the banner\r
+ \r
+ FormBuffer - Output of banner as a form\r
+ \r
+Returns: \r
+\r
+ EFI_SUCCESS - Banner created to be a form.\r
+\r
+--*/\r
+{\r
+ EFI_IFR_BANNER Banner;\r
+\r
+ Banner.Header.OpCode = EFI_IFR_BANNER_OP;\r
+ Banner.Header.Length = sizeof (EFI_IFR_BANNER);\r
+ CopyMem (&Banner.Title, &Title, sizeof (UINT16));\r
+ CopyMem (&Banner.LineNumber, &LineNumber, sizeof (UINT16));\r
+ Banner.Alignment = Alignment;\r
+\r
+ CopyMem (FormBuffer, &Banner, sizeof (EFI_IFR_BANNER));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+#/** @file\r
+# EDK Internal Form Refresentation Support Library Instance.\r
+#\r
+# The library instance provides common library routines help in \r
+# IFR creation on-the-fly, HII variable access, HII database access, multi language supports.\r
+# Copyright (c) 2006 - 2007, Intel Corporation.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = FrameworkIfrSupportLib\r
+ FILE_GUID = ea55bada-d488-427b-9d2d-227e0aaa3707\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = FrameworkIfrSupportLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER \r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ CONSTRUCTOR = IfrLibConstruct\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+# Variable Guid C Name: gLanGuid Variable Name: L"Lan"\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+ IfrVariable.c\r
+ IfrOpCodeCreation.c\r
+ IfrOnTheFly.c\r
+ IfrCommon.c\r
+ CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+# this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+ UefiRuntimeServicesTableLib\r
+ UefiBootServicesTableLib\r
+ MemoryAllocationLib\r
+ BaseMemoryLib\r
+ BaseLib\r
+ DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+ gEfiGlobalVariableGuid # ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+# that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+ gEfiHiiProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>EdkIfrSupportLib</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>ea55bada-d488-427b-9d2d-227e0aaa3707</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>EDK Internal Form Refresentation Support Library Instance.</Abstract>\r
+ <Description>The library instance provides common library routines help in
+ IFR creation on-the-fly, HII variable access, HII database access, multi language supports.</Description>\r
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation.</Copyright>\r
+ <License>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.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>EdkIfrSupportLib</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_PRODUCED" SupModuleList="DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER">\r
+ <Keyword>EdkIfrSupportLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>IfrCommon.c</Filename>\r
+ <Filename>IfrOnTheFly.c</Filename>\r
+ <Filename>IfrOpCodeCreation.c</Filename>\r
+ <Filename>IfrVariable.c</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiHiiProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Variables>\r
+ <Variable Usage="ALWAYS_CONSUMED">\r
+ <VariableName>0x004C 0x0061 0x006E</VariableName>\r
+ <GuidC_Name>gLanGuid</GuidC_Name>\r
+ </Variable>\r
+ </Variables>\r
+ <Guids>\r
+ <GuidCNames Usage="ALWAYS_CONSUMED">\r
+ <GuidCName>gEfiGlobalVariableGuid</GuidCName>\r
+ </GuidCNames>\r
+ </Guids>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <Constructor>IfrLibConstruct</Constructor>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+ IfrVariable.c\r
+\r
+Abstract:\r
+ Variable/Map manipulations routines\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+VOID\r
+EfiLibHiiVariablePackGetMap (\r
+ IN EFI_HII_VARIABLE_PACK *Pack, \r
+ OUT CHAR16 **Name, OPTIONAL\r
+ OUT EFI_GUID **Guid, OPTIONAL\r
+ OUT UINT16 *Id, OPTIONAL\r
+ OUT VOID **Var, OPTIONAL\r
+ OUT UINTN *Size OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Extracts a variable form a Pack.\r
+\r
+Arguments:\r
+\r
+ Pack - List of variables\r
+ Name - Name of the variable/map\r
+ Guid - GUID of the variable/map\r
+ Var - Pointer to the variable/map\r
+ Size - Size of the variable/map in bytes\r
+\r
+Returns: \r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ if (NULL != Name) {\r
+ *Name = (VOID *) (Pack + 1);\r
+ }\r
+ \r
+ if (NULL != Guid) { \r
+ *Guid = (EFI_GUID *)(UINTN)&Pack->VariableGuid;\r
+ }\r
+ \r
+ \r
+ if (NULL != Id) {\r
+ *Id = Pack->VariableId;\r
+ }\r
+ \r
+ if (NULL != Var) {\r
+ *Var = (VOID *) ((CHAR8 *) (Pack + 1) + Pack->VariableNameLength);\r
+ }\r
+ \r
+ if (NULL != Size) {\r
+ *Size = Pack->Header.Length - sizeof (*Pack) - Pack->VariableNameLength;\r
+ }\r
+}\r
+\r
+\r
+UINTN\r
+EfiLibHiiVariablePackListGetMapCnt (\r
+ IN EFI_HII_VARIABLE_PACK_LIST *List\r
+ )\r
+ \r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Finds a count of the variables/maps in the List.\r
+\r
+Arguments:\r
+\r
+ List - List of variables\r
+\r
+Returns: \r
+\r
+ UINTN - The number of map count.\r
+\r
+--*/\r
+\r
+{\r
+ UINTN Cnt = 0;\r
+ while (NULL != List) {\r
+ Cnt++;\r
+ List = List->NextVariablePack;\r
+ }\r
+ return Cnt;\r
+}\r
+\r
+\r
+VOID\r
+EfiLibHiiVariablePackListForEachVar (\r
+ IN EFI_HII_VARIABLE_PACK_LIST *List,\r
+ IN EFI_LIB_HII_VARIABLE_PACK_LIST_CALLBACK *Callback\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Will iterate all variable/maps as appearing \r
+ in List and for each, it will call the Callback.\r
+\r
+Arguments:\r
+\r
+ List - List of variables\r
+ Callback - Routine to be called for each iterated variable.\r
+\r
+Returns: \r
+\r
+ VOID\r
+ \r
+--*/\r
+\r
+{\r
+ CHAR16 *MapName;\r
+ EFI_GUID *MapGuid;\r
+ UINT16 MapId;\r
+ VOID *Map;\r
+ UINTN MapSize;\r
+\r
+ while (NULL != List) {\r
+ EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
+ //\r
+ // call the callback\r
+ //\r
+ Callback (MapName, MapGuid, MapId, Map, MapSize); \r
+ List = List->NextVariablePack;\r
+ }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariablePackListGetMapByIdx (\r
+ IN UINTN Idx, \r
+ IN EFI_HII_VARIABLE_PACK_LIST *List, \r
+ OUT CHAR16 **Name, OPTIONAL\r
+ OUT EFI_GUID **Guid, OPTIONAL\r
+ OUT UINT16 *Id, OPTIONAL\r
+ OUT VOID **Var,\r
+ OUT UINTN *Size\r
+ )\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Finds a variable form List given \r
+ the order number as appears in the List.\r
+\r
+Arguments:\r
+\r
+ Idx - The index of the variable/map to retrieve\r
+ List - List of variables\r
+ Name - Name of the variable/map\r
+ Guid - GUID of the variable/map\r
+ Var - Pointer to the variable/map\r
+ Size - Size of the variable/map in bytes\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Variable is found, OUT parameters are valid\r
+ EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid\r
+\r
+--*/\r
+{\r
+ CHAR16 *MapName;\r
+ EFI_GUID *MapGuid;\r
+ UINT16 MapId;\r
+ VOID *Map;\r
+ UINTN MapSize;\r
+\r
+ while (NULL != List) {\r
+ EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
+ if (0 == Idx--) {\r
+ *Var = Map;\r
+ *Size = MapSize;\r
+\r
+ if (NULL != Name) {\r
+ *Name = MapName;\r
+ }\r
+\r
+ if (NULL != Guid) {\r
+ *Guid = MapGuid;\r
+ }\r
+ \r
+ if (NULL != Id) {\r
+ *Id = MapId;\r
+ }\r
+ \r
+ return EFI_SUCCESS; // Map found\r
+ }\r
+ List = List->NextVariablePack;\r
+ }\r
+ //\r
+ // If here, the map is not found\r
+ //\r
+ return EFI_NOT_FOUND; \r
+}\r
+\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariablePackListGetMapById (\r
+ IN UINT16 Id, \r
+ IN EFI_HII_VARIABLE_PACK_LIST *List,\r
+ OUT CHAR16 **Name, OPTIONAL\r
+ OUT EFI_GUID **Guid, OPTIONAL\r
+ OUT VOID **Var,\r
+ OUT UINTN *Size\r
+ )\r
+ \r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Finds a variable form List given the \r
+ order number as appears in the List.\r
+\r
+Arguments:\r
+\r
+ Id - The ID of the variable/map to retrieve\r
+ List - List of variables\r
+ Name - Name of the variable/map\r
+ Guid - GUID of the variable/map\r
+ Var - Pointer to the variable/map\r
+ Size - Size of the variable/map in bytes\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Variable is found, OUT parameters are valid\r
+ EFI_NOT_FOUND - Variable is not found, OUT parameters are not valid\r
+\r
+--*/\r
+\r
+{ \r
+ CHAR16 *MapName;\r
+ EFI_GUID *MapGuid;\r
+ UINT16 MapId;\r
+ VOID *Map;\r
+ UINTN MapSize;\r
+\r
+ while (NULL != List) {\r
+ EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
+ if (MapId == Id) {\r
+ *Var = Map;\r
+ *Size = MapSize;\r
+ if (NULL != Name) {\r
+ *Name = MapName;\r
+ }\r
+ if (NULL != Guid) {\r
+ *Guid = MapGuid;\r
+ }\r
+ //\r
+ // Map found\r
+ //\r
+ return EFI_SUCCESS; \r
+ }\r
+ List = List->NextVariablePack;\r
+ }\r
+ //\r
+ // If here, the map is not found\r
+ //\r
+ return EFI_NOT_FOUND; \r
+}\r
+\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariablePackListGetMap (\r
+ IN EFI_HII_VARIABLE_PACK_LIST *List,\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ OUT UINT16 *Id,\r
+ OUT VOID **Var, \r
+ OUT UINTN *Size\r
+ )\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Finds a variable form EFI_HII_VARIABLE_PACK_LIST given name and GUID.\r
+\r
+Arguments:\r
+\r
+ List - List of variables\r
+ Name - Name of the variable/map to be found\r
+ Guid - GUID of the variable/map to be found\r
+ Var - Pointer to the variable/map found\r
+ Size - Size of the variable/map in bytes found\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - variable is found, OUT parameters are valid\r
+ EFI_NOT_FOUND - variable is not found, OUT parameters are not valid\r
+\r
+--*/\r
+\r
+{ \r
+ VOID *Map;\r
+ UINTN MapSize;\r
+ UINT16 MapId;\r
+ CHAR16 *MapName;\r
+ EFI_GUID *MapGuid;\r
+\r
+ while (NULL != List) {\r
+ EfiLibHiiVariablePackGetMap (List->VariablePack, &MapName, &MapGuid, &MapId, &Map, &MapSize);\r
+ if ((0 == StrCmp (Name, MapName)) && CompareGuid (Guid, MapGuid)) {\r
+ *Id = MapId;\r
+ *Var = Map;\r
+ *Size = MapSize;\r
+ return EFI_SUCCESS;\r
+ }\r
+ List = List->NextVariablePack;\r
+ }\r
+ //\r
+ // If here, the map is not found\r
+ //\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariableRetrieveFromNv (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN UINTN Size,\r
+ OUT VOID **Var\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Finds out if a variable of specific Name/Guid/Size exists in NV. \r
+ If it does, it will retrieve it into the Var. \r
+\r
+Arguments:\r
+ Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
+ Var - Variable will be retrieved into buffer pointed by this pointer.\r
+ If pointing to NULL, the buffer will be allocated. Caller is responsible for releasing the buffer.\r
+Returns:\r
+ EFI_SUCCESS - The variable of exact Name/Guid/Size parameters was retrieved and written to Var.\r
+ EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
+ EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN SizeNv;\r
+\r
+ //\r
+ // Test for existence of the variable.\r
+ //\r
+ SizeNv = 0;\r
+ Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, NULL);\r
+ if (EFI_BUFFER_TOO_SMALL != Status) {\r
+ ASSERT (EFI_SUCCESS != Status);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ if (SizeNv != Size) {\r
+ //\r
+ // The variable is considered corrupt, as it has different size from expected.\r
+ //\r
+ return EFI_LOAD_ERROR; \r
+ }\r
+\r
+ if (NULL == *Var) {\r
+ *Var = AllocatePool (Size);\r
+ ASSERT (NULL != *Var);\r
+ }\r
+ SizeNv = Size;\r
+ //\r
+ // Final read into the Var\r
+ //\r
+ Status = gRT->GetVariable (Name, Guid, NULL, &SizeNv, *Var); \r
+ //\r
+ // No tolerance for random failures. Such behavior is undetermined and not validated.\r
+ //\r
+ ASSERT_EFI_ERROR (Status); \r
+ ASSERT (SizeNv == Size);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariableOverrideIfSuffix (\r
+ IN CHAR16 *Suffix,\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN UINTN Size,\r
+ OUT VOID *Var\r
+ ) \r
+/*++\r
+\r
+Routine Description:\r
+ Overrrides the variable with NV data if found.\r
+ But it only does it if the Name ends with specified Suffix.\r
+ For example, if Suffix="MyOverride" and the Name="XyzSetupMyOverride",\r
+ the Suffix matches the end of Name, so the variable will be loaded from NV\r
+ provided the variable exists and the GUID and Size matches.\r
+\r
+Arguments:\r
+ Suffix - Suffix the Name should end with.\r
+ Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
+ Var - Variable will be retrieved into this buffer.\r
+ Caller is responsible for providing storage of exactly Size size in bytes.\r
+Returns:\r
+ EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.\r
+ EFI_INVALID_PARAMETER - The name of the variable does not end with <Suffix>.\r
+ EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
+ EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
+\r
+--*/\r
+{\r
+ UINTN StrLength;\r
+ UINTN StrLenSuffix;\r
+\r
+ StrLength = StrLen (Name);\r
+ StrLenSuffix = StrLen (Suffix);\r
+ if ((StrLength <= StrLenSuffix) || (0 != StrCmp (Suffix, &Name[StrLength - StrLenSuffix]))) {\r
+ //\r
+ // Not ending with <Suffix>.\r
+ //\r
+ return EFI_INVALID_PARAMETER; \r
+ }\r
+ return EfiLibHiiVariableRetrieveFromNv (Name, Guid, Size, &Var);\r
+}\r
+\r
+EFI_STATUS\r
+EfiLibHiiVariableOverrideBySuffix (\r
+ IN CHAR16 *Suffix,\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN UINTN Size,\r
+ OUT VOID *Var\r
+ ) \r
+/*++\r
+\r
+Routine Description:\r
+ Overrrides the variable with NV data if found.\r
+ But it only does it if the NV contains the same variable with Name is appended with Suffix. \r
+ For example, if Suffix="MyOverride" and the Name="XyzSetup",\r
+ the Suffix will be appended to the end of Name, and the variable with Name="XyzSetupMyOverride"\r
+ will be loaded from NV provided the variable exists and the GUID and Size matches.\r
+\r
+Arguments:\r
+ Suffix - Suffix the variable will be appended with.\r
+ Name, Guid, Size - Parameters of the variable to retrieve. Must match exactly.\r
+ Var - Variable will be retrieved into this buffer.\r
+ Caller is responsible for providing storage of exactly Size size in bytes.\r
+\r
+Returns:\r
+ EFI_SUCCESS - The variable was overriden with NV variable of same Name/Guid/Size.\r
+ EFI_NOT_FOUND - The variable of this Name/Guid was not found in the NV.\r
+ EFI_LOAD_ERROR - The variable in the NV was of different size, or NV API returned error.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR16 *NameSuffixed;\r
+ UINTN NameLength;\r
+ UINTN SuffixLength;\r
+\r
+ //\r
+ // enough to concatenate both strings.\r
+ //\r
+ NameLength = StrLen (Name);\r
+ SuffixLength = StrLen (Suffix);\r
+ NameSuffixed = AllocateZeroPool ((NameLength + SuffixLength + 1) * sizeof (CHAR16)); \r
+ \r
+ StrCpy (NameSuffixed, Name);\r
+ StrCat (NameSuffixed, Suffix);\r
+ \r
+ Status = EfiLibHiiVariableRetrieveFromNv (NameSuffixed, Guid, Size, &Var);\r
+ gBS->FreePool (NameSuffixed);\r
+ \r
+ return Status;\r
+}\r
+\r