]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update to use DOS format
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 31 Oct 2008 03:38:21 +0000 (03:38 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 31 Oct 2008 03:38:21 +0000 (03:38 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6317 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c
MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h
MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c

index f41fc25d520265a0db4e1b86f08c5cd77074b3e9..5613a50d3e46ac058f3a9b71455645abf4c42cb3 100644 (file)
-/** @file
-Utility functions which helps in opcode creation, HII configuration string manipulations, 
-pop up window creations, setup browser persistence data set and get.
-
-Copyright (c) 2007- 2008, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "UefiIfrLibraryInternal.h"
-
-CONST EFI_FORM_BROWSER2_PROTOCOL      *mFormBrowser2     = NULL;
-CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mIfrSupportLibHiiConfigRouting = NULL;
-
-/**
-  This function locate FormBrowser2 protocols for later usage.
-
-  @return Status the status to locate protocol.
-**/
-EFI_STATUS
-LocateFormBrowser2Protocols (
-  VOID
-  )
-{
-  EFI_STATUS Status;
-  //
-  // Locate protocols for later usage
-  //
-  if (mFormBrowser2 == NULL) {
-    Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-  
-  if (mIfrSupportLibHiiConfigRouting == NULL) {
-    Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mIfrSupportLibHiiConfigRouting);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-//
-// Fake <ConfigHdr>
-//
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
-
-/**
-  Draw a dialog and return the selected key.
-
-  @param  NumberOfLines          The number of lines for the dialog box
-  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..
-  @param  Marker                 A series of (quantity == NumberOfLines - 1) text
-                                 strings which will be used to construct the dialog
-                                 box
-
-  @retval EFI_SUCCESS            Displayed dialog and received user interaction
-  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.
-  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
-
-**/
-EFI_STATUS
-EFIAPI
-IfrLibCreatePopUp2 (
-  IN  UINTN                       NumberOfLines,
-  OUT EFI_INPUT_KEY               *KeyValue,
-  IN  VA_LIST                     Marker
-  )
-{
-  UINTN                         Index;
-  UINTN                         Count;
-  UINTN                         Start;
-  UINTN                         Top;
-  CHAR16                        *StringPtr;
-  UINTN                         LeftColumn;
-  UINTN                         RightColumn;
-  UINTN                         TopRow;
-  UINTN                         BottomRow;
-  UINTN                         DimensionsWidth;
-  UINTN                         DimensionsHeight;
-  EFI_INPUT_KEY                 Key;
-  UINTN                         LargestString;
-  CHAR16                        *StackString;
-  EFI_STATUS                    Status;
-  UINTN                         StringLen;
-  CHAR16                        *LineBuffer;
-  CHAR16                        **StringArray;
-  EFI_EVENT                     TimerEvent;
-  EFI_EVENT                     WaitList[2];
-  UINTN                         CurrentAttribute;
-  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
-  CHAR16                        *String;
-
-  String = VA_ARG (Marker, CHAR16 *);
-  
-  if ((KeyValue == NULL) || (String == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  TopRow      = 0;
-  BottomRow   = 0;
-  LeftColumn  = 0;
-  RightColumn = 0;
-
-  ConOut = gST->ConOut;
-  ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &RightColumn, &BottomRow);
-
-  DimensionsWidth  = RightColumn - LeftColumn;
-  DimensionsHeight = BottomRow - TopRow;
-
-  CurrentAttribute = ConOut->Mode->Attribute;
-
-  LineBuffer = AllocateZeroPool (DimensionsWidth * sizeof (CHAR16));
-  if (LineBuffer == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Determine the largest string in the dialog box
-  // Notice we are starting with 1 since String is the first string
-  //
-  StringArray = AllocateZeroPool (NumberOfLines * sizeof (CHAR16 *));
-  if (StringArray == NULL) {
-    FreePool (LineBuffer);
-    return EFI_OUT_OF_RESOURCES;
-  }
-  LargestString = StrLen (String);
-  StringArray[0] = String;
-
-  for (Index = 1; Index < NumberOfLines; Index++) {
-    StackString = VA_ARG (Marker, CHAR16 *);
-
-    if (StackString == NULL) {
-      FreePool (LineBuffer);
-      FreePool (StringArray);
-      return EFI_INVALID_PARAMETER;
-    }
-
-    StringArray[Index] = StackString;
-    StringLen = StrLen (StackString);
-    if (StringLen > LargestString) {
-      LargestString = StringLen;
-    }
-  }
-
-  if ((LargestString + 2) > DimensionsWidth) {
-    LargestString = DimensionsWidth - 2;
-  }
-
-  //
-  // Subtract the PopUp width from total Columns, allow for one space extra on
-  // each end plus a border.
-  //
-  Start     = (DimensionsWidth - LargestString - 2) / 2 + LeftColumn + 1;
-
-  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + TopRow - 1;
-
-  //
-  // Disable cursor
-  //
-  ConOut->EnableCursor (ConOut, FALSE);
-  ConOut->SetAttribute (ConOut, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
-
-  StringPtr = &LineBuffer[0];
-  *StringPtr++ = BOXDRAW_DOWN_RIGHT;
-  for (Index = 0; Index < LargestString; Index++) {
-    *StringPtr++ = BOXDRAW_HORIZONTAL;
-  }
-  *StringPtr++ = BOXDRAW_DOWN_LEFT;
-  *StringPtr = L'\0';
-
-  ConOut->SetCursorPosition (ConOut, Start, Top);
-  ConOut->OutputString (ConOut, LineBuffer);
-
-  for (Index = 0; Index < NumberOfLines; Index++) {
-    StringPtr = &LineBuffer[0];
-    *StringPtr++ = BOXDRAW_VERTICAL;
-
-    for (Count = 0; Count < LargestString; Count++) {
-      StringPtr[Count] = L' ';
-    }
-
-    StringLen = StrLen (StringArray[Index]);
-    if (StringLen > LargestString) {
-      StringLen = LargestString;
-    }
-    CopyMem (
-      StringPtr + ((LargestString - StringLen) / 2),
-      StringArray[Index],
-      StringLen * sizeof (CHAR16)
-      );
-    StringPtr += LargestString;
-
-    *StringPtr++ = BOXDRAW_VERTICAL;
-    *StringPtr = L'\0';
-
-    ConOut->SetCursorPosition (ConOut, Start, Top + 1 + Index);
-    ConOut->OutputString (ConOut, LineBuffer);
-  }
-
-  StringPtr = &LineBuffer[0];
-  *StringPtr++ = BOXDRAW_UP_RIGHT;
-  for (Index = 0; Index < LargestString; Index++) {
-    *StringPtr++ = BOXDRAW_HORIZONTAL;
-  }
-  *StringPtr++ = BOXDRAW_UP_LEFT;
-  *StringPtr = L'\0';
-
-  ConOut->SetCursorPosition (ConOut, Start, Top + NumberOfLines + 1);
-  ConOut->OutputString (ConOut, LineBuffer);
-
-  do {
-    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
-
-    //
-    // Set a timer event of 1 second expiration
-    //
-    gBS->SetTimer (
-          TimerEvent,
-          TimerRelative,
-          10000000
-          );
-
-    //
-    // Wait for the keystroke event or the timer
-    //
-    WaitList[0] = gST->ConIn->WaitForKey;
-    WaitList[1] = TimerEvent;
-    Status      = gBS->WaitForEvent (2, WaitList, &Index);
-
-    //
-    // Check for the timer expiration
-    //
-    if (!EFI_ERROR (Status) && Index == 1) {
-      Status = EFI_TIMEOUT;
-    }
-
-    gBS->CloseEvent (TimerEvent);
-  } while (Status == EFI_TIMEOUT);
-
-  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-  CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));
-
-  ConOut->SetAttribute (ConOut, CurrentAttribute);
-  ConOut->EnableCursor (ConOut, TRUE);
-
-  FreePool (LineBuffer);
-  FreePool (StringArray);
-
-  return Status;
-}
-
-
-/**
-  Draw a dialog and return the selected key.
-
-  @param  NumberOfLines          The number of lines for the dialog box
-  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..
-  @param  String                 Pointer to the first string in the list
-  @param  ...                    A series of (quantity == NumberOfLines - 1) text
-                                 strings which will be used to construct the dialog
-                                 box
-
-  @retval EFI_SUCCESS            Displayed dialog and received user interaction
-  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.
-
-**/
-EFI_STATUS
-EFIAPI
-IfrLibCreatePopUp (
-  IN  UINTN                       NumberOfLines,
-  OUT EFI_INPUT_KEY               *KeyValue,
-  IN  CHAR16                      *String,
-  ...
-  )
-{
-  EFI_STATUS                      Status;
-  VA_LIST                         Marker;
-
-  VA_START (Marker, KeyValue);
-
-  Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, Marker);
-
-  VA_END (Marker);
-
-  return Status;
-}
-
-/**
-  Swap bytes in the buffer. This is a internal function.
-
-  @param  Buffer                 Binary buffer.
-  @param  BufferSize             Size of the buffer in bytes.
-
-  @return None.
-
-**/
-VOID
-SwapBuffer (
-  IN OUT UINT8     *Buffer,
-  IN UINTN         BufferSize
-  )
-{
-  UINTN  Index;
-  UINT8  Temp;
-  UINTN  SwapCount;
-
-  SwapCount = BufferSize / 2;
-  for (Index = 0; Index < SwapCount; Index++) {
-    Temp = Buffer[Index];
-    Buffer[Index] = Buffer[BufferSize - 1 - Index];
-    Buffer[BufferSize - 1 - Index] = Temp;
-  }
-}
-
-/**
-  Converts the unicode character of the string from uppercase to lowercase.
-  This is a internal function.
-
-  @param Str     String to be converted
-
-**/
-VOID
-EFIAPI
-ToLower (
-  IN OUT CHAR16    *Str
-  )
-{
-  CHAR16      *Ptr;
-  
-  for (Ptr = Str; *Ptr != L'\0'; Ptr++) {
-    if (*Ptr >= L'A' && *Ptr <= L'Z') {
-      *Ptr = (CHAR16) (*Ptr - L'A' + L'a');
-    }
-  }
-}
-
-
-/**
-  Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
-
-  @param  Str                    String for output
-  @param  Buffer                 Binary buffer.
-  @param  BufferSize             Size of the buffer in bytes.
-
-  @retval EFI_SUCCESS            The function completed successfully.
-  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
-
-**/
-EFI_STATUS
-EFIAPI
-BufInReverseOrderToHexString (
-  IN OUT CHAR16    *Str,
-  IN UINT8         *Buffer,
-  IN UINTN         BufferSize
-  )
-{
-  EFI_STATUS  Status;
-  UINT8       *NewBuffer;
-  UINTN       StrBufferLen;
-
-  NewBuffer = AllocateCopyPool (BufferSize, Buffer);
-  if (NewBuffer == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  SwapBuffer (NewBuffer, BufferSize);
-
-  StrBufferLen = BufferSize * sizeof (CHAR16) + 1;
-  Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
-
-  FreePool (NewBuffer);
-  //
-  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
-  //
-  ToLower (Str);
-
-  return Status;
-}
-
-
-/**
-  Converts Hex String to binary buffer in reversed byte order from HexStringToBuf().
-
-  @param  Buffer                 Pointer to buffer that receives the data.
-  @param  BufferSize             Length in bytes of the buffer to hold converted
-                                 data. If routine return with EFI_SUCCESS,
-                                 containing length of converted data. If routine
-                                 return with EFI_BUFFER_TOO_SMALL, containg length
-                                 of buffer desired.
-  @param  Str                    String to be converted from.
-
-  @retval EFI_SUCCESS            The function completed successfully.
-  @retval RETURN_BUFFER_TOO_SMALL   The input BufferSize is too small to hold the output. BufferSize
-                                 will be updated to the size required for the converstion.
-
-**/
-EFI_STATUS
-EFIAPI
-HexStringToBufInReverseOrder (
-  IN OUT UINT8         *Buffer,
-  IN OUT UINTN         *BufferSize,
-  IN CHAR16            *Str
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       ConvertedStrLen;
-
-  ConvertedStrLen = 0;
-  Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);
-  if (!EFI_ERROR (Status)) {
-    SwapBuffer (Buffer, ConvertedStrLen);
-  }
-
-  return Status;
-}
-
-/**
-  Convert binary representation Config string (e.g. "0041004200430044") to the
-  original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
-  "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
-
-  @param UnicodeString  Original Unicode string.
-  @param StrBufferLen   On input: Length in bytes of buffer to hold the Unicode string.
-                                    Includes tailing '\0' character.
-                                    On output:
-                                      If return EFI_SUCCESS, containing length of Unicode string buffer.
-                                      If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
-  @param ConfigString   Binary representation of Unicode String, <string> := (<HexCh>4)+
-
-  @retval EFI_SUCCESS          Operation completes successfully.
-  @retval EFI_BUFFER_TOO_SMALL The string buffer is too small.
-
-**/
-EFI_STATUS
-EFIAPI
-ConfigStringToUnicode (
-  IN OUT CHAR16                *UnicodeString,
-  IN OUT UINTN                 *StrBufferLen,
-  IN CHAR16                    *ConfigString
-  )
-{
-  UINTN       Index;
-  UINTN       Len;
-  UINTN       BufferSize;
-  CHAR16      BackupChar;
-
-  Len = StrLen (ConfigString) / 4;
-  BufferSize = (Len + 1) * sizeof (CHAR16);
-
-  if (*StrBufferLen < BufferSize) {
-    *StrBufferLen = BufferSize;
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  *StrBufferLen = BufferSize;
-
-  for (Index = 0; Index < Len; Index++) {
-    BackupChar = ConfigString[4];
-    ConfigString[4] = L'\0';
-
-    HexStringToBuf ((UINT8 *) UnicodeString, &BufferSize, ConfigString, NULL);
-
-    ConfigString[4] = BackupChar;
-
-    ConfigString += 4;
-    UnicodeString += 1;
-  }
-
-  //
-  // Add tailing '\0' character
-  //
-  *UnicodeString = L'\0';
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Convert Unicode string to binary representation Config string, e.g.
-  "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
-  "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
-
-  @param ConfigString   Binary representation of Unicode String, <string> := (<HexCh>4)+
-  @param  StrBufferLen  On input: Length in bytes of buffer to hold the Unicode string.
-                                    Includes tailing '\0' character.
-                                    On output:
-                                      If return EFI_SUCCESS, containing length of Unicode string buffer.
-                                      If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
-  @param  UnicodeString  Original Unicode string.
-
-  @retval EFI_SUCCESS           Operation completes successfully.
-  @retval EFI_BUFFER_TOO_SMALL  The string buffer is too small.
-
-**/
-EFI_STATUS
-EFIAPI
-UnicodeToConfigString (
-  IN OUT CHAR16                *ConfigString,
-  IN OUT UINTN                 *StrBufferLen,
-  IN CHAR16                    *UnicodeString
-  )
-{
-  UINTN       Index;
-  UINTN       Len;
-  UINTN       BufferSize;
-  CHAR16      *String;
-
-  Len = StrLen (UnicodeString);
-  BufferSize = (Len * 4 + 1) * sizeof (CHAR16);
-
-  if (*StrBufferLen < BufferSize) {
-    *StrBufferLen = BufferSize;
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  *StrBufferLen = BufferSize;
-  String        = ConfigString;
-
-  for (Index = 0; Index < Len; Index++) {
-    BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);
-
-    ConfigString += 4;
-    UnicodeString += 1;
-  }
-
-  //
-  // Add tailing '\0' character
-  //
-  *ConfigString = L'\0';
-
-  //
-  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
-  //
-  ToLower (String);  
-  return EFI_SUCCESS;
-}
-
-/**
-  Construct <ConfigHdr> using routing information GUID/NAME/PATH.
-
-  @param  ConfigHdr              Pointer to the ConfigHdr string.
-  @param  StrBufferLen           On input: Length in bytes of buffer to hold the
-                                 ConfigHdr string. Includes tailing '\0' character.
-                                 On output: If return EFI_SUCCESS, containing
-                                 length of ConfigHdr string buffer. If return
-                                 EFI_BUFFER_TOO_SMALL, containg length of string
-                                 buffer desired.
-  @param  Guid                   Routing information: GUID.
-  @param  Name                   Routing information: NAME.
-  @param  DriverHandle           Driver handle which contains the routing
-                                 information: PATH.
-
-  @retval EFI_SUCCESS            Operation completes successfully.
-  @retval EFI_BUFFER_TOO_SMALL   The ConfigHdr string buffer is too small.
-
-**/
-EFI_STATUS
-EFIAPI
-ConstructConfigHdr (
-  IN OUT CHAR16                *ConfigHdr,
-  IN OUT UINTN                 *StrBufferLen,
-  IN CONST EFI_GUID            *Guid,
-  IN CHAR16                    *Name, OPTIONAL
-  IN EFI_HANDLE                *DriverHandle
-  )
-{
-  EFI_STATUS                Status;
-  UINTN                     NameStrLen;
-  UINTN                     DevicePathSize;
-  UINTN                     BufferSize;
-  CHAR16                    *StrPtr;
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
-
-  if (Name == NULL) {
-    //
-    // There will be no "NAME" in <ConfigHdr> for  Name/Value storage
-    //
-    NameStrLen = 0;
-  } else {
-    //
-    // For buffer storage
-    //
-    NameStrLen = StrLen (Name);
-  }
-
-  //
-  // Retrieve DevicePath Protocol associated with this HiiPackageList
-  //
-  Status = gBS->HandleProtocol (
-                  DriverHandle,
-                  &gEfiDevicePathProtocolGuid,
-                  (VOID **) &DevicePath
-                  );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  DevicePathSize = GetDevicePathSize (DevicePath);
-
-  //
-  // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
-  // | 5  |   32   |  6  |  NameStrLen*4 |  6  |    DevicePathStrLen    | 1 |
-  //
-  BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16);
-  if (*StrBufferLen < BufferSize) {
-    *StrBufferLen = BufferSize;
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  *StrBufferLen = BufferSize;
-
-  StrPtr = ConfigHdr;
-
-  StrCpy (StrPtr, L"GUID=");
-  StrPtr += 5;
-  BufInReverseOrderToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
-  StrPtr += 32;
-
-  //
-  // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
-  //
-  StrCpy (StrPtr, L"&NAME=");
-  StrPtr += 6;
-  if (Name != NULL) {
-    BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);
-    UnicodeToConfigString (StrPtr, &BufferSize, Name);
-    StrPtr += (NameStrLen * 4);
-  }
-
-  StrCpy (StrPtr, L"&PATH=");
-  StrPtr += 6;
-  BufInReverseOrderToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
-
-  @param  String                 The string to be searched in.
-  @param  Offset                 Offset in BlockName.
-  @param  Width                  Width in BlockName.
-
-  @retval TRUE                   Block name found.
-  @retval FALSE                  Block name not found.
-
-**/
-BOOLEAN
-EFIAPI
-FindBlockName (
-  IN OUT CHAR16                *String,
-  IN UINTN                     Offset,
-  IN UINTN                     Width
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       Data;
-  UINTN       BufferSize;
-  UINTN       ConvertedStrLen;
-
-  while ((String = StrStr (String, L"&OFFSET=")) != NULL) {
-    //
-    // Skip '&OFFSET='
-    //
-    String = String + 8;
-
-    Data = 0;
-    BufferSize = sizeof (UINTN);
-    Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);
-    if (EFI_ERROR (Status)) {
-      return FALSE;
-    }
-    String = String + ConvertedStrLen;
-
-    if (Data != Offset) {
-      continue;
-    }
-
-    if (StrnCmp (String, L"&WIDTH=", 7) != 0) {
-      return FALSE;
-    }
-    String = String + 7;
-
-    Data = 0;
-    BufferSize = sizeof (UINTN);
-    Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);
-    if (EFI_ERROR (Status)) {
-      return FALSE;
-    }
-    if (Data == Width) {
-      return TRUE;
-    }
-
-    String = String + ConvertedStrLen;
-  }
-
-  return FALSE;
-}
-
-
-/**
-  This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
-
-  @param  VariableGuid           An optional field to indicate the target variable
-                                 GUID name to use.
-  @param  VariableName           An optional field to indicate the target
-                                 human-readable variable name.
-  @param  BufferSize             On input: Length in bytes of buffer to hold
-                                 retrived data. On output: If return
-                                 EFI_BUFFER_TOO_SMALL, containg length of buffer
-                                 desired.
-  @param  Buffer                 Buffer to hold retrived data.
-
-  @retval EFI_SUCCESS            Operation completes successfully.
-  @retval EFI_BUFFER_TOO_SMALL   The intput buffer is too small.
-  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
-
-**/
-EFI_STATUS
-EFIAPI
-GetBrowserData (
-  IN CONST EFI_GUID              *VariableGuid, OPTIONAL
-  IN CONST CHAR16                *VariableName, OPTIONAL
-  IN OUT UINTN                   *BufferSize,
-  IN OUT UINT8                   *Buffer
-  )
-{
-  EFI_STATUS                      Status;
-  CONST CHAR16                    *ConfigHdr;
-  CHAR16                          *ConfigResp;
-  CHAR16                          *StringPtr;
-  UINTN                           HeaderLen;
-  UINTN                           BufferLen;
-  CHAR16                          *Progress;
-
-  //
-  // Locate protocols for use
-  //
-  Status = LocateFormBrowser2Protocols ();
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Retrive formset storage data from Form Browser
-  //
-  ConfigHdr = mFakeConfigHdr;
-  HeaderLen = StrLen (ConfigHdr);
-  
-  //
-  // First try allocate 0x4000 buffer for the formet storage data.
-  //
-  BufferLen = 0x4000;
-  ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
-  if (ConfigResp == NULL) {
-    BufferLen = 0;
-  }
-
-  StringPtr = ConfigResp + HeaderLen;
-  *StringPtr = L'&';
-  StringPtr++;
-
-  Status = mFormBrowser2->BrowserCallback (
-                           mFormBrowser2,
-                           &BufferLen,
-                           StringPtr,
-                           TRUE,
-                           VariableGuid,
-                           VariableName
-                           );
-  if (Status == EFI_BUFFER_TOO_SMALL) {
-    if (ConfigResp != NULL) {
-      FreePool (ConfigResp);
-    }
-
-    ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
-    if (ConfigResp == NULL) {
-      return EFI_OUT_OF_RESOURCES;
-    }
-
-    StringPtr = ConfigResp + HeaderLen;
-    *StringPtr = L'&';
-    StringPtr++;
-
-    Status = mFormBrowser2->BrowserCallback (
-                             mFormBrowser2,
-                             &BufferLen,
-                             StringPtr,
-                             TRUE,
-                             VariableGuid,
-                             VariableName
-                             );
-  }
-  if (EFI_ERROR (Status)) {
-    FreePool (ConfigResp);
-    return Status;
-  }
-  CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16));
-
-  //
-  // Convert <ConfigResp> to buffer data
-  //
-  Status = mIfrSupportLibHiiConfigRouting->ConfigToBlock (
-                               mIfrSupportLibHiiConfigRouting,
-                               ConfigResp,
-                               Buffer,
-                               BufferSize,
-                               &Progress
-                               );
-  FreePool (ConfigResp);
-
-  return Status;
-}
-
-
-/**
-  This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
-
-  @param  VariableGuid           An optional field to indicate the target variable
-                                 GUID name to use.
-  @param  VariableName           An optional field to indicate the target
-                                 human-readable variable name.
-  @param  BufferSize             Length in bytes of buffer to hold retrived data.
-  @param  Buffer                 Buffer to hold retrived data.
-  @param  RequestElement         An optional field to specify which part of the
-                                 buffer data will be send back to Browser. If NULL,
-                                 the whole buffer of data will be committed to
-                                 Browser. <RequestElement> ::=
-                                 &OFFSET=<Number>&WIDTH=<Number>*
-
-  @retval EFI_SUCCESS            Operation completes successfully.
-  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
-  @retval Other                  Updating Browser uncommitted data failed.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBrowserData (
-  IN CONST EFI_GUID          *VariableGuid, OPTIONAL
-  IN CONST CHAR16            *VariableName, OPTIONAL
-  IN UINTN                   BufferSize,
-  IN CONST UINT8             *Buffer,
-  IN CONST CHAR16            *RequestElement  OPTIONAL
-  )
-{
-  EFI_STATUS                      Status;
-  CONST CHAR16                    *ConfigHdr;
-  CHAR16                          *ConfigResp;
-  CHAR16                          *StringPtr;
-  UINTN                           HeaderLen;
-  UINTN                           BufferLen;
-  CHAR16                          *Progress;
-  CHAR16                          BlockName[33];
-  CHAR16                          *ConfigRequest;
-  CONST CHAR16                    *Request;
-
-  //
-  // Locate protocols for use
-  //
-  Status = LocateFormBrowser2Protocols ();
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Prepare <ConfigRequest>
-  //
-  ConfigHdr = mFakeConfigHdr;
-  HeaderLen = StrLen (ConfigHdr);
-
-  if (RequestElement == NULL) {
-    //
-    // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>
-    //
-    BlockName[0] = L'\0';
-    StrCpy (BlockName, L"&OFFSET=0&WIDTH=");
-
-    //
-    // String lenghth of L"&OFFSET=0&WIDTH=" is 16
-    //
-    StringPtr = BlockName + 16;
-    BufferLen = sizeof (BlockName) - (16 * sizeof (CHAR16));
-    BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN));
-
-    Request = BlockName;
-  } else {
-    Request = RequestElement;
-  }
-
-  BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request);
-  ConfigRequest = AllocateZeroPool (BufferLen);
-  if (ConfigRequest == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16));
-  StringPtr = ConfigRequest + HeaderLen;
-  StrCpy (StringPtr, Request);
-
-  //
-  // Convert buffer to <ConfigResp>
-  //
-  Status = mIfrSupportLibHiiConfigRouting->BlockToConfig (
-                                mIfrSupportLibHiiConfigRouting,
-                                ConfigRequest,
-                                Buffer,
-                                BufferSize,
-                                &ConfigResp,
-                                &Progress
-                                );
-  if (EFI_ERROR (Status)) {
-    FreePool (ConfigRequest);
-    return Status;
-  }
-
-  //
-  // Skip <ConfigHdr> and '&'
-  //
-  StringPtr = ConfigResp + HeaderLen + 1;
-
-  //
-  // Change uncommitted data in Browser
-  //
-  Status = mFormBrowser2->BrowserCallback (
-                           mFormBrowser2,
-                           &BufferSize,
-                           StringPtr,
-                           FALSE,
-                           NULL,
-                           NULL
-                           );
-  FreePool (ConfigRequest);
-  return Status;
-}
+/** @file\r
+Utility functions which helps in opcode creation, HII configuration string manipulations, \r
+pop up window creations, setup browser persistence data set and get.\r
+\r
+Copyright (c) 2007- 2008, 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
+**/\r
+\r
+#include "UefiIfrLibraryInternal.h"\r
+\r
+CONST EFI_FORM_BROWSER2_PROTOCOL      *mFormBrowser2     = NULL;\r
+CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mIfrSupportLibHiiConfigRouting = NULL;\r
+\r
+/**\r
+  This function locate FormBrowser2 protocols for later usage.\r
+\r
+  @return Status the status to locate protocol.\r
+**/\r
+EFI_STATUS\r
+LocateFormBrowser2Protocols (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  //\r
+  // Locate protocols for later usage\r
+  //\r
+  if (mFormBrowser2 == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+  \r
+  if (mIfrSupportLibHiiConfigRouting == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mIfrSupportLibHiiConfigRouting);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// Fake <ConfigHdr>\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";\r
+\r
+/**\r
+  Draw a dialog and return the selected key.\r
+\r
+  @param  NumberOfLines          The number of lines for the dialog box\r
+  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..\r
+  @param  Marker                 A series of (quantity == NumberOfLines - 1) text\r
+                                 strings which will be used to construct the dialog\r
+                                 box\r
+\r
+  @retval EFI_SUCCESS            Displayed dialog and received user interaction\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IfrLibCreatePopUp2 (\r
+  IN  UINTN                       NumberOfLines,\r
+  OUT EFI_INPUT_KEY               *KeyValue,\r
+  IN  VA_LIST                     Marker\r
+  )\r
+{\r
+  UINTN                         Index;\r
+  UINTN                         Count;\r
+  UINTN                         Start;\r
+  UINTN                         Top;\r
+  CHAR16                        *StringPtr;\r
+  UINTN                         LeftColumn;\r
+  UINTN                         RightColumn;\r
+  UINTN                         TopRow;\r
+  UINTN                         BottomRow;\r
+  UINTN                         DimensionsWidth;\r
+  UINTN                         DimensionsHeight;\r
+  EFI_INPUT_KEY                 Key;\r
+  UINTN                         LargestString;\r
+  CHAR16                        *StackString;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         StringLen;\r
+  CHAR16                        *LineBuffer;\r
+  CHAR16                        **StringArray;\r
+  EFI_EVENT                     TimerEvent;\r
+  EFI_EVENT                     WaitList[2];\r
+  UINTN                         CurrentAttribute;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;\r
+  CHAR16                        *String;\r
+\r
+  String = VA_ARG (Marker, CHAR16 *);\r
+  \r
+  if ((KeyValue == NULL) || (String == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  TopRow      = 0;\r
+  BottomRow   = 0;\r
+  LeftColumn  = 0;\r
+  RightColumn = 0;\r
+\r
+  ConOut = gST->ConOut;\r
+  ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &RightColumn, &BottomRow);\r
+\r
+  DimensionsWidth  = RightColumn - LeftColumn;\r
+  DimensionsHeight = BottomRow - TopRow;\r
+\r
+  CurrentAttribute = ConOut->Mode->Attribute;\r
+\r
+  LineBuffer = AllocateZeroPool (DimensionsWidth * sizeof (CHAR16));\r
+  if (LineBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Determine the largest string in the dialog box\r
+  // Notice we are starting with 1 since String is the first string\r
+  //\r
+  StringArray = AllocateZeroPool (NumberOfLines * sizeof (CHAR16 *));\r
+  if (StringArray == NULL) {\r
+    FreePool (LineBuffer);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  LargestString = StrLen (String);\r
+  StringArray[0] = String;\r
+\r
+  for (Index = 1; Index < NumberOfLines; Index++) {\r
+    StackString = VA_ARG (Marker, CHAR16 *);\r
+\r
+    if (StackString == NULL) {\r
+      FreePool (LineBuffer);\r
+      FreePool (StringArray);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    StringArray[Index] = StackString;\r
+    StringLen = StrLen (StackString);\r
+    if (StringLen > LargestString) {\r
+      LargestString = StringLen;\r
+    }\r
+  }\r
+\r
+  if ((LargestString + 2) > DimensionsWidth) {\r
+    LargestString = DimensionsWidth - 2;\r
+  }\r
+\r
+  //\r
+  // Subtract the PopUp width from total Columns, allow for one space extra on\r
+  // each end plus a border.\r
+  //\r
+  Start     = (DimensionsWidth - LargestString - 2) / 2 + LeftColumn + 1;\r
+\r
+  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + TopRow - 1;\r
+\r
+  //\r
+  // Disable cursor\r
+  //\r
+  ConOut->EnableCursor (ConOut, FALSE);\r
+  ConOut->SetAttribute (ConOut, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);\r
+\r
+  StringPtr = &LineBuffer[0];\r
+  *StringPtr++ = BOXDRAW_DOWN_RIGHT;\r
+  for (Index = 0; Index < LargestString; Index++) {\r
+    *StringPtr++ = BOXDRAW_HORIZONTAL;\r
+  }\r
+  *StringPtr++ = BOXDRAW_DOWN_LEFT;\r
+  *StringPtr = L'\0';\r
+\r
+  ConOut->SetCursorPosition (ConOut, Start, Top);\r
+  ConOut->OutputString (ConOut, LineBuffer);\r
+\r
+  for (Index = 0; Index < NumberOfLines; Index++) {\r
+    StringPtr = &LineBuffer[0];\r
+    *StringPtr++ = BOXDRAW_VERTICAL;\r
+\r
+    for (Count = 0; Count < LargestString; Count++) {\r
+      StringPtr[Count] = L' ';\r
+    }\r
+\r
+    StringLen = StrLen (StringArray[Index]);\r
+    if (StringLen > LargestString) {\r
+      StringLen = LargestString;\r
+    }\r
+    CopyMem (\r
+      StringPtr + ((LargestString - StringLen) / 2),\r
+      StringArray[Index],\r
+      StringLen * sizeof (CHAR16)\r
+      );\r
+    StringPtr += LargestString;\r
+\r
+    *StringPtr++ = BOXDRAW_VERTICAL;\r
+    *StringPtr = L'\0';\r
+\r
+    ConOut->SetCursorPosition (ConOut, Start, Top + 1 + Index);\r
+    ConOut->OutputString (ConOut, LineBuffer);\r
+  }\r
+\r
+  StringPtr = &LineBuffer[0];\r
+  *StringPtr++ = BOXDRAW_UP_RIGHT;\r
+  for (Index = 0; Index < LargestString; Index++) {\r
+    *StringPtr++ = BOXDRAW_HORIZONTAL;\r
+  }\r
+  *StringPtr++ = BOXDRAW_UP_LEFT;\r
+  *StringPtr = L'\0';\r
+\r
+  ConOut->SetCursorPosition (ConOut, Start, Top + NumberOfLines + 1);\r
+  ConOut->OutputString (ConOut, LineBuffer);\r
+\r
+  do {\r
+    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
+\r
+    //\r
+    // Set a timer event of 1 second expiration\r
+    //\r
+    gBS->SetTimer (\r
+          TimerEvent,\r
+          TimerRelative,\r
+          10000000\r
+          );\r
+\r
+    //\r
+    // Wait for the keystroke event or the timer\r
+    //\r
+    WaitList[0] = gST->ConIn->WaitForKey;\r
+    WaitList[1] = TimerEvent;\r
+    Status      = gBS->WaitForEvent (2, WaitList, &Index);\r
+\r
+    //\r
+    // Check for the timer expiration\r
+    //\r
+    if (!EFI_ERROR (Status) && Index == 1) {\r
+      Status = EFI_TIMEOUT;\r
+    }\r
+\r
+    gBS->CloseEvent (TimerEvent);\r
+  } while (Status == EFI_TIMEOUT);\r
+\r
+  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+  CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));\r
+\r
+  ConOut->SetAttribute (ConOut, CurrentAttribute);\r
+  ConOut->EnableCursor (ConOut, TRUE);\r
+\r
+  FreePool (LineBuffer);\r
+  FreePool (StringArray);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Draw a dialog and return the selected key.\r
+\r
+  @param  NumberOfLines          The number of lines for the dialog box\r
+  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..\r
+  @param  String                 Pointer to the first string in the list\r
+  @param  ...                    A series of (quantity == NumberOfLines - 1) text\r
+                                 strings which will be used to construct the dialog\r
+                                 box\r
+\r
+  @retval EFI_SUCCESS            Displayed dialog and received user interaction\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IfrLibCreatePopUp (\r
+  IN  UINTN                       NumberOfLines,\r
+  OUT EFI_INPUT_KEY               *KeyValue,\r
+  IN  CHAR16                      *String,\r
+  ...\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  VA_LIST                         Marker;\r
+\r
+  VA_START (Marker, KeyValue);\r
+\r
+  Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, Marker);\r
+\r
+  VA_END (Marker);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Swap bytes in the buffer. This is a internal function.\r
+\r
+  @param  Buffer                 Binary buffer.\r
+  @param  BufferSize             Size of the buffer in bytes.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+SwapBuffer (\r
+  IN OUT UINT8     *Buffer,\r
+  IN UINTN         BufferSize\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UINT8  Temp;\r
+  UINTN  SwapCount;\r
+\r
+  SwapCount = BufferSize / 2;\r
+  for (Index = 0; Index < SwapCount; Index++) {\r
+    Temp = Buffer[Index];\r
+    Buffer[Index] = Buffer[BufferSize - 1 - Index];\r
+    Buffer[BufferSize - 1 - Index] = Temp;\r
+  }\r
+}\r
+\r
+/**\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
+\r
+  @param Str     String to be converted\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ToLower (\r
+  IN OUT CHAR16    *Str\r
+  )\r
+{\r
+  CHAR16      *Ptr;\r
+  \r
+  for (Ptr = Str; *Ptr != L'\0'; Ptr++) {\r
+    if (*Ptr >= L'A' && *Ptr <= L'Z') {\r
+      *Ptr = (CHAR16) (*Ptr - L'A' + L'a');\r
+    }\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Converts binary buffer to Unicode string in reversed byte order from BufToHexString().\r
+\r
+  @param  Str                    String for output\r
+  @param  Buffer                 Binary buffer.\r
+  @param  BufferSize             Size of the buffer in bytes.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BufInReverseOrderToHexString (\r
+  IN OUT CHAR16    *Str,\r
+  IN UINT8         *Buffer,\r
+  IN UINTN         BufferSize\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       *NewBuffer;\r
+  UINTN       StrBufferLen;\r
+\r
+  NewBuffer = AllocateCopyPool (BufferSize, Buffer);\r
+  if (NewBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  SwapBuffer (NewBuffer, BufferSize);\r
+\r
+  StrBufferLen = BufferSize * sizeof (CHAR16) + 1;\r
+  Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);\r
+\r
+  FreePool (NewBuffer);\r
+  //\r
+  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+  //\r
+  ToLower (Str);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Converts Hex String to binary buffer in reversed byte order from HexStringToBuf().\r
+\r
+  @param  Buffer                 Pointer to buffer that receives the data.\r
+  @param  BufferSize             Length in bytes of the buffer to hold converted\r
+                                 data. If routine return with EFI_SUCCESS,\r
+                                 containing length of converted data. If routine\r
+                                 return with EFI_BUFFER_TOO_SMALL, containg length\r
+                                 of buffer desired.\r
+  @param  Str                    String to be converted from.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The input BufferSize is too small to hold the output. BufferSize\r
+                                 will be updated to the size required for the converstion.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HexStringToBufInReverseOrder (\r
+  IN OUT UINT8         *Buffer,\r
+  IN OUT UINTN         *BufferSize,\r
+  IN CHAR16            *Str\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       ConvertedStrLen;\r
+\r
+  ConvertedStrLen = 0;\r
+  Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);\r
+  if (!EFI_ERROR (Status)) {\r
+    SwapBuffer (Buffer, ConvertedStrLen);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Convert binary representation Config string (e.g. "0041004200430044") to the\r
+  original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.\r
+  "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").\r
+\r
+  @param UnicodeString  Original Unicode string.\r
+  @param StrBufferLen   On input: Length in bytes of buffer to hold the Unicode string.\r
+                                    Includes tailing '\0' character.\r
+                                    On output:\r
+                                      If return EFI_SUCCESS, containing length of Unicode string buffer.\r
+                                      If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.\r
+  @param ConfigString   Binary representation of Unicode String, <string> := (<HexCh>4)+\r
+\r
+  @retval EFI_SUCCESS          Operation completes successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The string buffer is too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConfigStringToUnicode (\r
+  IN OUT CHAR16                *UnicodeString,\r
+  IN OUT UINTN                 *StrBufferLen,\r
+  IN CHAR16                    *ConfigString\r
+  )\r
+{\r
+  UINTN       Index;\r
+  UINTN       Len;\r
+  UINTN       BufferSize;\r
+  CHAR16      BackupChar;\r
+\r
+  Len = StrLen (ConfigString) / 4;\r
+  BufferSize = (Len + 1) * sizeof (CHAR16);\r
+\r
+  if (*StrBufferLen < BufferSize) {\r
+    *StrBufferLen = BufferSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *StrBufferLen = BufferSize;\r
+\r
+  for (Index = 0; Index < Len; Index++) {\r
+    BackupChar = ConfigString[4];\r
+    ConfigString[4] = L'\0';\r
+\r
+    HexStringToBuf ((UINT8 *) UnicodeString, &BufferSize, ConfigString, NULL);\r
+\r
+    ConfigString[4] = BackupChar;\r
+\r
+    ConfigString += 4;\r
+    UnicodeString += 1;\r
+  }\r
+\r
+  //\r
+  // Add tailing '\0' character\r
+  //\r
+  *UnicodeString = L'\0';\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert Unicode string to binary representation Config string, e.g.\r
+  "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.\r
+  "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").\r
+\r
+  @param ConfigString   Binary representation of Unicode String, <string> := (<HexCh>4)+\r
+  @param  StrBufferLen  On input: Length in bytes of buffer to hold the Unicode string.\r
+                                    Includes tailing '\0' character.\r
+                                    On output:\r
+                                      If return EFI_SUCCESS, containing length of Unicode string buffer.\r
+                                      If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.\r
+  @param  UnicodeString  Original Unicode string.\r
+\r
+  @retval EFI_SUCCESS           Operation completes successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL  The string buffer is too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnicodeToConfigString (\r
+  IN OUT CHAR16                *ConfigString,\r
+  IN OUT UINTN                 *StrBufferLen,\r
+  IN CHAR16                    *UnicodeString\r
+  )\r
+{\r
+  UINTN       Index;\r
+  UINTN       Len;\r
+  UINTN       BufferSize;\r
+  CHAR16      *String;\r
+\r
+  Len = StrLen (UnicodeString);\r
+  BufferSize = (Len * 4 + 1) * sizeof (CHAR16);\r
+\r
+  if (*StrBufferLen < BufferSize) {\r
+    *StrBufferLen = BufferSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *StrBufferLen = BufferSize;\r
+  String        = ConfigString;\r
+\r
+  for (Index = 0; Index < Len; Index++) {\r
+    BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);\r
+\r
+    ConfigString += 4;\r
+    UnicodeString += 1;\r
+  }\r
+\r
+  //\r
+  // Add tailing '\0' character\r
+  //\r
+  *ConfigString = L'\0';\r
+\r
+  //\r
+  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+  //\r
+  ToLower (String);  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Construct <ConfigHdr> using routing information GUID/NAME/PATH.\r
+\r
+  @param  ConfigHdr              Pointer to the ConfigHdr string.\r
+  @param  StrBufferLen           On input: Length in bytes of buffer to hold the\r
+                                 ConfigHdr string. Includes tailing '\0' character.\r
+                                 On output: If return EFI_SUCCESS, containing\r
+                                 length of ConfigHdr string buffer. If return\r
+                                 EFI_BUFFER_TOO_SMALL, containg length of string\r
+                                 buffer desired.\r
+  @param  Guid                   Routing information: GUID.\r
+  @param  Name                   Routing information: NAME.\r
+  @param  DriverHandle           Driver handle which contains the routing\r
+                                 information: PATH.\r
+\r
+  @retval EFI_SUCCESS            Operation completes successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL   The ConfigHdr string buffer is too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConstructConfigHdr (\r
+  IN OUT CHAR16                *ConfigHdr,\r
+  IN OUT UINTN                 *StrBufferLen,\r
+  IN CONST EFI_GUID            *Guid,\r
+  IN CHAR16                    *Name, OPTIONAL\r
+  IN EFI_HANDLE                *DriverHandle\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     NameStrLen;\r
+  UINTN                     DevicePathSize;\r
+  UINTN                     BufferSize;\r
+  CHAR16                    *StrPtr;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+  if (Name == NULL) {\r
+    //\r
+    // There will be no "NAME" in <ConfigHdr> for  Name/Value storage\r
+    //\r
+    NameStrLen = 0;\r
+  } else {\r
+    //\r
+    // For buffer storage\r
+    //\r
+    NameStrLen = StrLen (Name);\r
+  }\r
+\r
+  //\r
+  // Retrieve DevicePath Protocol associated with this HiiPackageList\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  DriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &DevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DevicePathSize = GetDevicePathSize (DevicePath);\r
+\r
+  //\r
+  // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>\r
+  // | 5  |   32   |  6  |  NameStrLen*4 |  6  |    DevicePathStrLen    | 1 |\r
+  //\r
+  BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16);\r
+  if (*StrBufferLen < BufferSize) {\r
+    *StrBufferLen = BufferSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *StrBufferLen = BufferSize;\r
+\r
+  StrPtr = ConfigHdr;\r
+\r
+  StrCpy (StrPtr, L"GUID=");\r
+  StrPtr += 5;\r
+  BufInReverseOrderToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));\r
+  StrPtr += 32;\r
+\r
+  //\r
+  // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"\r
+  //\r
+  StrCpy (StrPtr, L"&NAME=");\r
+  StrPtr += 6;\r
+  if (Name != NULL) {\r
+    BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);\r
+    UnicodeToConfigString (StrPtr, &BufferSize, Name);\r
+    StrPtr += (NameStrLen * 4);\r
+  }\r
+\r
+  StrCpy (StrPtr, L"&PATH=");\r
+  StrPtr += 6;\r
+  BufInReverseOrderToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.\r
+\r
+  @param  String                 The string to be searched in.\r
+  @param  Offset                 Offset in BlockName.\r
+  @param  Width                  Width in BlockName.\r
+\r
+  @retval TRUE                   Block name found.\r
+  @retval FALSE                  Block name not found.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+FindBlockName (\r
+  IN OUT CHAR16                *String,\r
+  IN UINTN                     Offset,\r
+  IN UINTN                     Width\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Data;\r
+  UINTN       BufferSize;\r
+  UINTN       ConvertedStrLen;\r
+\r
+  while ((String = StrStr (String, L"&OFFSET=")) != NULL) {\r
+    //\r
+    // Skip '&OFFSET='\r
+    //\r
+    String = String + 8;\r
+\r
+    Data = 0;\r
+    BufferSize = sizeof (UINTN);\r
+    Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);\r
+    if (EFI_ERROR (Status)) {\r
+      return FALSE;\r
+    }\r
+    String = String + ConvertedStrLen;\r
+\r
+    if (Data != Offset) {\r
+      continue;\r
+    }\r
+\r
+    if (StrnCmp (String, L"&WIDTH=", 7) != 0) {\r
+      return FALSE;\r
+    }\r
+    String = String + 7;\r
+\r
+    Data = 0;\r
+    BufferSize = sizeof (UINTN);\r
+    Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);\r
+    if (EFI_ERROR (Status)) {\r
+      return FALSE;\r
+    }\r
+    if (Data == Width) {\r
+      return TRUE;\r
+    }\r
+\r
+    String = String + ConvertedStrLen;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.\r
+\r
+  @param  VariableGuid           An optional field to indicate the target variable\r
+                                 GUID name to use.\r
+  @param  VariableName           An optional field to indicate the target\r
+                                 human-readable variable name.\r
+  @param  BufferSize             On input: Length in bytes of buffer to hold\r
+                                 retrived data. On output: If return\r
+                                 EFI_BUFFER_TOO_SMALL, containg length of buffer\r
+                                 desired.\r
+  @param  Buffer                 Buffer to hold retrived data.\r
+\r
+  @retval EFI_SUCCESS            Operation completes successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL   The intput buffer is too small.\r
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetBrowserData (\r
+  IN CONST EFI_GUID              *VariableGuid, OPTIONAL\r
+  IN CONST CHAR16                *VariableName, OPTIONAL\r
+  IN OUT UINTN                   *BufferSize,\r
+  IN OUT UINT8                   *Buffer\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  CONST CHAR16                    *ConfigHdr;\r
+  CHAR16                          *ConfigResp;\r
+  CHAR16                          *StringPtr;\r
+  UINTN                           HeaderLen;\r
+  UINTN                           BufferLen;\r
+  CHAR16                          *Progress;\r
+\r
+  //\r
+  // Locate protocols for use\r
+  //\r
+  Status = LocateFormBrowser2Protocols ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Retrive formset storage data from Form Browser\r
+  //\r
+  ConfigHdr = mFakeConfigHdr;\r
+  HeaderLen = StrLen (ConfigHdr);\r
+  \r
+  //\r
+  // First try allocate 0x4000 buffer for the formet storage data.\r
+  //\r
+  BufferLen = 0x4000;\r
+  ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);\r
+  if (ConfigResp == NULL) {\r
+    BufferLen = 0;\r
+  }\r
+\r
+  StringPtr = ConfigResp + HeaderLen;\r
+  *StringPtr = L'&';\r
+  StringPtr++;\r
+\r
+  Status = mFormBrowser2->BrowserCallback (\r
+                           mFormBrowser2,\r
+                           &BufferLen,\r
+                           StringPtr,\r
+                           TRUE,\r
+                           VariableGuid,\r
+                           VariableName\r
+                           );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    if (ConfigResp != NULL) {\r
+      FreePool (ConfigResp);\r
+    }\r
+\r
+    ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);\r
+    if (ConfigResp == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    StringPtr = ConfigResp + HeaderLen;\r
+    *StringPtr = L'&';\r
+    StringPtr++;\r
+\r
+    Status = mFormBrowser2->BrowserCallback (\r
+                             mFormBrowser2,\r
+                             &BufferLen,\r
+                             StringPtr,\r
+                             TRUE,\r
+                             VariableGuid,\r
+                             VariableName\r
+                             );\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (ConfigResp);\r
+    return Status;\r
+  }\r
+  CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16));\r
+\r
+  //\r
+  // Convert <ConfigResp> to buffer data\r
+  //\r
+  Status = mIfrSupportLibHiiConfigRouting->ConfigToBlock (\r
+                               mIfrSupportLibHiiConfigRouting,\r
+                               ConfigResp,\r
+                               Buffer,\r
+                               BufferSize,\r
+                               &Progress\r
+                               );\r
+  FreePool (ConfigResp);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.\r
+\r
+  @param  VariableGuid           An optional field to indicate the target variable\r
+                                 GUID name to use.\r
+  @param  VariableName           An optional field to indicate the target\r
+                                 human-readable variable name.\r
+  @param  BufferSize             Length in bytes of buffer to hold retrived data.\r
+  @param  Buffer                 Buffer to hold retrived data.\r
+  @param  RequestElement         An optional field to specify which part of the\r
+                                 buffer data will be send back to Browser. If NULL,\r
+                                 the whole buffer of data will be committed to\r
+                                 Browser. <RequestElement> ::=\r
+                                 &OFFSET=<Number>&WIDTH=<Number>*\r
+\r
+  @retval EFI_SUCCESS            Operation completes successfully.\r
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.\r
+  @retval Other                  Updating Browser uncommitted data failed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetBrowserData (\r
+  IN CONST EFI_GUID          *VariableGuid, OPTIONAL\r
+  IN CONST CHAR16            *VariableName, OPTIONAL\r
+  IN UINTN                   BufferSize,\r
+  IN CONST UINT8             *Buffer,\r
+  IN CONST CHAR16            *RequestElement  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  CONST CHAR16                    *ConfigHdr;\r
+  CHAR16                          *ConfigResp;\r
+  CHAR16                          *StringPtr;\r
+  UINTN                           HeaderLen;\r
+  UINTN                           BufferLen;\r
+  CHAR16                          *Progress;\r
+  CHAR16                          BlockName[33];\r
+  CHAR16                          *ConfigRequest;\r
+  CONST CHAR16                    *Request;\r
+\r
+  //\r
+  // Locate protocols for use\r
+  //\r
+  Status = LocateFormBrowser2Protocols ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Prepare <ConfigRequest>\r
+  //\r
+  ConfigHdr = mFakeConfigHdr;\r
+  HeaderLen = StrLen (ConfigHdr);\r
+\r
+  if (RequestElement == NULL) {\r
+    //\r
+    // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>\r
+    //\r
+    BlockName[0] = L'\0';\r
+    StrCpy (BlockName, L"&OFFSET=0&WIDTH=");\r
+\r
+    //\r
+    // String lenghth of L"&OFFSET=0&WIDTH=" is 16\r
+    //\r
+    StringPtr = BlockName + 16;\r
+    BufferLen = sizeof (BlockName) - (16 * sizeof (CHAR16));\r
+    BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN));\r
+\r
+    Request = BlockName;\r
+  } else {\r
+    Request = RequestElement;\r
+  }\r
+\r
+  BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request);\r
+  ConfigRequest = AllocateZeroPool (BufferLen);\r
+  if (ConfigRequest == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16));\r
+  StringPtr = ConfigRequest + HeaderLen;\r
+  StrCpy (StringPtr, Request);\r
+\r
+  //\r
+  // Convert buffer to <ConfigResp>\r
+  //\r
+  Status = mIfrSupportLibHiiConfigRouting->BlockToConfig (\r
+                                mIfrSupportLibHiiConfigRouting,\r
+                                ConfigRequest,\r
+                                Buffer,\r
+                                BufferSize,\r
+                                &ConfigResp,\r
+                                &Progress\r
+                                );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (ConfigRequest);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Skip <ConfigHdr> and '&'\r
+  //\r
+  StringPtr = ConfigResp + HeaderLen + 1;\r
+\r
+  //\r
+  // Change uncommitted data in Browser\r
+  //\r
+  Status = mFormBrowser2->BrowserCallback (\r
+                           mFormBrowser2,\r
+                           &BufferSize,\r
+                           StringPtr,\r
+                           FALSE,\r
+                           NULL,\r
+                           NULL\r
+                           );\r
+  FreePool (ConfigRequest);\r
+  return Status;\r
+}\r
index 4b53f18eb982e34fc57a93ab8a3d2431caaa88b5..43897b9920fba4824960ce2f00ef04cff07fe785 100644 (file)
@@ -1,37 +1,37 @@
-/** @file
-Utility functions which helps in opcode creation, HII configuration string manipulations, 
-pop up window creations, setup browser persistence data set and get.
-
-Copyright (c) 2007 - 2008, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-
-**/
-
-#ifndef _IFRLIBRARY_INTERNAL_H_
-#define _IFRLIBRARY_INTERNAL_H_
-
-
-#include <Uefi.h>
-
-#include <Protocol/DevicePath.h>
+/** @file\r
+Utility functions which helps in opcode creation, HII configuration string manipulations, \r
+pop up window creations, setup browser persistence data set and get.\r
+\r
+Copyright (c) 2007 - 2008, 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
+\r
+**/\r
+\r
+#ifndef _IFRLIBRARY_INTERNAL_H_\r
+#define _IFRLIBRARY_INTERNAL_H_\r
+\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/DevicePath.h>\r
 #include <Protocol/HiiConfigRouting.h>\r
 #include <Protocol/FormBrowser2.h>\r
-
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/IfrSupportLib.h>
-
-
-#endif
-
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/IfrSupportLib.h>\r
+\r
+\r
+#endif\r
+\r
index d79e254aae2a2e40414df08e7e591f284b450c6f..9b48a27e1927ad028932977216c053e35e618b39 100644 (file)
-/** @file
-  Library Routines to create IFR independent of string data - assume tokens already exist
-  Primarily to be used for exporting op-codes at a label in pre-defined forms.
-
-
-Copyright (c) 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-
-**/
-
-#include "UefiIfrLibraryInternal.h"
-
-/**
-  Check if the input question flags is a valid value.
-  The valid combination of question flags includes
-  EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY.
-
-  @param Flags The question flags to check.
-
-  @retval TRUE  If the question flag is a valid combination.
-  @retval FALSE If the question flag is an invalid combination.
-  
-**/
-BOOLEAN
-IsValidQuestionFlags (
-  IN UINT8                   Flags
-  )
-{
-  return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE);
-}
-
-/**
-  Check if the input value type is a valid type.
-  The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER.
-
-  @param Type   The value type to check.
-
-  @retval TRUE  If the value type is valid.
-  @retval FALSE If the value type is invalid.
-  
-**/
-BOOLEAN
-IsValidValueType (
-  IN UINT8                   Type
-  )
-{
-  return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE);
-}
-
-/**
-  Check if the input numeric flags is a valid value.
-
-  @param Flags The numeric flags to check.
-
-  @retval TRUE  If the numeric flags is valid.
-  @retval FALSE If the numeric flags is invalid.
-  
-**/
-BOOLEAN
-IsValidNumricFlags (
-  IN UINT8                   Flags
-  )
-{
-  if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) {
-    return FALSE;
-  }
-
-  if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
-  Check if the checkbox flags is a valid value.
-
-  @param Flags The checkbox flags to check.
-
-  @retval TRUE  If the checkbox flags is valid.
-  @retval FALSE If the checkbox flags is invalid.
-  
-**/
-BOOLEAN
-IsValidCheckboxFlags (
-  IN UINT8                   Flags
-  )
-{
-  return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE);
-}
-
-/**
-  Create EFI_IFR_END_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateEndOpCode (
-  IN OUT EFI_HII_UPDATE_DATA *Data
-  )
-{
-  EFI_IFR_END                 End;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  End.Header.Length  = sizeof (EFI_IFR_END);
-  End.Header.OpCode  = EFI_IFR_END_OP;
-  End.Header.Scope   = 0;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_END to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));
-  Data->Offset += sizeof (EFI_IFR_END);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_DEFAULT_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  Value                  Value for the default
-  @param  Type                   Type for the default
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER The type is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateDefaultOpCode (
-  IN     EFI_IFR_TYPE_VALUE  *Value,
-  IN     UINT8               Type,
-  IN OUT EFI_HII_UPDATE_DATA *Data
-  )
-{
-  EFI_IFR_DEFAULT            Default;
-  UINT8                      *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if ((Value == NULL) || !IsValidValueType (Type)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Default.Header.OpCode = EFI_IFR_DEFAULT_OP;
-  Default.Header.Length = sizeof (EFI_IFR_DEFAULT);
-  Default.Header.Scope  = 0;
-  Default.Type          = Type;
-  Default.DefaultId     = EFI_HII_DEFAULT_CLASS_STANDARD;
-  CopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE));
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_DEFAULT to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));
-  Data->Offset += sizeof (EFI_IFR_DEFAULT);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_ACTION_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  QuestionConfig         String ID for configuration
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateActionOpCode (
-  IN     EFI_QUESTION_ID      QuestionId,
-  IN     EFI_STRING_ID        Prompt,
-  IN     EFI_STRING_ID        Help,
-  IN     UINT8                QuestionFlags,
-  IN     EFI_STRING_ID        QuestionConfig,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_ACTION              Action;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Action.Header.OpCode          = EFI_IFR_ACTION_OP;
-  Action.Header.Length          = sizeof (EFI_IFR_ACTION);
-  Action.Header.Scope           = 0;
-  Action.Question.QuestionId    = QuestionId;
-  Action.Question.Header.Prompt = Prompt;
-  Action.Question.Header.Help   = Help;
-  Action.Question.VarStoreId    = INVALID_VARSTORE_ID;
-  Action.Question.Flags         = QuestionFlags;
-  Action.QuestionConfig         = QuestionConfig;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_ACTION to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));
-  Data->Offset += sizeof (EFI_IFR_ACTION);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_SUBTITLE_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  Flags                  Subtitle opcode flags
-  @param  Scope                  Subtitle Scope bit
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  
-**/
-EFI_STATUS
-EFIAPI
-CreateSubTitleOpCode (
-  IN      EFI_STRING_ID       Prompt,
-  IN      EFI_STRING_ID       Help,
-  IN      UINT8               Flags,
-  IN      UINT8               Scope,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_SUBTITLE            Subtitle;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Subtitle.Header.OpCode    = EFI_IFR_SUBTITLE_OP;
-  Subtitle.Header.Length    = sizeof (EFI_IFR_SUBTITLE);
-  Subtitle.Header.Scope     = Scope;
-  Subtitle.Statement.Prompt = Prompt;
-  Subtitle.Statement.Help   = Help;
-  Subtitle.Flags            = Flags;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_SUBTITLE to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));
-  Data->Offset += sizeof (EFI_IFR_SUBTITLE);
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Create EFI_IFR_TEXT_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  TextTwo                String ID for text two
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateTextOpCode (
-  IN     EFI_STRING_ID        Prompt,
-  IN     EFI_STRING_ID        Help,
-  IN     EFI_STRING_ID        TextTwo,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_TEXT                Text;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Text.Header.OpCode    = EFI_IFR_TEXT_OP;
-  Text.Header.Length    = sizeof (EFI_IFR_TEXT);
-  Text.Header.Scope     = 0;
-  Text.Statement.Prompt = Prompt;
-  Text.Statement.Help   = Help;
-  Text.TextTwo          = TextTwo;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_TEXT to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));
-  Data->Offset += sizeof (EFI_IFR_TEXT);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_REF_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  FormId                 Destination Form ID
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  QuestionId             Question ID
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateGotoOpCode (
-  IN     EFI_FORM_ID          FormId,
-  IN     EFI_STRING_ID        Prompt,
-  IN     EFI_STRING_ID        Help,
-  IN     UINT8                QuestionFlags,
-  IN     EFI_QUESTION_ID      QuestionId,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_REF                 Goto;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Goto.Header.OpCode          = EFI_IFR_REF_OP;
-  Goto.Header.Length          = sizeof (EFI_IFR_REF);
-  Goto.Header.Scope           = 0;
-  Goto.Question.Header.Prompt = Prompt;
-  Goto.Question.Header.Help   = Help;
-  Goto.Question.VarStoreId    = INVALID_VARSTORE_ID;
-  Goto.Question.QuestionId    = QuestionId;
-  Goto.Question.Flags         = QuestionFlags;
-  Goto.FormId                 = FormId;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_REF to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));
-  Data->Offset += sizeof (EFI_IFR_REF);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_ONE_OF_OPTION_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  OptionCount            The number of options.
-  @param  OptionsList            The list of Options.
-  @param  Type                   The data type.
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If OptionCount is not zero but OptionsList is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateOneOfOptionOpCode (
-  IN     UINTN                OptionCount,
-  IN     IFR_OPTION           *OptionsList,
-  IN     UINT8                Type,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  UINTN                       Index;
-  UINT8                       *LocalBuffer;
-  EFI_IFR_ONE_OF_OPTION       OneOfOption;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if ((OptionCount != 0) && (OptionsList == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  for (Index = 0; Index < OptionCount; Index++) {
-    OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;
-    OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);
-    OneOfOption.Header.Scope  = 0;
-
-    OneOfOption.Option        = OptionsList[Index].StringToken;
-    OneOfOption.Value         = OptionsList[Index].Value;
-    OneOfOption.Flags         = (UINT8) (OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
-    OneOfOption.Type          = Type;
-
-    LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-    //
-    // CopyMem is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access.
-    //
-    CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));
-    Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_ONE_OF_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  VarStoreId             Storage ID
-  @param  VarOffset              Offset in Storage
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  OneOfFlags             Flags for oneof opcode
-  @param  OptionsList            List of options
-  @param  OptionCount            Number of options in option list
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateOneOfOpCode (
-  IN     EFI_QUESTION_ID      QuestionId,
-  IN     EFI_VARSTORE_ID      VarStoreId,
-  IN     UINT16               VarOffset,
-  IN     EFI_STRING_ID        Prompt,
-  IN     EFI_STRING_ID        Help,
-  IN     UINT8                QuestionFlags,
-  IN     UINT8                OneOfFlags,
-  IN     IFR_OPTION           *OptionsList,
-  IN     UINTN                OptionCount,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  UINTN                       Length;
-  EFI_IFR_ONE_OF              OneOf;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidNumricFlags (OneOfFlags) ||
-      !IsValidQuestionFlags (QuestionFlags) ||
-      ((OptionCount != 0) && (OptionsList == NULL))) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
-  if (Data->Offset + Length > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  OneOf.Header.OpCode                   = EFI_IFR_ONE_OF_OP;
-  OneOf.Header.Length                   = sizeof (EFI_IFR_ONE_OF);
-  OneOf.Header.Scope                    = 1;
-  OneOf.Question.Header.Prompt          = Prompt;
-  OneOf.Question.Header.Help            = Help;
-  OneOf.Question.QuestionId             = QuestionId;
-  OneOf.Question.VarStoreId             = VarStoreId;
-  OneOf.Question.VarStoreInfo.VarOffset = VarOffset;
-  OneOf.Question.Flags                  = QuestionFlags;
-  OneOf.Flags                           = OneOfFlags;
-  ZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_ONF_OF to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));
-  Data->Offset += sizeof (EFI_IFR_ONE_OF);
-
-  CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8) (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);
-
-  CreateEndOpCode (Data);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_ORDERED_LIST_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  VarStoreId             Storage ID
-  @param  VarOffset              Offset in Storage
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  OrderedListFlags       Flags for ordered list opcode
-  @param  DataType               Type for option value
-  @param  MaxContainers          Maximum count for options in this ordered list
-  @param  OptionsList            List of options
-  @param  OptionCount            Number of options in option list
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateOrderedListOpCode (
-  IN      EFI_QUESTION_ID     QuestionId,
-  IN      EFI_VARSTORE_ID     VarStoreId,
-  IN      UINT16              VarOffset,
-  IN      EFI_STRING_ID       Prompt,
-  IN      EFI_STRING_ID       Help,
-  IN      UINT8               QuestionFlags,
-  IN      UINT8               OrderedListFlags,
-  IN      UINT8               DataType,
-  IN      UINT8               MaxContainers,
-  IN      IFR_OPTION          *OptionsList,
-  IN     UINTN                OptionCount,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  UINTN                       Length;
-  EFI_IFR_ORDERED_LIST        OrderedList;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags) ||
-      ((OptionCount != 0) && (OptionsList == NULL))) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if ((OrderedListFlags != 0) &&
-      (OrderedListFlags != EFI_IFR_UNIQUE_SET) &&
-      (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
-  if (Data->Offset + Length > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  OrderedList.Header.OpCode                   = EFI_IFR_ORDERED_LIST_OP;
-  OrderedList.Header.Length                   = sizeof (EFI_IFR_ORDERED_LIST);
-  OrderedList.Header.Scope                    = 1;
-  OrderedList.Question.Header.Prompt          = Prompt;
-  OrderedList.Question.Header.Help            = Help;
-  OrderedList.Question.QuestionId             = QuestionId;
-  OrderedList.Question.VarStoreId             = VarStoreId;
-  OrderedList.Question.VarStoreInfo.VarOffset = VarOffset;
-  OrderedList.Question.Flags                  = QuestionFlags;
-  OrderedList.MaxContainers                   = MaxContainers;
-  OrderedList.Flags                           = OrderedListFlags;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));
-  Data->Offset += sizeof (EFI_IFR_ORDERED_LIST);
-
-  CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data);
-
-  CreateEndOpCode (Data);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_CHECKBOX_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  VarStoreId             Storage ID
-  @param  VarOffset              Offset in Storage
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  CheckBoxFlags          Flags for checkbox opcode
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateCheckBoxOpCode (
-  IN      EFI_QUESTION_ID     QuestionId,
-  IN      EFI_VARSTORE_ID     VarStoreId,
-  IN      UINT16              VarOffset,
-  IN      EFI_STRING_ID       Prompt,
-  IN      EFI_STRING_ID       Help,
-  IN      UINT8               QuestionFlags,
-  IN      UINT8               CheckBoxFlags,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_CHECKBOX            CheckBox;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  CheckBox.Header.OpCode                   = EFI_IFR_CHECKBOX_OP;
-  CheckBox.Header.Length                   = sizeof (EFI_IFR_CHECKBOX);
-  CheckBox.Header.Scope                    = 0;
-  CheckBox.Question.QuestionId             = QuestionId;
-  CheckBox.Question.VarStoreId             = VarStoreId;
-  CheckBox.Question.VarStoreInfo.VarOffset = VarOffset;
-  CheckBox.Question.Header.Prompt          = Prompt;
-  CheckBox.Question.Header.Help            = Help;
-  CheckBox.Question.Flags                  = QuestionFlags;
-  CheckBox.Flags                           = CheckBoxFlags;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_CHECKBOX to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));
-  Data->Offset += sizeof (EFI_IFR_CHECKBOX);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_NUMERIC_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  VarStoreId             Storage ID
-  @param  VarOffset              Offset in Storage
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  NumericFlags           Flags for numeric opcode
-  @param  Minimum                Numeric minimum value
-  @param  Maximum                Numeric maximum value
-  @param  Step                   Numeric step for edit
-  @param  Default                Numeric default value
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateNumericOpCode (
-  IN     EFI_QUESTION_ID     QuestionId,
-  IN     EFI_VARSTORE_ID     VarStoreId,
-  IN     UINT16              VarOffset,
-  IN     EFI_STRING_ID       Prompt,
-  IN     EFI_STRING_ID       Help,
-  IN     UINT8               QuestionFlags,
-  IN     UINT8               NumericFlags,
-  IN     UINT64              Minimum,
-  IN     UINT64              Maximum,
-  IN     UINT64              Step,
-  IN     UINT64              Default,
-  IN OUT EFI_HII_UPDATE_DATA *Data
-  )
-{
-  EFI_STATUS                  Status;
-  EFI_IFR_NUMERIC             Numeric;
-  MINMAXSTEP_DATA             MinMaxStep;
-  EFI_IFR_TYPE_VALUE          DefaultValue;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  Numeric.Header.OpCode                   = EFI_IFR_NUMERIC_OP;
-  Numeric.Header.Length                   = sizeof (EFI_IFR_NUMERIC);
-  Numeric.Header.Scope                    = 1;
-  Numeric.Question.QuestionId             = QuestionId;
-  Numeric.Question.VarStoreId             = VarStoreId;
-  Numeric.Question.VarStoreInfo.VarOffset = VarOffset;
-  Numeric.Question.Header.Prompt          = Prompt;
-  Numeric.Question.Header.Help            = Help;
-  Numeric.Question.Flags                  = QuestionFlags;
-  Numeric.Flags                           = NumericFlags;
-
-  switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
-  case EFI_IFR_NUMERIC_SIZE_1:
-    MinMaxStep.u8.MinValue = (UINT8) Minimum;
-    MinMaxStep.u8.MaxValue = (UINT8) Maximum;
-    MinMaxStep.u8.Step     = (UINT8) Step;
-    break;
-
-  case EFI_IFR_NUMERIC_SIZE_2:
-    MinMaxStep.u16.MinValue = (UINT16) Minimum;
-    MinMaxStep.u16.MaxValue = (UINT16) Maximum;
-    MinMaxStep.u16.Step     = (UINT16) Step;
-    break;
-
-  case EFI_IFR_NUMERIC_SIZE_4:
-    MinMaxStep.u32.MinValue = (UINT32) Minimum;
-    MinMaxStep.u32.MaxValue = (UINT32) Maximum;
-    MinMaxStep.u32.Step     = (UINT32) Step;
-    break;
-
-  case EFI_IFR_NUMERIC_SIZE_8:
-    MinMaxStep.u64.MinValue = Minimum;
-    MinMaxStep.u64.MaxValue = Maximum;
-    MinMaxStep.u64.Step     = Step;
-    break;
-  }
-
-  CopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA));
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_NUMERIC to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));
-  Data->Offset += sizeof (EFI_IFR_NUMERIC);
-
-  DefaultValue.u64 = Default;
-  Status = CreateDefaultOpCode (&DefaultValue, (UINT8) (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data);
-  if (EFI_ERROR(Status)) {
-    return Status;
-  }
-
-  CreateEndOpCode (Data);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create EFI_IFR_STRING_OP opcode.
-
-  If Data is NULL or Data->Data is NULL, then ASSERT.
-
-  @param  QuestionId             Question ID
-  @param  VarStoreId             Storage ID
-  @param  VarOffset              Offset in Storage
-  @param  Prompt                 String ID for Prompt
-  @param  Help                   String ID for Help
-  @param  QuestionFlags          Flags in Question Header
-  @param  StringFlags            Flags for string opcode
-  @param  MinSize                String minimum length
-  @param  MaxSize                String maximum length
-  @param  Data                   Destination for the created opcode binary
-
-  @retval EFI_SUCCESS            Opcode is created successfully.
-  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
-  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-CreateStringOpCode (
-  IN      EFI_QUESTION_ID     QuestionId,
-  IN      EFI_VARSTORE_ID     VarStoreId,
-  IN      UINT16              VarOffset,
-  IN      EFI_STRING_ID       Prompt,
-  IN      EFI_STRING_ID       Help,
-  IN      UINT8               QuestionFlags,
-  IN      UINT8               StringFlags,
-  IN      UINT8               MinSize,
-  IN      UINT8               MaxSize,
-  IN OUT EFI_HII_UPDATE_DATA  *Data
-  )
-{
-  EFI_IFR_STRING              String;
-  UINT8                       *LocalBuffer;
-
-  ASSERT (Data != NULL && Data->Data != NULL);
-
-  if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & ~EFI_IFR_STRING_MULTI_LINE) != 0) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) {
-    return EFI_BUFFER_TOO_SMALL;
-  }
-
-  String.Header.OpCode                   = EFI_IFR_STRING_OP;
-  String.Header.Length                   = sizeof (EFI_IFR_STRING);
-  String.Header.Scope                    = 0;
-  String.Question.Header.Prompt          = Prompt;
-  String.Question.Header.Help            = Help;
-  String.Question.QuestionId             = QuestionId;
-  String.Question.VarStoreId             = VarStoreId;
-  String.Question.VarStoreInfo.VarOffset = VarOffset;
-  String.Question.Flags                  = QuestionFlags;
-  String.MinSize                         = MinSize;
-  String.MaxSize                         = MaxSize;
-  String.Flags                           = StringFlags;
-
-  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
-  //
-  // CopyMem is used for EFI_IFR_STRING to cover the unaligned address access.
-  //
-  CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));
-  Data->Offset += sizeof (EFI_IFR_STRING);
-
-  return EFI_SUCCESS;
-}
-
-
+/** @file\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
+\r
+Copyright (c) 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
+\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
+#include "UefiIfrLibraryInternal.h"\r
+\r
+/**\r
+  Check if the input question flags is a valid value.\r
+  The valid combination of question flags includes\r
+  EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY.\r
+\r
+  @param Flags The question flags to check.\r
+\r
+  @retval TRUE  If the question flag is a valid combination.\r
+  @retval FALSE If the question flag is an invalid combination.\r
+  \r
+**/\r
+BOOLEAN\r
+IsValidQuestionFlags (\r
+  IN UINT8                   Flags\r
+  )\r
+{\r
+  return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE);\r
+}\r
+\r
+/**\r
+  Check if the input value type is a valid type.\r
+  The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER.\r
+\r
+  @param Type   The value type to check.\r
+\r
+  @retval TRUE  If the value type is valid.\r
+  @retval FALSE If the value type is invalid.\r
+  \r
+**/\r
+BOOLEAN\r
+IsValidValueType (\r
+  IN UINT8                   Type\r
+  )\r
+{\r
+  return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE);\r
+}\r
+\r
+/**\r
+  Check if the input numeric flags is a valid value.\r
+\r
+  @param Flags The numeric flags to check.\r
+\r
+  @retval TRUE  If the numeric flags is valid.\r
+  @retval FALSE If the numeric flags is invalid.\r
+  \r
+**/\r
+BOOLEAN\r
+IsValidNumricFlags (\r
+  IN UINT8                   Flags\r
+  )\r
+{\r
+  if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Check if the checkbox flags is a valid value.\r
+\r
+  @param Flags The checkbox flags to check.\r
+\r
+  @retval TRUE  If the checkbox flags is valid.\r
+  @retval FALSE If the checkbox flags is invalid.\r
+  \r
+**/\r
+BOOLEAN\r
+IsValidCheckboxFlags (\r
+  IN UINT8                   Flags\r
+  )\r
+{\r
+  return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE);\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_END_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateEndOpCode (\r
+  IN OUT EFI_HII_UPDATE_DATA *Data\r
+  )\r
+{\r
+  EFI_IFR_END                 End;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  End.Header.Length  = sizeof (EFI_IFR_END);\r
+  End.Header.OpCode  = EFI_IFR_END_OP;\r
+  End.Header.Scope   = 0;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_END to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));\r
+  Data->Offset += sizeof (EFI_IFR_END);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_DEFAULT_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  Value                  Value for the default\r
+  @param  Type                   Type for the default\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER The type is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateDefaultOpCode (\r
+  IN     EFI_IFR_TYPE_VALUE  *Value,\r
+  IN     UINT8               Type,\r
+  IN OUT EFI_HII_UPDATE_DATA *Data\r
+  )\r
+{\r
+  EFI_IFR_DEFAULT            Default;\r
+  UINT8                      *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if ((Value == NULL) || !IsValidValueType (Type)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Default.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
+  Default.Header.Length = sizeof (EFI_IFR_DEFAULT);\r
+  Default.Header.Scope  = 0;\r
+  Default.Type          = Type;\r
+  Default.DefaultId     = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+  CopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE));\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_DEFAULT to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));\r
+  Data->Offset += sizeof (EFI_IFR_DEFAULT);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_ACTION_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  QuestionConfig         String ID for configuration\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateActionOpCode (\r
+  IN     EFI_QUESTION_ID      QuestionId,\r
+  IN     EFI_STRING_ID        Prompt,\r
+  IN     EFI_STRING_ID        Help,\r
+  IN     UINT8                QuestionFlags,\r
+  IN     EFI_STRING_ID        QuestionConfig,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_ACTION              Action;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Action.Header.OpCode          = EFI_IFR_ACTION_OP;\r
+  Action.Header.Length          = sizeof (EFI_IFR_ACTION);\r
+  Action.Header.Scope           = 0;\r
+  Action.Question.QuestionId    = QuestionId;\r
+  Action.Question.Header.Prompt = Prompt;\r
+  Action.Question.Header.Help   = Help;\r
+  Action.Question.VarStoreId    = INVALID_VARSTORE_ID;\r
+  Action.Question.Flags         = QuestionFlags;\r
+  Action.QuestionConfig         = QuestionConfig;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_ACTION to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));\r
+  Data->Offset += sizeof (EFI_IFR_ACTION);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_SUBTITLE_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  Flags                  Subtitle opcode flags\r
+  @param  Scope                  Subtitle Scope bit\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateSubTitleOpCode (\r
+  IN      EFI_STRING_ID       Prompt,\r
+  IN      EFI_STRING_ID       Help,\r
+  IN      UINT8               Flags,\r
+  IN      UINT8               Scope,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_SUBTITLE            Subtitle;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Subtitle.Header.OpCode    = EFI_IFR_SUBTITLE_OP;\r
+  Subtitle.Header.Length    = sizeof (EFI_IFR_SUBTITLE);\r
+  Subtitle.Header.Scope     = Scope;\r
+  Subtitle.Statement.Prompt = Prompt;\r
+  Subtitle.Statement.Help   = Help;\r
+  Subtitle.Flags            = Flags;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_SUBTITLE to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));\r
+  Data->Offset += sizeof (EFI_IFR_SUBTITLE);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Create EFI_IFR_TEXT_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  TextTwo                String ID for text two\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateTextOpCode (\r
+  IN     EFI_STRING_ID        Prompt,\r
+  IN     EFI_STRING_ID        Help,\r
+  IN     EFI_STRING_ID        TextTwo,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_TEXT                Text;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Text.Header.OpCode    = EFI_IFR_TEXT_OP;\r
+  Text.Header.Length    = sizeof (EFI_IFR_TEXT);\r
+  Text.Header.Scope     = 0;\r
+  Text.Statement.Prompt = Prompt;\r
+  Text.Statement.Help   = Help;\r
+  Text.TextTwo          = TextTwo;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_TEXT to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));\r
+  Data->Offset += sizeof (EFI_IFR_TEXT);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_REF_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  FormId                 Destination Form ID\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  QuestionId             Question ID\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateGotoOpCode (\r
+  IN     EFI_FORM_ID          FormId,\r
+  IN     EFI_STRING_ID        Prompt,\r
+  IN     EFI_STRING_ID        Help,\r
+  IN     UINT8                QuestionFlags,\r
+  IN     EFI_QUESTION_ID      QuestionId,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_REF                 Goto;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Goto.Header.OpCode          = EFI_IFR_REF_OP;\r
+  Goto.Header.Length          = sizeof (EFI_IFR_REF);\r
+  Goto.Header.Scope           = 0;\r
+  Goto.Question.Header.Prompt = Prompt;\r
+  Goto.Question.Header.Help   = Help;\r
+  Goto.Question.VarStoreId    = INVALID_VARSTORE_ID;\r
+  Goto.Question.QuestionId    = QuestionId;\r
+  Goto.Question.Flags         = QuestionFlags;\r
+  Goto.FormId                 = FormId;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_REF to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));\r
+  Data->Offset += sizeof (EFI_IFR_REF);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_ONE_OF_OPTION_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  OptionCount            The number of options.\r
+  @param  OptionsList            The list of Options.\r
+  @param  Type                   The data type.\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If OptionCount is not zero but OptionsList is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateOneOfOptionOpCode (\r
+  IN     UINTN                OptionCount,\r
+  IN     IFR_OPTION           *OptionsList,\r
+  IN     UINT8                Type,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  UINT8                       *LocalBuffer;\r
+  EFI_IFR_ONE_OF_OPTION       OneOfOption;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if ((OptionCount != 0) && (OptionsList == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\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
+    OneOfOption.Header.Scope  = 0;\r
+\r
+    OneOfOption.Option        = OptionsList[Index].StringToken;\r
+    OneOfOption.Value         = OptionsList[Index].Value;\r
+    OneOfOption.Flags         = (UINT8) (OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));\r
+    OneOfOption.Type          = Type;\r
+\r
+    LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+    //\r
+    // CopyMem is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access.\r
+    //\r
+    CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));\r
+    Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_ONE_OF_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  VarStoreId             Storage ID\r
+  @param  VarOffset              Offset in Storage\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  OneOfFlags             Flags for oneof opcode\r
+  @param  OptionsList            List of options\r
+  @param  OptionCount            Number of options in option list\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateOneOfOpCode (\r
+  IN     EFI_QUESTION_ID      QuestionId,\r
+  IN     EFI_VARSTORE_ID      VarStoreId,\r
+  IN     UINT16               VarOffset,\r
+  IN     EFI_STRING_ID        Prompt,\r
+  IN     EFI_STRING_ID        Help,\r
+  IN     UINT8                QuestionFlags,\r
+  IN     UINT8                OneOfFlags,\r
+  IN     IFR_OPTION           *OptionsList,\r
+  IN     UINTN                OptionCount,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  UINTN                       Length;\r
+  EFI_IFR_ONE_OF              OneOf;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidNumricFlags (OneOfFlags) ||\r
+      !IsValidQuestionFlags (QuestionFlags) ||\r
+      ((OptionCount != 0) && (OptionsList == NULL))) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);\r
+  if (Data->Offset + Length > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  OneOf.Header.OpCode                   = EFI_IFR_ONE_OF_OP;\r
+  OneOf.Header.Length                   = sizeof (EFI_IFR_ONE_OF);\r
+  OneOf.Header.Scope                    = 1;\r
+  OneOf.Question.Header.Prompt          = Prompt;\r
+  OneOf.Question.Header.Help            = Help;\r
+  OneOf.Question.QuestionId             = QuestionId;\r
+  OneOf.Question.VarStoreId             = VarStoreId;\r
+  OneOf.Question.VarStoreInfo.VarOffset = VarOffset;\r
+  OneOf.Question.Flags                  = QuestionFlags;\r
+  OneOf.Flags                           = OneOfFlags;\r
+  ZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_ONF_OF to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));\r
+  Data->Offset += sizeof (EFI_IFR_ONE_OF);\r
+\r
+  CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8) (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);\r
+\r
+  CreateEndOpCode (Data);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_ORDERED_LIST_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  VarStoreId             Storage ID\r
+  @param  VarOffset              Offset in Storage\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  OrderedListFlags       Flags for ordered list opcode\r
+  @param  DataType               Type for option value\r
+  @param  MaxContainers          Maximum count for options in this ordered list\r
+  @param  OptionsList            List of options\r
+  @param  OptionCount            Number of options in option list\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateOrderedListOpCode (\r
+  IN      EFI_QUESTION_ID     QuestionId,\r
+  IN      EFI_VARSTORE_ID     VarStoreId,\r
+  IN      UINT16              VarOffset,\r
+  IN      EFI_STRING_ID       Prompt,\r
+  IN      EFI_STRING_ID       Help,\r
+  IN      UINT8               QuestionFlags,\r
+  IN      UINT8               OrderedListFlags,\r
+  IN      UINT8               DataType,\r
+  IN      UINT8               MaxContainers,\r
+  IN      IFR_OPTION          *OptionsList,\r
+  IN     UINTN                OptionCount,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  UINTN                       Length;\r
+  EFI_IFR_ORDERED_LIST        OrderedList;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags) ||\r
+      ((OptionCount != 0) && (OptionsList == NULL))) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((OrderedListFlags != 0) &&\r
+      (OrderedListFlags != EFI_IFR_UNIQUE_SET) &&\r
+      (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);\r
+  if (Data->Offset + Length > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  OrderedList.Header.OpCode                   = EFI_IFR_ORDERED_LIST_OP;\r
+  OrderedList.Header.Length                   = sizeof (EFI_IFR_ORDERED_LIST);\r
+  OrderedList.Header.Scope                    = 1;\r
+  OrderedList.Question.Header.Prompt          = Prompt;\r
+  OrderedList.Question.Header.Help            = Help;\r
+  OrderedList.Question.QuestionId             = QuestionId;\r
+  OrderedList.Question.VarStoreId             = VarStoreId;\r
+  OrderedList.Question.VarStoreInfo.VarOffset = VarOffset;\r
+  OrderedList.Question.Flags                  = QuestionFlags;\r
+  OrderedList.MaxContainers                   = MaxContainers;\r
+  OrderedList.Flags                           = OrderedListFlags;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));\r
+  Data->Offset += sizeof (EFI_IFR_ORDERED_LIST);\r
+\r
+  CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data);\r
+\r
+  CreateEndOpCode (Data);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_CHECKBOX_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  VarStoreId             Storage ID\r
+  @param  VarOffset              Offset in Storage\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  CheckBoxFlags          Flags for checkbox opcode\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateCheckBoxOpCode (\r
+  IN      EFI_QUESTION_ID     QuestionId,\r
+  IN      EFI_VARSTORE_ID     VarStoreId,\r
+  IN      UINT16              VarOffset,\r
+  IN      EFI_STRING_ID       Prompt,\r
+  IN      EFI_STRING_ID       Help,\r
+  IN      UINT8               QuestionFlags,\r
+  IN      UINT8               CheckBoxFlags,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_CHECKBOX            CheckBox;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  CheckBox.Header.OpCode                   = EFI_IFR_CHECKBOX_OP;\r
+  CheckBox.Header.Length                   = sizeof (EFI_IFR_CHECKBOX);\r
+  CheckBox.Header.Scope                    = 0;\r
+  CheckBox.Question.QuestionId             = QuestionId;\r
+  CheckBox.Question.VarStoreId             = VarStoreId;\r
+  CheckBox.Question.VarStoreInfo.VarOffset = VarOffset;\r
+  CheckBox.Question.Header.Prompt          = Prompt;\r
+  CheckBox.Question.Header.Help            = Help;\r
+  CheckBox.Question.Flags                  = QuestionFlags;\r
+  CheckBox.Flags                           = CheckBoxFlags;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_CHECKBOX to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));\r
+  Data->Offset += sizeof (EFI_IFR_CHECKBOX);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_NUMERIC_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  VarStoreId             Storage ID\r
+  @param  VarOffset              Offset in Storage\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  NumericFlags           Flags for numeric opcode\r
+  @param  Minimum                Numeric minimum value\r
+  @param  Maximum                Numeric maximum value\r
+  @param  Step                   Numeric step for edit\r
+  @param  Default                Numeric default value\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateNumericOpCode (\r
+  IN     EFI_QUESTION_ID     QuestionId,\r
+  IN     EFI_VARSTORE_ID     VarStoreId,\r
+  IN     UINT16              VarOffset,\r
+  IN     EFI_STRING_ID       Prompt,\r
+  IN     EFI_STRING_ID       Help,\r
+  IN     UINT8               QuestionFlags,\r
+  IN     UINT8               NumericFlags,\r
+  IN     UINT64              Minimum,\r
+  IN     UINT64              Maximum,\r
+  IN     UINT64              Step,\r
+  IN     UINT64              Default,\r
+  IN OUT EFI_HII_UPDATE_DATA *Data\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_IFR_NUMERIC             Numeric;\r
+  MINMAXSTEP_DATA             MinMaxStep;\r
+  EFI_IFR_TYPE_VALUE          DefaultValue;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Numeric.Header.OpCode                   = EFI_IFR_NUMERIC_OP;\r
+  Numeric.Header.Length                   = sizeof (EFI_IFR_NUMERIC);\r
+  Numeric.Header.Scope                    = 1;\r
+  Numeric.Question.QuestionId             = QuestionId;\r
+  Numeric.Question.VarStoreId             = VarStoreId;\r
+  Numeric.Question.VarStoreInfo.VarOffset = VarOffset;\r
+  Numeric.Question.Header.Prompt          = Prompt;\r
+  Numeric.Question.Header.Help            = Help;\r
+  Numeric.Question.Flags                  = QuestionFlags;\r
+  Numeric.Flags                           = NumericFlags;\r
+\r
+  switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {\r
+  case EFI_IFR_NUMERIC_SIZE_1:\r
+    MinMaxStep.u8.MinValue = (UINT8) Minimum;\r
+    MinMaxStep.u8.MaxValue = (UINT8) Maximum;\r
+    MinMaxStep.u8.Step     = (UINT8) Step;\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_2:\r
+    MinMaxStep.u16.MinValue = (UINT16) Minimum;\r
+    MinMaxStep.u16.MaxValue = (UINT16) Maximum;\r
+    MinMaxStep.u16.Step     = (UINT16) Step;\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_4:\r
+    MinMaxStep.u32.MinValue = (UINT32) Minimum;\r
+    MinMaxStep.u32.MaxValue = (UINT32) Maximum;\r
+    MinMaxStep.u32.Step     = (UINT32) Step;\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_8:\r
+    MinMaxStep.u64.MinValue = Minimum;\r
+    MinMaxStep.u64.MaxValue = Maximum;\r
+    MinMaxStep.u64.Step     = Step;\r
+    break;\r
+  }\r
+\r
+  CopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA));\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_NUMERIC to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));\r
+  Data->Offset += sizeof (EFI_IFR_NUMERIC);\r
+\r
+  DefaultValue.u64 = Default;\r
+  Status = CreateDefaultOpCode (&DefaultValue, (UINT8) (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  CreateEndOpCode (Data);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create EFI_IFR_STRING_OP opcode.\r
+\r
+  If Data is NULL or Data->Data is NULL, then ASSERT.\r
+\r
+  @param  QuestionId             Question ID\r
+  @param  VarStoreId             Storage ID\r
+  @param  VarOffset              Offset in Storage\r
+  @param  Prompt                 String ID for Prompt\r
+  @param  Help                   String ID for Help\r
+  @param  QuestionFlags          Flags in Question Header\r
+  @param  StringFlags            Flags for string opcode\r
+  @param  MinSize                String minimum length\r
+  @param  MaxSize                String maximum length\r
+  @param  Data                   Destination for the created opcode binary\r
+\r
+  @retval EFI_SUCCESS            Opcode is created successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.\r
+  @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateStringOpCode (\r
+  IN      EFI_QUESTION_ID     QuestionId,\r
+  IN      EFI_VARSTORE_ID     VarStoreId,\r
+  IN      UINT16              VarOffset,\r
+  IN      EFI_STRING_ID       Prompt,\r
+  IN      EFI_STRING_ID       Help,\r
+  IN      UINT8               QuestionFlags,\r
+  IN      UINT8               StringFlags,\r
+  IN      UINT8               MinSize,\r
+  IN      UINT8               MaxSize,\r
+  IN OUT EFI_HII_UPDATE_DATA  *Data\r
+  )\r
+{\r
+  EFI_IFR_STRING              String;\r
+  UINT8                       *LocalBuffer;\r
+\r
+  ASSERT (Data != NULL && Data->Data != NULL);\r
+\r
+  if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & ~EFI_IFR_STRING_MULTI_LINE) != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  String.Header.OpCode                   = EFI_IFR_STRING_OP;\r
+  String.Header.Length                   = sizeof (EFI_IFR_STRING);\r
+  String.Header.Scope                    = 0;\r
+  String.Question.Header.Prompt          = Prompt;\r
+  String.Question.Header.Help            = Help;\r
+  String.Question.QuestionId             = QuestionId;\r
+  String.Question.VarStoreId             = VarStoreId;\r
+  String.Question.VarStoreInfo.VarOffset = VarOffset;\r
+  String.Question.Flags                  = QuestionFlags;\r
+  String.MinSize                         = MinSize;\r
+  String.MaxSize                         = MaxSize;\r
+  String.Flags                           = StringFlags;\r
+\r
+  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;\r
+  //\r
+  // CopyMem is used for EFI_IFR_STRING to cover the unaligned address access.\r
+  //\r
+  CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));\r
+  Data->Offset += sizeof (EFI_IFR_STRING);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r