+/**\r
+ Update names of Name/Value storage to current language.\r
+\r
+ @param PrivateData Points to the driver private data.\r
+\r
+ @retval EFI_SUCCESS All names are successfully updated.\r
+ @retval EFI_NOT_FOUND Failed to get Name from HII database.\r
+\r
+**/\r
+EFI_STATUS\r
+LoadNameValueNames (\r
+ IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ //\r
+ // Get Name/Value name string of current language\r
+ //\r
+ for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
+ PrivateData->NameValueName[Index] = HiiGetString (\r
+ PrivateData->HiiHandle[0],\r
+ PrivateData->NameStringId[Index],\r
+ NULL\r
+ );\r
+ if (PrivateData->NameValueName[Index] == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ 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 = StrLen (Result);\r
+ //\r
+ // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")\r
+ //\r
+ NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * 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
+ 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
+ TmpBuffer = NULL;\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
+ 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 Value\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, ValueOffset, ValueWidth);\r
+ return;\r
+ }\r
+ }\r
+}\r