2 This is an example of how a driver might export data to the HII protocol to be
3 later utilized by the Setup Protocol
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "DriverSample.h"
13 #define DISPLAY_ONLY_MY_ITEM 0x0002
15 CHAR16 VariableName
[] = L
"MyIfrNVData";
16 CHAR16 MyEfiVar
[] = L
"MyEfiVar";
17 CHAR16 MyEfiBitVar
[] = L
"MyEfiBitVar";
18 CHAR16 MyEfiUnionVar
[] = L
"MyEfiUnionVar";
20 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
21 DRIVER_SAMPLE_PRIVATE_DATA
*mPrivateData
= NULL
;
24 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
30 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
31 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
34 DRIVER_SAMPLE_FORMSET_GUID
38 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
40 (UINT8
) (END_DEVICE_PATH_LENGTH
),
41 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
46 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
52 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
53 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
56 DRIVER_SAMPLE_INVENTORY_GUID
60 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
62 (UINT8
) (END_DEVICE_PATH_LENGTH
),
63 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
69 Set value of a data element in an Array by its Index.
71 @param Array The data array.
72 @param Type Type of the data in this array.
73 @param Index Zero based index for data in this array.
74 @param Value The value to be set.
86 ASSERT (Array
!= NULL
);
89 case EFI_IFR_TYPE_NUM_SIZE_8
:
90 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
93 case EFI_IFR_TYPE_NUM_SIZE_16
:
94 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
97 case EFI_IFR_TYPE_NUM_SIZE_32
:
98 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
101 case EFI_IFR_TYPE_NUM_SIZE_64
:
102 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
111 Notification function for keystrokes.
113 @param[in] KeyData The key that was pressed.
115 @retval EFI_SUCCESS The operation was successful.
119 NotificationFunction(
120 IN EFI_KEY_DATA
*KeyData
123 gBS
->SignalEvent (mEvent
);
129 Function to start monitoring for CTRL-C using SimpleTextInputEx.
131 @retval EFI_SUCCESS The feature is enabled.
132 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
136 InternalStartMonitor(
140 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
141 EFI_KEY_DATA KeyData
;
146 EFI_HANDLE NotifyHandle
;
148 Status
= gBS
->LocateHandleBuffer (
150 &gEfiSimpleTextInputExProtocolGuid
,
155 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
156 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
157 ASSERT_EFI_ERROR (Status
);
159 KeyData
.KeyState
.KeyToggleState
= 0;
160 KeyData
.Key
.ScanCode
= 0;
161 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
162 KeyData
.Key
.UnicodeChar
= L
'c';
164 Status
= SimpleEx
->RegisterKeyNotify(
167 NotificationFunction
,
169 if (EFI_ERROR (Status
)) {
173 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
174 Status
= SimpleEx
->RegisterKeyNotify(
177 NotificationFunction
,
179 if (EFI_ERROR (Status
)) {
188 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
190 @retval EFI_SUCCESS The feature is enabled.
191 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
199 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
202 EFI_KEY_DATA KeyData
;
205 EFI_HANDLE NotifyHandle
;
207 Status
= gBS
->LocateHandleBuffer (
209 &gEfiSimpleTextInputExProtocolGuid
,
214 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
215 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
216 ASSERT_EFI_ERROR (Status
);
218 KeyData
.KeyState
.KeyToggleState
= 0;
219 KeyData
.Key
.ScanCode
= 0;
220 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
221 KeyData
.Key
.UnicodeChar
= L
'c';
223 Status
= SimpleEx
->RegisterKeyNotify(
226 NotificationFunction
,
228 if (!EFI_ERROR (Status
)) {
229 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
232 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
233 Status
= SimpleEx
->RegisterKeyNotify(
236 NotificationFunction
,
238 if (!EFI_ERROR (Status
)) {
239 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
246 Update names of Name/Value storage to current language.
248 @param PrivateData Points to the driver private data.
250 @retval EFI_SUCCESS All names are successfully updated.
251 @retval EFI_NOT_FOUND Failed to get Name from HII database.
256 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
262 // Get Name/Value name string of current language
264 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
265 PrivateData
->NameValueName
[Index
] = HiiGetString (
266 PrivateData
->HiiHandle
[0],
267 PrivateData
->NameStringId
[Index
],
270 if (PrivateData
->NameValueName
[Index
] == NULL
) {
271 return EFI_NOT_FOUND
;
280 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
282 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
284 This is a internal function.
286 @param StringPtr String in <BlockConfig> format and points to the
287 first character of <Number>.
288 @param Number The output value. Caller takes the responsibility
290 @param Len Length of the <Number>, in characters.
292 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
294 @retval EFI_SUCCESS Value of <Number> is outputted in Number
300 IN EFI_STRING StringPtr
,
314 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
315 return EFI_INVALID_PARAMETER
;
321 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
324 *Len
= StringPtr
- TmpPtr
;
327 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
329 Status
= EFI_OUT_OF_RESOURCES
;
332 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
333 *(Str
+ *Len
) = L
'\0';
335 Length
= (Length
+ 1) / 2;
336 Buf
= (UINT8
*) AllocateZeroPool (Length
);
338 Status
= EFI_OUT_OF_RESOURCES
;
343 ZeroMem (TemStr
, sizeof (TemStr
));
344 for (Index
= 0; Index
< Length
; Index
++) {
345 TemStr
[0] = Str
[Length
- Index
- 1];
346 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
347 if ((Index
& 1) == 0) {
348 Buf
[Index
/2] = DigitUint8
;
350 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
355 Status
= EFI_SUCCESS
;
366 Create altcfg string.
368 @param Result The request result string.
369 @param ConfigHdr The request head info. <ConfigHdr> format.
370 @param Offset The offset of the parameter int he structure.
371 @param Width The width of the parameter.
374 @retval The string with altcfg info append at the end.
378 IN EFI_STRING Result
,
379 IN EFI_STRING ConfigHdr
,
384 EFI_STRING StringPtr
;
388 NewLen
= StrLen (Result
);
390 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
392 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
393 StringPtr
= AllocateZeroPool (NewLen
);
394 if (StringPtr
== NULL
) {
399 if (Result
!= NULL
) {
400 StrCpyS (StringPtr
, NewLen
/ sizeof (CHAR16
), Result
);
401 StringPtr
+= StrLen (Result
);
407 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
410 EFI_HII_DEFAULT_CLASS_STANDARD
412 StringPtr
+= StrLen (StringPtr
);
416 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
417 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
420 DEFAULT_CLASS_STANDARD_VALUE
422 StringPtr
+= StrLen (StringPtr
);
426 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
429 EFI_HII_DEFAULT_CLASS_MANUFACTURING
431 StringPtr
+= StrLen (StringPtr
);
435 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
436 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
439 DEFAULT_CLASS_MANUFACTURING_VALUE
441 StringPtr
+= StrLen (StringPtr
);
447 Check whether need to add the altcfg string. if need to add, add the altcfg
450 @param RequestResult The request result string.
451 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
456 IN OUT EFI_STRING
*RequestResult
,
457 IN EFI_STRING ConfigRequestHdr
460 EFI_STRING StringPtr
;
471 StringPtr
= *RequestResult
;
472 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
473 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
474 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
475 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
477 if (StringPtr
== NULL
) {
481 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
482 StringPtr
+= StrLen (L
"OFFSET=");
486 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
487 if (EFI_ERROR (Status
)) {
494 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
496 FreePool (TmpBuffer
);
499 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
502 StringPtr
+= StrLen (L
"&WIDTH=");
507 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
508 if (EFI_ERROR (Status
)) {
515 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
517 FreePool (TmpBuffer
);
520 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
523 StringPtr
+= StrLen (L
"&VALUE=");
528 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
529 if (EFI_ERROR (Status
)) {
535 // Skip the character "&" before "OFFSET".
540 // Calculate Value and convert it to hex string.
542 if (Offset
+ Width
> BlockSize
) {
546 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
547 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
554 This function allows a caller to extract the current configuration for one
555 or more named elements from the target driver.
557 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
558 @param Request A null-terminated Unicode string in
559 <ConfigRequest> format.
560 @param Progress On return, points to a character in the Request
561 string. Points to the string's null terminator if
562 request was successful. Points to the most recent
563 '&' before the first failing name/value pair (or
564 the beginning of the string if the failure is in
565 the first name/value pair) if the request was not
567 @param Results A null-terminated Unicode string in
568 <ConfigAltResp> format which has all values filled
569 in for the names in the Request string. String to
570 be allocated by the called function.
572 @retval EFI_SUCCESS The Results is filled with the requested values.
573 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
574 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
575 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
582 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
583 IN CONST EFI_STRING Request
,
584 OUT EFI_STRING
*Progress
,
585 OUT EFI_STRING
*Results
590 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
591 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
592 EFI_STRING ConfigRequest
;
593 EFI_STRING ConfigRequestHdr
;
599 BOOLEAN AllocatedRequest
;
601 if (Progress
== NULL
|| Results
== NULL
) {
602 return EFI_INVALID_PARAMETER
;
605 // Initialize the local variables.
607 ConfigRequestHdr
= NULL
;
608 ConfigRequest
= NULL
;
611 AllocatedRequest
= FALSE
;
613 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
614 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
617 // Get Buffer Storage data from EFI variable.
618 // Try to get the current setting from variable.
620 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
621 Status
= gRT
->GetVariable (
623 &gDriverSampleFormSetGuid
,
626 &PrivateData
->Configuration
628 if (EFI_ERROR (Status
)) {
629 return EFI_NOT_FOUND
;
632 if (Request
== NULL
) {
634 // Request is set to NULL, construct full request string.
638 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
639 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
641 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
642 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
643 ConfigRequest
= AllocateZeroPool (Size
);
644 ASSERT (ConfigRequest
!= NULL
);
645 AllocatedRequest
= TRUE
;
646 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
647 FreePool (ConfigRequestHdr
);
648 ConfigRequestHdr
= NULL
;
651 // Check routing data in <ConfigHdr>.
652 // Note: if only one Storage is used, then this checking could be skipped.
654 if (!HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, NULL
)) {
655 return EFI_NOT_FOUND
;
658 // Check whether request for EFI Varstore. EFI varstore get data
659 // through hii database, not support in this path.
661 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
662 return EFI_UNSUPPORTED
;
664 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
665 return EFI_UNSUPPORTED
;
667 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
668 return EFI_UNSUPPORTED
;
672 // Set Request to the unified request string.
674 ConfigRequest
= Request
;
676 // Check whether Request includes Request Element.
678 if (StrStr (Request
, L
"OFFSET") == NULL
) {
680 // Check Request Element does exist in Reques String
682 StrPointer
= StrStr (Request
, L
"PATH");
683 if (StrPointer
== NULL
) {
684 return EFI_INVALID_PARAMETER
;
686 if (StrStr (StrPointer
, L
"&") == NULL
) {
687 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
688 ConfigRequest
= AllocateZeroPool (Size
);
689 ASSERT (ConfigRequest
!= NULL
);
690 AllocatedRequest
= TRUE
;
691 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
697 // Check if requesting Name/Value storage
699 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
701 // Update Name/Value storage Names
703 Status
= LoadNameValueNames (PrivateData
);
704 if (EFI_ERROR (Status
)) {
709 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
710 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
711 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
713 BufferSize
= (StrLen (ConfigRequest
) +
714 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
715 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
716 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
717 *Results
= AllocateZeroPool (BufferSize
);
718 ASSERT (*Results
!= NULL
);
719 StrCpyS (*Results
, BufferSize
/ sizeof (CHAR16
), ConfigRequest
);
723 // Append value of NameValueVar0, type is UINT8
725 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
726 Value
+= StrLen (PrivateData
->NameValueName
[0]);
727 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
728 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
730 BackupChar
= Value
[ValueStrLen
];
732 UnicodeValueToStringS (
734 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
735 PREFIX_ZERO
| RADIX_HEX
,
736 PrivateData
->Configuration
.NameValueVar0
,
737 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
739 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
744 // Append value of NameValueVar1, type is UINT16
746 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
747 Value
+= StrLen (PrivateData
->NameValueName
[1]);
748 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
749 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
751 BackupChar
= Value
[ValueStrLen
];
753 UnicodeValueToStringS (
755 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
756 PREFIX_ZERO
| RADIX_HEX
,
757 PrivateData
->Configuration
.NameValueVar1
,
758 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
760 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
765 // Append value of NameValueVar2, type is CHAR16 *
767 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
768 Value
+= StrLen (PrivateData
->NameValueName
[2]);
769 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
770 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
774 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
776 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
777 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
778 UnicodeValueToStringS (
780 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
781 PREFIX_ZERO
| RADIX_HEX
,
785 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
789 Status
= EFI_SUCCESS
;
792 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
794 Status
= HiiConfigRouting
->BlockToConfig (
797 (UINT8
*) &PrivateData
->Configuration
,
802 if (!EFI_ERROR (Status
)) {
803 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
804 AppendAltCfgString(Results
, ConfigRequestHdr
);
809 // Free the allocated config request string.
811 if (AllocatedRequest
) {
812 FreePool (ConfigRequest
);
815 if (ConfigRequestHdr
!= NULL
) {
816 FreePool (ConfigRequestHdr
);
819 // Set Progress string to the original request string.
821 if (Request
== NULL
) {
823 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
824 *Progress
= Request
+ StrLen (Request
);
832 This function processes the results of changes in configuration.
834 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
835 @param Configuration A null-terminated Unicode string in <ConfigResp>
837 @param Progress A pointer to a string filled in with the offset of
838 the most recent '&' before the first failing
839 name/value pair (or the beginning of the string if
840 the failure is in the first name/value pair) or
841 the terminating NULL if all was successful.
843 @retval EFI_SUCCESS The Results is processed successfully.
844 @retval EFI_INVALID_PARAMETER Configuration is NULL.
845 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
852 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
853 IN CONST EFI_STRING Configuration
,
854 OUT EFI_STRING
*Progress
859 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
860 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
869 if (Configuration
== NULL
|| Progress
== NULL
) {
870 return EFI_INVALID_PARAMETER
;
873 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
874 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
875 *Progress
= Configuration
;
878 // Check routing data in <ConfigHdr>.
879 // Note: if only one Storage is used, then this checking could be skipped.
881 if (!HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, NULL
)) {
882 return EFI_NOT_FOUND
;
886 // Check whether request for EFI Varstore. EFI varstore get data
887 // through hii database, not support in this path.
889 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
890 return EFI_UNSUPPORTED
;
892 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
893 return EFI_UNSUPPORTED
;
895 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
896 return EFI_UNSUPPORTED
;
900 // Get Buffer Storage data from EFI variable
902 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
903 Status
= gRT
->GetVariable (
905 &gDriverSampleFormSetGuid
,
908 &PrivateData
->Configuration
910 if (EFI_ERROR (Status
)) {
915 // Check if configuring Name/Value storage
917 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
919 // Update Name/Value storage Names
921 Status
= LoadNameValueNames (PrivateData
);
922 if (EFI_ERROR (Status
)) {
927 // Convert value for NameValueVar0
929 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
933 Value
+= StrLen (PrivateData
->NameValueName
[0]);
938 StrPtr
= StrStr (Value
, L
"&");
939 if (StrPtr
== NULL
) {
940 StrPtr
= Value
+ StrLen (Value
);
943 // Convert Value to Buffer data
945 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
946 ZeroMem (TemStr
, sizeof (TemStr
));
947 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
949 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
950 if ((Index
& 1) == 0) {
951 DataBuffer
[Index
/2] = DigitUint8
;
953 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
959 // Convert value for NameValueVar1
961 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
965 Value
+= StrLen (PrivateData
->NameValueName
[1]);
970 StrPtr
= StrStr (Value
, L
"&");
971 if (StrPtr
== NULL
) {
972 StrPtr
= Value
+ StrLen (Value
);
975 // Convert Value to Buffer data
977 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
978 ZeroMem (TemStr
, sizeof (TemStr
));
979 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
981 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
982 if ((Index
& 1) == 0) {
983 DataBuffer
[Index
/2] = DigitUint8
;
985 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
991 // Convert value for NameValueVar2
993 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
997 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1002 StrPtr
= StrStr (Value
, L
"&");
1003 if (StrPtr
== NULL
) {
1004 StrPtr
= Value
+ StrLen (Value
);
1007 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1009 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1010 ZeroMem (TemStr
, sizeof (TemStr
));
1011 while (Value
< StrPtr
) {
1012 StrnCpyS (TemStr
, sizeof (TemStr
) / sizeof (CHAR16
), Value
, 4);
1013 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1020 // Store Buffer Storage back to EFI variable
1022 Status
= gRT
->SetVariable(
1024 &gDriverSampleFormSetGuid
,
1025 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1026 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1027 &PrivateData
->Configuration
1034 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1036 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1037 Status
= HiiConfigRouting
->ConfigToBlock (
1040 (UINT8
*) &PrivateData
->Configuration
,
1044 if (EFI_ERROR (Status
)) {
1049 // Store Buffer Storage back to EFI variable
1051 Status
= gRT
->SetVariable(
1053 &gDriverSampleFormSetGuid
,
1054 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1055 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1056 &PrivateData
->Configuration
1064 This function processes the results of changes in configuration.
1066 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1067 @param Action Specifies the type of action taken by the browser.
1068 @param QuestionId A unique value which is sent to the original
1069 exporting driver so that it can identify the type
1071 @param Type The type of value for the question.
1072 @param Value A pointer to the data being sent to the original
1074 @param ActionRequest On return, points to the action requested by the
1077 @retval EFI_SUCCESS The callback successfully handled the action.
1078 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1079 variable and its data.
1080 @retval EFI_DEVICE_ERROR The variable could not be saved.
1081 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1088 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1089 IN EFI_BROWSER_ACTION Action
,
1090 IN EFI_QUESTION_ID QuestionId
,
1092 IN EFI_IFR_TYPE_VALUE
*Value
,
1093 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1096 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1098 VOID
*StartOpCodeHandle
;
1099 VOID
*OptionsOpCodeHandle
;
1100 EFI_IFR_GUID_LABEL
*StartLabel
;
1101 VOID
*EndOpCodeHandle
;
1102 EFI_IFR_GUID_LABEL
*EndLabel
;
1104 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1105 MY_EFI_VARSTORE_DATA
*EfiData
;
1107 EFI_STRING Progress
;
1113 EFI_HII_POPUP_SELECTION UserSelection
;
1115 UserSelection
= 0xFF;
1117 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1118 (ActionRequest
== NULL
)) {
1119 return EFI_INVALID_PARAMETER
;
1125 Status
= EFI_SUCCESS
;
1127 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1130 case EFI_BROWSER_ACTION_FORM_OPEN
:
1132 if (QuestionId
== 0x1234) {
1134 // Sample CallBack for UEFI FORM_OPEN action:
1135 // Add Save action into Form 3 when Form 1 is opened.
1136 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1138 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1141 // Initialize the container for dynamic opcodes
1143 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1144 ASSERT (StartOpCodeHandle
!= NULL
);
1147 // Create Hii Extend Label OpCode as the start opcode
1149 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1150 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1151 StartLabel
->Number
= LABEL_UPDATE2
;
1153 HiiCreateActionOpCode (
1154 StartOpCodeHandle
, // Container for dynamic created opcodes
1155 0x1238, // Question ID
1156 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1157 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1158 EFI_IFR_FLAG_CALLBACK
, // Question flag
1159 0 // Action String ID
1163 PrivateData
->HiiHandle
[0], // HII handle
1164 &gDriverSampleFormSetGuid
, // Formset GUID
1166 StartOpCodeHandle
, // Label for where to insert opcodes
1170 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1173 if (QuestionId
== 0x1247) {
1174 Status
= InternalStartMonitor ();
1175 ASSERT_EFI_ERROR (Status
);
1180 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1182 if (QuestionId
== 0x5678) {
1184 // Sample CallBack for UEFI FORM_CLOSE action:
1185 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1189 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1192 L
"You are going to leave third Form!",
1193 L
"Press ESC or ENTER to continue ...",
1197 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1200 if (QuestionId
== 0x1247) {
1201 Status
= InternalStopMonitor ();
1202 ASSERT_EFI_ERROR (Status
);
1207 case EFI_BROWSER_ACTION_RETRIEVE
:
1209 switch (QuestionId
) {
1211 if (Type
!= EFI_IFR_TYPE_REF
) {
1212 return EFI_INVALID_PARAMETER
;
1214 Value
->ref
.FormId
= 0x3;
1220 // We will reach here once the Question is refreshed
1224 // Initialize the container for dynamic opcodes
1226 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1227 ASSERT (StartOpCodeHandle
!= NULL
);
1230 // Create Hii Extend Label OpCode as the start opcode
1232 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1233 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1234 if (QuestionId
== 0x5678) {
1235 StartLabel
->Number
= LABEL_UPDATE2
;
1237 PrivateData
->Configuration
.DynamicRefresh
++;
1238 } else if (QuestionId
== 0x1247 ) {
1239 StartLabel
->Number
= LABEL_UPDATE3
;
1241 PrivateData
->Configuration
.RefreshGuidCount
++;
1244 HiiCreateActionOpCode (
1245 StartOpCodeHandle
, // Container for dynamic created opcodes
1246 0x1237, // Question ID
1247 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1248 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1249 EFI_IFR_FLAG_CALLBACK
, // Question flag
1250 0 // Action String ID
1254 PrivateData
->HiiHandle
[0], // HII handle
1255 &gDriverSampleFormSetGuid
, // Formset GUID
1257 StartOpCodeHandle
, // Label for where to insert opcodes
1261 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1264 // Refresh the Question value
1266 Status
= gRT
->SetVariable(
1268 &gDriverSampleFormSetGuid
,
1269 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1270 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1271 &PrivateData
->Configuration
1274 if (QuestionId
== 0x5678) {
1276 // Update uncommitted data of Browser
1278 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1279 ASSERT (EfiData
!= NULL
);
1280 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*) EfiData
)) {
1281 EfiData
->Field8
= 111;
1283 &gDriverSampleFormSetGuid
,
1285 sizeof (MY_EFI_VARSTORE_DATA
),
1297 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1299 switch (QuestionId
) {
1301 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1305 for (Index
= 0; Index
< 3; Index
++) {
1306 SetArrayData (Value
, EFI_IFR_TYPE_NUM_SIZE_8
, Index
, BufferValue
--);
1315 Status
= EFI_UNSUPPORTED
;
1321 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1323 switch (QuestionId
) {
1325 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1333 Status
= EFI_UNSUPPORTED
;
1339 case EFI_BROWSER_ACTION_CHANGING
:
1341 switch (QuestionId
) {
1344 if (Type
!= EFI_IFR_TYPE_REF
) {
1345 return EFI_INVALID_PARAMETER
;
1348 Value
->ref
.FormId
= 0x1234;
1353 // Initialize the container for dynamic opcodes
1355 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1356 ASSERT (StartOpCodeHandle
!= NULL
);
1358 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1359 ASSERT (EndOpCodeHandle
!= NULL
);
1362 // Create Hii Extend Label OpCode as the start opcode
1364 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1365 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1366 StartLabel
->Number
= LABEL_UPDATE1
;
1369 // Create Hii Extend Label OpCode as the end opcode
1371 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1372 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1373 EndLabel
->Number
= LABEL_END
;
1375 HiiCreateActionOpCode (
1376 StartOpCodeHandle
, // Container for dynamic created opcodes
1377 0x1237, // Question ID
1378 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1379 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1380 EFI_IFR_FLAG_CALLBACK
, // Question flag
1381 0 // Action String ID
1385 // Create Option OpCode
1387 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1388 ASSERT (OptionsOpCodeHandle
!= NULL
);
1390 HiiCreateOneOfOptionOpCode (
1391 OptionsOpCodeHandle
,
1392 STRING_TOKEN (STR_BOOT_OPTION1
),
1394 EFI_IFR_NUMERIC_SIZE_1
,
1398 HiiCreateOneOfOptionOpCode (
1399 OptionsOpCodeHandle
,
1400 STRING_TOKEN (STR_BOOT_OPTION2
),
1402 EFI_IFR_NUMERIC_SIZE_1
,
1407 // Prepare initial value for the dynamic created oneof Question
1409 PrivateData
->Configuration
.DynamicOneof
= 2;
1410 Status
= gRT
->SetVariable(
1412 &gDriverSampleFormSetGuid
,
1413 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1414 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1415 &PrivateData
->Configuration
1419 // Set initial vlaue of dynamic created oneof Question in Form Browser
1421 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1422 ASSERT (Configuration
!= NULL
);
1423 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1424 Configuration
->DynamicOneof
= 2;
1427 // Update uncommitted data of Browser
1430 &gDriverSampleFormSetGuid
,
1432 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1433 (UINT8
*) Configuration
,
1437 FreePool (Configuration
);
1439 HiiCreateOneOfOpCode (
1440 StartOpCodeHandle
, // Container for dynamic created opcodes
1441 0x8001, // Question ID (or call it "key")
1442 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1443 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1444 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1445 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1446 EFI_IFR_FLAG_CALLBACK
, // Question flag
1447 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1448 OptionsOpCodeHandle
, // Option Opcode list
1449 NULL
// Default Opcode is NULl
1452 HiiCreateOrderedListOpCode (
1453 StartOpCodeHandle
, // Container for dynamic created opcodes
1454 0x8002, // Question ID
1455 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1456 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1457 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1458 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1459 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1460 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1461 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1462 5, // Maximum container
1463 OptionsOpCodeHandle
, // Option Opcode list
1464 NULL
// Default Opcode is NULl
1467 HiiCreateTextOpCode (
1469 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1470 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1471 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1474 HiiCreateDateOpCode (
1479 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1480 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1482 QF_DATE_STORAGE_TIME
,
1486 HiiCreateTimeOpCode (
1491 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1492 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1494 QF_TIME_STORAGE_TIME
,
1498 HiiCreateGotoOpCode (
1499 StartOpCodeHandle
, // Container for dynamic created opcodes
1500 1, // Target Form ID
1501 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1502 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1504 0x8003 // Question ID
1508 PrivateData
->HiiHandle
[0], // HII handle
1509 &gDriverSampleFormSetGuid
, // Formset GUID
1511 StartOpCodeHandle
, // Label for where to insert opcodes
1512 EndOpCodeHandle
// Replace data
1515 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1516 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1517 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1526 case EFI_BROWSER_ACTION_CHANGED
:
1527 switch (QuestionId
) {
1530 // User press "Exit now", request Browser to exit
1532 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1537 // User press "Save now", request Browser to save the uncommitted data.
1539 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1545 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1547 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1552 // User press "Discard current form now", request Browser to discard the uncommitted data.
1554 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1559 // User press "Submit current form now", request Browser to save the uncommitted data.
1561 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1567 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1569 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1574 // 1. Check to see whether system support keyword.
1576 Status
= PrivateData
->HiiKeywordHandler
->GetData (PrivateData
->HiiKeywordHandler
,
1577 L
"NAMESPACE=x-UEFI-ns",
1578 L
"KEYWORD=iSCSIBootEnable",
1583 if (EFI_ERROR (Status
)) {
1586 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1589 L
"This system not support this keyword!",
1590 L
"Press ENTER to continue ...",
1594 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1596 Status
= EFI_SUCCESS
;
1601 // 2. If system support this keyword, just try to change value.
1605 // Change value from '0' to '1' or from '1' to '0'
1607 TmpStr
= StrStr (Results
, L
"&VALUE=");
1608 ASSERT (TmpStr
!= NULL
);
1609 TmpStr
+= StrLen (L
"&VALUE=");
1611 if (*TmpStr
== L
'0') {
1618 // 3. Call the keyword handler protocol to change the value.
1620 Status
= PrivateData
->HiiKeywordHandler
->SetData (PrivateData
->HiiKeywordHandler
,
1625 if (EFI_ERROR (Status
)) {
1628 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1631 L
"Set keyword to the system failed!",
1632 L
"Press ENTER to continue ...",
1636 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1638 Status
= EFI_SUCCESS
;
1644 Status
= mPrivateData
->HiiPopup
->CreatePopup (
1645 mPrivateData
->HiiPopup
,
1646 EfiHiiPopupStyleInfo
,
1647 EfiHiiPopupTypeYesNo
,
1648 mPrivateData
->HiiHandle
[0],
1649 STRING_TOKEN (STR_POPUP_STRING
),
1652 if (!EFI_ERROR (Status
)) {
1653 if (UserSelection
== EfiHiiPopupSelectionYes
) {
1654 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1664 case EFI_BROWSER_ACTION_SUBMITTED
:
1666 if (QuestionId
== 0x1250) {
1668 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:
1669 // Show up a pop-up to show SUBMITTED callback has been triggered.
1673 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1676 L
"EfiVarstore value has been submitted!",
1677 L
"Press ESC or ENTER to continue ...",
1681 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1687 Status
= EFI_UNSUPPORTED
;
1695 Main entry for this driver.
1697 @param ImageHandle Image handle this driver.
1698 @param SystemTable Pointer to SystemTable.
1700 @retval EFI_SUCESS This function always complete successfully.
1706 IN EFI_HANDLE ImageHandle
,
1707 IN EFI_SYSTEM_TABLE
*SystemTable
1711 EFI_HII_HANDLE HiiHandle
[2];
1712 EFI_SCREEN_DESCRIPTOR Screen
;
1713 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1714 EFI_HII_STRING_PROTOCOL
*HiiString
;
1715 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1716 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1717 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL
*HiiKeywordHandler
;
1718 EFI_HII_POPUP_PROTOCOL
*PopupHandler
;
1721 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1723 EFI_STRING ConfigRequestHdr
;
1724 EFI_STRING NameRequestHdr
;
1725 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1726 MY_EFI_BITS_VARSTORE_DATA
*BitsVarStoreConfig
;
1727 MY_EFI_UNION_DATA
*UnionConfig
;
1728 EFI_INPUT_KEY HotKey
;
1729 EDKII_FORM_BROWSER_EXTENSION_PROTOCOL
*FormBrowserEx
;
1732 // Initialize the local variables.
1734 ConfigRequestHdr
= NULL
;
1738 // Initialize screen dimensions for SendForm().
1739 // Remove 3 characters from top and bottom
1741 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1742 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1745 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1748 // Initialize driver private data
1750 mPrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1751 if (mPrivateData
== NULL
) {
1752 return EFI_OUT_OF_RESOURCES
;
1755 mPrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1757 mPrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1758 mPrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1759 mPrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1762 // Locate Hii Database protocol
1764 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1765 if (EFI_ERROR (Status
)) {
1768 mPrivateData
->HiiDatabase
= HiiDatabase
;
1771 // Locate HiiString protocol
1773 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1774 if (EFI_ERROR (Status
)) {
1777 mPrivateData
->HiiString
= HiiString
;
1780 // Locate Formbrowser2 protocol
1782 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1783 if (EFI_ERROR (Status
)) {
1786 mPrivateData
->FormBrowser2
= FormBrowser2
;
1789 // Locate ConfigRouting protocol
1791 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1792 if (EFI_ERROR (Status
)) {
1795 mPrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1798 // Locate keyword handler protocol
1800 Status
= gBS
->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid
, NULL
, (VOID
**) &HiiKeywordHandler
);
1801 if (EFI_ERROR (Status
)) {
1804 mPrivateData
->HiiKeywordHandler
= HiiKeywordHandler
;
1807 // Locate HiiPopup protocol
1809 Status
= gBS
->LocateProtocol (&gEfiHiiPopupProtocolGuid
, NULL
, (VOID
**) &PopupHandler
);
1810 if (EFI_ERROR (Status
)) {
1813 mPrivateData
->HiiPopup
= PopupHandler
;
1815 Status
= gBS
->InstallMultipleProtocolInterfaces (
1817 &gEfiDevicePathProtocolGuid
,
1818 &mHiiVendorDevicePath0
,
1819 &gEfiHiiConfigAccessProtocolGuid
,
1820 &mPrivateData
->ConfigAccess
,
1823 ASSERT_EFI_ERROR (Status
);
1825 mPrivateData
->DriverHandle
[0] = DriverHandle
[0];
1828 // Publish our HII data
1830 HiiHandle
[0] = HiiAddPackages (
1831 &gDriverSampleFormSetGuid
,
1833 DriverSampleStrings
,
1837 if (HiiHandle
[0] == NULL
) {
1838 return EFI_OUT_OF_RESOURCES
;
1841 mPrivateData
->HiiHandle
[0] = HiiHandle
[0];
1844 // Publish another Fromset
1846 Status
= gBS
->InstallMultipleProtocolInterfaces (
1848 &gEfiDevicePathProtocolGuid
,
1849 &mHiiVendorDevicePath1
,
1850 &gEfiHiiConfigAccessProtocolGuid
,
1851 &mPrivateData
->ConfigAccess
,
1854 ASSERT_EFI_ERROR (Status
);
1856 mPrivateData
->DriverHandle
[1] = DriverHandle
[1];
1858 HiiHandle
[1] = HiiAddPackages (
1859 &gDriverSampleInventoryGuid
,
1861 DriverSampleStrings
,
1865 if (HiiHandle
[1] == NULL
) {
1866 DriverSampleUnload (ImageHandle
);
1867 return EFI_OUT_OF_RESOURCES
;
1870 mPrivateData
->HiiHandle
[1] = HiiHandle
[1];
1873 // Update the device path string.
1875 NewString
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)&mHiiVendorDevicePath0
, FALSE
, FALSE
);
1876 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_DEVICE_PATH
), NewString
, NULL
) == 0) {
1877 DriverSampleUnload (ImageHandle
);
1878 return EFI_OUT_OF_RESOURCES
;
1880 if (NewString
!= NULL
) {
1881 FreePool (NewString
);
1885 // Very simple example of how one would update a string that is already
1886 // in the HII database
1888 NewString
= L
"700 Mhz";
1890 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1891 DriverSampleUnload (ImageHandle
);
1892 return EFI_OUT_OF_RESOURCES
;
1895 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1898 // Initialize Name/Value name String ID
1900 mPrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1901 mPrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1902 mPrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1905 // Initialize configuration data
1907 Configuration
= &mPrivateData
->Configuration
;
1908 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1911 // Try to read NV config EFI variable first
1913 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, DriverHandle
[0]);
1914 ASSERT (ConfigRequestHdr
!= NULL
);
1916 NameRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, NULL
, DriverHandle
[0]);
1917 ASSERT (NameRequestHdr
!= NULL
);
1919 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1920 Status
= gRT
->GetVariable (VariableName
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1921 if (EFI_ERROR (Status
)) {
1923 // Store zero data Buffer Storage to EFI variable
1925 Status
= gRT
->SetVariable(
1927 &gDriverSampleFormSetGuid
,
1928 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1929 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1932 if (EFI_ERROR (Status
)) {
1933 DriverSampleUnload (ImageHandle
);
1937 // EFI variable for NV config doesn't exit, we should build this variable
1938 // based on default values stored in IFR
1940 ActionFlag
= HiiSetToDefaults (NameRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1942 DriverSampleUnload (ImageHandle
);
1943 return EFI_INVALID_PARAMETER
;
1946 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1948 DriverSampleUnload (ImageHandle
);
1949 return EFI_INVALID_PARAMETER
;
1953 // EFI variable does exist and Validate Current Setting
1955 ActionFlag
= HiiValidateSettings (NameRequestHdr
);
1957 DriverSampleUnload (ImageHandle
);
1958 return EFI_INVALID_PARAMETER
;
1961 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1963 DriverSampleUnload (ImageHandle
);
1964 return EFI_INVALID_PARAMETER
;
1967 FreePool (ConfigRequestHdr
);
1970 // Initialize efi varstore configuration data
1972 VarStoreConfig
= &mPrivateData
->VarStoreConfig
;
1973 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
1975 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
1976 ASSERT (ConfigRequestHdr
!= NULL
);
1978 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
1979 Status
= gRT
->GetVariable (MyEfiVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
1980 if (EFI_ERROR (Status
)) {
1982 // Store zero data to EFI variable Storage.
1984 Status
= gRT
->SetVariable(
1986 &gDriverSampleFormSetGuid
,
1987 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1988 sizeof (MY_EFI_VARSTORE_DATA
),
1991 if (EFI_ERROR (Status
)) {
1992 DriverSampleUnload (ImageHandle
);
1996 // EFI variable for NV config doesn't exit, we should build this variable
1997 // based on default values stored in IFR
1999 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2001 DriverSampleUnload (ImageHandle
);
2002 return EFI_INVALID_PARAMETER
;
2006 // EFI variable does exist and Validate Current Setting
2008 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2010 DriverSampleUnload (ImageHandle
);
2011 return EFI_INVALID_PARAMETER
;
2014 FreePool (ConfigRequestHdr
);
2017 // Initialize Bits efi varstore configuration data
2019 BitsVarStoreConfig
= &mPrivateData
->BitsVarStoreConfig
;
2020 ZeroMem (BitsVarStoreConfig
, sizeof (MY_EFI_BITS_VARSTORE_DATA
));
2022 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiBitVar
, DriverHandle
[0]);
2023 ASSERT (ConfigRequestHdr
!= NULL
);
2025 BufferSize
= sizeof (MY_EFI_BITS_VARSTORE_DATA
);
2026 Status
= gRT
->GetVariable (MyEfiBitVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, BitsVarStoreConfig
);
2027 if (EFI_ERROR (Status
)) {
2029 // Store zero data to EFI variable Storage.
2031 Status
= gRT
->SetVariable(
2033 &gDriverSampleFormSetGuid
,
2034 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2035 sizeof (MY_EFI_BITS_VARSTORE_DATA
),
2038 if (EFI_ERROR (Status
)) {
2039 DriverSampleUnload (ImageHandle
);
2043 // EFI variable for NV config doesn't exit, we should build this variable
2044 // based on default values stored in IFR
2046 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2048 DriverSampleUnload (ImageHandle
);
2049 return EFI_INVALID_PARAMETER
;
2053 // EFI variable does exist and Validate Current Setting
2055 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2057 DriverSampleUnload (ImageHandle
);
2058 return EFI_INVALID_PARAMETER
;
2061 FreePool (ConfigRequestHdr
);
2064 // Initialize Union efi varstore configuration data
2066 UnionConfig
= &mPrivateData
->UnionConfig
;
2067 ZeroMem (UnionConfig
, sizeof (MY_EFI_UNION_DATA
));
2069 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiUnionVar
, DriverHandle
[0]);
2070 ASSERT (ConfigRequestHdr
!= NULL
);
2072 BufferSize
= sizeof (MY_EFI_UNION_DATA
);
2073 Status
= gRT
->GetVariable (MyEfiUnionVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, UnionConfig
);
2074 if (EFI_ERROR (Status
)) {
2076 // Store zero data to EFI variable Storage.
2078 Status
= gRT
->SetVariable(
2080 &gDriverSampleFormSetGuid
,
2081 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2082 sizeof (MY_EFI_UNION_DATA
),
2085 if (EFI_ERROR (Status
)) {
2086 DriverSampleUnload (ImageHandle
);
2090 // EFI variable for NV config doesn't exit, we should build this variable
2091 // based on default values stored in IFR
2093 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2095 DriverSampleUnload (ImageHandle
);
2096 return EFI_INVALID_PARAMETER
;
2100 // EFI variable does exist and Validate Current Setting
2102 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2104 DriverSampleUnload (ImageHandle
);
2105 return EFI_INVALID_PARAMETER
;
2108 FreePool (ConfigRequestHdr
);
2110 Status
= gBS
->CreateEventEx (
2113 EfiEventEmptyFunction
,
2115 &gEfiIfrRefreshIdOpGuid
,
2118 ASSERT_EFI_ERROR (Status
);
2121 // Example of how to use BrowserEx protocol to register HotKey.
2123 Status
= gBS
->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid
, NULL
, (VOID
**) &FormBrowserEx
);
2124 if (!EFI_ERROR (Status
)) {
2126 // First unregister the default hot key F9 and F10.
2128 HotKey
.UnicodeChar
= CHAR_NULL
;
2129 HotKey
.ScanCode
= SCAN_F9
;
2130 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2131 HotKey
.ScanCode
= SCAN_F10
;
2132 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2135 // Register the default HotKey F9 and F10 again.
2137 HotKey
.ScanCode
= SCAN_F10
;
2138 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_TEN_STRING
), NULL
);
2139 ASSERT (NewString
!= NULL
);
2140 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_SUBMIT
, 0, NewString
);
2141 HotKey
.ScanCode
= SCAN_F9
;
2142 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_NINE_STRING
), NULL
);
2143 ASSERT (NewString
!= NULL
);
2144 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, NewString
);
2148 // In default, this driver is built into Flash device image,
2149 // the following code doesn't run.
2153 // Example of how to display only the item we sent to HII
2154 // When this driver is not built into Flash device image,
2155 // it need to call SendForm to show front page by itself.
2157 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2159 // Have the browser pull out our copy of the data, and only display our data
2161 Status
= FormBrowser2
->SendForm (
2163 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2171 HiiRemovePackages (HiiHandle
[0]);
2173 HiiRemovePackages (HiiHandle
[1]);
2180 Unloads the application and its installed protocol.
2182 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2184 @retval EFI_SUCCESS The image has been unloaded.
2188 DriverSampleUnload (
2189 IN EFI_HANDLE ImageHandle
2194 ASSERT (mPrivateData
!= NULL
);
2196 if (DriverHandle
[0] != NULL
) {
2197 gBS
->UninstallMultipleProtocolInterfaces (
2199 &gEfiDevicePathProtocolGuid
,
2200 &mHiiVendorDevicePath0
,
2201 &gEfiHiiConfigAccessProtocolGuid
,
2202 &mPrivateData
->ConfigAccess
,
2205 DriverHandle
[0] = NULL
;
2208 if (DriverHandle
[1] != NULL
) {
2209 gBS
->UninstallMultipleProtocolInterfaces (
2211 &gEfiDevicePathProtocolGuid
,
2212 &mHiiVendorDevicePath1
,
2213 &gEfiHiiConfigAccessProtocolGuid
,
2214 &mPrivateData
->ConfigAccess
,
2217 DriverHandle
[1] = NULL
;
2220 if (mPrivateData
->HiiHandle
[0] != NULL
) {
2221 HiiRemovePackages (mPrivateData
->HiiHandle
[0]);
2224 if (mPrivateData
->HiiHandle
[1] != NULL
) {
2225 HiiRemovePackages (mPrivateData
->HiiHandle
[1]);
2228 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2229 if (mPrivateData
->NameValueName
[Index
] != NULL
) {
2230 FreePool (mPrivateData
->NameValueName
[Index
]);
2233 FreePool (mPrivateData
);
2234 mPrivateData
= NULL
;
2236 gBS
->CloseEvent (mEvent
);