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
10 #include "DriverSample.h"
12 #define DISPLAY_ONLY_MY_ITEM 0x0002
14 CHAR16 VariableName
[] = L
"MyIfrNVData";
15 CHAR16 MyEfiVar
[] = L
"MyEfiVar";
16 CHAR16 MyEfiBitVar
[] = L
"MyEfiBitVar";
17 CHAR16 MyEfiUnionVar
[] = L
"MyEfiUnionVar";
19 EFI_HANDLE DriverHandle
[2] = { NULL
, NULL
};
20 DRIVER_SAMPLE_PRIVATE_DATA
*mPrivateData
= NULL
;
23 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
29 (UINT8
)(sizeof (VENDOR_DEVICE_PATH
)),
30 (UINT8
)((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
33 DRIVER_SAMPLE_FORMSET_GUID
37 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
39 (UINT8
)(END_DEVICE_PATH_LENGTH
),
40 (UINT8
)((END_DEVICE_PATH_LENGTH
) >> 8)
45 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
51 (UINT8
)(sizeof (VENDOR_DEVICE_PATH
)),
52 (UINT8
)((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
55 DRIVER_SAMPLE_INVENTORY_GUID
59 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
61 (UINT8
)(END_DEVICE_PATH_LENGTH
),
62 (UINT8
)((END_DEVICE_PATH_LENGTH
) >> 8)
68 Set value of a data element in an Array by its Index.
70 @param Array The data array.
71 @param Type Type of the data in this array.
72 @param Index Zero based index for data in this array.
73 @param Value The value to be set.
84 ASSERT (Array
!= NULL
);
87 case EFI_IFR_TYPE_NUM_SIZE_8
:
88 *(((UINT8
*)Array
) + Index
) = (UINT8
)Value
;
91 case EFI_IFR_TYPE_NUM_SIZE_16
:
92 *(((UINT16
*)Array
) + Index
) = (UINT16
)Value
;
95 case EFI_IFR_TYPE_NUM_SIZE_32
:
96 *(((UINT32
*)Array
) + Index
) = (UINT32
)Value
;
99 case EFI_IFR_TYPE_NUM_SIZE_64
:
100 *(((UINT64
*)Array
) + Index
) = (UINT64
)Value
;
109 Notification function for keystrokes.
111 @param[in] KeyData The key that was pressed.
113 @retval EFI_SUCCESS The operation was successful.
117 NotificationFunction (
118 IN EFI_KEY_DATA
*KeyData
121 gBS
->SignalEvent (mEvent
);
127 Function to start monitoring for CTRL-C using SimpleTextInputEx.
129 @retval EFI_SUCCESS The feature is enabled.
130 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
134 InternalStartMonitor (
138 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
139 EFI_KEY_DATA KeyData
;
146 Status
= gBS
->LocateHandleBuffer (
148 &gEfiSimpleTextInputExProtocolGuid
,
153 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
154 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**)&SimpleEx
);
155 ASSERT_EFI_ERROR (Status
);
157 KeyData
.KeyState
.KeyToggleState
= 0;
158 KeyData
.Key
.ScanCode
= 0;
159 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
160 KeyData
.Key
.UnicodeChar
= L
'c';
162 Status
= SimpleEx
->RegisterKeyNotify (
165 NotificationFunction
,
168 if (EFI_ERROR (Status
)) {
172 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
173 Status
= SimpleEx
->RegisterKeyNotify (
176 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.
195 InternalStopMonitor (
199 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
202 EFI_KEY_DATA KeyData
;
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
,
229 if (!EFI_ERROR (Status
)) {
230 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
233 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
234 Status
= SimpleEx
->RegisterKeyNotify (
237 NotificationFunction
,
240 if (!EFI_ERROR (Status
)) {
241 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
249 Update names of Name/Value storage to current language.
251 @param PrivateData Points to the driver private data.
253 @retval EFI_SUCCESS All names are successfully updated.
254 @retval EFI_NOT_FOUND Failed to get Name from HII database.
259 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
265 // Get Name/Value name string of current language
267 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
268 PrivateData
->NameValueName
[Index
] = HiiGetString (
269 PrivateData
->HiiHandle
[0],
270 PrivateData
->NameStringId
[Index
],
273 if (PrivateData
->NameValueName
[Index
] == NULL
) {
274 return EFI_NOT_FOUND
;
282 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
284 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
286 This is a internal function.
288 @param StringPtr String in <BlockConfig> format and points to the
289 first character of <Number>.
290 @param Number The output value. Caller takes the responsibility
292 @param Len Length of the <Number>, in characters.
294 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
296 @retval EFI_SUCCESS Value of <Number> is outputted in Number
302 IN EFI_STRING StringPtr
,
316 if ((StringPtr
== NULL
) || (*StringPtr
== L
'\0') || (Number
== NULL
) || (Len
== NULL
)) {
317 return EFI_INVALID_PARAMETER
;
323 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
327 *Len
= StringPtr
- TmpPtr
;
330 Str
= (EFI_STRING
)AllocateZeroPool (Length
* sizeof (CHAR16
));
332 Status
= EFI_OUT_OF_RESOURCES
;
336 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
337 *(Str
+ *Len
) = L
'\0';
339 Length
= (Length
+ 1) / 2;
340 Buf
= (UINT8
*)AllocateZeroPool (Length
);
342 Status
= EFI_OUT_OF_RESOURCES
;
347 ZeroMem (TemStr
, sizeof (TemStr
));
348 for (Index
= 0; Index
< Length
; Index
++) {
349 TemStr
[0] = Str
[Length
- Index
- 1];
350 DigitUint8
= (UINT8
)StrHexToUint64 (TemStr
);
351 if ((Index
& 1) == 0) {
352 Buf
[Index
/2] = DigitUint8
;
354 Buf
[Index
/2] = (UINT8
)((DigitUint8
<< 4) + Buf
[Index
/2]);
359 Status
= EFI_SUCCESS
;
370 Create altcfg string.
372 @param Result The request result string.
373 @param ConfigHdr The request head info. <ConfigHdr> format.
374 @param Offset The offset of the parameter int he structure.
375 @param Width The width of the parameter.
378 @retval The string with altcfg info append at the end.
382 IN EFI_STRING Result
,
383 IN EFI_STRING ConfigHdr
,
388 EFI_STRING StringPtr
;
392 NewLen
= StrLen (Result
);
394 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
396 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
397 StringPtr
= AllocateZeroPool (NewLen
);
398 if (StringPtr
== NULL
) {
403 if (Result
!= NULL
) {
404 StrCpyS (StringPtr
, NewLen
/ sizeof (CHAR16
), Result
);
405 StringPtr
+= StrLen (Result
);
411 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
414 EFI_HII_DEFAULT_CLASS_STANDARD
416 StringPtr
+= StrLen (StringPtr
);
420 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
421 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
424 DEFAULT_CLASS_STANDARD_VALUE
426 StringPtr
+= StrLen (StringPtr
);
430 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
433 EFI_HII_DEFAULT_CLASS_MANUFACTURING
435 StringPtr
+= StrLen (StringPtr
);
439 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
440 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
443 DEFAULT_CLASS_MANUFACTURING_VALUE
445 StringPtr
+= StrLen (StringPtr
);
451 Check whether need to add the altcfg string. if need to add, add the altcfg
454 @param RequestResult The request result string.
455 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
460 IN OUT EFI_STRING
*RequestResult
,
461 IN EFI_STRING ConfigRequestHdr
464 EFI_STRING StringPtr
;
475 StringPtr
= *RequestResult
;
476 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
477 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
478 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
479 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
481 if (StringPtr
== NULL
) {
485 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
486 StringPtr
+= StrLen (L
"OFFSET=");
490 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
491 if (EFI_ERROR (Status
)) {
499 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
501 FreePool (TmpBuffer
);
504 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
508 StringPtr
+= StrLen (L
"&WIDTH=");
513 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
514 if (EFI_ERROR (Status
)) {
522 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
524 FreePool (TmpBuffer
);
527 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
531 StringPtr
+= StrLen (L
"&VALUE=");
536 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
537 if (EFI_ERROR (Status
)) {
544 // Skip the character "&" before "OFFSET".
549 // Calculate Value and convert it to hex string.
551 if (Offset
+ Width
> BlockSize
) {
555 if ((Offset
<= ValueOffset
) && (Offset
+ Width
>= ValueOffset
+ ValueWidth
)) {
556 *RequestResult
= CreateAltCfgString (*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
563 This function allows a caller to extract the current configuration for one
564 or more named elements from the target driver.
566 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
567 @param Request A null-terminated Unicode string in
568 <ConfigRequest> format.
569 @param Progress On return, points to a character in the Request
570 string. Points to the string's null terminator if
571 request was successful. Points to the most recent
572 '&' before the first failing name/value pair (or
573 the beginning of the string if the failure is in
574 the first name/value pair) if the request was not
576 @param Results A null-terminated Unicode string in
577 <ConfigAltResp> format which has all values filled
578 in for the names in the Request string. String to
579 be allocated by the called function.
581 @retval EFI_SUCCESS The Results is filled with the requested values.
582 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
583 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
584 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
591 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
592 IN CONST EFI_STRING Request
,
593 OUT EFI_STRING
*Progress
,
594 OUT EFI_STRING
*Results
599 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
600 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
601 EFI_STRING ConfigRequest
;
602 EFI_STRING ConfigRequestHdr
;
608 BOOLEAN AllocatedRequest
;
610 if ((Progress
== NULL
) || (Results
== NULL
)) {
611 return EFI_INVALID_PARAMETER
;
615 // Initialize the local variables.
617 ConfigRequestHdr
= NULL
;
618 ConfigRequest
= NULL
;
621 AllocatedRequest
= FALSE
;
623 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
624 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
627 // Get Buffer Storage data from EFI variable.
628 // Try to get the current setting from variable.
630 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
631 Status
= gRT
->GetVariable (
633 &gDriverSampleFormSetGuid
,
636 &PrivateData
->Configuration
638 if (EFI_ERROR (Status
)) {
639 return EFI_NOT_FOUND
;
642 if (Request
== NULL
) {
644 // Request is set to NULL, construct full request string.
648 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
649 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
651 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
652 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
653 ConfigRequest
= AllocateZeroPool (Size
);
654 ASSERT (ConfigRequest
!= NULL
);
655 AllocatedRequest
= TRUE
;
656 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
657 FreePool (ConfigRequestHdr
);
658 ConfigRequestHdr
= NULL
;
661 // Check routing data in <ConfigHdr>.
662 // Note: if only one Storage is used, then this checking could be skipped.
664 if (!HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, NULL
)) {
665 return EFI_NOT_FOUND
;
669 // Check whether request for EFI Varstore. EFI varstore get data
670 // through hii database, not support in this path.
672 if (HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
673 return EFI_UNSUPPORTED
;
676 if (HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
677 return EFI_UNSUPPORTED
;
680 if (HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
681 return EFI_UNSUPPORTED
;
685 // Set Request to the unified request string.
687 ConfigRequest
= Request
;
689 // Check whether Request includes Request Element.
691 if (StrStr (Request
, L
"OFFSET") == NULL
) {
693 // Check Request Element does exist in Reques String
695 StrPointer
= StrStr (Request
, L
"PATH");
696 if (StrPointer
== NULL
) {
697 return EFI_INVALID_PARAMETER
;
700 if (StrStr (StrPointer
, L
"&") == NULL
) {
701 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
702 ConfigRequest
= AllocateZeroPool (Size
);
703 ASSERT (ConfigRequest
!= NULL
);
704 AllocatedRequest
= TRUE
;
705 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
711 // Check if requesting Name/Value storage
713 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
715 // Update Name/Value storage Names
717 Status
= LoadNameValueNames (PrivateData
);
718 if (EFI_ERROR (Status
)) {
723 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
724 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
725 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
727 BufferSize
= (StrLen (ConfigRequest
) +
728 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
729 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
730 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
731 *Results
= AllocateZeroPool (BufferSize
);
732 ASSERT (*Results
!= NULL
);
733 StrCpyS (*Results
, BufferSize
/ sizeof (CHAR16
), ConfigRequest
);
737 // Append value of NameValueVar0, type is UINT8
739 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
740 Value
+= StrLen (PrivateData
->NameValueName
[0]);
741 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
742 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
744 BackupChar
= Value
[ValueStrLen
];
746 UnicodeValueToStringS (
748 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
749 PREFIX_ZERO
| RADIX_HEX
,
750 PrivateData
->Configuration
.NameValueVar0
,
751 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
753 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
758 // Append value of NameValueVar1, type is UINT16
760 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
761 Value
+= StrLen (PrivateData
->NameValueName
[1]);
762 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
763 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
765 BackupChar
= Value
[ValueStrLen
];
767 UnicodeValueToStringS (
769 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
770 PREFIX_ZERO
| RADIX_HEX
,
771 PrivateData
->Configuration
.NameValueVar1
,
772 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
774 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
779 // Append value of NameValueVar2, type is CHAR16 *
781 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
782 Value
+= StrLen (PrivateData
->NameValueName
[2]);
783 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
784 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
788 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
790 StrPointer
= (CHAR16
*)PrivateData
->Configuration
.NameValueVar2
;
791 for ( ; *StrPointer
!= L
'\0'; StrPointer
++) {
792 UnicodeValueToStringS (
794 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
795 PREFIX_ZERO
| RADIX_HEX
,
799 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
803 Status
= EFI_SUCCESS
;
806 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
808 Status
= HiiConfigRouting
->BlockToConfig (
811 (UINT8
*)&PrivateData
->Configuration
,
816 if (!EFI_ERROR (Status
)) {
817 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
818 AppendAltCfgString (Results
, ConfigRequestHdr
);
823 // Free the allocated config request string.
825 if (AllocatedRequest
) {
826 FreePool (ConfigRequest
);
829 if (ConfigRequestHdr
!= NULL
) {
830 FreePool (ConfigRequestHdr
);
834 // Set Progress string to the original request string.
836 if (Request
== NULL
) {
838 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
839 *Progress
= Request
+ StrLen (Request
);
846 This function processes the results of changes in configuration.
848 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
849 @param Configuration A null-terminated Unicode string in <ConfigResp>
851 @param Progress A pointer to a string filled in with the offset of
852 the most recent '&' before the first failing
853 name/value pair (or the beginning of the string if
854 the failure is in the first name/value pair) or
855 the terminating NULL if all was successful.
857 @retval EFI_SUCCESS The Results is processed successfully.
858 @retval EFI_INVALID_PARAMETER Configuration is NULL.
859 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
866 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
867 IN CONST EFI_STRING Configuration
,
868 OUT EFI_STRING
*Progress
873 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
874 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
883 if ((Configuration
== NULL
) || (Progress
== NULL
)) {
884 return EFI_INVALID_PARAMETER
;
887 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
888 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
889 *Progress
= Configuration
;
892 // Check routing data in <ConfigHdr>.
893 // Note: if only one Storage is used, then this checking could be skipped.
895 if (!HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, NULL
)) {
896 return EFI_NOT_FOUND
;
900 // Check whether request for EFI Varstore. EFI varstore get data
901 // through hii database, not support in this path.
903 if (HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
904 return EFI_UNSUPPORTED
;
907 if (HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
908 return EFI_UNSUPPORTED
;
911 if (HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
912 return EFI_UNSUPPORTED
;
916 // Get Buffer Storage data from EFI variable
918 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
919 Status
= gRT
->GetVariable (
921 &gDriverSampleFormSetGuid
,
924 &PrivateData
->Configuration
926 if (EFI_ERROR (Status
)) {
931 // Check if configuring Name/Value storage
933 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
935 // Update Name/Value storage Names
937 Status
= LoadNameValueNames (PrivateData
);
938 if (EFI_ERROR (Status
)) {
943 // Convert value for NameValueVar0
945 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
949 Value
+= StrLen (PrivateData
->NameValueName
[0]);
954 StrPtr
= StrStr (Value
, L
"&");
955 if (StrPtr
== NULL
) {
956 StrPtr
= Value
+ StrLen (Value
);
960 // Convert Value to Buffer data
962 DataBuffer
= (UINT8
*)&PrivateData
->Configuration
.NameValueVar0
;
963 ZeroMem (TemStr
, sizeof (TemStr
));
964 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
966 DigitUint8
= (UINT8
)StrHexToUint64 (TemStr
);
967 if ((Index
& 1) == 0) {
968 DataBuffer
[Index
/2] = DigitUint8
;
970 DataBuffer
[Index
/2] = (UINT8
)((UINT8
)(DigitUint8
<< 4) + DataBuffer
[Index
/2]);
976 // Convert value for NameValueVar1
978 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
982 Value
+= StrLen (PrivateData
->NameValueName
[1]);
987 StrPtr
= StrStr (Value
, L
"&");
988 if (StrPtr
== NULL
) {
989 StrPtr
= Value
+ StrLen (Value
);
993 // Convert Value to Buffer data
995 DataBuffer
= (UINT8
*)&PrivateData
->Configuration
.NameValueVar1
;
996 ZeroMem (TemStr
, sizeof (TemStr
));
997 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
999 DigitUint8
= (UINT8
)StrHexToUint64 (TemStr
);
1000 if ((Index
& 1) == 0) {
1001 DataBuffer
[Index
/2] = DigitUint8
;
1003 DataBuffer
[Index
/2] = (UINT8
)((UINT8
)(DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1009 // Convert value for NameValueVar2
1011 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1015 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1020 StrPtr
= StrStr (Value
, L
"&");
1021 if (StrPtr
== NULL
) {
1022 StrPtr
= Value
+ StrLen (Value
);
1026 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1028 StrBuffer
= (CHAR16
*)PrivateData
->Configuration
.NameValueVar2
;
1029 ZeroMem (TemStr
, sizeof (TemStr
));
1030 while (Value
< StrPtr
) {
1031 StrnCpyS (TemStr
, sizeof (TemStr
) / sizeof (CHAR16
), Value
, 4);
1032 *(StrBuffer
++) = (CHAR16
)StrHexToUint64 (TemStr
);
1040 // Store Buffer Storage back to EFI variable
1042 Status
= gRT
->SetVariable (
1044 &gDriverSampleFormSetGuid
,
1045 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1046 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1047 &PrivateData
->Configuration
1054 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1056 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1057 Status
= HiiConfigRouting
->ConfigToBlock (
1060 (UINT8
*)&PrivateData
->Configuration
,
1064 if (EFI_ERROR (Status
)) {
1069 // Store Buffer Storage back to EFI variable
1071 Status
= gRT
->SetVariable (
1073 &gDriverSampleFormSetGuid
,
1074 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1075 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1076 &PrivateData
->Configuration
1083 This function processes the results of changes in configuration.
1085 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1086 @param Action Specifies the type of action taken by the browser.
1087 @param QuestionId A unique value which is sent to the original
1088 exporting driver so that it can identify the type
1090 @param Type The type of value for the question.
1091 @param Value A pointer to the data being sent to the original
1093 @param ActionRequest On return, points to the action requested by the
1096 @retval EFI_SUCCESS The callback successfully handled the action.
1097 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1098 variable and its data.
1099 @retval EFI_DEVICE_ERROR The variable could not be saved.
1100 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1107 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1108 IN EFI_BROWSER_ACTION Action
,
1109 IN EFI_QUESTION_ID QuestionId
,
1111 IN EFI_IFR_TYPE_VALUE
*Value
,
1112 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1115 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1117 VOID
*StartOpCodeHandle
;
1118 VOID
*OptionsOpCodeHandle
;
1119 EFI_IFR_GUID_LABEL
*StartLabel
;
1120 VOID
*EndOpCodeHandle
;
1121 EFI_IFR_GUID_LABEL
*EndLabel
;
1123 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1124 MY_EFI_VARSTORE_DATA
*EfiData
;
1126 EFI_STRING Progress
;
1132 EFI_HII_POPUP_SELECTION UserSelection
;
1134 UserSelection
= 0xFF;
1136 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
)) ||
1137 (ActionRequest
== NULL
))
1139 return EFI_INVALID_PARAMETER
;
1144 Status
= EFI_SUCCESS
;
1146 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1149 case EFI_BROWSER_ACTION_FORM_OPEN
:
1151 if (QuestionId
== 0x1234) {
1153 // Sample CallBack for UEFI FORM_OPEN action:
1154 // Add Save action into Form 3 when Form 1 is opened.
1155 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1157 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1160 // Initialize the container for dynamic opcodes
1162 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1163 ASSERT (StartOpCodeHandle
!= NULL
);
1166 // Create Hii Extend Label OpCode as the start opcode
1168 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1169 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1170 StartLabel
->Number
= LABEL_UPDATE2
;
1172 HiiCreateActionOpCode (
1173 StartOpCodeHandle
, // Container for dynamic created opcodes
1174 0x1238, // Question ID
1175 STRING_TOKEN (STR_SAVE_TEXT
), // Prompt text
1176 STRING_TOKEN (STR_SAVE_TEXT
), // Help text
1177 EFI_IFR_FLAG_CALLBACK
, // Question flag
1178 0 // Action String ID
1182 PrivateData
->HiiHandle
[0], // HII handle
1183 &gDriverSampleFormSetGuid
, // Formset GUID
1185 StartOpCodeHandle
, // Label for where to insert opcodes
1189 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1192 if (QuestionId
== 0x1247) {
1193 Status
= InternalStartMonitor ();
1194 ASSERT_EFI_ERROR (Status
);
1200 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1202 if (QuestionId
== 0x5678) {
1204 // Sample CallBack for UEFI FORM_CLOSE action:
1205 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1209 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1212 L
"You are going to leave third Form!",
1213 L
"Press ESC or ENTER to continue ...",
1217 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1220 if (QuestionId
== 0x1247) {
1221 Status
= InternalStopMonitor ();
1222 ASSERT_EFI_ERROR (Status
);
1228 case EFI_BROWSER_ACTION_RETRIEVE
:
1230 switch (QuestionId
) {
1232 if (Type
!= EFI_IFR_TYPE_REF
) {
1233 return EFI_INVALID_PARAMETER
;
1236 Value
->ref
.FormId
= 0x3;
1242 // We will reach here once the Question is refreshed
1246 // Initialize the container for dynamic opcodes
1248 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1249 ASSERT (StartOpCodeHandle
!= NULL
);
1252 // Create Hii Extend Label OpCode as the start opcode
1254 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1255 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1256 if (QuestionId
== 0x5678) {
1257 StartLabel
->Number
= LABEL_UPDATE2
;
1259 PrivateData
->Configuration
.DynamicRefresh
++;
1260 } else if (QuestionId
== 0x1247 ) {
1261 StartLabel
->Number
= LABEL_UPDATE3
;
1263 PrivateData
->Configuration
.RefreshGuidCount
++;
1266 HiiCreateActionOpCode (
1267 StartOpCodeHandle
, // Container for dynamic created opcodes
1268 0x1237, // Question ID
1269 STRING_TOKEN (STR_EXIT_TEXT
), // Prompt text
1270 STRING_TOKEN (STR_EXIT_TEXT
), // Help text
1271 EFI_IFR_FLAG_CALLBACK
, // Question flag
1272 0 // Action String ID
1276 PrivateData
->HiiHandle
[0], // HII handle
1277 &gDriverSampleFormSetGuid
, // Formset GUID
1279 StartOpCodeHandle
, // Label for where to insert opcodes
1283 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1286 // Refresh the Question value
1288 Status
= gRT
->SetVariable (
1290 &gDriverSampleFormSetGuid
,
1291 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1292 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1293 &PrivateData
->Configuration
1296 if (QuestionId
== 0x5678) {
1298 // Update uncommitted data of Browser
1300 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1301 ASSERT (EfiData
!= NULL
);
1302 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*)EfiData
)) {
1303 EfiData
->Field8
= 111;
1305 &gDriverSampleFormSetGuid
,
1307 sizeof (MY_EFI_VARSTORE_DATA
),
1322 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1324 switch (QuestionId
) {
1326 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1330 for (Index
= 0; Index
< 3; Index
++) {
1331 SetArrayData (Value
, EFI_IFR_TYPE_NUM_SIZE_8
, Index
, BufferValue
--);
1341 Status
= EFI_UNSUPPORTED
;
1348 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1350 switch (QuestionId
) {
1352 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1360 Status
= EFI_UNSUPPORTED
;
1367 case EFI_BROWSER_ACTION_CHANGING
:
1369 switch (QuestionId
) {
1372 if (Type
!= EFI_IFR_TYPE_REF
) {
1373 return EFI_INVALID_PARAMETER
;
1376 Value
->ref
.FormId
= 0x1234;
1381 // Initialize the container for dynamic opcodes
1383 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1384 ASSERT (StartOpCodeHandle
!= NULL
);
1386 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1387 ASSERT (EndOpCodeHandle
!= NULL
);
1390 // Create Hii Extend Label OpCode as the start opcode
1392 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1393 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1394 StartLabel
->Number
= LABEL_UPDATE1
;
1397 // Create Hii Extend Label OpCode as the end opcode
1399 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1400 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1401 EndLabel
->Number
= LABEL_END
;
1403 HiiCreateActionOpCode (
1404 StartOpCodeHandle
, // Container for dynamic created opcodes
1405 0x1237, // Question ID
1406 STRING_TOKEN (STR_EXIT_TEXT
), // Prompt text
1407 STRING_TOKEN (STR_EXIT_TEXT
), // Help text
1408 EFI_IFR_FLAG_CALLBACK
, // Question flag
1409 0 // Action String ID
1413 // Create Option OpCode
1415 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1416 ASSERT (OptionsOpCodeHandle
!= NULL
);
1418 HiiCreateOneOfOptionOpCode (
1419 OptionsOpCodeHandle
,
1420 STRING_TOKEN (STR_BOOT_OPTION1
),
1422 EFI_IFR_NUMERIC_SIZE_1
,
1426 HiiCreateOneOfOptionOpCode (
1427 OptionsOpCodeHandle
,
1428 STRING_TOKEN (STR_BOOT_OPTION2
),
1430 EFI_IFR_NUMERIC_SIZE_1
,
1435 // Prepare initial value for the dynamic created oneof Question
1437 PrivateData
->Configuration
.DynamicOneof
= 2;
1438 Status
= gRT
->SetVariable (
1440 &gDriverSampleFormSetGuid
,
1441 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1442 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1443 &PrivateData
->Configuration
1447 // Set initial vlaue of dynamic created oneof Question in Form Browser
1449 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1450 ASSERT (Configuration
!= NULL
);
1451 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*)Configuration
)) {
1452 Configuration
->DynamicOneof
= 2;
1455 // Update uncommitted data of Browser
1458 &gDriverSampleFormSetGuid
,
1460 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1461 (UINT8
*)Configuration
,
1466 FreePool (Configuration
);
1468 HiiCreateOneOfOpCode (
1469 StartOpCodeHandle
, // Container for dynamic created opcodes
1470 0x8001, // Question ID (or call it "key")
1471 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1472 (UINT16
)DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1473 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1474 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1475 EFI_IFR_FLAG_CALLBACK
, // Question flag
1476 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1477 OptionsOpCodeHandle
, // Option Opcode list
1478 NULL
// Default Opcode is NULl
1481 HiiCreateOrderedListOpCode (
1482 StartOpCodeHandle
, // Container for dynamic created opcodes
1483 0x8002, // Question ID
1484 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1485 (UINT16
)DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1486 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1487 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1488 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1489 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1490 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1491 5, // Maximum container
1492 OptionsOpCodeHandle
, // Option Opcode list
1493 NULL
// Default Opcode is NULl
1496 HiiCreateTextOpCode (
1498 STRING_TOKEN (STR_TEXT_SAMPLE_HELP
),
1499 STRING_TOKEN (STR_TEXT_SAMPLE_HELP
),
1500 STRING_TOKEN (STR_TEXT_SAMPLE_STRING
)
1503 HiiCreateDateOpCode (
1508 STRING_TOKEN (STR_DATE_SAMPLE_HELP
),
1509 STRING_TOKEN (STR_DATE_SAMPLE_HELP
),
1511 QF_DATE_STORAGE_TIME
,
1515 HiiCreateTimeOpCode (
1520 STRING_TOKEN (STR_TIME_SAMPLE_HELP
),
1521 STRING_TOKEN (STR_TIME_SAMPLE_HELP
),
1523 QF_TIME_STORAGE_TIME
,
1527 HiiCreateGotoOpCode (
1528 StartOpCodeHandle
, // Container for dynamic created opcodes
1529 1, // Target Form ID
1530 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1531 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1533 0x8003 // Question ID
1537 PrivateData
->HiiHandle
[0], // HII handle
1538 &gDriverSampleFormSetGuid
, // Formset GUID
1540 StartOpCodeHandle
, // Label for where to insert opcodes
1541 EndOpCodeHandle
// Replace data
1544 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1545 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1546 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1556 case EFI_BROWSER_ACTION_CHANGED
:
1557 switch (QuestionId
) {
1560 // User press "Exit now", request Browser to exit
1562 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1567 // User press "Save now", request Browser to save the uncommitted data.
1569 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1575 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1577 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1582 // User press "Discard current form now", request Browser to discard the uncommitted data.
1584 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1589 // User press "Submit current form now", request Browser to save the uncommitted data.
1591 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1597 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1599 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1604 // 1. Check to see whether system support keyword.
1606 Status
= PrivateData
->HiiKeywordHandler
->GetData (
1607 PrivateData
->HiiKeywordHandler
,
1608 L
"NAMESPACE=x-UEFI-ns",
1609 L
"KEYWORD=iSCSIBootEnable",
1614 if (EFI_ERROR (Status
)) {
1617 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1620 L
"This system not support this keyword!",
1621 L
"Press ENTER to continue ...",
1625 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1627 Status
= EFI_SUCCESS
;
1632 // 2. If system support this keyword, just try to change value.
1636 // Change value from '0' to '1' or from '1' to '0'
1638 TmpStr
= StrStr (Results
, L
"&VALUE=");
1639 ASSERT (TmpStr
!= NULL
);
1640 TmpStr
+= StrLen (L
"&VALUE=");
1642 if (*TmpStr
== L
'0') {
1649 // 3. Call the keyword handler protocol to change the value.
1651 Status
= PrivateData
->HiiKeywordHandler
->SetData (
1652 PrivateData
->HiiKeywordHandler
,
1657 if (EFI_ERROR (Status
)) {
1660 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1663 L
"Set keyword to the system failed!",
1664 L
"Press ENTER to continue ...",
1668 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1670 Status
= EFI_SUCCESS
;
1677 Status
= mPrivateData
->HiiPopup
->CreatePopup (
1678 mPrivateData
->HiiPopup
,
1679 EfiHiiPopupStyleInfo
,
1680 EfiHiiPopupTypeYesNo
,
1681 mPrivateData
->HiiHandle
[0],
1682 STRING_TOKEN (STR_POPUP_STRING
),
1685 if (!EFI_ERROR (Status
)) {
1686 if (UserSelection
== EfiHiiPopupSelectionYes
) {
1687 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1699 case EFI_BROWSER_ACTION_SUBMITTED
:
1701 if (QuestionId
== 0x1250) {
1703 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:
1704 // Show up a pop-up to show SUBMITTED callback has been triggered.
1708 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1711 L
"EfiVarstore value has been submitted!",
1712 L
"Press ESC or ENTER to continue ...",
1716 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1723 Status
= EFI_UNSUPPORTED
;
1731 Main entry for this driver.
1733 @param ImageHandle Image handle this driver.
1734 @param SystemTable Pointer to SystemTable.
1736 @retval EFI_SUCESS This function always complete successfully.
1742 IN EFI_HANDLE ImageHandle
,
1743 IN EFI_SYSTEM_TABLE
*SystemTable
1747 EFI_HII_HANDLE HiiHandle
[2];
1748 EFI_SCREEN_DESCRIPTOR Screen
;
1749 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1750 EFI_HII_STRING_PROTOCOL
*HiiString
;
1751 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1752 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1753 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL
*HiiKeywordHandler
;
1754 EFI_HII_POPUP_PROTOCOL
*PopupHandler
;
1757 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1759 EFI_STRING ConfigRequestHdr
;
1760 EFI_STRING NameRequestHdr
;
1761 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1762 MY_EFI_BITS_VARSTORE_DATA
*BitsVarStoreConfig
;
1763 MY_EFI_UNION_DATA
*UnionConfig
;
1764 EFI_INPUT_KEY HotKey
;
1765 EDKII_FORM_BROWSER_EXTENSION_PROTOCOL
*FormBrowserEx
;
1768 // Initialize the local variables.
1770 ConfigRequestHdr
= NULL
;
1774 // Initialize screen dimensions for SendForm().
1775 // Remove 3 characters from top and bottom
1777 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1778 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1781 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1784 // Initialize driver private data
1786 mPrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1787 if (mPrivateData
== NULL
) {
1788 return EFI_OUT_OF_RESOURCES
;
1791 mPrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1793 mPrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1794 mPrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1795 mPrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1798 // Locate Hii Database protocol
1800 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**)&HiiDatabase
);
1801 if (EFI_ERROR (Status
)) {
1805 mPrivateData
->HiiDatabase
= HiiDatabase
;
1808 // Locate HiiString protocol
1810 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**)&HiiString
);
1811 if (EFI_ERROR (Status
)) {
1815 mPrivateData
->HiiString
= HiiString
;
1818 // Locate Formbrowser2 protocol
1820 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**)&FormBrowser2
);
1821 if (EFI_ERROR (Status
)) {
1825 mPrivateData
->FormBrowser2
= FormBrowser2
;
1828 // Locate ConfigRouting protocol
1830 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**)&HiiConfigRouting
);
1831 if (EFI_ERROR (Status
)) {
1835 mPrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1838 // Locate keyword handler protocol
1840 Status
= gBS
->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid
, NULL
, (VOID
**)&HiiKeywordHandler
);
1841 if (EFI_ERROR (Status
)) {
1845 mPrivateData
->HiiKeywordHandler
= HiiKeywordHandler
;
1848 // Locate HiiPopup protocol
1850 Status
= gBS
->LocateProtocol (&gEfiHiiPopupProtocolGuid
, NULL
, (VOID
**)&PopupHandler
);
1851 if (EFI_ERROR (Status
)) {
1855 mPrivateData
->HiiPopup
= PopupHandler
;
1857 Status
= gBS
->InstallMultipleProtocolInterfaces (
1859 &gEfiDevicePathProtocolGuid
,
1860 &mHiiVendorDevicePath0
,
1861 &gEfiHiiConfigAccessProtocolGuid
,
1862 &mPrivateData
->ConfigAccess
,
1865 ASSERT_EFI_ERROR (Status
);
1867 mPrivateData
->DriverHandle
[0] = DriverHandle
[0];
1870 // Publish our HII data
1872 HiiHandle
[0] = HiiAddPackages (
1873 &gDriverSampleFormSetGuid
,
1875 DriverSampleStrings
,
1879 if (HiiHandle
[0] == NULL
) {
1880 return EFI_OUT_OF_RESOURCES
;
1883 mPrivateData
->HiiHandle
[0] = HiiHandle
[0];
1886 // Publish another Fromset
1888 Status
= gBS
->InstallMultipleProtocolInterfaces (
1890 &gEfiDevicePathProtocolGuid
,
1891 &mHiiVendorDevicePath1
,
1892 &gEfiHiiConfigAccessProtocolGuid
,
1893 &mPrivateData
->ConfigAccess
,
1896 ASSERT_EFI_ERROR (Status
);
1898 mPrivateData
->DriverHandle
[1] = DriverHandle
[1];
1900 HiiHandle
[1] = HiiAddPackages (
1901 &gDriverSampleInventoryGuid
,
1903 DriverSampleStrings
,
1907 if (HiiHandle
[1] == NULL
) {
1908 DriverSampleUnload (ImageHandle
);
1909 return EFI_OUT_OF_RESOURCES
;
1912 mPrivateData
->HiiHandle
[1] = HiiHandle
[1];
1915 // Update the device path string.
1917 NewString
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*)&mHiiVendorDevicePath0
, FALSE
, FALSE
);
1918 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_DEVICE_PATH
), NewString
, NULL
) == 0) {
1919 DriverSampleUnload (ImageHandle
);
1920 return EFI_OUT_OF_RESOURCES
;
1923 if (NewString
!= NULL
) {
1924 FreePool (NewString
);
1928 // Very simple example of how one would update a string that is already
1929 // in the HII database
1931 NewString
= L
"700 Mhz";
1933 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1934 DriverSampleUnload (ImageHandle
);
1935 return EFI_OUT_OF_RESOURCES
;
1938 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1941 // Initialize Name/Value name String ID
1943 mPrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1944 mPrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1945 mPrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1948 // Initialize configuration data
1950 Configuration
= &mPrivateData
->Configuration
;
1951 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1954 // Try to read NV config EFI variable first
1956 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, DriverHandle
[0]);
1957 ASSERT (ConfigRequestHdr
!= NULL
);
1959 NameRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, NULL
, DriverHandle
[0]);
1960 ASSERT (NameRequestHdr
!= NULL
);
1962 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1963 Status
= gRT
->GetVariable (VariableName
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1964 if (EFI_ERROR (Status
)) {
1966 // Store zero data Buffer Storage to EFI variable
1968 Status
= gRT
->SetVariable (
1970 &gDriverSampleFormSetGuid
,
1971 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1972 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1975 if (EFI_ERROR (Status
)) {
1976 DriverSampleUnload (ImageHandle
);
1981 // EFI variable for NV config doesn't exit, we should build this variable
1982 // based on default values stored in IFR
1984 ActionFlag
= HiiSetToDefaults (NameRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1986 DriverSampleUnload (ImageHandle
);
1987 return EFI_INVALID_PARAMETER
;
1990 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1992 DriverSampleUnload (ImageHandle
);
1993 return EFI_INVALID_PARAMETER
;
1997 // EFI variable does exist and Validate Current Setting
1999 ActionFlag
= HiiValidateSettings (NameRequestHdr
);
2001 DriverSampleUnload (ImageHandle
);
2002 return EFI_INVALID_PARAMETER
;
2005 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2007 DriverSampleUnload (ImageHandle
);
2008 return EFI_INVALID_PARAMETER
;
2012 FreePool (ConfigRequestHdr
);
2015 // Initialize efi varstore configuration data
2017 VarStoreConfig
= &mPrivateData
->VarStoreConfig
;
2018 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
2020 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
2021 ASSERT (ConfigRequestHdr
!= NULL
);
2023 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
2024 Status
= gRT
->GetVariable (MyEfiVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
2025 if (EFI_ERROR (Status
)) {
2027 // Store zero data to EFI variable Storage.
2029 Status
= gRT
->SetVariable (
2031 &gDriverSampleFormSetGuid
,
2032 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2033 sizeof (MY_EFI_VARSTORE_DATA
),
2036 if (EFI_ERROR (Status
)) {
2037 DriverSampleUnload (ImageHandle
);
2042 // EFI variable for NV config doesn't exit, we should build this variable
2043 // based on default values stored in IFR
2045 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2047 DriverSampleUnload (ImageHandle
);
2048 return EFI_INVALID_PARAMETER
;
2052 // EFI variable does exist and Validate Current Setting
2054 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2056 DriverSampleUnload (ImageHandle
);
2057 return EFI_INVALID_PARAMETER
;
2061 FreePool (ConfigRequestHdr
);
2064 // Initialize Bits efi varstore configuration data
2066 BitsVarStoreConfig
= &mPrivateData
->BitsVarStoreConfig
;
2067 ZeroMem (BitsVarStoreConfig
, sizeof (MY_EFI_BITS_VARSTORE_DATA
));
2069 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiBitVar
, DriverHandle
[0]);
2070 ASSERT (ConfigRequestHdr
!= NULL
);
2072 BufferSize
= sizeof (MY_EFI_BITS_VARSTORE_DATA
);
2073 Status
= gRT
->GetVariable (MyEfiBitVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, BitsVarStoreConfig
);
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_BITS_VARSTORE_DATA
),
2085 if (EFI_ERROR (Status
)) {
2086 DriverSampleUnload (ImageHandle
);
2091 // EFI variable for NV config doesn't exit, we should build this variable
2092 // based on default values stored in IFR
2094 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2096 DriverSampleUnload (ImageHandle
);
2097 return EFI_INVALID_PARAMETER
;
2101 // EFI variable does exist and Validate Current Setting
2103 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2105 DriverSampleUnload (ImageHandle
);
2106 return EFI_INVALID_PARAMETER
;
2110 FreePool (ConfigRequestHdr
);
2113 // Initialize Union efi varstore configuration data
2115 UnionConfig
= &mPrivateData
->UnionConfig
;
2116 ZeroMem (UnionConfig
, sizeof (MY_EFI_UNION_DATA
));
2118 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiUnionVar
, DriverHandle
[0]);
2119 ASSERT (ConfigRequestHdr
!= NULL
);
2121 BufferSize
= sizeof (MY_EFI_UNION_DATA
);
2122 Status
= gRT
->GetVariable (MyEfiUnionVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, UnionConfig
);
2123 if (EFI_ERROR (Status
)) {
2125 // Store zero data to EFI variable Storage.
2127 Status
= gRT
->SetVariable (
2129 &gDriverSampleFormSetGuid
,
2130 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2131 sizeof (MY_EFI_UNION_DATA
),
2134 if (EFI_ERROR (Status
)) {
2135 DriverSampleUnload (ImageHandle
);
2140 // EFI variable for NV config doesn't exit, we should build this variable
2141 // based on default values stored in IFR
2143 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2145 DriverSampleUnload (ImageHandle
);
2146 return EFI_INVALID_PARAMETER
;
2150 // EFI variable does exist and Validate Current Setting
2152 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2154 DriverSampleUnload (ImageHandle
);
2155 return EFI_INVALID_PARAMETER
;
2159 FreePool (ConfigRequestHdr
);
2161 Status
= gBS
->CreateEventEx (
2164 EfiEventEmptyFunction
,
2166 &gEfiIfrRefreshIdOpGuid
,
2169 ASSERT_EFI_ERROR (Status
);
2172 // Example of how to use BrowserEx protocol to register HotKey.
2174 Status
= gBS
->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid
, NULL
, (VOID
**)&FormBrowserEx
);
2175 if (!EFI_ERROR (Status
)) {
2177 // First unregister the default hot key F9 and F10.
2179 HotKey
.UnicodeChar
= CHAR_NULL
;
2180 HotKey
.ScanCode
= SCAN_F9
;
2181 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2182 HotKey
.ScanCode
= SCAN_F10
;
2183 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2186 // Register the default HotKey F9 and F10 again.
2188 HotKey
.ScanCode
= SCAN_F10
;
2189 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_TEN_STRING
), NULL
);
2190 ASSERT (NewString
!= NULL
);
2191 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_SUBMIT
, 0, NewString
);
2192 HotKey
.ScanCode
= SCAN_F9
;
2193 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_NINE_STRING
), NULL
);
2194 ASSERT (NewString
!= NULL
);
2195 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, NewString
);
2199 // In default, this driver is built into Flash device image,
2200 // the following code doesn't run.
2204 // Example of how to display only the item we sent to HII
2205 // When this driver is not built into Flash device image,
2206 // it need to call SendForm to show front page by itself.
2208 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2210 // Have the browser pull out our copy of the data, and only display our data
2212 Status
= FormBrowser2
->SendForm (
2214 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2222 HiiRemovePackages (HiiHandle
[0]);
2224 HiiRemovePackages (HiiHandle
[1]);
2231 Unloads the application and its installed protocol.
2233 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2235 @retval EFI_SUCCESS The image has been unloaded.
2239 DriverSampleUnload (
2240 IN EFI_HANDLE ImageHandle
2245 ASSERT (mPrivateData
!= NULL
);
2247 if (DriverHandle
[0] != NULL
) {
2248 gBS
->UninstallMultipleProtocolInterfaces (
2250 &gEfiDevicePathProtocolGuid
,
2251 &mHiiVendorDevicePath0
,
2252 &gEfiHiiConfigAccessProtocolGuid
,
2253 &mPrivateData
->ConfigAccess
,
2256 DriverHandle
[0] = NULL
;
2259 if (DriverHandle
[1] != NULL
) {
2260 gBS
->UninstallMultipleProtocolInterfaces (
2262 &gEfiDevicePathProtocolGuid
,
2263 &mHiiVendorDevicePath1
,
2264 &gEfiHiiConfigAccessProtocolGuid
,
2265 &mPrivateData
->ConfigAccess
,
2268 DriverHandle
[1] = NULL
;
2271 if (mPrivateData
->HiiHandle
[0] != NULL
) {
2272 HiiRemovePackages (mPrivateData
->HiiHandle
[0]);
2275 if (mPrivateData
->HiiHandle
[1] != NULL
) {
2276 HiiRemovePackages (mPrivateData
->HiiHandle
[1]);
2279 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2280 if (mPrivateData
->NameValueName
[Index
] != NULL
) {
2281 FreePool (mPrivateData
->NameValueName
[Index
]);
2285 FreePool (mPrivateData
);
2286 mPrivateData
= NULL
;
2288 gBS
->CloseEvent (mEvent
);