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 - 2008, Intel Corporation
6 All rights reserved. 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";
26 EFI_HANDLE DriverHandle
[2] = {NULL
, NULL
};
27 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
= NULL
;
29 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0
= {
35 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
36 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
40 // {C153B68D-EBFC-488e-B110-662867745B87}
42 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }
46 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
48 (UINT8
) (END_DEVICE_PATH_LENGTH
),
49 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
54 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1
= {
60 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
61 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
65 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}
67 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }
71 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
73 (UINT8
) (END_DEVICE_PATH_LENGTH
),
74 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
80 Encode the password using a simple algorithm.
82 @param Password The string to be encoded.
83 @param MaxSize The size of the string.
98 Buffer
= AllocateZeroPool (MaxSize
);
99 ASSERT (Buffer
!= NULL
);
101 for (Index
= 0; Key
[Index
] != 0; Index
++) {
102 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
103 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
107 CopyMem (Password
, Buffer
, MaxSize
);
114 Validate the user's password.
116 @param PrivateData This driver's private context data.
117 @param StringId The user's input.
119 @retval EFI_SUCCESS The user's input matches the password.
120 @retval EFI_NOT_READY The user's input does not match the password.
124 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
125 IN EFI_STRING_ID StringId
131 UINTN PasswordMaxSize
;
133 CHAR16
*EncodedPassword
;
137 // Get encoded password first
139 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
140 Status
= gRT
->GetVariable (
145 &PrivateData
->Configuration
147 if (EFI_ERROR (Status
)) {
149 // Old password not exist, prompt for new password
155 PasswordMaxSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
157 // Check whether we have any old password set
159 for (Index
= 0; Index
< PasswordMaxSize
/ sizeof (UINT16
); Index
++) {
160 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
167 // Old password not exist, return EFI_SUCCESS to prompt for new password
173 // Get user input password
175 Password
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
176 if (Password
== NULL
) {
177 return EFI_NOT_READY
;
179 if (StrSize (Password
) > PasswordMaxSize
) {
181 return EFI_NOT_READY
;
185 // Validate old password
187 EncodedPassword
= AllocateZeroPool (PasswordMaxSize
);
188 ASSERT (EncodedPassword
!= NULL
);
189 StrnCpy (EncodedPassword
, Password
, StrLen (Password
));
190 EncodePassword (EncodedPassword
, StrLen (EncodedPassword
) * sizeof (CHAR16
));
191 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, StrLen (EncodedPassword
) * sizeof (CHAR16
)) != 0) {
193 // Old password mismatch, return EFI_NOT_READY to prompt for error message
195 Status
= EFI_NOT_READY
;
197 Status
= EFI_SUCCESS
;
201 FreePool (EncodedPassword
);
207 Encode the password using a simple algorithm.
209 @param PrivateData This driver's private context data.
210 @param StringId The password from User.
212 @retval EFI_SUCESS The operation is successful.
213 @return Other value if gRT->SetVariable () fails.
218 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
219 IN EFI_STRING_ID StringId
224 CHAR16
*TempPassword
;
226 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
230 // Get Buffer Storage data from EFI variable
232 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
233 Status
= gRT
->GetVariable (
238 &PrivateData
->Configuration
240 if (EFI_ERROR (Status
)) {
245 // Get user input password
247 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
248 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
249 ZeroMem (Password
, PasswordSize
);
251 TempPassword
= HiiGetString (PrivateData
->HiiHandle
[0], StringId
, NULL
);
252 if (TempPassword
== NULL
) {
253 return EFI_NOT_READY
;
255 if (StrSize (TempPassword
) > PasswordSize
) {
256 FreePool (TempPassword
);
257 return EFI_NOT_READY
;
259 StrnCpy (Password
, TempPassword
, StrLen (TempPassword
));
260 FreePool (TempPassword
);
263 // Retrive uncommitted data from Browser
265 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION
));
266 ASSERT (Configuration
!= NULL
);
267 if (HiiGetBrowserData (&mFormSetGuid
, VariableName
, sizeof (DRIVER_SAMPLE_CONFIGURATION
), (UINT8
*) Configuration
)) {
269 // Update password's clear text in the screen
271 CopyMem (Configuration
->PasswordClearText
, Password
, StrSize (Password
));
274 // Update uncommitted data of Browser
279 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
280 (UINT8
*) Configuration
,
286 // Free Configuration Buffer
288 FreePool (Configuration
);
294 EncodePassword (Password
, StrLen (Password
) * 2);
295 Status
= gRT
->SetVariable(
298 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
299 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
300 &PrivateData
->Configuration
307 This function allows a caller to extract the current configuration for one
308 or more named elements from the target driver.
310 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
311 @param Request A null-terminated Unicode string in
312 <ConfigRequest> format.
313 @param Progress On return, points to a character in the Request
314 string. Points to the string's null terminator if
315 request was successful. Points to the most recent
316 '&' before the first failing name/value pair (or
317 the beginning of the string if the failure is in
318 the first name/value pair) if the request was not
320 @param Results A null-terminated Unicode string in
321 <ConfigAltResp> format which has all values filled
322 in for the names in the Request string. String to
323 be allocated by the called function.
325 @retval EFI_SUCCESS The Results is filled with the requested values.
326 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
327 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
328 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
335 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
336 IN CONST EFI_STRING Request
,
337 OUT EFI_STRING
*Progress
,
338 OUT EFI_STRING
*Results
343 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
344 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
345 EFI_STRING ConfigRequestHdr
;
346 EFI_STRING ConfigRequest
;
349 if (Progress
== NULL
|| Results
== NULL
) {
350 return EFI_INVALID_PARAMETER
;
353 // Initialize the local variables.
355 ConfigRequestHdr
= NULL
;
356 ConfigRequest
= NULL
;
360 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
361 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
364 // Get Buffer Storage data from EFI variable.
365 // Try to get the current setting from variable.
367 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
368 Status
= gRT
->GetVariable (
373 &PrivateData
->Configuration
375 if (EFI_ERROR (Status
)) {
379 if (Request
== NULL
) {
381 // Request is set to NULL, construct full request string.
385 // First Set ConfigRequestHdr string.
387 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, PrivateData
->DriverHandle
[0]);
388 ASSERT (ConfigRequestHdr
!= NULL
);
391 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
392 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
394 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
395 ConfigRequest
= AllocateZeroPool (Size
);
396 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
397 FreePool (ConfigRequestHdr
);
399 ConfigRequest
= Request
;
403 // Check routing data in <ConfigHdr>.
404 // Note: if only one Storage is used, then this checking could be skipped.
406 if (!HiiIsConfigHdrMatch (ConfigRequest
, &mFormSetGuid
, VariableName
)) {
407 if (Request
== NULL
) {
408 FreePool (ConfigRequest
);
410 return EFI_NOT_FOUND
;
414 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
416 Status
= HiiConfigRouting
->BlockToConfig (
419 (UINT8
*) &PrivateData
->Configuration
,
425 if (Request
== NULL
) {
426 FreePool (ConfigRequest
);
435 This function processes the results of changes in configuration.
437 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
438 @param Configuration A null-terminated Unicode string in <ConfigResp>
440 @param Progress A pointer to a string filled in with the offset of
441 the most recent '&' before the first failing
442 name/value pair (or the beginning of the string if
443 the failure is in the first name/value pair) or
444 the terminating NULL if all was successful.
446 @retval EFI_SUCCESS The Results is processed successfully.
447 @retval EFI_INVALID_PARAMETER Configuration is NULL.
448 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
455 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
456 IN CONST EFI_STRING Configuration
,
457 OUT EFI_STRING
*Progress
462 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
463 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
465 if (Configuration
== NULL
) {
466 return EFI_INVALID_PARAMETER
;
469 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
470 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
473 // Check routing data in <ConfigHdr>.
474 // Note: if only one Storage is used, then this checking could be skipped.
476 if (!HiiIsConfigHdrMatch (Configuration
, &mFormSetGuid
, VariableName
)) {
477 *Progress
= Configuration
;
478 return EFI_NOT_FOUND
;
482 // Get Buffer Storage data from EFI variable
484 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
485 Status
= gRT
->GetVariable (
490 &PrivateData
->Configuration
492 if (EFI_ERROR (Status
)) {
497 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
499 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
500 Status
= HiiConfigRouting
->ConfigToBlock (
503 (UINT8
*) &PrivateData
->Configuration
,
507 if (EFI_ERROR (Status
)) {
512 // Store Buffer Storage back to EFI variable
514 Status
= gRT
->SetVariable(
517 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
518 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
519 &PrivateData
->Configuration
527 This function processes the results of changes in configuration.
529 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
530 @param Action Specifies the type of action taken by the browser.
531 @param QuestionId A unique value which is sent to the original
532 exporting driver so that it can identify the type
534 @param Type The type of value for the question.
535 @param Value A pointer to the data being sent to the original
537 @param ActionRequest On return, points to the action requested by the
540 @retval EFI_SUCCESS The callback successfully handled the action.
541 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
542 variable and its data.
543 @retval EFI_DEVICE_ERROR The variable could not be saved.
544 @retval EFI_UNSUPPORTED The specified Action is not supported by the
551 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
552 IN EFI_BROWSER_ACTION Action
,
553 IN EFI_QUESTION_ID QuestionId
,
555 IN EFI_IFR_TYPE_VALUE
*Value
,
556 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
559 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
562 VOID
*StartOpCodeHandle
;
563 VOID
*OptionsOpCodeHandle
;
564 EFI_IFR_GUID_LABEL
*StartLabel
;
565 VOID
*EndOpCodeHandle
;
566 EFI_IFR_GUID_LABEL
*EndLabel
;
568 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
569 return EFI_INVALID_PARAMETER
;
572 if ((Type
== EFI_IFR_TYPE_STRING
) && (Value
->string
== 0)) {
573 return EFI_INVALID_PARAMETER
;
577 Status
= EFI_SUCCESS
;
578 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
580 switch (QuestionId
) {
583 // Initialize the container for dynamic opcodes
585 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
586 ASSERT (StartOpCodeHandle
!= NULL
);
588 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
589 ASSERT (EndOpCodeHandle
!= NULL
);
592 // Create Hii Extend Label OpCode as the start opcode
594 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
595 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
596 StartLabel
->Number
= LABEL_UPDATE1
;
599 // Create Hii Extend Label OpCode as the end opcode
601 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
602 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
603 EndLabel
->Number
= LABEL_END
;
605 HiiCreateActionOpCode (
606 StartOpCodeHandle
, // Container for dynamic created opcodes
607 0x1237, // Question ID
608 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
609 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
610 EFI_IFR_FLAG_CALLBACK
, // Question flag
611 0 // Action String ID
615 // Create Option OpCode
617 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
618 ASSERT (OptionsOpCodeHandle
!= NULL
);
620 HiiCreateOneOfOptionOpCode (
622 STRING_TOKEN (STR_BOOT_OPTION1
),
624 EFI_IFR_NUMERIC_SIZE_1
,
628 HiiCreateOneOfOptionOpCode (
630 STRING_TOKEN (STR_BOOT_OPTION2
),
632 EFI_IFR_NUMERIC_SIZE_1
,
637 // Prepare initial value for the dynamic created oneof Question
639 PrivateData
->Configuration
.DynamicOneof
= 2;
640 Status
= gRT
->SetVariable(
643 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
644 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
645 &PrivateData
->Configuration
648 HiiCreateOneOfOpCode (
649 StartOpCodeHandle
, // Container for dynamic created opcodes
650 0x8001, // Question ID (or call it "key")
651 CONFIGURATION_VARSTORE_ID
, // VarStore ID
652 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
653 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
654 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
655 EFI_IFR_FLAG_CALLBACK
, // Question flag
656 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
657 OptionsOpCodeHandle
, // Option Opcode list
658 NULL
// Default Opcode is NULl
661 HiiCreateOrderedListOpCode (
662 StartOpCodeHandle
, // Container for dynamic created opcodes
663 0x8002, // Question ID
664 CONFIGURATION_VARSTORE_ID
, // VarStore ID
665 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
666 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
667 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
668 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
669 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
670 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
671 5, // Maximum container
672 OptionsOpCodeHandle
, // Option Opcode list
673 NULL
// Default Opcode is NULl
676 HiiCreateGotoOpCode (
677 StartOpCodeHandle
, // Container for dynamic created opcodes
679 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
680 STRING_TOKEN (STR_GOTO_HELP
), // Help text
682 0x8003 // Question ID
686 PrivateData
->HiiHandle
[0], // HII handle
687 &mFormSetGuid
, // Formset GUID
689 StartOpCodeHandle
, // Label for where to insert opcodes
690 EndOpCodeHandle
// Replace data
693 HiiFreeOpCodeHandle (StartOpCodeHandle
);
694 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
699 // We will reach here once the Question is refreshed
703 // Initialize the container for dynamic opcodes
705 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
706 ASSERT (StartOpCodeHandle
!= NULL
);
709 // Create Hii Extend Label OpCode as the start opcode
711 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
712 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
713 StartLabel
->Number
= LABEL_UPDATE2
;
715 HiiCreateActionOpCode (
716 StartOpCodeHandle
, // Container for dynamic created opcodes
717 0x1237, // Question ID
718 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
719 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
720 EFI_IFR_FLAG_CALLBACK
, // Question flag
721 0 // Action String ID
725 PrivateData
->HiiHandle
[0], // HII handle
726 &mFormSetGuid
, // Formset GUID
728 StartOpCodeHandle
, // Label for where to insert opcodes
732 HiiFreeOpCodeHandle (StartOpCodeHandle
);
735 // Refresh the Question value
737 PrivateData
->Configuration
.DynamicRefresh
++;
738 Status
= gRT
->SetVariable(
741 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
742 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
743 &PrivateData
->Configuration
747 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
748 // the first statement in Form 3 be suppressed
751 Status
= gRT
->SetVariable(
754 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
762 // User press "Exit now", request Browser to exit
764 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
769 // User press "Save now", request Browser to save the uncommitted data.
771 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
776 // When try to set a new password, user will be chanlleged with old password.
777 // The Callback is responsible for validating old password input by user,
778 // If Callback return EFI_SUCCESS, it indicates validation pass.
780 switch (PrivateData
->PasswordState
) {
781 case BROWSER_STATE_VALIDATE_PASSWORD
:
782 Status
= ValidatePassword (PrivateData
, Value
->string
);
783 if (Status
== EFI_SUCCESS
) {
784 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
788 case BROWSER_STATE_SET_PASSWORD
:
789 Status
= SetPassword (PrivateData
, Value
->string
);
790 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
807 Main entry for this driver.
809 @param ImageHandle Image handle this driver.
810 @param SystemTable Pointer to SystemTable.
812 @retval EFI_SUCESS This function always complete successfully.
818 IN EFI_HANDLE ImageHandle
,
819 IN EFI_SYSTEM_TABLE
*SystemTable
823 EFI_HII_HANDLE HiiHandle
[2];
824 EFI_SCREEN_DESCRIPTOR Screen
;
825 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
826 EFI_HII_STRING_PROTOCOL
*HiiString
;
827 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
828 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
831 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
833 EFI_STRING ConfigRequestHdr
;
836 // Initialize the local variables.
838 ConfigRequestHdr
= NULL
;
840 // Initialize screen dimensions for SendForm().
841 // Remove 3 characters from top and bottom
843 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
844 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
847 Screen
.BottomRow
= Screen
.BottomRow
- 3;
850 // Initialize driver private data
852 PrivateData
= AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
853 if (PrivateData
== NULL
) {
854 return EFI_OUT_OF_RESOURCES
;
857 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
859 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
860 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
861 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
862 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
865 // Locate Hii Database protocol
867 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
868 if (EFI_ERROR (Status
)) {
871 PrivateData
->HiiDatabase
= HiiDatabase
;
874 // Locate HiiString protocol
876 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
877 if (EFI_ERROR (Status
)) {
880 PrivateData
->HiiString
= HiiString
;
883 // Locate Formbrowser2 protocol
885 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
886 if (EFI_ERROR (Status
)) {
889 PrivateData
->FormBrowser2
= FormBrowser2
;
892 // Locate ConfigRouting protocol
894 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
895 if (EFI_ERROR (Status
)) {
898 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
900 Status
= gBS
->InstallMultipleProtocolInterfaces (
902 &gEfiDevicePathProtocolGuid
,
903 &mHiiVendorDevicePath0
,
904 &gEfiHiiConfigAccessProtocolGuid
,
905 &PrivateData
->ConfigAccess
,
908 ASSERT_EFI_ERROR (Status
);
910 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
913 // Publish our HII data
915 HiiHandle
[0] = HiiAddPackages (
922 if (HiiHandle
[0] == NULL
) {
923 return EFI_OUT_OF_RESOURCES
;
926 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
929 // Publish another Fromset
931 Status
= gBS
->InstallMultipleProtocolInterfaces (
933 &gEfiDevicePathProtocolGuid
,
934 &mHiiVendorDevicePath1
,
937 ASSERT_EFI_ERROR (Status
);
939 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
941 HiiHandle
[1] = HiiAddPackages (
948 if (HiiHandle
[1] == NULL
) {
949 return EFI_OUT_OF_RESOURCES
;
952 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
955 // Very simple example of how one would update a string that is already
956 // in the HII database
958 NewString
= L
"700 Mhz";
960 if (HiiSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
, NULL
) == 0) {
961 return EFI_OUT_OF_RESOURCES
;
965 // Initialize configuration data
967 Configuration
= &PrivateData
->Configuration
;
968 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
971 // Try to read NV config EFI variable first
973 ConfigRequestHdr
= HiiConstructConfigHdr (&mFormSetGuid
, VariableName
, DriverHandle
[0]);
974 ASSERT (ConfigRequestHdr
!= NULL
);
976 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
977 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
978 if (EFI_ERROR (Status
)) {
980 // Store zero data Buffer Storage to EFI variable
982 Status
= gRT
->SetVariable(
985 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
986 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
989 ASSERT (Status
== EFI_SUCCESS
);
991 // EFI variable for NV config doesn't exit, we should build this variable
992 // based on default values stored in IFR
994 ActionFlag
= HiiSetToDefaults (ConfigRequestHdr
, EFI_HII_DEFAULT_CLASS_STANDARD
);
998 // EFI variable does exist and Validate Current Setting
1000 ActionFlag
= HiiValidateSettings (ConfigRequestHdr
);
1001 ASSERT (ActionFlag
);
1004 FreePool (ConfigRequestHdr
);
1008 // In default, this driver is built into Flash device image,
1009 // the following code doesn't run.
1013 // Example of how to display only the item we sent to HII
1014 // When this driver is not built into Flash device image,
1015 // it need to call SendForm to show front page by itself.
1017 if (DISPLAY_ONLY_MY_ITEM
<= 1) {
1019 // Have the browser pull out our copy of the data, and only display our data
1021 Status
= FormBrowser2
->SendForm (
1023 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
1031 HiiRemovePackages (HiiHandle
[0]);
1033 HiiRemovePackages (HiiHandle
[1]);
1040 Unloads the application and its installed protocol.
1042 @param[in] ImageHandle Handle that identifies the image to be unloaded.
1044 @retval EFI_SUCCESS The image has been unloaded.
1048 DriverSampleUnload (
1049 IN EFI_HANDLE ImageHandle
1052 if (DriverHandle
[0] != NULL
) {
1053 gBS
->UninstallMultipleProtocolInterfaces (
1055 &gEfiDevicePathProtocolGuid
,
1056 &mHiiVendorDevicePath0
,
1057 &gEfiHiiConfigAccessProtocolGuid
,
1058 &PrivateData
->ConfigAccess
,
1063 if (DriverHandle
[1] != NULL
) {
1064 gBS
->UninstallMultipleProtocolInterfaces (
1066 &gEfiDevicePathProtocolGuid
,
1067 &mHiiVendorDevicePath1
,
1072 if (PrivateData
->HiiHandle
[0] != NULL
) {
1073 HiiRemovePackages (PrivateData
->HiiHandle
[0]);
1076 if (PrivateData
->HiiHandle
[1] != NULL
) {
1077 HiiRemovePackages (PrivateData
->HiiHandle
[1]);
1080 if (PrivateData
!= NULL
) {
1081 FreePool (PrivateData
);