From 901ba0e78d02bd4407571c296871f96a0d225698 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Fri, 18 Nov 2011 07:07:31 +0000 Subject: [PATCH] Enable buffer type when process some expression opcode which support buffer type. Signed-off-by: ydong10 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12739 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/SetupBrowserDxe/Expression.c | 216 ++++++++++++++---- .../Universal/SetupBrowserDxe/IfrParse.c | 4 + .../Universal/SetupBrowserDxe/Setup.c | 45 +++- .../Universal/SetupBrowserDxe/Setup.h | 2 + 4 files changed, 218 insertions(+), 49 deletions(-) diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c index aba565ca64..883693fde5 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c @@ -140,6 +140,11 @@ PushStack ( // Push the item onto the stack // CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE)); + if (Data->Type == EFI_IFR_TYPE_BUFFER) { + (*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer); + ASSERT ((*StackPtr)->Buffer != NULL); + } + *StackPtr = *StackPtr + 1; return EFI_SUCCESS; @@ -703,6 +708,7 @@ IfrToString ( CHAR16 *String; CHAR16 *PrintFormat; CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS]; + UINT8 *TmpBuf; UINTN BufferSize; Status = PopExpression (&Value); @@ -744,7 +750,27 @@ IfrToString ( case EFI_IFR_TYPE_BOOLEAN: String = (Value.Value.b) ? L"True" : L"False"; break; - + + case EFI_IFR_TYPE_BUFFER: + // + // + 3 is base on the unicode format, the length may be odd number, + // so need 1 byte to align, also need 2 bytes for L'\0'. + // + TmpBuf = AllocateZeroPool (Value.BufferLen + 3); + if (Format == EFI_IFR_STRING_ASCII) { + CopyMem (TmpBuf, Value.Buffer, Value.BufferLen); + PrintFormat = L"%a"; + } else { + // Format == EFI_IFR_STRING_UNICODE + CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16)); + PrintFormat = L"%s"; + } + UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer); + String = Buffer; + FreePool (TmpBuf); + FreePool (Value.Buffer); + break; + default: return EFI_UNSUPPORTED; } @@ -781,7 +807,7 @@ IfrToUint ( return Status; } - if (Value.Type >= EFI_IFR_TYPE_OTHER) { + if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) { return EFI_UNSUPPORTED; } @@ -806,6 +832,13 @@ IfrToUint ( Result->Value.u64 = StrDecimalToUint64 (String); } FreePool (String); + } else if (Value.Type == EFI_IFR_TYPE_BUFFER) { + if (Value.BufferLen > 8) { + FreePool (Value.Buffer); + return EFI_UNSUPPORTED; + } + Result->Value.u64 = *(UINT64*) Value.Buffer; + FreePool (Value.Buffer); } else { CopyMem (Result, &Value, sizeof (EFI_HII_VALUE)); } @@ -832,7 +865,7 @@ IfrCatenate ( ) { EFI_STATUS Status; - EFI_HII_VALUE Value; + EFI_HII_VALUE Value[2]; CHAR16 *String[2]; UINTN Index; CHAR16 *StringPtr; @@ -846,35 +879,54 @@ IfrCatenate ( String[1] = NULL; StringPtr = NULL; Status = EFI_SUCCESS; + ZeroMem (Value, sizeof (Value)); for (Index = 0; Index < 2; Index++) { - Status = PopExpression (&Value); + Status = PopExpression (&Value[Index]); if (EFI_ERROR (Status)) { goto Done; } - if (Value.Type != EFI_IFR_TYPE_STRING) { + if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) { Status = EFI_UNSUPPORTED; goto Done; } - String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle); - if (String[Index] == NULL) { - Status = EFI_NOT_FOUND; - goto Done; + if (Value[Index].Type == EFI_IFR_TYPE_STRING) { + String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle); + if (String[Index] == NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } } } - Size = StrSize (String[0]); - StringPtr= AllocatePool (StrSize (String[1]) + Size); - ASSERT (StringPtr != NULL); - StrCpy (StringPtr, String[1]); - StrCat (StringPtr, String[0]); + if (Value[0].Type == EFI_IFR_TYPE_STRING) { + Size = StrSize (String[0]); + StringPtr= AllocatePool (StrSize (String[1]) + Size); + ASSERT (StringPtr != NULL); + StrCpy (StringPtr, String[1]); + StrCat (StringPtr, String[0]); - Result->Type = EFI_IFR_TYPE_STRING; - Result->Value.string = NewString (StringPtr, FormSet->HiiHandle); + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (StringPtr, FormSet->HiiHandle); + } else { + Result->Type = EFI_IFR_TYPE_BUFFER; + Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen); + Result->Buffer = AllocateZeroPool (Result->BufferLen); + ASSERT (Result->Buffer != NULL); + + CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen); + CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen); + } Done: + if (Value[0].Buffer != NULL) { + FreePool (Value[0].Buffer); + } + if (Value[1].Buffer != NULL) { + FreePool (Value[1].Buffer); + } if (String[0] != NULL) { FreePool (String[0]); } @@ -1061,6 +1113,8 @@ IfrMid ( UINTN Base; UINTN Length; CHAR16 *SubString; + UINT8 *Buffer; + UINT16 BufferLen; Status = PopExpression (&Value); if (EFI_ERROR (Status)) { @@ -1084,28 +1138,46 @@ IfrMid ( if (EFI_ERROR (Status)) { return Status; } - if (Value.Type != EFI_IFR_TYPE_STRING) { + if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) { return EFI_UNSUPPORTED; } - String = GetToken (Value.Value.string, FormSet->HiiHandle); - if (String == NULL) { - return EFI_NOT_FOUND; - } - - if (Length == 0 || Base >= StrLen (String)) { - SubString = gEmptyString; - } else { - SubString = String + Base; - if ((Base + Length) < StrLen (String)) { - SubString[Length] = L'\0'; + if (Value.Type == EFI_IFR_TYPE_STRING) { + String = GetToken (Value.Value.string, FormSet->HiiHandle); + if (String == NULL) { + return EFI_NOT_FOUND; } + + if (Length == 0 || Base >= StrLen (String)) { + SubString = gEmptyString; + } else { + SubString = String + Base; + if ((Base + Length) < StrLen (String)) { + SubString[Length] = L'\0'; + } + } + + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (SubString, FormSet->HiiHandle); + + FreePool (String); + } else { + Buffer = Value.Buffer; + BufferLen = Value.BufferLen; + + Result->Type = EFI_IFR_TYPE_BUFFER; + if (Length == 0 || Base >= BufferLen) { + Result->BufferLen = 0; + Result->Buffer = NULL; + } else { + Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length); + Result->Buffer = AllocateZeroPool (Result->BufferLen); + ASSERT (Result->Buffer != NULL); + CopyMem (Result->Buffer, &Value.Buffer[Base], Result->BufferLen); + } + + FreePool (Value.Buffer); } - - Result->Type = EFI_IFR_TYPE_STRING; - Result->Value.string = NewString (SubString, FormSet->HiiHandle); - - FreePool (String); - + return Status; } @@ -1392,9 +1464,12 @@ CompareHiiValue ( INT64 Temp64; CHAR16 *Str1; CHAR16 *Str2; + UINTN Len; if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) { - return EFI_INVALID_PARAMETER; + if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) { + return EFI_INVALID_PARAMETER; + } } if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) { @@ -1438,6 +1513,26 @@ CompareHiiValue ( return Result; } + if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) { + if (Value1->Type != Value2->Type) { + // + // Both Operator should be type of Buffer. + // + return EFI_INVALID_PARAMETER; + } + Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen; + Result = CompareMem (Value1->Buffer, Value2->Buffer, Len); + if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen)) + { + // + // In this case, means base on samll number buffer, the data is same + // So which value has more data, which value is bigger. + // + Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1; + } + return Result; + } + // // Take remain types(integer, boolean, date/time) as integer // @@ -1925,20 +2020,26 @@ EvaluateExpression ( if (EFI_ERROR (Status)) { goto Done; } - if (Value->Type != EFI_IFR_TYPE_STRING) { + if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) { Status = EFI_INVALID_PARAMETER; goto Done; } - StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle); - if (StrPtr == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } + if (Value->Type == EFI_IFR_TYPE_STRING) { + StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle); + if (StrPtr == NULL) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } - Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; - Value->Value.u64 = StrLen (StrPtr); - FreePool (StrPtr); + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = StrLen (StrPtr); + FreePool (StrPtr); + } else { + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = Value->BufferLen; + FreePool (Value->Buffer); + } break; case EFI_IFR_NOT_OP: @@ -2054,6 +2155,24 @@ EvaluateExpression ( } FreePool (StrPtr); Value->Type = EFI_IFR_TYPE_BOOLEAN; + } else if (Value->Type == EFI_IFR_TYPE_BUFFER) { + // + // When converting from a buffer, if the buffer is all zeroes, + // then push False. Otherwise push True. + // + for (Index =0; Index < Value->BufferLen; Index ++) { + if (Value->Buffer[Index] != 0) { + break; + } + } + + if (Index >= Value->BufferLen) { + Value->Value.b = FALSE; + } else { + Value->Value.b = TRUE; + } + Value->Type = EFI_IFR_TYPE_BOOLEAN; + FreePool (Value->Buffer); } break; @@ -2359,7 +2478,9 @@ EvaluateExpression ( if (EFI_ERROR (Status)) { goto Done; } - if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) { + if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && + Data2.Type != EFI_IFR_TYPE_STRING && + Data2.Type != EFI_IFR_TYPE_BUFFER) { Status = EFI_INVALID_PARAMETER; goto Done; } @@ -2373,6 +2494,11 @@ EvaluateExpression ( } Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle); + if (Data1.Type == EFI_IFR_TYPE_BUFFER) { + FreePool (Data1.Buffer); + FreePool (Data2.Buffer); + } + if (Result == EFI_INVALID_PARAMETER) { Status = EFI_INVALID_PARAMETER; goto Done; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 87924792a7..8e55b99706 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -1841,6 +1841,10 @@ ParseOpCodes ( CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width); CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); CurrentStatement->ValueType = CurrentOption->Value.Type; + if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) { + CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue; + CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth; + } InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index 00462a270f..1e592c1e9f 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -1234,7 +1234,19 @@ GetQuestionValue ( if (Question->ValueExpression != NULL) { Status = EvaluateExpression (FormSet, Form, Question->ValueExpression); if (!EFI_ERROR (Status)) { - CopyMem (&Question->HiiValue, &Question->ValueExpression->Result, sizeof (EFI_HII_VALUE)); + if (Question->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) { + ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL); + if (Question->StorageWidth > Question->ValueExpression->Result.BufferLen) { + CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->ValueExpression->Result.BufferLen); + Question->HiiValue.BufferLen = Question->ValueExpression->Result.BufferLen; + } else { + CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->StorageWidth); + Question->HiiValue.BufferLen = Question->StorageWidth; + } + FreePool (Question->ValueExpression->Result.Buffer); + } + Question->HiiValue.Type = Question->ValueExpression->Result.Type; + CopyMem (&Question->HiiValue.Value, &Question->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); } return Status; } @@ -1244,11 +1256,24 @@ GetQuestionValue ( // if (Question->ReadExpression != NULL && Form->FormType == STANDARD_MAP_FORM_TYPE) { Status = EvaluateExpression (FormSet, Form, Question->ReadExpression); - if (!EFI_ERROR (Status) && (Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER)) { + if (!EFI_ERROR (Status) && + ((Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER) || (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER))) { // // Only update question value to the valid result. // - CopyMem (&Question->HiiValue, &Question->ReadExpression->Result, sizeof (EFI_HII_VALUE)); + if (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER) { + ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL); + if (Question->StorageWidth > Question->ReadExpression->Result.BufferLen) { + CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->ReadExpression->Result.BufferLen); + Question->HiiValue.BufferLen = Question->ReadExpression->Result.BufferLen; + } else { + CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->StorageWidth); + Question->HiiValue.BufferLen = Question->StorageWidth; + } + FreePool (Question->ReadExpression->Result.Buffer); + } + Question->HiiValue.Type = Question->ReadExpression->Result.Type; + CopyMem (&Question->HiiValue.Value, &Question->ReadExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); return EFI_SUCCESS; } } @@ -2795,7 +2820,19 @@ GetQuestionDefault ( return Status; } - CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE)); + if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) { + ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && Question->BufferValue != NULL); + if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) { + CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen); + Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen; + } else { + CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth); + Question->HiiValue.BufferLen = Question->StorageWidth; + } + FreePool (Default->ValueExpression->Result.Buffer); + } + HiiValue->Type = Default->ValueExpression->Result.Type; + CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); } else { // // Default value is embedded in EFI_IFR_DEFAULT diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index eaf409b8e6..6c34b4f996 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -198,6 +198,8 @@ typedef struct { typedef struct { UINT8 Type; + UINT8 *Buffer; + UINT16 BufferLen; EFI_IFR_TYPE_VALUE Value; } EFI_HII_VALUE;