diff options
Diffstat (limited to 'MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c')
| -rw-r--r-- | MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c | 4608 |
1 files changed, 2304 insertions, 2304 deletions
diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c index 003cb499b5..dced92f54c 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c @@ -1,2304 +1,2304 @@ -/** @file
-This is an example of how a driver might export data to the HII protocol to be
-later utilized by the Setup Protocol
-
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "DriverSample.h"
-
-#define DISPLAY_ONLY_MY_ITEM 0x0002
-
-CHAR16 VariableName[] = L"MyIfrNVData";
-CHAR16 MyEfiVar[] = L"MyEfiVar";
-CHAR16 MyEfiBitVar[] = L"MyEfiBitVar";
-CHAR16 MyEfiUnionVar[] = L"MyEfiUnionVar";
-
-EFI_HANDLE DriverHandle[2] = { NULL, NULL };
-DRIVER_SAMPLE_PRIVATE_DATA *mPrivateData = NULL;
-EFI_EVENT mEvent;
-
-HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
- (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
- }
- },
- DRIVER_SAMPLE_FORMSET_GUID
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8)(END_DEVICE_PATH_LENGTH),
- (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
- }
- }
-};
-
-HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
- (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
- }
- },
- DRIVER_SAMPLE_INVENTORY_GUID
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8)(END_DEVICE_PATH_LENGTH),
- (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
- }
- }
-};
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- )
-{
- ASSERT (Array != NULL);
-
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- *(((UINT8 *)Array) + Index) = (UINT8)Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- *(((UINT16 *)Array) + Index) = (UINT16)Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- *(((UINT32 *)Array) + Index) = (UINT32)Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- *(((UINT64 *)Array) + Index) = (UINT64)Value;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Notification function for keystrokes.
-
- @param[in] KeyData The key that was pressed.
-
- @retval EFI_SUCCESS The operation was successful.
-**/
-EFI_STATUS
-EFIAPI
-NotificationFunction (
- IN EFI_KEY_DATA *KeyData
- )
-{
- gBS->SignalEvent (mEvent);
-
- return EFI_SUCCESS;
-}
-
-/**
- Function to start monitoring for CTRL-C using SimpleTextInputEx.
-
- @retval EFI_SUCCESS The feature is enabled.
- @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
-**/
-EFI_STATUS
-EFIAPI
-InternalStartMonitor (
- VOID
- )
-{
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
- EFI_KEY_DATA KeyData;
- EFI_STATUS Status;
- EFI_HANDLE *Handles;
- UINTN HandleCount;
- UINTN HandleIndex;
- VOID *NotifyHandle;
-
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextInputExProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
- Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **)&SimpleEx);
- ASSERT_EFI_ERROR (Status);
-
- KeyData.KeyState.KeyToggleState = 0;
- KeyData.Key.ScanCode = 0;
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
- KeyData.Key.UnicodeChar = L'c';
-
- Status = SimpleEx->RegisterKeyNotify (
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
- Status = SimpleEx->RegisterKeyNotify (
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Function to stop monitoring for CTRL-C using SimpleTextInputEx.
-
- @retval EFI_SUCCESS The feature is enabled.
- @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
-**/
-EFI_STATUS
-EFIAPI
-InternalStopMonitor (
- VOID
- )
-{
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
- EFI_STATUS Status;
- EFI_HANDLE *Handles;
- EFI_KEY_DATA KeyData;
- UINTN HandleCount;
- UINTN HandleIndex;
- VOID *NotifyHandle;
-
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextInputExProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
- Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **)&SimpleEx);
- ASSERT_EFI_ERROR (Status);
-
- KeyData.KeyState.KeyToggleState = 0;
- KeyData.Key.ScanCode = 0;
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
- KeyData.Key.UnicodeChar = L'c';
-
- Status = SimpleEx->RegisterKeyNotify (
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &NotifyHandle
- );
- if (!EFI_ERROR (Status)) {
- Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);
- }
-
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
- Status = SimpleEx->RegisterKeyNotify (
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &NotifyHandle
- );
- if (!EFI_ERROR (Status)) {
- Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Update names of Name/Value storage to current language.
-
- @param PrivateData Points to the driver private data.
-
- @retval EFI_SUCCESS All names are successfully updated.
- @retval EFI_NOT_FOUND Failed to get Name from HII database.
-
-**/
-EFI_STATUS
-LoadNameValueNames (
- IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData
- )
-{
- UINTN Index;
-
- //
- // Get Name/Value name string of current language
- //
- for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
- PrivateData->NameValueName[Index] = HiiGetString (
- PrivateData->HiiHandle[0],
- PrivateData->NameStringId[Index],
- NULL
- );
- if (PrivateData->NameValueName[Index] == NULL) {
- return EFI_NOT_FOUND;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
- or WIDTH or VALUE.
- <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
-
- This is a internal function.
-
- @param StringPtr String in <BlockConfig> format and points to the
- first character of <Number>.
- @param Number The output value. Caller takes the responsibility
- to free memory.
- @param Len Length of the <Number>, in characters.
-
- @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
- structures.
- @retval EFI_SUCCESS Value of <Number> is outputted in Number
- successfully.
-
-**/
-EFI_STATUS
-GetValueOfNumber (
- IN EFI_STRING StringPtr,
- OUT UINT8 **Number,
- OUT UINTN *Len
- )
-{
- EFI_STRING TmpPtr;
- UINTN Length;
- EFI_STRING Str;
- UINT8 *Buf;
- EFI_STATUS Status;
- UINT8 DigitUint8;
- UINTN Index;
- CHAR16 TemStr[2];
-
- if ((StringPtr == NULL) || (*StringPtr == L'\0') || (Number == NULL) || (Len == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Buf = NULL;
-
- TmpPtr = StringPtr;
- while (*StringPtr != L'\0' && *StringPtr != L'&') {
- StringPtr++;
- }
-
- *Len = StringPtr - TmpPtr;
- Length = *Len + 1;
-
- Str = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
- if (Str == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));
- *(Str + *Len) = L'\0';
-
- Length = (Length + 1) / 2;
- Buf = (UINT8 *)AllocateZeroPool (Length);
- if (Buf == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Length = *Len;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < Length; Index++) {
- TemStr[0] = Str[Length - Index - 1];
- DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- Buf[Index/2] = DigitUint8;
- } else {
- Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);
- }
- }
-
- *Number = Buf;
- Status = EFI_SUCCESS;
-
-Exit:
- if (Str != NULL) {
- FreePool (Str);
- }
-
- return Status;
-}
-
-/**
- Create altcfg string.
-
- @param Result The request result string.
- @param ConfigHdr The request head info. <ConfigHdr> format.
- @param Offset The offset of the parameter int he structure.
- @param Width The width of the parameter.
-
-
- @retval The string with altcfg info append at the end.
-**/
-EFI_STRING
-CreateAltCfgString (
- IN EFI_STRING Result,
- IN EFI_STRING ConfigHdr,
- IN UINTN Offset,
- IN UINTN Width
- )
-{
- EFI_STRING StringPtr;
- EFI_STRING TmpStr;
- UINTN NewLen;
-
- NewLen = StrLen (Result);
- //
- // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
- //
- NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16);
- StringPtr = AllocateZeroPool (NewLen);
- if (StringPtr == NULL) {
- return NULL;
- }
-
- TmpStr = StringPtr;
- if (Result != NULL) {
- StrCpyS (StringPtr, NewLen / sizeof (CHAR16), Result);
- StringPtr += StrLen (Result);
- FreePool (Result);
- }
-
- UnicodeSPrint (
- StringPtr,
- (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
- L"&%s&ALTCFG=%04x",
- ConfigHdr,
- EFI_HII_DEFAULT_CLASS_STANDARD
- );
- StringPtr += StrLen (StringPtr);
-
- UnicodeSPrint (
- StringPtr,
- (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
- L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
- Offset,
- Width,
- DEFAULT_CLASS_STANDARD_VALUE
- );
- StringPtr += StrLen (StringPtr);
-
- UnicodeSPrint (
- StringPtr,
- (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
- L"&%s&ALTCFG=%04x",
- ConfigHdr,
- EFI_HII_DEFAULT_CLASS_MANUFACTURING
- );
- StringPtr += StrLen (StringPtr);
-
- UnicodeSPrint (
- StringPtr,
- (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
- L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
- Offset,
- Width,
- DEFAULT_CLASS_MANUFACTURING_VALUE
- );
- StringPtr += StrLen (StringPtr);
-
- return TmpStr;
-}
-
-/**
- Check whether need to add the altcfg string. if need to add, add the altcfg
- string.
-
- @param RequestResult The request result string.
- @param ConfigRequestHdr The request head info. <ConfigHdr> format.
-
-**/
-VOID
-AppendAltCfgString (
- IN OUT EFI_STRING *RequestResult,
- IN EFI_STRING ConfigRequestHdr
- )
-{
- EFI_STRING StringPtr;
- UINTN Length;
- UINT8 *TmpBuffer;
- UINTN Offset;
- UINTN Width;
- UINTN BlockSize;
- UINTN ValueOffset;
- UINTN ValueWidth;
- EFI_STATUS Status;
-
- TmpBuffer = NULL;
- StringPtr = *RequestResult;
- StringPtr = StrStr (StringPtr, L"OFFSET");
- BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
- ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);
- ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);
-
- if (StringPtr == NULL) {
- return;
- }
-
- while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
- StringPtr += StrLen (L"OFFSET=");
- //
- // Get Offset
- //
- Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- Offset = 0;
- CopyMem (
- &Offset,
- TmpBuffer,
- (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
- );
- FreePool (TmpBuffer);
-
- StringPtr += Length;
- if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
- return;
- }
-
- StringPtr += StrLen (L"&WIDTH=");
-
- //
- // Get Width
- //
- Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- Width = 0;
- CopyMem (
- &Width,
- TmpBuffer,
- (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
- );
- FreePool (TmpBuffer);
-
- StringPtr += Length;
- if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
- return;
- }
-
- StringPtr += StrLen (L"&VALUE=");
-
- //
- // Get Value
- //
- Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- StringPtr += Length;
-
- //
- // Skip the character "&" before "OFFSET".
- //
- StringPtr++;
-
- //
- // Calculate Value and convert it to hex string.
- //
- if (Offset + Width > BlockSize) {
- return;
- }
-
- if ((Offset <= ValueOffset) && (Offset + Width >= ValueOffset + ValueWidth)) {
- *RequestResult = CreateAltCfgString (*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);
- return;
- }
- }
-}
-
-/**
- This function allows a caller to extract the current configuration for one
- or more named elements from the target driver.
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Request A null-terminated Unicode string in
- <ConfigRequest> format.
- @param Progress On return, points to a character in the Request
- string. Points to the string's null terminator if
- request was successful. Points to the most recent
- '&' before the first failing name/value pair (or
- the beginning of the string if the failure is in
- the first name/value pair) if the request was not
- successful.
- @param Results A null-terminated Unicode string in
- <ConfigAltResp> format which has all values filled
- in for the names in the Request string. String to
- be allocated by the called function.
-
- @retval EFI_SUCCESS The Results is filled with the requested values.
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
- driver.
-
-**/
-EFI_STATUS
-EFIAPI
-ExtractConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Request,
- OUT EFI_STRING *Progress,
- OUT EFI_STRING *Results
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
- EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
- EFI_STRING ConfigRequest;
- EFI_STRING ConfigRequestHdr;
- UINTN Size;
- EFI_STRING Value;
- UINTN ValueStrLen;
- CHAR16 BackupChar;
- CHAR16 *StrPointer;
- BOOLEAN AllocatedRequest;
-
- if ((Progress == NULL) || (Results == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Initialize the local variables.
- //
- ConfigRequestHdr = NULL;
- ConfigRequest = NULL;
- Size = 0;
- *Progress = Request;
- AllocatedRequest = FALSE;
-
- PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
- HiiConfigRouting = PrivateData->HiiConfigRouting;
-
- //
- // Get Buffer Storage data from EFI variable.
- // Try to get the current setting from variable.
- //
- BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
- Status = gRT->GetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- NULL,
- &BufferSize,
- &PrivateData->Configuration
- );
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
-
- if (Request == NULL) {
- //
- // Request is set to NULL, construct full request string.
- //
-
- //
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
- //
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
- Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- ASSERT (ConfigRequest != NULL);
- AllocatedRequest = TRUE;
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
- FreePool (ConfigRequestHdr);
- ConfigRequestHdr = NULL;
- } else {
- //
- // Check routing data in <ConfigHdr>.
- // Note: if only one Storage is used, then this checking could be skipped.
- //
- if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether request for EFI Varstore. EFI varstore get data
- // through hii database, not support in this path.
- //
- if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiVar)) {
- return EFI_UNSUPPORTED;
- }
-
- if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiBitVar)) {
- return EFI_UNSUPPORTED;
- }
-
- if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiUnionVar)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Set Request to the unified request string.
- //
- ConfigRequest = Request;
- //
- // Check whether Request includes Request Element.
- //
- if (StrStr (Request, L"OFFSET") == NULL) {
- //
- // Check Request Element does exist in Reques String
- //
- StrPointer = StrStr (Request, L"PATH");
- if (StrPointer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (StrStr (StrPointer, L"&") == NULL) {
- Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- ASSERT (ConfigRequest != NULL);
- AllocatedRequest = TRUE;
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
- }
- }
- }
-
- //
- // Check if requesting Name/Value storage
- //
- if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
- //
- // Update Name/Value storage Names
- //
- Status = LoadNameValueNames (PrivateData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
- // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
- // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
- //
- BufferSize = (StrLen (ConfigRequest) +
- 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 +
- 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 +
- 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16);
- *Results = AllocateZeroPool (BufferSize);
- ASSERT (*Results != NULL);
- StrCpyS (*Results, BufferSize / sizeof (CHAR16), ConfigRequest);
- Value = *Results;
-
- //
- // Append value of NameValueVar0, type is UINT8
- //
- if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) {
- Value += StrLen (PrivateData->NameValueName[0]);
- ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1);
- CopyMem (Value + ValueStrLen, Value, StrSize (Value));
-
- BackupChar = Value[ValueStrLen];
- *Value++ = L'=';
- UnicodeValueToStringS (
- Value,
- BufferSize - ((UINTN)Value - (UINTN)*Results),
- PREFIX_ZERO | RADIX_HEX,
- PrivateData->Configuration.NameValueVar0,
- sizeof (PrivateData->Configuration.NameValueVar0) * 2
- );
- Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));
- *Value = BackupChar;
- }
-
- //
- // Append value of NameValueVar1, type is UINT16
- //
- if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {
- Value += StrLen (PrivateData->NameValueName[1]);
- ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);
- CopyMem (Value + ValueStrLen, Value, StrSize (Value));
-
- BackupChar = Value[ValueStrLen];
- *Value++ = L'=';
- UnicodeValueToStringS (
- Value,
- BufferSize - ((UINTN)Value - (UINTN)*Results),
- PREFIX_ZERO | RADIX_HEX,
- PrivateData->Configuration.NameValueVar1,
- sizeof (PrivateData->Configuration.NameValueVar1) * 2
- );
- Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));
- *Value = BackupChar;
- }
-
- //
- // Append value of NameValueVar2, type is CHAR16 *
- //
- if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {
- Value += StrLen (PrivateData->NameValueName[2]);
- ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;
- CopyMem (Value + ValueStrLen, Value, StrSize (Value));
-
- *Value++ = L'=';
- //
- // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
- //
- StrPointer = (CHAR16 *)PrivateData->Configuration.NameValueVar2;
- for ( ; *StrPointer != L'\0'; StrPointer++) {
- UnicodeValueToStringS (
- Value,
- BufferSize - ((UINTN)Value - (UINTN)*Results),
- PREFIX_ZERO | RADIX_HEX,
- *StrPointer,
- 4
- );
- Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));
- }
- }
-
- Status = EFI_SUCCESS;
- } else {
- //
- // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
- //
- Status = HiiConfigRouting->BlockToConfig (
- HiiConfigRouting,
- ConfigRequest,
- (UINT8 *)&PrivateData->Configuration,
- BufferSize,
- Results,
- Progress
- );
- if (!EFI_ERROR (Status)) {
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
- AppendAltCfgString (Results, ConfigRequestHdr);
- }
- }
-
- //
- // Free the allocated config request string.
- //
- if (AllocatedRequest) {
- FreePool (ConfigRequest);
- }
-
- if (ConfigRequestHdr != NULL) {
- FreePool (ConfigRequestHdr);
- }
-
- //
- // Set Progress string to the original request string.
- //
- if (Request == NULL) {
- *Progress = NULL;
- } else if (StrStr (Request, L"OFFSET") == NULL) {
- *Progress = Request + StrLen (Request);
- }
-
- return Status;
-}
-
-/**
- This function processes the results of changes in configuration.
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Configuration A null-terminated Unicode string in <ConfigResp>
- format.
- @param Progress A pointer to a string filled in with the offset of
- the most recent '&' before the first failing
- name/value pair (or the beginning of the string if
- the failure is in the first name/value pair) or
- the terminating NULL if all was successful.
-
- @retval EFI_SUCCESS The Results is processed successfully.
- @retval EFI_INVALID_PARAMETER Configuration is NULL.
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
- driver.
- @retval EFI_DEVICE_ERROR If value is 44, return error for testing.
-
-**/
-EFI_STATUS
-EFIAPI
-RouteConfig (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN CONST EFI_STRING Configuration,
- OUT EFI_STRING *Progress
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
- EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
- CHAR16 *Value;
- CHAR16 *StrPtr;
- CHAR16 TemStr[5];
- UINT8 *DataBuffer;
- UINT8 DigitUint8;
- UINTN Index;
- CHAR16 *StrBuffer;
-
- if ((Configuration == NULL) || (Progress == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
- HiiConfigRouting = PrivateData->HiiConfigRouting;
- *Progress = Configuration;
-
- //
- // Check routing data in <ConfigHdr>.
- // Note: if only one Storage is used, then this checking could be skipped.
- //
- if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether request for EFI Varstore. EFI varstore get data
- // through hii database, not support in this path.
- //
- if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {
- return EFI_UNSUPPORTED;
- }
-
- if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiBitVar)) {
- return EFI_UNSUPPORTED;
- }
-
- if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiUnionVar)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Get Buffer Storage data from EFI variable
- //
- BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
- Status = gRT->GetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- NULL,
- &BufferSize,
- &PrivateData->Configuration
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Check if configuring Name/Value storage
- //
- if (StrStr (Configuration, L"OFFSET") == NULL) {
- //
- // Update Name/Value storage Names
- //
- Status = LoadNameValueNames (PrivateData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Convert value for NameValueVar0
- //
- if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {
- //
- // Skip "Name="
- //
- Value += StrLen (PrivateData->NameValueName[0]);
- Value++;
- //
- // Get Value String
- //
- StrPtr = StrStr (Value, L"&");
- if (StrPtr == NULL) {
- StrPtr = Value + StrLen (Value);
- }
-
- //
- // Convert Value to Buffer data
- //
- DataBuffer = (UINT8 *)&PrivateData->Configuration.NameValueVar0;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0, StrPtr--; StrPtr >= Value; StrPtr--, Index++) {
- TemStr[0] = *StrPtr;
- DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- DataBuffer[Index/2] = DigitUint8;
- } else {
- DataBuffer[Index/2] = (UINT8)((UINT8)(DigitUint8 << 4) + DataBuffer[Index/2]);
- }
- }
- }
-
- //
- // Convert value for NameValueVar1
- //
- if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {
- //
- // Skip "Name="
- //
- Value += StrLen (PrivateData->NameValueName[1]);
- Value++;
- //
- // Get Value String
- //
- StrPtr = StrStr (Value, L"&");
- if (StrPtr == NULL) {
- StrPtr = Value + StrLen (Value);
- }
-
- //
- // Convert Value to Buffer data
- //
- DataBuffer = (UINT8 *)&PrivateData->Configuration.NameValueVar1;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0, StrPtr--; StrPtr >= Value; StrPtr--, Index++) {
- TemStr[0] = *StrPtr;
- DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- DataBuffer[Index/2] = DigitUint8;
- } else {
- DataBuffer[Index/2] = (UINT8)((UINT8)(DigitUint8 << 4) + DataBuffer[Index/2]);
- }
- }
- }
-
- //
- // Convert value for NameValueVar2
- //
- if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {
- //
- // Skip "Name="
- //
- Value += StrLen (PrivateData->NameValueName[2]);
- Value++;
- //
- // Get Value String
- //
- StrPtr = StrStr (Value, L"&");
- if (StrPtr == NULL) {
- StrPtr = Value + StrLen (Value);
- }
-
- //
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
- //
- StrBuffer = (CHAR16 *)PrivateData->Configuration.NameValueVar2;
- ZeroMem (TemStr, sizeof (TemStr));
- while (Value < StrPtr) {
- StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value, 4);
- *(StrBuffer++) = (CHAR16)StrHexToUint64 (TemStr);
- Value += 4;
- }
-
- *StrBuffer = L'\0';
- }
-
- //
- // Store Buffer Storage back to EFI variable
- //
- Status = gRT->SetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- &PrivateData->Configuration
- );
-
- return Status;
- }
-
- //
- // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
- //
- BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
- Status = HiiConfigRouting->ConfigToBlock (
- HiiConfigRouting,
- Configuration,
- (UINT8 *)&PrivateData->Configuration,
- &BufferSize,
- Progress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (PrivateData->Configuration.QuestionApply == 44) {
- // Return error for verify the error handling of caller.
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Store Buffer Storage back to EFI variable
- //
- Status = gRT->SetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- &PrivateData->Configuration
- );
-
- return Status;
-}
-
-/**
- This function processes the results of changes in configuration.
-
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
- @param Action Specifies the type of action taken by the browser.
- @param QuestionId A unique value which is sent to the original
- exporting driver so that it can identify the type
- of data to expect.
- @param Type The type of value for the question.
- @param Value A pointer to the data being sent to the original
- exporting driver.
- @param ActionRequest On return, points to the action requested by the
- callback function.
-
- @retval EFI_SUCCESS The callback successfully handled the action.
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
- variable and its data.
- @retval EFI_DEVICE_ERROR The variable could not be saved.
- @retval EFI_UNSUPPORTED The specified Action is not supported by the
- callback.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverCallback (
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
- IN EFI_BROWSER_ACTION Action,
- IN EFI_QUESTION_ID QuestionId,
- IN UINT8 Type,
- IN EFI_IFR_TYPE_VALUE *Value,
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
- )
-{
- DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
- EFI_STATUS Status;
- VOID *StartOpCodeHandle;
- VOID *OptionsOpCodeHandle;
- EFI_IFR_GUID_LABEL *StartLabel;
- VOID *EndOpCodeHandle;
- EFI_IFR_GUID_LABEL *EndLabel;
- EFI_INPUT_KEY Key;
- DRIVER_SAMPLE_CONFIGURATION *Configuration;
- MY_EFI_VARSTORE_DATA *EfiData;
- EFI_FORM_ID FormId;
- EFI_STRING Progress;
- EFI_STRING Results;
- UINT32 ProgressErr;
- CHAR16 *TmpStr;
- UINTN Index;
- UINT64 BufferValue;
- EFI_HII_POPUP_SELECTION UserSelection;
-
- UserSelection = 0xFF;
-
- if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
- (ActionRequest == NULL))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- FormId = 0;
- ProgressErr = 0;
- Status = EFI_SUCCESS;
- BufferValue = 3;
- PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
-
- switch (Action) {
- case EFI_BROWSER_ACTION_FORM_OPEN:
- {
- if (QuestionId == 0x1234) {
- //
- // Sample CallBack for UEFI FORM_OPEN action:
- // Add Save action into Form 3 when Form 1 is opened.
- // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
- //
- PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
-
- //
- // Initialize the container for dynamic opcodes
- //
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (StartOpCodeHandle != NULL);
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- StartLabel->Number = LABEL_UPDATE2;
-
- HiiCreateActionOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 0x1238, // Question ID
- STRING_TOKEN (STR_SAVE_TEXT), // Prompt text
- STRING_TOKEN (STR_SAVE_TEXT), // Help text
- EFI_IFR_FLAG_CALLBACK, // Question flag
- 0 // Action String ID
- );
-
- HiiUpdateForm (
- PrivateData->HiiHandle[0], // HII handle
- &gDriverSampleFormSetGuid, // Formset GUID
- 0x3, // Form ID
- StartOpCodeHandle, // Label for where to insert opcodes
- NULL // Insert data
- );
-
- HiiFreeOpCodeHandle (StartOpCodeHandle);
- }
-
- if (QuestionId == 0x1247) {
- Status = InternalStartMonitor ();
- ASSERT_EFI_ERROR (Status);
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_FORM_CLOSE:
- {
- if (QuestionId == 0x5678) {
- //
- // Sample CallBack for UEFI FORM_CLOSE action:
- // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
- //
- do {
- CreatePopUp (
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
- &Key,
- L"",
- L"You are going to leave third Form!",
- L"Press ESC or ENTER to continue ...",
- L"",
- NULL
- );
- } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
- }
-
- if (QuestionId == 0x1247) {
- Status = InternalStopMonitor ();
- ASSERT_EFI_ERROR (Status);
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_RETRIEVE:
- {
- switch (QuestionId ) {
- case 0x1248:
- if (Type != EFI_IFR_TYPE_REF) {
- return EFI_INVALID_PARAMETER;
- }
-
- Value->ref.FormId = 0x3;
- break;
-
- case 0x5678:
- case 0x1247:
- //
- // We will reach here once the Question is refreshed
- //
-
- //
- // Initialize the container for dynamic opcodes
- //
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (StartOpCodeHandle != NULL);
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- if (QuestionId == 0x5678) {
- StartLabel->Number = LABEL_UPDATE2;
- FormId = 0x03;
- PrivateData->Configuration.DynamicRefresh++;
- } else if (QuestionId == 0x1247 ) {
- StartLabel->Number = LABEL_UPDATE3;
- FormId = 0x06;
- PrivateData->Configuration.RefreshGuidCount++;
- }
-
- HiiCreateActionOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 0x1237, // Question ID
- STRING_TOKEN (STR_EXIT_TEXT), // Prompt text
- STRING_TOKEN (STR_EXIT_TEXT), // Help text
- EFI_IFR_FLAG_CALLBACK, // Question flag
- 0 // Action String ID
- );
-
- HiiUpdateForm (
- PrivateData->HiiHandle[0], // HII handle
- &gDriverSampleFormSetGuid, // Formset GUID
- FormId, // Form ID
- StartOpCodeHandle, // Label for where to insert opcodes
- NULL // Insert data
- );
-
- HiiFreeOpCodeHandle (StartOpCodeHandle);
-
- //
- // Refresh the Question value
- //
- Status = gRT->SetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- &PrivateData->Configuration
- );
-
- if (QuestionId == 0x5678) {
- //
- // Update uncommitted data of Browser
- //
- EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));
- ASSERT (EfiData != NULL);
- if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *)EfiData)) {
- EfiData->Field8 = 111;
- HiiSetBrowserData (
- &gDriverSampleFormSetGuid,
- MyEfiVar,
- sizeof (MY_EFI_VARSTORE_DATA),
- (UINT8 *)EfiData,
- NULL
- );
- }
-
- FreePool (EfiData);
- }
-
- break;
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
- {
- switch (QuestionId) {
- case 0x1240:
- Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;
- break;
-
- case 0x1252:
- for (Index = 0; Index < 3; Index++) {
- SetArrayData (Value, EFI_IFR_TYPE_NUM_SIZE_8, Index, BufferValue--);
- }
-
- break;
-
- case 0x6666:
- Value->u8 = 12;
- break;
-
- default:
- Status = EFI_UNSUPPORTED;
- break;
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
- {
- switch (QuestionId) {
- case 0x1240:
- Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;
- break;
-
- case 0x6666:
- Value->u8 = 13;
- break;
-
- default:
- Status = EFI_UNSUPPORTED;
- break;
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_CHANGING:
- {
- switch (QuestionId) {
- case 0x1249:
- {
- if (Type != EFI_IFR_TYPE_REF) {
- return EFI_INVALID_PARAMETER;
- }
-
- Value->ref.FormId = 0x1234;
- break;
- }
- case 0x1234:
- //
- // Initialize the container for dynamic opcodes
- //
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (StartOpCodeHandle != NULL);
-
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (EndOpCodeHandle != NULL);
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- StartLabel->Number = LABEL_UPDATE1;
-
- //
- // Create Hii Extend Label OpCode as the end opcode
- //
- EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- EndLabel->Number = LABEL_END;
-
- HiiCreateActionOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 0x1237, // Question ID
- STRING_TOKEN (STR_EXIT_TEXT), // Prompt text
- STRING_TOKEN (STR_EXIT_TEXT), // Help text
- EFI_IFR_FLAG_CALLBACK, // Question flag
- 0 // Action String ID
- );
-
- //
- // Create Option OpCode
- //
- OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (OptionsOpCodeHandle != NULL);
-
- HiiCreateOneOfOptionOpCode (
- OptionsOpCodeHandle,
- STRING_TOKEN (STR_BOOT_OPTION1),
- 0,
- EFI_IFR_NUMERIC_SIZE_1,
- 1
- );
-
- HiiCreateOneOfOptionOpCode (
- OptionsOpCodeHandle,
- STRING_TOKEN (STR_BOOT_OPTION2),
- 0,
- EFI_IFR_NUMERIC_SIZE_1,
- 2
- );
-
- //
- // Prepare initial value for the dynamic created oneof Question
- //
- PrivateData->Configuration.DynamicOneof = 2;
- Status = gRT->SetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- &PrivateData->Configuration
- );
-
- //
- // Set initial vlaue of dynamic created oneof Question in Form Browser
- //
- Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));
- ASSERT (Configuration != NULL);
- if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *)Configuration)) {
- Configuration->DynamicOneof = 2;
-
- //
- // Update uncommitted data of Browser
- //
- HiiSetBrowserData (
- &gDriverSampleFormSetGuid,
- VariableName,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- (UINT8 *)Configuration,
- NULL
- );
- }
-
- FreePool (Configuration);
-
- HiiCreateOneOfOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 0x8001, // Question ID (or call it "key")
- CONFIGURATION_VARSTORE_ID, // VarStore ID
- (UINT16)DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage
- STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text
- STRING_TOKEN (STR_ONE_OF_HELP), // Question help text
- EFI_IFR_FLAG_CALLBACK, // Question flag
- EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value
- OptionsOpCodeHandle, // Option Opcode list
- NULL // Default Opcode is NULl
- );
-
- HiiCreateOrderedListOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 0x8002, // Question ID
- CONFIGURATION_VARSTORE_ID, // VarStore ID
- (UINT16)DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage
- STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text
- STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text
- EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
- 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
- EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value
- 5, // Maximum container
- OptionsOpCodeHandle, // Option Opcode list
- NULL // Default Opcode is NULl
- );
-
- HiiCreateTextOpCode (
- StartOpCodeHandle,
- STRING_TOKEN (STR_TEXT_SAMPLE_HELP),
- STRING_TOKEN (STR_TEXT_SAMPLE_HELP),
- STRING_TOKEN (STR_TEXT_SAMPLE_STRING)
- );
-
- HiiCreateDateOpCode (
- StartOpCodeHandle,
- 0x8004,
- 0x0,
- 0x0,
- STRING_TOKEN (STR_DATE_SAMPLE_HELP),
- STRING_TOKEN (STR_DATE_SAMPLE_HELP),
- 0,
- QF_DATE_STORAGE_TIME,
- NULL
- );
-
- HiiCreateTimeOpCode (
- StartOpCodeHandle,
- 0x8005,
- 0x0,
- 0x0,
- STRING_TOKEN (STR_TIME_SAMPLE_HELP),
- STRING_TOKEN (STR_TIME_SAMPLE_HELP),
- 0,
- QF_TIME_STORAGE_TIME,
- NULL
- );
-
- HiiCreateGotoOpCode (
- StartOpCodeHandle, // Container for dynamic created opcodes
- 1, // Target Form ID
- STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
- STRING_TOKEN (STR_GOTO_HELP), // Help text
- 0, // Question flag
- 0x8003 // Question ID
- );
-
- HiiUpdateForm (
- PrivateData->HiiHandle[0], // HII handle
- &gDriverSampleFormSetGuid, // Formset GUID
- 0x1234, // Form ID
- StartOpCodeHandle, // Label for where to insert opcodes
- EndOpCodeHandle // Replace data
- );
-
- HiiFreeOpCodeHandle (StartOpCodeHandle);
- HiiFreeOpCodeHandle (OptionsOpCodeHandle);
- HiiFreeOpCodeHandle (EndOpCodeHandle);
- break;
-
- default:
- break;
- }
-
- break;
- }
-
- case EFI_BROWSER_ACTION_CHANGED:
- switch (QuestionId) {
- case 0x1237:
- //
- // User press "Exit now", request Browser to exit
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- break;
-
- case 0x1238:
- //
- // User press "Save now", request Browser to save the uncommitted data.
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
- break;
-
- case 0x1241:
- case 0x1246:
- //
- // User press "Submit current form and Exit now", request Browser to submit current form and exit
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
- break;
-
- case 0x1242:
- //
- // User press "Discard current form now", request Browser to discard the uncommitted data.
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;
- break;
-
- case 0x1243:
- //
- // User press "Submit current form now", request Browser to save the uncommitted data.
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
- break;
-
- case 0x1244:
- case 0x1245:
- //
- // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
- break;
-
- case 0x1253:
- //
- // User change the value of "Question apply test".
- //
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_QUESTION_APPLY;
- break;
-
- case 0x1231:
- //
- // 1. Check to see whether system support keyword.
- //
- Status = PrivateData->HiiKeywordHandler->GetData (
- PrivateData->HiiKeywordHandler,
- L"NAMESPACE=x-UEFI-ns",
- L"KEYWORD=iSCSIBootEnable",
- &Progress,
- &ProgressErr,
- &Results
- );
- if (EFI_ERROR (Status)) {
- do {
- CreatePopUp (
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
- &Key,
- L"",
- L"This system not support this keyword!",
- L"Press ENTER to continue ...",
- L"",
- NULL
- );
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- Status = EFI_SUCCESS;
- break;
- }
-
- //
- // 2. If system support this keyword, just try to change value.
- //
-
- //
- // Change value from '0' to '1' or from '1' to '0'
- //
- TmpStr = StrStr (Results, L"&VALUE=");
- ASSERT (TmpStr != NULL);
- TmpStr += StrLen (L"&VALUE=");
- TmpStr++;
- if (*TmpStr == L'0') {
- *TmpStr = L'1';
- } else {
- *TmpStr = L'0';
- }
-
- //
- // 3. Call the keyword handler protocol to change the value.
- //
- Status = PrivateData->HiiKeywordHandler->SetData (
- PrivateData->HiiKeywordHandler,
- Results,
- &Progress,
- &ProgressErr
- );
- if (EFI_ERROR (Status)) {
- do {
- CreatePopUp (
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
- &Key,
- L"",
- L"Set keyword to the system failed!",
- L"Press ENTER to continue ...",
- L"",
- NULL
- );
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- Status = EFI_SUCCESS;
- break;
- }
-
- break;
-
- case 0x1330:
- Status = mPrivateData->HiiPopup->CreatePopup (
- mPrivateData->HiiPopup,
- EfiHiiPopupStyleInfo,
- EfiHiiPopupTypeYesNo,
- mPrivateData->HiiHandle[0],
- STRING_TOKEN (STR_POPUP_STRING),
- &UserSelection
- );
- if (!EFI_ERROR (Status)) {
- if (UserSelection == EfiHiiPopupSelectionYes) {
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- }
- }
-
- break;
-
- default:
- break;
- }
-
- break;
-
- case EFI_BROWSER_ACTION_SUBMITTED:
- {
- if (QuestionId == 0x1250) {
- //
- // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:
- // Show up a pop-up to show SUBMITTED callback has been triggered.
- //
- do {
- CreatePopUp (
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
- &Key,
- L"",
- L"EfiVarstore value has been submitted!",
- L"Press ESC or ENTER to continue ...",
- L"",
- NULL
- );
- } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
- }
-
- break;
- }
-
- default:
- Status = EFI_UNSUPPORTED;
- break;
- }
-
- return Status;
-}
-
-/**
- Main entry for this driver.
-
- @param ImageHandle Image handle this driver.
- @param SystemTable Pointer to SystemTable.
-
- @retval EFI_SUCESS This function always complete successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverSampleInit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- EFI_HII_HANDLE HiiHandle[2];
- EFI_SCREEN_DESCRIPTOR Screen;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
- EFI_HII_STRING_PROTOCOL *HiiString;
- EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
- EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
- EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
- EFI_HII_POPUP_PROTOCOL *PopupHandler;
- CHAR16 *NewString;
- UINTN BufferSize;
- DRIVER_SAMPLE_CONFIGURATION *Configuration;
- BOOLEAN ActionFlag;
- EFI_STRING ConfigRequestHdr;
- EFI_STRING NameRequestHdr;
- MY_EFI_VARSTORE_DATA *VarStoreConfig;
- MY_EFI_BITS_VARSTORE_DATA *BitsVarStoreConfig;
- MY_EFI_UNION_DATA *UnionConfig;
- EFI_INPUT_KEY HotKey;
- EDKII_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;
-
- //
- // Initialize the local variables.
- //
- ConfigRequestHdr = NULL;
- NewString = NULL;
-
- //
- // Initialize screen dimensions for SendForm().
- // Remove 3 characters from top and bottom
- //
- ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
- gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
-
- Screen.TopRow = 3;
- Screen.BottomRow = Screen.BottomRow - 3;
-
- //
- // Initialize driver private data
- //
- mPrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
- if (mPrivateData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- mPrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
-
- mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
- mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
- mPrivateData->ConfigAccess.Callback = DriverCallback;
-
- //
- // Locate Hii Database protocol
- //
- Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->HiiDatabase = HiiDatabase;
-
- //
- // Locate HiiString protocol
- //
- Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **)&HiiString);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->HiiString = HiiString;
-
- //
- // Locate Formbrowser2 protocol
- //
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&FormBrowser2);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->FormBrowser2 = FormBrowser2;
-
- //
- // Locate ConfigRouting protocol
- //
- Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->HiiConfigRouting = HiiConfigRouting;
-
- //
- // Locate keyword handler protocol
- //
- Status = gBS->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid, NULL, (VOID **)&HiiKeywordHandler);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->HiiKeywordHandler = HiiKeywordHandler;
-
- //
- // Locate HiiPopup protocol
- //
- Status = gBS->LocateProtocol (&gEfiHiiPopupProtocolGuid, NULL, (VOID **)&PopupHandler);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- mPrivateData->HiiPopup = PopupHandler;
-
- Status = gBS->InstallMultipleProtocolInterfaces (
- &DriverHandle[0],
- &gEfiDevicePathProtocolGuid,
- &mHiiVendorDevicePath0,
- &gEfiHiiConfigAccessProtocolGuid,
- &mPrivateData->ConfigAccess,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- mPrivateData->DriverHandle[0] = DriverHandle[0];
-
- //
- // Publish our HII data
- //
- HiiHandle[0] = HiiAddPackages (
- &gDriverSampleFormSetGuid,
- DriverHandle[0],
- DriverSampleStrings,
- VfrBin,
- NULL
- );
- if (HiiHandle[0] == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- mPrivateData->HiiHandle[0] = HiiHandle[0];
-
- //
- // Publish another Fromset
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &DriverHandle[1],
- &gEfiDevicePathProtocolGuid,
- &mHiiVendorDevicePath1,
- &gEfiHiiConfigAccessProtocolGuid,
- &mPrivateData->ConfigAccess,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- mPrivateData->DriverHandle[1] = DriverHandle[1];
-
- HiiHandle[1] = HiiAddPackages (
- &gDriverSampleInventoryGuid,
- DriverHandle[1],
- DriverSampleStrings,
- InventoryBin,
- NULL
- );
- if (HiiHandle[1] == NULL) {
- DriverSampleUnload (ImageHandle);
- return EFI_OUT_OF_RESOURCES;
- }
-
- mPrivateData->HiiHandle[1] = HiiHandle[1];
-
- //
- // Update the device path string.
- //
- NewString = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)&mHiiVendorDevicePath0, FALSE, FALSE);
- if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) {
- DriverSampleUnload (ImageHandle);
- return EFI_OUT_OF_RESOURCES;
- }
-
- if (NewString != NULL) {
- FreePool (NewString);
- }
-
- //
- // Very simple example of how one would update a string that is already
- // in the HII database
- //
- NewString = L"700 Mhz";
-
- if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {
- DriverSampleUnload (ImageHandle);
- return EFI_OUT_OF_RESOURCES;
- }
-
- HiiSetString (HiiHandle[0], 0, NewString, NULL);
-
- //
- // Initialize Name/Value name String ID
- //
- mPrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;
- mPrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;
- mPrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;
-
- //
- // Initialize configuration data
- //
- Configuration = &mPrivateData->Configuration;
- ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
-
- //
- // Try to read NV config EFI variable first
- //
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);
- ASSERT (ConfigRequestHdr != NULL);
-
- NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);
- ASSERT (NameRequestHdr != NULL);
-
- BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
- Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);
- if (EFI_ERROR (Status)) {
- //
- // Store zero data Buffer Storage to EFI variable
- //
- Status = gRT->SetVariable (
- VariableName,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (DRIVER_SAMPLE_CONFIGURATION),
- Configuration
- );
- if (EFI_ERROR (Status)) {
- DriverSampleUnload (ImageHandle);
- return Status;
- }
-
- //
- // EFI variable for NV config doesn't exit, we should build this variable
- // based on default values stored in IFR
- //
- ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // EFI variable does exist and Validate Current Setting
- //
- ActionFlag = HiiValidateSettings (NameRequestHdr);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- FreePool (ConfigRequestHdr);
-
- //
- // Initialize efi varstore configuration data
- //
- VarStoreConfig = &mPrivateData->VarStoreConfig;
- ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));
-
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);
- ASSERT (ConfigRequestHdr != NULL);
-
- BufferSize = sizeof (MY_EFI_VARSTORE_DATA);
- Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);
- if (EFI_ERROR (Status)) {
- //
- // Store zero data to EFI variable Storage.
- //
- Status = gRT->SetVariable (
- MyEfiVar,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (MY_EFI_VARSTORE_DATA),
- VarStoreConfig
- );
- if (EFI_ERROR (Status)) {
- DriverSampleUnload (ImageHandle);
- return Status;
- }
-
- //
- // EFI variable for NV config doesn't exit, we should build this variable
- // based on default values stored in IFR
- //
- ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // EFI variable does exist and Validate Current Setting
- //
- ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- FreePool (ConfigRequestHdr);
-
- //
- // Initialize Bits efi varstore configuration data
- //
- BitsVarStoreConfig = &mPrivateData->BitsVarStoreConfig;
- ZeroMem (BitsVarStoreConfig, sizeof (MY_EFI_BITS_VARSTORE_DATA));
-
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiBitVar, DriverHandle[0]);
- ASSERT (ConfigRequestHdr != NULL);
-
- BufferSize = sizeof (MY_EFI_BITS_VARSTORE_DATA);
- Status = gRT->GetVariable (MyEfiBitVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, BitsVarStoreConfig);
- if (EFI_ERROR (Status)) {
- //
- // Store zero data to EFI variable Storage.
- //
- Status = gRT->SetVariable (
- MyEfiBitVar,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (MY_EFI_BITS_VARSTORE_DATA),
- BitsVarStoreConfig
- );
- if (EFI_ERROR (Status)) {
- DriverSampleUnload (ImageHandle);
- return Status;
- }
-
- //
- // EFI variable for NV config doesn't exit, we should build this variable
- // based on default values stored in IFR
- //
- ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // EFI variable does exist and Validate Current Setting
- //
- ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- FreePool (ConfigRequestHdr);
-
- //
- // Initialize Union efi varstore configuration data
- //
- UnionConfig = &mPrivateData->UnionConfig;
- ZeroMem (UnionConfig, sizeof (MY_EFI_UNION_DATA));
-
- ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiUnionVar, DriverHandle[0]);
- ASSERT (ConfigRequestHdr != NULL);
-
- BufferSize = sizeof (MY_EFI_UNION_DATA);
- Status = gRT->GetVariable (MyEfiUnionVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, UnionConfig);
- if (EFI_ERROR (Status)) {
- //
- // Store zero data to EFI variable Storage.
- //
- Status = gRT->SetVariable (
- MyEfiUnionVar,
- &gDriverSampleFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (MY_EFI_UNION_DATA),
- UnionConfig
- );
- if (EFI_ERROR (Status)) {
- DriverSampleUnload (ImageHandle);
- return Status;
- }
-
- //
- // EFI variable for NV config doesn't exit, we should build this variable
- // based on default values stored in IFR
- //
- ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // EFI variable does exist and Validate Current Setting
- //
- ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- if (!ActionFlag) {
- DriverSampleUnload (ImageHandle);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- FreePool (ConfigRequestHdr);
-
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- EfiEventEmptyFunction,
- NULL,
- &gEfiIfrRefreshIdOpGuid,
- &mEvent
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Example of how to use BrowserEx protocol to register HotKey.
- //
- Status = gBS->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid, NULL, (VOID **)&FormBrowserEx);
- if (!EFI_ERROR (Status)) {
- //
- // First unregister the default hot key F9 and F10.
- //
- HotKey.UnicodeChar = CHAR_NULL;
- HotKey.ScanCode = SCAN_F9;
- FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
- HotKey.ScanCode = SCAN_F10;
- FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
-
- //
- // Register the default HotKey F9 and F10 again.
- //
- HotKey.ScanCode = SCAN_F10;
- NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
- ASSERT (NewString != NULL);
- FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
- HotKey.ScanCode = SCAN_F9;
- NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
- ASSERT (NewString != NULL);
- FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
- }
-
- //
- // In default, this driver is built into Flash device image,
- // the following code doesn't run.
- //
-
- //
- // Example of how to display only the item we sent to HII
- // When this driver is not built into Flash device image,
- // it need to call SendForm to show front page by itself.
- //
- if (DISPLAY_ONLY_MY_ITEM <= 1) {
- //
- // Have the browser pull out our copy of the data, and only display our data
- //
- Status = FormBrowser2->SendForm (
- FormBrowser2,
- &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
- 1,
- NULL,
- 0,
- NULL,
- NULL
- );
-
- HiiRemovePackages (HiiHandle[0]);
-
- HiiRemovePackages (HiiHandle[1]);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Unloads the application and its installed protocol.
-
- @param[in] ImageHandle Handle that identifies the image to be unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
-**/
-EFI_STATUS
-EFIAPI
-DriverSampleUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- UINTN Index;
-
- ASSERT (mPrivateData != NULL);
-
- if (DriverHandle[0] != NULL) {
- gBS->UninstallMultipleProtocolInterfaces (
- DriverHandle[0],
- &gEfiDevicePathProtocolGuid,
- &mHiiVendorDevicePath0,
- &gEfiHiiConfigAccessProtocolGuid,
- &mPrivateData->ConfigAccess,
- NULL
- );
- DriverHandle[0] = NULL;
- }
-
- if (DriverHandle[1] != NULL) {
- gBS->UninstallMultipleProtocolInterfaces (
- DriverHandle[1],
- &gEfiDevicePathProtocolGuid,
- &mHiiVendorDevicePath1,
- &gEfiHiiConfigAccessProtocolGuid,
- &mPrivateData->ConfigAccess,
- NULL
- );
- DriverHandle[1] = NULL;
- }
-
- if (mPrivateData->HiiHandle[0] != NULL) {
- HiiRemovePackages (mPrivateData->HiiHandle[0]);
- }
-
- if (mPrivateData->HiiHandle[1] != NULL) {
- HiiRemovePackages (mPrivateData->HiiHandle[1]);
- }
-
- for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
- if (mPrivateData->NameValueName[Index] != NULL) {
- FreePool (mPrivateData->NameValueName[Index]);
- }
- }
-
- FreePool (mPrivateData);
- mPrivateData = NULL;
-
- gBS->CloseEvent (mEvent);
-
- return EFI_SUCCESS;
-}
+/** @file +This is an example of how a driver might export data to the HII protocol to be +later utilized by the Setup Protocol + +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "DriverSample.h" + +#define DISPLAY_ONLY_MY_ITEM 0x0002 + +CHAR16 VariableName[] = L"MyIfrNVData"; +CHAR16 MyEfiVar[] = L"MyEfiVar"; +CHAR16 MyEfiBitVar[] = L"MyEfiBitVar"; +CHAR16 MyEfiUnionVar[] = L"MyEfiUnionVar"; + +EFI_HANDLE DriverHandle[2] = { NULL, NULL }; +DRIVER_SAMPLE_PRIVATE_DATA *mPrivateData = NULL; +EFI_EVENT mEvent; + +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + DRIVER_SAMPLE_FORMSET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + DRIVER_SAMPLE_INVENTORY_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + Set value of a data element in an Array by its Index. + + @param Array The data array. + @param Type Type of the data in this array. + @param Index Zero based index for data in this array. + @param Value The value to be set. + +**/ +VOID +SetArrayData ( + IN VOID *Array, + IN UINT8 Type, + IN UINTN Index, + IN UINT64 Value + ) +{ + ASSERT (Array != NULL); + + switch (Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + *(((UINT8 *)Array) + Index) = (UINT8)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + *(((UINT16 *)Array) + Index) = (UINT16)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + *(((UINT32 *)Array) + Index) = (UINT32)Value; + break; + + case EFI_IFR_TYPE_NUM_SIZE_64: + *(((UINT64 *)Array) + Index) = (UINT64)Value; + break; + + default: + break; + } +} + +/** + Notification function for keystrokes. + + @param[in] KeyData The key that was pressed. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +EFIAPI +NotificationFunction ( + IN EFI_KEY_DATA *KeyData + ) +{ + gBS->SignalEvent (mEvent); + + return EFI_SUCCESS; +} + +/** + Function to start monitoring for CTRL-C using SimpleTextInputEx. + + @retval EFI_SUCCESS The feature is enabled. + @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available. +**/ +EFI_STATUS +EFIAPI +InternalStartMonitor ( + VOID + ) +{ + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; + EFI_KEY_DATA KeyData; + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN HandleCount; + UINTN HandleIndex; + VOID *NotifyHandle; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleTextInputExProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { + Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **)&SimpleEx); + ASSERT_EFI_ERROR (Status); + + KeyData.KeyState.KeyToggleState = 0; + KeyData.Key.ScanCode = 0; + KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED; + KeyData.Key.UnicodeChar = L'c'; + + Status = SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + NotificationFunction, + &NotifyHandle + ); + if (EFI_ERROR (Status)) { + break; + } + + KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED; + Status = SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + NotificationFunction, + &NotifyHandle + ); + if (EFI_ERROR (Status)) { + break; + } + } + + return EFI_SUCCESS; +} + +/** + Function to stop monitoring for CTRL-C using SimpleTextInputEx. + + @retval EFI_SUCCESS The feature is enabled. + @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available. +**/ +EFI_STATUS +EFIAPI +InternalStopMonitor ( + VOID + ) +{ + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; + EFI_STATUS Status; + EFI_HANDLE *Handles; + EFI_KEY_DATA KeyData; + UINTN HandleCount; + UINTN HandleIndex; + VOID *NotifyHandle; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleTextInputExProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { + Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **)&SimpleEx); + ASSERT_EFI_ERROR (Status); + + KeyData.KeyState.KeyToggleState = 0; + KeyData.Key.ScanCode = 0; + KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED; + KeyData.Key.UnicodeChar = L'c'; + + Status = SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + NotificationFunction, + &NotifyHandle + ); + if (!EFI_ERROR (Status)) { + Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle); + } + + KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED; + Status = SimpleEx->RegisterKeyNotify ( + SimpleEx, + &KeyData, + NotificationFunction, + &NotifyHandle + ); + if (!EFI_ERROR (Status)) { + Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle); + } + } + + return EFI_SUCCESS; +} + +/** + Update names of Name/Value storage to current language. + + @param PrivateData Points to the driver private data. + + @retval EFI_SUCCESS All names are successfully updated. + @retval EFI_NOT_FOUND Failed to get Name from HII database. + +**/ +EFI_STATUS +LoadNameValueNames ( + IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData + ) +{ + UINTN Index; + + // + // Get Name/Value name string of current language + // + for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) { + PrivateData->NameValueName[Index] = HiiGetString ( + PrivateData->HiiHandle[0], + PrivateData->NameStringId[Index], + NULL + ); + if (PrivateData->NameValueName[Index] == NULL) { + return EFI_NOT_FOUND; + } + } + + return EFI_SUCCESS; +} + +/** + Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET + or WIDTH or VALUE. + <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number> + + This is a internal function. + + @param StringPtr String in <BlockConfig> format and points to the + first character of <Number>. + @param Number The output value. Caller takes the responsibility + to free memory. + @param Len Length of the <Number>, in characters. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary + structures. + @retval EFI_SUCCESS Value of <Number> is outputted in Number + successfully. + +**/ +EFI_STATUS +GetValueOfNumber ( + IN EFI_STRING StringPtr, + OUT UINT8 **Number, + OUT UINTN *Len + ) +{ + EFI_STRING TmpPtr; + UINTN Length; + EFI_STRING Str; + UINT8 *Buf; + EFI_STATUS Status; + UINT8 DigitUint8; + UINTN Index; + CHAR16 TemStr[2]; + + if ((StringPtr == NULL) || (*StringPtr == L'\0') || (Number == NULL) || (Len == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Buf = NULL; + + TmpPtr = StringPtr; + while (*StringPtr != L'\0' && *StringPtr != L'&') { + StringPtr++; + } + + *Len = StringPtr - TmpPtr; + Length = *Len + 1; + + Str = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16)); + if (Str == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16)); + *(Str + *Len) = L'\0'; + + Length = (Length + 1) / 2; + Buf = (UINT8 *)AllocateZeroPool (Length); + if (Buf == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + Length = *Len; + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index++) { + TemStr[0] = Str[Length - Index - 1]; + DigitUint8 = (UINT8)StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + Buf[Index/2] = DigitUint8; + } else { + Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]); + } + } + + *Number = Buf; + Status = EFI_SUCCESS; + +Exit: + if (Str != NULL) { + FreePool (Str); + } + + return Status; +} + +/** + Create altcfg string. + + @param Result The request result string. + @param ConfigHdr The request head info. <ConfigHdr> format. + @param Offset The offset of the parameter int he structure. + @param Width The width of the parameter. + + + @retval The string with altcfg info append at the end. +**/ +EFI_STRING +CreateAltCfgString ( + IN EFI_STRING Result, + IN EFI_STRING ConfigHdr, + IN UINTN Offset, + IN UINTN Width + ) +{ + EFI_STRING StringPtr; + EFI_STRING TmpStr; + UINTN NewLen; + + NewLen = StrLen (Result); + // + // String Len = ConfigResp + AltConfig + AltConfig + 1("\0") + // + NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16); + StringPtr = AllocateZeroPool (NewLen); + if (StringPtr == NULL) { + return NULL; + } + + TmpStr = StringPtr; + if (Result != NULL) { + StrCpyS (StringPtr, NewLen / sizeof (CHAR16), Result); + StringPtr += StrLen (Result); + FreePool (Result); + } + + UnicodeSPrint ( + StringPtr, + (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), + L"&%s&ALTCFG=%04x", + ConfigHdr, + EFI_HII_DEFAULT_CLASS_STANDARD + ); + StringPtr += StrLen (StringPtr); + + UnicodeSPrint ( + StringPtr, + (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16), + L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", + Offset, + Width, + DEFAULT_CLASS_STANDARD_VALUE + ); + StringPtr += StrLen (StringPtr); + + UnicodeSPrint ( + StringPtr, + (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), + L"&%s&ALTCFG=%04x", + ConfigHdr, + EFI_HII_DEFAULT_CLASS_MANUFACTURING + ); + StringPtr += StrLen (StringPtr); + + UnicodeSPrint ( + StringPtr, + (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16), + L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", + Offset, + Width, + DEFAULT_CLASS_MANUFACTURING_VALUE + ); + StringPtr += StrLen (StringPtr); + + return TmpStr; +} + +/** + Check whether need to add the altcfg string. if need to add, add the altcfg + string. + + @param RequestResult The request result string. + @param ConfigRequestHdr The request head info. <ConfigHdr> format. + +**/ +VOID +AppendAltCfgString ( + IN OUT EFI_STRING *RequestResult, + IN EFI_STRING ConfigRequestHdr + ) +{ + EFI_STRING StringPtr; + UINTN Length; + UINT8 *TmpBuffer; + UINTN Offset; + UINTN Width; + UINTN BlockSize; + UINTN ValueOffset; + UINTN ValueWidth; + EFI_STATUS Status; + + TmpBuffer = NULL; + StringPtr = *RequestResult; + StringPtr = StrStr (StringPtr, L"OFFSET"); + BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); + ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess); + ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess); + + if (StringPtr == NULL) { + return; + } + + while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) { + StringPtr += StrLen (L"OFFSET="); + // + // Get Offset + // + Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + return; + } + + Offset = 0; + CopyMem ( + &Offset, + TmpBuffer, + (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN) + ); + FreePool (TmpBuffer); + + StringPtr += Length; + if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) { + return; + } + + StringPtr += StrLen (L"&WIDTH="); + + // + // Get Width + // + Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + return; + } + + Width = 0; + CopyMem ( + &Width, + TmpBuffer, + (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN) + ); + FreePool (TmpBuffer); + + StringPtr += Length; + if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) { + return; + } + + StringPtr += StrLen (L"&VALUE="); + + // + // Get Value + // + Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + return; + } + + StringPtr += Length; + + // + // Skip the character "&" before "OFFSET". + // + StringPtr++; + + // + // Calculate Value and convert it to hex string. + // + if (Offset + Width > BlockSize) { + return; + } + + if ((Offset <= ValueOffset) && (Offset + Width >= ValueOffset + ValueWidth)) { + *RequestResult = CreateAltCfgString (*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth); + return; + } + } +} + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Request A null-terminated Unicode string in + <ConfigRequest> format. + @param Progress On return, points to a character in the Request + string. Points to the string's null terminator if + request was successful. Points to the most recent + '&' before the first failing name/value pair (or + the beginning of the string if the failure is in + the first name/value pair) if the request was not + successful. + @param Results A null-terminated Unicode string in + <ConfigAltResp> format which has all values filled + in for the names in the Request string. String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + +**/ +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_STRING ConfigRequest; + EFI_STRING ConfigRequestHdr; + UINTN Size; + EFI_STRING Value; + UINTN ValueStrLen; + CHAR16 BackupChar; + CHAR16 *StrPointer; + BOOLEAN AllocatedRequest; + + if ((Progress == NULL) || (Results == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the local variables. + // + ConfigRequestHdr = NULL; + ConfigRequest = NULL; + Size = 0; + *Progress = Request; + AllocatedRequest = FALSE; + + PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); + HiiConfigRouting = PrivateData->HiiConfigRouting; + + // + // Get Buffer Storage data from EFI variable. + // Try to get the current setting from variable. + // + BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); + Status = gRT->GetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + NULL, + &BufferSize, + &PrivateData->Configuration + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + if (Request == NULL) { + // + // Request is set to NULL, construct full request string. + // + + // + // Allocate and fill a buffer large enough to hold the <ConfigHdr> template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator + // + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]); + Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + ASSERT (ConfigRequest != NULL); + AllocatedRequest = TRUE; + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); + FreePool (ConfigRequestHdr); + ConfigRequestHdr = NULL; + } else { + // + // Check routing data in <ConfigHdr>. + // Note: if only one Storage is used, then this checking could be skipped. + // + if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) { + return EFI_NOT_FOUND; + } + + // + // Check whether request for EFI Varstore. EFI varstore get data + // through hii database, not support in this path. + // + if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiVar)) { + return EFI_UNSUPPORTED; + } + + if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiBitVar)) { + return EFI_UNSUPPORTED; + } + + if (HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, MyEfiUnionVar)) { + return EFI_UNSUPPORTED; + } + + // + // Set Request to the unified request string. + // + ConfigRequest = Request; + // + // Check whether Request includes Request Element. + // + if (StrStr (Request, L"OFFSET") == NULL) { + // + // Check Request Element does exist in Reques String + // + StrPointer = StrStr (Request, L"PATH"); + if (StrPointer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (StrStr (StrPointer, L"&") == NULL) { + Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + ASSERT (ConfigRequest != NULL); + AllocatedRequest = TRUE; + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize); + } + } + } + + // + // Check if requesting Name/Value storage + // + if (StrStr (ConfigRequest, L"OFFSET") == NULL) { + // + // Update Name/Value storage Names + // + Status = LoadNameValueNames (PrivateData); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD" + // <Request> ::=<ConfigHdr>&Name0&Name1&Name2 + // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044 + // + BufferSize = (StrLen (ConfigRequest) + + 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 + + 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 + + 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16); + *Results = AllocateZeroPool (BufferSize); + ASSERT (*Results != NULL); + StrCpyS (*Results, BufferSize / sizeof (CHAR16), ConfigRequest); + Value = *Results; + + // + // Append value of NameValueVar0, type is UINT8 + // + if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) { + Value += StrLen (PrivateData->NameValueName[0]); + ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1); + CopyMem (Value + ValueStrLen, Value, StrSize (Value)); + + BackupChar = Value[ValueStrLen]; + *Value++ = L'='; + UnicodeValueToStringS ( + Value, + BufferSize - ((UINTN)Value - (UINTN)*Results), + PREFIX_ZERO | RADIX_HEX, + PrivateData->Configuration.NameValueVar0, + sizeof (PrivateData->Configuration.NameValueVar0) * 2 + ); + Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16)); + *Value = BackupChar; + } + + // + // Append value of NameValueVar1, type is UINT16 + // + if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) { + Value += StrLen (PrivateData->NameValueName[1]); + ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1); + CopyMem (Value + ValueStrLen, Value, StrSize (Value)); + + BackupChar = Value[ValueStrLen]; + *Value++ = L'='; + UnicodeValueToStringS ( + Value, + BufferSize - ((UINTN)Value - (UINTN)*Results), + PREFIX_ZERO | RADIX_HEX, + PrivateData->Configuration.NameValueVar1, + sizeof (PrivateData->Configuration.NameValueVar1) * 2 + ); + Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16)); + *Value = BackupChar; + } + + // + // Append value of NameValueVar2, type is CHAR16 * + // + if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) { + Value += StrLen (PrivateData->NameValueName[2]); + ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1; + CopyMem (Value + ValueStrLen, Value, StrSize (Value)); + + *Value++ = L'='; + // + // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044" + // + StrPointer = (CHAR16 *)PrivateData->Configuration.NameValueVar2; + for ( ; *StrPointer != L'\0'; StrPointer++) { + UnicodeValueToStringS ( + Value, + BufferSize - ((UINTN)Value - (UINTN)*Results), + PREFIX_ZERO | RADIX_HEX, + *StrPointer, + 4 + ); + Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16)); + } + } + + Status = EFI_SUCCESS; + } else { + // + // Convert buffer data to <ConfigResp> by helper function BlockToConfig() + // + Status = HiiConfigRouting->BlockToConfig ( + HiiConfigRouting, + ConfigRequest, + (UINT8 *)&PrivateData->Configuration, + BufferSize, + Results, + Progress + ); + if (!EFI_ERROR (Status)) { + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]); + AppendAltCfgString (Results, ConfigRequestHdr); + } + } + + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + } + + if (ConfigRequestHdr != NULL) { + FreePool (ConfigRequestHdr); + } + + // + // Set Progress string to the original request string. + // + if (Request == NULL) { + *Progress = NULL; + } else if (StrStr (Request, L"OFFSET") == NULL) { + *Progress = Request + StrLen (Request); + } + + return Status; +} + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Configuration A null-terminated Unicode string in <ConfigResp> + format. + @param Progress A pointer to a string filled in with the offset of + the most recent '&' before the first failing + name/value pair (or the beginning of the string if + the failure is in the first name/value pair) or + the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + @retval EFI_DEVICE_ERROR If value is 44, return error for testing. + +**/ +EFI_STATUS +EFIAPI +RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + CHAR16 *Value; + CHAR16 *StrPtr; + CHAR16 TemStr[5]; + UINT8 *DataBuffer; + UINT8 DigitUint8; + UINTN Index; + CHAR16 *StrBuffer; + + if ((Configuration == NULL) || (Progress == NULL)) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); + HiiConfigRouting = PrivateData->HiiConfigRouting; + *Progress = Configuration; + + // + // Check routing data in <ConfigHdr>. + // Note: if only one Storage is used, then this checking could be skipped. + // + if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) { + return EFI_NOT_FOUND; + } + + // + // Check whether request for EFI Varstore. EFI varstore get data + // through hii database, not support in this path. + // + if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) { + return EFI_UNSUPPORTED; + } + + if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiBitVar)) { + return EFI_UNSUPPORTED; + } + + if (HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, MyEfiUnionVar)) { + return EFI_UNSUPPORTED; + } + + // + // Get Buffer Storage data from EFI variable + // + BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); + Status = gRT->GetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + NULL, + &BufferSize, + &PrivateData->Configuration + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check if configuring Name/Value storage + // + if (StrStr (Configuration, L"OFFSET") == NULL) { + // + // Update Name/Value storage Names + // + Status = LoadNameValueNames (PrivateData); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Convert value for NameValueVar0 + // + if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) { + // + // Skip "Name=" + // + Value += StrLen (PrivateData->NameValueName[0]); + Value++; + // + // Get Value String + // + StrPtr = StrStr (Value, L"&"); + if (StrPtr == NULL) { + StrPtr = Value + StrLen (Value); + } + + // + // Convert Value to Buffer data + // + DataBuffer = (UINT8 *)&PrivateData->Configuration.NameValueVar0; + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0, StrPtr--; StrPtr >= Value; StrPtr--, Index++) { + TemStr[0] = *StrPtr; + DigitUint8 = (UINT8)StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + DataBuffer[Index/2] = DigitUint8; + } else { + DataBuffer[Index/2] = (UINT8)((UINT8)(DigitUint8 << 4) + DataBuffer[Index/2]); + } + } + } + + // + // Convert value for NameValueVar1 + // + if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) { + // + // Skip "Name=" + // + Value += StrLen (PrivateData->NameValueName[1]); + Value++; + // + // Get Value String + // + StrPtr = StrStr (Value, L"&"); + if (StrPtr == NULL) { + StrPtr = Value + StrLen (Value); + } + + // + // Convert Value to Buffer data + // + DataBuffer = (UINT8 *)&PrivateData->Configuration.NameValueVar1; + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0, StrPtr--; StrPtr >= Value; StrPtr--, Index++) { + TemStr[0] = *StrPtr; + DigitUint8 = (UINT8)StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + DataBuffer[Index/2] = DigitUint8; + } else { + DataBuffer[Index/2] = (UINT8)((UINT8)(DigitUint8 << 4) + DataBuffer[Index/2]); + } + } + } + + // + // Convert value for NameValueVar2 + // + if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) { + // + // Skip "Name=" + // + Value += StrLen (PrivateData->NameValueName[2]); + Value++; + // + // Get Value String + // + StrPtr = StrStr (Value, L"&"); + if (StrPtr == NULL) { + StrPtr = Value + StrLen (Value); + } + + // + // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD" + // + StrBuffer = (CHAR16 *)PrivateData->Configuration.NameValueVar2; + ZeroMem (TemStr, sizeof (TemStr)); + while (Value < StrPtr) { + StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value, 4); + *(StrBuffer++) = (CHAR16)StrHexToUint64 (TemStr); + Value += 4; + } + + *StrBuffer = L'\0'; + } + + // + // Store Buffer Storage back to EFI variable + // + Status = gRT->SetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + return Status; + } + + // + // Convert <ConfigResp> to buffer data by helper function ConfigToBlock() + // + BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); + Status = HiiConfigRouting->ConfigToBlock ( + HiiConfigRouting, + Configuration, + (UINT8 *)&PrivateData->Configuration, + &BufferSize, + Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (PrivateData->Configuration.QuestionApply == 44) { + // Return error for verify the error handling of caller. + return EFI_DEVICE_ERROR; + } + + // + // Store Buffer Storage back to EFI variable + // + Status = gRT->SetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + return Status; +} + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +DriverCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; + EFI_STATUS Status; + VOID *StartOpCodeHandle; + VOID *OptionsOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; + EFI_INPUT_KEY Key; + DRIVER_SAMPLE_CONFIGURATION *Configuration; + MY_EFI_VARSTORE_DATA *EfiData; + EFI_FORM_ID FormId; + EFI_STRING Progress; + EFI_STRING Results; + UINT32 ProgressErr; + CHAR16 *TmpStr; + UINTN Index; + UINT64 BufferValue; + EFI_HII_POPUP_SELECTION UserSelection; + + UserSelection = 0xFF; + + if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) || + (ActionRequest == NULL)) + { + return EFI_INVALID_PARAMETER; + } + + FormId = 0; + ProgressErr = 0; + Status = EFI_SUCCESS; + BufferValue = 3; + PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + { + if (QuestionId == 0x1234) { + // + // Sample CallBack for UEFI FORM_OPEN action: + // Add Save action into Form 3 when Form 1 is opened. + // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1. + // + PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); + + // + // Initialize the container for dynamic opcodes + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LABEL_UPDATE2; + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1238, // Question ID + STRING_TOKEN (STR_SAVE_TEXT), // Prompt text + STRING_TOKEN (STR_SAVE_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &gDriverSampleFormSetGuid, // Formset GUID + 0x3, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + NULL // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + } + + if (QuestionId == 0x1247) { + Status = InternalStartMonitor (); + ASSERT_EFI_ERROR (Status); + } + + break; + } + + case EFI_BROWSER_ACTION_FORM_CLOSE: + { + if (QuestionId == 0x5678) { + // + // Sample CallBack for UEFI FORM_CLOSE action: + // Show up a pop-up to specify Form 3 will be closed when exit Form 3. + // + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"You are going to leave third Form!", + L"Press ESC or ENTER to continue ...", + L"", + NULL + ); + } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); + } + + if (QuestionId == 0x1247) { + Status = InternalStopMonitor (); + ASSERT_EFI_ERROR (Status); + } + + break; + } + + case EFI_BROWSER_ACTION_RETRIEVE: + { + switch (QuestionId ) { + case 0x1248: + if (Type != EFI_IFR_TYPE_REF) { + return EFI_INVALID_PARAMETER; + } + + Value->ref.FormId = 0x3; + break; + + case 0x5678: + case 0x1247: + // + // We will reach here once the Question is refreshed + // + + // + // Initialize the container for dynamic opcodes + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + if (QuestionId == 0x5678) { + StartLabel->Number = LABEL_UPDATE2; + FormId = 0x03; + PrivateData->Configuration.DynamicRefresh++; + } else if (QuestionId == 0x1247 ) { + StartLabel->Number = LABEL_UPDATE3; + FormId = 0x06; + PrivateData->Configuration.RefreshGuidCount++; + } + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1237, // Question ID + STRING_TOKEN (STR_EXIT_TEXT), // Prompt text + STRING_TOKEN (STR_EXIT_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &gDriverSampleFormSetGuid, // Formset GUID + FormId, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + NULL // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + + // + // Refresh the Question value + // + Status = gRT->SetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + if (QuestionId == 0x5678) { + // + // Update uncommitted data of Browser + // + EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA)); + ASSERT (EfiData != NULL); + if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *)EfiData)) { + EfiData->Field8 = 111; + HiiSetBrowserData ( + &gDriverSampleFormSetGuid, + MyEfiVar, + sizeof (MY_EFI_VARSTORE_DATA), + (UINT8 *)EfiData, + NULL + ); + } + + FreePool (EfiData); + } + + break; + } + + break; + } + + case EFI_BROWSER_ACTION_DEFAULT_STANDARD: + { + switch (QuestionId) { + case 0x1240: + Value->u8 = DEFAULT_CLASS_STANDARD_VALUE; + break; + + case 0x1252: + for (Index = 0; Index < 3; Index++) { + SetArrayData (Value, EFI_IFR_TYPE_NUM_SIZE_8, Index, BufferValue--); + } + + break; + + case 0x6666: + Value->u8 = 12; + break; + + default: + Status = EFI_UNSUPPORTED; + break; + } + + break; + } + + case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING: + { + switch (QuestionId) { + case 0x1240: + Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE; + break; + + case 0x6666: + Value->u8 = 13; + break; + + default: + Status = EFI_UNSUPPORTED; + break; + } + + break; + } + + case EFI_BROWSER_ACTION_CHANGING: + { + switch (QuestionId) { + case 0x1249: + { + if (Type != EFI_IFR_TYPE_REF) { + return EFI_INVALID_PARAMETER; + } + + Value->ref.FormId = 0x1234; + break; + } + case 0x1234: + // + // Initialize the container for dynamic opcodes + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LABEL_UPDATE1; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1237, // Question ID + STRING_TOKEN (STR_EXIT_TEXT), // Prompt text + STRING_TOKEN (STR_EXIT_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + + // + // Create Option OpCode + // + OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle != NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_BOOT_OPTION1), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_BOOT_OPTION2), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 + ); + + // + // Prepare initial value for the dynamic created oneof Question + // + PrivateData->Configuration.DynamicOneof = 2; + Status = gRT->SetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + &PrivateData->Configuration + ); + + // + // Set initial vlaue of dynamic created oneof Question in Form Browser + // + Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION)); + ASSERT (Configuration != NULL); + if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *)Configuration)) { + Configuration->DynamicOneof = 2; + + // + // Update uncommitted data of Browser + // + HiiSetBrowserData ( + &gDriverSampleFormSetGuid, + VariableName, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + (UINT8 *)Configuration, + NULL + ); + } + + FreePool (Configuration); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8001, // Question ID (or call it "key") + CONFIGURATION_VARSTORE_ID, // VarStore ID + (UINT16)DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text + STRING_TOKEN (STR_ONE_OF_HELP), // Question help text + EFI_IFR_FLAG_CALLBACK, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + HiiCreateOrderedListOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x8002, // Question ID + CONFIGURATION_VARSTORE_ID, // VarStore ID + (UINT16)DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text + STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text + EFI_IFR_FLAG_RESET_REQUIRED, // Question flag + 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value + 5, // Maximum container + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_TEXT_SAMPLE_HELP), + STRING_TOKEN (STR_TEXT_SAMPLE_HELP), + STRING_TOKEN (STR_TEXT_SAMPLE_STRING) + ); + + HiiCreateDateOpCode ( + StartOpCodeHandle, + 0x8004, + 0x0, + 0x0, + STRING_TOKEN (STR_DATE_SAMPLE_HELP), + STRING_TOKEN (STR_DATE_SAMPLE_HELP), + 0, + QF_DATE_STORAGE_TIME, + NULL + ); + + HiiCreateTimeOpCode ( + StartOpCodeHandle, + 0x8005, + 0x0, + 0x0, + STRING_TOKEN (STR_TIME_SAMPLE_HELP), + STRING_TOKEN (STR_TIME_SAMPLE_HELP), + 0, + QF_TIME_STORAGE_TIME, + NULL + ); + + HiiCreateGotoOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 1, // Target Form ID + STRING_TOKEN (STR_GOTO_FORM1), // Prompt text + STRING_TOKEN (STR_GOTO_HELP), // Help text + 0, // Question flag + 0x8003 // Question ID + ); + + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &gDriverSampleFormSetGuid, // Formset GUID + 0x1234, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (OptionsOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + break; + + default: + break; + } + + break; + } + + case EFI_BROWSER_ACTION_CHANGED: + switch (QuestionId) { + case 0x1237: + // + // User press "Exit now", request Browser to exit + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + break; + + case 0x1238: + // + // User press "Save now", request Browser to save the uncommitted data. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + case 0x1241: + case 0x1246: + // + // User press "Submit current form and Exit now", request Browser to submit current form and exit + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; + break; + + case 0x1242: + // + // User press "Discard current form now", request Browser to discard the uncommitted data. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD; + break; + + case 0x1243: + // + // User press "Submit current form now", request Browser to save the uncommitted data. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + break; + + case 0x1244: + case 0x1245: + // + // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + case 0x1253: + // + // User change the value of "Question apply test". + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_QUESTION_APPLY; + break; + + case 0x1231: + // + // 1. Check to see whether system support keyword. + // + Status = PrivateData->HiiKeywordHandler->GetData ( + PrivateData->HiiKeywordHandler, + L"NAMESPACE=x-UEFI-ns", + L"KEYWORD=iSCSIBootEnable", + &Progress, + &ProgressErr, + &Results + ); + if (EFI_ERROR (Status)) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"This system not support this keyword!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + Status = EFI_SUCCESS; + break; + } + + // + // 2. If system support this keyword, just try to change value. + // + + // + // Change value from '0' to '1' or from '1' to '0' + // + TmpStr = StrStr (Results, L"&VALUE="); + ASSERT (TmpStr != NULL); + TmpStr += StrLen (L"&VALUE="); + TmpStr++; + if (*TmpStr == L'0') { + *TmpStr = L'1'; + } else { + *TmpStr = L'0'; + } + + // + // 3. Call the keyword handler protocol to change the value. + // + Status = PrivateData->HiiKeywordHandler->SetData ( + PrivateData->HiiKeywordHandler, + Results, + &Progress, + &ProgressErr + ); + if (EFI_ERROR (Status)) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"Set keyword to the system failed!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + Status = EFI_SUCCESS; + break; + } + + break; + + case 0x1330: + Status = mPrivateData->HiiPopup->CreatePopup ( + mPrivateData->HiiPopup, + EfiHiiPopupStyleInfo, + EfiHiiPopupTypeYesNo, + mPrivateData->HiiHandle[0], + STRING_TOKEN (STR_POPUP_STRING), + &UserSelection + ); + if (!EFI_ERROR (Status)) { + if (UserSelection == EfiHiiPopupSelectionYes) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; + } + } + + break; + + default: + break; + } + + break; + + case EFI_BROWSER_ACTION_SUBMITTED: + { + if (QuestionId == 0x1250) { + // + // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action: + // Show up a pop-up to show SUBMITTED callback has been triggered. + // + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"EfiVarstore value has been submitted!", + L"Press ESC or ENTER to continue ...", + L"", + NULL + ); + } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); + } + + break; + } + + default: + Status = EFI_UNSUPPORTED; + break; + } + + return Status; +} + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS This function always complete successfully. + +**/ +EFI_STATUS +EFIAPI +DriverSampleInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle[2]; + EFI_SCREEN_DESCRIPTOR Screen; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_STRING_PROTOCOL *HiiString; + EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; + EFI_HII_POPUP_PROTOCOL *PopupHandler; + CHAR16 *NewString; + UINTN BufferSize; + DRIVER_SAMPLE_CONFIGURATION *Configuration; + BOOLEAN ActionFlag; + EFI_STRING ConfigRequestHdr; + EFI_STRING NameRequestHdr; + MY_EFI_VARSTORE_DATA *VarStoreConfig; + MY_EFI_BITS_VARSTORE_DATA *BitsVarStoreConfig; + MY_EFI_UNION_DATA *UnionConfig; + EFI_INPUT_KEY HotKey; + EDKII_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx; + + // + // Initialize the local variables. + // + ConfigRequestHdr = NULL; + NewString = NULL; + + // + // Initialize screen dimensions for SendForm(). + // Remove 3 characters from top and bottom + // + ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR)); + gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow); + + Screen.TopRow = 3; + Screen.BottomRow = Screen.BottomRow - 3; + + // + // Initialize driver private data + // + mPrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA)); + if (mPrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE; + + mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig; + mPrivateData->ConfigAccess.RouteConfig = RouteConfig; + mPrivateData->ConfigAccess.Callback = DriverCallback; + + // + // Locate Hii Database protocol + // + Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->HiiDatabase = HiiDatabase; + + // + // Locate HiiString protocol + // + Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **)&HiiString); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->HiiString = HiiString; + + // + // Locate Formbrowser2 protocol + // + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&FormBrowser2); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->FormBrowser2 = FormBrowser2; + + // + // Locate ConfigRouting protocol + // + Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->HiiConfigRouting = HiiConfigRouting; + + // + // Locate keyword handler protocol + // + Status = gBS->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid, NULL, (VOID **)&HiiKeywordHandler); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->HiiKeywordHandler = HiiKeywordHandler; + + // + // Locate HiiPopup protocol + // + Status = gBS->LocateProtocol (&gEfiHiiPopupProtocolGuid, NULL, (VOID **)&PopupHandler); + if (EFI_ERROR (Status)) { + return Status; + } + + mPrivateData->HiiPopup = PopupHandler; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle[0], + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath0, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + mPrivateData->DriverHandle[0] = DriverHandle[0]; + + // + // Publish our HII data + // + HiiHandle[0] = HiiAddPackages ( + &gDriverSampleFormSetGuid, + DriverHandle[0], + DriverSampleStrings, + VfrBin, + NULL + ); + if (HiiHandle[0] == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->HiiHandle[0] = HiiHandle[0]; + + // + // Publish another Fromset + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle[1], + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath1, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + mPrivateData->DriverHandle[1] = DriverHandle[1]; + + HiiHandle[1] = HiiAddPackages ( + &gDriverSampleInventoryGuid, + DriverHandle[1], + DriverSampleStrings, + InventoryBin, + NULL + ); + if (HiiHandle[1] == NULL) { + DriverSampleUnload (ImageHandle); + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->HiiHandle[1] = HiiHandle[1]; + + // + // Update the device path string. + // + NewString = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)&mHiiVendorDevicePath0, FALSE, FALSE); + if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) { + DriverSampleUnload (ImageHandle); + return EFI_OUT_OF_RESOURCES; + } + + if (NewString != NULL) { + FreePool (NewString); + } + + // + // Very simple example of how one would update a string that is already + // in the HII database + // + NewString = L"700 Mhz"; + + if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) { + DriverSampleUnload (ImageHandle); + return EFI_OUT_OF_RESOURCES; + } + + HiiSetString (HiiHandle[0], 0, NewString, NULL); + + // + // Initialize Name/Value name String ID + // + mPrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0; + mPrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1; + mPrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2; + + // + // Initialize configuration data + // + Configuration = &mPrivateData->Configuration; + ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION)); + + // + // Try to read NV config EFI variable first + // + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]); + ASSERT (ConfigRequestHdr != NULL); + + NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]); + ASSERT (NameRequestHdr != NULL); + + BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); + Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration); + if (EFI_ERROR (Status)) { + // + // Store zero data Buffer Storage to EFI variable + // + Status = gRT->SetVariable ( + VariableName, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (DRIVER_SAMPLE_CONFIGURATION), + Configuration + ); + if (EFI_ERROR (Status)) { + DriverSampleUnload (ImageHandle); + return Status; + } + + // + // EFI variable for NV config doesn't exit, we should build this variable + // based on default values stored in IFR + // + ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + + ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } else { + // + // EFI variable does exist and Validate Current Setting + // + ActionFlag = HiiValidateSettings (NameRequestHdr); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + + ActionFlag = HiiValidateSettings (ConfigRequestHdr); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } + + FreePool (ConfigRequestHdr); + + // + // Initialize efi varstore configuration data + // + VarStoreConfig = &mPrivateData->VarStoreConfig; + ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA)); + + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]); + ASSERT (ConfigRequestHdr != NULL); + + BufferSize = sizeof (MY_EFI_VARSTORE_DATA); + Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig); + if (EFI_ERROR (Status)) { + // + // Store zero data to EFI variable Storage. + // + Status = gRT->SetVariable ( + MyEfiVar, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (MY_EFI_VARSTORE_DATA), + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + DriverSampleUnload (ImageHandle); + return Status; + } + + // + // EFI variable for NV config doesn't exit, we should build this variable + // based on default values stored in IFR + // + ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } else { + // + // EFI variable does exist and Validate Current Setting + // + ActionFlag = HiiValidateSettings (ConfigRequestHdr); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } + + FreePool (ConfigRequestHdr); + + // + // Initialize Bits efi varstore configuration data + // + BitsVarStoreConfig = &mPrivateData->BitsVarStoreConfig; + ZeroMem (BitsVarStoreConfig, sizeof (MY_EFI_BITS_VARSTORE_DATA)); + + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiBitVar, DriverHandle[0]); + ASSERT (ConfigRequestHdr != NULL); + + BufferSize = sizeof (MY_EFI_BITS_VARSTORE_DATA); + Status = gRT->GetVariable (MyEfiBitVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, BitsVarStoreConfig); + if (EFI_ERROR (Status)) { + // + // Store zero data to EFI variable Storage. + // + Status = gRT->SetVariable ( + MyEfiBitVar, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (MY_EFI_BITS_VARSTORE_DATA), + BitsVarStoreConfig + ); + if (EFI_ERROR (Status)) { + DriverSampleUnload (ImageHandle); + return Status; + } + + // + // EFI variable for NV config doesn't exit, we should build this variable + // based on default values stored in IFR + // + ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } else { + // + // EFI variable does exist and Validate Current Setting + // + ActionFlag = HiiValidateSettings (ConfigRequestHdr); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } + + FreePool (ConfigRequestHdr); + + // + // Initialize Union efi varstore configuration data + // + UnionConfig = &mPrivateData->UnionConfig; + ZeroMem (UnionConfig, sizeof (MY_EFI_UNION_DATA)); + + ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiUnionVar, DriverHandle[0]); + ASSERT (ConfigRequestHdr != NULL); + + BufferSize = sizeof (MY_EFI_UNION_DATA); + Status = gRT->GetVariable (MyEfiUnionVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, UnionConfig); + if (EFI_ERROR (Status)) { + // + // Store zero data to EFI variable Storage. + // + Status = gRT->SetVariable ( + MyEfiUnionVar, + &gDriverSampleFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (MY_EFI_UNION_DATA), + UnionConfig + ); + if (EFI_ERROR (Status)) { + DriverSampleUnload (ImageHandle); + return Status; + } + + // + // EFI variable for NV config doesn't exit, we should build this variable + // based on default values stored in IFR + // + ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } else { + // + // EFI variable does exist and Validate Current Setting + // + ActionFlag = HiiValidateSettings (ConfigRequestHdr); + if (!ActionFlag) { + DriverSampleUnload (ImageHandle); + return EFI_INVALID_PARAMETER; + } + } + + FreePool (ConfigRequestHdr); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + EfiEventEmptyFunction, + NULL, + &gEfiIfrRefreshIdOpGuid, + &mEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Example of how to use BrowserEx protocol to register HotKey. + // + Status = gBS->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid, NULL, (VOID **)&FormBrowserEx); + if (!EFI_ERROR (Status)) { + // + // First unregister the default hot key F9 and F10. + // + HotKey.UnicodeChar = CHAR_NULL; + HotKey.ScanCode = SCAN_F9; + FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL); + HotKey.ScanCode = SCAN_F10; + FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL); + + // + // Register the default HotKey F9 and F10 again. + // + HotKey.ScanCode = SCAN_F10; + NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL); + ASSERT (NewString != NULL); + FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString); + HotKey.ScanCode = SCAN_F9; + NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL); + ASSERT (NewString != NULL); + FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString); + } + + // + // In default, this driver is built into Flash device image, + // the following code doesn't run. + // + + // + // Example of how to display only the item we sent to HII + // When this driver is not built into Flash device image, + // it need to call SendForm to show front page by itself. + // + if (DISPLAY_ONLY_MY_ITEM <= 1) { + // + // Have the browser pull out our copy of the data, and only display our data + // + Status = FormBrowser2->SendForm ( + FormBrowser2, + &(HiiHandle[DISPLAY_ONLY_MY_ITEM]), + 1, + NULL, + 0, + NULL, + NULL + ); + + HiiRemovePackages (HiiHandle[0]); + + HiiRemovePackages (HiiHandle[1]); + } + + return EFI_SUCCESS; +} + +/** + Unloads the application and its installed protocol. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +DriverSampleUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + UINTN Index; + + ASSERT (mPrivateData != NULL); + + if (DriverHandle[0] != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle[0], + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath0, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + DriverHandle[0] = NULL; + } + + if (DriverHandle[1] != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle[1], + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath1, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + DriverHandle[1] = NULL; + } + + if (mPrivateData->HiiHandle[0] != NULL) { + HiiRemovePackages (mPrivateData->HiiHandle[0]); + } + + if (mPrivateData->HiiHandle[1] != NULL) { + HiiRemovePackages (mPrivateData->HiiHandle[1]); + } + + for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) { + if (mPrivateData->NameValueName[Index] != NULL) { + FreePool (mPrivateData->NameValueName[Index]); + } + } + + FreePool (mPrivateData); + mPrivateData = NULL; + + gBS->CloseEvent (mEvent); + + return EFI_SUCCESS; +} |
