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 - 2011, 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 EFI_GUID mFormSetGuid
= FORMSET_GUID
;
22 EFI_GUID mInventoryGuid
= INVENTORY_GUID
;
23 EFI_GUID MyEventGroupGuid
= EFI_IFR_REFRESH_ID_OP_GUID
;
25 CHAR16 VariableName
[] = L
"MyIfrNVData";
26 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
27 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
= NULL
;
30 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
36 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
37 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
41 // {C153B68D-EBFC-488e-B110-662867745B87}
43 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }
47 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 (UINT8
) (END_DEVICE_PATH_LENGTH
),
50 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
55 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
61 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
62 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
66 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}
68 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }
72 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
74 (UINT8
) (END_DEVICE_PATH_LENGTH
),
75 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
81 Add empty function for event process function.
83 @param Event The Event need to be process
84 @param Context The context of the event.
89 DriverSampleInternalEmptyFunction (
97 Notification function for keystrokes.
99 @param[in] KeyData The key that was pressed.
101 @retval EFI_SUCCESS The operation was successful.
105 NotificationFunction(
106 IN EFI_KEY_DATA
*KeyData
109 gBS
->SignalEvent (mEvent
);
115 Function to start monitoring for CTRL-C using SimpleTextInputEx.
117 @retval EFI_SUCCESS The feature is enabled.
118 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
122 InternalStartMonitor(
126 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
127 EFI_KEY_DATA KeyData
;
132 EFI_HANDLE NotifyHandle
;
134 Status
= gBS
->LocateHandleBuffer (
136 &gEfiSimpleTextInputExProtocolGuid
,
141 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
142 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
143 ASSERT_EFI_ERROR (Status
);
145 KeyData
.KeyState
.KeyToggleState
= 0;
146 KeyData
.Key
.ScanCode
= 0;
147 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
148 KeyData
.Key
.UnicodeChar
= L
'c';
150 Status
= SimpleEx
->RegisterKeyNotify(
153 NotificationFunction
,
155 if (EFI_ERROR (Status
)) {
159 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
160 Status
= SimpleEx
->RegisterKeyNotify(
163 NotificationFunction
,
165 if (EFI_ERROR (Status
)) {
174 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
176 @retval EFI_SUCCESS The feature is enabled.
177 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
185 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
188 EFI_KEY_DATA KeyData
;
191 EFI_HANDLE NotifyHandle
;
193 Status
= gBS
->LocateHandleBuffer (
195 &gEfiSimpleTextInputExProtocolGuid
,
200 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
201 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
202 ASSERT_EFI_ERROR (Status
);
204 KeyData
.KeyState
.KeyToggleState
= 0;
205 KeyData
.Key
.ScanCode
= 0;
206 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
207 KeyData
.Key
.UnicodeChar
= L
'c';
209 Status
= SimpleEx
->RegisterKeyNotify(
212 NotificationFunction
,
214 if (!EFI_ERROR (Status
)) {
215 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
218 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
219 Status
= SimpleEx
->RegisterKeyNotify(
222 NotificationFunction
,
224 if (!EFI_ERROR (Status
)) {
225 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
233 Encode the password using a simple algorithm.
235 @param Password The string to be encoded.
236 @param MaxSize The size of the string.
250 Key
= L
"MAR10648567";
251 Buffer
= AllocateZeroPool (MaxSize
);
252 ASSERT (Buffer
!= NULL
);
254 for (Index
= 0; Key
[Index
] != 0; Index
++) {
255 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
256 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
260 CopyMem (Password
, Buffer
, MaxSize
);
267 Validate the user's password.
269 @param PrivateData This driver's private context data.
270 @param StringId The user's input.
272 @retval EFI_SUCCESS The user's input matches the password.
273 @retval EFI_NOT_READY The user's input does not match the password.
277 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
278 IN EFI_STRING_ID StringId
284 UINTN PasswordMaxSize
;
286 CHAR16
*EncodedPassword
;
290 // Get encoded password first
292 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
293 Status
= gRT
->GetVariable (
298 &PrivateData
->Configuration
300 if (EFI_ERROR (Status
)) {
302 // Old password not exist, prompt for new password
308 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
310 // Check whether we have any old password set
312 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
313 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
320 // Old password not exist, return EFI_SUCCESS to prompt for new password
326 // Get user input password
328 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
329 if (Password
== NULL
) {
330 return EFI_NOT_READY
;
332 if (StrSize (Password
) > PasswordMaxSize
) {
334 return EFI_NOT_READY
;
338 // Validate old password
340 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
341 ASSERT (EncodedPassword
!= NULL
);
342 StrnCpy (EncodedPassword
, Password
, StrLen (Password
));
343 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
344 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, PasswordMaxSize
) != 0) {
346 // Old password mismatch, return EFI_NOT_READY to prompt for error message
348 Status
= EFI_NOT_READY
;
350 Status
= EFI_SUCCESS
;
354 FreePool (EncodedPassword
);
360 Encode the password using a simple algorithm.
362 @param PrivateData This driver's private context data.
363 @param StringId The password from User.
365 @retval EFI_SUCESS The operation is successful.
366 @return Other value if gRT->SetVariable () fails.
371 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
372 IN EFI_STRING_ID StringId
377 CHAR16
*TempPassword
;
379 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
383 // Get Buffer Storage data from EFI variable
385 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
386 Status
= gRT
->GetVariable (
391 &PrivateData
->Configuration
393 if (EFI_ERROR (Status
)) {
398 // Get user input password
400 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
401 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
402 ZeroMem (Password
, PasswordSize
);
404 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
405 if (TempPassword
== NULL
) {
406 return EFI_NOT_READY
;
408 if (StrSize (TempPassword
) > PasswordSize
) {
409 FreePool (TempPassword
);
410 return EFI_NOT_READY
;
412 StrnCpy (Password
, TempPassword
, StrLen (TempPassword
));
413 FreePool (TempPassword
);
416 // Retrive uncommitted data from Browser
418 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
419 ASSERT (Configuration
!= NULL
);
420 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
422 // Update password's clear text in the screen
424 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
427 // Update uncommitted data of Browser
432 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
433 (UINT8
*) Configuration
,
439 // Free Configuration Buffer
441 FreePool (Configuration
);
447 EncodePassword (Password
, StrLen (Password
) * 2);
448 Status
= gRT
->SetVariable(
451 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
452 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
453 &PrivateData
->Configuration
459 Update names of Name/Value storage to current language.
461 @param PrivateData Points to the driver private data.
463 @retval EFI_SUCCESS All names are successfully updated.
464 @retval EFI_NOT_FOUND Failed to get Name from HII database.
469 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
475 // Get Name/Value name string of current language
477 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
478 PrivateData
->NameValueName
[Index
] = HiiGetString (
479 PrivateData
->HiiHandle
[0],
480 PrivateData
->NameStringId
[Index
],
483 if (PrivateData
->NameValueName
[Index
] == NULL
) {
484 return EFI_NOT_FOUND
;
493 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
495 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
497 This is a internal function.
499 @param StringPtr String in <BlockConfig> format and points to the
500 first character of <Number>.
501 @param Number The output value. Caller takes the responsibility
503 @param Len Length of the <Number>, in characters.
505 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
507 @retval EFI_SUCCESS Value of <Number> is outputted in Number
513 IN EFI_STRING StringPtr
,
527 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
528 return EFI_INVALID_PARAMETER
;
534 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
537 *Len
= StringPtr
- TmpPtr
;
540 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
542 Status
= EFI_OUT_OF_RESOURCES
;
545 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
546 *(Str
+ *Len
) = L
'\0';
548 Length
= (Length
+ 1) / 2;
549 Buf
= (UINT8
*) AllocateZeroPool (Length
);
551 Status
= EFI_OUT_OF_RESOURCES
;
556 ZeroMem (TemStr
, sizeof (TemStr
));
557 for (Index
= 0; Index
< Length
; Index
++) {
558 TemStr
[0] = Str
[Length
- Index
- 1];
559 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
560 if ((Index
& 1) == 0) {
561 Buf
[Index
/2] = DigitUint8
;
563 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
568 Status
= EFI_SUCCESS
;
579 Create altcfg string.
581 @param Result The request result string.
582 @param ConfigHdr The request head info. <ConfigHdr> format.
583 @param Offset The offset of the parameter int he structure.
584 @param Width The width of the parameter.
587 @retval The string with altcfg info append at the end.
591 IN EFI_STRING Result
,
592 IN EFI_STRING ConfigHdr
,
597 EFI_STRING StringPtr
;
601 NewLen
= StrLen (Result
);
603 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
605 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
606 StringPtr
= AllocateZeroPool (NewLen
);
607 if (StringPtr
== NULL
) {
612 if (Result
!= NULL
) {
613 StrCpy (StringPtr
, Result
);
614 StringPtr
+= StrLen (Result
);
620 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
623 EFI_HII_DEFAULT_CLASS_STANDARD
625 StringPtr
+= StrLen (StringPtr
);
629 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
630 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
633 DEFAULT_CLASS_STANDARD_VALUE
635 StringPtr
+= StrLen (StringPtr
);
639 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
642 EFI_HII_DEFAULT_CLASS_MANUFACTURING
644 StringPtr
+= StrLen (StringPtr
);
648 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
649 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
652 DEFAULT_CLASS_MANUFACTURING_VALUE
654 StringPtr
+= StrLen (StringPtr
);
660 Check whether need to add the altcfg string. if need to add, add the altcfg
663 @param RequestResult The request result string.
664 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
669 IN OUT EFI_STRING
*RequestResult
,
670 IN EFI_STRING ConfigRequestHdr
673 EFI_STRING StringPtr
;
684 StringPtr
= *RequestResult
;
685 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
686 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
687 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
688 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
690 if (StringPtr
== NULL
) {
694 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
696 // Back up the header of one <BlockName>
700 StringPtr
+= StrLen (L
"OFFSET=");
704 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
705 if (EFI_ERROR (Status
)) {
712 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
714 FreePool (TmpBuffer
);
717 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
720 StringPtr
+= StrLen (L
"&WIDTH=");
725 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
726 if (EFI_ERROR (Status
)) {
733 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
735 FreePool (TmpBuffer
);
738 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
741 StringPtr
+= StrLen (L
"&VALUE=");
746 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
747 if (EFI_ERROR (Status
)) {
753 // Calculate Value and convert it to hex string.
755 if (Offset
+ Width
> BlockSize
) {
759 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
760 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
767 This function allows a caller to extract the current configuration for one
768 or more named elements from the target driver.
770 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
771 @param Request A null-terminated Unicode string in
772 <ConfigRequest> format.
773 @param Progress On return, points to a character in the Request
774 string. Points to the string's null terminator if
775 request was successful. Points to the most recent
776 '&' before the first failing name/value pair (or
777 the beginning of the string if the failure is in
778 the first name/value pair) if the request was not
780 @param Results A null-terminated Unicode string in
781 <ConfigAltResp> format which has all values filled
782 in for the names in the Request string. String to
783 be allocated by the called function.
785 @retval EFI_SUCCESS The Results is filled with the requested values.
786 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
787 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
788 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
795 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
796 IN CONST EFI_STRING Request
,
797 OUT EFI_STRING
*Progress
,
798 OUT EFI_STRING
*Results
803 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
804 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
805 EFI_STRING ConfigRequest
;
806 EFI_STRING ConfigRequestHdr
;
812 BOOLEAN AllocatedRequest
;
814 if (Progress
== NULL
|| Results
== NULL
) {
815 return EFI_INVALID_PARAMETER
;
818 // Initialize the local variables.
820 ConfigRequestHdr
= NULL
;
821 ConfigRequest
= NULL
;
824 AllocatedRequest
= FALSE
;
826 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
827 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
830 // Get Buffer Storage data from EFI variable.
831 // Try to get the current setting from variable.
833 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
834 Status
= gRT
->GetVariable (
839 &PrivateData
->Configuration
841 if (EFI_ERROR (Status
)) {
842 return EFI_NOT_FOUND
;
845 if (Request
== NULL
) {
847 // Request is set to NULL, construct full request string.
851 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
852 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
854 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
855 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
856 ConfigRequest
= AllocateZeroPool (Size
);
857 ASSERT (ConfigRequest
!= NULL
);
858 AllocatedRequest
= TRUE
;
859 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
860 FreePool (ConfigRequestHdr
);
861 ConfigRequestHdr
= NULL
;
864 // Check routing data in <ConfigHdr>.
865 // Note: if only one Storage is used, then this checking could be skipped.
867 if (!HiiIsConfigHdrMatch (Request
, &mFormSetGuid
, NULL
)) {
868 return EFI_NOT_FOUND
;
871 // Set Request to the unified request string.
873 ConfigRequest
= Request
;
875 // Check whether Request includes Request Element.
877 if (StrStr (Request
, L
"OFFSET") == NULL
) {
879 // Check Request Element does exist in Reques String
881 StrPointer
= StrStr (Request
, L
"PATH");
882 if (StrPointer
== NULL
) {
883 return EFI_INVALID_PARAMETER
;
885 if (StrStr (StrPointer
, L
"&") == NULL
) {
886 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
887 ConfigRequest
= AllocateZeroPool (Size
);
888 ASSERT (ConfigRequest
!= NULL
);
889 AllocatedRequest
= TRUE
;
890 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
896 // Check if requesting Name/Value storage
898 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
900 // Update Name/Value storage Names
902 Status
= LoadNameValueNames (PrivateData
);
903 if (EFI_ERROR (Status
)) {
908 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
909 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
910 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
912 BufferSize
= (StrLen (ConfigRequest
) +
913 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
914 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
915 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
916 *Results
= AllocateZeroPool (BufferSize
);
917 ASSERT (*Results
!= NULL
);
918 StrCpy (*Results
, ConfigRequest
);
922 // Append value of NameValueVar0, type is UINT8
924 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
925 Value
+= StrLen (PrivateData
->NameValueName
[0]);
926 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
927 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
929 BackupChar
= Value
[ValueStrLen
];
931 Value
+= UnicodeValueToString (
933 PREFIX_ZERO
| RADIX_HEX
,
934 PrivateData
->Configuration
.NameValueVar0
,
935 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
941 // Append value of NameValueVar1, type is UINT16
943 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
944 Value
+= StrLen (PrivateData
->NameValueName
[1]);
945 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
946 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
948 BackupChar
= Value
[ValueStrLen
];
950 Value
+= UnicodeValueToString (
952 PREFIX_ZERO
| RADIX_HEX
,
953 PrivateData
->Configuration
.NameValueVar1
,
954 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
960 // Append value of NameValueVar2, type is CHAR16 *
962 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
963 Value
+= StrLen (PrivateData
->NameValueName
[2]);
964 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
965 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
969 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
971 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
972 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
973 Value
+= UnicodeValueToString (Value
, PREFIX_ZERO
| RADIX_HEX
, *StrPointer
, 4);
977 Status
= EFI_SUCCESS
;
980 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
982 Status
= HiiConfigRouting
->BlockToConfig (
985 (UINT8
*) &PrivateData
->Configuration
,
990 if (!EFI_ERROR (Status
)) {
991 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
992 AppendAltCfgString(Results
, ConfigRequestHdr
);
997 // Free the allocated config request string.
999 if (AllocatedRequest
) {
1000 FreePool (ConfigRequest
);
1003 if (ConfigRequestHdr
!= NULL
) {
1004 FreePool (ConfigRequestHdr
);
1007 // Set Progress string to the original request string.
1009 if (Request
== NULL
) {
1011 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1012 *Progress
= Request
+ StrLen (Request
);
1020 This function processes the results of changes in configuration.
1022 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1023 @param Configuration A null-terminated Unicode string in <ConfigResp>
1025 @param Progress A pointer to a string filled in with the offset of
1026 the most recent '&' before the first failing
1027 name/value pair (or the beginning of the string if
1028 the failure is in the first name/value pair) or
1029 the terminating NULL if all was successful.
1031 @retval EFI_SUCCESS The Results is processed successfully.
1032 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1033 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1040 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1041 IN CONST EFI_STRING Configuration
,
1042 OUT EFI_STRING
*Progress
1047 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1048 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1057 if (Configuration
== NULL
|| Progress
== NULL
) {
1058 return EFI_INVALID_PARAMETER
;
1061 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1062 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
1063 *Progress
= Configuration
;
1066 // Check routing data in <ConfigHdr>.
1067 // Note: if only one Storage is used, then this checking could be skipped.
1069 if (!HiiIsConfigHdrMatch (Configuration
, &mFormSetGuid
, NULL
)) {
1070 return EFI_NOT_FOUND
;
1074 // Get Buffer Storage data from EFI variable
1076 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1077 Status
= gRT
->GetVariable (
1082 &PrivateData
->Configuration
1084 if (EFI_ERROR (Status
)) {
1089 // Check if configuring Name/Value storage
1091 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
1093 // Update Name/Value storage Names
1095 Status
= LoadNameValueNames (PrivateData
);
1096 if (EFI_ERROR (Status
)) {
1101 // Convert value for NameValueVar0
1103 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
1107 Value
+= StrLen (PrivateData
->NameValueName
[0]);
1112 StrPtr
= StrStr (Value
, L
"&");
1113 if (StrPtr
== NULL
) {
1114 StrPtr
= Value
+ StrLen (Value
);
1117 // Convert Value to Buffer data
1119 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
1120 ZeroMem (TemStr
, sizeof (TemStr
));
1121 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1122 TemStr
[0] = *StrPtr
;
1123 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1124 if ((Index
& 1) == 0) {
1125 DataBuffer
[Index
/2] = DigitUint8
;
1127 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1133 // Convert value for NameValueVar1
1135 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
1139 Value
+= StrLen (PrivateData
->NameValueName
[1]);
1144 StrPtr
= StrStr (Value
, L
"&");
1145 if (StrPtr
== NULL
) {
1146 StrPtr
= Value
+ StrLen (Value
);
1149 // Convert Value to Buffer data
1151 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
1152 ZeroMem (TemStr
, sizeof (TemStr
));
1153 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1154 TemStr
[0] = *StrPtr
;
1155 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1156 if ((Index
& 1) == 0) {
1157 DataBuffer
[Index
/2] = DigitUint8
;
1159 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1165 // Convert value for NameValueVar2
1167 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1171 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1176 StrPtr
= StrStr (Value
, L
"&");
1177 if (StrPtr
== NULL
) {
1178 StrPtr
= Value
+ StrLen (Value
);
1181 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1183 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1184 ZeroMem (TemStr
, sizeof (TemStr
));
1185 while (Value
< StrPtr
) {
1186 StrnCpy (TemStr
, Value
, 4);
1187 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1194 // Store Buffer Storage back to EFI variable
1196 Status
= gRT
->SetVariable(
1199 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1200 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1201 &PrivateData
->Configuration
1208 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1210 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1211 Status
= HiiConfigRouting
->ConfigToBlock (
1214 (UINT8
*) &PrivateData
->Configuration
,
1218 if (EFI_ERROR (Status
)) {
1223 // Store Buffer Storage back to EFI variable
1225 Status
= gRT
->SetVariable(
1228 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1229 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1230 &PrivateData
->Configuration
1238 This function processes the results of changes in configuration.
1240 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1241 @param Action Specifies the type of action taken by the browser.
1242 @param QuestionId A unique value which is sent to the original
1243 exporting driver so that it can identify the type
1245 @param Type The type of value for the question.
1246 @param Value A pointer to the data being sent to the original
1248 @param ActionRequest On return, points to the action requested by the
1251 @retval EFI_SUCCESS The callback successfully handled the action.
1252 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1253 variable and its data.
1254 @retval EFI_DEVICE_ERROR The variable could not be saved.
1255 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1262 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1263 IN EFI_BROWSER_ACTION Action
,
1264 IN EFI_QUESTION_ID QuestionId
,
1266 IN EFI_IFR_TYPE_VALUE
*Value
,
1267 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1270 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1273 VOID
*StartOpCodeHandle
;
1274 VOID
*OptionsOpCodeHandle
;
1275 EFI_IFR_GUID_LABEL
*StartLabel
;
1276 VOID
*EndOpCodeHandle
;
1277 EFI_IFR_GUID_LABEL
*EndLabel
;
1279 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1283 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1284 (ActionRequest
== NULL
)) {
1285 return EFI_INVALID_PARAMETER
;
1290 Status
= EFI_SUCCESS
;
1291 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1294 case EFI_BROWSER_ACTION_FORM_OPEN
:
1296 if (QuestionId
== 0x1234) {
1298 // Sample CallBack for UEFI FORM_OPEN action:
1299 // Add Save action into Form 3 when Form 1 is opened.
1300 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1302 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1305 // Initialize the container for dynamic opcodes
1307 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1308 ASSERT (StartOpCodeHandle
!= NULL
);
1311 // Create Hii Extend Label OpCode as the start opcode
1313 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1314 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1315 StartLabel
->Number
= LABEL_UPDATE2
;
1317 HiiCreateActionOpCode (
1318 StartOpCodeHandle
, // Container for dynamic created opcodes
1319 0x1238, // Question ID
1320 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1321 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1322 EFI_IFR_FLAG_CALLBACK
, // Question flag
1323 0 // Action String ID
1327 PrivateData
->HiiHandle
[0], // HII handle
1328 &mFormSetGuid
, // Formset GUID
1330 StartOpCodeHandle
, // Label for where to insert opcodes
1334 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1337 if (QuestionId
== 0x1247) {
1338 Status
= InternalStartMonitor ();
1339 ASSERT_EFI_ERROR (Status
);
1344 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1346 if (QuestionId
== 0x5678) {
1348 // Sample CallBack for UEFI FORM_CLOSE action:
1349 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1353 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1356 L
"You are going to leave third Form!",
1357 L
"Press ESC or ENTER to continue ...",
1361 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1364 if (QuestionId
== 0x1247) {
1365 Status
= InternalStopMonitor ();
1366 ASSERT_EFI_ERROR (Status
);
1371 case EFI_BROWSER_ACTION_RETRIEVE
:
1373 if (QuestionId
== 0x1111) {
1375 // EfiVarstore question takes sample action (print value as debug information)
1376 // after read/write question.
1379 Status
= gRT
->GetVariable(
1386 ASSERT_EFI_ERROR (Status
);
1387 DEBUG ((DEBUG_INFO
, "EfiVarstore question: Tall value is %d with value width %d\n", MyVar
, MyVarSize
));
1392 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1394 switch (QuestionId
) {
1396 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1400 Status
= EFI_UNSUPPORTED
;
1406 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1408 switch (QuestionId
) {
1410 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1414 Status
= EFI_UNSUPPORTED
;
1420 case EFI_BROWSER_ACTION_CHANGING
:
1422 switch (QuestionId
) {
1425 // Initialize the container for dynamic opcodes
1427 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1428 ASSERT (StartOpCodeHandle
!= NULL
);
1430 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1431 ASSERT (EndOpCodeHandle
!= NULL
);
1434 // Create Hii Extend Label OpCode as the start opcode
1436 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1437 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1438 StartLabel
->Number
= LABEL_UPDATE1
;
1441 // Create Hii Extend Label OpCode as the end opcode
1443 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1444 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1445 EndLabel
->Number
= LABEL_END
;
1447 HiiCreateActionOpCode (
1448 StartOpCodeHandle
, // Container for dynamic created opcodes
1449 0x1237, // Question ID
1450 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1451 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1452 EFI_IFR_FLAG_CALLBACK
, // Question flag
1453 0 // Action String ID
1457 // Create Option OpCode
1459 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1460 ASSERT (OptionsOpCodeHandle
!= NULL
);
1462 HiiCreateOneOfOptionOpCode (
1463 OptionsOpCodeHandle
,
1464 STRING_TOKEN (STR_BOOT_OPTION1
),
1466 EFI_IFR_NUMERIC_SIZE_1
,
1470 HiiCreateOneOfOptionOpCode (
1471 OptionsOpCodeHandle
,
1472 STRING_TOKEN (STR_BOOT_OPTION2
),
1474 EFI_IFR_NUMERIC_SIZE_1
,
1479 // Prepare initial value for the dynamic created oneof Question
1481 PrivateData
->Configuration
.DynamicOneof
= 2;
1482 Status
= gRT
->SetVariable(
1485 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1486 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1487 &PrivateData
->Configuration
1491 // Set initial vlaue of dynamic created oneof Question in Form Browser
1493 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1494 ASSERT (Configuration
!= NULL
);
1495 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1496 Configuration
->DynamicOneof
= 2;
1499 // Update uncommitted data of Browser
1504 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1505 (UINT8
*) Configuration
,
1509 FreePool (Configuration
);
1511 HiiCreateOneOfOpCode (
1512 StartOpCodeHandle
, // Container for dynamic created opcodes
1513 0x8001, // Question ID (or call it "key")
1514 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1515 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1516 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1517 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1518 EFI_IFR_FLAG_CALLBACK
, // Question flag
1519 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1520 OptionsOpCodeHandle
, // Option Opcode list
1521 NULL
// Default Opcode is NULl
1524 HiiCreateOrderedListOpCode (
1525 StartOpCodeHandle
, // Container for dynamic created opcodes
1526 0x8002, // Question ID
1527 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1528 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1529 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1530 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1531 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1532 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1533 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1534 5, // Maximum container
1535 OptionsOpCodeHandle
, // Option Opcode list
1536 NULL
// Default Opcode is NULl
1539 HiiCreateTextOpCode (
1541 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1542 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1543 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1546 HiiCreateDateOpCode (
1551 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1552 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1554 QF_DATE_STORAGE_TIME
,
1558 HiiCreateTimeOpCode (
1563 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1564 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1566 QF_TIME_STORAGE_TIME
,
1570 HiiCreateGotoOpCode (
1571 StartOpCodeHandle
, // Container for dynamic created opcodes
1572 1, // Target Form ID
1573 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1574 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1576 0x8003 // Question ID
1580 PrivateData
->HiiHandle
[0], // HII handle
1581 &mFormSetGuid
, // Formset GUID
1583 StartOpCodeHandle
, // Label for where to insert opcodes
1584 EndOpCodeHandle
// Replace data
1587 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1588 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1589 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1595 // We will reach here once the Question is refreshed
1599 // Initialize the container for dynamic opcodes
1601 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1602 ASSERT (StartOpCodeHandle
!= NULL
);
1605 // Create Hii Extend Label OpCode as the start opcode
1607 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1608 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1609 if (QuestionId
== 0x5678) {
1610 StartLabel
->Number
= LABEL_UPDATE2
;
1612 PrivateData
->Configuration
.DynamicRefresh
++;
1613 } else if (QuestionId
== 0x1247 ) {
1614 StartLabel
->Number
= LABEL_UPDATE3
;
1616 PrivateData
->Configuration
.RefreshGuidCount
++;
1619 HiiCreateActionOpCode (
1620 StartOpCodeHandle
, // Container for dynamic created opcodes
1621 0x1237, // Question ID
1622 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1623 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1624 EFI_IFR_FLAG_CALLBACK
, // Question flag
1625 0 // Action String ID
1629 PrivateData
->HiiHandle
[0], // HII handle
1630 &mFormSetGuid
, // Formset GUID
1632 StartOpCodeHandle
, // Label for where to insert opcodes
1636 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1639 // Refresh the Question value
1641 Status
= gRT
->SetVariable(
1644 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1645 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1646 &PrivateData
->Configuration
1649 if (QuestionId
== 0x5678) {
1651 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
1652 // the first statement in Form 3 be suppressed
1656 Status
= gRT
->SetVariable(
1659 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1668 // User press "Exit now", request Browser to exit
1670 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1675 // User press "Save now", request Browser to save the uncommitted data.
1677 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1683 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1685 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1690 // User press "Discard current form now", request Browser to discard the uncommitted data.
1692 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1697 // User press "Submit current form now", request Browser to save the uncommitted data.
1699 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1705 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1707 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1712 // Only used to update the state.
1714 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0) &&
1715 (PrivateData
->PasswordState
== BROWSER_STATE_SET_PASSWORD
)) {
1716 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1717 return EFI_INVALID_PARAMETER
;
1721 // When try to set a new password, user will be chanlleged with old password.
1722 // The Callback is responsible for validating old password input by user,
1723 // If Callback return EFI_SUCCESS, it indicates validation pass.
1725 switch (PrivateData
->PasswordState
) {
1726 case BROWSER_STATE_VALIDATE_PASSWORD
:
1727 Status
= ValidatePassword (PrivateData
, Value
->string
);
1728 if (Status
== EFI_SUCCESS
) {
1729 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
1733 case BROWSER_STATE_SET_PASSWORD
:
1734 Status
= SetPassword (PrivateData
, Value
->string
);
1735 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1746 // EfiVarstore question takes sample action (print value as debug information)
1747 // after read/write question.
1750 Status
= gRT
->GetVariable(
1757 ASSERT_EFI_ERROR (Status
);
1758 DEBUG ((DEBUG_INFO
, "EfiVarstore question: Tall value is %d with value width %d\n", MyVar
, MyVarSize
));
1766 Status
= EFI_UNSUPPORTED
;
1774 Main entry for this driver.
1776 @param ImageHandle Image handle this driver.
1777 @param SystemTable Pointer to SystemTable.
1779 @retval EFI_SUCESS This function always complete successfully.
1785 IN EFI_HANDLE ImageHandle
,
1786 IN EFI_SYSTEM_TABLE
*SystemTable
1790 EFI_HII_HANDLE HiiHandle
[2];
1791 EFI_SCREEN_DESCRIPTOR Screen
;
1792 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1793 EFI_HII_STRING_PROTOCOL
*HiiString
;
1794 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1795 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1798 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1800 EFI_STRING ConfigRequestHdr
;
1803 // Initialize the local variables.
1805 ConfigRequestHdr
= NULL
;
1807 // Initialize screen dimensions for SendForm().
1808 // Remove 3 characters from top and bottom
1810 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1811 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1814 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1817 // Initialize driver private data
1819 PrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1820 if (PrivateData
== NULL
) {
1821 return EFI_OUT_OF_RESOURCES
;
1824 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1826 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1827 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1828 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1829 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1832 // Locate Hii Database protocol
1834 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1835 if (EFI_ERROR (Status
)) {
1838 PrivateData
->HiiDatabase
= HiiDatabase
;
1841 // Locate HiiString protocol
1843 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1844 if (EFI_ERROR (Status
)) {
1847 PrivateData
->HiiString
= HiiString
;
1850 // Locate Formbrowser2 protocol
1852 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1853 if (EFI_ERROR (Status
)) {
1856 PrivateData
->FormBrowser2
= FormBrowser2
;
1859 // Locate ConfigRouting protocol
1861 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1862 if (EFI_ERROR (Status
)) {
1865 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1867 Status
= gBS
->InstallMultipleProtocolInterfaces (
1869 &gEfiDevicePathProtocolGuid
,
1870 &mHiiVendorDevicePath0
,
1871 &gEfiHiiConfigAccessProtocolGuid
,
1872 &PrivateData
->ConfigAccess
,
1875 ASSERT_EFI_ERROR (Status
);
1877 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
1880 // Publish our HII data
1882 HiiHandle
[0] = HiiAddPackages (
1885 DriverSampleStrings
,
1889 if (HiiHandle
[0] == NULL
) {
1890 return EFI_OUT_OF_RESOURCES
;
1893 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
1896 // Publish another Fromset
1898 Status
= gBS
->InstallMultipleProtocolInterfaces (
1900 &gEfiDevicePathProtocolGuid
,
1901 &mHiiVendorDevicePath1
,
1904 ASSERT_EFI_ERROR (Status
);
1906 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
1908 HiiHandle
[1] = HiiAddPackages (
1911 DriverSampleStrings
,
1915 if (HiiHandle
[1] == NULL
) {
1916 DriverSampleUnload (ImageHandle
);
1917 return EFI_OUT_OF_RESOURCES
;
1920 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
1923 // Very simple example of how one would update a string that is already
1924 // in the HII database
1926 NewString
= L
"700 Mhz";
1928 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1929 DriverSampleUnload (ImageHandle
);
1930 return EFI_OUT_OF_RESOURCES
;
1933 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1936 // Initialize Name/Value name String ID
1938 PrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1939 PrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1940 PrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1943 // Initialize configuration data
1945 Configuration
= &PrivateData
->Configuration
;
1946 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1949 // Try to read NV config EFI variable first
1951 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, DriverHandle
[0]);
1952 ASSERT (ConfigRequestHdr
!= NULL
);
1954 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1955 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1956 if (EFI_ERROR (Status
)) {
1958 // Store zero data Buffer Storage to EFI variable
1960 Status
= gRT
->SetVariable(
1963 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1964 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1967 ASSERT (Status
== EFI_SUCCESS
);
1969 // EFI variable for NV config doesn't exit, we should build this variable
1970 // based on default values stored in IFR
1972 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1973 ASSERT (ActionFlag
);
1976 // EFI variable does exist and Validate Current Setting
1978 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1979 ASSERT (ActionFlag
);
1982 FreePool (ConfigRequestHdr
);
1984 Status
= gBS
->CreateEventEx (
1987 DriverSampleInternalEmptyFunction
,
1992 ASSERT_EFI_ERROR (Status
);
1994 // In default, this driver is built into Flash device image,
1995 // the following code doesn't run.
1999 // Example of how to display only the item we sent to HII
2000 // When this driver is not built into Flash device image,
2001 // it need to call SendForm to show front page by itself.
2003 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2005 // Have the browser pull out our copy of the data, and only display our data
2007 Status
= FormBrowser2
->SendForm (
2009 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2017 HiiRemovePackages (HiiHandle
[0]);
2019 HiiRemovePackages (HiiHandle
[1]);
2026 Unloads the application and its installed protocol.
2028 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2030 @retval EFI_SUCCESS The image has been unloaded.
2034 DriverSampleUnload (
2035 IN EFI_HANDLE ImageHandle
2040 ASSERT (PrivateData
!= NULL
);
2042 if (DriverHandle
[0] != NULL
) {
2043 gBS
->UninstallMultipleProtocolInterfaces (
2045 &gEfiDevicePathProtocolGuid
,
2046 &mHiiVendorDevicePath0
,
2047 &gEfiHiiConfigAccessProtocolGuid
,
2048 &PrivateData
->ConfigAccess
,
2051 DriverHandle
[0] = NULL
;
2054 if (DriverHandle
[1] != NULL
) {
2055 gBS
->UninstallMultipleProtocolInterfaces (
2057 &gEfiDevicePathProtocolGuid
,
2058 &mHiiVendorDevicePath1
,
2061 DriverHandle
[1] = NULL
;
2064 if (PrivateData
->HiiHandle
[0] != NULL
) {
2065 HiiRemovePackages (PrivateData
->HiiHandle
[0]);
2068 if (PrivateData
->HiiHandle
[1] != NULL
) {
2069 HiiRemovePackages (PrivateData
->HiiHandle
[1]);
2072 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2073 if (PrivateData
->NameValueName
[Index
] != NULL
) {
2074 FreePool (PrivateData
->NameValueName
[Index
]);
2077 FreePool (PrivateData
);
2080 gBS
->CloseEvent (mEvent
);