summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c')
-rw-r--r--MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c4608
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;
+}