diff options
author | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-02-02 13:11:49 +0000 |
---|---|---|
committer | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-02-02 13:11:49 +0000 |
commit | e52c5a9fdcc1663f98e1a1090c424c1606990650 (patch) | |
tree | 6bba76e4eed7ddbccb4c1d12258d8a86db81c797 /MdePkg/Library/IfrSupportLib | |
parent | 59ab6d02a98545df6b35178cce796af7ad56d0b9 (diff) | |
download | edk2-platforms-e52c5a9fdcc1663f98e1a1090c424c1606990650.tar.xz |
1) Cleanup HiiLib, IfrSupportLib.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4661 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdePkg/Library/IfrSupportLib')
-rw-r--r-- | MdePkg/Library/IfrSupportLib/IfrSupportLib.inf | 74 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/IfrSupportLib.msa | 74 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/R8Lib.c | 241 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/R8Lib.h | 93 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/UefiIfrCommon.c | 47 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/UefiIfrForm.c | 759 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/UefiIfrLibraryInternal.h | 47 | ||||
-rw-r--r-- | MdePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c | 618 |
8 files changed, 1953 insertions, 0 deletions
diff --git a/MdePkg/Library/IfrSupportLib/IfrSupportLib.inf b/MdePkg/Library/IfrSupportLib/IfrSupportLib.inf new file mode 100644 index 0000000000..a8d5df4c95 --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/IfrSupportLib.inf @@ -0,0 +1,74 @@ +#/** @file
+# Component name for module UefiEfiIfrSupportLib
+#
+# FIX ME!
+# Copyright (c) 2007, Intel Corporation. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IfrSupportLib
+ FILE_GUID = bf38668e-e231-4baa-99e4-8c0e4c35dca6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = IfrSupportLib
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+ CONSTRUCTOR = IfrSupportLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ UefiIfrCommon.c
+ UefiIfrForm.c
+ UefiIfrLibraryInternal.h
+ UefiIfrOpCodeCreation.c
+ R8Lib.h
+ R8Lib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+ MemoryAllocationLib
+ DevicePathLib
+ BaseLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+
+[Guids]
+ gEfiGlobalVariableGuid # ALWAYS_CONSUMED
+
+[Protocols]
+ gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiHiiDatabaseProtocolGuid
+ gEfiHiiStringProtocolGuid
+ gEfiHiiConfigRoutingProtocolGuid
+ gEfiFormBrowser2ProtocolGuid
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid AND gEfiHiiStringProtocolGuid
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+
\ No newline at end of file diff --git a/MdePkg/Library/IfrSupportLib/IfrSupportLib.msa b/MdePkg/Library/IfrSupportLib/IfrSupportLib.msa new file mode 100644 index 0000000000..dc9d665a14 --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/IfrSupportLib.msa @@ -0,0 +1,74 @@ +<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>UefiEfiIfrSupportLib</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>bf38668e-e231-4baa-99e4-8c0e4c35dca6</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component name for module UefiEfiIfrSupportLib</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UefiEfiIfrSupportLib</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>R8Lib.c</Filename>
+ <Filename>R8Lib.h</Filename>
+ <Filename>UefiIfrString.c</Filename>
+ <Filename>UefiIfrOpCodeCreation.c</Filename>
+ <Filename>UefiIfrLibraryInternal.h</Filename>
+ <Filename>UefiIfrForm.c</Filename>
+ <Filename>UefiIfrCommon.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiGlobalVariableGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ </Externs>
+</ModuleSurfaceArea>
\ No newline at end of file diff --git a/MdePkg/Library/IfrSupportLib/R8Lib.c b/MdePkg/Library/IfrSupportLib/R8Lib.c new file mode 100644 index 0000000000..634bdb682d --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/R8Lib.c @@ -0,0 +1,241 @@ +/**@file + Copyright (c) 2007, Intel Corporation + + All rights reserved. This program and the accompanying materials + 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 + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ + +#include "UefiIfrLibraryInternal.h" + + +CHAR16 +InternalNibbleToHexChar ( + IN UINT8 Nibble + ) +/*++ + + Routine Description: + Converts the low nibble of a byte to hex unicode character. + + Arguments: + Nibble - lower nibble of a byte. + + Returns: + Hex unicode character. + +--*/ +{ + Nibble &= 0x0F; + if (Nibble <= 0x9) { + return (CHAR16)(Nibble + L'0'); + } + + return (CHAR16)(Nibble - 0xA + L'A'); +} + + +/** + Converts binary buffer to Unicode string. + At a minimum, any blob of data could be represented as a hex string. + + @param Str Pointer to the string. + @param HexStringBufferLength Length in bytes of buffer to hold the hex string. + Includes tailing '\0' character. If routine return + with EFI_SUCCESS, containing length of hex string + buffer. If routine return with + EFI_BUFFER_TOO_SMALL, containg length of hex + string buffer desired. + @param Buf Buffer to be converted from. + @param Len Length in bytes of the buffer to be converted. + + @retval EFI_SUCCESS Routine success. + @retval EFI_BUFFER_TOO_SMALL The hex string buffer is too small. + +**/ +EFI_STATUS +R8_BufToHexString ( + IN OUT CHAR16 *Str, + IN OUT UINTN *HexStringBufferLength, + IN UINT8 *Buf, + IN UINTN Len + ) +{ + // + // Porting Guide: + // This library interface is simply obsolete. + // Include the source code to user code. + // + UINTN Idx; + UINT8 Byte; + UINTN StrLen; + + // + // Make sure string is either passed or allocate enough. + // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer. + // Plus the Unicode termination character. + // + StrLen = Len * 2; + if (StrLen > ((*HexStringBufferLength) - 1)) { + *HexStringBufferLength = StrLen + 1; + return EFI_BUFFER_TOO_SMALL; + } + + *HexStringBufferLength = StrLen + 1; + // + // Ends the string. + // + Str[StrLen] = L'\0'; + + for (Idx = 0; Idx < Len; Idx++) { + + Byte = Buf[Idx]; + Str[StrLen - 1 - Idx * 2] = InternalNibbleToHexChar (Byte); + Str[StrLen - 2 - Idx * 2] = InternalNibbleToHexChar ((UINT8)(Byte >> 4)); + } + + return EFI_SUCCESS; +} + + + + +/** + Converts Unicode string to binary buffer. + The conversion may be partial. + The first character in the string that is not hex digit stops the conversion. + At a minimum, any blob of data could be represented as a hex string. + + @param Buf Pointer to buffer that receives the data. + @param Len Length in bytes of the buffer to hold converted + data. If routine return with EFI_SUCCESS, + containing length of converted data. If routine + return with EFI_BUFFER_TOO_SMALL, containg length + of buffer desired. + @param Str String to be converted from. + @param ConvertedStrLen Length of the Hex String consumed. + + @retval EFI_SUCCESS Routine Success. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold converted data. + +**/ +EFI_STATUS +R8_HexStringToBuf ( + IN OUT UINT8 *Buf, + IN OUT UINTN *Len, + IN CHAR16 *Str, + OUT UINTN *ConvertedStrLen OPTIONAL + ) +{ + // + // Porting Guide: + // This library interface is simply obsolete. + // Include the source code to user code. + // + + UINTN HexCnt; + UINTN Idx; + UINTN BufferLength; + UINT8 Digit; + UINT8 Byte; + + // + // Find out how many hex characters the string has. + // + for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++); + + if (HexCnt == 0) { + *Len = 0; + return EFI_SUCCESS; + } + // + // Two Unicode characters make up 1 buffer byte. Round up. + // + BufferLength = (HexCnt + 1) / 2; + + // + // Test if buffer is passed enough. + // + if (BufferLength > (*Len)) { + *Len = BufferLength; + return EFI_BUFFER_TOO_SMALL; + } + + *Len = BufferLength; + + for (Idx = 0; Idx < HexCnt; Idx++) { + + R8_IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]); + + // + // For odd charaters, write the lower nibble for each buffer byte, + // and for even characters, the upper nibble. + // + if ((Idx & 1) == 0) { + Byte = Digit; + } else { + Byte = Buf[Idx / 2]; + Byte &= 0x0F; + Byte = (UINT8) (Byte | Digit << 4); + } + + Buf[Idx / 2] = Byte; + } + + if (ConvertedStrLen != NULL) { + *ConvertedStrLen = HexCnt; + } + + return EFI_SUCCESS; +} + + +/** + Determines if a Unicode character is a hexadecimal digit. + The test is case insensitive. + + @param Digit Pointer to byte that receives the value of the hex + character. + @param Char Unicode character to test. + + @retval TRUE If the character is a hexadecimal digit. + @retval FALSE Otherwise. + +**/ +BOOLEAN +R8_IsHexDigit ( + OUT UINT8 *Digit, + IN CHAR16 Char + ) +{ + // + // Porting Guide: + // This library interface is simply obsolete. + // Include the source code to user code. + // + + if ((Char >= L'0') && (Char <= L'9')) { + *Digit = (UINT8) (Char - L'0'); + return TRUE; + } + + if ((Char >= L'A') && (Char <= L'F')) { + *Digit = (UINT8) (Char - L'A' + 0x0A); + return TRUE; + } + + if ((Char >= L'a') && (Char <= L'f')) { + *Digit = (UINT8) (Char - L'a' + 0x0A); + return TRUE; + } + + return FALSE; +} + + diff --git a/MdePkg/Library/IfrSupportLib/R8Lib.h b/MdePkg/Library/IfrSupportLib/R8Lib.h new file mode 100644 index 0000000000..ca9b93989e --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/R8Lib.h @@ -0,0 +1,93 @@ +/**@file + Copyright (c) 2007, Intel Corporation + + All rights reserved. This program and the accompanying materials + 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 + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +**/ + + + +/** + Converts binary buffer to Unicode string. + At a minimum, any blob of data could be represented as a hex string. + + @param Str Pointer to the string. + @param HexStringBufferLength Length in bytes of buffer to hold the hex string. + Includes tailing '\0' character. If routine return + with EFI_SUCCESS, containing length of hex string + buffer. If routine return with + EFI_BUFFER_TOO_SMALL, containg length of hex + string buffer desired. + @param Buf Buffer to be converted from. + @param Len Length in bytes of the buffer to be converted. + + @retval EFI_SUCCESS Routine success. + @retval EFI_BUFFER_TOO_SMALL The hex string buffer is too small. + +**/ +EFI_STATUS +R8_BufToHexString ( + IN OUT CHAR16 *Str, + IN OUT UINTN *HexStringBufferLength, + IN UINT8 *Buf, + IN UINTN Len + ) +; + + + + +/** + Converts Unicode string to binary buffer. + The conversion may be partial. + The first character in the string that is not hex digit stops the conversion. + At a minimum, any blob of data could be represented as a hex string. + + @param Buf Pointer to buffer that receives the data. + @param Len Length in bytes of the buffer to hold converted + data. If routine return with EFI_SUCCESS, + containing length of converted data. If routine + return with EFI_BUFFER_TOO_SMALL, containg length + of buffer desired. + @param Str String to be converted from. + @param ConvertedStrLen Length of the Hex String consumed. + + @retval EFI_SUCCESS Routine Success. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold converted data. + +**/ +EFI_STATUS +R8_HexStringToBuf ( + IN OUT UINT8 *Buf, + IN OUT UINTN *Len, + IN CHAR16 *Str, + OUT UINTN *ConvertedStrLen OPTIONAL + ) +; + +/** + Determines if a Unicode character is a hexadecimal digit. + The test is case insensitive. + + @param Digit Pointer to byte that receives the value of the hex + character. + @param Char Unicode character to test. + + @retval TRUE If the character is a hexadecimal digit. + @retval FALSE Otherwise. + +**/ +BOOLEAN +R8_IsHexDigit ( + OUT UINT8 *Digit, + IN CHAR16 Char + ) +; + diff --git a/MdePkg/Library/IfrSupportLib/UefiIfrCommon.c b/MdePkg/Library/IfrSupportLib/UefiIfrCommon.c new file mode 100644 index 0000000000..958400fc51 --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/UefiIfrCommon.c @@ -0,0 +1,47 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UefiIfrCommon.c + +Abstract: + + Common Library Routines to assist handle HII elements. + + +**/ + +#include "UefiIfrLibraryInternal.h" + +EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase; +EFI_HII_STRING_PROTOCOL *gIfrLibHiiString; + + +EFI_STATUS +EFIAPI +IfrSupportLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + + diff --git a/MdePkg/Library/IfrSupportLib/UefiIfrForm.c b/MdePkg/Library/IfrSupportLib/UefiIfrForm.c new file mode 100644 index 0000000000..10ca13c3d7 --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/UefiIfrForm.c @@ -0,0 +1,759 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UefiIfrForm.c + +Abstract: + + Common Library Routines to assist handle HII elements. + + +**/ + +#include "UefiIfrLibraryInternal.h" + +// +// Fake <ConfigHdr> +// +UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0"; + +STATIC +EFI_STATUS +GetPackageDataFromPackageList ( + IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList, + IN UINT32 PackageIndex, + OUT UINT32 *BufferLen, + OUT EFI_HII_PACKAGE_HEADER **Buffer + ) +{ + UINT32 Index; + EFI_HII_PACKAGE_HEADER *Package; + UINT32 Offset; + UINT32 PackageListLength; + EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0}; + + ASSERT(HiiPackageList != NULL); + + if ((BufferLen == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Package = NULL; + Index = 0; + Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); + while (Offset < PackageListLength) { + Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset); + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + if (Index == PackageIndex) { + break; + } + Offset += PackageHeader.Length; + Index++; + } + if (Offset >= PackageListLength) { + // + // no package found in this Package List + // + return EFI_NOT_FOUND; + } + + *BufferLen = PackageHeader.Length; + *Buffer = Package; + return EFI_SUCCESS; +} + + +/** + Draw a dialog and return the selected key. + + @param NumberOfLines The number of lines for the dialog box + @param KeyValue The EFI_KEY value returned if HotKey is TRUE.. + @param String Pointer to the first string in the list + @param ... A series of (quantity == NumberOfLines) text + strings which will be used to construct the dialog + box + + @retval EFI_SUCCESS Displayed dialog and received user interaction + @retval EFI_INVALID_PARAMETER One of the parameters was invalid. + +**/ +EFI_STATUS +EFIAPI +IfrLibCreatePopUp ( + IN UINTN NumberOfLines, + OUT EFI_INPUT_KEY *KeyValue, + IN CHAR16 *String, + ... + ) +{ + UINTN Index; + UINTN Count; + UINTN Start; + UINTN Top; + CHAR16 *StringPtr; + UINTN LeftColumn; + UINTN RightColumn; + UINTN TopRow; + UINTN BottomRow; + UINTN DimensionsWidth; + UINTN DimensionsHeight; + VA_LIST Marker; + EFI_INPUT_KEY Key; + UINTN LargestString; + CHAR16 *StackString; + EFI_STATUS Status; + UINTN StringLen; + CHAR16 *LineBuffer; + CHAR16 **StringArray; + EFI_EVENT TimerEvent; + EFI_EVENT WaitList[2]; + UINTN CurrentAttribute; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + + if ((KeyValue == NULL) || (String == NULL)) { + return EFI_INVALID_PARAMETER; + } + + TopRow = 0; + BottomRow = 0; + LeftColumn = 0; + RightColumn = 0; + + ConOut = gST->ConOut; + ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &RightColumn, &BottomRow); + + DimensionsWidth = RightColumn - LeftColumn; + DimensionsHeight = BottomRow - TopRow; + + CurrentAttribute = ConOut->Mode->Attribute; + + LineBuffer = AllocateZeroPool (DimensionsWidth * sizeof (CHAR16)); + ASSERT (LineBuffer != NULL); + + // + // Determine the largest string in the dialog box + // Notice we are starting with 1 since String is the first string + // + StringArray = AllocateZeroPool (NumberOfLines * sizeof (CHAR16 *)); + LargestString = StrLen (String); + StringArray[0] = String; + + VA_START (Marker, String); + for (Index = 1; Index < NumberOfLines; Index++) { + StackString = VA_ARG (Marker, CHAR16 *); + + if (StackString == NULL) { + return EFI_INVALID_PARAMETER; + } + + StringArray[Index] = StackString; + StringLen = StrLen (StackString); + if (StringLen > LargestString) { + LargestString = StringLen; + } + } + + if ((LargestString + 2) > DimensionsWidth) { + LargestString = DimensionsWidth - 2; + } + + // + // Subtract the PopUp width from total Columns, allow for one space extra on + // each end plus a border. + // + Start = (DimensionsWidth - LargestString - 2) / 2 + LeftColumn + 1; + + Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + TopRow - 1; + + // + // Disable cursor + // + ConOut->EnableCursor (ConOut, FALSE); + ConOut->SetAttribute (ConOut, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); + + StringPtr = &LineBuffer[0]; + *StringPtr++ = BOXDRAW_DOWN_RIGHT; + for (Index = 0; Index < LargestString; Index++) { + *StringPtr++ = BOXDRAW_HORIZONTAL; + } + *StringPtr++ = BOXDRAW_DOWN_LEFT; + *StringPtr = L'\0'; + + ConOut->SetCursorPosition (ConOut, Start, Top); + ConOut->OutputString (ConOut, LineBuffer); + + for (Index = 0; Index < NumberOfLines; Index++) { + StringPtr = &LineBuffer[0]; + *StringPtr++ = BOXDRAW_VERTICAL; + + for (Count = 0; Count < LargestString; Count++) { + StringPtr[Count] = L' '; + } + + StringLen = StrLen (StringArray[Index]); + if (StringLen > LargestString) { + StringLen = LargestString; + } + CopyMem ( + StringPtr + ((LargestString - StringLen) / 2), + StringArray[Index], + StringLen * sizeof (CHAR16) + ); + StringPtr += LargestString; + + *StringPtr++ = BOXDRAW_VERTICAL; + *StringPtr = L'\0'; + + ConOut->SetCursorPosition (ConOut, Start, Top + 1 + Index); + ConOut->OutputString (ConOut, LineBuffer); + } + + StringPtr = &LineBuffer[0]; + *StringPtr++ = BOXDRAW_UP_RIGHT; + for (Index = 0; Index < LargestString; Index++) { + *StringPtr++ = BOXDRAW_HORIZONTAL; + } + *StringPtr++ = BOXDRAW_UP_LEFT; + *StringPtr = L'\0'; + + ConOut->SetCursorPosition (ConOut, Start, Top + NumberOfLines + 1); + ConOut->OutputString (ConOut, LineBuffer); + + do { + Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent); + + // + // Set a timer event of 1 second expiration + // + gBS->SetTimer ( + TimerEvent, + TimerRelative, + 10000000 + ); + + // + // Wait for the keystroke event or the timer + // + WaitList[0] = gST->ConIn->WaitForKey; + WaitList[1] = TimerEvent; + Status = gBS->WaitForEvent (2, WaitList, &Index); + + // + // Check for the timer expiration + // + if (!EFI_ERROR (Status) && Index == 1) { + Status = EFI_TIMEOUT; + } + + gBS->CloseEvent (TimerEvent); + } while (Status == EFI_TIMEOUT); + + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY)); + + ConOut->SetAttribute (ConOut, CurrentAttribute); + ConOut->EnableCursor (ConOut, TRUE); + + return Status; +} + + +/** + Swap bytes in the buffer. + + @param Buffer Binary buffer. + @param BufferSize Size of the buffer in bytes. + + @return None. + +**/ +STATIC +VOID +SwapBuffer ( + IN OUT UINT8 *Buffer, + IN UINTN BufferSize + ) +{ + UINTN Index; + UINT8 Temp; + UINTN SwapCount; + + SwapCount = (BufferSize - 1) / 2; + for (Index = 0; Index < SwapCount; Index++) { + Temp = Buffer[Index]; + Buffer[Index] = Buffer[BufferSize - 1 - Index]; + Buffer[BufferSize - 1 - Index] = Temp; + } +} + + +/** + Converts binary buffer to Unicode string in reversed byte order from R8_BufToHexString(). + + @param Str String for output + @param Buffer Binary buffer. + @param BufferSize Size of the buffer in bytes. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +EFIAPI +BufferToHexString ( + IN OUT CHAR16 *Str, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + UINT8 *NewBuffer; + UINTN StrBufferLen; + + NewBuffer = AllocateCopyPool (BufferSize, Buffer); + SwapBuffer (NewBuffer, BufferSize); + + StrBufferLen = (BufferSize + 1) * sizeof (CHAR16); + Status = R8_BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize); + + gBS->FreePool (NewBuffer); + + return Status; +} + + +/** + Converts Hex String to binary buffer in reversed byte order from R8_HexStringToBuf(). + + @param Buffer Pointer to buffer that receives the data. + @param BufferSize Length in bytes of the buffer to hold converted + data. If routine return with EFI_SUCCESS, + containing length of converted data. If routine + return with EFI_BUFFER_TOO_SMALL, containg length + of buffer desired. + @param Str String to be converted from. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +EFIAPI +HexStringToBuffer ( + IN OUT UINT8 *Buffer, + IN OUT UINTN *BufferSize, + IN CHAR16 *Str + ) +{ + EFI_STATUS Status; + UINTN ConvertedStrLen; + + ConvertedStrLen = 0; + Status = R8_HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen); + if (!EFI_ERROR (Status)) { + SwapBuffer (Buffer, ConvertedStrLen); + } + + return Status; +} + + +/** + Construct <ConfigHdr> using routing information GUID/NAME/PATH. + + @param ConfigHdr Pointer to the ConfigHdr string. + @param StrBufferLen On input: Length in bytes of buffer to hold the + ConfigHdr string. Includes tailing '\0' character. + On output: If return EFI_SUCCESS, containing + length of ConfigHdr string buffer. If return + EFI_BUFFER_TOO_SMALL, containg length of string + buffer desired. + @param Guid Routing information: GUID. + @param Name Routing information: NAME. + @param DriverHandle Driver handle which contains the routing + information: PATH. + + @retval EFI_SUCCESS Routine success. + @retval EFI_BUFFER_TOO_SMALL The ConfigHdr string buffer is too small. + +**/ +EFI_STATUS +EFIAPI +ConstructConfigHdr ( + IN OUT CHAR16 *ConfigHdr, + IN OUT UINTN *StrBufferLen, + IN EFI_GUID *Guid, + IN CHAR16 *Name, OPTIONAL + IN EFI_HANDLE *DriverHandle + ) +{ + EFI_STATUS Status; + UINTN NameStrLen; + UINTN DevicePathSize; + UINTN BufferSize; + CHAR16 *StrPtr; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + if (Name == NULL) { + // + // There will be no "NAME" in <ConfigHdr> for Name/Value storage + // + NameStrLen = 0; + } else { + // + // For buffer storage + // + NameStrLen = StrLen (Name); + } + + // + // Retrieve DevicePath Protocol associated with this HiiPackageList + // + Status = gBS->HandleProtocol ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevicePathSize = GetDevicePathSize (DevicePath); + + // + // GUID=<HexCh>32&NAME=<Alpha>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL> + // | 5 | 32 | 6 | NameStrLen | 6 | DevicePathStrLen | + // + BufferSize = (5 + 32 + 6 + NameStrLen + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16); + if (*StrBufferLen < BufferSize) { + *StrBufferLen = BufferSize; + return EFI_BUFFER_TOO_SMALL; + } + + *StrBufferLen = BufferSize; + + StrPtr = ConfigHdr; + + StrCpy (StrPtr, L"GUID="); + StrPtr += 5; + BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID)); + StrPtr += 32; + + StrCpy (StrPtr, L"&NAME="); + StrPtr += 6; + if (Name != NULL) { + StrCpy (StrPtr, Name); + StrPtr += NameStrLen; + } + + StrCpy (StrPtr, L"&PATH="); + StrPtr += 6; + BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize); + + return EFI_SUCCESS; +} + + +/** + Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string. + + @param String The string to be searched in. + @param Offset Offset in BlockName. + @param Width Width in BlockName. + + @retval TRUE Block name found. + @retval FALSE Block name not found. + +**/ +BOOLEAN +FindBlockName ( + IN OUT CHAR16 *String, + UINTN Offset, + UINTN Width + ) +{ + EFI_STATUS Status; + UINTN Data; + UINTN BufferSize; + UINTN ConvertedStrLen; + + while ((String = StrStr (String, L"&OFFSET=")) != NULL) { + // + // Skip '&OFFSET=' + // + String = String + 8; + + Data = 0; + BufferSize = sizeof (UINTN); + Status = R8_HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen); + if (EFI_ERROR (Status)) { + return FALSE; + } + String = String + ConvertedStrLen; + + if (Data != Offset) { + continue; + } + + if (StrnCmp (String, L"&WIDTH=", 7) != 0) { + return FALSE; + } + String = String + 7; + + Data = 0; + BufferSize = sizeof (UINTN); + Status = R8_HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen); + if (EFI_ERROR (Status)) { + return FALSE; + } + if (Data == Width) { + return TRUE; + } + + String = String + ConvertedStrLen; + } + + return FALSE; +} + + +/** + This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser. + + @param VariableGuid An optional field to indicate the target variable + GUID name to use. + @param VariableName An optional field to indicate the target + human-readable variable name. + @param BufferSize On input: Length in bytes of buffer to hold + retrived data. On output: If return + EFI_BUFFER_TOO_SMALL, containg length of buffer + desired. + @param Buffer Buffer to hold retrived data. + + @retval EFI_SUCCESS Routine success. + @retval EFI_BUFFER_TOO_SMALL The intput buffer is too small. + +**/ +EFI_STATUS +EFIAPI +GetBrowserData ( + EFI_GUID *VariableGuid, OPTIONAL + CHAR16 *VariableName, OPTIONAL + UINTN *BufferSize, + UINT8 *Buffer + ) +{ + EFI_STATUS Status; + CHAR16 *ConfigHdr; + CHAR16 *ConfigResp; + CHAR16 *StringPtr; + UINTN HeaderLen; + UINTN BufferLen; + CHAR16 *Progress; + EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + + // + // Locate protocols for use + // + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrive formset storage data from Form Browser + // + ConfigHdr = mFakeConfigHdr; + HeaderLen = StrLen (ConfigHdr); + + BufferLen = 0x4000; + ConfigResp = AllocateZeroPool (BufferLen + HeaderLen); + + StringPtr = ConfigResp + HeaderLen; + *StringPtr = L'&'; + StringPtr++; + + Status = FormBrowser2->BrowserCallback ( + FormBrowser2, + &BufferLen, + StringPtr, + TRUE, + VariableGuid, + VariableName + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + gBS->FreePool (ConfigResp); + ConfigResp = AllocateZeroPool (BufferLen + HeaderLen); + + StringPtr = ConfigResp + HeaderLen; + *StringPtr = L'&'; + StringPtr++; + + Status = FormBrowser2->BrowserCallback ( + FormBrowser2, + &BufferLen, + StringPtr, + TRUE, + VariableGuid, + VariableName + ); + } + if (EFI_ERROR (Status)) { + gBS->FreePool (ConfigResp); + return Status; + } + CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16)); + + // + // Convert <ConfigResp> to buffer data + // + Status = HiiConfigRouting->ConfigToBlock ( + HiiConfigRouting, + ConfigResp, + Buffer, + BufferSize, + &Progress + ); + gBS->FreePool (ConfigResp); + + return Status; +} + + +/** + This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser. + + @param VariableGuid An optional field to indicate the target variable + GUID name to use. + @param VariableName An optional field to indicate the target + human-readable variable name. + @param BufferSize Length in bytes of buffer to hold retrived data. + @param Buffer Buffer to hold retrived data. + @param RequestElement An optional field to specify which part of the + buffer data will be send back to Browser. If NULL, + the whole buffer of data will be committed to + Browser. <RequestElement> ::= + &OFFSET=<Number>&WIDTH=<Number>* + + @retval EFI_SUCCESS Routine success. + @retval Other Updating Browser uncommitted data failed. + +**/ +EFI_STATUS +EFIAPI +SetBrowserData ( + EFI_GUID *VariableGuid, OPTIONAL + CHAR16 *VariableName, OPTIONAL + UINTN BufferSize, + UINT8 *Buffer, + CHAR16 *RequestElement OPTIONAL + ) +{ + EFI_STATUS Status; + CHAR16 *ConfigHdr; + CHAR16 *ConfigResp; + CHAR16 *StringPtr; + UINTN HeaderLen; + UINTN BufferLen; + CHAR16 *Progress; + EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + CHAR16 BlockName[33]; + CHAR16 *ConfigRequest; + CHAR16 *Request; + + // + // Locate protocols for use + // + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Prepare <ConfigRequest> + // + ConfigHdr = mFakeConfigHdr; + HeaderLen = StrLen (ConfigHdr); + + if (RequestElement == NULL) { + // + // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName> + // + BlockName[0] = L'\0'; + StrCpy (BlockName, L"&OFFSET=0&WIDTH="); + + // + // String lenghth of L"&OFFSET=0&WIDTH=" is 16 + // + StringPtr = BlockName + 16; + BufferLen = sizeof (BlockName) - (16 * sizeof (CHAR16)); + R8_BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN)); + + Request = BlockName; + } else { + Request = RequestElement; + } + + BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request); + ConfigRequest = AllocateZeroPool (BufferLen); + + CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16)); + StringPtr = ConfigRequest + HeaderLen; + StrCpy (StringPtr, Request); + + // + // Convert buffer to <ConfigResp> + // + Status = HiiConfigRouting->BlockToConfig ( + HiiConfigRouting, + ConfigRequest, + Buffer, + BufferSize, + &ConfigResp, + &Progress + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (ConfigResp); + return Status; + } + + // + // Skip <ConfigHdr> and '&' + // + StringPtr = ConfigResp + HeaderLen + 1; + + // + // Change uncommitted data in Browser + // + Status = FormBrowser2->BrowserCallback ( + FormBrowser2, + &BufferSize, + StringPtr, + FALSE, + NULL, + NULL + ); + gBS->FreePool (ConfigResp); + return Status; +} diff --git a/MdePkg/Library/IfrSupportLib/UefiIfrLibraryInternal.h b/MdePkg/Library/IfrSupportLib/UefiIfrLibraryInternal.h new file mode 100644 index 0000000000..dd41c7aea3 --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/UefiIfrLibraryInternal.h @@ -0,0 +1,47 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UefiIfrLibraryInternal + +Abstract: + + The file contain all library function for Ifr Operations. + + +**/ + +#ifndef _IFRLIBRARY_INTERNAL_H +#define _IFRLIBRARY_INTERNAL_H + + +#include <PiDxe.h> + +#include <Guid/GlobalVariable.h> +#include <Protocol/DevicePath.h> + +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h> +#include <Library/DevicePathLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IfrSupportLib.h> +#include <Library/HiiLib.h> +#include <Library/PcdLib.h> + +//#include <MdeModuleHii.h> + +#include "R8Lib.h" + +#endif diff --git a/MdePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c b/MdePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c new file mode 100644 index 0000000000..f2f82e06db --- /dev/null +++ b/MdePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c @@ -0,0 +1,618 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UefiIfrOpCodeCreation.c + +Abstract: + + Library Routines to create IFR independent of string data - assume tokens already exist + Primarily to be used for exporting op-codes at a label in pre-defined forms. + +Revision History: + + +**/ + +#include "UefiIfrLibraryInternal.h" + +STATIC +BOOLEAN +IsValidQuestionFlags ( + IN UINT8 Flags + ) +{ + return (BOOLEAN) ((Flags & (~QUESTION_FLAGS)) ? FALSE : TRUE); +} + +STATIC +BOOLEAN +IsValidValueType ( + IN UINT8 Type + ) +{ + return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE); +} + +STATIC +BOOLEAN +IsValidNumricFlags ( + IN UINT8 Flags + ) +{ + if (Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) { + return FALSE; + } + + if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) { + return FALSE; + } + + return TRUE; +} + +STATIC +BOOLEAN +IsValidCheckboxFlags ( + IN UINT8 Flags + ) +{ + return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE); +} + +EFI_STATUS +EFIAPI +CreateEndOpCode ( + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_END End; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + End.Header.Length = sizeof (EFI_IFR_END); + End.Header.OpCode = EFI_IFR_END_OP; + End.Header.Scope = 0; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END)); + Data->Offset += sizeof (EFI_IFR_END); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateDefaultOpCode ( + IN EFI_IFR_TYPE_VALUE *Value, + IN UINT8 Type, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_DEFAULT Default; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if ((Value == NULL) || !IsValidValueType (Type)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Default.Header.OpCode = EFI_IFR_DEFAULT_OP; + Default.Header.Length = sizeof (EFI_IFR_DEFAULT); + Default.Header.Scope = 0; + Default.Type = Type; + Default.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD; + CopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE)); + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT)); + Data->Offset += sizeof (EFI_IFR_DEFAULT); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateActionOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_STRING_ID QuestionConfig, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_ACTION Action; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Action.Header.OpCode = EFI_IFR_ACTION_OP; + Action.Header.Length = sizeof (EFI_IFR_ACTION); + Action.Header.Scope = 0; + Action.Question.QuestionId = QuestionId; + Action.Question.Header.Prompt = Prompt; + Action.Question.Header.Help = Help; + Action.Question.VarStoreId = INVALID_VARSTORE_ID; + Action.Question.Flags = QuestionFlags; + Action.QuestionConfig = QuestionConfig; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION)); + Data->Offset += sizeof (EFI_IFR_ACTION); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateSubTitleOpCode ( + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 Flags, + IN UINT8 Scope, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_SUBTITLE Subtitle; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP; + Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE); + Subtitle.Header.Scope = Scope; + Subtitle.Statement.Prompt = Prompt; + Subtitle.Statement.Help = Help; + Subtitle.Flags = Flags; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE)); + Data->Offset += sizeof (EFI_IFR_SUBTITLE); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +CreateTextOpCode ( + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN EFI_STRING_ID TextTwo, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_TEXT Text; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Text.Header.OpCode = EFI_IFR_TEXT_OP; + Text.Header.Length = sizeof (EFI_IFR_TEXT); + Text.Header.Scope = 0; + Text.Statement.Prompt = Prompt; + Text.Statement.Help = Help; + Text.TextTwo = TextTwo; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT)); + Data->Offset += sizeof (EFI_IFR_TEXT); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateGotoOpCode ( + IN EFI_FORM_ID FormId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_QUESTION_ID QuestionId, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_REF Goto; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Goto.Header.OpCode = EFI_IFR_REF_OP; + Goto.Header.Length = sizeof (EFI_IFR_REF); + Goto.Header.Scope = 0; + Goto.Question.Header.Prompt = Prompt; + Goto.Question.Header.Help = Help; + Goto.Question.VarStoreId = INVALID_VARSTORE_ID; + Goto.Question.QuestionId = QuestionId; + Goto.Question.Flags = QuestionFlags; + Goto.FormId = FormId; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF)); + Data->Offset += sizeof (EFI_IFR_REF); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateOneOfOptionOpCode ( + IN UINTN OptionCount, + IN IFR_OPTION *OptionsList, + IN UINT8 Type, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + UINTN Index; + UINT8 *LocalBuffer; + EFI_IFR_ONE_OF_OPTION OneOfOption; + + ASSERT (Data != NULL && Data->Data != NULL); + + if ((OptionCount != 0) && (OptionsList == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + for (Index = 0; Index < OptionCount; Index++) { + OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP; + OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION); + OneOfOption.Header.Scope = 0; + + OneOfOption.Option = OptionsList[Index].StringToken; + OneOfOption.Value = OptionsList[Index].Value; + OneOfOption.Flags = (UINT8) (OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)); + OneOfOption.Type = Type; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION)); + Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateOneOfOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OneOfFlags, + IN IFR_OPTION *OptionsList, + IN UINTN OptionCount, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + UINTN Length; + EFI_IFR_ONE_OF OneOf; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidNumricFlags (OneOfFlags) || + !IsValidQuestionFlags (QuestionFlags) || + ((OptionCount != 0) && (OptionsList == NULL))) { + return EFI_INVALID_PARAMETER; + } + + Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END); + if (Data->Offset + Length > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP; + OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF); + OneOf.Header.Scope = 1; + OneOf.Question.Header.Prompt = Prompt; + OneOf.Question.Header.Help = Help; + OneOf.Question.QuestionId = QuestionId; + OneOf.Question.VarStoreId = VarStoreId; + OneOf.Question.VarStoreInfo.VarOffset = VarOffset; + OneOf.Question.Flags = QuestionFlags; + OneOf.Flags = OneOfFlags; + ZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA)); + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF)); + Data->Offset += sizeof (EFI_IFR_ONE_OF); + + CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8) (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data); + + CreateEndOpCode (Data); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateOrderedListOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 OrderedListFlags, + IN UINT8 DataType, + IN UINT8 MaxContainers, + IN IFR_OPTION *OptionsList, + IN UINTN OptionCount, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + UINTN Length; + EFI_IFR_ORDERED_LIST OrderedList; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags) || + ((OptionCount != 0) && (OptionsList == NULL))) { + return EFI_INVALID_PARAMETER; + } + + if ((OrderedListFlags != 0) && + (OrderedListFlags != EFI_IFR_UNIQUE_SET) && + (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) { + return EFI_INVALID_PARAMETER; + } + + Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END); + if (Data->Offset + Length > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP; + OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST); + OrderedList.Header.Scope = 1; + OrderedList.Question.Header.Prompt = Prompt; + OrderedList.Question.Header.Help = Help; + OrderedList.Question.QuestionId = QuestionId; + OrderedList.Question.VarStoreId = VarStoreId; + OrderedList.Question.VarStoreInfo.VarOffset = VarOffset; + OrderedList.Question.Flags = QuestionFlags; + OrderedList.MaxContainers = MaxContainers; + OrderedList.Flags = OrderedListFlags; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST)); + Data->Offset += sizeof (EFI_IFR_ORDERED_LIST); + + CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data); + + CreateEndOpCode (Data); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateCheckBoxOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 CheckBoxFlags, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_CHECKBOX CheckBox; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP; + CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX); + CheckBox.Header.Scope = 0; + CheckBox.Question.QuestionId = QuestionId; + CheckBox.Question.VarStoreId = VarStoreId; + CheckBox.Question.VarStoreInfo.VarOffset = VarOffset; + CheckBox.Question.Header.Prompt = Prompt; + CheckBox.Question.Header.Help = Help; + CheckBox.Question.Flags = QuestionFlags; + CheckBox.Flags = CheckBoxFlags; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX)); + Data->Offset += sizeof (EFI_IFR_CHECKBOX); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateNumericOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 NumericFlags, + IN UINT64 Minimum, + IN UINT64 Maximum, + IN UINT64 Step, + IN UINT64 Default, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_STATUS Status; + EFI_IFR_NUMERIC Numeric; + MINMAXSTEP_DATA MinMaxStep; + EFI_IFR_TYPE_VALUE DefaultValue; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP; + Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC); + Numeric.Header.Scope = 1; + Numeric.Question.QuestionId = QuestionId; + Numeric.Question.VarStoreId = VarStoreId; + Numeric.Question.VarStoreInfo.VarOffset = VarOffset; + Numeric.Question.Header.Prompt = Prompt; + Numeric.Question.Header.Help = Help; + Numeric.Question.Flags = QuestionFlags; + Numeric.Flags = NumericFlags; + + switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + MinMaxStep.u8.MinValue = (UINT8) Minimum; + MinMaxStep.u8.MaxValue = (UINT8) Maximum; + MinMaxStep.u8.Step = (UINT8) Step; + break; + + case EFI_IFR_NUMERIC_SIZE_2: + MinMaxStep.u16.MinValue = (UINT16) Minimum; + MinMaxStep.u16.MaxValue = (UINT16) Maximum; + MinMaxStep.u16.Step = (UINT16) Step; + break; + + case EFI_IFR_NUMERIC_SIZE_4: + MinMaxStep.u32.MinValue = (UINT32) Minimum; + MinMaxStep.u32.MaxValue = (UINT32) Maximum; + MinMaxStep.u32.Step = (UINT32) Step; + break; + + case EFI_IFR_NUMERIC_SIZE_8: + MinMaxStep.u64.MinValue = Minimum; + MinMaxStep.u64.MaxValue = Maximum; + MinMaxStep.u64.Step = Step; + break; + } + + CopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA)); + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC)); + Data->Offset += sizeof (EFI_IFR_NUMERIC); + + DefaultValue.u64 = Default; + Status = CreateDefaultOpCode (&DefaultValue, (UINT8) (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data); + if (EFI_ERROR(Status)) { + return Status; + } + + CreateEndOpCode (Data); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CreateStringOpCode ( + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId, + IN UINT16 VarOffset, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 StringFlags, + IN UINT8 MinSize, + IN UINT8 MaxSize, + IN OUT EFI_HII_UPDATE_DATA *Data + ) +{ + EFI_IFR_STRING String; + UINT8 *LocalBuffer; + + ASSERT (Data != NULL && Data->Data != NULL); + + if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & (~EFI_IFR_STRING_MULTI_LINE))) { + return EFI_INVALID_PARAMETER; + } + + if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + String.Header.OpCode = EFI_IFR_STRING_OP; + String.Header.Length = sizeof (EFI_IFR_STRING); + String.Header.Scope = 0; + String.Question.Header.Prompt = Prompt; + String.Question.Header.Help = Help; + String.Question.QuestionId = QuestionId; + String.Question.VarStoreId = VarStoreId; + String.Question.VarStoreInfo.VarOffset = VarOffset; + String.Question.Flags = QuestionFlags; + String.MinSize = MinSize; + String.MaxSize = MaxSize; + String.Flags = StringFlags; + + LocalBuffer = (UINT8 *) Data->Data + Data->Offset; + CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING)); + Data->Offset += sizeof (EFI_IFR_STRING); + + return EFI_SUCCESS; +} + + |