]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add two new methods to get default value, also add sample code in sample driver.
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 May 2011 02:58:35 +0000 (02:58 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 20 May 2011 02:58:35 +0000 (02:58 +0000)
Add sample code to use time opcode

Signed-off-by: ydong10
Reviewed-by: lgao4
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11688 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h
MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h
MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr
MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni
MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.c

index 947df96b2cb0453bfe7d278c3984cf63539c2787..618aa92dc90abf9935a0f8354abeed193c495343 100644 (file)
@@ -334,6 +334,277 @@ LoadNameValueNames (
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET\r
+  or WIDTH or VALUE.\r
+  <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
+\r
+  This is a internal function.\r
+\r
+  @param  StringPtr              String in <BlockConfig> format and points to the\r
+                                 first character of <Number>.\r
+  @param  Number                 The output value. Caller takes the responsibility\r
+                                 to free memory.\r
+  @param  Len                    Length of the <Number>, in characters.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary\r
+                                 structures.\r
+  @retval EFI_SUCCESS            Value of <Number> is outputted in Number\r
+                                 successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+GetValueOfNumber (\r
+  IN EFI_STRING                    StringPtr,\r
+  OUT UINT8                        **Number,\r
+  OUT UINTN                        *Len\r
+  )\r
+{\r
+  EFI_STRING               TmpPtr;\r
+  UINTN                    Length;\r
+  EFI_STRING               Str;\r
+  UINT8                    *Buf;\r
+  EFI_STATUS               Status;\r
+  UINT8                    DigitUint8;\r
+  UINTN                    Index;\r
+  CHAR16                   TemStr[2];\r
+\r
+  if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Buf = NULL;\r
+\r
+  TmpPtr = StringPtr;\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+  *Len   = StringPtr - TmpPtr;\r
+  Length = *Len + 1;\r
+\r
+  Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (Str == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
+  *(Str + *Len) = L'\0';\r
+\r
+  Length = (Length + 1) / 2;\r
+  Buf = (UINT8 *) AllocateZeroPool (Length);\r
+  if (Buf == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  \r
+  Length = *Len;\r
+  ZeroMem (TemStr, sizeof (TemStr));\r
+  for (Index = 0; Index < Length; Index ++) {\r
+    TemStr[0] = Str[Length - Index - 1];\r
+    DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+    if ((Index & 1) == 0) {\r
+      Buf [Index/2] = DigitUint8;\r
+    } else {\r
+      Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);\r
+    }\r
+  }\r
+\r
+  *Number = Buf;\r
+  Status  = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (Str != NULL) {\r
+    FreePool (Str);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Create altcfg string. \r
+\r
+  @param  Result               The request result string.\r
+  @param  ConfigHdr            The request head info. <ConfigHdr> format.\r
+  @param  Offset               The offset of the parameter int he structure.\r
+  @param  Width                The width of the parameter.\r
+\r
+\r
+  @retval  The string with altcfg info append at the end.\r
+**/\r
+EFI_STRING \r
+CreateAltCfgString (\r
+  IN     EFI_STRING     Result,\r
+  IN     EFI_STRING     ConfigHdr,\r
+  IN     UINTN          Offset,\r
+  IN     UINTN          Width\r
+  )\r
+{\r
+  EFI_STRING StringPtr;\r
+  EFI_STRING TmpStr;\r
+  UINTN      NewLen;\r
+\r
+  NewLen = (((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + StrLen (Result)) * sizeof (CHAR16);\r
+  StringPtr = AllocateZeroPool (NewLen);\r
+  if (StringPtr == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  TmpStr = StringPtr;\r
+  if (Result != NULL) {\r
+    StrCpy (StringPtr, Result);\r
+    StringPtr += StrLen (Result);  \r
+    FreePool (Result);\r
+  }\r
+  \r
+  UnicodeSPrint (\r
+  StringPtr, \r
+  (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+  L"&%s&ALTCFG=%04x", \r
+  ConfigHdr, \r
+  EFI_HII_DEFAULT_CLASS_STANDARD\r
+  );\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  UnicodeSPrint (\r
+    StringPtr, \r
+    (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
+    Offset, \r
+    Width,\r
+    DEFAULT_CLASS_STANDARD_VALUE\r
+    );\r
+  StringPtr += StrLen (StringPtr);  \r
+\r
+  UnicodeSPrint (\r
+  StringPtr, \r
+  (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+  L"&%s&ALTCFG=%04x", \r
+  ConfigHdr, \r
+  EFI_HII_DEFAULT_CLASS_MANUFACTURING\r
+  );\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  UnicodeSPrint (\r
+    StringPtr, \r
+    (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", \r
+    Offset, \r
+    Width,\r
+    DEFAULT_CLASS_MANUFACTURING_VALUE\r
+    );\r
+  StringPtr += StrLen (StringPtr); \r
+\r
+  return TmpStr;\r
+}\r
+\r
+/**\r
+  Check whether need to add the altcfg string. if need to add, add the altcfg \r
+  string.\r
+\r
+  @param  RequestResult              The request result string.\r
+  @param  ConfigRequestHdr           The request head info. <ConfigHdr> format.\r
+\r
+**/\r
+VOID \r
+AppendAltCfgString (\r
+  IN OUT EFI_STRING                       *RequestResult,\r
+  IN     EFI_STRING                       ConfigRequestHdr\r
+  )\r
+{\r
+  EFI_STRING                          StringPtr;\r
+  EFI_STRING                          TmpPtr;\r
+  UINTN                               Length;\r
+  UINT8                               *TmpBuffer;\r
+  UINTN                               Offset;\r
+  UINTN                               Width;\r
+  UINTN                               BlockSize;\r
+  UINTN                               ValueOffset;\r
+  UINTN                               ValueWidth;\r
+  EFI_STATUS                          Status;\r
+\r
+  StringPtr = *RequestResult;\r
+  StringPtr = StrStr (StringPtr, L"OFFSET");\r
+  BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
+  ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);\r
+  ValueWidth  = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);\r
+\r
+  if (StringPtr == NULL) {\r
+    return;\r
+  }\r
+\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {\r
+    //\r
+    // Back up the header of one <BlockName>\r
+    //\r
+    TmpPtr = StringPtr;\r
+\r
+    StringPtr += StrLen (L"OFFSET=");\r
+    //\r
+    // Get Offset\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    Offset = 0;\r
+    CopyMem (\r
+     &Offset,\r
+     TmpBuffer,\r
+     (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
+     );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      return;\r
+    }\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    Width = 0;\r
+    CopyMem (\r
+     &Width,\r
+     TmpBuffer,\r
+     (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
+     );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
+      return;\r
+    }\r
+    StringPtr += StrLen (L"&VALUE=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+    StringPtr += Length;\r
+\r
+    //\r
+    // Calculate Value and convert it to hex string.\r
+    //\r
+    if (Offset + Width > BlockSize) {\r
+      return;\r
+    }\r
+\r
+    if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {\r
+      *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, Offset, Width);\r
+           return;\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   This function allows a caller to extract the current configuration for one\r
   or more named elements from the target driver.\r
@@ -429,6 +700,7 @@ ExtractConfig (
     AllocatedRequest = TRUE;\r
     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
     FreePool (ConfigRequestHdr);\r
+    ConfigRequestHdr = NULL;\r
   } else {\r
     //\r
     // Check routing data in <ConfigHdr>.\r
@@ -557,6 +829,8 @@ ExtractConfig (
                                   Results,\r
                                   Progress\r
                                   );\r
+    ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
+    AppendAltCfgString(Results, ConfigRequestHdr);\r
   }\r
 \r
   //\r
@@ -565,6 +839,10 @@ ExtractConfig (
   if (AllocatedRequest) {\r
     FreePool (ConfigRequest);\r
   }\r
+\r
+  if (ConfigRequestHdr != NULL) {\r
+    FreePool (ConfigRequestHdr);\r
+  }\r
   //\r
   // Set Progress string to the original request string.\r
   //\r
@@ -939,6 +1217,34 @@ DriverCallback (
     }\r
     break;\r
 \r
+  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:\r
+    {\r
+      switch (QuestionId) {\r
+      case 0x1240:\r
+        Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;\r
+      break;\r
+\r
+      default:\r
+        Status = EFI_UNSUPPORTED;\r
+      break;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:\r
+    {\r
+      switch (QuestionId) {\r
+      case 0x1240:\r
+        Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;\r
+      break;\r
+\r
+      default:\r
+        Status = EFI_UNSUPPORTED;      \r
+      break;\r
+      }\r
+    }\r
+    break;\r
+\r
   case EFI_BROWSER_ACTION_CHANGING:\r
   {\r
     switch (QuestionId) {\r
index 728c44abcee7c294f9b191f1657e89936e4ea1f5..a6445664df39975985f983e984c5d8f574474e87 100644 (file)
@@ -65,6 +65,9 @@ extern UINT8  DriverSampleStrings[];
 #define DYNAMIC_ONE_OF_VAR_OFFSET        OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, DynamicOneof)\r
 #define DYNAMIC_ORDERED_LIST_VAR_OFFSET  OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, DynamicOrderedList)\r
 \r
+#define DEFAULT_CLASS_MANUFACTURING_VALUE     0xFF\r
+#define DEFAULT_CLASS_STANDARD_VALUE          0x0\r
+\r
 //\r
 // Number of name in Name/Value storage\r
 //\r
index cf71dfce39f8d234b9c522529b78d58a3a2ef480..8926ab017789c661fed63248372f868d19a17c9b 100644 (file)
@@ -74,6 +74,9 @@ typedef struct {
   UINT8   SerialPortStatus;\r
   UINT16  SerialPortIo;\r
   UINT8   SerialPortIrq;\r
+  UINT8   GetDefaultValueFromCallBack;\r
+  UINT8   GetDefaultValueFromAccess;\r
+  EFI_HII_TIME  Time;\r
 } DRIVER_SAMPLE_CONFIGURATION;\r
 \r
 //\r
index 00982700b7b03f2585852eada595587cf90aa26b..fce22fef2fcfdc8234664aed79992b2fd0eb213a 100644 (file)
@@ -385,6 +385,28 @@ formset
         \r
       endnumeric;\r
     endif;\r
+\r
+    numeric varid   = MyIfrNVData.GetDefaultValueFromAccess,\r
+            questionid = 0x1239,\r
+            prompt  = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_ACCESS_PROMPT),\r
+            help    = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_ACCESS_HELP),\r
+            flags   = DISPLAY_UINT_HEX | INTERACTIVE, \r
+            minimum = 0,\r
+            maximum = 255,\r
+            step    = 1,\r
+            default = 18,\r
+    endnumeric;\r
+\r
+    numeric varid   = MyIfrNVData.GetDefaultValueFromCallBack,\r
+            questionid = 0x1240,\r
+            prompt  = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_PROMPT),\r
+            help    = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_HELP),\r
+            flags   = DISPLAY_UINT_HEX | INTERACTIVE, \r
+            minimum = 0,\r
+            maximum = 255,\r
+            step    = 1,\r
+            default = 18,\r
+    endnumeric;\r
         \r
     resetbutton\r
       defaultstore = MyStandardDefault,\r
@@ -533,7 +555,16 @@ formset
               default       = 0,\r
 \r
       endtime;\r
-\r
+      \r
+      time \r
+            name    = MyTime, \r
+            varid   = MyIfrNVData.Time, \r
+            prompt  = STRING_TOKEN(STR_TIME_PROMPT), \r
+            help    = STRING_TOKEN(STR_TIME_PROMPT), \r
+            flags   = STORAGE_NORMAL, \r
+            default = 15:33:33, \r
+      endtime;\r
+      \r
       checkbox varid   = MyIfrNVData.ChooseToActivateNuclearWeaponry,\r
               prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),\r
               help     = STRING_TOKEN(STR_CHECK_BOX_HELP),\r
index 5b65a1bc1b4af22facac7f96f3efe583e7e815a7..1901fd8d2e010d9d43e4c7a31b59b9f261503551 100644 (file)
Binary files a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni and b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ
index ca766a24bc1fb1dd335724f7fb3fb8d260bde80e..8dc1651950745245d6a7cd2aee8828fd4975f07d 100644 (file)
@@ -1027,6 +1027,11 @@ SetupBrowser (
           default:\r
             break;\r
           }\r
+        } else if (Status == EFI_UNSUPPORTED) {\r
+          //\r
+          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
+          //\r
+          Status = EFI_SUCCESS;\r
         }\r
       }\r
       if (SubmitFormIsRequired) {\r
@@ -1151,6 +1156,11 @@ SetupBrowser (
             Selection->FormId = Selection->Form->FormId;\r
             Selection->QuestionId = 0;\r
           }\r
+        } else {\r
+          //\r
+          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
+          //\r
+          Status = EFI_SUCCESS;\r
         }\r
       }\r
 \r
@@ -1216,6 +1226,11 @@ SetupBrowser (
           default:\r
             break;\r
           }\r
+        } else if (Status == EFI_UNSUPPORTED) {\r
+          //\r
+          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
+          //\r
+          Status = EFI_SUCCESS;\r
         }\r
       }\r
       if (SubmitFormIsRequired) {\r
index ea98d46db9c5f30f5dd1723cfb1698cba8361d37..67a4aeb7ecc7097fc5bb382fb9b2df88390f0e80 100644 (file)
@@ -1804,6 +1804,221 @@ SubmitForm (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Get Question default value from AltCfg string.\r
+\r
+  @param  FormSet                The form set.\r
+  @param  Question               The question.\r
+  @param  DefaultId              The default Id.\r
+\r
+  @retval EFI_SUCCESS            Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetDefaultValueFromAltCfg (\r
+  IN     FORM_BROWSER_FORMSET             *FormSet,\r
+  IN OUT FORM_BROWSER_STATEMENT           *Question,\r
+  IN     UINT16                           DefaultId\r
+  )\r
+{\r
+  BOOLEAN             IsBufferStorage;\r
+  BOOLEAN             IsString;  \r
+  UINTN               Length;\r
+  FORMSET_STORAGE     *Storage;\r
+  CHAR16              *ConfigRequest;\r
+  CHAR16              *Progress;\r
+  CHAR16              *Result;\r
+  CHAR16              *ConfigResp;\r
+  CHAR16              *Value;\r
+  CHAR16              *StringPtr;\r
+  UINTN               LengthStr;\r
+  UINT8               *Dst;\r
+  CHAR16              TemStr[5];\r
+  UINTN               Index;\r
+  UINT8               DigitUint8;\r
+  EFI_STATUS          Status;\r
+\r
+  Status        = EFI_NOT_FOUND;\r
+  Length        = 0;\r
+  Dst           = NULL;\r
+  ConfigRequest = NULL;\r
+  Result        = NULL;\r
+  ConfigResp    = NULL;\r
+  Storage       = Question->Storage;\r
+\r
+  if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Question Value is provided by Buffer Storage or NameValue Storage\r
+  //\r
+  if (Question->BufferValue != NULL) {\r
+    //\r
+    // This Question is password or orderedlist\r
+    //\r
+    Dst = Question->BufferValue;\r
+  } else {\r
+    //\r
+    // Other type of Questions\r
+    //\r
+    Dst = (UINT8 *) &Question->HiiValue.Value;\r
+  }\r
+\r
+  IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\r
+  IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ?  TRUE : FALSE);\r
+\r
+  //\r
+  // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
+  //                   <ConfigHdr> + "&" + <VariableName>\r
+  //\r
+  if (IsBufferStorage) {\r
+    Length  = StrLen (Storage->ConfigHdr);\r
+    Length += StrLen (Question->BlockName);\r
+  } else {\r
+    Length  = StrLen (Storage->ConfigHdr);\r
+    Length += StrLen (Question->VariableName) + 1;\r
+  }\r
+  ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
+  ASSERT (ConfigRequest != NULL);\r
+\r
+  StrCpy (ConfigRequest, Storage->ConfigHdr);\r
+  if (IsBufferStorage) {\r
+    StrCat (ConfigRequest, Question->BlockName);\r
+  } else {\r
+    StrCat (ConfigRequest, L"&");\r
+    StrCat (ConfigRequest, Question->VariableName);\r
+  }\r
+\r
+  Status = FormSet->ConfigAccess->ExtractConfig (\r
+                                    FormSet->ConfigAccess,\r
+                                    ConfigRequest,\r
+                                    &Progress,\r
+                                    &Result\r
+                                    );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+  //    Get the default configuration string according to the default ID.\r
+  //\r
+  Status = mHiiConfigRouting->GetAltConfig (\r
+                                mHiiConfigRouting,\r
+                                Result,\r
+                                &Storage->Guid,\r
+                                Storage->Name,\r
+                                NULL,\r
+                                &DefaultId,  // it can be NULL to get the current setting.\r
+                                &ConfigResp\r
+                              );\r
+  \r
+  //\r
+  // The required setting can't be found. So, it is not required to be validated and set.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Skip <ConfigRequest>\r
+  //\r
+  Value = StrStr (ConfigResp, L"&VALUE");\r
+  if (IsBufferStorage) {\r
+    //\r
+    // Skip "&VALUE"\r
+    //\r
+    Value = Value + 6;\r
+  }\r
+  if (*Value != '=') {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
+  }\r
+  //\r
+  // Skip '=', point to value\r
+  //\r
+  Value = Value + 1;\r
+\r
+  //\r
+  // Suppress <AltResp> if any\r
+  //\r
+  StringPtr = Value;\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+  *StringPtr = L'\0';\r
+\r
+  LengthStr = StrLen (Value);\r
+  if (!IsBufferStorage && IsString) {\r
+    StringPtr = (CHAR16 *) Dst;\r
+    ZeroMem (TemStr, sizeof (TemStr));\r
+    for (Index = 0; Index < LengthStr; Index += 4) {\r
+      StrnCpy (TemStr, Value + Index, 4);\r
+      StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+    }\r
+    //\r
+    // Add tailing L'\0' character\r
+    //\r
+    StringPtr[Index/4] = L'\0';\r
+  } else {\r
+    ZeroMem (TemStr, sizeof (TemStr));\r
+    for (Index = 0; Index < LengthStr; Index ++) {\r
+      TemStr[0] = Value[LengthStr - Index - 1];\r
+      DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+      if ((Index & 1) == 0) {\r
+        Dst [Index/2] = DigitUint8;\r
+      } else {\r
+        Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+      }\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (ConfigRequest != NULL){\r
+    FreePool (ConfigRequest);\r
+  }\r
+\r
+  if (ConfigResp != NULL) {\r
+    FreePool (ConfigResp);\r
+  }\r
+  \r
+  if (Result != NULL) {\r
+    FreePool (Result);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get default Id value used for browser.\r
+\r
+  @param  DefaultId              The default id value used by hii.\r
+\r
+  @retval Browser used default value.\r
+\r
+**/\r
+INTN\r
+GetDefaultIdForCallBack (\r
+  UINTN DefaultId\r
+  )\r
+{ \r
+  if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
+  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
+  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
+  } else {\r
+    return -1;\r
+  }\r
+}\r
 \r
 /**\r
   Reset Question to its default value.\r
@@ -1831,6 +2046,9 @@ GetQuestionDefault (
   EFI_HII_VALUE           *HiiValue;\r
   UINT8                   Index;\r
   EFI_STRING              StrValue;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
+  INTN                            Action;\r
 \r
   Status   = EFI_SUCCESS;\r
   StrValue = NULL;\r
@@ -1843,13 +2061,45 @@ GetQuestionDefault (
   }\r
 \r
   //\r
-  // There are three ways to specify default value for a Question:\r
-  //  1, use nested EFI_IFR_DEFAULT (highest priority)\r
-  //  2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
-  //  3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
+  // There are Five ways to specify default value for a Question:\r
+  //  1, use call back function (highest priority)\r
+  //  2, use ExtractConfig function\r
+  //  3, use nested EFI_IFR_DEFAULT \r
+  //  4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
+  //  5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
   //\r
   HiiValue = &Question->HiiValue;\r
 \r
+  //\r
+  // Get Question defaut value from call back function.\r
+  //\r
+  ConfigAccess = FormSet->ConfigAccess;\r
+  Action = GetDefaultIdForCallBack (DefaultId);\r
+  if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
+    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+    Status = ConfigAccess->Callback (\r
+                             ConfigAccess,\r
+                             Action,\r
+                             Question->QuestionId,\r
+                             HiiValue->Type,\r
+                             &HiiValue->Value,\r
+                             &ActionRequest\r
+                             );\r
+    if (!EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get default value from altcfg string.\r
+  //\r
+  if (ConfigAccess != NULL) {  \r
+    Status = GetDefaultValueFromAltCfg(FormSet, Question, DefaultId);\r
+    if (!EFI_ERROR (Status)) {\r
+        return Status;\r
+    }\r
+  }\r
+\r
   //\r
   // EFI_IFR_DEFAULT has highest priority\r
   //\r