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 0x0000
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
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
155 // Check whether we have any old password set
157 for (Index
= 0; Index
< 20; Index
++) {
158 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
165 // Old password not exist, return EFI_SUCCESS to prompt for new password
171 // Get user input password
173 BufferSize
= 21 * sizeof (CHAR16
);
174 Password
= AllocateZeroPool (BufferSize
);
175 ASSERT (Password
!= NULL
);
177 Status
= HiiLibGetString (PrivateData
->HiiHandle
[0], StringId
, Password
, &BufferSize
);
178 if (EFI_ERROR (Status
)) {
184 // Validate old password
186 EncodedPassword
= AllocateCopyPool (21 * sizeof (CHAR16
), Password
);
187 ASSERT (EncodedPassword
!= NULL
);
188 EncodePassword (EncodedPassword
, 20 * sizeof (CHAR16
));
189 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, 20 * sizeof (CHAR16
)) != 0) {
191 // Old password mismatch, return EFI_NOT_READY to prompt for error message
193 Status
= EFI_NOT_READY
;
195 Status
= EFI_SUCCESS
;
199 FreePool (EncodedPassword
);
205 Encode the password using a simple algorithm.
207 @param PrivateData This driver's private context data.
208 @param StringId The password from User.
210 @retval EFI_SUCESS The operation is successful.
211 @return Other value if gRT->SetVariable () fails.
216 IN DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
217 IN EFI_STRING_ID StringId
224 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
227 // Get Buffer Storage data from EFI variable
229 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
230 Status
= gRT
->GetVariable (
235 &PrivateData
->Configuration
237 if (EFI_ERROR (Status
)) {
242 // Get user input password
244 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
245 PasswordSize
= sizeof (PrivateData
->Configuration
.WhatIsThePassword2
);
247 ZeroMem (Password
, PasswordSize
);
248 Status
= HiiLibGetString (PrivateData
->HiiHandle
[0], StringId
, Password
, &BufferSize
);
249 if (EFI_ERROR (Status
)) {
254 // Retrive uncommitted data from Browser
256 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
257 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
258 ASSERT (Configuration
!= NULL
);
259 Status
= GetBrowserData (&mFormSetGuid
, VariableName
, &BufferSize
, (UINT8
*) Configuration
);
260 if (!EFI_ERROR (Status
)) {
262 // Update password's clear text in the screen
264 CopyMem (Configuration
->PasswordClearText
, Password
, PasswordSize
);
267 // Update uncommitted data of Browser
269 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
270 Status
= SetBrowserData (
274 (UINT8
*) Configuration
,
278 FreePool (Configuration
);
283 EncodePassword (Password
, PasswordSize
);
284 Status
= gRT
->SetVariable(
287 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
288 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
289 &PrivateData
->Configuration
296 This function allows a caller to extract the current configuration for one
297 or more named elements from the target driver.
299 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
300 @param Request A null-terminated Unicode string in
301 <ConfigRequest> format.
302 @param Progress On return, points to a character in the Request
303 string. Points to the string's null terminator if
304 request was successful. Points to the most recent
305 '&' before the first failing name/value pair (or
306 the beginning of the string if the failure is in
307 the first name/value pair) if the request was not
309 @param Results A null-terminated Unicode string in
310 <ConfigAltResp> format which has all values filled
311 in for the names in the Request string. String to
312 be allocated by the called function.
314 @retval EFI_SUCCESS The Results is filled with the requested values.
315 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
316 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
317 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
324 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
325 IN CONST EFI_STRING Request
,
326 OUT EFI_STRING
*Progress
,
327 OUT EFI_STRING
*Results
332 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
333 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
335 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
336 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
340 // Get Buffer Storage data from EFI variable
342 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
343 Status
= gRT
->GetVariable (
348 &PrivateData
->Configuration
350 if (EFI_ERROR (Status
)) {
354 if (Request
== NULL
) {
356 // Request is set to NULL, return all configurable elements together with ALTCFG
358 Status
= ConstructConfigAltResp (
364 PrivateData
->DriverHandle
[0],
365 &PrivateData
->Configuration
,
367 VfrMyIfrNVDataBlockName
,
369 STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT
),
370 VfrMyIfrNVDataDefault0000
,
371 STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT
),
372 VfrMyIfrNVDataDefault0001
379 // Check routing data in <ConfigHdr>.
380 // Note: if only one Storage is used, then this checking could be skipped.
382 if (!IsConfigHdrMatch (Request
, &mFormSetGuid
, VariableName
)) {
384 return EFI_NOT_FOUND
;
388 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
390 Status
= HiiConfigRouting
->BlockToConfig (
393 (UINT8
*) &PrivateData
->Configuration
,
403 This function processes the results of changes in configuration.
405 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
406 @param Configuration A null-terminated Unicode string in <ConfigResp>
408 @param Progress A pointer to a string filled in with the offset of
409 the most recent '&' before the first failing
410 name/value pair (or the beginning of the string if
411 the failure is in the first name/value pair) or
412 the terminating NULL if all was successful.
414 @retval EFI_SUCCESS The Results is processed successfully.
415 @retval EFI_INVALID_PARAMETER Configuration is NULL.
416 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
424 IN CONST EFI_STRING Configuration
,
425 OUT EFI_STRING
*Progress
430 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
431 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
433 if (Configuration
== NULL
) {
434 return EFI_INVALID_PARAMETER
;
437 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
438 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
440 // Check routing data in <ConfigHdr>.
441 // Note: if only one Storage is used, then this checking could be skipped.
443 if (!IsConfigHdrMatch (Configuration
, &mFormSetGuid
, VariableName
)) {
444 *Progress
= Configuration
;
445 return EFI_NOT_FOUND
;
449 // Get Buffer Storage data from EFI variable
451 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
452 Status
= gRT
->GetVariable (
457 &PrivateData
->Configuration
459 if (EFI_ERROR (Status
)) {
464 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
466 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
467 Status
= HiiConfigRouting
->ConfigToBlock (
470 (UINT8
*) &PrivateData
->Configuration
,
474 if (EFI_ERROR (Status
)) {
479 // Store Buffer Storage back to EFI variable
481 Status
= gRT
->SetVariable(
484 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
485 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
486 &PrivateData
->Configuration
494 This function processes the results of changes in configuration.
496 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
497 @param Action Specifies the type of action taken by the browser.
498 @param QuestionId A unique value which is sent to the original
499 exporting driver so that it can identify the type
501 @param Type The type of value for the question.
502 @param Value A pointer to the data being sent to the original
504 @param ActionRequest On return, points to the action requested by the
507 @retval EFI_SUCCESS The callback successfully handled the action.
508 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
509 variable and its data.
510 @retval EFI_DEVICE_ERROR The variable could not be saved.
511 @retval EFI_UNSUPPORTED The specified Action is not supported by the
518 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
519 IN EFI_BROWSER_ACTION Action
,
520 IN EFI_QUESTION_ID QuestionId
,
522 IN EFI_IFR_TYPE_VALUE
*Value
,
523 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
526 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
528 EFI_HII_UPDATE_DATA UpdateData
;
529 IFR_OPTION
*IfrOptionList
;
532 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
533 return EFI_INVALID_PARAMETER
;
536 Status
= EFI_SUCCESS
;
537 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
539 switch (QuestionId
) {
542 // Initialize the container for dynamic opcodes
544 IfrLibInitUpdateData (&UpdateData
, 0x1000);
546 IfrOptionList
= AllocatePool (2 * sizeof (IFR_OPTION
));
547 ASSERT (IfrOptionList
!= NULL
);
549 IfrOptionList
[0].Flags
= 0;
550 IfrOptionList
[0].StringToken
= STRING_TOKEN (STR_BOOT_OPTION1
);
551 IfrOptionList
[0].Value
.u8
= 1;
552 IfrOptionList
[1].Flags
= EFI_IFR_OPTION_DEFAULT
;
553 IfrOptionList
[1].StringToken
= STRING_TOKEN (STR_BOOT_OPTION2
);
554 IfrOptionList
[1].Value
.u8
= 2;
557 0x1237, // Question ID
558 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
559 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
560 EFI_IFR_FLAG_CALLBACK
, // Question flag
561 0, // Action String ID
562 &UpdateData
// Container for dynamic created opcodes
566 // Prepare initial value for the dynamic created oneof Question
568 PrivateData
->Configuration
.DynamicOneof
= 2;
569 Status
= gRT
->SetVariable(
572 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
573 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
574 &PrivateData
->Configuration
577 0x8001, // Question ID (or call it "key")
578 CONFIGURATION_VARSTORE_ID
, // VarStore ID
579 (UINT16
) DYNAMIC_ONE_OF_VAR_OFFSET
, // Offset in Buffer Storage
580 STRING_TOKEN (STR_ONE_OF_PROMPT
), // Question prompt text
581 STRING_TOKEN (STR_ONE_OF_HELP
), // Question help text
582 EFI_IFR_FLAG_CALLBACK
, // Question flag
583 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question Value
584 IfrOptionList
, // Option list
585 2, // Number of options in Option list
586 &UpdateData
// Container for dynamic created opcodes
589 CreateOrderedListOpCode (
590 0x8002, // Question ID
591 CONFIGURATION_VARSTORE_ID
, // VarStore ID
592 (UINT16
) DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
593 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question prompt text
594 STRING_TOKEN (STR_BOOT_OPTIONS
), // Question help text
595 EFI_IFR_FLAG_RESET_REQUIRED
, // Question flag
596 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
597 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
598 5, // Maximum container
599 IfrOptionList
, // Option list
600 2, // Number of options in Option list
601 &UpdateData
// Container for dynamic created opcodes
606 STRING_TOKEN (STR_GOTO_FORM1
), // Prompt text
607 STRING_TOKEN (STR_GOTO_HELP
), // Help text
609 0x8003, // Question ID
610 &UpdateData
// Container for dynamic created opcodes
613 Status
= IfrLibUpdateForm (
614 PrivateData
->HiiHandle
[0], // HII handle
615 &mFormSetGuid
, // Formset GUID
617 0x1234, // Label for where to insert opcodes
618 TRUE
, // Append or replace
619 &UpdateData
// Dynamic created opcodes
621 FreePool (IfrOptionList
);
622 IfrLibFreeUpdateData (&UpdateData
);
627 // We will reach here once the Question is refreshed
629 IfrLibInitUpdateData (&UpdateData
, 0x1000);
631 IfrOptionList
= AllocatePool (2 * sizeof (IFR_OPTION
));
632 ASSERT (IfrOptionList
!= NULL
);
635 0x1237, // Question ID
636 STRING_TOKEN(STR_EXIT_TEXT
), // Prompt text
637 STRING_TOKEN(STR_EXIT_TEXT
), // Help text
638 EFI_IFR_FLAG_CALLBACK
, // Question flag
639 0, // Action String ID
640 &UpdateData
// Container for dynamic created opcodes
643 Status
= IfrLibUpdateForm (
644 PrivateData
->HiiHandle
[0], // HII handle
645 &mFormSetGuid
, // Formset GUID
647 0x2234, // Label for where to insert opcodes
648 TRUE
, // Append or replace
649 &UpdateData
// Dynamic created opcodes
651 IfrLibFreeUpdateData (&UpdateData
);
654 // Refresh the Question value
656 PrivateData
->Configuration
.DynamicRefresh
++;
657 Status
= gRT
->SetVariable(
660 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
661 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
662 &PrivateData
->Configuration
666 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
667 // the first statement in Form 3 be suppressed
670 Status
= gRT
->SetVariable(
673 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
681 // User press "Exit now", request Browser to exit
683 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
688 // User press "Save now", request Browser to save the uncommitted data.
690 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
695 // When try to set a new password, user will be chanlleged with old password.
696 // The Callback is responsible for validating old password input by user,
697 // If Callback return EFI_SUCCESS, it indicates validation pass.
699 switch (PrivateData
->PasswordState
) {
700 case BROWSER_STATE_VALIDATE_PASSWORD
:
701 Status
= ValidatePassword (PrivateData
, Value
->string
);
702 if (Status
== EFI_SUCCESS
) {
703 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
707 case BROWSER_STATE_SET_PASSWORD
:
708 Status
= SetPassword (PrivateData
, Value
->string
);
709 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
726 Main entry for this driver.
728 @param ImageHandle Image handle this driver.
729 @param SystemTable Pointer to SystemTable.
731 @retval EFI_SUCESS This function always complete successfully.
737 IN EFI_HANDLE ImageHandle
,
738 IN EFI_SYSTEM_TABLE
*SystemTable
742 EFI_STATUS SavedStatus
;
743 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
744 EFI_HII_HANDLE HiiHandle
[2];
745 EFI_SCREEN_DESCRIPTOR Screen
;
746 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
747 EFI_HII_STRING_PROTOCOL
*HiiString
;
748 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
749 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
752 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
753 BOOLEAN ExtractIfrDefault
;
756 // Initialize the library and our protocol.
760 // Initialize screen dimensions for SendForm().
761 // Remove 3 characters from top and bottom
763 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
764 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
767 Screen
.BottomRow
= Screen
.BottomRow
- 3;
770 // Initialize driver private data
772 PrivateData
= AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
773 if (PrivateData
== NULL
) {
774 return EFI_OUT_OF_RESOURCES
;
777 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
779 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
780 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
781 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
782 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
785 // Locate Hii Database protocol
787 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
788 if (EFI_ERROR (Status
)) {
791 PrivateData
->HiiDatabase
= HiiDatabase
;
794 // Locate HiiString protocol
796 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
797 if (EFI_ERROR (Status
)) {
800 PrivateData
->HiiString
= HiiString
;
803 // Locate Formbrowser2 protocol
805 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
806 if (EFI_ERROR (Status
)) {
809 PrivateData
->FormBrowser2
= FormBrowser2
;
812 // Locate ConfigRouting protocol
814 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
815 if (EFI_ERROR (Status
)) {
818 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
820 Status
= gBS
->InstallMultipleProtocolInterfaces (
822 &gEfiDevicePathProtocolGuid
,
823 &mHiiVendorDevicePath0
,
824 &gEfiHiiConfigAccessProtocolGuid
,
825 &PrivateData
->ConfigAccess
,
828 ASSERT_EFI_ERROR (Status
);
830 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
833 // Publish our HII data
835 PackageList
= HiiLibPreparePackageList (
841 if (PackageList
== NULL
) {
842 return EFI_OUT_OF_RESOURCES
;
845 Status
= HiiDatabase
->NewPackageList (
851 FreePool (PackageList
);
852 if (EFI_ERROR (Status
)) {
855 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
858 // Publish another Fromset
860 Status
= gBS
->InstallMultipleProtocolInterfaces (
862 &gEfiDevicePathProtocolGuid
,
863 &mHiiVendorDevicePath1
,
866 ASSERT_EFI_ERROR (Status
);
868 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
870 PackageList
= HiiLibPreparePackageList (
876 if (PackageList
== NULL
) {
877 return EFI_OUT_OF_RESOURCES
;
880 Status
= HiiDatabase
->NewPackageList (
886 FreePool (PackageList
);
887 if (EFI_ERROR (Status
)) {
890 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
893 // Very simple example of how one would update a string that is already
894 // in the HII database
896 NewString
= L
"700 Mhz";
898 Status
= HiiLibSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
);
899 if (EFI_ERROR (Status
)) {
904 // Initialize configuration data
906 Configuration
= &PrivateData
->Configuration
;
907 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
910 // Try to read NV config EFI variable first
912 ExtractIfrDefault
= TRUE
;
913 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
914 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
915 if (!EFI_ERROR (Status
) && (BufferSize
== sizeof (DRIVER_SAMPLE_CONFIGURATION
))) {
916 ExtractIfrDefault
= FALSE
;
919 if (ExtractIfrDefault
) {
921 // EFI variable for NV config doesn't exit, we should build this variable
922 // based on default values stored in IFR
924 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
925 Status
= IfrLibExtractDefault (Configuration
, &BufferSize
, 1, VfrMyIfrNVDataDefault0000
);
927 if (!EFI_ERROR (Status
)) {
931 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
932 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
939 // Example of how to display only the item we sent to HII
942 // Have the browser pull out our copy of the data, and only display our data
944 Status
= FormBrowser2
->SendForm (
946 &(HiiHandle
[DISPLAY_ONLY_MY_ITEM
]),
953 SavedStatus
= Status
;
955 Status
= HiiDatabase
->RemovePackageList (HiiDatabase
, HiiHandle
[0]);
956 if (EFI_ERROR (Status
)) {
960 Status
= HiiDatabase
->RemovePackageList (HiiDatabase
, HiiHandle
[1]);
961 if (EFI_ERROR (Status
)) {
969 Unloads the application and its installed protocol.
971 @param[in] ImageHandle Handle that identifies the image to be unloaded.
973 @retval EFI_SUCCESS The image has been unloaded.
978 IN EFI_HANDLE ImageHandle
981 if (DriverHandle
[0] != NULL
) {
982 gBS
->UninstallMultipleProtocolInterfaces (
984 &gEfiDevicePathProtocolGuid
,
985 &mHiiVendorDevicePath0
,
986 &gEfiHiiConfigAccessProtocolGuid
,
987 &PrivateData
->ConfigAccess
,
992 if (DriverHandle
[1] != NULL
) {
993 gBS
->UninstallMultipleProtocolInterfaces (
995 &gEfiDevicePathProtocolGuid
,
996 &mHiiVendorDevicePath1
,
1001 if (PrivateData
!= NULL
) {
1002 FreePool (PrivateData
);