2 Copyright (c) 2004 - 2007, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 This is an example of how a driver might export data to the HII protocol to be
17 later utilized by the Setup Protocol
23 #include "DriverSample.h"
25 #define DISPLAY_ONLY_MY_ITEM 0x0002
27 EFI_GUID mFormSetGuid
= FORMSET_GUID
;
28 EFI_GUID mInventoryGuid
= INVENTORY_GUID
;
30 CHAR16 VariableName
[] = L
"MyIfrNVData";
44 Buffer
= AllocateZeroPool (MaxSize
);
45 ASSERT (Buffer
!= NULL
);
47 for (Index
= 0; Key
[Index
] != 0; Index
++) {
48 for (Loop
= 0; Loop
< (UINT8
) (MaxSize
/ 2); Loop
++) {
49 Buffer
[Loop
] = (CHAR16
) (Password
[Loop
] ^ Key
[Index
]);
53 CopyMem (Password
, Buffer
, MaxSize
);
55 gBS
->FreePool (Buffer
);
61 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
62 EFI_STRING_ID StringId
69 CHAR16
*EncodedPassword
;
73 // Get encoded password first
75 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
76 Status
= gRT
->GetVariable (
81 &PrivateData
->Configuration
83 if (EFI_ERROR (Status
)) {
85 // Old password not exist, prompt for new password
92 // Check whether we have any old password set
94 for (Index
= 0; Index
< 20; Index
++) {
95 if (PrivateData
->Configuration
.WhatIsThePassword2
[Index
] != 0) {
102 // Old password not exist, return EFI_SUCCESS to prompt for new password
108 // Get user input password
110 BufferSize
= 21 * sizeof (CHAR16
);
111 Password
= AllocateZeroPool (BufferSize
);
112 ASSERT (Password
!= NULL
);
114 Status
= HiiLibGetString (PrivateData
->HiiHandle
[0], StringId
, Password
, &BufferSize
);
115 if (EFI_ERROR (Status
)) {
116 gBS
->FreePool (Password
);
121 // Validate old password
123 EncodedPassword
= AllocateCopyPool (21 * sizeof (CHAR16
), Password
);
124 ASSERT (EncodedPassword
!= NULL
);
125 EncodePassword (EncodedPassword
, 20 * sizeof (CHAR16
));
126 if (CompareMem (EncodedPassword
, PrivateData
->Configuration
.WhatIsThePassword2
, 20 * sizeof (CHAR16
)) != 0) {
128 // Old password mismatch, return EFI_NOT_READY to prompt for error message
130 Status
= EFI_NOT_READY
;
132 Status
= EFI_SUCCESS
;
135 gBS
->FreePool (Password
);
136 gBS
->FreePool (EncodedPassword
);
143 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
,
144 EFI_STRING_ID StringId
150 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
153 // Get Buffer Storage data from EFI variable
155 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
156 Status
= gRT
->GetVariable (
161 &PrivateData
->Configuration
163 if (EFI_ERROR (Status
)) {
168 // Get user input password
170 Password
= &PrivateData
->Configuration
.WhatIsThePassword2
[0];
171 ZeroMem (Password
, 20 * sizeof (CHAR16
));
172 Status
= HiiLibGetString (PrivateData
->HiiHandle
[0], StringId
, Password
, &BufferSize
);
173 if (EFI_ERROR (Status
)) {
178 // Retrive uncommitted data from Browser
180 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
181 Configuration
= AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
182 ASSERT (Configuration
!= NULL
);
183 Status
= GetBrowserData (&mFormSetGuid
, VariableName
, &BufferSize
, (UINT8
*) Configuration
);
184 if (!EFI_ERROR (Status
)) {
186 // Update password's clear text in the screen
188 CopyMem (Configuration
->PasswordClearText
, Password
, 20 * sizeof (CHAR16
));
191 // Update uncommitted data of Browser
193 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
194 Status
= SetBrowserData (
198 (UINT8
*) Configuration
,
202 gBS
->FreePool (Configuration
);
207 EncodePassword (Password
, 20 * sizeof (CHAR16
));
208 Status
= gRT
->SetVariable(
211 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
212 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
213 &PrivateData
->Configuration
220 This function allows a caller to extract the current configuration for one
221 or more named elements from the target driver.
223 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
224 @param Request A null-terminated Unicode string in
225 <ConfigRequest> format.
226 @param Progress On return, points to a character in the Request
227 string. Points to the string's null terminator if
228 request was successful. Points to the most recent
229 '&' before the first failing name/value pair (or
230 the beginning of the string if the failure is in
231 the first name/value pair) if the request was not
233 @param Results A null-terminated Unicode string in
234 <ConfigAltResp> format which has all values filled
235 in for the names in the Request string. String to
236 be allocated by the called function.
238 @retval EFI_SUCCESS The Results is filled with the requested values.
239 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
240 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
241 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
248 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
249 IN CONST EFI_STRING Request
,
250 OUT EFI_STRING
*Progress
,
251 OUT EFI_STRING
*Results
256 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
257 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
259 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
260 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
263 // Get Buffer Storage data from EFI variable
265 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
266 Status
= gRT
->GetVariable (
271 &PrivateData
->Configuration
273 if (EFI_ERROR (Status
)) {
278 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
280 Status
= HiiConfigRouting
->BlockToConfig (
283 (UINT8
*) &PrivateData
->Configuration
,
293 This function processes the results of changes in configuration.
295 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
296 @param Configuration A null-terminated Unicode string in <ConfigResp>
298 @param Progress A pointer to a string filled in with the offset of
299 the most recent '&' before the first failing
300 name/value pair (or the beginning of the string if
301 the failure is in the first name/value pair) or
302 the terminating NULL if all was successful.
304 @retval EFI_SUCCESS The Results is processed successfully.
305 @retval EFI_INVALID_PARAMETER Configuration is NULL.
306 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
313 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
314 IN CONST EFI_STRING Configuration
,
315 OUT EFI_STRING
*Progress
320 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
321 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
323 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
324 HiiConfigRouting
= PrivateData
->HiiConfigRouting
;
327 // Get Buffer Storage data from EFI variable
329 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
330 Status
= gRT
->GetVariable (
335 &PrivateData
->Configuration
337 if (EFI_ERROR (Status
)) {
342 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
344 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
345 Status
= HiiConfigRouting
->ConfigToBlock (
348 (UINT8
*) &PrivateData
->Configuration
,
352 if (EFI_ERROR (Status
)) {
357 // Store Buffer Storage back to EFI variable
359 Status
= gRT
->SetVariable(
362 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
363 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
364 &PrivateData
->Configuration
372 This function processes the results of changes in configuration.
374 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
375 @param Action Specifies the type of action taken by the browser.
376 @param QuestionId A unique value which is sent to the original
377 exporting driver so that it can identify the type
379 @param Type The type of value for the question.
380 @param Value A pointer to the data being sent to the original
382 @param ActionRequest On return, points to the action requested by the
385 @retval EFI_SUCCESS The callback successfully handled the action.
386 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
387 variable and its data.
388 @retval EFI_DEVICE_ERROR The variable could not be saved.
389 @retval EFI_UNSUPPORTED The specified Action is not supported by the
396 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
397 IN EFI_BROWSER_ACTION Action
,
398 IN EFI_QUESTION_ID QuestionId
,
400 IN EFI_IFR_TYPE_VALUE
*Value
,
401 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
404 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
406 EFI_HII_UPDATE_DATA UpdateData
;
407 IFR_OPTION
*IfrOptionList
;
409 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
410 return EFI_INVALID_PARAMETER
;
413 Status
= EFI_SUCCESS
;
414 PrivateData
= DRIVER_SAMPLE_PRIVATE_FROM_THIS (This
);
416 switch (QuestionId
) {
419 // Create dynamic page for this interactive goto
421 UpdateData
.BufferSize
= 0x1000;
422 UpdateData
.Offset
= 0;
423 UpdateData
.Data
= AllocatePool (0x1000);
424 ASSERT (UpdateData
.Data
!= NULL
);
426 IfrOptionList
= AllocatePool (2 * sizeof (IFR_OPTION
));
427 ASSERT (IfrOptionList
!= NULL
);
429 IfrOptionList
[0].Flags
= 0;
430 IfrOptionList
[0].StringToken
= STRING_TOKEN (STR_BOOT_OPTION1
);
431 IfrOptionList
[0].Value
.u8
= 1;
432 IfrOptionList
[1].Flags
= EFI_IFR_OPTION_DEFAULT
;
433 IfrOptionList
[1].StringToken
= STRING_TOKEN (STR_BOOT_OPTION2
);
434 IfrOptionList
[1].Value
.u8
= 2;
438 STRING_TOKEN(STR_EXIT_TEXT
),
439 STRING_TOKEN(STR_EXIT_TEXT
),
440 EFI_IFR_FLAG_CALLBACK
,
449 STRING_TOKEN (STR_ONE_OF_PROMPT
),
450 STRING_TOKEN (STR_ONE_OF_HELP
),
451 EFI_IFR_FLAG_CALLBACK
,
452 EFI_IFR_NUMERIC_SIZE_1
,
458 CreateOrderedListOpCode (
462 STRING_TOKEN (STR_BOOT_OPTIONS
),
463 STRING_TOKEN (STR_BOOT_OPTIONS
),
464 EFI_IFR_FLAG_RESET_REQUIRED
,
466 EFI_IFR_NUMERIC_SIZE_1
,
475 STRING_TOKEN (STR_GOTO_FORM1
),
476 STRING_TOKEN (STR_GOTO_HELP
),
482 Status
= IfrLibUpdateForm (
483 PrivateData
->HiiHandle
[0],
490 gBS
->FreePool (IfrOptionList
);
491 gBS
->FreePool (UpdateData
.Data
);
496 // User press "Exit now", request Browser to exit
498 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
503 // User press "Save now", request Browser to save the uncommitted data.
505 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
510 // When try to set a new password, user will be chanlleged with old password.
511 // The Callback is responsible for validating old password input by user,
512 // If Callback return EFI_SUCCESS, it indicates validation pass.
514 switch (PrivateData
->PasswordState
) {
515 case BROWSER_STATE_VALIDATE_PASSWORD
:
516 Status
= ValidatePassword (PrivateData
, Value
->string
);
517 if (Status
== EFI_SUCCESS
) {
518 PrivateData
->PasswordState
= BROWSER_STATE_SET_PASSWORD
;
522 case BROWSER_STATE_SET_PASSWORD
:
523 Status
= SetPassword (PrivateData
, Value
->string
);
524 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
543 IN EFI_HANDLE ImageHandle
,
544 IN EFI_SYSTEM_TABLE
*SystemTable
548 EFI_STATUS SavedStatus
;
549 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
550 EFI_HII_HANDLE HiiHandle
[2];
551 EFI_HANDLE DriverHandle
[2];
552 DRIVER_SAMPLE_PRIVATE_DATA
*PrivateData
;
553 EFI_SCREEN_DESCRIPTOR Screen
;
554 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
555 EFI_HII_STRING_PROTOCOL
*HiiString
;
556 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
557 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
560 DRIVER_SAMPLE_CONFIGURATION
*Configuration
;
561 BOOLEAN ExtractIfrDefault
;
564 // Initialize the library and our protocol.
568 // Initialize screen dimensions for SendForm().
569 // Remove 3 characters from top and bottom
571 ZeroMem (&Screen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
572 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Screen
.RightColumn
, &Screen
.BottomRow
);
575 Screen
.BottomRow
= Screen
.BottomRow
- 3;
578 // Initialize driver private data
580 PrivateData
= AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA
));
581 if (PrivateData
== NULL
) {
582 return EFI_OUT_OF_RESOURCES
;
585 PrivateData
->Signature
= DRIVER_SAMPLE_PRIVATE_SIGNATURE
;
587 PrivateData
->ConfigAccess
.ExtractConfig
= ExtractConfig
;
588 PrivateData
->ConfigAccess
.RouteConfig
= RouteConfig
;
589 PrivateData
->ConfigAccess
.Callback
= DriverCallback
;
590 PrivateData
->PasswordState
= BROWSER_STATE_VALIDATE_PASSWORD
;
593 // Locate Hii Database protocol
595 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &HiiDatabase
);
596 if (EFI_ERROR (Status
)) {
599 PrivateData
->HiiDatabase
= HiiDatabase
;
602 // Locate HiiString protocol
604 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
605 if (EFI_ERROR (Status
)) {
608 PrivateData
->HiiString
= HiiString
;
611 // Locate Formbrowser2 protocol
613 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &FormBrowser2
);
614 if (EFI_ERROR (Status
)) {
617 PrivateData
->FormBrowser2
= FormBrowser2
;
620 // Locate ConfigRouting protocol
622 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &HiiConfigRouting
);
623 if (EFI_ERROR (Status
)) {
626 PrivateData
->HiiConfigRouting
= HiiConfigRouting
;
629 // Install Config Access protocol
631 Status
= HiiLibCreateHiiDriverHandle (&DriverHandle
[0]);
632 if (EFI_ERROR (Status
)) {
635 PrivateData
->DriverHandle
[0] = DriverHandle
[0];
637 Status
= gBS
->InstallProtocolInterface (
639 &gEfiHiiConfigAccessProtocolGuid
,
640 EFI_NATIVE_INTERFACE
,
641 &PrivateData
->ConfigAccess
643 ASSERT_EFI_ERROR (Status
);
646 // Publish our HII data
648 PackageList
= HiiLibPreparePackageList (
654 if (PackageList
== NULL
) {
655 return EFI_OUT_OF_RESOURCES
;
658 Status
= HiiDatabase
->NewPackageList (
664 gBS
->FreePool (PackageList
);
665 if (EFI_ERROR (Status
)) {
668 PrivateData
->HiiHandle
[0] = HiiHandle
[0];
671 // Publish another Fromset
673 Status
= HiiLibCreateHiiDriverHandle (&DriverHandle
[1]);
674 if (EFI_ERROR (Status
)) {
677 PrivateData
->DriverHandle
[1] = DriverHandle
[1];
679 PackageList
= HiiLibPreparePackageList (
685 if (PackageList
== NULL
) {
686 return EFI_OUT_OF_RESOURCES
;
689 Status
= HiiDatabase
->NewPackageList (
695 gBS
->FreePool (PackageList
);
696 if (EFI_ERROR (Status
)) {
699 PrivateData
->HiiHandle
[1] = HiiHandle
[1];
702 // Very simple example of how one would update a string that is already
703 // in the HII database
705 NewString
= L
"700 Mhz";
707 Status
= HiiLibSetString (HiiHandle
[0], STRING_TOKEN (STR_CPU_STRING2
), NewString
);
708 if (EFI_ERROR (Status
)) {
713 // Initialize configuration data
715 Configuration
= &PrivateData
->Configuration
;
716 ZeroMem (Configuration
, sizeof (DRIVER_SAMPLE_CONFIGURATION
));
719 // Try to read NV config EFI variable first
721 ExtractIfrDefault
= TRUE
;
722 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
723 Status
= gRT
->GetVariable (VariableName
, &mFormSetGuid
, NULL
, &BufferSize
, Configuration
);
724 if (!EFI_ERROR (Status
) && (BufferSize
== sizeof (DRIVER_SAMPLE_CONFIGURATION
))) {
725 ExtractIfrDefault
= FALSE
;
728 if (ExtractIfrDefault
) {
730 // EFI variable for NV config doesn't exit, we should build this variable
731 // based on default values stored in IFR
733 BufferSize
= sizeof (DRIVER_SAMPLE_CONFIGURATION
);
734 Status
= IfrLibExtractDefault (Configuration
, &BufferSize
, 1, VfrMyIfrNVDataDefault0000
);
736 if (!EFI_ERROR (Status
)) {
740 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
741 sizeof (DRIVER_SAMPLE_CONFIGURATION
),
748 // Example of how to display only the item we sent to HII
750 if (DISPLAY_ONLY_MY_ITEM
== 0x0001) {
752 // Have the browser pull out our copy of the data, and only display our data
754 // Status = FormConfig->SendForm (FormConfig, TRUE, HiiHandle, NULL, NULL, NULL, &Screen, NULL);
756 Status
= FormBrowser2
->SendForm (
765 SavedStatus
= Status
;
767 Status
= HiiDatabase
->RemovePackageList (HiiDatabase
, HiiHandle
[0]);
768 if (EFI_ERROR (Status
)) {
772 Status
= HiiDatabase
->RemovePackageList (HiiDatabase
, HiiHandle
[1]);
773 if (EFI_ERROR (Status
)) {
780 // Have the browser pull out all the data in the HII Database and display it.
782 // Status = FormConfig->SendForm (FormConfig, TRUE, 0, NULL, NULL, NULL, NULL, NULL);