diff options
-rw-r--r-- | MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c | 1886 | ||||
-rw-r--r-- | MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h | 70 | ||||
-rw-r--r-- | MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c | 1782 |
3 files changed, 1869 insertions, 1869 deletions
diff --git a/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c b/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c index f41fc25d52..5613a50d3e 100644 --- a/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c +++ b/MdePkg/Library/UefiIfrSupportLib/UefiIfrForm.c @@ -1,943 +1,943 @@ -/** @file -Utility functions which helps in opcode creation, HII configuration string manipulations, -pop up window creations, setup browser persistence data set and get. - -Copyright (c) 2007- 2008, 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" - -CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2 = NULL; -CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mIfrSupportLibHiiConfigRouting = NULL; - -/** - This function locate FormBrowser2 protocols for later usage. - - @return Status the status to locate protocol. -**/ -EFI_STATUS -LocateFormBrowser2Protocols ( - VOID - ) -{ - EFI_STATUS Status; - // - // Locate protocols for later usage - // - if (mFormBrowser2 == NULL) { - Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2); - if (EFI_ERROR (Status)) { - return Status; - } - } - - if (mIfrSupportLibHiiConfigRouting == NULL) { - Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mIfrSupportLibHiiConfigRouting); - if (EFI_ERROR (Status)) { - return Status; - } - } - - return EFI_SUCCESS; -} - -// -// Fake <ConfigHdr> -// -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0"; - -/** - 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 Marker A series of (quantity == NumberOfLines - 1) 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. - @retval EFI_OUT_OF_RESOURCES There is no enough available memory space. - -**/ -EFI_STATUS -EFIAPI -IfrLibCreatePopUp2 ( - IN UINTN NumberOfLines, - OUT EFI_INPUT_KEY *KeyValue, - IN VA_LIST Marker - ) -{ - UINTN Index; - UINTN Count; - UINTN Start; - UINTN Top; - CHAR16 *StringPtr; - UINTN LeftColumn; - UINTN RightColumn; - UINTN TopRow; - UINTN BottomRow; - UINTN DimensionsWidth; - UINTN DimensionsHeight; - 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; - CHAR16 *String; - - String = VA_ARG (Marker, CHAR16 *); - - 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)); - if (LineBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // 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 *)); - if (StringArray == NULL) { - FreePool (LineBuffer); - return EFI_OUT_OF_RESOURCES; - } - LargestString = StrLen (String); - StringArray[0] = String; - - for (Index = 1; Index < NumberOfLines; Index++) { - StackString = VA_ARG (Marker, CHAR16 *); - - if (StackString == NULL) { - FreePool (LineBuffer); - FreePool (StringArray); - 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); - - FreePool (LineBuffer); - FreePool (StringArray); - - return Status; -} - - -/** - 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 - 1) 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, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Marker; - - VA_START (Marker, KeyValue); - - Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, Marker); - - VA_END (Marker); - - return Status; -} - -/** - Swap bytes in the buffer. This is a internal function. - - @param Buffer Binary buffer. - @param BufferSize Size of the buffer in bytes. - - @return None. - -**/ -VOID -SwapBuffer ( - IN OUT UINT8 *Buffer, - IN UINTN BufferSize - ) -{ - UINTN Index; - UINT8 Temp; - UINTN SwapCount; - - SwapCount = BufferSize / 2; - for (Index = 0; Index < SwapCount; Index++) { - Temp = Buffer[Index]; - Buffer[Index] = Buffer[BufferSize - 1 - Index]; - Buffer[BufferSize - 1 - Index] = Temp; - } -} - -/** - Converts the unicode character of the string from uppercase to lowercase. - This is a internal function. - - @param Str String to be converted - -**/ -VOID -EFIAPI -ToLower ( - IN OUT CHAR16 *Str - ) -{ - CHAR16 *Ptr; - - for (Ptr = Str; *Ptr != L'\0'; Ptr++) { - if (*Ptr >= L'A' && *Ptr <= L'Z') { - *Ptr = (CHAR16) (*Ptr - L'A' + L'a'); - } - } -} - - -/** - Converts binary buffer to Unicode string in reversed byte order from 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. - @retval EFI_OUT_OF_RESOURCES There is no enough available memory space. - -**/ -EFI_STATUS -EFIAPI -BufInReverseOrderToHexString ( - IN OUT CHAR16 *Str, - IN UINT8 *Buffer, - IN UINTN BufferSize - ) -{ - EFI_STATUS Status; - UINT8 *NewBuffer; - UINTN StrBufferLen; - - NewBuffer = AllocateCopyPool (BufferSize, Buffer); - if (NewBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - SwapBuffer (NewBuffer, BufferSize); - - StrBufferLen = BufferSize * sizeof (CHAR16) + 1; - Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize); - - FreePool (NewBuffer); - // - // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format. - // - ToLower (Str); - - return Status; -} - - -/** - Converts Hex String to binary buffer in reversed byte order from 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. - @retval RETURN_BUFFER_TOO_SMALL The input BufferSize is too small to hold the output. BufferSize - will be updated to the size required for the converstion. - -**/ -EFI_STATUS -EFIAPI -HexStringToBufInReverseOrder ( - IN OUT UINT8 *Buffer, - IN OUT UINTN *BufferSize, - IN CHAR16 *Str - ) -{ - EFI_STATUS Status; - UINTN ConvertedStrLen; - - ConvertedStrLen = 0; - Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen); - if (!EFI_ERROR (Status)) { - SwapBuffer (Buffer, ConvertedStrLen); - } - - return Status; -} - -/** - Convert binary representation Config string (e.g. "0041004200430044") to the - original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e. - "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>"). - - @param UnicodeString Original Unicode string. - @param StrBufferLen On input: Length in bytes of buffer to hold the Unicode string. - Includes tailing '\0' character. - On output: - If return EFI_SUCCESS, containing length of Unicode string buffer. - If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired. - @param ConfigString Binary representation of Unicode String, <string> := (<HexCh>4)+ - - @retval EFI_SUCCESS Operation completes successfully. - @retval EFI_BUFFER_TOO_SMALL The string buffer is too small. - -**/ -EFI_STATUS -EFIAPI -ConfigStringToUnicode ( - IN OUT CHAR16 *UnicodeString, - IN OUT UINTN *StrBufferLen, - IN CHAR16 *ConfigString - ) -{ - UINTN Index; - UINTN Len; - UINTN BufferSize; - CHAR16 BackupChar; - - Len = StrLen (ConfigString) / 4; - BufferSize = (Len + 1) * sizeof (CHAR16); - - if (*StrBufferLen < BufferSize) { - *StrBufferLen = BufferSize; - return EFI_BUFFER_TOO_SMALL; - } - - *StrBufferLen = BufferSize; - - for (Index = 0; Index < Len; Index++) { - BackupChar = ConfigString[4]; - ConfigString[4] = L'\0'; - - HexStringToBuf ((UINT8 *) UnicodeString, &BufferSize, ConfigString, NULL); - - ConfigString[4] = BackupChar; - - ConfigString += 4; - UnicodeString += 1; - } - - // - // Add tailing '\0' character - // - *UnicodeString = L'\0'; - - return EFI_SUCCESS; -} - -/** - Convert Unicode string to binary representation Config string, e.g. - "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e. - "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>"). - - @param ConfigString Binary representation of Unicode String, <string> := (<HexCh>4)+ - @param StrBufferLen On input: Length in bytes of buffer to hold the Unicode string. - Includes tailing '\0' character. - On output: - If return EFI_SUCCESS, containing length of Unicode string buffer. - If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired. - @param UnicodeString Original Unicode string. - - @retval EFI_SUCCESS Operation completes successfully. - @retval EFI_BUFFER_TOO_SMALL The string buffer is too small. - -**/ -EFI_STATUS -EFIAPI -UnicodeToConfigString ( - IN OUT CHAR16 *ConfigString, - IN OUT UINTN *StrBufferLen, - IN CHAR16 *UnicodeString - ) -{ - UINTN Index; - UINTN Len; - UINTN BufferSize; - CHAR16 *String; - - Len = StrLen (UnicodeString); - BufferSize = (Len * 4 + 1) * sizeof (CHAR16); - - if (*StrBufferLen < BufferSize) { - *StrBufferLen = BufferSize; - return EFI_BUFFER_TOO_SMALL; - } - - *StrBufferLen = BufferSize; - String = ConfigString; - - for (Index = 0; Index < Len; Index++) { - BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2); - - ConfigString += 4; - UnicodeString += 1; - } - - // - // Add tailing '\0' character - // - *ConfigString = L'\0'; - - // - // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format. - // - ToLower (String); - return EFI_SUCCESS; -} - -/** - 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 Operation completes successfully. - @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 CONST 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=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL> - // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 | - // - BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 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; - BufInReverseOrderToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID)); - StrPtr += 32; - - // - // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044" - // - StrCpy (StrPtr, L"&NAME="); - StrPtr += 6; - if (Name != NULL) { - BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16); - UnicodeToConfigString (StrPtr, &BufferSize, Name); - StrPtr += (NameStrLen * 4); - } - - StrCpy (StrPtr, L"&PATH="); - StrPtr += 6; - BufInReverseOrderToHexString (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 -EFIAPI -FindBlockName ( - IN OUT CHAR16 *String, - IN UINTN Offset, - IN 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 = 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 = 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 Operation completes successfully. - @retval EFI_BUFFER_TOO_SMALL The intput buffer is too small. - @retval EFI_OUT_OF_RESOURCES There is no enough available memory space. - -**/ -EFI_STATUS -EFIAPI -GetBrowserData ( - IN CONST EFI_GUID *VariableGuid, OPTIONAL - IN CONST CHAR16 *VariableName, OPTIONAL - IN OUT UINTN *BufferSize, - IN OUT UINT8 *Buffer - ) -{ - EFI_STATUS Status; - CONST CHAR16 *ConfigHdr; - CHAR16 *ConfigResp; - CHAR16 *StringPtr; - UINTN HeaderLen; - UINTN BufferLen; - CHAR16 *Progress; - - // - // Locate protocols for use - // - Status = LocateFormBrowser2Protocols (); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Retrive formset storage data from Form Browser - // - ConfigHdr = mFakeConfigHdr; - HeaderLen = StrLen (ConfigHdr); - - // - // First try allocate 0x4000 buffer for the formet storage data. - // - BufferLen = 0x4000; - ConfigResp = AllocateZeroPool (BufferLen + HeaderLen); - if (ConfigResp == NULL) { - BufferLen = 0; - } - - StringPtr = ConfigResp + HeaderLen; - *StringPtr = L'&'; - StringPtr++; - - Status = mFormBrowser2->BrowserCallback ( - mFormBrowser2, - &BufferLen, - StringPtr, - TRUE, - VariableGuid, - VariableName - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - if (ConfigResp != NULL) { - FreePool (ConfigResp); - } - - ConfigResp = AllocateZeroPool (BufferLen + HeaderLen); - if (ConfigResp == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - StringPtr = ConfigResp + HeaderLen; - *StringPtr = L'&'; - StringPtr++; - - Status = mFormBrowser2->BrowserCallback ( - mFormBrowser2, - &BufferLen, - StringPtr, - TRUE, - VariableGuid, - VariableName - ); - } - if (EFI_ERROR (Status)) { - FreePool (ConfigResp); - return Status; - } - CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16)); - - // - // Convert <ConfigResp> to buffer data - // - Status = mIfrSupportLibHiiConfigRouting->ConfigToBlock ( - mIfrSupportLibHiiConfigRouting, - ConfigResp, - Buffer, - BufferSize, - &Progress - ); - 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 Operation completes successfully. - @retval EFI_OUT_OF_RESOURCES There is no enough available memory space. - @retval Other Updating Browser uncommitted data failed. - -**/ -EFI_STATUS -EFIAPI -SetBrowserData ( - IN CONST EFI_GUID *VariableGuid, OPTIONAL - IN CONST CHAR16 *VariableName, OPTIONAL - IN UINTN BufferSize, - IN CONST UINT8 *Buffer, - IN CONST CHAR16 *RequestElement OPTIONAL - ) -{ - EFI_STATUS Status; - CONST CHAR16 *ConfigHdr; - CHAR16 *ConfigResp; - CHAR16 *StringPtr; - UINTN HeaderLen; - UINTN BufferLen; - CHAR16 *Progress; - CHAR16 BlockName[33]; - CHAR16 *ConfigRequest; - CONST CHAR16 *Request; - - // - // Locate protocols for use - // - Status = LocateFormBrowser2Protocols (); - 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)); - BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN)); - - Request = BlockName; - } else { - Request = RequestElement; - } - - BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request); - ConfigRequest = AllocateZeroPool (BufferLen); - if (ConfigRequest == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16)); - StringPtr = ConfigRequest + HeaderLen; - StrCpy (StringPtr, Request); - - // - // Convert buffer to <ConfigResp> - // - Status = mIfrSupportLibHiiConfigRouting->BlockToConfig ( - mIfrSupportLibHiiConfigRouting, - ConfigRequest, - Buffer, - BufferSize, - &ConfigResp, - &Progress - ); - if (EFI_ERROR (Status)) { - FreePool (ConfigRequest); - return Status; - } - - // - // Skip <ConfigHdr> and '&' - // - StringPtr = ConfigResp + HeaderLen + 1; - - // - // Change uncommitted data in Browser - // - Status = mFormBrowser2->BrowserCallback ( - mFormBrowser2, - &BufferSize, - StringPtr, - FALSE, - NULL, - NULL - ); - FreePool (ConfigRequest); - return Status; -} +/** @file
+Utility functions which helps in opcode creation, HII configuration string manipulations,
+pop up window creations, setup browser persistence data set and get.
+
+Copyright (c) 2007- 2008, 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"
+
+CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2 = NULL;
+CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mIfrSupportLibHiiConfigRouting = NULL;
+
+/**
+ This function locate FormBrowser2 protocols for later usage.
+
+ @return Status the status to locate protocol.
+**/
+EFI_STATUS
+LocateFormBrowser2Protocols (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ //
+ // Locate protocols for later usage
+ //
+ if (mFormBrowser2 == NULL) {
+ Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ if (mIfrSupportLibHiiConfigRouting == NULL) {
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mIfrSupportLibHiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Fake <ConfigHdr>
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
+
+/**
+ 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 Marker A series of (quantity == NumberOfLines - 1) 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.
+ @retval EFI_OUT_OF_RESOURCES There is no enough available memory space.
+
+**/
+EFI_STATUS
+EFIAPI
+IfrLibCreatePopUp2 (
+ IN UINTN NumberOfLines,
+ OUT EFI_INPUT_KEY *KeyValue,
+ IN VA_LIST Marker
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN Start;
+ UINTN Top;
+ CHAR16 *StringPtr;
+ UINTN LeftColumn;
+ UINTN RightColumn;
+ UINTN TopRow;
+ UINTN BottomRow;
+ UINTN DimensionsWidth;
+ UINTN DimensionsHeight;
+ 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;
+ CHAR16 *String;
+
+ String = VA_ARG (Marker, CHAR16 *);
+
+ 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));
+ if (LineBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // 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 *));
+ if (StringArray == NULL) {
+ FreePool (LineBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ LargestString = StrLen (String);
+ StringArray[0] = String;
+
+ for (Index = 1; Index < NumberOfLines; Index++) {
+ StackString = VA_ARG (Marker, CHAR16 *);
+
+ if (StackString == NULL) {
+ FreePool (LineBuffer);
+ FreePool (StringArray);
+ 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);
+
+ FreePool (LineBuffer);
+ FreePool (StringArray);
+
+ return Status;
+}
+
+
+/**
+ 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 - 1) 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,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Marker;
+
+ VA_START (Marker, KeyValue);
+
+ Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, Marker);
+
+ VA_END (Marker);
+
+ return Status;
+}
+
+/**
+ Swap bytes in the buffer. This is a internal function.
+
+ @param Buffer Binary buffer.
+ @param BufferSize Size of the buffer in bytes.
+
+ @return None.
+
+**/
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Index;
+ UINT8 Temp;
+ UINTN SwapCount;
+
+ SwapCount = BufferSize / 2;
+ for (Index = 0; Index < SwapCount; Index++) {
+ Temp = Buffer[Index];
+ Buffer[Index] = Buffer[BufferSize - 1 - Index];
+ Buffer[BufferSize - 1 - Index] = Temp;
+ }
+}
+
+/**
+ Converts the unicode character of the string from uppercase to lowercase.
+ This is a internal function.
+
+ @param Str String to be converted
+
+**/
+VOID
+EFIAPI
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+{
+ CHAR16 *Ptr;
+
+ for (Ptr = Str; *Ptr != L'\0'; Ptr++) {
+ if (*Ptr >= L'A' && *Ptr <= L'Z') {
+ *Ptr = (CHAR16) (*Ptr - L'A' + L'a');
+ }
+ }
+}
+
+
+/**
+ Converts binary buffer to Unicode string in reversed byte order from 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.
+ @retval EFI_OUT_OF_RESOURCES There is no enough available memory space.
+
+**/
+EFI_STATUS
+EFIAPI
+BufInReverseOrderToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *NewBuffer;
+ UINTN StrBufferLen;
+
+ NewBuffer = AllocateCopyPool (BufferSize, Buffer);
+ if (NewBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SwapBuffer (NewBuffer, BufferSize);
+
+ StrBufferLen = BufferSize * sizeof (CHAR16) + 1;
+ Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
+
+ FreePool (NewBuffer);
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (Str);
+
+ return Status;
+}
+
+
+/**
+ Converts Hex String to binary buffer in reversed byte order from 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.
+ @retval RETURN_BUFFER_TOO_SMALL The input BufferSize is too small to hold the output. BufferSize
+ will be updated to the size required for the converstion.
+
+**/
+EFI_STATUS
+EFIAPI
+HexStringToBufInReverseOrder (
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize,
+ IN CHAR16 *Str
+ )
+{
+ EFI_STATUS Status;
+ UINTN ConvertedStrLen;
+
+ ConvertedStrLen = 0;
+ Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);
+ if (!EFI_ERROR (Status)) {
+ SwapBuffer (Buffer, ConvertedStrLen);
+ }
+
+ return Status;
+}
+
+/**
+ Convert binary representation Config string (e.g. "0041004200430044") to the
+ original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+ @param UnicodeString Original Unicode string.
+ @param StrBufferLen On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ @param ConfigString Binary representation of Unicode String, <string> := (<HexCh>4)+
+
+ @retval EFI_SUCCESS Operation completes successfully.
+ @retval EFI_BUFFER_TOO_SMALL The string buffer is too small.
+
+**/
+EFI_STATUS
+EFIAPI
+ConfigStringToUnicode (
+ IN OUT CHAR16 *UnicodeString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *ConfigString
+ )
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 BackupChar;
+
+ Len = StrLen (ConfigString) / 4;
+ BufferSize = (Len + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+
+ for (Index = 0; Index < Len; Index++) {
+ BackupChar = ConfigString[4];
+ ConfigString[4] = L'\0';
+
+ HexStringToBuf ((UINT8 *) UnicodeString, &BufferSize, ConfigString, NULL);
+
+ ConfigString[4] = BackupChar;
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *UnicodeString = L'\0';
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert Unicode string to binary representation Config string, e.g.
+ "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+ @param ConfigString Binary representation of Unicode String, <string> := (<HexCh>4)+
+ @param StrBufferLen On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ @param UnicodeString Original Unicode string.
+
+ @retval EFI_SUCCESS Operation completes successfully.
+ @retval EFI_BUFFER_TOO_SMALL The string buffer is too small.
+
+**/
+EFI_STATUS
+EFIAPI
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ )
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 *String;
+
+ Len = StrLen (UnicodeString);
+ BufferSize = (Len * 4 + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+ String = ConfigString;
+
+ for (Index = 0; Index < Len; Index++) {
+ BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *ConfigString = L'\0';
+
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (String);
+ return EFI_SUCCESS;
+}
+
+/**
+ 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 Operation completes successfully.
+ @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 CONST 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=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 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;
+ BufInReverseOrderToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
+ StrPtr += 32;
+
+ //
+ // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
+ //
+ StrCpy (StrPtr, L"&NAME=");
+ StrPtr += 6;
+ if (Name != NULL) {
+ BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);
+ UnicodeToConfigString (StrPtr, &BufferSize, Name);
+ StrPtr += (NameStrLen * 4);
+ }
+
+ StrCpy (StrPtr, L"&PATH=");
+ StrPtr += 6;
+ BufInReverseOrderToHexString (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
+EFIAPI
+FindBlockName (
+ IN OUT CHAR16 *String,
+ IN UINTN Offset,
+ IN 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 = 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 = 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 Operation completes successfully.
+ @retval EFI_BUFFER_TOO_SMALL The intput buffer is too small.
+ @retval EFI_OUT_OF_RESOURCES There is no enough available memory space.
+
+**/
+EFI_STATUS
+EFIAPI
+GetBrowserData (
+ IN CONST EFI_GUID *VariableGuid, OPTIONAL
+ IN CONST CHAR16 *VariableName, OPTIONAL
+ IN OUT UINTN *BufferSize,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ CONST CHAR16 *ConfigHdr;
+ CHAR16 *ConfigResp;
+ CHAR16 *StringPtr;
+ UINTN HeaderLen;
+ UINTN BufferLen;
+ CHAR16 *Progress;
+
+ //
+ // Locate protocols for use
+ //
+ Status = LocateFormBrowser2Protocols ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrive formset storage data from Form Browser
+ //
+ ConfigHdr = mFakeConfigHdr;
+ HeaderLen = StrLen (ConfigHdr);
+
+ //
+ // First try allocate 0x4000 buffer for the formet storage data.
+ //
+ BufferLen = 0x4000;
+ ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
+ if (ConfigResp == NULL) {
+ BufferLen = 0;
+ }
+
+ StringPtr = ConfigResp + HeaderLen;
+ *StringPtr = L'&';
+ StringPtr++;
+
+ Status = mFormBrowser2->BrowserCallback (
+ mFormBrowser2,
+ &BufferLen,
+ StringPtr,
+ TRUE,
+ VariableGuid,
+ VariableName
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ if (ConfigResp != NULL) {
+ FreePool (ConfigResp);
+ }
+
+ ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
+ if (ConfigResp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StringPtr = ConfigResp + HeaderLen;
+ *StringPtr = L'&';
+ StringPtr++;
+
+ Status = mFormBrowser2->BrowserCallback (
+ mFormBrowser2,
+ &BufferLen,
+ StringPtr,
+ TRUE,
+ VariableGuid,
+ VariableName
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
+ CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16));
+
+ //
+ // Convert <ConfigResp> to buffer data
+ //
+ Status = mIfrSupportLibHiiConfigRouting->ConfigToBlock (
+ mIfrSupportLibHiiConfigRouting,
+ ConfigResp,
+ Buffer,
+ BufferSize,
+ &Progress
+ );
+ 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 Operation completes successfully.
+ @retval EFI_OUT_OF_RESOURCES There is no enough available memory space.
+ @retval Other Updating Browser uncommitted data failed.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBrowserData (
+ IN CONST EFI_GUID *VariableGuid, OPTIONAL
+ IN CONST CHAR16 *VariableName, OPTIONAL
+ IN UINTN BufferSize,
+ IN CONST UINT8 *Buffer,
+ IN CONST CHAR16 *RequestElement OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CONST CHAR16 *ConfigHdr;
+ CHAR16 *ConfigResp;
+ CHAR16 *StringPtr;
+ UINTN HeaderLen;
+ UINTN BufferLen;
+ CHAR16 *Progress;
+ CHAR16 BlockName[33];
+ CHAR16 *ConfigRequest;
+ CONST CHAR16 *Request;
+
+ //
+ // Locate protocols for use
+ //
+ Status = LocateFormBrowser2Protocols ();
+ 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));
+ BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN));
+
+ Request = BlockName;
+ } else {
+ Request = RequestElement;
+ }
+
+ BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request);
+ ConfigRequest = AllocateZeroPool (BufferLen);
+ if (ConfigRequest == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16));
+ StringPtr = ConfigRequest + HeaderLen;
+ StrCpy (StringPtr, Request);
+
+ //
+ // Convert buffer to <ConfigResp>
+ //
+ Status = mIfrSupportLibHiiConfigRouting->BlockToConfig (
+ mIfrSupportLibHiiConfigRouting,
+ ConfigRequest,
+ Buffer,
+ BufferSize,
+ &ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigRequest);
+ return Status;
+ }
+
+ //
+ // Skip <ConfigHdr> and '&'
+ //
+ StringPtr = ConfigResp + HeaderLen + 1;
+
+ //
+ // Change uncommitted data in Browser
+ //
+ Status = mFormBrowser2->BrowserCallback (
+ mFormBrowser2,
+ &BufferSize,
+ StringPtr,
+ FALSE,
+ NULL,
+ NULL
+ );
+ FreePool (ConfigRequest);
+ return Status;
+}
diff --git a/MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h b/MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h index 4b53f18eb9..43897b9920 100644 --- a/MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h +++ b/MdePkg/Library/UefiIfrSupportLib/UefiIfrLibraryInternal.h @@ -1,37 +1,37 @@ -/** @file -Utility functions which helps in opcode creation, HII configuration string manipulations, -pop up window creations, setup browser persistence data set and get. - -Copyright (c) 2007 - 2008, 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. - - -**/ - -#ifndef _IFRLIBRARY_INTERNAL_H_ -#define _IFRLIBRARY_INTERNAL_H_ - - -#include <Uefi.h> - -#include <Protocol/DevicePath.h> +/** @file
+Utility functions which helps in opcode creation, HII configuration string manipulations,
+pop up window creations, setup browser persistence data set and get.
+
+Copyright (c) 2007 - 2008, 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.
+
+
+**/
+
+#ifndef _IFRLIBRARY_INTERNAL_H_
+#define _IFRLIBRARY_INTERNAL_H_
+
+
+#include <Uefi.h>
+
+#include <Protocol/DevicePath.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/FormBrowser2.h>
- -#include <Library/DebugLib.h> -#include <Library/BaseMemoryLib.h> -#include <Library/UefiBootServicesTableLib.h> -#include <Library/BaseLib.h> -#include <Library/DevicePathLib.h> -#include <Library/MemoryAllocationLib.h> -#include <Library/IfrSupportLib.h> - - -#endif - +
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IfrSupportLib.h>
+
+
+#endif
+
diff --git a/MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c b/MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c index d79e254aae..9b48a27e19 100644 --- a/MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c +++ b/MdePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c @@ -1,891 +1,891 @@ -/** @file - 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. - - -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" - -/** - Check if the input question flags is a valid value. - The valid combination of question flags includes - EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY. - - @param Flags The question flags to check. - - @retval TRUE If the question flag is a valid combination. - @retval FALSE If the question flag is an invalid combination. - -**/ -BOOLEAN -IsValidQuestionFlags ( - IN UINT8 Flags - ) -{ - return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE); -} - -/** - Check if the input value type is a valid type. - The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER. - - @param Type The value type to check. - - @retval TRUE If the value type is valid. - @retval FALSE If the value type is invalid. - -**/ -BOOLEAN -IsValidValueType ( - IN UINT8 Type - ) -{ - return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE); -} - -/** - Check if the input numeric flags is a valid value. - - @param Flags The numeric flags to check. - - @retval TRUE If the numeric flags is valid. - @retval FALSE If the numeric flags is invalid. - -**/ -BOOLEAN -IsValidNumricFlags ( - IN UINT8 Flags - ) -{ - if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) { - return FALSE; - } - - if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) { - return FALSE; - } - - return TRUE; -} - -/** - Check if the checkbox flags is a valid value. - - @param Flags The checkbox flags to check. - - @retval TRUE If the checkbox flags is valid. - @retval FALSE If the checkbox flags is invalid. - -**/ -BOOLEAN -IsValidCheckboxFlags ( - IN UINT8 Flags - ) -{ - return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE); -} - -/** - Create EFI_IFR_END_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - -**/ -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 is used for EFI_IFR_END to cover the unaligned address access. - // - CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END)); - Data->Offset += sizeof (EFI_IFR_END); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_DEFAULT_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param Value Value for the default - @param Type Type for the default - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER The type is not valid. - -**/ -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 is used for EFI_IFR_DEFAULT to cover the unaligned address access. - // - CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT)); - Data->Offset += sizeof (EFI_IFR_DEFAULT); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_ACTION_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param QuestionConfig String ID for configuration - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_ACTION to cover the unaligned address access. - // - CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION)); - Data->Offset += sizeof (EFI_IFR_ACTION); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_SUBTITLE_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param Prompt String ID for Prompt - @param Help String ID for Help - @param Flags Subtitle opcode flags - @param Scope Subtitle Scope bit - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - -**/ -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 is used for EFI_IFR_SUBTITLE to cover the unaligned address access. - // - CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE)); - Data->Offset += sizeof (EFI_IFR_SUBTITLE); - - return EFI_SUCCESS; -} - - -/** - Create EFI_IFR_TEXT_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param Prompt String ID for Prompt - @param Help String ID for Help - @param TextTwo String ID for text two - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - -**/ -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 is used for EFI_IFR_TEXT to cover the unaligned address access. - // - CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT)); - Data->Offset += sizeof (EFI_IFR_TEXT); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_REF_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param FormId Destination Form ID - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param QuestionId Question ID - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_REF to cover the unaligned address access. - // - CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF)); - Data->Offset += sizeof (EFI_IFR_REF); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_ONE_OF_OPTION_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param OptionCount The number of options. - @param OptionsList The list of Options. - @param Type The data type. - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If OptionCount is not zero but OptionsList is NULL. - -**/ -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 is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access. - // - CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION)); - Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION); - } - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_ONE_OF_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param VarStoreId Storage ID - @param VarOffset Offset in Storage - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param OneOfFlags Flags for oneof opcode - @param OptionsList List of options - @param OptionCount Number of options in option list - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_ONF_OF to cover the unaligned address access. - // - 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; -} - -/** - Create EFI_IFR_ORDERED_LIST_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param VarStoreId Storage ID - @param VarOffset Offset in Storage - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param OrderedListFlags Flags for ordered list opcode - @param DataType Type for option value - @param MaxContainers Maximum count for options in this ordered list - @param OptionsList List of options - @param OptionCount Number of options in option list - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access. - // - 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; -} - -/** - Create EFI_IFR_CHECKBOX_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param VarStoreId Storage ID - @param VarOffset Offset in Storage - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param CheckBoxFlags Flags for checkbox opcode - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_CHECKBOX to cover the unaligned address access. - // - CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX)); - Data->Offset += sizeof (EFI_IFR_CHECKBOX); - - return EFI_SUCCESS; -} - -/** - Create EFI_IFR_NUMERIC_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param VarStoreId Storage ID - @param VarOffset Offset in Storage - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param NumericFlags Flags for numeric opcode - @param Minimum Numeric minimum value - @param Maximum Numeric maximum value - @param Step Numeric step for edit - @param Default Numeric default value - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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 is used for EFI_IFR_NUMERIC to cover the unaligned address access. - // - 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; -} - -/** - Create EFI_IFR_STRING_OP opcode. - - If Data is NULL or Data->Data is NULL, then ASSERT. - - @param QuestionId Question ID - @param VarStoreId Storage ID - @param VarOffset Offset in Storage - @param Prompt String ID for Prompt - @param Help String ID for Help - @param QuestionFlags Flags in Question Header - @param StringFlags Flags for string opcode - @param MinSize String minimum length - @param MaxSize String maximum length - @param Data Destination for the created opcode binary - - @retval EFI_SUCCESS Opcode is created successfully. - @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small. - @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid. - -**/ -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) != 0) { - 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 is used for EFI_IFR_STRING to cover the unaligned address access. - // - CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING)); - Data->Offset += sizeof (EFI_IFR_STRING); - - return EFI_SUCCESS; -} - - +/** @file
+ 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.
+
+
+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"
+
+/**
+ Check if the input question flags is a valid value.
+ The valid combination of question flags includes
+ EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY.
+
+ @param Flags The question flags to check.
+
+ @retval TRUE If the question flag is a valid combination.
+ @retval FALSE If the question flag is an invalid combination.
+
+**/
+BOOLEAN
+IsValidQuestionFlags (
+ IN UINT8 Flags
+ )
+{
+ return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE);
+}
+
+/**
+ Check if the input value type is a valid type.
+ The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER.
+
+ @param Type The value type to check.
+
+ @retval TRUE If the value type is valid.
+ @retval FALSE If the value type is invalid.
+
+**/
+BOOLEAN
+IsValidValueType (
+ IN UINT8 Type
+ )
+{
+ return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE);
+}
+
+/**
+ Check if the input numeric flags is a valid value.
+
+ @param Flags The numeric flags to check.
+
+ @retval TRUE If the numeric flags is valid.
+ @retval FALSE If the numeric flags is invalid.
+
+**/
+BOOLEAN
+IsValidNumricFlags (
+ IN UINT8 Flags
+ )
+{
+ if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) {
+ return FALSE;
+ }
+
+ if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Check if the checkbox flags is a valid value.
+
+ @param Flags The checkbox flags to check.
+
+ @retval TRUE If the checkbox flags is valid.
+ @retval FALSE If the checkbox flags is invalid.
+
+**/
+BOOLEAN
+IsValidCheckboxFlags (
+ IN UINT8 Flags
+ )
+{
+ return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE);
+}
+
+/**
+ Create EFI_IFR_END_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+
+**/
+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 is used for EFI_IFR_END to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));
+ Data->Offset += sizeof (EFI_IFR_END);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_DEFAULT_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param Value Value for the default
+ @param Type Type for the default
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER The type is not valid.
+
+**/
+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 is used for EFI_IFR_DEFAULT to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));
+ Data->Offset += sizeof (EFI_IFR_DEFAULT);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_ACTION_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param QuestionConfig String ID for configuration
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_ACTION to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));
+ Data->Offset += sizeof (EFI_IFR_ACTION);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_SUBTITLE_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param Flags Subtitle opcode flags
+ @param Scope Subtitle Scope bit
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+
+**/
+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 is used for EFI_IFR_SUBTITLE to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));
+ Data->Offset += sizeof (EFI_IFR_SUBTITLE);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Create EFI_IFR_TEXT_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param TextTwo String ID for text two
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+
+**/
+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 is used for EFI_IFR_TEXT to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));
+ Data->Offset += sizeof (EFI_IFR_TEXT);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_REF_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param FormId Destination Form ID
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param QuestionId Question ID
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_REF to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));
+ Data->Offset += sizeof (EFI_IFR_REF);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_ONE_OF_OPTION_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param OptionCount The number of options.
+ @param OptionsList The list of Options.
+ @param Type The data type.
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If OptionCount is not zero but OptionsList is NULL.
+
+**/
+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 is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));
+ Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_ONE_OF_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param VarStoreId Storage ID
+ @param VarOffset Offset in Storage
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param OneOfFlags Flags for oneof opcode
+ @param OptionsList List of options
+ @param OptionCount Number of options in option list
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_ONF_OF to cover the unaligned address access.
+ //
+ 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;
+}
+
+/**
+ Create EFI_IFR_ORDERED_LIST_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param VarStoreId Storage ID
+ @param VarOffset Offset in Storage
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param OrderedListFlags Flags for ordered list opcode
+ @param DataType Type for option value
+ @param MaxContainers Maximum count for options in this ordered list
+ @param OptionsList List of options
+ @param OptionCount Number of options in option list
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access.
+ //
+ 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;
+}
+
+/**
+ Create EFI_IFR_CHECKBOX_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param VarStoreId Storage ID
+ @param VarOffset Offset in Storage
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param CheckBoxFlags Flags for checkbox opcode
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_CHECKBOX to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));
+ Data->Offset += sizeof (EFI_IFR_CHECKBOX);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create EFI_IFR_NUMERIC_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param VarStoreId Storage ID
+ @param VarOffset Offset in Storage
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param NumericFlags Flags for numeric opcode
+ @param Minimum Numeric minimum value
+ @param Maximum Numeric maximum value
+ @param Step Numeric step for edit
+ @param Default Numeric default value
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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 is used for EFI_IFR_NUMERIC to cover the unaligned address access.
+ //
+ 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;
+}
+
+/**
+ Create EFI_IFR_STRING_OP opcode.
+
+ If Data is NULL or Data->Data is NULL, then ASSERT.
+
+ @param QuestionId Question ID
+ @param VarStoreId Storage ID
+ @param VarOffset Offset in Storage
+ @param Prompt String ID for Prompt
+ @param Help String ID for Help
+ @param QuestionFlags Flags in Question Header
+ @param StringFlags Flags for string opcode
+ @param MinSize String minimum length
+ @param MaxSize String maximum length
+ @param Data Destination for the created opcode binary
+
+ @retval EFI_SUCCESS Opcode is created successfully.
+ @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
+ @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
+
+**/
+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) != 0) {
+ 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 is used for EFI_IFR_STRING to cover the unaligned address access.
+ //
+ CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));
+ Data->Offset += sizeof (EFI_IFR_STRING);
+
+ return EFI_SUCCESS;
+}
+
+
|