summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-11-04 14:22:22 +0000
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-11-04 14:22:22 +0000
commit9185c388a9e992bcbcf38d10fb24321a60950562 (patch)
tree7ed8afde7326a109830a70dfbda14ef65114d62f
parentba954c772d62950d412d6e0e893be8f0615b9f57 (diff)
downloadedk2-9185c388a9e992bcbcf38d10fb24321a60950562.zip
edk2-9185c388a9e992bcbcf38d10fb24321a60950562.tar.gz
edk2-9185c388a9e992bcbcf38d10fb24321a60950562.tar.bz2
Sync in bug fix from EDK I:
1) issue with setup browser and IFR refresh opcode 2) [HII]HIIConfigRoutingExportConfig generate error format of <MultiConfigAltResp> 3) [HII] ConfigRouting->ExtractConfig() will cause overflow 4) [Hii Database] EFI_HII_DATABASE_NOTIFY should be invoked when a string package is created internally when a new String Token is created 5) [PT]HIIConfigAccessProtocolTest fail on NT32uefi 6) Incorrect HII package types in EDK git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6377 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdePkg/Include/Library/IfrSupportLib.h60
-rw-r--r--MdePkg/Include/Uefi/UefiInternalFormRepresentation.h4
-rw-r--r--MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c457
3 files changed, 516 insertions, 5 deletions
diff --git a/MdePkg/Include/Library/IfrSupportLib.h b/MdePkg/Include/Library/IfrSupportLib.h
index 2904cb2..3f686bd 100644
--- a/MdePkg/Include/Library/IfrSupportLib.h
+++ b/MdePkg/Include/Library/IfrSupportLib.h
@@ -434,6 +434,47 @@ CreateStringOpCode (
IN OUT EFI_HII_UPDATE_DATA *Data
)
;
+/**
+ Construct <ConfigAltResp> for a buffer storage.
+
+ @param ConfigRequest The Config request string. If set to NULL, all the
+ configurable elements will be extracted from BlockNameArray.
+ @param ConfigAltResp The returned <ConfigAltResp>.
+ @param Progress On return, points to a character in the Request.
+ @param Guid GUID of the buffer storage.
+ @param Name Name of the buffer storage.
+ @param DriverHandle The DriverHandle which is used to invoke HiiDatabase
+ protocol interface NewPackageList().
+ @param BufferStorage Content of the buffer storage.
+ @param BufferStorageSize Length in bytes of the buffer storage.
+ @param BlockNameArray Array generated by VFR compiler.
+ @param NumberAltCfg Number of Default value array generated by VFR compiler.
+ The sequential input parameters will be number of
+ AltCfgId and DefaultValueArray pairs. When set to 0,
+ there will be no <AltResp>.
+
+ retval EFI_OUT_OF_RESOURCES Run out of memory resource.
+ retval EFI_INVALID_PARAMETER ConfigAltResp is NULL.
+ retval EFI_SUCCESS Operation successful.
+
+**/
+EFI_STATUS
+ConstructConfigAltResp (
+ IN EFI_STRING ConfigRequest, OPTIONAL
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *ConfigAltResp,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name,
+ IN EFI_HANDLE *DriverHandle,
+ IN VOID *BufferStorage,
+ IN UINTN BufferStorageSize,
+ IN VOID *BlockNameArray, OPTIONAL
+ IN UINTN NumberAltCfg,
+ ...
+//IN UINT16 AltCfgId,
+//IN VOID *DefaultValueArray,
+ )
+;
/**
Converts the unicode character of the string from uppercase to lowercase.
@@ -579,6 +620,25 @@ ConstructConfigHdr (
;
/**
+ Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
+
+ @param ConfigString Either <ConfigRequest> or <ConfigResp>.
+ @param StorageGuid GUID of the storage.
+ @param StorageName Name of the stoarge.
+
+ @retval TRUE Routing information is correct in ConfigString.
+ @retval FALSE Routing information is incorrect in ConfigString.
+
+**/
+BOOLEAN
+IsConfigHdrMatch (
+ IN EFI_STRING ConfigString,
+ IN EFI_GUID *StorageGuid, OPTIONAL
+ IN CHAR16 *StorageName OPTIONAL
+ )
+;
+
+/**
Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
@param String The string to be searched in.
diff --git a/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h b/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h
index 9c0f2a2..a26ac8d 100644
--- a/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h
+++ b/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h
@@ -66,13 +66,13 @@ typedef struct {
//
#define EFI_HII_PACKAGE_TYPE_ALL 0x00
#define EFI_HII_PACKAGE_TYPE_GUID 0x01
-#define EFI_HII_PACKAGE_FORM 0x02
-#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x03
+#define EFI_HII_PACKAGE_FORMS 0x02
#define EFI_HII_PACKAGE_STRINGS 0x04
#define EFI_HII_PACKAGE_FONTS 0x05
#define EFI_HII_PACKAGE_IMAGES 0x06
#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07
#define EFI_HII_PACKAGE_DEVICE_PATH 0x08
+#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x09
#define EFI_HII_PACKAGE_END 0xDF
#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0
#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF
diff --git a/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c b/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c
index 5613a50..b6da34a 100644
--- a/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c
+++ b/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c
@@ -296,6 +296,363 @@ IfrLibCreatePopUp (
}
/**
+ Extract block name from the array generated by VFR compiler. The name of
+ this array is "Vfr + <StorageName> + BlockName", e.g. "VfrMyIfrNVDataBlockName".
+ Format of this array is:
+ Array length | 4-bytes
+ Offset | 2-bytes
+ Width | 2-bytes
+ Offset | 2-bytes
+ Width | 2-bytes
+ ... ...
+
+ @param Buffer Array generated by VFR compiler.
+ @param BlockName The returned <BlockName>
+
+ @retval EFI_OUT_OF_RESOURCES Run out of memory resource.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or BlockName is NULL.
+ @retval EFI_SUCCESS Operation successful.
+
+**/
+EFI_STATUS
+ExtractBlockName (
+ IN UINT8 *Buffer,
+ OUT CHAR16 **BlockName
+ )
+
+{
+ UINTN Index;
+ UINT32 Length;
+ UINT32 BlockNameNumber;
+ UINTN HexStringBufferLen;
+ CHAR16 *StringPtr;
+
+ if ((Buffer == NULL) || (BlockName == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate number of Offset/Width pair
+ //
+ CopyMem (&Length, Buffer, sizeof (UINT32));
+ BlockNameNumber = (Length - sizeof (UINT32)) / (sizeof (UINT16) * 2);
+
+ //
+ // <BlockName> ::= &OFFSET=1234&WIDTH=1234
+ // | 8 | 4 | 7 | 4 |
+ //
+ StringPtr = AllocateZeroPool ((BlockNameNumber * (8 + 4 + 7 + 4) + 1) * sizeof (CHAR16));
+ *BlockName = StringPtr;
+ if (StringPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Buffer += sizeof (UINT32);
+ for (Index = 0; Index < BlockNameNumber; Index++) {
+ StrCpy (StringPtr, L"&OFFSET=");
+ StringPtr += 8;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ StrCpy (StringPtr, L"&WIDTH=");
+ StringPtr += 7;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Extract block config from the array generated by VFR compiler. The name of
+ this array is "Vfr + <StorageName> + Default<HexCh>4", e.g. "VfrMyIfrNVDataDefault0000".
+
+ @param Buffer - Array generated by VFR compiler.
+ @param BlockConfig - The returned <BlockConfig>
+
+ @retval EFI_OUT_OF_RESOURCES - Run out of memory resource.
+ @retval EFI_INVALID_PARAMETER - Buffer is NULL or BlockConfig is NULL.
+ @retval EFI_SUCCESS - Operation successful.
+
+**/
+EFI_STATUS
+ExtractBlockConfig (
+ IN UINT8 *Buffer,
+ OUT CHAR16 **BlockConfig
+ )
+{
+ UINT32 Length;
+ UINT16 Width;
+ UINTN HexStringBufferLen;
+ CHAR16 *StringPtr;
+ UINT8 *BufferEnd;
+ CHAR16 *StringEnd;
+ EFI_STATUS Status;
+
+ if ((Buffer == NULL) || (BlockConfig == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate length of AltResp string
+ // Format of Default value array is:
+ // Array length | 4-bytes
+ // Offset | 2-bytes
+ // Width | 2-bytes
+ // Value | Variable length
+ // Offset | 2-bytes
+ // Width | 2-bytes
+ // Value | Variable length
+ // ... ...
+ // When value is 1 byte in length, overhead of AltResp string will be maximum,
+ // BlockConfig ::= <&OFFSET=1234&WIDTH=1234&VALUE=12>+
+ // | 8 | 4 | 7 | 4 | 7 |2|
+ // so the maximum length of BlockConfig could be calculated as:
+ // (ArrayLength / 5) * (8 + 4 + 7 + 4 + 7 + 2) = ArrayLength * 6.4 < ArrayLength * 7
+ //
+ CopyMem (&Length, Buffer, sizeof (UINT32));
+ BufferEnd = Buffer + Length;
+ StringPtr = AllocatePool (Length * 7 * sizeof (CHAR16));
+ *BlockConfig = StringPtr;
+ if (StringPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ StringEnd = StringPtr + (Length * 7);
+
+ Buffer += sizeof (UINT32);
+ while (Buffer < BufferEnd) {
+ StrCpy (StringPtr, L"&OFFSET=");
+ StringPtr += 8;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ StrCpy (StringPtr, L"&WIDTH=");
+ StringPtr += 7;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ CopyMem (&Width, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ StrCpy (StringPtr, L"&VALUE=");
+ StringPtr += 7;
+
+ HexStringBufferLen = StringEnd - StringPtr;
+ Status = BufToHexString (StringPtr, &HexStringBufferLen, Buffer, Width);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Buffer += Width;
+ StringPtr += (Width * 2);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Construct <ConfigAltResp> for a buffer storage.
+
+ @param ConfigRequest The Config request string. If set to NULL, all the
+ configurable elements will be extracted from BlockNameArray.
+ @param ConfigAltResp The returned <ConfigAltResp>.
+ @param Progress On return, points to a character in the Request.
+ @param Guid GUID of the buffer storage.
+ @param Name Name of the buffer storage.
+ @param DriverHandle The DriverHandle which is used to invoke HiiDatabase
+ protocol interface NewPackageList().
+ @param BufferStorage Content of the buffer storage.
+ @param BufferStorageSize Length in bytes of the buffer storage.
+ @param BlockNameArray Array generated by VFR compiler.
+ @param NumberAltCfg Number of Default value array generated by VFR compiler.
+ The sequential input parameters will be number of
+ AltCfgId and DefaultValueArray pairs. When set to 0,
+ there will be no <AltResp>.
+
+ retval EFI_OUT_OF_RESOURCES Run out of memory resource.
+ retval EFI_INVALID_PARAMETER ConfigAltResp is NULL.
+ retval EFI_SUCCESS Operation successful.
+
+**/
+EFI_STATUS
+ConstructConfigAltResp (
+ IN EFI_STRING ConfigRequest, OPTIONAL
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *ConfigAltResp,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name,
+ IN EFI_HANDLE *DriverHandle,
+ IN VOID *BufferStorage,
+ IN UINTN BufferStorageSize,
+ IN VOID *BlockNameArray, OPTIONAL
+ IN UINTN NumberAltCfg,
+ ...
+//IN UINT16 AltCfgId,
+//IN VOID *DefaultValueArray,
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ConfigHdr;
+ CHAR16 *BlockName;
+ CHAR16 *DescHdr;
+ CHAR16 *StringPtr;
+ CHAR16 **AltCfg;
+ UINT16 AltCfgId;
+ VOID *DefaultValueArray;
+ UINTN StrBufferLen;
+ EFI_STRING ConfigResp;
+ EFI_STRING TempStr;
+ VA_LIST Args;
+ UINTN AltRespLen;
+ UINTN Index;
+ BOOLEAN NeedFreeConfigRequest;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ UINTN Len;
+
+ if (ConfigAltResp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
+ //
+ ConfigHdr = NULL;
+ StrBufferLen = 0;
+ Status = ConstructConfigHdr (
+ ConfigHdr,
+ &StrBufferLen,
+ Guid,
+ Name,
+ DriverHandle
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ ConfigHdr = AllocateZeroPool (StrBufferLen);
+ Status = ConstructConfigHdr (
+ ConfigHdr,
+ &StrBufferLen,
+ Guid,
+ Name,
+ DriverHandle
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Construct <ConfigResp>
+ //
+ NeedFreeConfigRequest = FALSE;
+ if (ConfigRequest == NULL) {
+ //
+ // If ConfigRequest is set to NULL, export all configurable elements in BlockNameArray
+ //
+ Status = ExtractBlockName (BlockNameArray, &BlockName);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Len = StrSize (ConfigHdr);
+ ConfigRequest = AllocateZeroPool (Len + StrSize (BlockName) - sizeof (CHAR16));
+ StrCpy (ConfigRequest, ConfigHdr);
+ StrCat (ConfigRequest, BlockName);
+ NeedFreeConfigRequest = TRUE;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ BufferStorage,
+ BufferStorageSize,
+ &ConfigResp,
+ (Progress == NULL) ? &TempStr : Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Construct <AltResp>
+ //
+ DescHdr = AllocateZeroPool (NumberAltCfg * 16 * sizeof (CHAR16));
+ StringPtr = DescHdr;
+ AltCfg = AllocateZeroPool (NumberAltCfg * sizeof (CHAR16 *));
+ AltRespLen = 0;
+ VA_START (Args, NumberAltCfg);
+ for (Index = 0; Index < NumberAltCfg; Index++) {
+ AltCfgId = (UINT16) VA_ARG (Args, UINT16);
+ DefaultValueArray = (UINT8 *) VA_ARG (Args, VOID *);
+
+ //
+ // '&' <ConfigHdr>
+ //
+ AltRespLen += (StrLen (ConfigHdr) + 1);
+
+ StringPtr = DescHdr + Index * 16;
+ StrCpy (StringPtr, L"&ALTCFG=");
+ AltRespLen += (8 + sizeof (UINT16) * 2);
+
+ StrBufferLen = 5;
+ BufToHexString (StringPtr + 8, &StrBufferLen, (UINT8 *) &AltCfgId, sizeof (UINT16));
+ Status = ExtractBlockConfig (DefaultValueArray, &AltCfg[Index]);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ AltRespLen += StrLen (AltCfg[Index]);
+ }
+ VA_END (Args);
+
+ //
+ // Generate the final <ConfigAltResp>
+ //
+ StrBufferLen = (StrLen ((CHAR16 *) ConfigResp) + AltRespLen + 1) * sizeof (CHAR16);
+ TempStr = AllocateZeroPool (StrBufferLen);
+ *ConfigAltResp = TempStr;
+ if (TempStr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // <ConfigAltResp> ::= <ConfigResp> ['&' <AltResp>]*
+ //
+ StrCpy (TempStr, ConfigResp);
+ for (Index = 0; Index < NumberAltCfg; Index++) {
+ StrCat (TempStr, L"&");
+ StrCat (TempStr, ConfigHdr);
+ StrCat (TempStr, DescHdr + Index * 16);
+ StrCat (TempStr, AltCfg[Index]);
+
+ gBS->FreePool (AltCfg[Index]);
+ }
+
+ if (NeedFreeConfigRequest) {
+ gBS->FreePool (ConfigRequest);
+ }
+ gBS->FreePool (ConfigHdr);
+ gBS->FreePool (ConfigResp);
+ gBS->FreePool (DescHdr);
+ gBS->FreePool (AltCfg);
+
+ return EFI_SUCCESS;
+}
+
+/**
Swap bytes in the buffer. This is a internal function.
@param Buffer Binary buffer.
@@ -417,7 +774,7 @@ HexStringToBufInReverseOrder (
ConvertedStrLen = 0;
Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);
if (!EFI_ERROR (Status)) {
- SwapBuffer (Buffer, ConvertedStrLen);
+ SwapBuffer (Buffer, (ConvertedStrLen + 1) / 2);
}
return Status;
@@ -642,6 +999,100 @@ ConstructConfigHdr (
return EFI_SUCCESS;
}
+/**
+ Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
+
+ @param ConfigString Either <ConfigRequest> or <ConfigResp>.
+ @param StorageGuid GUID of the storage.
+ @param StorageName Name of the stoarge.
+
+ @retval TRUE Routing information is correct in ConfigString.
+ @retval FALSE Routing information is incorrect in ConfigString.
+
+**/
+BOOLEAN
+IsConfigHdrMatch (
+ IN EFI_STRING ConfigString,
+ IN EFI_GUID *StorageGuid, OPTIONAL
+ IN CHAR16 *StorageName OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Match;
+ EFI_GUID Guid;
+ CHAR16 *Name;
+ CHAR16 *StrPtr;
+ UINTN BufferSize;
+
+ //
+ // <ConfigHdr> ::=
+ // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ if (StrLen (ConfigString) <= (5 + 32 + 6)) {
+ return FALSE;
+ }
+
+ //
+ // Compare GUID
+ //
+ if (StorageGuid != NULL) {
+
+ StrPtr = ConfigString + 5 + 32;
+ if (*StrPtr != L'&') {
+ return FALSE;
+ }
+ *StrPtr = L'\0';
+
+ BufferSize = sizeof (EFI_GUID);
+ Status = HexStringToBufInReverseOrder (
+ (UINT8 *) &Guid,
+ &BufferSize,
+ ConfigString + 5
+ );
+ *StrPtr = L'&';
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if (!CompareGuid (&Guid, StorageGuid)) {
+ return FALSE;
+ }
+ }
+
+ //
+ // Compare Name
+ //
+ Match = TRUE;
+ if (StorageName != NULL) {
+ StrPtr = ConfigString + 5 + 32 + 6;
+ while (*StrPtr != L'\0' && *StrPtr != L'&') {
+ StrPtr++;
+ }
+ if (*StrPtr != L'&') {
+ return FALSE;
+ }
+
+ *StrPtr = L'\0';
+ BufferSize = (((UINTN) StrPtr) - ((UINTN) &ConfigString[5 + 32 + 6])) / 4 + sizeof (CHAR16);
+ Name = AllocatePool (BufferSize);
+ ASSERT (Name != NULL);
+ Status = ConfigStringToUnicode (
+ Name,
+ &BufferSize,
+ ConfigString + 5 + 32 + 6
+ );
+ *StrPtr = L'&';
+
+ if (EFI_ERROR (Status) || (StrCmp (Name, StorageName) != 0)) {
+ Match = FALSE;
+ }
+ gBS->FreePool (Name);
+ }
+
+ return Match;
+}
/**
Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
@@ -935,8 +1386,8 @@ SetBrowserData (
&BufferSize,
StringPtr,
FALSE,
- NULL,
- NULL
+ VariableGuid,
+ VariableName
);
FreePool (ConfigRequest);
return Status;