mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/UefiHiiLib: Validate question with bit fields
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=545 In UefiHiiLib, there are codes to validate the current setting of questions, now update the logic to handle question with bit storage. Cc: Eric Dong <eric.dong@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
parent
01723271a8
commit
95a7135191
|
@ -1169,6 +1169,13 @@ ValidateQuestionFromVfr (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
CHAR16 *QuestionName;
|
CHAR16 *QuestionName;
|
||||||
CHAR16 *StringPtr;
|
CHAR16 *StringPtr;
|
||||||
|
UINT16 BitOffset;
|
||||||
|
UINT16 BitWidth;
|
||||||
|
UINT16 TotalBits;
|
||||||
|
UINTN StartBit;
|
||||||
|
UINTN EndBit;
|
||||||
|
BOOLEAN QuestionReferBitField;
|
||||||
|
UINT32 BufferValue;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize the local variables.
|
// Initialize the local variables.
|
||||||
|
@ -1182,6 +1189,9 @@ ValidateQuestionFromVfr (
|
||||||
IfrEfiVarStore = NULL;
|
IfrEfiVarStore = NULL;
|
||||||
ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));
|
ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));
|
||||||
ZeroMem (&VarBlockData, sizeof (VarBlockData));
|
ZeroMem (&VarBlockData, sizeof (VarBlockData));
|
||||||
|
BitOffset = 0;
|
||||||
|
BitWidth = 0;
|
||||||
|
QuestionReferBitField = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check IFR value is in block data, then Validate Value
|
// Check IFR value is in block data, then Validate Value
|
||||||
|
@ -1345,8 +1355,19 @@ ValidateQuestionFromVfr (
|
||||||
//
|
//
|
||||||
// Get Offset by Question header and Width by DataType Flags
|
// Get Offset by Question header and Width by DataType Flags
|
||||||
//
|
//
|
||||||
Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;
|
if (QuestionReferBitField) {
|
||||||
Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
|
//
|
||||||
|
// Get the byte offset/width for bit field.
|
||||||
|
//
|
||||||
|
BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;
|
||||||
|
BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
|
||||||
|
Offset = BitOffset / 8;
|
||||||
|
TotalBits = BitOffset % 8 + BitWidth;
|
||||||
|
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
|
||||||
|
} else {
|
||||||
|
Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;
|
||||||
|
Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Check whether this question is in current block array.
|
// Check whether this question is in current block array.
|
||||||
//
|
//
|
||||||
|
@ -1370,7 +1391,17 @@ ValidateQuestionFromVfr (
|
||||||
// Get the current value for oneof opcode
|
// Get the current value for oneof opcode
|
||||||
//
|
//
|
||||||
VarValue = 0;
|
VarValue = 0;
|
||||||
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
if (QuestionReferBitField) {
|
||||||
|
//
|
||||||
|
// Get the value in bit fields.
|
||||||
|
//
|
||||||
|
StartBit = BitOffset % 8;
|
||||||
|
EndBit = StartBit + BitWidth - 1;
|
||||||
|
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
|
||||||
|
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
|
||||||
|
} else {
|
||||||
|
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Set Block Data, to be checked in the following Oneof option opcode.
|
// Set Block Data, to be checked in the following Oneof option opcode.
|
||||||
|
@ -1416,8 +1447,19 @@ ValidateQuestionFromVfr (
|
||||||
//
|
//
|
||||||
// Get Offset by Question header and Width by DataType Flags
|
// Get Offset by Question header and Width by DataType Flags
|
||||||
//
|
//
|
||||||
Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;
|
if (QuestionReferBitField) {
|
||||||
Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
|
//
|
||||||
|
// Get the byte offset/width for bit field.
|
||||||
|
//
|
||||||
|
BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;
|
||||||
|
BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
|
||||||
|
Offset = BitOffset / 8;
|
||||||
|
TotalBits = BitOffset % 8 + BitWidth;
|
||||||
|
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
|
||||||
|
} else {
|
||||||
|
Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;
|
||||||
|
Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Check whether this question is in current block array.
|
// Check whether this question is in current block array.
|
||||||
//
|
//
|
||||||
|
@ -1441,77 +1483,108 @@ ValidateQuestionFromVfr (
|
||||||
// Check the current value is in the numeric range.
|
// Check the current value is in the numeric range.
|
||||||
//
|
//
|
||||||
VarValue = 0;
|
VarValue = 0;
|
||||||
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
if (QuestionReferBitField) {
|
||||||
}
|
//
|
||||||
if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {
|
// Get the value in the bit fields.
|
||||||
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
|
//
|
||||||
case EFI_IFR_NUMERIC_SIZE_1:
|
StartBit = BitOffset % 8;
|
||||||
if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {
|
EndBit = StartBit + BitWidth - 1;
|
||||||
//
|
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
|
||||||
// Not in the valid range.
|
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
|
||||||
//
|
} else {
|
||||||
return EFI_INVALID_PARAMETER;
|
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EFI_IFR_NUMERIC_SIZE_2:
|
|
||||||
if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {
|
|
||||||
//
|
|
||||||
// Not in the valid range.
|
|
||||||
//
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EFI_IFR_NUMERIC_SIZE_4:
|
|
||||||
if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {
|
|
||||||
//
|
|
||||||
// Not in the valid range.
|
|
||||||
//
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EFI_IFR_NUMERIC_SIZE_8:
|
|
||||||
if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {
|
|
||||||
//
|
|
||||||
// Not in the valid range.
|
|
||||||
//
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( QuestionReferBitField) {
|
||||||
|
//
|
||||||
|
// Value in bit fields was stored as UINt32 type.
|
||||||
|
//
|
||||||
|
if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) {
|
||||||
|
if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (VarValue < IfrNumeric->data.u32.MinValue || VarValue > IfrNumeric->data.u32.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
|
if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {
|
||||||
case EFI_IFR_NUMERIC_SIZE_1:
|
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
|
||||||
if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {
|
case EFI_IFR_NUMERIC_SIZE_1:
|
||||||
//
|
if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {
|
||||||
// Not in the valid range.
|
//
|
||||||
//
|
// Not in the valid range.
|
||||||
return EFI_INVALID_PARAMETER;
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_2:
|
||||||
|
if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_4:
|
||||||
|
if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_8:
|
||||||
|
if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case EFI_IFR_NUMERIC_SIZE_2:
|
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
|
||||||
if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {
|
case EFI_IFR_NUMERIC_SIZE_1:
|
||||||
//
|
if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {
|
||||||
// Not in the valid range.
|
//
|
||||||
//
|
// Not in the valid range.
|
||||||
return EFI_INVALID_PARAMETER;
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_2:
|
||||||
|
if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_4:
|
||||||
|
if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EFI_IFR_NUMERIC_SIZE_8:
|
||||||
|
if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {
|
||||||
|
//
|
||||||
|
// Not in the valid range.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EFI_IFR_NUMERIC_SIZE_4:
|
|
||||||
if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {
|
|
||||||
//
|
|
||||||
// Not in the valid range.
|
|
||||||
//
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EFI_IFR_NUMERIC_SIZE_8:
|
|
||||||
if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {
|
|
||||||
//
|
|
||||||
// Not in the valid range.
|
|
||||||
//
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1554,8 +1627,19 @@ ValidateQuestionFromVfr (
|
||||||
//
|
//
|
||||||
// Get Offset by Question header
|
// Get Offset by Question header
|
||||||
//
|
//
|
||||||
Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
|
if (QuestionReferBitField) {
|
||||||
Width = (UINT16) sizeof (BOOLEAN);
|
//
|
||||||
|
// Get the byte offset/width for bit field.
|
||||||
|
//
|
||||||
|
BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
|
||||||
|
BitWidth = 1;
|
||||||
|
Offset = BitOffset / 8;
|
||||||
|
TotalBits = BitOffset % 8 + BitWidth;
|
||||||
|
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
|
||||||
|
} else {
|
||||||
|
Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
|
||||||
|
Width = (UINT16) sizeof (BOOLEAN);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Check whether this question is in current block array.
|
// Check whether this question is in current block array.
|
||||||
//
|
//
|
||||||
|
@ -1578,7 +1662,17 @@ ValidateQuestionFromVfr (
|
||||||
// Check the current value is in the numeric range.
|
// Check the current value is in the numeric range.
|
||||||
//
|
//
|
||||||
VarValue = 0;
|
VarValue = 0;
|
||||||
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
if (QuestionReferBitField) {
|
||||||
|
//
|
||||||
|
// Get the value in bit fields.
|
||||||
|
//
|
||||||
|
StartBit = BitOffset % 8;
|
||||||
|
EndBit = StartBit + BitWidth - 1;
|
||||||
|
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
|
||||||
|
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
|
||||||
|
} else {
|
||||||
|
CopyMem (&VarValue, VarBuffer + Offset, Width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Boolean type, only 1 and 0 is valid.
|
// Boolean type, only 1 and 0 is valid.
|
||||||
|
@ -1703,6 +1797,7 @@ ValidateQuestionFromVfr (
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFI_IFR_END_OP:
|
case EFI_IFR_END_OP:
|
||||||
|
QuestionReferBitField = FALSE;
|
||||||
//
|
//
|
||||||
// Decrease opcode scope for the validated opcode
|
// Decrease opcode scope for the validated opcode
|
||||||
//
|
//
|
||||||
|
@ -1717,6 +1812,11 @@ ValidateQuestionFromVfr (
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EFI_IFR_GUID_OP:
|
||||||
|
if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
|
||||||
|
QuestionReferBitField = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
//
|
//
|
||||||
// Increase Scope for the validated opcode
|
// Increase Scope for the validated opcode
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Internal include file for the HII Library instance.
|
Internal include file for the HII Library instance.
|
||||||
|
|
||||||
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -20,6 +20,8 @@
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
#include <Protocol/FormBrowser2.h>
|
#include <Protocol/FormBrowser2.h>
|
||||||
|
|
||||||
|
#include <Guid/MdeModuleHii.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/HiiLib.h>
|
#include <Library/HiiLib.h>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# HII Library implementation using UEFI HII protocols and services.
|
# HII Library implementation using UEFI HII protocols and services.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -51,3 +51,6 @@
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID
|
||||||
|
|
Loading…
Reference in New Issue