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
This commit is contained in:
qwang12 2008-11-04 14:22:22 +00:00
parent ba954c772d
commit 9185c388a9
3 changed files with 516 additions and 5 deletions

View File

@ -434,6 +434,47 @@ CreateStringOpCode (
IN OUT EFI_HII_UPDATE_DATA *Data 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. Converts the unicode character of the string from uppercase to lowercase.
@ -578,6 +619,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. Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.

View File

@ -66,13 +66,13 @@ typedef struct {
// //
#define EFI_HII_PACKAGE_TYPE_ALL 0x00 #define EFI_HII_PACKAGE_TYPE_ALL 0x00
#define EFI_HII_PACKAGE_TYPE_GUID 0x01 #define EFI_HII_PACKAGE_TYPE_GUID 0x01
#define EFI_HII_PACKAGE_FORM 0x02 #define EFI_HII_PACKAGE_FORMS 0x02
#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x03
#define EFI_HII_PACKAGE_STRINGS 0x04 #define EFI_HII_PACKAGE_STRINGS 0x04
#define EFI_HII_PACKAGE_FONTS 0x05 #define EFI_HII_PACKAGE_FONTS 0x05
#define EFI_HII_PACKAGE_IMAGES 0x06 #define EFI_HII_PACKAGE_IMAGES 0x06
#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07 #define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07
#define EFI_HII_PACKAGE_DEVICE_PATH 0x08 #define EFI_HII_PACKAGE_DEVICE_PATH 0x08
#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x09
#define EFI_HII_PACKAGE_END 0xDF #define EFI_HII_PACKAGE_END 0xDF
#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0 #define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0
#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF #define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF

View File

@ -295,6 +295,363 @@ IfrLibCreatePopUp (
return Status; return Status;
} }
/**
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. Swap bytes in the buffer. This is a internal function.
@ -417,7 +774,7 @@ HexStringToBufInReverseOrder (
ConvertedStrLen = 0; ConvertedStrLen = 0;
Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen); Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
SwapBuffer (Buffer, ConvertedStrLen); SwapBuffer (Buffer, (ConvertedStrLen + 1) / 2);
} }
return Status; return Status;
@ -642,6 +999,100 @@ ConstructConfigHdr (
return EFI_SUCCESS; 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. Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
@ -935,8 +1386,8 @@ SetBrowserData (
&BufferSize, &BufferSize,
StringPtr, StringPtr,
FALSE, FALSE,
NULL, VariableGuid,
NULL VariableName
); );
FreePool (ConfigRequest); FreePool (ConfigRequest);
return Status; return Status;