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 - 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "DriverSample.h"
19 #define DISPLAY_ONLY_MY_ITEM 0x0002
21 CHAR16 VariableName
[] = L
"MyIfrNVData";
22 CHAR16 MyEfiVar
[] = L
"MyEfiVar";
23 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
24 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
= NULL
;
27 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
33 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
34 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
37 DRIVER_SAMPLE_FORMSET_GUID
41 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
43 (UINT8
) (END_DEVICE_PATH_LENGTH
),
44 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
49 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
55 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
56 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
59 DRIVER_SAMPLE_INVENTORY_GUID
63 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
65 (UINT8
) (END_DEVICE_PATH_LENGTH
),
66 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
72 Add empty function for event process function.
74 @param Event The Event need to be process
75 @param Context The context of the event.
80 DriverSampleInternalEmptyFunction (
88 Notification function for keystrokes.
90 @param[in] KeyData The key that was pressed.
92 @retval EFI_SUCCESS The operation was successful.
97 IN EFI_KEY_DATA
*KeyData
100 gBS
->SignalEvent (mEvent
);
106 Function to start monitoring for CTRL-C using SimpleTextInputEx.
108 @retval EFI_SUCCESS The feature is enabled.
109 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
113 InternalStartMonitor(
117 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
118 EFI_KEY_DATA KeyData
;
123 EFI_HANDLE NotifyHandle
;
125 Status
= gBS
->LocateHandleBuffer (
127 &gEfiSimpleTextInputExProtocolGuid
,
132 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
133 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
134 ASSERT_EFI_ERROR (Status
);
136 KeyData
.KeyState
.KeyToggleState
= 0;
137 KeyData
.Key
.ScanCode
= 0;
138 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
139 KeyData
.Key
.UnicodeChar
= L
'c';
141 Status
= SimpleEx
->RegisterKeyNotify(
144 NotificationFunction
,
146 if (EFI_ERROR (Status
)) {
150 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
151 Status
= SimpleEx
->RegisterKeyNotify(
154 NotificationFunction
,
156 if (EFI_ERROR (Status
)) {
165 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
167 @retval EFI_SUCCESS The feature is enabled.
168 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
176 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*SimpleEx
;
179 EFI_KEY_DATA KeyData
;
182 EFI_HANDLE NotifyHandle
;
184 Status
= gBS
->LocateHandleBuffer (
186 &gEfiSimpleTextInputExProtocolGuid
,
191 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
192 Status
= gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleTextInputExProtocolGuid
, (VOID
**) &SimpleEx
);
193 ASSERT_EFI_ERROR (Status
);
195 KeyData
.KeyState
.KeyToggleState
= 0;
196 KeyData
.Key
.ScanCode
= 0;
197 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_LEFT_CONTROL_PRESSED
;
198 KeyData
.Key
.UnicodeChar
= L
'c';
200 Status
= SimpleEx
->RegisterKeyNotify(
203 NotificationFunction
,
205 if (!EFI_ERROR (Status
)) {
206 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
209 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
|EFI_RIGHT_CONTROL_PRESSED
;
210 Status
= SimpleEx
->RegisterKeyNotify(
213 NotificationFunction
,
215 if (!EFI_ERROR (Status
)) {
216 Status
= SimpleEx
->UnregisterKeyNotify (SimpleEx
, NotifyHandle
);
224 Encode the password using a simple algorithm.
226 @param Password The string to be encoded.
227 @param MaxSize The size of the string.
241 Key
= L
"MAR10648567";
242 Buffer
= AllocateZeroPool (MaxSize
);
243 ASSERT (Buffer
!= NULL
);
245 for (Index
= 0; Key
[Index
] != 0; Index
++) {
246 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
247 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
251 CopyMem (Password
, Buffer
, MaxSize
);
258 Validate the user's password.
260 @param PrivateData This driver's private context data.
261 @param StringId The user's input.
263 @retval EFI_SUCCESS The user's input matches the password.
264 @retval EFI_NOT_READY The user's input does not match the password.
268 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
269 IN EFI_STRING_ID StringId
275 UINTN PasswordMaxSize
;
277 CHAR16
*EncodedPassword
;
281 // Get encoded password first
283 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
284 Status
= gRT
->GetVariable (
286 &gDriverSampleFormSetGuid
,
289 &PrivateData
->Configuration
291 if (EFI_ERROR (Status
)) {
293 // Old password not exist, prompt for new password
299 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
301 // Check whether we have any old password set
303 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
304 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
311 // Old password not exist, return EFI_SUCCESS to prompt for new password
317 // Get user input password
319 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
320 if (Password
== NULL
) {
321 return EFI_NOT_READY
;
323 if (StrSize (Password
) > PasswordMaxSize
) {
325 return EFI_NOT_READY
;
329 // Validate old password
331 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
332 ASSERT (EncodedPassword
!= NULL
);
333 StrnCpy (EncodedPassword
, Password
, StrLen (Password
));
334 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
335 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, PasswordMaxSize
) != 0) {
337 // Old password mismatch, return EFI_NOT_READY to prompt for error message
339 Status
= EFI_NOT_READY
;
341 Status
= EFI_SUCCESS
;
345 FreePool (EncodedPassword
);
351 Encode the password using a simple algorithm.
353 @param PrivateData This driver's private context data.
354 @param StringId The password from User.
356 @retval EFI_SUCESS The operation is successful.
357 @return Other value if gRT->SetVariable () fails.
362 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
363 IN EFI_STRING_ID StringId
368 CHAR16
*TempPassword
;
370 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
374 // Get Buffer Storage data from EFI variable
376 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
377 Status
= gRT
->GetVariable (
379 &gDriverSampleFormSetGuid
,
382 &PrivateData
->Configuration
384 if (EFI_ERROR (Status
)) {
389 // Get user input password
391 Password
= PrivateData
->Configuration
.WhatIsThePassword2
;
392 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
393 ZeroMem (Password
, PasswordSize
);
395 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
396 if (TempPassword
== NULL
) {
397 return EFI_NOT_READY
;
399 if (StrSize (TempPassword
) > PasswordSize
) {
400 FreePool (TempPassword
);
401 return EFI_NOT_READY
;
403 StrnCpy (Password
, TempPassword
, StrLen (TempPassword
));
404 FreePool (TempPassword
);
407 // Retrive uncommitted data from Browser
409 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
410 ASSERT (Configuration
!= NULL
);
411 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
413 // Update password's clear text in the screen
415 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
418 // Update uncommitted data of Browser
421 &gDriverSampleFormSetGuid
,
423 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
424 (UINT8
*) Configuration
,
430 // Free Configuration Buffer
432 FreePool (Configuration
);
438 EncodePassword (Password
, StrLen (Password
) * 2);
439 Status
= gRT
->SetVariable(
441 &gDriverSampleFormSetGuid
,
442 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
443 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
444 &PrivateData
->Configuration
450 Update names of Name/Value storage to current language.
452 @param PrivateData Points to the driver private data.
454 @retval EFI_SUCCESS All names are successfully updated.
455 @retval EFI_NOT_FOUND Failed to get Name from HII database.
460 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
466 // Get Name/Value name string of current language
468 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
469 PrivateData
->NameValueName
[Index
] = HiiGetString (
470 PrivateData
->HiiHandle
[0],
471 PrivateData
->NameStringId
[Index
],
474 if (PrivateData
->NameValueName
[Index
] == NULL
) {
475 return EFI_NOT_FOUND
;
484 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
486 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
488 This is a internal function.
490 @param StringPtr String in <BlockConfig> format and points to the
491 first character of <Number>.
492 @param Number The output value. Caller takes the responsibility
494 @param Len Length of the <Number>, in characters.
496 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
498 @retval EFI_SUCCESS Value of <Number> is outputted in Number
504 IN EFI_STRING StringPtr
,
518 if (StringPtr
== NULL
|| *StringPtr
== L
'\0' || Number
== NULL
|| Len
== NULL
) {
519 return EFI_INVALID_PARAMETER
;
525 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
528 *Len
= StringPtr
- TmpPtr
;
531 Str
= (EFI_STRING
) AllocateZeroPool (Length
* sizeof (CHAR16
));
533 Status
= EFI_OUT_OF_RESOURCES
;
536 CopyMem (Str
, TmpPtr
, *Len
* sizeof (CHAR16
));
537 *(Str
+ *Len
) = L
'\0';
539 Length
= (Length
+ 1) / 2;
540 Buf
= (UINT8
*) AllocateZeroPool (Length
);
542 Status
= EFI_OUT_OF_RESOURCES
;
547 ZeroMem (TemStr
, sizeof (TemStr
));
548 for (Index
= 0; Index
< Length
; Index
++) {
549 TemStr
[0] = Str
[Length
- Index
- 1];
550 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
551 if ((Index
& 1) == 0) {
552 Buf
[Index
/2] = DigitUint8
;
554 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
559 Status
= EFI_SUCCESS
;
570 Create altcfg string.
572 @param Result The request result string.
573 @param ConfigHdr The request head info. <ConfigHdr> format.
574 @param Offset The offset of the parameter int he structure.
575 @param Width The width of the parameter.
578 @retval The string with altcfg info append at the end.
582 IN EFI_STRING Result
,
583 IN EFI_STRING ConfigHdr
,
588 EFI_STRING StringPtr
;
592 NewLen
= StrLen (Result
);
594 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
596 NewLen
= (NewLen
+ ((1 + StrLen (ConfigHdr
) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16
);
597 StringPtr
= AllocateZeroPool (NewLen
);
598 if (StringPtr
== NULL
) {
603 if (Result
!= NULL
) {
604 StrCpy (StringPtr
, Result
);
605 StringPtr
+= StrLen (Result
);
611 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
614 EFI_HII_DEFAULT_CLASS_STANDARD
616 StringPtr
+= StrLen (StringPtr
);
620 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
621 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
624 DEFAULT_CLASS_STANDARD_VALUE
626 StringPtr
+= StrLen (StringPtr
);
630 (1 + StrLen (ConfigHdr
) + 8 + 4 + 1) * sizeof (CHAR16
),
633 EFI_HII_DEFAULT_CLASS_MANUFACTURING
635 StringPtr
+= StrLen (StringPtr
);
639 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
640 L
"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
643 DEFAULT_CLASS_MANUFACTURING_VALUE
645 StringPtr
+= StrLen (StringPtr
);
651 Check whether need to add the altcfg string. if need to add, add the altcfg
654 @param RequestResult The request result string.
655 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
660 IN OUT EFI_STRING
*RequestResult
,
661 IN EFI_STRING ConfigRequestHdr
664 EFI_STRING StringPtr
;
675 StringPtr
= *RequestResult
;
676 StringPtr
= StrStr (StringPtr
, L
"OFFSET");
677 BlockSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
678 ValueOffset
= OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION
, GetDefaultValueFromAccess
);
679 ValueWidth
= sizeof (((DRIVER_SAMPLE_CONFIGURATION
*)0)->GetDefaultValueFromAccess
);
681 if (StringPtr
== NULL
) {
685 while (*StringPtr
!= 0 && StrnCmp (StringPtr
, L
"OFFSET=", StrLen (L
"OFFSET=")) == 0) {
686 StringPtr
+= StrLen (L
"OFFSET=");
690 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
691 if (EFI_ERROR (Status
)) {
698 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
700 FreePool (TmpBuffer
);
703 if (StrnCmp (StringPtr
, L
"&WIDTH=", StrLen (L
"&WIDTH=")) != 0) {
706 StringPtr
+= StrLen (L
"&WIDTH=");
711 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
712 if (EFI_ERROR (Status
)) {
719 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
721 FreePool (TmpBuffer
);
724 if (StrnCmp (StringPtr
, L
"&VALUE=", StrLen (L
"&VALUE=")) != 0) {
727 StringPtr
+= StrLen (L
"&VALUE=");
732 Status
= GetValueOfNumber (StringPtr
, &TmpBuffer
, &Length
);
733 if (EFI_ERROR (Status
)) {
739 // Calculate Value and convert it to hex string.
741 if (Offset
+ Width
> BlockSize
) {
745 if (Offset
<= ValueOffset
&& Offset
+ Width
>= ValueOffset
+ ValueWidth
) {
746 *RequestResult
= CreateAltCfgString(*RequestResult
, ConfigRequestHdr
, ValueOffset
, ValueWidth
);
753 This function allows a caller to extract the current configuration for one
754 or more named elements from the target driver.
756 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
757 @param Request A null-terminated Unicode string in
758 <ConfigRequest> format.
759 @param Progress On return, points to a character in the Request
760 string. Points to the string's null terminator if
761 request was successful. Points to the most recent
762 '&' before the first failing name/value pair (or
763 the beginning of the string if the failure is in
764 the first name/value pair) if the request was not
766 @param Results A null-terminated Unicode string in
767 <ConfigAltResp> format which has all values filled
768 in for the names in the Request string. String to
769 be allocated by the called function.
771 @retval EFI_SUCCESS The Results is filled with the requested values.
772 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
773 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
774 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
781 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
782 IN CONST EFI_STRING Request
,
783 OUT EFI_STRING
*Progress
,
784 OUT EFI_STRING
*Results
789 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
790 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
791 EFI_STRING ConfigRequest
;
792 EFI_STRING ConfigRequestHdr
;
798 BOOLEAN AllocatedRequest
;
800 if (Progress
== NULL
|| Results
== NULL
) {
801 return EFI_INVALID_PARAMETER
;
804 // Initialize the local variables.
806 ConfigRequestHdr
= NULL
;
807 ConfigRequest
= NULL
;
810 AllocatedRequest
= FALSE
;
812 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
813 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
816 // Get Buffer Storage data from EFI variable.
817 // Try to get the current setting from variable.
819 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
820 Status
= gRT
->GetVariable (
822 &gDriverSampleFormSetGuid
,
825 &PrivateData
->Configuration
827 if (EFI_ERROR (Status
)) {
828 return EFI_NOT_FOUND
;
831 if (Request
== NULL
) {
833 // Request is set to NULL, construct full request string.
837 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
838 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
840 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
841 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
842 ConfigRequest
= AllocateZeroPool (Size
);
843 ASSERT (ConfigRequest
!= NULL
);
844 AllocatedRequest
= TRUE
;
845 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
846 FreePool (ConfigRequestHdr
);
847 ConfigRequestHdr
= NULL
;
850 // Check routing data in <ConfigHdr>.
851 // Note: if only one Storage is used, then this checking could be skipped.
853 if (!HiiIsConfigHdrMatch (Request
, &gDriverSampleFormSetGuid
, NULL
)) {
854 return EFI_NOT_FOUND
;
857 // Check whether request for EFI Varstore. EFI varstore get data
858 // through hii database, not support in this path.
860 if (HiiIsConfigHdrMatch(Request
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
861 return EFI_UNSUPPORTED
;
864 // Set Request to the unified request string.
866 ConfigRequest
= Request
;
868 // Check whether Request includes Request Element.
870 if (StrStr (Request
, L
"OFFSET") == NULL
) {
872 // Check Request Element does exist in Reques String
874 StrPointer
= StrStr (Request
, L
"PATH");
875 if (StrPointer
== NULL
) {
876 return EFI_INVALID_PARAMETER
;
878 if (StrStr (StrPointer
, L
"&") == NULL
) {
879 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
880 ConfigRequest
= AllocateZeroPool (Size
);
881 ASSERT (ConfigRequest
!= NULL
);
882 AllocatedRequest
= TRUE
;
883 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
889 // Check if requesting Name/Value storage
891 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
893 // Update Name/Value storage Names
895 Status
= LoadNameValueNames (PrivateData
);
896 if (EFI_ERROR (Status
)) {
901 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
902 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
903 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
905 BufferSize
= (StrLen (ConfigRequest
) +
906 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
907 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
908 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
909 *Results
= AllocateZeroPool (BufferSize
);
910 ASSERT (*Results
!= NULL
);
911 StrCpy (*Results
, ConfigRequest
);
915 // Append value of NameValueVar0, type is UINT8
917 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
918 Value
+= StrLen (PrivateData
->NameValueName
[0]);
919 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
920 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
922 BackupChar
= Value
[ValueStrLen
];
924 Value
+= UnicodeValueToString (
926 PREFIX_ZERO
| RADIX_HEX
,
927 PrivateData
->Configuration
.NameValueVar0
,
928 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
934 // Append value of NameValueVar1, type is UINT16
936 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
937 Value
+= StrLen (PrivateData
->NameValueName
[1]);
938 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
939 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
941 BackupChar
= Value
[ValueStrLen
];
943 Value
+= UnicodeValueToString (
945 PREFIX_ZERO
| RADIX_HEX
,
946 PrivateData
->Configuration
.NameValueVar1
,
947 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
953 // Append value of NameValueVar2, type is CHAR16 *
955 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
956 Value
+= StrLen (PrivateData
->NameValueName
[2]);
957 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
958 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
962 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
964 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
965 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
966 Value
+= UnicodeValueToString (Value
, PREFIX_ZERO
| RADIX_HEX
, *StrPointer
, 4);
970 Status
= EFI_SUCCESS
;
973 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
975 Status
= HiiConfigRouting
->BlockToConfig (
978 (UINT8
*) &PrivateData
->Configuration
,
983 if (!EFI_ERROR (Status
)) {
984 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
985 AppendAltCfgString(Results
, ConfigRequestHdr
);
990 // Free the allocated config request string.
992 if (AllocatedRequest
) {
993 FreePool (ConfigRequest
);
996 if (ConfigRequestHdr
!= NULL
) {
997 FreePool (ConfigRequestHdr
);
1000 // Set Progress string to the original request string.
1002 if (Request
== NULL
) {
1004 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1005 *Progress
= Request
+ StrLen (Request
);
1013 This function processes the results of changes in configuration.
1015 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1016 @param Configuration A null-terminated Unicode string in <ConfigResp>
1018 @param Progress A pointer to a string filled in with the offset of
1019 the most recent '&' before the first failing
1020 name/value pair (or the beginning of the string if
1021 the failure is in the first name/value pair) or
1022 the terminating NULL if all was successful.
1024 @retval EFI_SUCCESS The Results is processed successfully.
1025 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1026 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1033 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1034 IN CONST EFI_STRING Configuration
,
1035 OUT EFI_STRING
*Progress
1040 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
1041 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1050 if (Configuration
== NULL
|| Progress
== NULL
) {
1051 return EFI_INVALID_PARAMETER
;
1054 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1055 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
1056 *Progress
= Configuration
;
1059 // Check routing data in <ConfigHdr>.
1060 // Note: if only one Storage is used, then this checking could be skipped.
1062 if (!HiiIsConfigHdrMatch (Configuration
, &gDriverSampleFormSetGuid
, NULL
)) {
1063 return EFI_NOT_FOUND
;
1067 // Check whether request for EFI Varstore. EFI varstore get data
1068 // through hii database, not support in this path.
1070 if (HiiIsConfigHdrMatch(Configuration
, &gDriverSampleFormSetGuid
, MyEfiVar
)) {
1071 return EFI_UNSUPPORTED
;
1075 // Get Buffer Storage data from EFI variable
1077 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1078 Status
= gRT
->GetVariable (
1080 &gDriverSampleFormSetGuid
,
1083 &PrivateData
->Configuration
1085 if (EFI_ERROR (Status
)) {
1090 // Check if configuring Name/Value storage
1092 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
1094 // Update Name/Value storage Names
1096 Status
= LoadNameValueNames (PrivateData
);
1097 if (EFI_ERROR (Status
)) {
1102 // Convert value for NameValueVar0
1104 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
1108 Value
+= StrLen (PrivateData
->NameValueName
[0]);
1113 StrPtr
= StrStr (Value
, L
"&");
1114 if (StrPtr
== NULL
) {
1115 StrPtr
= Value
+ StrLen (Value
);
1118 // Convert Value to Buffer data
1120 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
1121 ZeroMem (TemStr
, sizeof (TemStr
));
1122 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1123 TemStr
[0] = *StrPtr
;
1124 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1125 if ((Index
& 1) == 0) {
1126 DataBuffer
[Index
/2] = DigitUint8
;
1128 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1134 // Convert value for NameValueVar1
1136 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
1140 Value
+= StrLen (PrivateData
->NameValueName
[1]);
1145 StrPtr
= StrStr (Value
, L
"&");
1146 if (StrPtr
== NULL
) {
1147 StrPtr
= Value
+ StrLen (Value
);
1150 // Convert Value to Buffer data
1152 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
1153 ZeroMem (TemStr
, sizeof (TemStr
));
1154 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
1155 TemStr
[0] = *StrPtr
;
1156 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1157 if ((Index
& 1) == 0) {
1158 DataBuffer
[Index
/2] = DigitUint8
;
1160 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
1166 // Convert value for NameValueVar2
1168 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
1172 Value
+= StrLen (PrivateData
->NameValueName
[2]);
1177 StrPtr
= StrStr (Value
, L
"&");
1178 if (StrPtr
== NULL
) {
1179 StrPtr
= Value
+ StrLen (Value
);
1182 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1184 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
1185 ZeroMem (TemStr
, sizeof (TemStr
));
1186 while (Value
< StrPtr
) {
1187 StrnCpy (TemStr
, Value
, 4);
1188 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
1195 // Store Buffer Storage back to EFI variable
1197 Status
= gRT
->SetVariable(
1199 &gDriverSampleFormSetGuid
,
1200 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1201 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1202 &PrivateData
->Configuration
1209 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1211 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1212 Status
= HiiConfigRouting
->ConfigToBlock (
1215 (UINT8
*) &PrivateData
->Configuration
,
1219 if (EFI_ERROR (Status
)) {
1224 // Store Buffer Storage back to EFI variable
1226 Status
= gRT
->SetVariable(
1228 &gDriverSampleFormSetGuid
,
1229 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1230 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1231 &PrivateData
->Configuration
1239 This function processes the results of changes in configuration.
1241 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1242 @param Action Specifies the type of action taken by the browser.
1243 @param QuestionId A unique value which is sent to the original
1244 exporting driver so that it can identify the type
1246 @param Type The type of value for the question.
1247 @param Value A pointer to the data being sent to the original
1249 @param ActionRequest On return, points to the action requested by the
1252 @retval EFI_SUCCESS The callback successfully handled the action.
1253 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1254 variable and its data.
1255 @retval EFI_DEVICE_ERROR The variable could not be saved.
1256 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1263 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1264 IN EFI_BROWSER_ACTION Action
,
1265 IN EFI_QUESTION_ID QuestionId
,
1267 IN EFI_IFR_TYPE_VALUE
*Value
,
1268 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1271 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
;
1280 MY_EFI_VARSTORE_DATA
*EfiData
;
1282 EFI_STRING Progress
;
1287 if (((Value
== NULL
) && (Action
!= EFI_BROWSER_ACTION_FORM_OPEN
) && (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
))||
1288 (ActionRequest
== NULL
)) {
1289 return EFI_INVALID_PARAMETER
;
1295 Status
= EFI_SUCCESS
;
1296 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1299 case EFI_BROWSER_ACTION_FORM_OPEN
:
1301 if (QuestionId
== 0x1234) {
1303 // Sample CallBack for UEFI FORM_OPEN action:
1304 // Add Save action into Form 3 when Form 1 is opened.
1305 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1307 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
1310 // Initialize the container for dynamic opcodes
1312 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1313 ASSERT (StartOpCodeHandle
!= NULL
);
1316 // Create Hii Extend Label OpCode as the start opcode
1318 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1319 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1320 StartLabel
->Number
= LABEL_UPDATE2
;
1322 HiiCreateActionOpCode (
1323 StartOpCodeHandle
, // Container for dynamic created opcodes
1324 0x1238, // Question ID
1325 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
1326 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
1327 EFI_IFR_FLAG_CALLBACK
, // Question flag
1328 0 // Action String ID
1332 PrivateData
->HiiHandle
[0], // HII handle
1333 &gDriverSampleFormSetGuid
, // Formset GUID
1335 StartOpCodeHandle
, // Label for where to insert opcodes
1339 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1342 if (QuestionId
== 0x1247) {
1343 Status
= InternalStartMonitor ();
1344 ASSERT_EFI_ERROR (Status
);
1349 case EFI_BROWSER_ACTION_FORM_CLOSE
:
1351 if (QuestionId
== 0x5678) {
1353 // Sample CallBack for UEFI FORM_CLOSE action:
1354 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1358 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1361 L
"You are going to leave third Form!",
1362 L
"Press ESC or ENTER to continue ...",
1366 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1369 if (QuestionId
== 0x1247) {
1370 Status
= InternalStopMonitor ();
1371 ASSERT_EFI_ERROR (Status
);
1376 case EFI_BROWSER_ACTION_RETRIEVE
:
1378 if (QuestionId
== 0x1248) {
1380 if (Type
!= EFI_IFR_TYPE_REF
) {
1381 return EFI_INVALID_PARAMETER
;
1384 Value
->ref
.FormId
= 0x3;
1390 case EFI_BROWSER_ACTION_DEFAULT_STANDARD
:
1392 switch (QuestionId
) {
1394 Value
->u8
= DEFAULT_CLASS_STANDARD_VALUE
;
1398 Status
= EFI_UNSUPPORTED
;
1404 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
:
1406 switch (QuestionId
) {
1408 Value
->u8
= DEFAULT_CLASS_MANUFACTURING_VALUE
;
1412 Status
= EFI_UNSUPPORTED
;
1418 case EFI_BROWSER_ACTION_CHANGING
:
1420 switch (QuestionId
) {
1423 if (Type
!= EFI_IFR_TYPE_REF
) {
1424 return EFI_INVALID_PARAMETER
;
1427 Value
->ref
.FormId
= 0x1234;
1432 // Initialize the container for dynamic opcodes
1434 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1435 ASSERT (StartOpCodeHandle
!= NULL
);
1437 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1438 ASSERT (EndOpCodeHandle
!= NULL
);
1441 // Create Hii Extend Label OpCode as the start opcode
1443 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1444 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1445 StartLabel
->Number
= LABEL_UPDATE1
;
1448 // Create Hii Extend Label OpCode as the end opcode
1450 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1451 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1452 EndLabel
->Number
= LABEL_END
;
1454 HiiCreateActionOpCode (
1455 StartOpCodeHandle
, // Container for dynamic created opcodes
1456 0x1237, // Question ID
1457 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1458 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1459 EFI_IFR_FLAG_CALLBACK
, // Question flag
1460 0 // Action String ID
1464 // Create Option OpCode
1466 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
1467 ASSERT (OptionsOpCodeHandle
!= NULL
);
1469 HiiCreateOneOfOptionOpCode (
1470 OptionsOpCodeHandle
,
1471 STRING_TOKEN (STR_BOOT_OPTION1
),
1473 EFI_IFR_NUMERIC_SIZE_1
,
1477 HiiCreateOneOfOptionOpCode (
1478 OptionsOpCodeHandle
,
1479 STRING_TOKEN (STR_BOOT_OPTION2
),
1481 EFI_IFR_NUMERIC_SIZE_1
,
1486 // Prepare initial value for the dynamic created oneof Question
1488 PrivateData
->Configuration
.DynamicOneof
= 2;
1489 Status
= gRT
->SetVariable(
1491 &gDriverSampleFormSetGuid
,
1492 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1493 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1494 &PrivateData
->Configuration
1498 // Set initial vlaue of dynamic created oneof Question in Form Browser
1500 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1501 ASSERT (Configuration
!= NULL
);
1502 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
1503 Configuration
->DynamicOneof
= 2;
1506 // Update uncommitted data of Browser
1509 &gDriverSampleFormSetGuid
,
1511 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1512 (UINT8
*) Configuration
,
1516 FreePool (Configuration
);
1518 HiiCreateOneOfOpCode (
1519 StartOpCodeHandle
, // Container for dynamic created opcodes
1520 0x8001, // Question ID (or call it "key")
1521 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1522 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1523 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1524 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1525 EFI_IFR_FLAG_CALLBACK
, // Question flag
1526 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1527 OptionsOpCodeHandle
, // Option Opcode list
1528 NULL
// Default Opcode is NULl
1531 HiiCreateOrderedListOpCode (
1532 StartOpCodeHandle
, // Container for dynamic created opcodes
1533 0x8002, // Question ID
1534 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1535 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1536 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1537 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1538 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1539 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1540 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1541 5, // Maximum container
1542 OptionsOpCodeHandle
, // Option Opcode list
1543 NULL
// Default Opcode is NULl
1546 HiiCreateTextOpCode (
1548 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1549 STRING_TOKEN(STR_TEXT_SAMPLE_HELP
),
1550 STRING_TOKEN(STR_TEXT_SAMPLE_STRING
)
1553 HiiCreateDateOpCode (
1558 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1559 STRING_TOKEN(STR_DATE_SAMPLE_HELP
),
1561 QF_DATE_STORAGE_TIME
,
1565 HiiCreateTimeOpCode (
1570 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1571 STRING_TOKEN(STR_TIME_SAMPLE_HELP
),
1573 QF_TIME_STORAGE_TIME
,
1577 HiiCreateGotoOpCode (
1578 StartOpCodeHandle
, // Container for dynamic created opcodes
1579 1, // Target Form ID
1580 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1581 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1583 0x8003 // Question ID
1587 PrivateData
->HiiHandle
[0], // HII handle
1588 &gDriverSampleFormSetGuid
, // Formset GUID
1590 StartOpCodeHandle
, // Label for where to insert opcodes
1591 EndOpCodeHandle
// Replace data
1594 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1595 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1596 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1602 // We will reach here once the Question is refreshed
1606 // Initialize the container for dynamic opcodes
1608 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1609 ASSERT (StartOpCodeHandle
!= NULL
);
1612 // Create Hii Extend Label OpCode as the start opcode
1614 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1615 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1616 if (QuestionId
== 0x5678) {
1617 StartLabel
->Number
= LABEL_UPDATE2
;
1619 PrivateData
->Configuration
.DynamicRefresh
++;
1620 } else if (QuestionId
== 0x1247 ) {
1621 StartLabel
->Number
= LABEL_UPDATE3
;
1623 PrivateData
->Configuration
.RefreshGuidCount
++;
1626 HiiCreateActionOpCode (
1627 StartOpCodeHandle
, // Container for dynamic created opcodes
1628 0x1237, // Question ID
1629 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1630 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1631 EFI_IFR_FLAG_CALLBACK
, // Question flag
1632 0 // Action String ID
1636 PrivateData
->HiiHandle
[0], // HII handle
1637 &gDriverSampleFormSetGuid
, // Formset GUID
1639 StartOpCodeHandle
, // Label for where to insert opcodes
1643 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1646 // Refresh the Question value
1648 Status
= gRT
->SetVariable(
1650 &gDriverSampleFormSetGuid
,
1651 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1652 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1653 &PrivateData
->Configuration
1656 if (QuestionId
== 0x5678) {
1658 // Update uncommitted data of Browser
1660 EfiData
= AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA
));
1661 ASSERT (EfiData
!= NULL
);
1662 if (HiiGetBrowserData (&gDriverSampleFormSetGuid
, MyEfiVar
, sizeof (MY_EFI_VARSTORE_DATA
), (UINT8
*) EfiData
)) {
1663 EfiData
->Field8
= 111;
1665 &gDriverSampleFormSetGuid
,
1667 sizeof (MY_EFI_VARSTORE_DATA
),
1678 // Only used to update the state.
1680 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0) &&
1681 (PrivateData
->PasswordState
== BROWSER_STATE_SET_PASSWORD
)) {
1682 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1683 return EFI_INVALID_PARAMETER
;
1687 // When try to set a new password, user will be chanlleged with old password.
1688 // The Callback is responsible for validating old password input by user,
1689 // If Callback return EFI_SUCCESS, it indicates validation pass.
1691 switch (PrivateData
->PasswordState
) {
1692 case BROWSER_STATE_VALIDATE_PASSWORD
:
1693 Status
= ValidatePassword (PrivateData
, Value
->string
);
1694 if (Status
== EFI_SUCCESS
) {
1695 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
1699 case BROWSER_STATE_SET_PASSWORD
:
1700 Status
= SetPassword (PrivateData
, Value
->string
);
1701 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1716 case EFI_BROWSER_ACTION_CHANGED
:
1717 switch (QuestionId
) {
1720 // User press "Exit now", request Browser to exit
1722 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1727 // User press "Save now", request Browser to save the uncommitted data.
1729 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1735 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1737 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1742 // User press "Discard current form now", request Browser to discard the uncommitted data.
1744 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
;
1749 // User press "Submit current form now", request Browser to save the uncommitted data.
1751 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1757 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1759 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1764 // 1. Check to see whether system support keyword.
1766 Status
= PrivateData
->HiiKeywordHandler
->GetData (PrivateData
->HiiKeywordHandler
,
1767 L
"NAMESPACE=x-UEFI-ns",
1768 L
"KEYWORD=iSCSIBootEnable",
1773 if (EFI_ERROR (Status
)) {
1776 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1779 L
"This system not support this keyword!",
1780 L
"Press ENTER to continue ...",
1784 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1786 Status
= EFI_SUCCESS
;
1791 // 2. If system support this keyword, just try to change value.
1795 // Change value from '0' to '1' or from '1' to '0'
1797 TmpStr
= StrStr (Results
, L
"&VALUE=");
1798 ASSERT (TmpStr
!= NULL
);
1799 TmpStr
+= StrLen (L
"&VALUE=");
1801 if (*TmpStr
== L
'0') {
1808 // 3. Call the keyword handler protocol to change the value.
1810 Status
= PrivateData
->HiiKeywordHandler
->SetData (PrivateData
->HiiKeywordHandler
,
1815 if (EFI_ERROR (Status
)) {
1818 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1821 L
"Set keyword to the system failed!",
1822 L
"Press ENTER to continue ...",
1826 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1828 Status
= EFI_SUCCESS
;
1839 Status
= EFI_UNSUPPORTED
;
1847 Main entry for this driver.
1849 @param ImageHandle Image handle this driver.
1850 @param SystemTable Pointer to SystemTable.
1852 @retval EFI_SUCESS This function always complete successfully.
1858 IN EFI_HANDLE ImageHandle
,
1859 IN EFI_SYSTEM_TABLE
*SystemTable
1863 EFI_HII_HANDLE HiiHandle
[2];
1864 EFI_SCREEN_DESCRIPTOR Screen
;
1865 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1866 EFI_HII_STRING_PROTOCOL
*HiiString
;
1867 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1868 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1869 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL
*HiiKeywordHandler
;
1872 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1874 EFI_STRING ConfigRequestHdr
;
1875 EFI_STRING NameRequestHdr
;
1876 MY_EFI_VARSTORE_DATA
*VarStoreConfig
;
1877 EFI_INPUT_KEY HotKey
;
1878 EFI_FORM_BROWSER_EXTENSION_PROTOCOL
*FormBrowserEx
;
1881 // Initialize the local variables.
1883 ConfigRequestHdr
= NULL
;
1887 // Initialize screen dimensions for SendForm().
1888 // Remove 3 characters from top and bottom
1890 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1891 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1894 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1897 // Initialize driver private data
1899 PrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1900 if (PrivateData
== NULL
) {
1901 return EFI_OUT_OF_RESOURCES
;
1904 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1906 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1907 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1908 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1909 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1912 // Locate Hii Database protocol
1914 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1915 if (EFI_ERROR (Status
)) {
1918 PrivateData
->HiiDatabase
= HiiDatabase
;
1921 // Locate HiiString protocol
1923 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1924 if (EFI_ERROR (Status
)) {
1927 PrivateData
->HiiString
= HiiString
;
1930 // Locate Formbrowser2 protocol
1932 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1933 if (EFI_ERROR (Status
)) {
1936 PrivateData
->FormBrowser2
= FormBrowser2
;
1939 // Locate ConfigRouting protocol
1941 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1942 if (EFI_ERROR (Status
)) {
1945 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1948 // Locate keyword handler protocol
1950 Status
= gBS
->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid
, NULL
, (VOID
**) &HiiKeywordHandler
);
1951 if (EFI_ERROR (Status
)) {
1954 PrivateData
->HiiKeywordHandler
= HiiKeywordHandler
;
1956 Status
= gBS
->InstallMultipleProtocolInterfaces (
1958 &gEfiDevicePathProtocolGuid
,
1959 &mHiiVendorDevicePath0
,
1960 &gEfiHiiConfigAccessProtocolGuid
,
1961 &PrivateData
->ConfigAccess
,
1964 ASSERT_EFI_ERROR (Status
);
1966 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
1969 // Publish our HII data
1971 HiiHandle
[0] = HiiAddPackages (
1972 &gDriverSampleFormSetGuid
,
1974 DriverSampleStrings
,
1978 if (HiiHandle
[0] == NULL
) {
1979 return EFI_OUT_OF_RESOURCES
;
1982 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
1985 // Publish another Fromset
1987 Status
= gBS
->InstallMultipleProtocolInterfaces (
1989 &gEfiDevicePathProtocolGuid
,
1990 &mHiiVendorDevicePath1
,
1991 &gEfiHiiConfigAccessProtocolGuid
,
1992 &PrivateData
->ConfigAccess
,
1995 ASSERT_EFI_ERROR (Status
);
1997 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
1999 HiiHandle
[1] = HiiAddPackages (
2000 &gDriverSampleInventoryGuid
,
2002 DriverSampleStrings
,
2006 if (HiiHandle
[1] == NULL
) {
2007 DriverSampleUnload (ImageHandle
);
2008 return EFI_OUT_OF_RESOURCES
;
2011 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
2014 // Update the device path string.
2016 NewString
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)&mHiiVendorDevicePath0
, FALSE
, FALSE
);
2017 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_DEVICE_PATH
), NewString
, NULL
) == 0) {
2018 DriverSampleUnload (ImageHandle
);
2019 return EFI_OUT_OF_RESOURCES
;
2021 if (NewString
!= NULL
) {
2022 FreePool (NewString
);
2026 // Very simple example of how one would update a string that is already
2027 // in the HII database
2029 NewString
= L
"700 Mhz";
2031 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
2032 DriverSampleUnload (ImageHandle
);
2033 return EFI_OUT_OF_RESOURCES
;
2036 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
2039 // Initialize Name/Value name String ID
2041 PrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
2042 PrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
2043 PrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
2046 // Initialize configuration data
2048 Configuration
= &PrivateData
->Configuration
;
2049 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
2052 // Try to read NV config EFI variable first
2054 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, VariableName
, DriverHandle
[0]);
2055 ASSERT (ConfigRequestHdr
!= NULL
);
2057 NameRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, NULL
, DriverHandle
[0]);
2058 ASSERT (NameRequestHdr
!= NULL
);
2060 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
2061 Status
= gRT
->GetVariable (VariableName
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, Configuration
);
2062 if (EFI_ERROR (Status
)) {
2064 // Store zero data Buffer Storage to EFI variable
2066 Status
= gRT
->SetVariable(
2068 &gDriverSampleFormSetGuid
,
2069 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2070 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
2073 if (EFI_ERROR (Status
)) {
2074 DriverSampleUnload (ImageHandle
);
2078 // EFI variable for NV config doesn't exit, we should build this variable
2079 // based on default values stored in IFR
2081 ActionFlag
= HiiSetToDefaults (NameRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2083 DriverSampleUnload (ImageHandle
);
2084 return EFI_INVALID_PARAMETER
;
2087 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2089 DriverSampleUnload (ImageHandle
);
2090 return EFI_INVALID_PARAMETER
;
2094 // EFI variable does exist and Validate Current Setting
2096 ActionFlag
= HiiValidateSettings (NameRequestHdr
);
2098 DriverSampleUnload (ImageHandle
);
2099 return EFI_INVALID_PARAMETER
;
2102 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2104 DriverSampleUnload (ImageHandle
);
2105 return EFI_INVALID_PARAMETER
;
2108 FreePool (ConfigRequestHdr
);
2111 // Initialize efi varstore configuration data
2113 VarStoreConfig
= &PrivateData
->VarStoreConfig
;
2114 ZeroMem (VarStoreConfig
, sizeof (MY_EFI_VARSTORE_DATA
));
2116 ConfigRequestHdr
= HiiConstructConfigHdr (&gDriverSampleFormSetGuid
, MyEfiVar
, DriverHandle
[0]);
2117 ASSERT (ConfigRequestHdr
!= NULL
);
2119 BufferSize
= sizeof (MY_EFI_VARSTORE_DATA
);
2120 Status
= gRT
->GetVariable (MyEfiVar
, &gDriverSampleFormSetGuid
, NULL
, &BufferSize
, VarStoreConfig
);
2121 if (EFI_ERROR (Status
)) {
2123 // Store zero data to EFI variable Storage.
2125 Status
= gRT
->SetVariable(
2127 &gDriverSampleFormSetGuid
,
2128 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
2129 sizeof (MY_EFI_VARSTORE_DATA
),
2132 if (EFI_ERROR (Status
)) {
2133 DriverSampleUnload (ImageHandle
);
2137 // EFI variable for NV config doesn't exit, we should build this variable
2138 // based on default values stored in IFR
2140 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2142 DriverSampleUnload (ImageHandle
);
2143 return EFI_INVALID_PARAMETER
;
2147 // EFI variable does exist and Validate Current Setting
2149 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
2151 DriverSampleUnload (ImageHandle
);
2152 return EFI_INVALID_PARAMETER
;
2155 FreePool (ConfigRequestHdr
);
2157 Status
= gBS
->CreateEventEx (
2160 DriverSampleInternalEmptyFunction
,
2162 &gEfiIfrRefreshIdOpGuid
,
2165 ASSERT_EFI_ERROR (Status
);
2168 // Example of how to use BrowserEx protocol to register HotKey.
2170 Status
= gBS
->LocateProtocol (&gEfiFormBrowserExProtocolGuid
, NULL
, (VOID
**) &FormBrowserEx
);
2171 if (!EFI_ERROR (Status
)) {
2173 // First unregister the default hot key F9 and F10.
2175 HotKey
.UnicodeChar
= CHAR_NULL
;
2176 HotKey
.ScanCode
= SCAN_F9
;
2177 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2178 HotKey
.ScanCode
= SCAN_F10
;
2179 FormBrowserEx
->RegisterHotKey (&HotKey
, 0, 0, NULL
);
2182 // Register the default HotKey F9 and F10 again.
2184 HotKey
.ScanCode
= SCAN_F10
;
2185 NewString
= HiiGetString (PrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_TEN_STRING
), NULL
);
2186 ASSERT (NewString
!= NULL
);
2187 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_SUBMIT
, 0, NewString
);
2188 HotKey
.ScanCode
= SCAN_F9
;
2189 NewString
= HiiGetString (PrivateData
->HiiHandle
[0], STRING_TOKEN (FUNCTION_NINE_STRING
), NULL
);
2190 ASSERT (NewString
!= NULL
);
2191 FormBrowserEx
->RegisterHotKey (&HotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, NewString
);
2195 // In default, this driver is built into Flash device image,
2196 // the following code doesn't run.
2200 // Example of how to display only the item we sent to HII
2201 // When this driver is not built into Flash device image,
2202 // it need to call SendForm to show front page by itself.
2204 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
2206 // Have the browser pull out our copy of the data, and only display our data
2208 Status
= FormBrowser2
->SendForm (
2210 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
2218 HiiRemovePackages (HiiHandle
[0]);
2220 HiiRemovePackages (HiiHandle
[1]);
2227 Unloads the application and its installed protocol.
2229 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2231 @retval EFI_SUCCESS The image has been unloaded.
2235 DriverSampleUnload (
2236 IN EFI_HANDLE ImageHandle
2241 ASSERT (PrivateData
!= NULL
);
2243 if (DriverHandle
[0] != NULL
) {
2244 gBS
->UninstallMultipleProtocolInterfaces (
2246 &gEfiDevicePathProtocolGuid
,
2247 &mHiiVendorDevicePath0
,
2248 &gEfiHiiConfigAccessProtocolGuid
,
2249 &PrivateData
->ConfigAccess
,
2252 DriverHandle
[0] = NULL
;
2255 if (DriverHandle
[1] != NULL
) {
2256 gBS
->UninstallMultipleProtocolInterfaces (
2258 &gEfiDevicePathProtocolGuid
,
2259 &mHiiVendorDevicePath1
,
2262 DriverHandle
[1] = NULL
;
2265 if (PrivateData
->HiiHandle
[0] != NULL
) {
2266 HiiRemovePackages (PrivateData
->HiiHandle
[0]);
2269 if (PrivateData
->HiiHandle
[1] != NULL
) {
2270 HiiRemovePackages (PrivateData
->HiiHandle
[1]);
2273 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
2274 if (PrivateData
->NameValueName
[Index
] != NULL
) {
2275 FreePool (PrivateData
->NameValueName
[Index
]);
2278 FreePool (PrivateData
);
2281 gBS
->CloseEvent (mEvent
);