/** @file
  Implementation of HII utility library.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiInternal.h"

/**
  Initialize the internal data structure of a FormSet.

  @param  Handle                 PackageList Handle
  @param  FormSetGuid            On input, GUID or class GUID of a formset. If not
                                 specified (NULL or zero GUID), take the first
                                 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
                                 found in package list.
                                 On output, GUID of the formset found(if not NULL).
  @param  FormSet                FormSet data structure.

  @retval EFI_SUCCESS            The function completed successfully.
  @retval EFI_NOT_FOUND          The specified FormSet could not be found.

**/
EFI_STATUS
CreateFormSetFromHiiHandle (
  IN     EFI_HII_HANDLE  Handle,
  IN OUT EFI_GUID        *FormSetGuid,
  OUT HII_FORMSET        *FormSet
  )
{
  EFI_STATUS                 Status;
  EFI_HANDLE                 DriverHandle;
  EFI_HII_DATABASE_PROTOCOL  *HiiDatabase;

  if ((FormSetGuid == NULL) || (FormSet == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate required Hii Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&HiiDatabase
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FormSet->Signature = HII_FORMSET_SIGNATURE;
  FormSet->HiiHandle = Handle;
  CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
  //
  // Retrieve ConfigAccess Protocol associated with this HiiPackageList
  //
  Status = HiiDatabase->GetPackageListHandle (HiiDatabase, Handle, &DriverHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FormSet->DriverHandle = DriverHandle;
  Status                = gBS->HandleProtocol (
                                 DriverHandle,
                                 &gEfiHiiConfigAccessProtocolGuid,
                                 (VOID **)&FormSet->ConfigAccess
                                 );
  if (EFI_ERROR (Status)) {
    //
    // Configuration Driver don't attach ConfigAccess protocol to its HII package
    // list, then there will be no configuration action required
    //
    FormSet->ConfigAccess = NULL;
  }

  Status = gBS->HandleProtocol (
                  DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&FormSet->DevicePath
                  );
  if (EFI_ERROR (Status)) {
    //
    // Configuration Driver don't attach ConfigAccess protocol to its HII package
    // list, then there will be no configuration action required
    //
    FormSet->DevicePath = NULL;
  }

  //
  // Parse the IFR binary OpCodes
  //
  Status = ParseOpCodes (FormSet);

  return Status;
}

/**
  Initialize a Formset and get current setting for Questions.

  @param  FormSet                FormSet data structure.

**/
VOID
InitializeFormSet (
  IN OUT HII_FORMSET  *FormSet
  )
{
  LIST_ENTRY           *Link;
  HII_FORMSET_STORAGE  *Storage;
  LIST_ENTRY           *FormLink;
  HII_STATEMENT        *Question;
  HII_FORM             *Form;

  if (FormSet == NULL) {
    return;
  }

  //
  // Load Storage for all questions with storage
  //
  Link = GetFirstNode (&FormSet->StorageListHead);
  while (!IsNull (&FormSet->StorageListHead, Link)) {
    Storage = HII_STORAGE_FROM_LINK (Link);
    LoadFormSetStorage (FormSet, Storage);
    Link = GetNextNode (&FormSet->StorageListHead, Link);
  }

  //
  // Get Current Value for all no storage questions
  //
  FormLink = GetFirstNode (&FormSet->FormListHead);
  while (!IsNull (&FormSet->FormListHead, FormLink)) {
    Form = HII_FORM_FROM_LINK (FormLink);
    Link = GetFirstNode (&Form->StatementListHead);
    while (!IsNull (&Form->StatementListHead, Link)) {
      Question = HII_STATEMENT_FROM_LINK (Link);
      if (Question->Storage == NULL) {
        RetrieveQuestion (FormSet, Form, Question);
      }

      Link = GetNextNode (&Form->StatementListHead, Link);
    }

    FormLink = GetNextNode (&FormSet->FormListHead, FormLink);
  }
}

/**
  Free resources allocated for a FormSet.

  @param[in,out]  FormSet                Pointer of the FormSet

**/
VOID
DestroyFormSet (
  IN OUT HII_FORMSET  *FormSet
  )
{
  LIST_ENTRY                *Link;
  HII_FORMSET_STORAGE       *Storage;
  HII_FORMSET_DEFAULTSTORE  *DefaultStore;
  HII_FORM                  *Form;

  if (FormSet->IfrBinaryData == NULL) {
    //
    // Uninitialized FormSet
    //
    FreePool (FormSet);
    return;
  }

  //
  // Free IFR binary buffer
  //
  FreePool (FormSet->IfrBinaryData);

  //
  // Free FormSet Storage
  //
  if (FormSet->StorageListHead.ForwardLink != NULL) {
    while (!IsListEmpty (&FormSet->StorageListHead)) {
      Link    = GetFirstNode (&FormSet->StorageListHead);
      Storage = HII_STORAGE_FROM_LINK (Link);
      RemoveEntryList (&Storage->Link);

      if (Storage != NULL) {
        FreePool (Storage);
      }
    }
  }

  //
  // Free FormSet Default Store
  //
  if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
    while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
      Link         = GetFirstNode (&FormSet->DefaultStoreListHead);
      DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (Link);
      RemoveEntryList (&DefaultStore->Link);

      FreePool (DefaultStore);
    }
  }

  //
  // Free Forms
  //
  if (FormSet->FormListHead.ForwardLink != NULL) {
    while (!IsListEmpty (&FormSet->FormListHead)) {
      Link = GetFirstNode (&FormSet->FormListHead);
      Form = HII_FORM_FROM_LINK (Link);
      RemoveEntryList (&Form->Link);

      DestroyForm (FormSet, Form);
    }
  }

  FreePool (FormSet);
}

/**
  Submit data for a form.

  @param[in]  FormSet                FormSet which contains the Form.
  @param[in]  Form                   Form to submit.

  @retval EFI_SUCCESS            The function completed successfully.
  @retval Others                 Other errors occur.

**/
EFI_STATUS
SubmitForm (
  IN HII_FORMSET  *FormSet,
  IN HII_FORM     *Form
  )
{
  EFI_STATUS                       Status;
  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
  LIST_ENTRY                       *Link;
  EFI_STRING                       ConfigResp;
  EFI_STRING                       Progress;
  HII_FORMSET_STORAGE              *Storage;
  HII_FORM_CONFIG_REQUEST          *ConfigInfo;

  if ((FormSet == NULL) || (Form == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = NoSubmitCheck (FormSet, &Form, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Link = GetFirstNode (&Form->ConfigRequestHead);
  while (!IsNull (&Form->ConfigRequestHead, Link)) {
    ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link);
    Link       = GetNextNode (&Form->ConfigRequestHead, Link);

    Storage = ConfigInfo->Storage;
    if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
      continue;
    }

    //
    // Skip if there is no RequestElement
    //
    if (ConfigInfo->ElementCount == 0) {
      continue;
    }

    Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gBS->LocateProtocol (
                    &gEfiHiiConfigRoutingProtocolGuid,
                    NULL,
                    (VOID **)&HiiConfigRouting
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = HiiConfigRouting->RouteConfig (
                                 HiiConfigRouting,
                                 ConfigResp,
                                 &Progress
                                 );

    if (EFI_ERROR (Status)) {
      FreePool (ConfigResp);
      continue;
    }

    FreePool (ConfigResp);
  }

  return Status;
}

/**
  Save Question Value to the memory, but not to storage.

  @param[in]     FormSet                FormSet data structure.
  @param[in]     Form                   Form data structure.
  @param[in,out] Question               Pointer to the Question.
  @param[in]     QuestionValue          New Question Value to be set.

  @retval EFI_SUCCESS            The question value has been set successfully.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.

**/
EFI_STATUS
SetQuestionValue (
  IN     HII_FORMSET          *FormSet,
  IN     HII_FORM             *Form,
  IN OUT HII_STATEMENT        *Question,
  IN     HII_STATEMENT_VALUE  *QuestionValue
  )
{
  UINT8                *Src;
  UINTN                BufferLen;
  UINTN                StorageWidth;
  HII_FORMSET_STORAGE  *Storage;
  CHAR16               *ValueStr;
  BOOLEAN              IsBufferStorage;
  UINT8                *TemBuffer;
  CHAR16               *TemName;
  CHAR16               *TemString;
  UINTN                Index;
  HII_NAME_VALUE_NODE  *Node;
  EFI_STATUS           Status;

  if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) || (QuestionValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_SUCCESS;
  Node   = NULL;

  //
  // If Question value is provided by an Expression, then it is read only
  //
  if ((Question->ValueExpression != NULL) || (Question->Value.Type != QuestionValue->Type)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Before set question value, evaluate its write expression.
  //
  if ((Question->WriteExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {
    Status = EvaluateHiiExpression (FormSet, Form, Question->WriteExpression);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  Storage = Question->Storage;
  if (Storage != NULL) {
    StorageWidth = Question->StorageWidth;
    if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
      Question->Value.BufferLen = QuestionValue->BufferLen;
      Question->Value.Buffer    = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
      if (Question->Value.Buffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      Question->Value.BufferValueType = QuestionValue->BufferValueType;
      Src                             = Question->Value.Buffer;
    } else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
      Question->Value.Value.string = QuestionValue->Value.string;
      TemString                    = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
      if (TemString == NULL) {
        return EFI_ABORTED;
      }

      Question->Value.BufferLen = Question->StorageWidth;
      Question->Value.Buffer    = AllocateZeroPool (Question->StorageWidth);
      if (Question->Value.Buffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
      Src = Question->Value.Buffer;
    } else {
      CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
      Src = (UINT8 *)&Question->Value.Value;
    }

    if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
      IsBufferStorage = TRUE;
    } else {
      IsBufferStorage = FALSE;
    }

    if (IsBufferStorage) {
      //
      // If the Question refer to bit filed, copy the value in related bit filed to storage edit buffer.
      //
      if (Question->QuestionReferToBitField) {
        SetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));
      } else {
        CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
      }
    } else {
      if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
        //
        // Allocate enough string buffer.
        //
        ValueStr  = NULL;
        BufferLen = ((StrLen ((CHAR16 *)Src) * 4) + 1) * sizeof (CHAR16);
        ValueStr  = AllocatePool (BufferLen);
        if (ValueStr == NULL) {
          if (Question->Value.Buffer != NULL) {
            FreePool (Question->Value.Buffer);
          }

          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
        //
        TemName   = (CHAR16 *)Src;
        TemString = ValueStr;
        for ( ; *TemName != L'\0'; TemName++) {
          UnicodeValueToStringS (
            TemString,
            BufferLen - ((UINTN)TemString - (UINTN)ValueStr),
            PREFIX_ZERO | RADIX_HEX,
            *TemName,
            4
            );
          TemString += StrnLenS (TemString, (BufferLen - ((UINTN)TemString - (UINTN)ValueStr)) / sizeof (CHAR16));
        }
      } else {
        BufferLen = StorageWidth * 2 + 1;
        ValueStr  = AllocateZeroPool (BufferLen * sizeof (CHAR16));
        if (ValueStr == NULL) {
          if (Question->Value.Buffer != NULL) {
            FreePool (Question->Value.Buffer);
          }

          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Convert Buffer to Hex String
        //
        TemBuffer = Src + StorageWidth - 1;
        TemString = ValueStr;
        for (Index = 0; Index < StorageWidth; Index++, TemBuffer--) {
          UnicodeValueToStringS (
            TemString,
            BufferLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),
            PREFIX_ZERO | RADIX_HEX,
            *TemBuffer,
            2
            );
          TemString += StrnLenS (TemString, BufferLen - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));
        }
      }

      Status = SetValueByName (Storage, Question->VariableName, ValueStr, &Node);
      FreePool (ValueStr);
      if (EFI_ERROR (Status)) {
        if (Question->Value.Buffer != NULL) {
          FreePool (Question->Value.Buffer);
        }

        return Status;
      }
    }
  } else {
    if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
      Question->Value.BufferLen = QuestionValue->BufferLen;
      Question->Value.Buffer    = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
      if (Question->Value.Buffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      Question->Value.BufferValueType = QuestionValue->BufferValueType;
    } else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
      Question->Value.Value.string = QuestionValue->Value.string;
      TemString                    = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
      if (TemString == NULL) {
        return EFI_ABORTED;
      }

      Question->Value.BufferLen = (UINT16)StrSize (TemString);
      Question->Value.Buffer    = AllocateZeroPool (QuestionValue->BufferLen);
      if (Question->Value.Buffer == NULL) {
        FreePool (TemString);
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
      FreePool (TemString);
    } else {
      CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
    }
  }

  return Status;
}

/**
  Get Question's current Value from storage.

  @param[in]     FormSet                FormSet data structure.
  @param[in]     Form                   Form data structure.
  @param[in,out] Question               Question to be initialized.

  @return the current Question Value in storage if success.
  @return NULL if Question is not found or any error occurs.

**/
HII_STATEMENT_VALUE *
RetrieveQuestion (
  IN     HII_FORMSET    *FormSet,
  IN     HII_FORM       *Form,
  IN OUT HII_STATEMENT  *Question
  )
{
  EFI_STATUS                       Status;
  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
  EFI_BROWSER_ACTION_REQUEST       ActionRequest;
  HII_FORMSET_STORAGE              *Storage;
  HII_STATEMENT_VALUE              *QuestionValue;
  EFI_IFR_TYPE_VALUE               *TypeValue;
  EFI_TIME                         EfiTime;
  BOOLEAN                          Enabled;
  BOOLEAN                          Pending;
  UINT8                            *Dst;
  UINTN                            StorageWidth;
  CHAR16                           *ConfigRequest;
  CHAR16                           *Progress;
  CHAR16                           *Result;
  CHAR16                           *ValueStr;
  UINTN                            Length;
  BOOLEAN                          IsBufferStorage;
  CHAR16                           *NewHiiString;

  if ((FormSet == NULL) || (Form == NULL) || (Question == NULL)) {
    return NULL;
  }

  Status   = EFI_SUCCESS;
  ValueStr = NULL;
  Result   = NULL;

  QuestionValue = AllocateZeroPool (sizeof (HII_STATEMENT_VALUE));
  if (QuestionValue == NULL) {
    return NULL;
  }

  QuestionValue->Type      = Question->Value.Type;
  QuestionValue->BufferLen = Question->Value.BufferLen;
  if (QuestionValue->BufferLen != 0) {
    QuestionValue->Buffer = AllocateZeroPool (QuestionValue->BufferLen);
    if (QuestionValue->Buffer == NULL) {
      FreePool (QuestionValue);
      return NULL;
    }
  }

  //
  // Question value is provided by RTC
  //
  Storage      = Question->Storage;
  StorageWidth = Question->StorageWidth;

  if (Storage == NULL) {
    //
    // It's a Question without storage, or RTC date/time
    //
    if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
      //
      // Date and time define the same Flags bit
      //
      switch (Question->ExtraData.Flags & EFI_QF_DATE_STORAGE) {
        case QF_DATE_STORAGE_TIME:

          Status = gRT->GetTime (&EfiTime, NULL);
          break;

        case QF_DATE_STORAGE_WAKEUP:

          Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);
          break;

        case QF_DATE_STORAGE_NORMAL:
        default:

          goto ON_ERROR;
      }

      if (EFI_ERROR (Status)) {
        if (Question->Operand == EFI_IFR_DATE_OP) {
          QuestionValue->Value.date.Year  = 0xff;
          QuestionValue->Value.date.Month = 0xff;
          QuestionValue->Value.date.Day   = 0xff;
        } else {
          QuestionValue->Value.time.Hour   = 0xff;
          QuestionValue->Value.time.Minute = 0xff;
          QuestionValue->Value.time.Second = 0xff;
        }

        return QuestionValue;
      }

      if (Question->Operand == EFI_IFR_DATE_OP) {
        QuestionValue->Value.date.Year  = EfiTime.Year;
        QuestionValue->Value.date.Month = EfiTime.Month;
        QuestionValue->Value.date.Day   = EfiTime.Day;
      } else {
        QuestionValue->Value.time.Hour   = EfiTime.Hour;
        QuestionValue->Value.time.Minute = EfiTime.Minute;
        QuestionValue->Value.time.Second = EfiTime.Second;
      }
    } else {
      if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) ||
          (FormSet->ConfigAccess == NULL))
      {
        goto ON_ERROR;
      }

      if (QuestionValue->Type == EFI_IFR_TYPE_BUFFER) {
        //
        // For OrderedList, passing in the value buffer to Callback()
        //
        TypeValue = (EFI_IFR_TYPE_VALUE *)QuestionValue->Buffer;
      } else {
        TypeValue = &QuestionValue->Value;
      }

      ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
      Status        = FormSet->ConfigAccess->Callback (
                                               FormSet->ConfigAccess,
                                               EFI_BROWSER_ACTION_RETRIEVE,
                                               Question->QuestionId,
                                               QuestionValue->Type,
                                               TypeValue,
                                               &ActionRequest
                                               );

      if (!EFI_ERROR (Status) && (QuestionValue->Type == EFI_IFR_TYPE_STRING)) {
        if (TypeValue->string == 0) {
          goto ON_ERROR;
        }

        NewHiiString = GetTokenString (TypeValue->string, FormSet->HiiHandle);
        if (NewHiiString == NULL) {
          goto ON_ERROR;
        }

        QuestionValue->Buffer = AllocatePool (StrSize (NewHiiString));
        if (QuestionValue->Buffer == NULL) {
          FreePool (NewHiiString);
          goto ON_ERROR;
        }

        CopyMem (QuestionValue->Buffer, NewHiiString, StrSize (NewHiiString));
        QuestionValue->BufferLen = (UINT16)StrSize (NewHiiString);

        FreePool (NewHiiString);
      }
    }

    return QuestionValue;
  }

  //
  // Question value is provided by EFI variable
  //
  if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
    if ((QuestionValue->Type != EFI_IFR_TYPE_BUFFER) && (QuestionValue->Type != EFI_IFR_TYPE_STRING)) {
      Dst          = QuestionValue->Buffer;
      StorageWidth = QuestionValue->BufferLen;
    } else {
      Dst          = (UINT8 *)&QuestionValue->Value;
      StorageWidth = sizeof (EFI_IFR_TYPE_VALUE);
    }

    Status = gRT->GetVariable (
                    Question->VariableName,
                    &Storage->Guid,
                    NULL,
                    &StorageWidth,
                    Dst
                    );

    return QuestionValue;
  }

  Status = gBS->LocateProtocol (
                  &gEfiHiiConfigRoutingProtocolGuid,
                  NULL,
                  (VOID **)&HiiConfigRouting
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  if (QuestionValue->BufferLen != 0) {
    Dst = QuestionValue->Buffer;
  } else {
    Dst = (UINT8 *)&QuestionValue->Value;
  }

  if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
    IsBufferStorage = TRUE;
  } else {
    IsBufferStorage = FALSE;
  }

  Storage = GetFstStgFromVarId (FormSet, Question->VarStoreId);
  if (Storage == NULL) {
    goto ON_ERROR;
  }

  //
  // <ConfigRequest> ::= <ConfigHdr> + <BlockName> || <ConfigHdr> + "&" + <VariableName>
  //
  if (IsBufferStorage) {
    Length  = StrLen (Storage->ConfigHdr);
    Length += StrLen (Question->BlockName);
  } else {
    Length  = StrLen (Storage->ConfigHdr);
    Length += StrLen (Question->VariableName) + 1;
  }

  ConfigRequest = AllocatePool ((Length + 1) * sizeof (CHAR16));
  if (ConfigRequest == NULL) {
    goto ON_ERROR;
  }

  StrCpyS (ConfigRequest, Length + 1, Storage->ConfigHdr);
  if (IsBufferStorage) {
    StrCatS (ConfigRequest, Length + 1, Question->BlockName);
  } else {
    StrCatS (ConfigRequest, Length + 1, L"&");
    StrCatS (ConfigRequest, Length + 1, Question->VariableName);
  }

  //
  // Request current settings from Configuration Driver
  //
  Status = HiiConfigRouting->ExtractConfig (
                               HiiConfigRouting,
                               ConfigRequest,
                               &Progress,
                               &Result
                               );
  FreePool (ConfigRequest);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  if (IsBufferStorage) {
    ValueStr = StrStr (Result, L"&VALUE");
    if (ValueStr == NULL) {
      FreePool (Result);
      goto ON_ERROR;
    }

    ValueStr = ValueStr + 6;
  } else {
    ValueStr = Result + Length;
  }

  if (*ValueStr != '=') {
    FreePool (Result);
    goto ON_ERROR;
  }

  ValueStr++;
  Status = BufferToQuestionValue (Question, ValueStr, QuestionValue);
  if (EFI_ERROR (Status)) {
    FreePool (Result);
    goto ON_ERROR;
  }

  if (Result != NULL) {
    FreePool (Result);
  }

  return QuestionValue;

ON_ERROR:

  if (QuestionValue->Buffer != NULL) {
    FreePool (QuestionValue->Buffer);
  }

  FreePool (QuestionValue);

  return NULL;
}
