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 - 2010, 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
;
24 CHAR16 VariableName
[] = L
"MyIfrNVData";
25 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
26 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
= NULL
;
28 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
34 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
35 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
39 // {C153B68D-EBFC-488e-B110-662867745B87}
41 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }
45 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
47 (UINT8
) (END_DEVICE_PATH_LENGTH
),
48 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
53 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
59 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
60 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
64 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}
66 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }
70 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
72 (UINT8
) (END_DEVICE_PATH_LENGTH
),
73 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
79 Encode the password using a simple algorithm.
81 @param Password The string to be encoded.
82 @param MaxSize The size of the string.
97 Buffer
= AllocateZeroPool (MaxSize
);
98 ASSERT (Buffer
!= NULL
);
100 for (Index
= 0; Key
[Index
] != 0; Index
++) {
101 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
102 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
106 CopyMem (Password
, Buffer
, MaxSize
);
113 Validate the user's password.
115 @param PrivateData This driver's private context data.
116 @param StringId The user's input.
118 @retval EFI_SUCCESS The user's input matches the password.
119 @retval EFI_NOT_READY The user's input does not match the password.
123 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
124 IN EFI_STRING_ID StringId
130 UINTN PasswordMaxSize
;
132 CHAR16
*EncodedPassword
;
136 // Get encoded password first
138 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
139 Status
= gRT
->GetVariable (
144 &PrivateData
->Configuration
146 if (EFI_ERROR (Status
)) {
148 // Old password not exist, prompt for new password
154 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
156 // Check whether we have any old password set
158 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
159 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
166 // Old password not exist, return EFI_SUCCESS to prompt for new password
172 // Get user input password
174 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
175 if (Password
== NULL
) {
176 return EFI_NOT_READY
;
178 if (StrSize (Password
) > PasswordMaxSize
) {
180 return EFI_NOT_READY
;
184 // Validate old password
186 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
187 ASSERT (EncodedPassword
!= NULL
);
188 StrnCpy (EncodedPassword
, Password
, StrLen (Password
));
189 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
190 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, StrLen (EncodedPassword
) * sizeof (CHAR16
)) != 0) {
192 // Old password mismatch, return EFI_NOT_READY to prompt for error message
194 Status
= EFI_NOT_READY
;
196 Status
= EFI_SUCCESS
;
200 FreePool (EncodedPassword
);
206 Encode the password using a simple algorithm.
208 @param PrivateData This driver's private context data.
209 @param StringId The password from User.
211 @retval EFI_SUCESS The operation is successful.
212 @return Other value if gRT->SetVariable () fails.
217 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
218 IN EFI_STRING_ID StringId
223 CHAR16
*TempPassword
;
225 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
229 // Get Buffer Storage data from EFI variable
231 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
232 Status
= gRT
->GetVariable (
237 &PrivateData
->Configuration
239 if (EFI_ERROR (Status
)) {
244 // Get user input password
246 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
247 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
248 ZeroMem (Password
, PasswordSize
);
250 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
251 if (TempPassword
== NULL
) {
252 return EFI_NOT_READY
;
254 if (StrSize (TempPassword
) > PasswordSize
) {
255 FreePool (TempPassword
);
256 return EFI_NOT_READY
;
258 StrnCpy (Password
, TempPassword
, StrLen (TempPassword
));
259 FreePool (TempPassword
);
262 // Retrive uncommitted data from Browser
264 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
265 ASSERT (Configuration
!= NULL
);
266 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
268 // Update password's clear text in the screen
270 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
273 // Update uncommitted data of Browser
278 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
279 (UINT8
*) Configuration
,
285 // Free Configuration Buffer
287 FreePool (Configuration
);
293 EncodePassword (Password
, StrLen (Password
) * 2);
294 Status
= gRT
->SetVariable(
297 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
298 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
299 &PrivateData
->Configuration
305 Update names of Name/Value storage to current language.
307 @param PrivateData Points to the driver private data.
309 @retval EFI_SUCCESS All names are successfully updated.
310 @retval EFI_NOT_FOUND Failed to get Name from HII database.
315 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
321 // Get Name/Value name string of current language
323 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
324 PrivateData
->NameValueName
[Index
] = HiiGetString (
325 PrivateData
->HiiHandle
[0],
326 PrivateData
->NameStringId
[Index
],
329 if (PrivateData
->NameValueName
[Index
] == NULL
) {
330 return EFI_NOT_FOUND
;
338 This function allows a caller to extract the current configuration for one
339 or more named elements from the target driver.
341 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
342 @param Request A null-terminated Unicode string in
343 <ConfigRequest> format.
344 @param Progress On return, points to a character in the Request
345 string. Points to the string's null terminator if
346 request was successful. Points to the most recent
347 '&' before the first failing name/value pair (or
348 the beginning of the string if the failure is in
349 the first name/value pair) if the request was not
351 @param Results A null-terminated Unicode string in
352 <ConfigAltResp> format which has all values filled
353 in for the names in the Request string. String to
354 be allocated by the called function.
356 @retval EFI_SUCCESS The Results is filled with the requested values.
357 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
358 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
359 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
366 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
367 IN CONST EFI_STRING Request
,
368 OUT EFI_STRING
*Progress
,
369 OUT EFI_STRING
*Results
374 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
375 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
376 EFI_STRING ConfigRequest
;
377 EFI_STRING ConfigRequestHdr
;
383 BOOLEAN AllocatedRequest
;
385 if (Progress
== NULL
|| Results
== NULL
) {
386 return EFI_INVALID_PARAMETER
;
389 // Initialize the local variables.
391 ConfigRequestHdr
= NULL
;
392 ConfigRequest
= NULL
;
395 AllocatedRequest
= FALSE
;
397 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
398 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
401 // Get Buffer Storage data from EFI variable.
402 // Try to get the current setting from variable.
404 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
405 Status
= gRT
->GetVariable (
410 &PrivateData
->Configuration
412 if (EFI_ERROR (Status
)) {
413 return EFI_NOT_FOUND
;
416 if (Request
== NULL
) {
418 // Request is set to NULL, construct full request string.
422 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
423 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
425 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
426 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
427 ConfigRequest
= AllocateZeroPool (Size
);
428 ASSERT (ConfigRequest
!= NULL
);
429 AllocatedRequest
= TRUE
;
430 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
431 FreePool (ConfigRequestHdr
);
434 // Check routing data in <ConfigHdr>.
435 // Note: if only one Storage is used, then this checking could be skipped.
437 if (!HiiIsConfigHdrMatch (Request
, &mFormSetGuid
, NULL
)) {
438 return EFI_NOT_FOUND
;
441 // Set Request to the unified request string.
443 ConfigRequest
= Request
;
445 // Check whether Request includes Request Element.
447 if (StrStr (Request
, L
"OFFSET") == NULL
) {
449 // Check Request Element does exist in Reques String
451 StrPointer
= StrStr (Request
, L
"PATH");
452 if (StrPointer
== NULL
) {
453 return EFI_INVALID_PARAMETER
;
455 if (StrStr (StrPointer
, L
"&") == NULL
) {
456 Size
= (StrLen (Request
) + 32 + 1) * sizeof (CHAR16
);
457 ConfigRequest
= AllocateZeroPool (Size
);
458 ASSERT (ConfigRequest
!= NULL
);
459 AllocatedRequest
= TRUE
;
460 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", Request
, (UINT64
)BufferSize
);
466 // Check if requesting Name/Value storage
468 if (StrStr (ConfigRequest
, L
"OFFSET") == NULL
) {
470 // Update Name/Value storage Names
472 Status
= LoadNameValueNames (PrivateData
);
473 if (EFI_ERROR (Status
)) {
478 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
479 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
480 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
482 BufferSize
= (StrLen (ConfigRequest
) +
483 1 + sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2 +
484 1 + sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2 +
485 1 + sizeof (PrivateData
->Configuration
.NameValueVar2
) * 2 + 1) * sizeof (CHAR16
);
486 *Results
= AllocateZeroPool (BufferSize
);
487 ASSERT (*Results
!= NULL
);
488 StrCpy (*Results
, ConfigRequest
);
492 // Append value of NameValueVar0, type is UINT8
494 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[0])) != NULL
) {
495 Value
+= StrLen (PrivateData
->NameValueName
[0]);
496 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2) + 1);
497 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
499 BackupChar
= Value
[ValueStrLen
];
501 Value
+= UnicodeValueToString (
503 PREFIX_ZERO
| RADIX_HEX
,
504 PrivateData
->Configuration
.NameValueVar0
,
505 sizeof (PrivateData
->Configuration
.NameValueVar0
) * 2
511 // Append value of NameValueVar1, type is UINT16
513 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[1])) != NULL
) {
514 Value
+= StrLen (PrivateData
->NameValueName
[1]);
515 ValueStrLen
= ((sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2) + 1);
516 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
518 BackupChar
= Value
[ValueStrLen
];
520 Value
+= UnicodeValueToString (
522 PREFIX_ZERO
| RADIX_HEX
,
523 PrivateData
->Configuration
.NameValueVar1
,
524 sizeof (PrivateData
->Configuration
.NameValueVar1
) * 2
530 // Append value of NameValueVar2, type is CHAR16 *
532 if ((Value
= StrStr (*Results
, PrivateData
->NameValueName
[2])) != NULL
) {
533 Value
+= StrLen (PrivateData
->NameValueName
[2]);
534 ValueStrLen
= StrLen (PrivateData
->Configuration
.NameValueVar2
) * 4 + 1;
535 CopyMem (Value
+ ValueStrLen
, Value
, StrSize (Value
));
539 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
541 StrPointer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
542 for (; *StrPointer
!= L
'\0'; StrPointer
++) {
543 Value
+= UnicodeValueToString (Value
, PREFIX_ZERO
| RADIX_HEX
, *StrPointer
, 4);
547 Status
= EFI_SUCCESS
;
550 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
552 Status
= HiiConfigRouting
->BlockToConfig (
555 (UINT8
*) &PrivateData
->Configuration
,
563 // Free the allocated config request string.
565 if (AllocatedRequest
) {
566 FreePool (ConfigRequest
);
569 // Set Progress string to the original request string.
571 if (Request
== NULL
) {
573 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
574 *Progress
= Request
+ StrLen (Request
);
582 This function processes the results of changes in configuration.
584 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
585 @param Configuration A null-terminated Unicode string in <ConfigResp>
587 @param Progress A pointer to a string filled in with the offset of
588 the most recent '&' before the first failing
589 name/value pair (or the beginning of the string if
590 the failure is in the first name/value pair) or
591 the terminating NULL if all was successful.
593 @retval EFI_SUCCESS The Results is processed successfully.
594 @retval EFI_INVALID_PARAMETER Configuration is NULL.
595 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
602 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
603 IN CONST EFI_STRING Configuration
,
604 OUT EFI_STRING
*Progress
609 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
610 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
619 if (Configuration
== NULL
|| Progress
== NULL
) {
620 return EFI_INVALID_PARAMETER
;
623 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
624 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
625 *Progress
= Configuration
;
628 // Check routing data in <ConfigHdr>.
629 // Note: if only one Storage is used, then this checking could be skipped.
631 if (!HiiIsConfigHdrMatch (Configuration
, &mFormSetGuid
, NULL
)) {
632 return EFI_NOT_FOUND
;
636 // Get Buffer Storage data from EFI variable
638 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
639 Status
= gRT
->GetVariable (
644 &PrivateData
->Configuration
646 if (EFI_ERROR (Status
)) {
651 // Check if configuring Name/Value storage
653 if (StrStr (Configuration
, L
"OFFSET") == NULL
) {
655 // Update Name/Value storage Names
657 Status
= LoadNameValueNames (PrivateData
);
658 if (EFI_ERROR (Status
)) {
663 // Convert value for NameValueVar0
665 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[0])) != NULL
) {
669 Value
+= StrLen (PrivateData
->NameValueName
[0]);
674 StrPtr
= StrStr (Value
, L
"&");
675 if (StrPtr
== NULL
) {
676 StrPtr
= Value
+ StrLen (Value
);
679 // Convert Value to Buffer data
681 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar0
;
682 ZeroMem (TemStr
, sizeof (TemStr
));
683 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
685 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
686 if ((Index
& 1) == 0) {
687 DataBuffer
[Index
/2] = DigitUint8
;
689 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
695 // Convert value for NameValueVar1
697 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[1])) != NULL
) {
701 Value
+= StrLen (PrivateData
->NameValueName
[1]);
706 StrPtr
= StrStr (Value
, L
"&");
707 if (StrPtr
== NULL
) {
708 StrPtr
= Value
+ StrLen (Value
);
711 // Convert Value to Buffer data
713 DataBuffer
= (UINT8
*) &PrivateData
->Configuration
.NameValueVar1
;
714 ZeroMem (TemStr
, sizeof (TemStr
));
715 for (Index
= 0, StrPtr
--; StrPtr
>= Value
; StrPtr
--, Index
++) {
717 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
718 if ((Index
& 1) == 0) {
719 DataBuffer
[Index
/2] = DigitUint8
;
721 DataBuffer
[Index
/2] = (UINT8
) ((UINT8
) (DigitUint8
<< 4) + DataBuffer
[Index
/2]);
727 // Convert value for NameValueVar2
729 if ((Value
= StrStr (Configuration
, PrivateData
->NameValueName
[2])) != NULL
) {
733 Value
+= StrLen (PrivateData
->NameValueName
[2]);
738 StrPtr
= StrStr (Value
, L
"&");
739 if (StrPtr
== NULL
) {
740 StrPtr
= Value
+ StrLen (Value
);
743 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
745 StrBuffer
= (CHAR16
*) PrivateData
->Configuration
.NameValueVar2
;
746 ZeroMem (TemStr
, sizeof (TemStr
));
747 while (Value
< StrPtr
) {
748 StrnCpy (TemStr
, Value
, 4);
749 *(StrBuffer
++) = (CHAR16
) StrHexToUint64 (TemStr
);
756 // Store Buffer Storage back to EFI variable
758 Status
= gRT
->SetVariable(
761 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
762 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
763 &PrivateData
->Configuration
770 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
772 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
773 Status
= HiiConfigRouting
->ConfigToBlock (
776 (UINT8
*) &PrivateData
->Configuration
,
780 if (EFI_ERROR (Status
)) {
785 // Store Buffer Storage back to EFI variable
787 Status
= gRT
->SetVariable(
790 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
791 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
792 &PrivateData
->Configuration
800 This function processes the results of changes in configuration.
802 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
803 @param Action Specifies the type of action taken by the browser.
804 @param QuestionId A unique value which is sent to the original
805 exporting driver so that it can identify the type
807 @param Type The type of value for the question.
808 @param Value A pointer to the data being sent to the original
810 @param ActionRequest On return, points to the action requested by the
813 @retval EFI_SUCCESS The callback successfully handled the action.
814 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
815 variable and its data.
816 @retval EFI_DEVICE_ERROR The variable could not be saved.
817 @retval EFI_UNSUPPORTED The specified Action is not supported by the
824 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
825 IN EFI_BROWSER_ACTION Action
,
826 IN EFI_QUESTION_ID QuestionId
,
828 IN EFI_IFR_TYPE_VALUE
*Value
,
829 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
832 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
835 VOID
*StartOpCodeHandle
;
836 VOID
*OptionsOpCodeHandle
;
837 EFI_IFR_GUID_LABEL
*StartLabel
;
838 VOID
*EndOpCodeHandle
;
839 EFI_IFR_GUID_LABEL
*EndLabel
;
841 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
844 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
846 // On FORM_OPEN event, update the form on-the-fly
848 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
851 // Initialize the container for dynamic opcodes
853 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
854 ASSERT (StartOpCodeHandle
!= NULL
);
857 // Create Hii Extend Label OpCode as the start opcode
859 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
860 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
861 StartLabel
->Number
= LABEL_UPDATE2
;
863 HiiCreateActionOpCode (
864 StartOpCodeHandle
, // Container for dynamic created opcodes
865 0x1238, // Question ID
866 STRING_TOKEN(STR_SAVE_TEXT
), // Prompt text
867 STRING_TOKEN(STR_SAVE_TEXT
), // Help text
868 EFI_IFR_FLAG_CALLBACK
, // Question flag
869 0 // Action String ID
873 PrivateData
->HiiHandle
[0], // HII handle
874 &mFormSetGuid
, // Formset GUID
876 StartOpCodeHandle
, // Label for where to insert opcodes
880 HiiFreeOpCodeHandle (StartOpCodeHandle
);
884 if (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
) {
886 // On FORM_CLOSE event, show up a pop-up
890 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
893 L
"You are going to leave the Form!",
894 L
"Press ESC or ENTER to continue ...",
898 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
903 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
904 return EFI_INVALID_PARAMETER
;
907 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0)) {
908 return EFI_INVALID_PARAMETER
;
911 Status
= EFI_SUCCESS
;
912 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
914 switch (QuestionId
) {
917 // Initialize the container for dynamic opcodes
919 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
920 ASSERT (StartOpCodeHandle
!= NULL
);
922 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
923 ASSERT (EndOpCodeHandle
!= NULL
);
926 // Create Hii Extend Label OpCode as the start opcode
928 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
929 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
930 StartLabel
->Number
= LABEL_UPDATE1
;
933 // Create Hii Extend Label OpCode as the end opcode
935 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
936 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
937 EndLabel
->Number
= LABEL_END
;
939 HiiCreateActionOpCode (
940 StartOpCodeHandle
, // Container for dynamic created opcodes
941 0x1237, // Question ID
942 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
943 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
944 EFI_IFR_FLAG_CALLBACK
, // Question flag
945 0 // Action String ID
949 // Create Option OpCode
951 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
952 ASSERT (OptionsOpCodeHandle
!= NULL
);
954 HiiCreateOneOfOptionOpCode (
956 STRING_TOKEN (STR_BOOT_OPTION1
),
958 EFI_IFR_NUMERIC_SIZE_1
,
962 HiiCreateOneOfOptionOpCode (
964 STRING_TOKEN (STR_BOOT_OPTION2
),
966 EFI_IFR_NUMERIC_SIZE_1
,
971 // Prepare initial value for the dynamic created oneof Question
973 PrivateData
->Configuration
.DynamicOneof
= 2;
974 Status
= gRT
->SetVariable(
977 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
978 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
979 &PrivateData
->Configuration
983 // Set initial vlaue of dynamic created oneof Question in Form Browser
985 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
986 ASSERT (Configuration
!= NULL
);
987 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
988 Configuration
->DynamicOneof
= 2;
991 // Update uncommitted data of Browser
996 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
997 (UINT8
*) Configuration
,
1001 FreePool (Configuration
);
1003 HiiCreateOneOfOpCode (
1004 StartOpCodeHandle
, // Container for dynamic created opcodes
1005 0x8001, // Question ID (or call it "key")
1006 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1007 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
1008 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
1009 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
1010 EFI_IFR_FLAG_CALLBACK
, // Question flag
1011 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
1012 OptionsOpCodeHandle
, // Option Opcode list
1013 NULL
// Default Opcode is NULl
1016 HiiCreateOrderedListOpCode (
1017 StartOpCodeHandle
, // Container for dynamic created opcodes
1018 0x8002, // Question ID
1019 CONFIGURATION_VARSTORE_ID
, // VarStore ID
1020 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
1021 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
1022 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
1023 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
1024 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1025 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
1026 5, // Maximum container
1027 OptionsOpCodeHandle
, // Option Opcode list
1028 NULL
// Default Opcode is NULl
1031 HiiCreateGotoOpCode (
1032 StartOpCodeHandle
, // Container for dynamic created opcodes
1033 1, // Target Form ID
1034 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
1035 STRING_TOKEN (STR_GOTO_HELP
), // Help text
1037 0x8003 // Question ID
1041 PrivateData
->HiiHandle
[0], // HII handle
1042 &mFormSetGuid
, // Formset GUID
1044 StartOpCodeHandle
, // Label for where to insert opcodes
1045 EndOpCodeHandle
// Replace data
1048 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1049 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1050 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1055 // We will reach here once the Question is refreshed
1059 // Initialize the container for dynamic opcodes
1061 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1062 ASSERT (StartOpCodeHandle
!= NULL
);
1065 // Create Hii Extend Label OpCode as the start opcode
1067 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1068 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1069 StartLabel
->Number
= LABEL_UPDATE2
;
1071 HiiCreateActionOpCode (
1072 StartOpCodeHandle
, // Container for dynamic created opcodes
1073 0x1237, // Question ID
1074 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
1075 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
1076 EFI_IFR_FLAG_CALLBACK
, // Question flag
1077 0 // Action String ID
1081 PrivateData
->HiiHandle
[0], // HII handle
1082 &mFormSetGuid
, // Formset GUID
1084 StartOpCodeHandle
, // Label for where to insert opcodes
1088 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1091 // Refresh the Question value
1093 PrivateData
->Configuration
.DynamicRefresh
++;
1094 Status
= gRT
->SetVariable(
1097 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1098 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1099 &PrivateData
->Configuration
1103 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
1104 // the first statement in Form 3 be suppressed
1108 Status
= gRT
->SetVariable(
1111 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1119 // User press "Exit now", request Browser to exit
1121 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1126 // User press "Save now", request Browser to save the uncommitted data.
1128 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1133 // When try to set a new password, user will be chanlleged with old password.
1134 // The Callback is responsible for validating old password input by user,
1135 // If Callback return EFI_SUCCESS, it indicates validation pass.
1137 switch (PrivateData
->PasswordState
) {
1138 case BROWSER_STATE_VALIDATE_PASSWORD
:
1139 Status
= ValidatePassword (PrivateData
, Value
->string
);
1140 if (Status
== EFI_SUCCESS
) {
1141 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
1145 case BROWSER_STATE_SET_PASSWORD
:
1146 Status
= SetPassword (PrivateData
, Value
->string
);
1147 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1158 // EfiVarstore question takes sample action (print value as debug information)
1159 // after read/write question.
1162 Status
= gRT
->GetVariable(
1169 ASSERT_EFI_ERROR (Status
);
1170 DEBUG ((DEBUG_INFO
, "EfiVarstore question: Tall value is %d with value width %d\n", MyVar
, MyVarSize
));
1179 Main entry for this driver.
1181 @param ImageHandle Image handle this driver.
1182 @param SystemTable Pointer to SystemTable.
1184 @retval EFI_SUCESS This function always complete successfully.
1190 IN EFI_HANDLE ImageHandle
,
1191 IN EFI_SYSTEM_TABLE
*SystemTable
1195 EFI_HII_HANDLE HiiHandle
[2];
1196 EFI_SCREEN_DESCRIPTOR Screen
;
1197 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1198 EFI_HII_STRING_PROTOCOL
*HiiString
;
1199 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1200 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1203 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
1205 EFI_STRING ConfigRequestHdr
;
1208 // Initialize the local variables.
1210 ConfigRequestHdr
= NULL
;
1212 // Initialize screen dimensions for SendForm().
1213 // Remove 3 characters from top and bottom
1215 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
1216 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
1219 Screen
.BottomRow
= Screen
.BottomRow
- 3;
1222 // Initialize driver private data
1224 PrivateData
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
1225 if (PrivateData
== NULL
) {
1226 return EFI_OUT_OF_RESOURCES
;
1229 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
1231 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
1232 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
1233 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
1234 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
1237 // Locate Hii Database protocol
1239 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
1240 if (EFI_ERROR (Status
)) {
1243 PrivateData
->HiiDatabase
= HiiDatabase
;
1246 // Locate HiiString protocol
1248 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
1249 if (EFI_ERROR (Status
)) {
1252 PrivateData
->HiiString
= HiiString
;
1255 // Locate Formbrowser2 protocol
1257 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
1258 if (EFI_ERROR (Status
)) {
1261 PrivateData
->FormBrowser2
= FormBrowser2
;
1264 // Locate ConfigRouting protocol
1266 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
1267 if (EFI_ERROR (Status
)) {
1270 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
1272 Status
= gBS
->InstallMultipleProtocolInterfaces (
1274 &gEfiDevicePathProtocolGuid
,
1275 &mHiiVendorDevicePath0
,
1276 &gEfiHiiConfigAccessProtocolGuid
,
1277 &PrivateData
->ConfigAccess
,
1280 ASSERT_EFI_ERROR (Status
);
1282 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
1285 // Publish our HII data
1287 HiiHandle
[0] = HiiAddPackages (
1290 DriverSampleStrings
,
1294 if (HiiHandle
[0] == NULL
) {
1295 return EFI_OUT_OF_RESOURCES
;
1298 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
1301 // Publish another Fromset
1303 Status
= gBS
->InstallMultipleProtocolInterfaces (
1305 &gEfiDevicePathProtocolGuid
,
1306 &mHiiVendorDevicePath1
,
1309 ASSERT_EFI_ERROR (Status
);
1311 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
1313 HiiHandle
[1] = HiiAddPackages (
1316 DriverSampleStrings
,
1320 if (HiiHandle
[1] == NULL
) {
1321 DriverSampleUnload (ImageHandle
);
1322 return EFI_OUT_OF_RESOURCES
;
1325 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
1328 // Very simple example of how one would update a string that is already
1329 // in the HII database
1331 NewString
= L
"700 Mhz";
1333 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
1334 DriverSampleUnload (ImageHandle
);
1335 return EFI_OUT_OF_RESOURCES
;
1338 HiiSetString (HiiHandle
[0], 0, NewString
, NULL
);
1341 // Initialize Name/Value name String ID
1343 PrivateData
->NameStringId
[0] = STR_NAME_VALUE_VAR_NAME0
;
1344 PrivateData
->NameStringId
[1] = STR_NAME_VALUE_VAR_NAME1
;
1345 PrivateData
->NameStringId
[2] = STR_NAME_VALUE_VAR_NAME2
;
1348 // Initialize configuration data
1350 Configuration
= &PrivateData
->Configuration
;
1351 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
1354 // Try to read NV config EFI variable first
1356 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, DriverHandle
[0]);
1357 ASSERT (ConfigRequestHdr
!= NULL
);
1359 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
1360 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
1361 if (EFI_ERROR (Status
)) {
1363 // Store zero data Buffer Storage to EFI variable
1365 Status
= gRT
->SetVariable(
1368 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1369 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
1372 ASSERT (Status
== EFI_SUCCESS
);
1374 // EFI variable for NV config doesn't exit, we should build this variable
1375 // based on default values stored in IFR
1377 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
1378 ASSERT (ActionFlag
);
1381 // EFI variable does exist and Validate Current Setting
1383 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1384 ASSERT (ActionFlag
);
1387 FreePool (ConfigRequestHdr
);
1391 // In default, this driver is built into Flash device image,
1392 // the following code doesn't run.
1396 // Example of how to display only the item we sent to HII
1397 // When this driver is not built into Flash device image,
1398 // it need to call SendForm to show front page by itself.
1400 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
1402 // Have the browser pull out our copy of the data, and only display our data
1404 Status
= FormBrowser2
->SendForm (
1406 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
1414 HiiRemovePackages (HiiHandle
[0]);
1416 HiiRemovePackages (HiiHandle
[1]);
1423 Unloads the application and its installed protocol.
1425 @param[in] ImageHandle Handle that identifies the image to be unloaded.
1427 @retval EFI_SUCCESS The image has been unloaded.
1431 DriverSampleUnload (
1432 IN EFI_HANDLE ImageHandle
1436 if (DriverHandle
[0] != NULL
) {
1437 gBS
->UninstallMultipleProtocolInterfaces (
1439 &gEfiDevicePathProtocolGuid
,
1440 &mHiiVendorDevicePath0
,
1441 &gEfiHiiConfigAccessProtocolGuid
,
1442 &PrivateData
->ConfigAccess
,
1445 DriverHandle
[0] = NULL
;
1448 if (DriverHandle
[1] != NULL
) {
1449 gBS
->UninstallMultipleProtocolInterfaces (
1451 &gEfiDevicePathProtocolGuid
,
1452 &mHiiVendorDevicePath1
,
1455 DriverHandle
[1] = NULL
;
1458 if (PrivateData
->HiiHandle
[0] != NULL
) {
1459 HiiRemovePackages (PrivateData
->HiiHandle
[0]);
1462 if (PrivateData
->HiiHandle
[1] != NULL
) {
1463 HiiRemovePackages (PrivateData
->HiiHandle
[1]);
1466 if (PrivateData
!= NULL
) {
1467 for (Index
= 0; Index
< NAME_VALUE_NAME_NUMBER
; Index
++) {
1468 if (PrivateData
->NameValueName
[Index
] != NULL
) {
1469 FreePool (PrivateData
->NameValueName
[Index
]);
1472 FreePool (PrivateData
);