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 - 2016, 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 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
24 DRIVER_SAMPLE_PRIVATE_DATA
*mPrivateData
= NULL
;
27 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
33 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
34 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
37 DRIVER_SAMPLE_FORMSET_GUID
41 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
43 (UINT8
) (END_DEVICE_PATH_LENGTH
),
44 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
49 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
55 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
56 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
59 DRIVER_SAMPLE_INVENTORY_GUID
63 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
65 (UINT8
) (END_DEVICE_PATH_LENGTH
),
66 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
72 Set value of a data element in an Array by its Index.
74 @param Array The data array.
75 @param Type Type of the data in this array.
76 @param Index Zero based index for data in this array.
77 @param Value The value to be set.
89 ASSERT (Array
!= NULL
);
92 case EFI_IFR_TYPE_NUM_SIZE_8
:
93 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
96 case EFI_IFR_TYPE_NUM_SIZE_16
:
97 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
100 case EFI_IFR_TYPE_NUM_SIZE_32
:
101 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
104 case EFI_IFR_TYPE_NUM_SIZE_64
:
105 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
114 Add empty function for event process function.
116 @param Event The Event need to be process
117 @param Context The context of the event.
122 DriverSampleInternalEmptyFunction (
130 Notification function for keystrokes.
132 @param[in] KeyData The key that was pressed.
134 @retval EFI_SUCCESS The operation was successful.
138 NotificationFunction(
139 IN EFI_KEY_DATA
*KeyData
142 gBS
->SignalEvent (mEvent
);
148 Function to start monitoring for CTRL-C using SimpleTextInputEx.
150 @retval EFI_SUCCESS The feature is enabled.
151 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
155 InternalStartMonitor(
159 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
160 EFI_KEY_DATA KeyData
;
165 EFI_HANDLE NotifyHandle
;
167 Status
= gBS
->LocateHandleBuffer (
169 &gEfiSimpleTextInputExProtocolGuid
,
174 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
175 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
176 ASSERT_EFI_ERROR (Status
);
178 KeyData
.KeyState
.KeyToggleState
= 0;
179 KeyData
.Key
.ScanCode
= 0;
180 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
181 KeyData
.Key
.UnicodeChar
= L
'c';
183 Status
= SimpleEx
->RegisterKeyNotify(
186 NotificationFunction
,
188 if (EFI_ERROR (Status
)) {
192 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
193 Status
= SimpleEx
->RegisterKeyNotify(
196 NotificationFunction
,
198 if (EFI_ERROR (Status
)) {
207 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
209 @retval EFI_SUCCESS The feature is enabled.
210 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
218 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
221 EFI_KEY_DATA KeyData
;
224 EFI_HANDLE NotifyHandle
;
226 Status
= gBS
->LocateHandleBuffer (
228 &gEfiSimpleTextInputExProtocolGuid
,
233 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
234 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
235 ASSERT_EFI_ERROR (Status
);
237 KeyData
.KeyState
.KeyToggleState
= 0;
238 KeyData
.Key
.ScanCode
= 0;
239 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
240 KeyData
.Key
.UnicodeChar
= L
'c';
242 Status
= SimpleEx
->RegisterKeyNotify(
245 NotificationFunction
,
247 if (!EFI_ERROR (Status
)) {
248 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
251 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
252 Status
= SimpleEx
->RegisterKeyNotify(
255 NotificationFunction
,
257 if (!EFI_ERROR (Status
)) {
258 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
266 Encode the password using a simple algorithm.
268 @param Password The string to be encoded.
269 @param MaxSize The size of the string.
283 Key
= L
"MAR10648567";
284 Buffer
= AllocateZeroPool (MaxSize
);
285 ASSERT (Buffer
!= NULL
);
287 for (Index
= 0; Key
[Index
] != 0; Index
++) {
288 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
289 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
293 CopyMem (Password
, Buffer
, MaxSize
);
300 Validate the user's password.
302 @param PrivateData This driver's private context data.
303 @param StringId The user's input.
305 @retval EFI_SUCCESS The user's input matches the password.
306 @retval EFI_NOT_READY The user's input does not match the password.
310 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
311 IN EFI_STRING_ID StringId
317 UINTN PasswordMaxSize
;
319 CHAR16
*EncodedPassword
;
323 // Get encoded password first
325 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
326 Status
= gRT
->GetVariable (
328 &gDriverSampleFormSetGuid
,
331 &PrivateData
->Configuration
333 if (EFI_ERROR (Status
)) {
335 // Old password not exist, prompt for new password
341 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
343 // Check whether we have any old password set
345 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
346 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
353 // Old password not exist, return EFI_SUCCESS to prompt for new password
359 // Get user input password
361 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
362 if (Password
== NULL
) {
363 return EFI_NOT_READY
;
365 if (StrSize (Password
) > PasswordMaxSize
) {
367 return EFI_NOT_READY
;
371 // Validate old password
373 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
374 ASSERT (EncodedPassword
!= NULL
);
375 StrnCpyS (EncodedPassword
, PasswordMaxSize
/ sizeof (CHAR16
), Password
, StrLen (Password
));
376 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
377 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, PasswordMaxSize
) != 0) {
379 // Old password mismatch, return EFI_NOT_READY to prompt for error message
381 Status
= EFI_NOT_READY
;
383 Status
= EFI_SUCCESS
;
387 FreePool (EncodedPassword
);
393 Encode the password using a simple algorithm.
395 @param PrivateData This driver's private context data.
396 @param StringId The password from User.
398 @retval EFI_SUCESS The operation is successful.
399 @return Other value if gRT->SetVariable () fails.
404 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
405 IN EFI_STRING_ID StringId
410 CHAR16
*TempPassword
;
412 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
416 // Get Buffer Storage data from EFI variable
418 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
419 Status
= gRT
->GetVariable (
421 &gDriverSampleFormSetGuid
,
424 &PrivateData
->Configuration
426 if (EFI_ERROR (Status
)) {
431 // Get user input password
433 Password
= PrivateData
->Configuration
.WhatIsThePassword2
;
434 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
435 ZeroMem (Password
, PasswordSize
);
437 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
438 if (TempPassword
== NULL
) {
439 return EFI_NOT_READY
;
441 if (StrSize (TempPassword
) > PasswordSize
) {
442 FreePool (TempPassword
);
443 return EFI_NOT_READY
;
445 StrnCpyS (Password
, PasswordSize
/ sizeof (CHAR16
), TempPassword
, StrLen (TempPassword
));
446 FreePool (TempPassword
);
449 // Retrieve uncommitted data from Browser
451 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
452 ASSERT (Configuration
!= NULL
);
453 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
455 // Update password's clear text in the screen
457 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
460 // Update uncommitted data of Browser
463 &gDriverSampleFormSetGuid
,
465 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
466 (UINT8
*) Configuration
,
472 // Free Configuration Buffer
474 FreePool (Configuration
);
480 EncodePassword (Password
, StrLen (Password
) * 2);
481 Status
= gRT
->SetVariable(
483 &gDriverSampleFormSetGuid
,
484 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
485 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
486 &PrivateData
->Configuration
492 Update names of Name/Value storage to current language.
494 @param PrivateData Points to the driver private data.
496 @retval EFI_SUCCESS All names are successfully updated.
497 @retval EFI_NOT_FOUND Failed to get Name from HII database.
502 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
508 // Get Name/Value name string of current language
510 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
511 PrivateData
->NameValueName
[Index
] = HiiGetString (
512 PrivateData
->HiiHandle
[0],
513 PrivateData
->NameStringId
[Index
],
516 if (PrivateData
->NameValueName
[Index
] == NULL
) {
517 return EFI_NOT_FOUND
;
526 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
528 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
530 This is a internal function.
532 @param StringPtr String in <BlockConfig> format and points to the
533 first character of <Number>.
534 @param Number The output value. Caller takes the responsibility
536 @param Len Length of the <Number>, in characters.
538 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
540 @retval EFI_SUCCESS Value of <Number> is outputted in Number
546 IN EFI_STRING StringPtr
,
560 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
561 return EFI_INVALID_PARAMETER
;
567 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
570 *Len
= StringPtr
- TmpPtr
;
573 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
575 Status
= EFI_OUT_OF_RESOURCES
;
578 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
579 *(Str
+ *Len
) = L
'\0';
581 Length
= (Length
+ 1) / 2;
582 Buf
= (UINT8
*) AllocateZeroPool (Length
);
584 Status
= EFI_OUT_OF_RESOURCES
;
589 ZeroMem (TemStr
, sizeof (TemStr
));
590 for (Index
= 0; Index
< Length
; Index
++) {
591 TemStr
[0] = Str
[Length
- Index
- 1];
592 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
593 if ((Index
& 1) == 0) {
594 Buf
[Index
/2] = DigitUint8
;
596 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
601 Status
= EFI_SUCCESS
;
612 Create altcfg string.
614 @param Result The request result string.
615 @param ConfigHdr The request head info. <ConfigHdr> format.
616 @param Offset The offset of the parameter int he structure.
617 @param Width The width of the parameter.
620 @retval The string with altcfg info append at the end.
624 IN EFI_STRING Result
,
625 IN EFI_STRING ConfigHdr
,
630 EFI_STRING StringPtr
;
634 NewLen
= StrLen (Result
);
636 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
638 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
639 StringPtr
= AllocateZeroPool (NewLen
);
640 if (StringPtr
== NULL
) {
645 if (Result
!= NULL
) {
646 StrCpyS (StringPtr
, NewLen
/ sizeof (CHAR16
), Result
);
647 StringPtr
+= StrLen (Result
);
653 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
656 EFI_HII_DEFAULT_CLASS_STANDARD
658 StringPtr
+= StrLen (StringPtr
);
662 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
663 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
666 DEFAULT_CLASS_STANDARD_VALUE
668 StringPtr
+= StrLen (StringPtr
);
672 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
675 EFI_HII_DEFAULT_CLASS_MANUFACTURING
677 StringPtr
+= StrLen (StringPtr
);
681 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
682 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
685 DEFAULT_CLASS_MANUFACTURING_VALUE
687 StringPtr
+= StrLen (StringPtr
);
693 Check whether need to add the altcfg string. if need to add, add the altcfg
696 @param RequestResult The request result string.
697 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
702 IN OUT EFI_STRING
*RequestResult
,
703 IN EFI_STRING ConfigRequestHdr
706 EFI_STRING StringPtr
;
717 StringPtr
= *RequestResult
;
718 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
719 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
720 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
721 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
723 if (StringPtr
== NULL
) {
727 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
728 StringPtr
+= StrLen (L
"OFFSET=");
732 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
733 if (EFI_ERROR (Status
)) {
740 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
742 FreePool (TmpBuffer
);
745 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
748 StringPtr
+= StrLen (L
"&WIDTH=");
753 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
754 if (EFI_ERROR (Status
)) {
761 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
763 FreePool (TmpBuffer
);
766 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
769 StringPtr
+= StrLen (L
"&VALUE=");
774 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
775 if (EFI_ERROR (Status
)) {
781 // Skip the character "&" before "OFFSET".
786 // Calculate Value and convert it to hex string.
788 if (Offset
+ Width
> BlockSize
) {
792 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
793 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
800 This function allows a caller to extract the current configuration for one
801 or more named elements from the target driver.
803 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
804 @param Request A null-terminated Unicode string in
805 <ConfigRequest> format.
806 @param Progress On return, points to a character in the Request
807 string. Points to the string's null terminator if
808 request was successful. Points to the most recent
809 '&' before the first failing name/value pair (or
810 the beginning of the string if the failure is in
811 the first name/value pair) if the request was not
813 @param Results A null-terminated Unicode string in
814 <ConfigAltResp> format which has all values filled
815 in for the names in the Request string. String to
816 be allocated by the called function.
818 @retval EFI_SUCCESS The Results is filled with the requested values.
819 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
820 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
821 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
828 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
829 IN CONST EFI_STRING Request
,
830 OUT EFI_STRING
*Progress
,
831 OUT EFI_STRING
*Results
836 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
837 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
838 EFI_STRING ConfigRequest
;
839 EFI_STRING ConfigRequestHdr
;
845 BOOLEAN AllocatedRequest
;
847 if (Progress
== NULL
|| Results
== NULL
) {
848 return EFI_INVALID_PARAMETER
;
851 // Initialize the local variables.
853 ConfigRequestHdr
= NULL
;
854 ConfigRequest
= NULL
;
857 AllocatedRequest
= FALSE
;
859 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
860 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
863 // Get Buffer Storage data from EFI variable.
864 // Try to get the current setting from variable.
866 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
867 Status
= gRT
->GetVariable (
869 &gDriverSampleFormSetGuid
,
872 &PrivateData
->Configuration
874 if (EFI_ERROR (Status
)) {
875 return EFI_NOT_FOUND
;
878 if (Request
== NULL
) {
880 // Request is set to NULL, construct full request string.
884 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
885 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
887 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
888 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
889 ConfigRequest
= AllocateZeroPool (Size
);
890 ASSERT (ConfigRequest
!= NULL
);
891 AllocatedRequest
= TRUE
;
892 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
893 FreePool (ConfigRequestHdr
);
894 ConfigRequestHdr
= NULL
;
897 // Check routing data in <ConfigHdr>.
898 // Note: if only one Storage is used, then this checking could be skipped.
900 if (!HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, NULL
)) {
901 return EFI_NOT_FOUND
;
904 // Check whether request for EFI Varstore. EFI varstore get data
905 // through hii database, not support in this path.
907 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
908 return EFI_UNSUPPORTED
;
911 // Set Request to the unified request string.
913 ConfigRequest
= Request
;
915 // Check whether Request includes Request Element.
917 if (StrStr (Request
, L
"OFFSET") == NULL
) {
919 // Check Request Element does exist in Reques String
921 StrPointer
= StrStr (Request
, L
"PATH");
922 if (StrPointer
== NULL
) {
923 return EFI_INVALID_PARAMETER
;
925 if (StrStr (StrPointer
, L
"&") == NULL
) {
926 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
927 ConfigRequest
= AllocateZeroPool (Size
);
928 ASSERT (ConfigRequest
!= NULL
);
929 AllocatedRequest
= TRUE
;
930 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
936 // Check if requesting Name/Value storage
938 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
940 // Update Name/Value storage Names
942 Status
= LoadNameValueNames (PrivateData
);
943 if (EFI_ERROR (Status
)) {
948 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
949 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
950 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
952 BufferSize
= (StrLen (ConfigRequest
) +
953 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
954 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
955 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
956 *Results
= AllocateZeroPool (BufferSize
);
957 ASSERT (*Results
!= NULL
);
958 StrCpyS (*Results
, BufferSize
/ sizeof (CHAR16
), ConfigRequest
);
962 // Append value of NameValueVar0, type is UINT8
964 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
965 Value
+= StrLen (PrivateData
->NameValueName
[0]);
966 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
967 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
969 BackupChar
= Value
[ValueStrLen
];
971 Value
+= UnicodeValueToString (
973 PREFIX_ZERO
| RADIX_HEX
,
974 PrivateData
->Configuration
.NameValueVar0
,
975 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
981 // Append value of NameValueVar1, type is UINT16
983 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
984 Value
+= StrLen (PrivateData
->NameValueName
[1]);
985 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
986 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
988 BackupChar
= Value
[ValueStrLen
];
990 Value
+= UnicodeValueToString (
992 PREFIX_ZERO
| RADIX_HEX
,
993 PrivateData
->Configuration
.NameValueVar1
,
994 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
1000 // Append value of NameValueVar2, type is CHAR16 *
1002 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
1003 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1004 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
1005 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
1009 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1011 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1012 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
1013 Value
+= UnicodeValueToString (Value
, PREFIX_ZERO
| RADIX_HEX
, *StrPointer
, 4);
1017 Status
= EFI_SUCCESS
;
1020 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1022 Status
= HiiConfigRouting
->BlockToConfig (
1025 (UINT8
*) &PrivateData
->Configuration
,
1030 if (!EFI_ERROR (Status
)) {
1031 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
1032 AppendAltCfgString(Results
, ConfigRequestHdr
);
1037 // Free the allocated config request string.
1039 if (AllocatedRequest
) {
1040 FreePool (ConfigRequest
);
1043 if (ConfigRequestHdr
!= NULL
) {
1044 FreePool (ConfigRequestHdr
);
1047 // Set Progress string to the original request string.
1049 if (Request
== NULL
) {
1051 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1052 *Progress
= Request
+ StrLen (Request
);
1060 This function processes the results of changes in configuration.
1062 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1063 @param Configuration A null-terminated Unicode string in <ConfigResp>
1065 @param Progress A pointer to a string filled in with the offset of
1066 the most recent '&' before the first failing
1067 name/value pair (or the beginning of the string if
1068 the failure is in the first name/value pair) or
1069 the terminating NULL if all was successful.
1071 @retval EFI_SUCCESS The Results is processed successfully.
1072 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1073 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1080 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1081 IN CONST EFI_STRING Configuration
,
1082 OUT EFI_STRING
*Progress
1087 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1088 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1097 if (Configuration
== NULL
|| Progress
== NULL
) {
1098 return EFI_INVALID_PARAMETER
;
1101 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1102 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
1103 *Progress
= Configuration
;
1106 // Check routing data in <ConfigHdr>.
1107 // Note: if only one Storage is used, then this checking could be skipped.
1109 if (!HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, NULL
)) {
1110 return EFI_NOT_FOUND
;
1114 // Check whether request for EFI Varstore. EFI varstore get data
1115 // through hii database, not support in this path.
1117 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
1118 return EFI_UNSUPPORTED
;
1122 // Get Buffer Storage data from EFI variable
1124 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1125 Status
= gRT
->GetVariable (
1127 &gDriverSampleFormSetGuid
,
1130 &PrivateData
->Configuration
1132 if (EFI_ERROR (Status
)) {
1137 // Check if configuring Name/Value storage
1139 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
1141 // Update Name/Value storage Names
1143 Status
= LoadNameValueNames (PrivateData
);
1144 if (EFI_ERROR (Status
)) {
1149 // Convert value for NameValueVar0
1151 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
1155 Value
+= StrLen (PrivateData
->NameValueName
[0]);
1160 StrPtr
= StrStr (Value
, L
"&");
1161 if (StrPtr
== NULL
) {
1162 StrPtr
= Value
+ StrLen (Value
);
1165 // Convert Value to Buffer data
1167 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
1168 ZeroMem (TemStr
, sizeof (TemStr
));
1169 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1170 TemStr
[0] = *StrPtr
;
1171 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1172 if ((Index
& 1) == 0) {
1173 DataBuffer
[Index
/2] = DigitUint8
;
1175 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1181 // Convert value for NameValueVar1
1183 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
1187 Value
+= StrLen (PrivateData
->NameValueName
[1]);
1192 StrPtr
= StrStr (Value
, L
"&");
1193 if (StrPtr
== NULL
) {
1194 StrPtr
= Value
+ StrLen (Value
);
1197 // Convert Value to Buffer data
1199 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
1200 ZeroMem (TemStr
, sizeof (TemStr
));
1201 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1202 TemStr
[0] = *StrPtr
;
1203 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1204 if ((Index
& 1) == 0) {
1205 DataBuffer
[Index
/2] = DigitUint8
;
1207 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1213 // Convert value for NameValueVar2
1215 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1219 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1224 StrPtr
= StrStr (Value
, L
"&");
1225 if (StrPtr
== NULL
) {
1226 StrPtr
= Value
+ StrLen (Value
);
1229 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1231 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1232 ZeroMem (TemStr
, sizeof (TemStr
));
1233 while (Value
< StrPtr
) {
1234 StrnCpyS (TemStr
, sizeof (TemStr
) / sizeof (CHAR16
), Value
, 4);
1235 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1242 // Store Buffer Storage back to EFI variable
1244 Status
= gRT
->SetVariable(
1246 &gDriverSampleFormSetGuid
,
1247 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1248 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1249 &PrivateData
->Configuration
1256 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1258 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1259 Status
= HiiConfigRouting
->ConfigToBlock (
1262 (UINT8
*) &PrivateData
->Configuration
,
1266 if (EFI_ERROR (Status
)) {
1271 // Store Buffer Storage back to EFI variable
1273 Status
= gRT
->SetVariable(
1275 &gDriverSampleFormSetGuid
,
1276 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1277 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1278 &PrivateData
->Configuration
1286 This function processes the results of changes in configuration.
1288 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1289 @param Action Specifies the type of action taken by the browser.
1290 @param QuestionId A unique value which is sent to the original
1291 exporting driver so that it can identify the type
1293 @param Type The type of value for the question.
1294 @param Value A pointer to the data being sent to the original
1296 @param ActionRequest On return, points to the action requested by the
1299 @retval EFI_SUCCESS The callback successfully handled the action.
1300 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1301 variable and its data.
1302 @retval EFI_DEVICE_ERROR The variable could not be saved.
1303 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1310 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1311 IN EFI_BROWSER_ACTION Action
,
1312 IN EFI_QUESTION_ID QuestionId
,
1314 IN EFI_IFR_TYPE_VALUE
*Value
,
1315 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1318 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1320 VOID
*StartOpCodeHandle
;
1321 VOID
*OptionsOpCodeHandle
;
1322 EFI_IFR_GUID_LABEL
*StartLabel
;
1323 VOID
*EndOpCodeHandle
;
1324 EFI_IFR_GUID_LABEL
*EndLabel
;
1326 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1327 MY_EFI_VARSTORE_DATA
*EfiData
;
1329 EFI_STRING Progress
;
1336 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1337 (ActionRequest
== NULL
)) {
1338 return EFI_INVALID_PARAMETER
;
1344 Status
= EFI_SUCCESS
;
1346 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1349 case EFI_BROWSER_ACTION_FORM_OPEN
:
1351 if (QuestionId
== 0x1234) {
1353 // Sample CallBack for UEFI FORM_OPEN action:
1354 // Add Save action into Form 3 when Form 1 is opened.
1355 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1357 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1360 // Initialize the container for dynamic opcodes
1362 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1363 ASSERT (StartOpCodeHandle
!= NULL
);
1366 // Create Hii Extend Label OpCode as the start opcode
1368 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1369 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1370 StartLabel
->Number
= LABEL_UPDATE2
;
1372 HiiCreateActionOpCode (
1373 StartOpCodeHandle
, // Container for dynamic created opcodes
1374 0x1238, // Question ID
1375 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1376 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1377 EFI_IFR_FLAG_CALLBACK
, // Question flag
1378 0 // Action String ID
1382 PrivateData
->HiiHandle
[0], // HII handle
1383 &gDriverSampleFormSetGuid
, // Formset GUID
1385 StartOpCodeHandle
, // Label for where to insert opcodes
1389 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1392 if (QuestionId
== 0x1247) {
1393 Status
= InternalStartMonitor ();
1394 ASSERT_EFI_ERROR (Status
);
1399 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1401 if (QuestionId
== 0x5678) {
1403 // Sample CallBack for UEFI FORM_CLOSE action:
1404 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1408 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1411 L
"You are going to leave third Form!",
1412 L
"Press ESC or ENTER to continue ...",
1416 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1419 if (QuestionId
== 0x1247) {
1420 Status
= InternalStopMonitor ();
1421 ASSERT_EFI_ERROR (Status
);
1426 case EFI_BROWSER_ACTION_RETRIEVE
:
1428 switch (QuestionId
) {
1430 if (Type
!= EFI_IFR_TYPE_REF
) {
1431 return EFI_INVALID_PARAMETER
;
1433 Value
->ref
.FormId
= 0x3;
1439 // We will reach here once the Question is refreshed
1443 // Initialize the container for dynamic opcodes
1445 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1446 ASSERT (StartOpCodeHandle
!= NULL
);
1449 // Create Hii Extend Label OpCode as the start opcode
1451 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1452 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1453 if (QuestionId
== 0x5678) {
1454 StartLabel
->Number
= LABEL_UPDATE2
;
1456 PrivateData
->Configuration
.DynamicRefresh
++;
1457 } else if (QuestionId
== 0x1247 ) {
1458 StartLabel
->Number
= LABEL_UPDATE3
;
1460 PrivateData
->Configuration
.RefreshGuidCount
++;
1463 HiiCreateActionOpCode (
1464 StartOpCodeHandle
, // Container for dynamic created opcodes
1465 0x1237, // Question ID
1466 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1467 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1468 EFI_IFR_FLAG_CALLBACK
, // Question flag
1469 0 // Action String ID
1473 PrivateData
->HiiHandle
[0], // HII handle
1474 &gDriverSampleFormSetGuid
, // Formset GUID
1476 StartOpCodeHandle
, // Label for where to insert opcodes
1480 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1483 // Refresh the Question value
1485 Status
= gRT
->SetVariable(
1487 &gDriverSampleFormSetGuid
,
1488 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1489 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1490 &PrivateData
->Configuration
1493 if (QuestionId
== 0x5678) {
1495 // Update uncommitted data of Browser
1497 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1498 ASSERT (EfiData
!= NULL
);
1499 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*) EfiData
)) {
1500 EfiData
->Field8
= 111;
1502 &gDriverSampleFormSetGuid
,
1504 sizeof (MY_EFI_VARSTORE_DATA
),
1516 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1518 switch (QuestionId
) {
1520 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1524 for (Index
= 0; Index
< 3; Index
++) {
1525 SetArrayData (Value
, EFI_IFR_TYPE_NUM_SIZE_8
, Index
, BufferValue
--);
1530 Status
= EFI_UNSUPPORTED
;
1536 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1538 switch (QuestionId
) {
1540 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1544 Status
= EFI_UNSUPPORTED
;
1550 case EFI_BROWSER_ACTION_CHANGING
:
1552 switch (QuestionId
) {
1555 if (Type
!= EFI_IFR_TYPE_REF
) {
1556 return EFI_INVALID_PARAMETER
;
1559 Value
->ref
.FormId
= 0x1234;
1564 // Initialize the container for dynamic opcodes
1566 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1567 ASSERT (StartOpCodeHandle
!= NULL
);
1569 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1570 ASSERT (EndOpCodeHandle
!= NULL
);
1573 // Create Hii Extend Label OpCode as the start opcode
1575 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1576 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1577 StartLabel
->Number
= LABEL_UPDATE1
;
1580 // Create Hii Extend Label OpCode as the end opcode
1582 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1583 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1584 EndLabel
->Number
= LABEL_END
;
1586 HiiCreateActionOpCode (
1587 StartOpCodeHandle
, // Container for dynamic created opcodes
1588 0x1237, // Question ID
1589 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1590 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1591 EFI_IFR_FLAG_CALLBACK
, // Question flag
1592 0 // Action String ID
1596 // Create Option OpCode
1598 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1599 ASSERT (OptionsOpCodeHandle
!= NULL
);
1601 HiiCreateOneOfOptionOpCode (
1602 OptionsOpCodeHandle
,
1603 STRING_TOKEN (STR_BOOT_OPTION1
),
1605 EFI_IFR_NUMERIC_SIZE_1
,
1609 HiiCreateOneOfOptionOpCode (
1610 OptionsOpCodeHandle
,
1611 STRING_TOKEN (STR_BOOT_OPTION2
),
1613 EFI_IFR_NUMERIC_SIZE_1
,
1618 // Prepare initial value for the dynamic created oneof Question
1620 PrivateData
->Configuration
.DynamicOneof
= 2;
1621 Status
= gRT
->SetVariable(
1623 &gDriverSampleFormSetGuid
,
1624 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1625 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1626 &PrivateData
->Configuration
1630 // Set initial vlaue of dynamic created oneof Question in Form Browser
1632 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1633 ASSERT (Configuration
!= NULL
);
1634 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1635 Configuration
->DynamicOneof
= 2;
1638 // Update uncommitted data of Browser
1641 &gDriverSampleFormSetGuid
,
1643 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1644 (UINT8
*) Configuration
,
1648 FreePool (Configuration
);
1650 HiiCreateOneOfOpCode (
1651 StartOpCodeHandle
, // Container for dynamic created opcodes
1652 0x8001, // Question ID (or call it "key")
1653 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1654 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1655 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1656 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1657 EFI_IFR_FLAG_CALLBACK
, // Question flag
1658 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1659 OptionsOpCodeHandle
, // Option Opcode list
1660 NULL
// Default Opcode is NULl
1663 HiiCreateOrderedListOpCode (
1664 StartOpCodeHandle
, // Container for dynamic created opcodes
1665 0x8002, // Question ID
1666 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1667 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1668 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1669 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1670 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1671 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1672 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1673 5, // Maximum container
1674 OptionsOpCodeHandle
, // Option Opcode list
1675 NULL
// Default Opcode is NULl
1678 HiiCreateTextOpCode (
1680 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1681 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1682 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1685 HiiCreateDateOpCode (
1690 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1691 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1693 QF_DATE_STORAGE_TIME
,
1697 HiiCreateTimeOpCode (
1702 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1703 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1705 QF_TIME_STORAGE_TIME
,
1709 HiiCreateGotoOpCode (
1710 StartOpCodeHandle
, // Container for dynamic created opcodes
1711 1, // Target Form ID
1712 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1713 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1715 0x8003 // Question ID
1719 PrivateData
->HiiHandle
[0], // HII handle
1720 &gDriverSampleFormSetGuid
, // Formset GUID
1722 StartOpCodeHandle
, // Label for where to insert opcodes
1723 EndOpCodeHandle
// Replace data
1726 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1727 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1728 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1733 // Only used to update the state.
1735 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0) &&
1736 (PrivateData
->PasswordState
== BROWSER_STATE_SET_PASSWORD
)) {
1737 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1738 return EFI_INVALID_PARAMETER
;
1742 // When try to set a new password, user will be chanlleged with old password.
1743 // The Callback is responsible for validating old password input by user,
1744 // If Callback return EFI_SUCCESS, it indicates validation pass.
1746 switch (PrivateData
->PasswordState
) {
1747 case BROWSER_STATE_VALIDATE_PASSWORD
:
1748 Status
= ValidatePassword (PrivateData
, Value
->string
);
1749 if (Status
== EFI_SUCCESS
) {
1750 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
1754 case BROWSER_STATE_SET_PASSWORD
:
1755 Status
= SetPassword (PrivateData
, Value
->string
);
1756 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1771 case EFI_BROWSER_ACTION_CHANGED
:
1772 switch (QuestionId
) {
1775 // User press "Exit now", request Browser to exit
1777 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1782 // User press "Save now", request Browser to save the uncommitted data.
1784 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1790 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1792 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1797 // User press "Discard current form now", request Browser to discard the uncommitted data.
1799 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1804 // User press "Submit current form now", request Browser to save the uncommitted data.
1806 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1812 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1814 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1819 // 1. Check to see whether system support keyword.
1821 Status
= PrivateData
->HiiKeywordHandler
->GetData (PrivateData
->HiiKeywordHandler
,
1822 L
"NAMESPACE=x-UEFI-ns",
1823 L
"KEYWORD=iSCSIBootEnable",
1828 if (EFI_ERROR (Status
)) {
1831 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1834 L
"This system not support this keyword!",
1835 L
"Press ENTER to continue ...",
1839 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1841 Status
= EFI_SUCCESS
;
1846 // 2. If system support this keyword, just try to change value.
1850 // Change value from '0' to '1' or from '1' to '0'
1852 TmpStr
= StrStr (Results
, L
"&VALUE=");
1853 ASSERT (TmpStr
!= NULL
);
1854 TmpStr
+= StrLen (L
"&VALUE=");
1856 if (*TmpStr
== L
'0') {
1863 // 3. Call the keyword handler protocol to change the value.
1865 Status
= PrivateData
->HiiKeywordHandler
->SetData (PrivateData
->HiiKeywordHandler
,
1870 if (EFI_ERROR (Status
)) {
1873 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1876 L
"Set keyword to the system failed!",
1877 L
"Press ENTER to continue ...",
1881 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1883 Status
= EFI_SUCCESS
;
1893 case EFI_BROWSER_ACTION_SUBMITTED
:
1895 if (QuestionId
== 0x1250) {
1897 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:
1898 // Show up a pop-up to show SUBMITTED callback has been triggered.
1902 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1905 L
"EfiVarstore value has been submitted!",
1906 L
"Press ESC or ENTER to continue ...",
1910 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1916 Status
= EFI_UNSUPPORTED
;
1924 Main entry for this driver.
1926 @param ImageHandle Image handle this driver.
1927 @param SystemTable Pointer to SystemTable.
1929 @retval EFI_SUCESS This function always complete successfully.
1935 IN EFI_HANDLE ImageHandle
,
1936 IN EFI_SYSTEM_TABLE
*SystemTable
1940 EFI_HII_HANDLE HiiHandle
[2];
1941 EFI_SCREEN_DESCRIPTOR Screen
;
1942 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1943 EFI_HII_STRING_PROTOCOL
*HiiString
;
1944 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1945 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1946 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL
*HiiKeywordHandler
;
1949 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1951 EFI_STRING ConfigRequestHdr
;
1952 EFI_STRING NameRequestHdr
;
1953 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1954 EFI_INPUT_KEY HotKey
;
1955 EDKII_FORM_BROWSER_EXTENSION_PROTOCOL
*FormBrowserEx
;
1958 // Initialize the local variables.
1960 ConfigRequestHdr
= NULL
;
1964 // Initialize screen dimensions for SendForm().
1965 // Remove 3 characters from top and bottom
1967 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1968 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1971 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1974 // Initialize driver private data
1976 mPrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1977 if (mPrivateData
== NULL
) {
1978 return EFI_OUT_OF_RESOURCES
;
1981 mPrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1983 mPrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1984 mPrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1985 mPrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1986 mPrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1989 // Locate Hii Database protocol
1991 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1992 if (EFI_ERROR (Status
)) {
1995 mPrivateData
->HiiDatabase
= HiiDatabase
;
1998 // Locate HiiString protocol
2000 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
2001 if (EFI_ERROR (Status
)) {
2004 mPrivateData
->HiiString
= HiiString
;
2007 // Locate Formbrowser2 protocol
2009 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
2010 if (EFI_ERROR (Status
)) {
2013 mPrivateData
->FormBrowser2
= FormBrowser2
;
2016 // Locate ConfigRouting protocol
2018 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
2019 if (EFI_ERROR (Status
)) {
2022 mPrivateData
->HiiConfigRouting
= HiiConfigRouting
;
2025 // Locate keyword handler protocol
2027 Status
= gBS
->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid
, NULL
, (VOID
**) &HiiKeywordHandler
);
2028 if (EFI_ERROR (Status
)) {
2031 mPrivateData
->HiiKeywordHandler
= HiiKeywordHandler
;
2033 Status
= gBS
->InstallMultipleProtocolInterfaces (
2035 &gEfiDevicePathProtocolGuid
,
2036 &mHiiVendorDevicePath0
,
2037 &gEfiHiiConfigAccessProtocolGuid
,
2038 &mPrivateData
->ConfigAccess
,
2041 ASSERT_EFI_ERROR (Status
);
2043 mPrivateData
->DriverHandle
[0] = DriverHandle
[0];
2046 // Publish our HII data
2048 HiiHandle
[0] = HiiAddPackages (
2049 &gDriverSampleFormSetGuid
,
2051 DriverSampleStrings
,
2055 if (HiiHandle
[0] == NULL
) {
2056 return EFI_OUT_OF_RESOURCES
;
2059 mPrivateData
->HiiHandle
[0] = HiiHandle
[0];
2062 // Publish another Fromset
2064 Status
= gBS
->InstallMultipleProtocolInterfaces (
2066 &gEfiDevicePathProtocolGuid
,
2067 &mHiiVendorDevicePath1
,
2068 &gEfiHiiConfigAccessProtocolGuid
,
2069 &mPrivateData
->ConfigAccess
,
2072 ASSERT_EFI_ERROR (Status
);
2074 mPrivateData
->DriverHandle
[1] = DriverHandle
[1];
2076 HiiHandle
[1] = HiiAddPackages (
2077 &gDriverSampleInventoryGuid
,
2079 DriverSampleStrings
,
2083 if (HiiHandle
[1] == NULL
) {
2084 DriverSampleUnload (ImageHandle
);
2085 return EFI_OUT_OF_RESOURCES
;
2088 mPrivateData
->HiiHandle
[1] = HiiHandle
[1];
2091 // Update the device path string.
2093 NewString
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)&mHiiVendorDevicePath0
, FALSE
, FALSE
);
2094 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_DEVICE_PATH
), NewString
, NULL
) == 0) {
2095 DriverSampleUnload (ImageHandle
);
2096 return EFI_OUT_OF_RESOURCES
;
2098 if (NewString
!= NULL
) {
2099 FreePool (NewString
);
2103 // Very simple example of how one would update a string that is already
2104 // in the HII database
2106 NewString
= L
"700 Mhz";
2108 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
2109 DriverSampleUnload (ImageHandle
);
2110 return EFI_OUT_OF_RESOURCES
;
2113 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
2116 // Initialize Name/Value name String ID
2118 mPrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
2119 mPrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
2120 mPrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
2123 // Initialize configuration data
2125 Configuration
= &mPrivateData
->Configuration
;
2126 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
2129 // Try to read NV config EFI variable first
2131 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, DriverHandle
[0]);
2132 ASSERT (ConfigRequestHdr
!= NULL
);
2134 NameRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, NULL
, DriverHandle
[0]);
2135 ASSERT (NameRequestHdr
!= NULL
);
2137 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
2138 Status
= gRT
->GetVariable (VariableName
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, Configuration
);
2139 if (EFI_ERROR (Status
)) {
2141 // Store zero data Buffer Storage to EFI variable
2143 Status
= gRT
->SetVariable(
2145 &gDriverSampleFormSetGuid
,
2146 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2147 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
2150 if (EFI_ERROR (Status
)) {
2151 DriverSampleUnload (ImageHandle
);
2155 // EFI variable for NV config doesn't exit, we should build this variable
2156 // based on default values stored in IFR
2158 ActionFlag
= HiiSetToDefaults (NameRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2160 DriverSampleUnload (ImageHandle
);
2161 return EFI_INVALID_PARAMETER
;
2164 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2166 DriverSampleUnload (ImageHandle
);
2167 return EFI_INVALID_PARAMETER
;
2171 // EFI variable does exist and Validate Current Setting
2173 ActionFlag
= HiiValidateSettings (NameRequestHdr
);
2175 DriverSampleUnload (ImageHandle
);
2176 return EFI_INVALID_PARAMETER
;
2179 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2181 DriverSampleUnload (ImageHandle
);
2182 return EFI_INVALID_PARAMETER
;
2185 FreePool (ConfigRequestHdr
);
2188 // Initialize efi varstore configuration data
2190 VarStoreConfig
= &mPrivateData
->VarStoreConfig
;
2191 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
2193 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
2194 ASSERT (ConfigRequestHdr
!= NULL
);
2196 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
2197 Status
= gRT
->GetVariable (MyEfiVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
2198 if (EFI_ERROR (Status
)) {
2200 // Store zero data to EFI variable Storage.
2202 Status
= gRT
->SetVariable(
2204 &gDriverSampleFormSetGuid
,
2205 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2206 sizeof (MY_EFI_VARSTORE_DATA
),
2209 if (EFI_ERROR (Status
)) {
2210 DriverSampleUnload (ImageHandle
);
2214 // EFI variable for NV config doesn't exit, we should build this variable
2215 // based on default values stored in IFR
2217 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2219 DriverSampleUnload (ImageHandle
);
2220 return EFI_INVALID_PARAMETER
;
2224 // EFI variable does exist and Validate Current Setting
2226 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2228 DriverSampleUnload (ImageHandle
);
2229 return EFI_INVALID_PARAMETER
;
2232 FreePool (ConfigRequestHdr
);
2234 Status
= gBS
->CreateEventEx (
2237 DriverSampleInternalEmptyFunction
,
2239 &gEfiIfrRefreshIdOpGuid
,
2242 ASSERT_EFI_ERROR (Status
);
2245 // Example of how to use BrowserEx protocol to register HotKey.
2247 Status
= gBS
->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid
, NULL
, (VOID
**) &FormBrowserEx
);
2248 if (!EFI_ERROR (Status
)) {
2250 // First unregister the default hot key F9 and F10.
2252 HotKey
.UnicodeChar
= CHAR_NULL
;
2253 HotKey
.ScanCode
= SCAN_F9
;
2254 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2255 HotKey
.ScanCode
= SCAN_F10
;
2256 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2259 // Register the default HotKey F9 and F10 again.
2261 HotKey
.ScanCode
= SCAN_F10
;
2262 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_TEN_STRING
), NULL
);
2263 ASSERT (NewString
!= NULL
);
2264 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_SUBMIT
, 0, NewString
);
2265 HotKey
.ScanCode
= SCAN_F9
;
2266 NewString
= HiiGetString (mPrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_NINE_STRING
), NULL
);
2267 ASSERT (NewString
!= NULL
);
2268 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, NewString
);
2272 // In default, this driver is built into Flash device image,
2273 // the following code doesn't run.
2277 // Example of how to display only the item we sent to HII
2278 // When this driver is not built into Flash device image,
2279 // it need to call SendForm to show front page by itself.
2281 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2283 // Have the browser pull out our copy of the data, and only display our data
2285 Status
= FormBrowser2
->SendForm (
2287 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2295 HiiRemovePackages (HiiHandle
[0]);
2297 HiiRemovePackages (HiiHandle
[1]);
2304 Unloads the application and its installed protocol.
2306 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2308 @retval EFI_SUCCESS The image has been unloaded.
2312 DriverSampleUnload (
2313 IN EFI_HANDLE ImageHandle
2318 ASSERT (mPrivateData
!= NULL
);
2320 if (DriverHandle
[0] != NULL
) {
2321 gBS
->UninstallMultipleProtocolInterfaces (
2323 &gEfiDevicePathProtocolGuid
,
2324 &mHiiVendorDevicePath0
,
2325 &gEfiHiiConfigAccessProtocolGuid
,
2326 &mPrivateData
->ConfigAccess
,
2329 DriverHandle
[0] = NULL
;
2332 if (DriverHandle
[1] != NULL
) {
2333 gBS
->UninstallMultipleProtocolInterfaces (
2335 &gEfiDevicePathProtocolGuid
,
2336 &mHiiVendorDevicePath1
,
2337 &gEfiHiiConfigAccessProtocolGuid
,
2338 &mPrivateData
->ConfigAccess
,
2341 DriverHandle
[1] = NULL
;
2344 if (mPrivateData
->HiiHandle
[0] != NULL
) {
2345 HiiRemovePackages (mPrivateData
->HiiHandle
[0]);
2348 if (mPrivateData
->HiiHandle
[1] != NULL
) {
2349 HiiRemovePackages (mPrivateData
->HiiHandle
[1]);
2352 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2353 if (mPrivateData
->NameValueName
[Index
] != NULL
) {
2354 FreePool (mPrivateData
->NameValueName
[Index
]);
2357 FreePool (mPrivateData
);
2358 mPrivateData
= NULL
;
2360 gBS
->CloseEvent (mEvent
);