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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "DriverSample.h"
19 #define DISPLAY_ONLY_MY_ITEM 0x0002
21 CHAR16 VariableName
[] = L
"MyIfrNVData";
22 CHAR16 MyEfiVar
[] = L
"MyEfiVar";
23 CHAR16 MyEfiBitVar
[] = L
"MyEfiBitVar";
24 CHAR16 MyEfiUnionVar
[] = L
"MyEfiUnionVar";
26 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
27 DRIVER_SAMPLE_PRIVATE_DATA
*mPrivateData
= NULL
;
30 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
36 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
37 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
40 DRIVER_SAMPLE_FORMSET_GUID
44 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
46 (UINT8
) (END_DEVICE_PATH_LENGTH
),
47 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
52 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
58 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
59 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
62 DRIVER_SAMPLE_INVENTORY_GUID
66 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
68 (UINT8
) (END_DEVICE_PATH_LENGTH
),
69 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
75 Set value of a data element in an Array by its Index.
77 @param Array The data array.
78 @param Type Type of the data in this array.
79 @param Index Zero based index for data in this array.
80 @param Value The value to be set.
92 ASSERT (Array
!= NULL
);
95 case EFI_IFR_TYPE_NUM_SIZE_8
:
96 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
99 case EFI_IFR_TYPE_NUM_SIZE_16
:
100 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
103 case EFI_IFR_TYPE_NUM_SIZE_32
:
104 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
107 case EFI_IFR_TYPE_NUM_SIZE_64
:
108 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
117 Notification function for keystrokes.
119 @param[in] KeyData The key that was pressed.
121 @retval EFI_SUCCESS The operation was successful.
125 NotificationFunction(
126 IN EFI_KEY_DATA
*KeyData
129 gBS
->SignalEvent (mEvent
);
135 Function to start monitoring for CTRL-C using SimpleTextInputEx.
137 @retval EFI_SUCCESS The feature is enabled.
138 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
142 InternalStartMonitor(
146 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
147 EFI_KEY_DATA KeyData
;
152 EFI_HANDLE NotifyHandle
;
154 Status
= gBS
->LocateHandleBuffer (
156 &gEfiSimpleTextInputExProtocolGuid
,
161 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
162 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
163 ASSERT_EFI_ERROR (Status
);
165 KeyData
.KeyState
.KeyToggleState
= 0;
166 KeyData
.Key
.ScanCode
= 0;
167 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
168 KeyData
.Key
.UnicodeChar
= L
'c';
170 Status
= SimpleEx
->RegisterKeyNotify(
173 NotificationFunction
,
175 if (EFI_ERROR (Status
)) {
179 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
180 Status
= SimpleEx
->RegisterKeyNotify(
183 NotificationFunction
,
185 if (EFI_ERROR (Status
)) {
194 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
196 @retval EFI_SUCCESS The feature is enabled.
197 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
205 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
208 EFI_KEY_DATA KeyData
;
211 EFI_HANDLE NotifyHandle
;
213 Status
= gBS
->LocateHandleBuffer (
215 &gEfiSimpleTextInputExProtocolGuid
,
220 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
221 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
222 ASSERT_EFI_ERROR (Status
);
224 KeyData
.KeyState
.KeyToggleState
= 0;
225 KeyData
.Key
.ScanCode
= 0;
226 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
227 KeyData
.Key
.UnicodeChar
= L
'c';
229 Status
= SimpleEx
->RegisterKeyNotify(
232 NotificationFunction
,
234 if (!EFI_ERROR (Status
)) {
235 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
238 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
239 Status
= SimpleEx
->RegisterKeyNotify(
242 NotificationFunction
,
244 if (!EFI_ERROR (Status
)) {
245 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
252 Update names of Name/Value storage to current language.
254 @param PrivateData Points to the driver private data.
256 @retval EFI_SUCCESS All names are successfully updated.
257 @retval EFI_NOT_FOUND Failed to get Name from HII database.
262 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
268 // Get Name/Value name string of current language
270 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
271 PrivateData
->NameValueName
[Index
] = HiiGetString (
272 PrivateData
->HiiHandle
[0],
273 PrivateData
->NameStringId
[Index
],
276 if (PrivateData
->NameValueName
[Index
] == NULL
) {
277 return EFI_NOT_FOUND
;
286 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
288 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
290 This is a internal function.
292 @param StringPtr String in <BlockConfig> format and points to the
293 first character of <Number>.
294 @param Number The output value. Caller takes the responsibility
296 @param Len Length of the <Number>, in characters.
298 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
300 @retval EFI_SUCCESS Value of <Number> is outputted in Number
306 IN EFI_STRING StringPtr
,
320 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
321 return EFI_INVALID_PARAMETER
;
327 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
330 *Len
= StringPtr
- TmpPtr
;
333 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
335 Status
= EFI_OUT_OF_RESOURCES
;
338 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
339 *(Str
+ *Len
) = L
'\0';
341 Length
= (Length
+ 1) / 2;
342 Buf
= (UINT8
*) AllocateZeroPool (Length
);
344 Status
= EFI_OUT_OF_RESOURCES
;
349 ZeroMem (TemStr
, sizeof (TemStr
));
350 for (Index
= 0; Index
< Length
; Index
++) {
351 TemStr
[0] = Str
[Length
- Index
- 1];
352 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
353 if ((Index
& 1) == 0) {
354 Buf
[Index
/2] = DigitUint8
;
356 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
361 Status
= EFI_SUCCESS
;
372 Create altcfg string.
374 @param Result The request result string.
375 @param ConfigHdr The request head info. <ConfigHdr> format.
376 @param Offset The offset of the parameter int he structure.
377 @param Width The width of the parameter.
380 @retval The string with altcfg info append at the end.
384 IN EFI_STRING Result
,
385 IN EFI_STRING ConfigHdr
,
390 EFI_STRING StringPtr
;
394 NewLen
= StrLen (Result
);
396 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
398 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
399 StringPtr
= AllocateZeroPool (NewLen
);
400 if (StringPtr
== NULL
) {
405 if (Result
!= NULL
) {
406 StrCpyS (StringPtr
, NewLen
/ sizeof (CHAR16
), Result
);
407 StringPtr
+= StrLen (Result
);
413 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
416 EFI_HII_DEFAULT_CLASS_STANDARD
418 StringPtr
+= StrLen (StringPtr
);
422 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
423 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
426 DEFAULT_CLASS_STANDARD_VALUE
428 StringPtr
+= StrLen (StringPtr
);
432 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
435 EFI_HII_DEFAULT_CLASS_MANUFACTURING
437 StringPtr
+= StrLen (StringPtr
);
441 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
442 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
445 DEFAULT_CLASS_MANUFACTURING_VALUE
447 StringPtr
+= StrLen (StringPtr
);
453 Check whether need to add the altcfg string. if need to add, add the altcfg
456 @param RequestResult The request result string.
457 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
462 IN OUT EFI_STRING
*RequestResult
,
463 IN EFI_STRING ConfigRequestHdr
466 EFI_STRING StringPtr
;
477 StringPtr
= *RequestResult
;
478 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
479 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
480 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
481 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
483 if (StringPtr
== NULL
) {
487 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
488 StringPtr
+= StrLen (L
"OFFSET=");
492 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
493 if (EFI_ERROR (Status
)) {
500 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
502 FreePool (TmpBuffer
);
505 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
)) {
521 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
523 FreePool (TmpBuffer
);
526 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
529 StringPtr
+= StrLen (L
"&VALUE=");
534 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
535 if (EFI_ERROR (Status
)) {
541 // Skip the character "&" before "OFFSET".
546 // Calculate Value and convert it to hex string.
548 if (Offset
+ Width
> BlockSize
) {
552 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
553 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
560 This function allows a caller to extract the current configuration for one
561 or more named elements from the target driver.
563 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
564 @param Request A null-terminated Unicode string in
565 <ConfigRequest> format.
566 @param Progress On return, points to a character in the Request
567 string. Points to the string's null terminator if
568 request was successful. Points to the most recent
569 '&' before the first failing name/value pair (or
570 the beginning of the string if the failure is in
571 the first name/value pair) if the request was not
573 @param Results A null-terminated Unicode string in
574 <ConfigAltResp> format which has all values filled
575 in for the names in the Request string. String to
576 be allocated by the called function.
578 @retval EFI_SUCCESS The Results is filled with the requested values.
579 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
580 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
581 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
588 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
589 IN CONST EFI_STRING Request
,
590 OUT EFI_STRING
*Progress
,
591 OUT EFI_STRING
*Results
596 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
597 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
598 EFI_STRING ConfigRequest
;
599 EFI_STRING ConfigRequestHdr
;
605 BOOLEAN AllocatedRequest
;
607 if (Progress
== NULL
|| Results
== NULL
) {
608 return EFI_INVALID_PARAMETER
;
611 // Initialize the local variables.
613 ConfigRequestHdr
= NULL
;
614 ConfigRequest
= NULL
;
617 AllocatedRequest
= FALSE
;
619 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
620 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
623 // Get Buffer Storage data from EFI variable.
624 // Try to get the current setting from variable.
626 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
627 Status
= gRT
->GetVariable (
629 &gDriverSampleFormSetGuid
,
632 &PrivateData
->Configuration
634 if (EFI_ERROR (Status
)) {
635 return EFI_NOT_FOUND
;
638 if (Request
== NULL
) {
640 // Request is set to NULL, construct full request string.
644 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
645 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
647 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
648 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
649 ConfigRequest
= AllocateZeroPool (Size
);
650 ASSERT (ConfigRequest
!= NULL
);
651 AllocatedRequest
= TRUE
;
652 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
653 FreePool (ConfigRequestHdr
);
654 ConfigRequestHdr
= NULL
;
657 // Check routing data in <ConfigHdr>.
658 // Note: if only one Storage is used, then this checking could be skipped.
660 if (!HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, NULL
)) {
661 return EFI_NOT_FOUND
;
664 // Check whether request for EFI Varstore. EFI varstore get data
665 // through hii database, not support in this path.
667 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
668 return EFI_UNSUPPORTED
;
670 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
671 return EFI_UNSUPPORTED
;
673 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
674 return EFI_UNSUPPORTED
;
678 // Set Request to the unified request string.
680 ConfigRequest
= Request
;
682 // Check whether Request includes Request Element.
684 if (StrStr (Request
, L
"OFFSET") == NULL
) {
686 // Check Request Element does exist in Reques String
688 StrPointer
= StrStr (Request
, L
"PATH");
689 if (StrPointer
== NULL
) {
690 return EFI_INVALID_PARAMETER
;
692 if (StrStr (StrPointer
, L
"&") == NULL
) {
693 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
694 ConfigRequest
= AllocateZeroPool (Size
);
695 ASSERT (ConfigRequest
!= NULL
);
696 AllocatedRequest
= TRUE
;
697 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
703 // Check if requesting Name/Value storage
705 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
707 // Update Name/Value storage Names
709 Status
= LoadNameValueNames (PrivateData
);
710 if (EFI_ERROR (Status
)) {
715 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
716 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
717 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
719 BufferSize
= (StrLen (ConfigRequest
) +
720 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
721 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
722 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
723 *Results
= AllocateZeroPool (BufferSize
);
724 ASSERT (*Results
!= NULL
);
725 StrCpyS (*Results
, BufferSize
/ sizeof (CHAR16
), ConfigRequest
);
729 // Append value of NameValueVar0, type is UINT8
731 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
732 Value
+= StrLen (PrivateData
->NameValueName
[0]);
733 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
734 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
736 BackupChar
= Value
[ValueStrLen
];
738 UnicodeValueToStringS (
740 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
741 PREFIX_ZERO
| RADIX_HEX
,
742 PrivateData
->Configuration
.NameValueVar0
,
743 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
745 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
750 // Append value of NameValueVar1, type is UINT16
752 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
753 Value
+= StrLen (PrivateData
->NameValueName
[1]);
754 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
755 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
757 BackupChar
= Value
[ValueStrLen
];
759 UnicodeValueToStringS (
761 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
762 PREFIX_ZERO
| RADIX_HEX
,
763 PrivateData
->Configuration
.NameValueVar1
,
764 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
766 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
771 // Append value of NameValueVar2, type is CHAR16 *
773 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
774 Value
+= StrLen (PrivateData
->NameValueName
[2]);
775 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
776 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
780 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
782 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
783 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
784 UnicodeValueToStringS (
786 BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
),
787 PREFIX_ZERO
| RADIX_HEX
,
791 Value
+= StrnLenS (Value
, (BufferSize
- ((UINTN
)Value
- (UINTN
)*Results
)) / sizeof (CHAR16
));
795 Status
= EFI_SUCCESS
;
798 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
800 Status
= HiiConfigRouting
->BlockToConfig (
803 (UINT8
*) &PrivateData
->Configuration
,
808 if (!EFI_ERROR (Status
)) {
809 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
810 AppendAltCfgString(Results
, ConfigRequestHdr
);
815 // Free the allocated config request string.
817 if (AllocatedRequest
) {
818 FreePool (ConfigRequest
);
821 if (ConfigRequestHdr
!= NULL
) {
822 FreePool (ConfigRequestHdr
);
825 // Set Progress string to the original request string.
827 if (Request
== NULL
) {
829 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
830 *Progress
= Request
+ StrLen (Request
);
838 This function processes the results of changes in configuration.
840 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
841 @param Configuration A null-terminated Unicode string in <ConfigResp>
843 @param Progress A pointer to a string filled in with the offset of
844 the most recent '&' before the first failing
845 name/value pair (or the beginning of the string if
846 the failure is in the first name/value pair) or
847 the terminating NULL if all was successful.
849 @retval EFI_SUCCESS The Results is processed successfully.
850 @retval EFI_INVALID_PARAMETER Configuration is NULL.
851 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
858 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
859 IN CONST EFI_STRING Configuration
,
860 OUT EFI_STRING
*Progress
865 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
866 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
875 if (Configuration
== NULL
|| Progress
== NULL
) {
876 return EFI_INVALID_PARAMETER
;
879 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
880 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
881 *Progress
= Configuration
;
884 // Check routing data in <ConfigHdr>.
885 // Note: if only one Storage is used, then this checking could be skipped.
887 if (!HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, NULL
)) {
888 return EFI_NOT_FOUND
;
892 // Check whether request for EFI Varstore. EFI varstore get data
893 // through hii database, not support in this path.
895 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
896 return EFI_UNSUPPORTED
;
898 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiBitVar
)) {
899 return EFI_UNSUPPORTED
;
901 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiUnionVar
)) {
902 return EFI_UNSUPPORTED
;
906 // Get Buffer Storage data from EFI variable
908 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
909 Status
= gRT
->GetVariable (
911 &gDriverSampleFormSetGuid
,
914 &PrivateData
->Configuration
916 if (EFI_ERROR (Status
)) {
921 // Check if configuring Name/Value storage
923 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
925 // Update Name/Value storage Names
927 Status
= LoadNameValueNames (PrivateData
);
928 if (EFI_ERROR (Status
)) {
933 // Convert value for NameValueVar0
935 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
939 Value
+= StrLen (PrivateData
->NameValueName
[0]);
944 StrPtr
= StrStr (Value
, L
"&");
945 if (StrPtr
== NULL
) {
946 StrPtr
= Value
+ StrLen (Value
);
949 // Convert Value to Buffer data
951 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
952 ZeroMem (TemStr
, sizeof (TemStr
));
953 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
955 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
956 if ((Index
& 1) == 0) {
957 DataBuffer
[Index
/2] = DigitUint8
;
959 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
965 // Convert value for NameValueVar1
967 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
971 Value
+= StrLen (PrivateData
->NameValueName
[1]);
976 StrPtr
= StrStr (Value
, L
"&");
977 if (StrPtr
== NULL
) {
978 StrPtr
= Value
+ StrLen (Value
);
981 // Convert Value to Buffer data
983 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
984 ZeroMem (TemStr
, sizeof (TemStr
));
985 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
987 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
988 if ((Index
& 1) == 0) {
989 DataBuffer
[Index
/2] = DigitUint8
;
991 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
997 // Convert value for NameValueVar2
999 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1003 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1008 StrPtr
= StrStr (Value
, L
"&");
1009 if (StrPtr
== NULL
) {
1010 StrPtr
= Value
+ StrLen (Value
);
1013 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1015 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1016 ZeroMem (TemStr
, sizeof (TemStr
));
1017 while (Value
< StrPtr
) {
1018 StrnCpyS (TemStr
, sizeof (TemStr
) / sizeof (CHAR16
), Value
, 4);
1019 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1026 // Store Buffer Storage back to EFI variable
1028 Status
= gRT
->SetVariable(
1030 &gDriverSampleFormSetGuid
,
1031 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1032 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1033 &PrivateData
->Configuration
1040 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1042 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1043 Status
= HiiConfigRouting
->ConfigToBlock (
1046 (UINT8
*) &PrivateData
->Configuration
,
1050 if (EFI_ERROR (Status
)) {
1055 // Store Buffer Storage back to EFI variable
1057 Status
= gRT
->SetVariable(
1059 &gDriverSampleFormSetGuid
,
1060 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1061 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1062 &PrivateData
->Configuration
1070 This function processes the results of changes in configuration.
1072 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1073 @param Action Specifies the type of action taken by the browser.
1074 @param QuestionId A unique value which is sent to the original
1075 exporting driver so that it can identify the type
1077 @param Type The type of value for the question.
1078 @param Value A pointer to the data being sent to the original
1080 @param ActionRequest On return, points to the action requested by the
1083 @retval EFI_SUCCESS The callback successfully handled the action.
1084 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1085 variable and its data.
1086 @retval EFI_DEVICE_ERROR The variable could not be saved.
1087 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1094 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1095 IN EFI_BROWSER_ACTION Action
,
1096 IN EFI_QUESTION_ID QuestionId
,
1098 IN EFI_IFR_TYPE_VALUE
*Value
,
1099 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1102 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1104 VOID
*StartOpCodeHandle
;
1105 VOID
*OptionsOpCodeHandle
;
1106 EFI_IFR_GUID_LABEL
*StartLabel
;
1107 VOID
*EndOpCodeHandle
;
1108 EFI_IFR_GUID_LABEL
*EndLabel
;
1110 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1111 MY_EFI_VARSTORE_DATA
*EfiData
;
1113 EFI_STRING Progress
;
1119 EFI_HII_POPUP_SELECTION UserSelection
;
1121 UserSelection
= 0xFF;
1123 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1124 (ActionRequest
== NULL
)) {
1125 return EFI_INVALID_PARAMETER
;
1131 Status
= EFI_SUCCESS
;
1133 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1136 case EFI_BROWSER_ACTION_FORM_OPEN
:
1138 if (QuestionId
== 0x1234) {
1140 // Sample CallBack for UEFI FORM_OPEN action:
1141 // Add Save action into Form 3 when Form 1 is opened.
1142 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1144 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1147 // Initialize the container for dynamic opcodes
1149 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1150 ASSERT (StartOpCodeHandle
!= NULL
);
1153 // Create Hii Extend Label OpCode as the start opcode
1155 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1156 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1157 StartLabel
->Number
= LABEL_UPDATE2
;
1159 HiiCreateActionOpCode (
1160 StartOpCodeHandle
, // Container for dynamic created opcodes
1161 0x1238, // Question ID
1162 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1163 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1164 EFI_IFR_FLAG_CALLBACK
, // Question flag
1165 0 // Action String ID
1169 PrivateData
->HiiHandle
[0], // HII handle
1170 &gDriverSampleFormSetGuid
, // Formset GUID
1172 StartOpCodeHandle
, // Label for where to insert opcodes
1176 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1179 if (QuestionId
== 0x1247) {
1180 Status
= InternalStartMonitor ();
1181 ASSERT_EFI_ERROR (Status
);
1186 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1188 if (QuestionId
== 0x5678) {
1190 // Sample CallBack for UEFI FORM_CLOSE action:
1191 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1195 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1198 L
"You are going to leave third Form!",
1199 L
"Press ESC or ENTER to continue ...",
1203 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1206 if (QuestionId
== 0x1247) {
1207 Status
= InternalStopMonitor ();
1208 ASSERT_EFI_ERROR (Status
);
1213 case EFI_BROWSER_ACTION_RETRIEVE
:
1215 switch (QuestionId
) {
1217 if (Type
!= EFI_IFR_TYPE_REF
) {
1218 return EFI_INVALID_PARAMETER
;
1220 Value
->ref
.FormId
= 0x3;
1226 // We will reach here once the Question is refreshed
1230 // Initialize the container for dynamic opcodes
1232 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1233 ASSERT (StartOpCodeHandle
!= NULL
);
1236 // Create Hii Extend Label OpCode as the start opcode
1238 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1239 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1240 if (QuestionId
== 0x5678) {
1241 StartLabel
->Number
= LABEL_UPDATE2
;
1243 PrivateData
->Configuration
.DynamicRefresh
++;
1244 } else if (QuestionId
== 0x1247 ) {
1245 StartLabel
->Number
= LABEL_UPDATE3
;
1247 PrivateData
->Configuration
.RefreshGuidCount
++;
1250 HiiCreateActionOpCode (
1251 StartOpCodeHandle
, // Container for dynamic created opcodes
1252 0x1237, // Question ID
1253 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1254 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1255 EFI_IFR_FLAG_CALLBACK
, // Question flag
1256 0 // Action String ID
1260 PrivateData
->HiiHandle
[0], // HII handle
1261 &gDriverSampleFormSetGuid
, // Formset GUID
1263 StartOpCodeHandle
, // Label for where to insert opcodes
1267 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1270 // Refresh the Question value
1272 Status
= gRT
->SetVariable(
1274 &gDriverSampleFormSetGuid
,
1275 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1276 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1277 &PrivateData
->Configuration
1280 if (QuestionId
== 0x5678) {
1282 // Update uncommitted data of Browser
1284 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1285 ASSERT (EfiData
!= NULL
);
1286 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*) EfiData
)) {
1287 EfiData
->Field8
= 111;
1289 &gDriverSampleFormSetGuid
,
1291 sizeof (MY_EFI_VARSTORE_DATA
),
1303 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1305 switch (QuestionId
) {
1307 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1311 for (Index
= 0; Index
< 3; Index
++) {
1312 SetArrayData (Value
, EFI_IFR_TYPE_NUM_SIZE_8
, Index
, BufferValue
--);
1321 Status
= EFI_UNSUPPORTED
;
1327 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1329 switch (QuestionId
) {
1331 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1339 Status
= EFI_UNSUPPORTED
;
1345 case EFI_BROWSER_ACTION_CHANGING
:
1347 switch (QuestionId
) {
1350 if (Type
!= EFI_IFR_TYPE_REF
) {
1351 return EFI_INVALID_PARAMETER
;
1354 Value
->ref
.FormId
= 0x1234;
1359 // Initialize the container for dynamic opcodes
1361 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1362 ASSERT (StartOpCodeHandle
!= NULL
);
1364 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1365 ASSERT (EndOpCodeHandle
!= NULL
);
1368 // Create Hii Extend Label OpCode as the start opcode
1370 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1371 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1372 StartLabel
->Number
= LABEL_UPDATE1
;
1375 // Create Hii Extend Label OpCode as the end opcode
1377 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1378 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1379 EndLabel
->Number
= LABEL_END
;
1381 HiiCreateActionOpCode (
1382 StartOpCodeHandle
, // Container for dynamic created opcodes
1383 0x1237, // Question ID
1384 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1385 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1386 EFI_IFR_FLAG_CALLBACK
, // Question flag
1387 0 // Action String ID
1391 // Create Option OpCode
1393 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1394 ASSERT (OptionsOpCodeHandle
!= NULL
);
1396 HiiCreateOneOfOptionOpCode (
1397 OptionsOpCodeHandle
,
1398 STRING_TOKEN (STR_BOOT_OPTION1
),
1400 EFI_IFR_NUMERIC_SIZE_1
,
1404 HiiCreateOneOfOptionOpCode (
1405 OptionsOpCodeHandle
,
1406 STRING_TOKEN (STR_BOOT_OPTION2
),
1408 EFI_IFR_NUMERIC_SIZE_1
,
1413 // Prepare initial value for the dynamic created oneof Question
1415 PrivateData
->Configuration
.DynamicOneof
= 2;
1416 Status
= gRT
->SetVariable(
1418 &gDriverSampleFormSetGuid
,
1419 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1420 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1421 &PrivateData
->Configuration
1425 // Set initial vlaue of dynamic created oneof Question in Form Browser
1427 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1428 ASSERT (Configuration
!= NULL
);
1429 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1430 Configuration
->DynamicOneof
= 2;
1433 // Update uncommitted data of Browser
1436 &gDriverSampleFormSetGuid
,
1438 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1439 (UINT8
*) Configuration
,
1443 FreePool (Configuration
);
1445 HiiCreateOneOfOpCode (
1446 StartOpCodeHandle
, // Container for dynamic created opcodes
1447 0x8001, // Question ID (or call it "key")
1448 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1449 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1450 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1451 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1452 EFI_IFR_FLAG_CALLBACK
, // Question flag
1453 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1454 OptionsOpCodeHandle
, // Option Opcode list
1455 NULL
// Default Opcode is NULl
1458 HiiCreateOrderedListOpCode (
1459 StartOpCodeHandle
, // Container for dynamic created opcodes
1460 0x8002, // Question ID
1461 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1462 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1463 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1464 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1465 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1466 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1467 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1468 5, // Maximum container
1469 OptionsOpCodeHandle
, // Option Opcode list
1470 NULL
// Default Opcode is NULl
1473 HiiCreateTextOpCode (
1475 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1476 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1477 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1480 HiiCreateDateOpCode (
1485 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1486 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1488 QF_DATE_STORAGE_TIME
,
1492 HiiCreateTimeOpCode (
1497 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1498 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1500 QF_TIME_STORAGE_TIME
,
1504 HiiCreateGotoOpCode (
1505 StartOpCodeHandle
, // Container for dynamic created opcodes
1506 1, // Target Form ID
1507 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1508 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1510 0x8003 // Question ID
1514 PrivateData
->HiiHandle
[0], // HII handle
1515 &gDriverSampleFormSetGuid
, // Formset GUID
1517 StartOpCodeHandle
, // Label for where to insert opcodes
1518 EndOpCodeHandle
// Replace data
1521 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1522 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1523 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1532 case EFI_BROWSER_ACTION_CHANGED
:
1533 switch (QuestionId
) {
1536 // User press "Exit now", request Browser to exit
1538 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1543 // User press "Save now", request Browser to save the uncommitted data.
1545 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1551 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1553 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1558 // User press "Discard current form now", request Browser to discard the uncommitted data.
1560 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1565 // User press "Submit current form now", request Browser to save the uncommitted data.
1567 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1573 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1575 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1580 // 1. Check to see whether system support keyword.
1582 Status
= PrivateData
->HiiKeywordHandler
->GetData (PrivateData
->HiiKeywordHandler
,
1583 L
"NAMESPACE=x-UEFI-ns",
1584 L
"KEYWORD=iSCSIBootEnable",
1589 if (EFI_ERROR (Status
)) {
1592 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1595 L
"This system not support this keyword!",
1596 L
"Press ENTER to continue ...",
1600 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1602 Status
= EFI_SUCCESS
;
1607 // 2. If system support this keyword, just try to change value.
1611 // Change value from '0' to '1' or from '1' to '0'
1613 TmpStr
= StrStr (Results
, L
"&VALUE=");
1614 ASSERT (TmpStr
!= NULL
);
1615 TmpStr
+= StrLen (L
"&VALUE=");
1617 if (*TmpStr
== L
'0') {
1624 // 3. Call the keyword handler protocol to change the value.
1626 Status
= PrivateData
->HiiKeywordHandler
->SetData (PrivateData
->HiiKeywordHandler
,
1631 if (EFI_ERROR (Status
)) {
1634 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1637 L
"Set keyword to the system failed!",
1638 L
"Press ENTER to continue ...",
1642 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1644 Status
= EFI_SUCCESS
;
1650 Status
= mPrivateData
->HiiPopup
->CreatePopup (
1651 mPrivateData
->HiiPopup
,
1652 EfiHiiPopupStyleInfo
,
1653 EfiHiiPopupTypeYesNo
,
1654 mPrivateData
->HiiHandle
[0],
1655 STRING_TOKEN (STR_POPUP_STRING
),
1658 if (!EFI_ERROR (Status
)) {
1659 if (UserSelection
== EfiHiiPopupSelectionYes
) {
1660 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1670 case EFI_BROWSER_ACTION_SUBMITTED
:
1672 if (QuestionId
== 0x1250) {
1674 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:
1675 // Show up a pop-up to show SUBMITTED callback has been triggered.
1679 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1682 L
"EfiVarstore value has been submitted!",
1683 L
"Press ESC or ENTER to continue ...",
1687 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1693 Status
= EFI_UNSUPPORTED
;
1701 Main entry for this driver.
1703 @param ImageHandle Image handle this driver.
1704 @param SystemTable Pointer to SystemTable.
1706 @retval EFI_SUCESS This function always complete successfully.
1712 IN EFI_HANDLE ImageHandle
,
1713 IN EFI_SYSTEM_TABLE
*SystemTable
1717 EFI_HII_HANDLE HiiHandle
[2];
1718 EFI_SCREEN_DESCRIPTOR Screen
;
1719 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1720 EFI_HII_STRING_PROTOCOL
*HiiString
;
1721 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1722 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1723 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL
*HiiKeywordHandler
;
1724 EFI_HII_POPUP_PROTOCOL
*PopupHandler
;
1727 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1729 EFI_STRING ConfigRequestHdr
;
1730 EFI_STRING NameRequestHdr
;
1731 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1732 MY_EFI_BITS_VARSTORE_DATA
*BitsVarStoreConfig
;
1733 MY_EFI_UNION_DATA
*UnionConfig
;
1734 EFI_INPUT_KEY HotKey
;
1735 EDKII_FORM_BROWSER_EXTENSION_PROTOCOL
*FormBrowserEx
;
1738 // Initialize the local variables.
1740 ConfigRequestHdr
= NULL
;
1744 // Initialize screen dimensions for SendForm().
1745 // Remove 3 characters from top and bottom
1747 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1748 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1751 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1754 // Initialize driver private data
1756 mPrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1757 if (mPrivateData
== NULL
) {
1758 return EFI_OUT_OF_RESOURCES
;
1761 mPrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1763 mPrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1764 mPrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1765 mPrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1768 // Locate Hii Database protocol
1770 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1771 if (EFI_ERROR (Status
)) {
1774 mPrivateData
->HiiDatabase
= HiiDatabase
;
1777 // Locate HiiString protocol
1779 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1780 if (EFI_ERROR (Status
)) {
1783 mPrivateData
->HiiString
= HiiString
;
1786 // Locate Formbrowser2 protocol
1788 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1789 if (EFI_ERROR (Status
)) {
1792 mPrivateData
->FormBrowser2
= FormBrowser2
;
1795 // Locate ConfigRouting protocol
1797 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1798 if (EFI_ERROR (Status
)) {
1801 mPrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1804 // Locate keyword handler protocol
1806 Status
= gBS
->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid
, NULL
, (VOID
**) &HiiKeywordHandler
);
1807 if (EFI_ERROR (Status
)) {
1810 mPrivateData
->HiiKeywordHandler
= HiiKeywordHandler
;
1813 // Locate HiiPopup protocol
1815 Status
= gBS
->LocateProtocol (&gEfiHiiPopupProtocolGuid
, NULL
, (VOID
**) &PopupHandler
);
1816 if (EFI_ERROR (Status
)) {
1819 mPrivateData
->HiiPopup
= PopupHandler
;
1821 Status
= gBS
->InstallMultipleProtocolInterfaces (
1823 &gEfiDevicePathProtocolGuid
,
1824 &mHiiVendorDevicePath0
,
1825 &gEfiHiiConfigAccessProtocolGuid
,
1826 &mPrivateData
->ConfigAccess
,
1829 ASSERT_EFI_ERROR (Status
);
1831 mPrivateData
->DriverHandle
[0] = DriverHandle
[0];
1834 // Publish our HII data
1836 HiiHandle
[0] = HiiAddPackages (
1837 &gDriverSampleFormSetGuid
,
1839 DriverSampleStrings
,
1843 if (HiiHandle
[0] == NULL
) {
1844 return EFI_OUT_OF_RESOURCES
;
1847 mPrivateData
->HiiHandle
[0] = HiiHandle
[0];
1850 // Publish another Fromset
1852 Status
= gBS
->InstallMultipleProtocolInterfaces (
1854 &gEfiDevicePathProtocolGuid
,
1855 &mHiiVendorDevicePath1
,
1856 &gEfiHiiConfigAccessProtocolGuid
,
1857 &mPrivateData
->ConfigAccess
,
1860 ASSERT_EFI_ERROR (Status
);
1862 mPrivateData
->DriverHandle
[1] = DriverHandle
[1];
1864 HiiHandle
[1] = HiiAddPackages (
1865 &gDriverSampleInventoryGuid
,
1867 DriverSampleStrings
,
1871 if (HiiHandle
[1] == NULL
) {
1872 DriverSampleUnload (ImageHandle
);
1873 return EFI_OUT_OF_RESOURCES
;
1876 mPrivateData
->HiiHandle
[1] = HiiHandle
[1];
1879 // Update the device path string.
1881 NewString
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)&mHiiVendorDevicePath0
, FALSE
, FALSE
);
1882 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_DEVICE_PATH
), NewString
, NULL
) == 0) {
1883 DriverSampleUnload (ImageHandle
);
1884 return EFI_OUT_OF_RESOURCES
;
1886 if (NewString
!= NULL
) {
1887 FreePool (NewString
);
1891 // Very simple example of how one would update a string that is already
1892 // in the HII database
1894 NewString
= L
"700 Mhz";
1896 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1897 DriverSampleUnload (ImageHandle
);
1898 return EFI_OUT_OF_RESOURCES
;
1901 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1904 // Initialize Name/Value name String ID
1906 mPrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1907 mPrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1908 mPrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1911 // Initialize configuration data
1913 Configuration
= &mPrivateData
->Configuration
;
1914 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1917 // Try to read NV config EFI variable first
1919 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, DriverHandle
[0]);
1920 ASSERT (ConfigRequestHdr
!= NULL
);
1922 NameRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, NULL
, DriverHandle
[0]);
1923 ASSERT (NameRequestHdr
!= NULL
);
1925 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1926 Status
= gRT
->GetVariable (VariableName
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1927 if (EFI_ERROR (Status
)) {
1929 // Store zero data Buffer Storage to EFI variable
1931 Status
= gRT
->SetVariable(
1933 &gDriverSampleFormSetGuid
,
1934 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1935 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1938 if (EFI_ERROR (Status
)) {
1939 DriverSampleUnload (ImageHandle
);
1943 // EFI variable for NV config doesn't exit, we should build this variable
1944 // based on default values stored in IFR
1946 ActionFlag
= HiiSetToDefaults (NameRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1948 DriverSampleUnload (ImageHandle
);
1949 return EFI_INVALID_PARAMETER
;
1952 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1954 DriverSampleUnload (ImageHandle
);
1955 return EFI_INVALID_PARAMETER
;
1959 // EFI variable does exist and Validate Current Setting
1961 ActionFlag
= HiiValidateSettings (NameRequestHdr
);
1963 DriverSampleUnload (ImageHandle
);
1964 return EFI_INVALID_PARAMETER
;
1967 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1969 DriverSampleUnload (ImageHandle
);
1970 return EFI_INVALID_PARAMETER
;
1973 FreePool (ConfigRequestHdr
);
1976 // Initialize efi varstore configuration data
1978 VarStoreConfig
= &mPrivateData
->VarStoreConfig
;
1979 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
1981 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
1982 ASSERT (ConfigRequestHdr
!= NULL
);
1984 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
1985 Status
= gRT
->GetVariable (MyEfiVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
1986 if (EFI_ERROR (Status
)) {
1988 // Store zero data to EFI variable Storage.
1990 Status
= gRT
->SetVariable(
1992 &gDriverSampleFormSetGuid
,
1993 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1994 sizeof (MY_EFI_VARSTORE_DATA
),
1997 if (EFI_ERROR (Status
)) {
1998 DriverSampleUnload (ImageHandle
);
2002 // EFI variable for NV config doesn't exit, we should build this variable
2003 // based on default values stored in IFR
2005 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2007 DriverSampleUnload (ImageHandle
);
2008 return EFI_INVALID_PARAMETER
;
2012 // EFI variable does exist and Validate Current Setting
2014 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2016 DriverSampleUnload (ImageHandle
);
2017 return EFI_INVALID_PARAMETER
;
2020 FreePool (ConfigRequestHdr
);
2023 // Initialize Bits efi varstore configuration data
2025 BitsVarStoreConfig
= &mPrivateData
->BitsVarStoreConfig
;
2026 ZeroMem (BitsVarStoreConfig
, sizeof (MY_EFI_BITS_VARSTORE_DATA
));
2028 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiBitVar
, DriverHandle
[0]);
2029 ASSERT (ConfigRequestHdr
!= NULL
);
2031 BufferSize
= sizeof (MY_EFI_BITS_VARSTORE_DATA
);
2032 Status
= gRT
->GetVariable (MyEfiBitVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, BitsVarStoreConfig
);
2033 if (EFI_ERROR (Status
)) {
2035 // Store zero data to EFI variable Storage.
2037 Status
= gRT
->SetVariable(
2039 &gDriverSampleFormSetGuid
,
2040 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2041 sizeof (MY_EFI_BITS_VARSTORE_DATA
),
2044 if (EFI_ERROR (Status
)) {
2045 DriverSampleUnload (ImageHandle
);
2049 // EFI variable for NV config doesn't exit, we should build this variable
2050 // based on default values stored in IFR
2052 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2054 DriverSampleUnload (ImageHandle
);
2055 return EFI_INVALID_PARAMETER
;
2059 // EFI variable does exist and Validate Current Setting
2061 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2063 DriverSampleUnload (ImageHandle
);
2064 return EFI_INVALID_PARAMETER
;
2067 FreePool (ConfigRequestHdr
);
2070 // Initialize Union efi varstore configuration data
2072 UnionConfig
= &mPrivateData
->UnionConfig
;
2073 ZeroMem (UnionConfig
, sizeof (MY_EFI_UNION_DATA
));
2075 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiUnionVar
, DriverHandle
[0]);
2076 ASSERT (ConfigRequestHdr
!= NULL
);
2078 BufferSize
= sizeof (MY_EFI_UNION_DATA
);
2079 Status
= gRT
->GetVariable (MyEfiUnionVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, UnionConfig
);
2080 if (EFI_ERROR (Status
)) {
2082 // Store zero data to EFI variable Storage.
2084 Status
= gRT
->SetVariable(
2086 &gDriverSampleFormSetGuid
,
2087 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2088 sizeof (MY_EFI_UNION_DATA
),
2091 if (EFI_ERROR (Status
)) {
2092 DriverSampleUnload (ImageHandle
);
2096 // EFI variable for NV config doesn't exit, we should build this variable
2097 // based on default values stored in IFR
2099 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2101 DriverSampleUnload (ImageHandle
);
2102 return EFI_INVALID_PARAMETER
;
2106 // EFI variable does exist and Validate Current Setting
2108 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2110 DriverSampleUnload (ImageHandle
);
2111 return EFI_INVALID_PARAMETER
;
2114 FreePool (ConfigRequestHdr
);
2116 Status
= gBS
->CreateEventEx (
2119 EfiEventEmptyFunction
,
2121 &gEfiIfrRefreshIdOpGuid
,
2124 ASSERT_EFI_ERROR (Status
);
2127 // Example of how to use BrowserEx protocol to register HotKey.
2129 Status
= gBS
->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid
, NULL
, (VOID
**) &FormBrowserEx
);
2130 if (!EFI_ERROR (Status
)) {
2132 // First unregister the default hot key F9 and F10.
2134 HotKey
.UnicodeChar
= CHAR_NULL
;
2135 HotKey
.ScanCode
= SCAN_F9
;
2136 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2137 HotKey
.ScanCode
= SCAN_F10
;
2138 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2141 // Register the default HotKey F9 and F10 again.
2143 HotKey
.ScanCode
= SCAN_F10
;
2144 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_TEN_STRING
), NULL
);
2145 ASSERT (NewString
!= NULL
);
2146 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_SUBMIT
, 0, NewString
);
2147 HotKey
.ScanCode
= SCAN_F9
;
2148 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_NINE_STRING
), NULL
);
2149 ASSERT (NewString
!= NULL
);
2150 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, NewString
);
2154 // In default, this driver is built into Flash device image,
2155 // the following code doesn't run.
2159 // Example of how to display only the item we sent to HII
2160 // When this driver is not built into Flash device image,
2161 // it need to call SendForm to show front page by itself.
2163 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2165 // Have the browser pull out our copy of the data, and only display our data
2167 Status
= FormBrowser2
->SendForm (
2169 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2177 HiiRemovePackages (HiiHandle
[0]);
2179 HiiRemovePackages (HiiHandle
[1]);
2186 Unloads the application and its installed protocol.
2188 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2190 @retval EFI_SUCCESS The image has been unloaded.
2194 DriverSampleUnload (
2195 IN EFI_HANDLE ImageHandle
2200 ASSERT (mPrivateData
!= NULL
);
2202 if (DriverHandle
[0] != NULL
) {
2203 gBS
->UninstallMultipleProtocolInterfaces (
2205 &gEfiDevicePathProtocolGuid
,
2206 &mHiiVendorDevicePath0
,
2207 &gEfiHiiConfigAccessProtocolGuid
,
2208 &mPrivateData
->ConfigAccess
,
2211 DriverHandle
[0] = NULL
;
2214 if (DriverHandle
[1] != NULL
) {
2215 gBS
->UninstallMultipleProtocolInterfaces (
2217 &gEfiDevicePathProtocolGuid
,
2218 &mHiiVendorDevicePath1
,
2219 &gEfiHiiConfigAccessProtocolGuid
,
2220 &mPrivateData
->ConfigAccess
,
2223 DriverHandle
[1] = NULL
;
2226 if (mPrivateData
->HiiHandle
[0] != NULL
) {
2227 HiiRemovePackages (mPrivateData
->HiiHandle
[0]);
2230 if (mPrivateData
->HiiHandle
[1] != NULL
) {
2231 HiiRemovePackages (mPrivateData
->HiiHandle
[1]);
2234 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2235 if (mPrivateData
->NameValueName
[Index
] != NULL
) {
2236 FreePool (mPrivateData
->NameValueName
[Index
]);
2239 FreePool (mPrivateData
);
2240 mPrivateData
= NULL
;
2242 gBS
->CloseEvent (mEvent
);