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 CHAR16 MyEfiVar
[] = L
"MyEfiVar";
27 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
28 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
= NULL
;
31 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
37 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
38 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
42 // {C153B68D-EBFC-488e-B110-662867745B87}
44 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }
48 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
50 (UINT8
) (END_DEVICE_PATH_LENGTH
),
51 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
56 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
62 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
63 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
67 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}
69 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }
73 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
75 (UINT8
) (END_DEVICE_PATH_LENGTH
),
76 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
82 Add empty function for event process function.
84 @param Event The Event need to be process
85 @param Context The context of the event.
90 DriverSampleInternalEmptyFunction (
98 Notification function for keystrokes.
100 @param[in] KeyData The key that was pressed.
102 @retval EFI_SUCCESS The operation was successful.
106 NotificationFunction(
107 IN EFI_KEY_DATA
*KeyData
110 gBS
->SignalEvent (mEvent
);
116 Function to start monitoring for CTRL-C using SimpleTextInputEx.
118 @retval EFI_SUCCESS The feature is enabled.
119 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
123 InternalStartMonitor(
127 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
128 EFI_KEY_DATA KeyData
;
133 EFI_HANDLE NotifyHandle
;
135 Status
= gBS
->LocateHandleBuffer (
137 &gEfiSimpleTextInputExProtocolGuid
,
142 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
143 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
144 ASSERT_EFI_ERROR (Status
);
146 KeyData
.KeyState
.KeyToggleState
= 0;
147 KeyData
.Key
.ScanCode
= 0;
148 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
149 KeyData
.Key
.UnicodeChar
= L
'c';
151 Status
= SimpleEx
->RegisterKeyNotify(
154 NotificationFunction
,
156 if (EFI_ERROR (Status
)) {
160 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
161 Status
= SimpleEx
->RegisterKeyNotify(
164 NotificationFunction
,
166 if (EFI_ERROR (Status
)) {
175 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
177 @retval EFI_SUCCESS The feature is enabled.
178 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
186 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
189 EFI_KEY_DATA KeyData
;
192 EFI_HANDLE NotifyHandle
;
194 Status
= gBS
->LocateHandleBuffer (
196 &gEfiSimpleTextInputExProtocolGuid
,
201 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
202 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
203 ASSERT_EFI_ERROR (Status
);
205 KeyData
.KeyState
.KeyToggleState
= 0;
206 KeyData
.Key
.ScanCode
= 0;
207 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
208 KeyData
.Key
.UnicodeChar
= L
'c';
210 Status
= SimpleEx
->RegisterKeyNotify(
213 NotificationFunction
,
215 if (!EFI_ERROR (Status
)) {
216 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
219 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
220 Status
= SimpleEx
->RegisterKeyNotify(
223 NotificationFunction
,
225 if (!EFI_ERROR (Status
)) {
226 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
234 Encode the password using a simple algorithm.
236 @param Password The string to be encoded.
237 @param MaxSize The size of the string.
251 Key
= L
"MAR10648567";
252 Buffer
= AllocateZeroPool (MaxSize
);
253 ASSERT (Buffer
!= NULL
);
255 for (Index
= 0; Key
[Index
] != 0; Index
++) {
256 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
257 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
261 CopyMem (Password
, Buffer
, MaxSize
);
268 Validate the user's password.
270 @param PrivateData This driver's private context data.
271 @param StringId The user's input.
273 @retval EFI_SUCCESS The user's input matches the password.
274 @retval EFI_NOT_READY The user's input does not match the password.
278 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
279 IN EFI_STRING_ID StringId
285 UINTN PasswordMaxSize
;
287 CHAR16
*EncodedPassword
;
291 // Get encoded password first
293 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
294 Status
= gRT
->GetVariable (
299 &PrivateData
->Configuration
301 if (EFI_ERROR (Status
)) {
303 // Old password not exist, prompt for new password
309 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
311 // Check whether we have any old password set
313 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
314 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
321 // Old password not exist, return EFI_SUCCESS to prompt for new password
327 // Get user input password
329 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
330 if (Password
== NULL
) {
331 return EFI_NOT_READY
;
333 if (StrSize (Password
) > PasswordMaxSize
) {
335 return EFI_NOT_READY
;
339 // Validate old password
341 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
342 ASSERT (EncodedPassword
!= NULL
);
343 StrnCpy (EncodedPassword
, Password
, StrLen (Password
));
344 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
345 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, PasswordMaxSize
) != 0) {
347 // Old password mismatch, return EFI_NOT_READY to prompt for error message
349 Status
= EFI_NOT_READY
;
351 Status
= EFI_SUCCESS
;
355 FreePool (EncodedPassword
);
361 Encode the password using a simple algorithm.
363 @param PrivateData This driver's private context data.
364 @param StringId The password from User.
366 @retval EFI_SUCESS The operation is successful.
367 @return Other value if gRT->SetVariable () fails.
372 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
373 IN EFI_STRING_ID StringId
378 CHAR16
*TempPassword
;
380 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
384 // Get Buffer Storage data from EFI variable
386 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
387 Status
= gRT
->GetVariable (
392 &PrivateData
->Configuration
394 if (EFI_ERROR (Status
)) {
399 // Get user input password
401 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
402 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
403 ZeroMem (Password
, PasswordSize
);
405 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
406 if (TempPassword
== NULL
) {
407 return EFI_NOT_READY
;
409 if (StrSize (TempPassword
) > PasswordSize
) {
410 FreePool (TempPassword
);
411 return EFI_NOT_READY
;
413 StrnCpy (Password
, TempPassword
, StrLen (TempPassword
));
414 FreePool (TempPassword
);
417 // Retrive uncommitted data from Browser
419 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
420 ASSERT (Configuration
!= NULL
);
421 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
423 // Update password's clear text in the screen
425 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
428 // Update uncommitted data of Browser
433 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
434 (UINT8
*) Configuration
,
440 // Free Configuration Buffer
442 FreePool (Configuration
);
448 EncodePassword (Password
, StrLen (Password
) * 2);
449 Status
= gRT
->SetVariable(
452 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
453 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
454 &PrivateData
->Configuration
460 Update names of Name/Value storage to current language.
462 @param PrivateData Points to the driver private data.
464 @retval EFI_SUCCESS All names are successfully updated.
465 @retval EFI_NOT_FOUND Failed to get Name from HII database.
470 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
476 // Get Name/Value name string of current language
478 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
479 PrivateData
->NameValueName
[Index
] = HiiGetString (
480 PrivateData
->HiiHandle
[0],
481 PrivateData
->NameStringId
[Index
],
484 if (PrivateData
->NameValueName
[Index
] == NULL
) {
485 return EFI_NOT_FOUND
;
494 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
496 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
498 This is a internal function.
500 @param StringPtr String in <BlockConfig> format and points to the
501 first character of <Number>.
502 @param Number The output value. Caller takes the responsibility
504 @param Len Length of the <Number>, in characters.
506 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
508 @retval EFI_SUCCESS Value of <Number> is outputted in Number
514 IN EFI_STRING StringPtr
,
528 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
529 return EFI_INVALID_PARAMETER
;
535 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
538 *Len
= StringPtr
- TmpPtr
;
541 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
543 Status
= EFI_OUT_OF_RESOURCES
;
546 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
547 *(Str
+ *Len
) = L
'\0';
549 Length
= (Length
+ 1) / 2;
550 Buf
= (UINT8
*) AllocateZeroPool (Length
);
552 Status
= EFI_OUT_OF_RESOURCES
;
557 ZeroMem (TemStr
, sizeof (TemStr
));
558 for (Index
= 0; Index
< Length
; Index
++) {
559 TemStr
[0] = Str
[Length
- Index
- 1];
560 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
561 if ((Index
& 1) == 0) {
562 Buf
[Index
/2] = DigitUint8
;
564 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
569 Status
= EFI_SUCCESS
;
580 Create altcfg string.
582 @param Result The request result string.
583 @param ConfigHdr The request head info. <ConfigHdr> format.
584 @param Offset The offset of the parameter int he structure.
585 @param Width The width of the parameter.
588 @retval The string with altcfg info append at the end.
592 IN EFI_STRING Result
,
593 IN EFI_STRING ConfigHdr
,
598 EFI_STRING StringPtr
;
602 NewLen
= StrLen (Result
);
604 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
606 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
607 StringPtr
= AllocateZeroPool (NewLen
);
608 if (StringPtr
== NULL
) {
613 if (Result
!= NULL
) {
614 StrCpy (StringPtr
, Result
);
615 StringPtr
+= StrLen (Result
);
621 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
624 EFI_HII_DEFAULT_CLASS_STANDARD
626 StringPtr
+= StrLen (StringPtr
);
630 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
631 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
634 DEFAULT_CLASS_STANDARD_VALUE
636 StringPtr
+= StrLen (StringPtr
);
640 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
643 EFI_HII_DEFAULT_CLASS_MANUFACTURING
645 StringPtr
+= StrLen (StringPtr
);
649 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
650 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
653 DEFAULT_CLASS_MANUFACTURING_VALUE
655 StringPtr
+= StrLen (StringPtr
);
661 Check whether need to add the altcfg string. if need to add, add the altcfg
664 @param RequestResult The request result string.
665 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
670 IN OUT EFI_STRING
*RequestResult
,
671 IN EFI_STRING ConfigRequestHdr
674 EFI_STRING StringPtr
;
685 StringPtr
= *RequestResult
;
686 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
687 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
688 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
689 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
691 if (StringPtr
== NULL
) {
695 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
697 // Back up the header of one <BlockName>
701 StringPtr
+= StrLen (L
"OFFSET=");
705 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
706 if (EFI_ERROR (Status
)) {
713 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
715 FreePool (TmpBuffer
);
718 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
721 StringPtr
+= StrLen (L
"&WIDTH=");
726 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
727 if (EFI_ERROR (Status
)) {
734 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
736 FreePool (TmpBuffer
);
739 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
742 StringPtr
+= StrLen (L
"&VALUE=");
747 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
748 if (EFI_ERROR (Status
)) {
754 // Calculate Value and convert it to hex string.
756 if (Offset
+ Width
> BlockSize
) {
760 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
761 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
768 This function allows a caller to extract the current configuration for one
769 or more named elements from the target driver.
771 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
772 @param Request A null-terminated Unicode string in
773 <ConfigRequest> format.
774 @param Progress On return, points to a character in the Request
775 string. Points to the string's null terminator if
776 request was successful. Points to the most recent
777 '&' before the first failing name/value pair (or
778 the beginning of the string if the failure is in
779 the first name/value pair) if the request was not
781 @param Results A null-terminated Unicode string in
782 <ConfigAltResp> format which has all values filled
783 in for the names in the Request string. String to
784 be allocated by the called function.
786 @retval EFI_SUCCESS The Results is filled with the requested values.
787 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
788 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
789 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
796 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
797 IN CONST EFI_STRING Request
,
798 OUT EFI_STRING
*Progress
,
799 OUT EFI_STRING
*Results
804 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
805 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
806 EFI_STRING ConfigRequest
;
807 EFI_STRING ConfigRequestHdr
;
813 BOOLEAN AllocatedRequest
;
815 if (Progress
== NULL
|| Results
== NULL
) {
816 return EFI_INVALID_PARAMETER
;
819 // Initialize the local variables.
821 ConfigRequestHdr
= NULL
;
822 ConfigRequest
= NULL
;
825 AllocatedRequest
= FALSE
;
827 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
828 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
831 // Get Buffer Storage data from EFI variable.
832 // Try to get the current setting from variable.
834 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
835 Status
= gRT
->GetVariable (
840 &PrivateData
->Configuration
842 if (EFI_ERROR (Status
)) {
843 return EFI_NOT_FOUND
;
846 if (Request
== NULL
) {
848 // Request is set to NULL, construct full request string.
852 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
853 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
855 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
856 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
857 ConfigRequest
= AllocateZeroPool (Size
);
858 ASSERT (ConfigRequest
!= NULL
);
859 AllocatedRequest
= TRUE
;
860 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
861 FreePool (ConfigRequestHdr
);
862 ConfigRequestHdr
= NULL
;
865 // Check routing data in <ConfigHdr>.
866 // Note: if only one Storage is used, then this checking could be skipped.
868 if (!HiiIsConfigHdrMatch (Request
, &mFormSetGuid
, NULL
)) {
869 return EFI_NOT_FOUND
;
872 // Check whether request for EFI Varstore. EFI varstore get data
873 // through hii database, not support in this path.
875 if (HiiIsConfigHdrMatch(Request
, &mFormSetGuid
, MyEfiVar
)) {
876 return EFI_UNSUPPORTED
;
879 // Set Request to the unified request string.
881 ConfigRequest
= Request
;
883 // Check whether Request includes Request Element.
885 if (StrStr (Request
, L
"OFFSET") == NULL
) {
887 // Check Request Element does exist in Reques String
889 StrPointer
= StrStr (Request
, L
"PATH");
890 if (StrPointer
== NULL
) {
891 return EFI_INVALID_PARAMETER
;
893 if (StrStr (StrPointer
, L
"&") == NULL
) {
894 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
895 ConfigRequest
= AllocateZeroPool (Size
);
896 ASSERT (ConfigRequest
!= NULL
);
897 AllocatedRequest
= TRUE
;
898 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
904 // Check if requesting Name/Value storage
906 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
908 // Update Name/Value storage Names
910 Status
= LoadNameValueNames (PrivateData
);
911 if (EFI_ERROR (Status
)) {
916 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
917 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
918 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
920 BufferSize
= (StrLen (ConfigRequest
) +
921 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
922 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
923 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
924 *Results
= AllocateZeroPool (BufferSize
);
925 ASSERT (*Results
!= NULL
);
926 StrCpy (*Results
, ConfigRequest
);
930 // Append value of NameValueVar0, type is UINT8
932 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
933 Value
+= StrLen (PrivateData
->NameValueName
[0]);
934 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
935 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
937 BackupChar
= Value
[ValueStrLen
];
939 Value
+= UnicodeValueToString (
941 PREFIX_ZERO
| RADIX_HEX
,
942 PrivateData
->Configuration
.NameValueVar0
,
943 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
949 // Append value of NameValueVar1, type is UINT16
951 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
952 Value
+= StrLen (PrivateData
->NameValueName
[1]);
953 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
954 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
956 BackupChar
= Value
[ValueStrLen
];
958 Value
+= UnicodeValueToString (
960 PREFIX_ZERO
| RADIX_HEX
,
961 PrivateData
->Configuration
.NameValueVar1
,
962 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
968 // Append value of NameValueVar2, type is CHAR16 *
970 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
971 Value
+= StrLen (PrivateData
->NameValueName
[2]);
972 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
973 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
977 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
979 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
980 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
981 Value
+= UnicodeValueToString (Value
, PREFIX_ZERO
| RADIX_HEX
, *StrPointer
, 4);
985 Status
= EFI_SUCCESS
;
988 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
990 Status
= HiiConfigRouting
->BlockToConfig (
993 (UINT8
*) &PrivateData
->Configuration
,
998 if (!EFI_ERROR (Status
)) {
999 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
1000 AppendAltCfgString(Results
, ConfigRequestHdr
);
1005 // Free the allocated config request string.
1007 if (AllocatedRequest
) {
1008 FreePool (ConfigRequest
);
1011 if (ConfigRequestHdr
!= NULL
) {
1012 FreePool (ConfigRequestHdr
);
1015 // Set Progress string to the original request string.
1017 if (Request
== NULL
) {
1019 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1020 *Progress
= Request
+ StrLen (Request
);
1028 This function processes the results of changes in configuration.
1030 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1031 @param Configuration A null-terminated Unicode string in <ConfigResp>
1033 @param Progress A pointer to a string filled in with the offset of
1034 the most recent '&' before the first failing
1035 name/value pair (or the beginning of the string if
1036 the failure is in the first name/value pair) or
1037 the terminating NULL if all was successful.
1039 @retval EFI_SUCCESS The Results is processed successfully.
1040 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1041 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1048 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1049 IN CONST EFI_STRING Configuration
,
1050 OUT EFI_STRING
*Progress
1055 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1056 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1065 if (Configuration
== NULL
|| Progress
== NULL
) {
1066 return EFI_INVALID_PARAMETER
;
1069 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1070 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
1071 *Progress
= Configuration
;
1074 // Check routing data in <ConfigHdr>.
1075 // Note: if only one Storage is used, then this checking could be skipped.
1077 if (!HiiIsConfigHdrMatch (Configuration
, &mFormSetGuid
, NULL
)) {
1078 return EFI_NOT_FOUND
;
1082 // Check whether request for EFI Varstore. EFI varstore get data
1083 // through hii database, not support in this path.
1085 if (HiiIsConfigHdrMatch(Configuration
, &mFormSetGuid
, MyEfiVar
)) {
1086 return EFI_UNSUPPORTED
;
1090 // Get Buffer Storage data from EFI variable
1092 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1093 Status
= gRT
->GetVariable (
1098 &PrivateData
->Configuration
1100 if (EFI_ERROR (Status
)) {
1105 // Check if configuring Name/Value storage
1107 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
1109 // Update Name/Value storage Names
1111 Status
= LoadNameValueNames (PrivateData
);
1112 if (EFI_ERROR (Status
)) {
1117 // Convert value for NameValueVar0
1119 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
1123 Value
+= StrLen (PrivateData
->NameValueName
[0]);
1128 StrPtr
= StrStr (Value
, L
"&");
1129 if (StrPtr
== NULL
) {
1130 StrPtr
= Value
+ StrLen (Value
);
1133 // Convert Value to Buffer data
1135 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
1136 ZeroMem (TemStr
, sizeof (TemStr
));
1137 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1138 TemStr
[0] = *StrPtr
;
1139 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1140 if ((Index
& 1) == 0) {
1141 DataBuffer
[Index
/2] = DigitUint8
;
1143 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1149 // Convert value for NameValueVar1
1151 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
1155 Value
+= StrLen (PrivateData
->NameValueName
[1]);
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
.NameValueVar1
;
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 NameValueVar2
1183 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1187 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1192 StrPtr
= StrStr (Value
, L
"&");
1193 if (StrPtr
== NULL
) {
1194 StrPtr
= Value
+ StrLen (Value
);
1197 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1199 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1200 ZeroMem (TemStr
, sizeof (TemStr
));
1201 while (Value
< StrPtr
) {
1202 StrnCpy (TemStr
, Value
, 4);
1203 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1210 // Store Buffer Storage back to EFI variable
1212 Status
= gRT
->SetVariable(
1215 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1216 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1217 &PrivateData
->Configuration
1224 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1226 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1227 Status
= HiiConfigRouting
->ConfigToBlock (
1230 (UINT8
*) &PrivateData
->Configuration
,
1234 if (EFI_ERROR (Status
)) {
1239 // Store Buffer Storage back to EFI variable
1241 Status
= gRT
->SetVariable(
1244 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1245 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1246 &PrivateData
->Configuration
1254 This function processes the results of changes in configuration.
1256 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1257 @param Action Specifies the type of action taken by the browser.
1258 @param QuestionId A unique value which is sent to the original
1259 exporting driver so that it can identify the type
1261 @param Type The type of value for the question.
1262 @param Value A pointer to the data being sent to the original
1264 @param ActionRequest On return, points to the action requested by the
1267 @retval EFI_SUCCESS The callback successfully handled the action.
1268 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1269 variable and its data.
1270 @retval EFI_DEVICE_ERROR The variable could not be saved.
1271 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1278 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1279 IN EFI_BROWSER_ACTION Action
,
1280 IN EFI_QUESTION_ID QuestionId
,
1282 IN EFI_IFR_TYPE_VALUE
*Value
,
1283 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1286 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1288 VOID
*StartOpCodeHandle
;
1289 VOID
*OptionsOpCodeHandle
;
1290 EFI_IFR_GUID_LABEL
*StartLabel
;
1291 VOID
*EndOpCodeHandle
;
1292 EFI_IFR_GUID_LABEL
*EndLabel
;
1294 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1295 MY_EFI_VARSTORE_DATA
*EfiData
;
1298 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1299 (ActionRequest
== NULL
)) {
1300 return EFI_INVALID_PARAMETER
;
1305 Status
= EFI_SUCCESS
;
1306 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1309 case EFI_BROWSER_ACTION_FORM_OPEN
:
1311 if (QuestionId
== 0x1234) {
1313 // Sample CallBack for UEFI FORM_OPEN action:
1314 // Add Save action into Form 3 when Form 1 is opened.
1315 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1317 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1320 // Initialize the container for dynamic opcodes
1322 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1323 ASSERT (StartOpCodeHandle
!= NULL
);
1326 // Create Hii Extend Label OpCode as the start opcode
1328 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1329 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1330 StartLabel
->Number
= LABEL_UPDATE2
;
1332 HiiCreateActionOpCode (
1333 StartOpCodeHandle
, // Container for dynamic created opcodes
1334 0x1238, // Question ID
1335 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1336 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1337 EFI_IFR_FLAG_CALLBACK
, // Question flag
1338 0 // Action String ID
1342 PrivateData
->HiiHandle
[0], // HII handle
1343 &mFormSetGuid
, // Formset GUID
1345 StartOpCodeHandle
, // Label for where to insert opcodes
1349 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1352 if (QuestionId
== 0x1247) {
1353 Status
= InternalStartMonitor ();
1354 ASSERT_EFI_ERROR (Status
);
1359 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1361 if (QuestionId
== 0x5678) {
1363 // Sample CallBack for UEFI FORM_CLOSE action:
1364 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1368 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1371 L
"You are going to leave third Form!",
1372 L
"Press ESC or ENTER to continue ...",
1376 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1379 if (QuestionId
== 0x1247) {
1380 Status
= InternalStopMonitor ();
1381 ASSERT_EFI_ERROR (Status
);
1386 case EFI_BROWSER_ACTION_RETRIEVE
:
1388 if (QuestionId
== 0x1248) {
1390 if (Type
!= EFI_IFR_TYPE_REF
) {
1391 return EFI_INVALID_PARAMETER
;
1394 Value
->ref
.FormId
= 0x3;
1400 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1402 switch (QuestionId
) {
1404 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1408 Status
= EFI_UNSUPPORTED
;
1414 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1416 switch (QuestionId
) {
1418 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1422 Status
= EFI_UNSUPPORTED
;
1428 case EFI_BROWSER_ACTION_CHANGING
:
1430 switch (QuestionId
) {
1433 if (Type
!= EFI_IFR_TYPE_REF
) {
1434 return EFI_INVALID_PARAMETER
;
1437 Value
->ref
.FormId
= 0x1234;
1442 // Initialize the container for dynamic opcodes
1444 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1445 ASSERT (StartOpCodeHandle
!= NULL
);
1447 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1448 ASSERT (EndOpCodeHandle
!= NULL
);
1451 // Create Hii Extend Label OpCode as the start opcode
1453 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1454 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1455 StartLabel
->Number
= LABEL_UPDATE1
;
1458 // Create Hii Extend Label OpCode as the end opcode
1460 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1461 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1462 EndLabel
->Number
= LABEL_END
;
1464 HiiCreateActionOpCode (
1465 StartOpCodeHandle
, // Container for dynamic created opcodes
1466 0x1237, // Question ID
1467 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1468 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1469 EFI_IFR_FLAG_CALLBACK
, // Question flag
1470 0 // Action String ID
1474 // Create Option OpCode
1476 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1477 ASSERT (OptionsOpCodeHandle
!= NULL
);
1479 HiiCreateOneOfOptionOpCode (
1480 OptionsOpCodeHandle
,
1481 STRING_TOKEN (STR_BOOT_OPTION1
),
1483 EFI_IFR_NUMERIC_SIZE_1
,
1487 HiiCreateOneOfOptionOpCode (
1488 OptionsOpCodeHandle
,
1489 STRING_TOKEN (STR_BOOT_OPTION2
),
1491 EFI_IFR_NUMERIC_SIZE_1
,
1496 // Prepare initial value for the dynamic created oneof Question
1498 PrivateData
->Configuration
.DynamicOneof
= 2;
1499 Status
= gRT
->SetVariable(
1502 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1503 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1504 &PrivateData
->Configuration
1508 // Set initial vlaue of dynamic created oneof Question in Form Browser
1510 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1511 ASSERT (Configuration
!= NULL
);
1512 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1513 Configuration
->DynamicOneof
= 2;
1516 // Update uncommitted data of Browser
1521 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1522 (UINT8
*) Configuration
,
1526 FreePool (Configuration
);
1528 HiiCreateOneOfOpCode (
1529 StartOpCodeHandle
, // Container for dynamic created opcodes
1530 0x8001, // Question ID (or call it "key")
1531 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1532 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1533 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1534 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1535 EFI_IFR_FLAG_CALLBACK
, // Question flag
1536 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1537 OptionsOpCodeHandle
, // Option Opcode list
1538 NULL
// Default Opcode is NULl
1541 HiiCreateOrderedListOpCode (
1542 StartOpCodeHandle
, // Container for dynamic created opcodes
1543 0x8002, // Question ID
1544 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1545 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1546 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1547 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1548 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1549 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1550 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1551 5, // Maximum container
1552 OptionsOpCodeHandle
, // Option Opcode list
1553 NULL
// Default Opcode is NULl
1556 HiiCreateTextOpCode (
1558 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1559 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1560 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1563 HiiCreateDateOpCode (
1568 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1569 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1571 QF_DATE_STORAGE_TIME
,
1575 HiiCreateTimeOpCode (
1580 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1581 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1583 QF_TIME_STORAGE_TIME
,
1587 HiiCreateGotoOpCode (
1588 StartOpCodeHandle
, // Container for dynamic created opcodes
1589 1, // Target Form ID
1590 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1591 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1593 0x8003 // Question ID
1597 PrivateData
->HiiHandle
[0], // HII handle
1598 &mFormSetGuid
, // Formset GUID
1600 StartOpCodeHandle
, // Label for where to insert opcodes
1601 EndOpCodeHandle
// Replace data
1604 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1605 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1606 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1612 // We will reach here once the Question is refreshed
1616 // Initialize the container for dynamic opcodes
1618 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1619 ASSERT (StartOpCodeHandle
!= NULL
);
1622 // Create Hii Extend Label OpCode as the start opcode
1624 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1625 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1626 if (QuestionId
== 0x5678) {
1627 StartLabel
->Number
= LABEL_UPDATE2
;
1629 PrivateData
->Configuration
.DynamicRefresh
++;
1630 } else if (QuestionId
== 0x1247 ) {
1631 StartLabel
->Number
= LABEL_UPDATE3
;
1633 PrivateData
->Configuration
.RefreshGuidCount
++;
1636 HiiCreateActionOpCode (
1637 StartOpCodeHandle
, // Container for dynamic created opcodes
1638 0x1237, // Question ID
1639 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1640 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1641 EFI_IFR_FLAG_CALLBACK
, // Question flag
1642 0 // Action String ID
1646 PrivateData
->HiiHandle
[0], // HII handle
1647 &mFormSetGuid
, // Formset GUID
1649 StartOpCodeHandle
, // Label for where to insert opcodes
1653 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1656 // Refresh the Question value
1658 Status
= gRT
->SetVariable(
1661 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1662 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1663 &PrivateData
->Configuration
1666 if (QuestionId
== 0x5678) {
1668 // Update uncommitted data of Browser
1670 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1671 ASSERT (EfiData
!= NULL
);
1672 if (HiiGetBrowserData (&mFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*) EfiData
)) {
1673 EfiData
->Field8
= 111;
1677 sizeof (MY_EFI_VARSTORE_DATA
),
1688 // User press "Exit now", request Browser to exit
1690 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1695 // User press "Save now", request Browser to save the uncommitted data.
1697 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1703 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1705 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1710 // User press "Discard current form now", request Browser to discard the uncommitted data.
1712 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1717 // User press "Submit current form now", request Browser to save the uncommitted data.
1719 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1725 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1727 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1732 // Only used to update the state.
1734 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0) &&
1735 (PrivateData
->PasswordState
== BROWSER_STATE_SET_PASSWORD
)) {
1736 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1737 return EFI_INVALID_PARAMETER
;
1741 // When try to set a new password, user will be chanlleged with old password.
1742 // The Callback is responsible for validating old password input by user,
1743 // If Callback return EFI_SUCCESS, it indicates validation pass.
1745 switch (PrivateData
->PasswordState
) {
1746 case BROWSER_STATE_VALIDATE_PASSWORD
:
1747 Status
= ValidatePassword (PrivateData
, Value
->string
);
1748 if (Status
== EFI_SUCCESS
) {
1749 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
1753 case BROWSER_STATE_SET_PASSWORD
:
1754 Status
= SetPassword (PrivateData
, Value
->string
);
1755 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1771 Status
= EFI_UNSUPPORTED
;
1779 Main entry for this driver.
1781 @param ImageHandle Image handle this driver.
1782 @param SystemTable Pointer to SystemTable.
1784 @retval EFI_SUCESS This function always complete successfully.
1790 IN EFI_HANDLE ImageHandle
,
1791 IN EFI_SYSTEM_TABLE
*SystemTable
1795 EFI_HII_HANDLE HiiHandle
[2];
1796 EFI_SCREEN_DESCRIPTOR Screen
;
1797 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1798 EFI_HII_STRING_PROTOCOL
*HiiString
;
1799 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1800 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1803 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1805 EFI_STRING ConfigRequestHdr
;
1806 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1809 // Initialize the local variables.
1811 ConfigRequestHdr
= NULL
;
1813 // Initialize screen dimensions for SendForm().
1814 // Remove 3 characters from top and bottom
1816 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1817 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1820 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1823 // Initialize driver private data
1825 PrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1826 if (PrivateData
== NULL
) {
1827 return EFI_OUT_OF_RESOURCES
;
1830 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1832 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1833 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1834 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1835 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1838 // Locate Hii Database protocol
1840 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1841 if (EFI_ERROR (Status
)) {
1844 PrivateData
->HiiDatabase
= HiiDatabase
;
1847 // Locate HiiString protocol
1849 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1850 if (EFI_ERROR (Status
)) {
1853 PrivateData
->HiiString
= HiiString
;
1856 // Locate Formbrowser2 protocol
1858 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1859 if (EFI_ERROR (Status
)) {
1862 PrivateData
->FormBrowser2
= FormBrowser2
;
1865 // Locate ConfigRouting protocol
1867 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1868 if (EFI_ERROR (Status
)) {
1871 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1873 Status
= gBS
->InstallMultipleProtocolInterfaces (
1875 &gEfiDevicePathProtocolGuid
,
1876 &mHiiVendorDevicePath0
,
1877 &gEfiHiiConfigAccessProtocolGuid
,
1878 &PrivateData
->ConfigAccess
,
1881 ASSERT_EFI_ERROR (Status
);
1883 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
1886 // Publish our HII data
1888 HiiHandle
[0] = HiiAddPackages (
1891 DriverSampleStrings
,
1895 if (HiiHandle
[0] == NULL
) {
1896 return EFI_OUT_OF_RESOURCES
;
1899 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
1902 // Publish another Fromset
1904 Status
= gBS
->InstallMultipleProtocolInterfaces (
1906 &gEfiDevicePathProtocolGuid
,
1907 &mHiiVendorDevicePath1
,
1910 ASSERT_EFI_ERROR (Status
);
1912 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
1914 HiiHandle
[1] = HiiAddPackages (
1917 DriverSampleStrings
,
1921 if (HiiHandle
[1] == NULL
) {
1922 DriverSampleUnload (ImageHandle
);
1923 return EFI_OUT_OF_RESOURCES
;
1926 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
1929 // Very simple example of how one would update a string that is already
1930 // in the HII database
1932 NewString
= L
"700 Mhz";
1934 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1935 DriverSampleUnload (ImageHandle
);
1936 return EFI_OUT_OF_RESOURCES
;
1939 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1942 // Initialize Name/Value name String ID
1944 PrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1945 PrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1946 PrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1949 // Initialize configuration data
1951 Configuration
= &PrivateData
->Configuration
;
1952 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1955 // Try to read NV config EFI variable first
1957 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, DriverHandle
[0]);
1958 ASSERT (ConfigRequestHdr
!= NULL
);
1960 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1961 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1962 if (EFI_ERROR (Status
)) {
1964 // Store zero data Buffer Storage to EFI variable
1966 Status
= gRT
->SetVariable(
1969 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1970 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1973 ASSERT (Status
== EFI_SUCCESS
);
1975 // EFI variable for NV config doesn't exit, we should build this variable
1976 // based on default values stored in IFR
1978 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1979 ASSERT (ActionFlag
);
1982 // EFI variable does exist and Validate Current Setting
1984 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1985 ASSERT (ActionFlag
);
1987 FreePool (ConfigRequestHdr
);
1990 // Initialize efi varstore configuration data
1992 VarStoreConfig
= &PrivateData
->VarStoreConfig
;
1993 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
1995 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
1996 ASSERT (ConfigRequestHdr
!= NULL
);
1998 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
1999 Status
= gRT
->GetVariable (MyEfiVar
, &mFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
2000 if (EFI_ERROR (Status
)) {
2002 // Store zero data to EFI variable Storage.
2004 Status
= gRT
->SetVariable(
2007 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2008 sizeof (MY_EFI_VARSTORE_DATA
),
2011 ASSERT (Status
== EFI_SUCCESS
);
2013 // EFI variable for NV config doesn't exit, we should build this variable
2014 // based on default values stored in IFR
2016 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2017 ASSERT (ActionFlag
);
2020 // EFI variable does exist and Validate Current Setting
2022 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2023 ASSERT (ActionFlag
);
2025 FreePool (ConfigRequestHdr
);
2027 Status
= gBS
->CreateEventEx (
2030 DriverSampleInternalEmptyFunction
,
2035 ASSERT_EFI_ERROR (Status
);
2037 // In default, this driver is built into Flash device image,
2038 // the following code doesn't run.
2042 // Example of how to display only the item we sent to HII
2043 // When this driver is not built into Flash device image,
2044 // it need to call SendForm to show front page by itself.
2046 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2048 // Have the browser pull out our copy of the data, and only display our data
2050 Status
= FormBrowser2
->SendForm (
2052 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2060 HiiRemovePackages (HiiHandle
[0]);
2062 HiiRemovePackages (HiiHandle
[1]);
2069 Unloads the application and its installed protocol.
2071 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2073 @retval EFI_SUCCESS The image has been unloaded.
2077 DriverSampleUnload (
2078 IN EFI_HANDLE ImageHandle
2083 ASSERT (PrivateData
!= NULL
);
2085 if (DriverHandle
[0] != NULL
) {
2086 gBS
->UninstallMultipleProtocolInterfaces (
2088 &gEfiDevicePathProtocolGuid
,
2089 &mHiiVendorDevicePath0
,
2090 &gEfiHiiConfigAccessProtocolGuid
,
2091 &PrivateData
->ConfigAccess
,
2094 DriverHandle
[0] = NULL
;
2097 if (DriverHandle
[1] != NULL
) {
2098 gBS
->UninstallMultipleProtocolInterfaces (
2100 &gEfiDevicePathProtocolGuid
,
2101 &mHiiVendorDevicePath1
,
2104 DriverHandle
[1] = NULL
;
2107 if (PrivateData
->HiiHandle
[0] != NULL
) {
2108 HiiRemovePackages (PrivateData
->HiiHandle
[0]);
2111 if (PrivateData
->HiiHandle
[1] != NULL
) {
2112 HiiRemovePackages (PrivateData
->HiiHandle
[1]);
2115 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2116 if (PrivateData
->NameValueName
[Index
] != NULL
) {
2117 FreePool (PrivateData
->NameValueName
[Index
]);
2120 FreePool (PrivateData
);
2123 gBS
->CloseEvent (mEvent
);