]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Merge new defined HII library APIs into HiiLib
[mirror_edk2.git] / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
1 /** @file
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
4
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
10
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.
13
14 **/
15
16
17 #include "DriverSample.h"
18
19 #define DISPLAY_ONLY_MY_ITEM 0x0002
20
21 EFI_GUID mFormSetGuid = FORMSET_GUID;
22 EFI_GUID mInventoryGuid = INVENTORY_GUID;
23
24 CHAR16 VariableName[] = L"MyIfrNVData";
25
26 EFI_HANDLE DriverHandle[2] = {NULL, NULL};
27 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData = NULL;
28
29 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {
30 {
31 {
32 HARDWARE_DEVICE_PATH,
33 HW_VENDOR_DP,
34 {
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
37 }
38 },
39 //
40 // {C153B68D-EBFC-488e-B110-662867745B87}
41 //
42 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }
43 },
44 {
45 END_DEVICE_PATH_TYPE,
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,
47 {
48 (UINT8) (END_DEVICE_PATH_LENGTH),
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
50 }
51 }
52 };
53
54 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {
55 {
56 {
57 HARDWARE_DEVICE_PATH,
58 HW_VENDOR_DP,
59 {
60 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
61 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
62 }
63 },
64 //
65 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}
66 //
67 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }
68 },
69 {
70 END_DEVICE_PATH_TYPE,
71 END_ENTIRE_DEVICE_PATH_SUBTYPE,
72 {
73 (UINT8) (END_DEVICE_PATH_LENGTH),
74 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
75 }
76 }
77 };
78
79 /**
80 Encode the password using a simple algorithm.
81
82 @param Password The string to be encoded.
83 @param MaxSize The size of the string.
84
85 **/
86 VOID
87 EncodePassword (
88 IN CHAR16 *Password,
89 IN UINTN MaxSize
90 )
91 {
92 UINTN Index;
93 UINTN Loop;
94 CHAR16 *Buffer;
95 CHAR16 *Key;
96
97 Key = L"MAR10648567";
98 Buffer = AllocateZeroPool (MaxSize);
99 ASSERT (Buffer != NULL);
100
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]);
104 }
105 }
106
107 CopyMem (Password, Buffer, MaxSize);
108
109 FreePool (Buffer);
110 return ;
111 }
112
113 /**
114 Validate the user's password.
115
116 @param PrivateData This driver's private context data.
117 @param StringId The user's input.
118
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.
121 **/
122 EFI_STATUS
123 ValidatePassword (
124 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,
125 IN EFI_STRING_ID StringId
126 )
127 {
128 EFI_STATUS Status;
129 UINTN Index;
130 UINTN BufferSize;
131 CHAR16 *Password;
132 CHAR16 *EncodedPassword;
133 BOOLEAN OldPassword;
134
135 //
136 // Get encoded password first
137 //
138 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
139 Status = gRT->GetVariable (
140 VariableName,
141 &mFormSetGuid,
142 NULL,
143 &BufferSize,
144 &PrivateData->Configuration
145 );
146 if (EFI_ERROR (Status)) {
147 //
148 // Old password not exist, prompt for new password
149 //
150 return EFI_SUCCESS;
151 }
152
153 OldPassword = FALSE;
154 //
155 // Check whether we have any old password set
156 //
157 for (Index = 0; Index < 20; Index++) {
158 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {
159 OldPassword = TRUE;
160 break;
161 }
162 }
163 if (!OldPassword) {
164 //
165 // Old password not exist, return EFI_SUCCESS to prompt for new password
166 //
167 return EFI_SUCCESS;
168 }
169
170 //
171 // Get user input password
172 //
173 BufferSize = 21 * sizeof (CHAR16);
174 Password = AllocateZeroPool (BufferSize);
175 ASSERT (Password != NULL);
176
177 Status = HiiLibGetString (PrivateData->HiiHandle[0], StringId, Password, &BufferSize);
178 if (EFI_ERROR (Status)) {
179 FreePool (Password);
180 return Status;
181 }
182
183 //
184 // Validate old password
185 //
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) {
190 //
191 // Old password mismatch, return EFI_NOT_READY to prompt for error message
192 //
193 Status = EFI_NOT_READY;
194 } else {
195 Status = EFI_SUCCESS;
196 }
197
198 FreePool (Password);
199 FreePool (EncodedPassword);
200
201 return Status;
202 }
203
204 /**
205 Encode the password using a simple algorithm.
206
207 @param PrivateData This driver's private context data.
208 @param StringId The password from User.
209
210 @retval EFI_SUCESS The operation is successful.
211 @return Other value if gRT->SetVariable () fails.
212
213 **/
214 EFI_STATUS
215 SetPassword (
216 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,
217 IN EFI_STRING_ID StringId
218 )
219 {
220 EFI_STATUS Status;
221 CHAR16 *Password;
222 UINTN PasswordSize;
223 DRIVER_SAMPLE_CONFIGURATION *Configuration;
224 UINTN BufferSize;
225
226 //
227 // Get Buffer Storage data from EFI variable
228 //
229 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
230 Status = gRT->GetVariable (
231 VariableName,
232 &mFormSetGuid,
233 NULL,
234 &BufferSize,
235 &PrivateData->Configuration
236 );
237 if (EFI_ERROR (Status)) {
238 return Status;
239 }
240
241 //
242 // Get user input password
243 //
244 Password = &PrivateData->Configuration.WhatIsThePassword2[0];
245 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);
246
247 ZeroMem (Password, PasswordSize);
248 Status = HiiLibGetString (PrivateData->HiiHandle[0], StringId, Password, &BufferSize);
249 if (EFI_ERROR (Status)) {
250 return Status;
251 }
252
253 //
254 // Retrive uncommitted data from Browser
255 //
256 Configuration = (DRIVER_SAMPLE_CONFIGURATION *) HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION));
257 if (Configuration != NULL) {
258 //
259 // Update password's clear text in the screen
260 //
261 CopyMem (Configuration->PasswordClearText, Password, PasswordSize);
262
263 //
264 // Update uncommitted data of Browser
265 //
266 HiiSetBrowserData (
267 &mFormSetGuid,
268 VariableName,
269 sizeof (DRIVER_SAMPLE_CONFIGURATION),
270 (UINT8 *) Configuration,
271 NULL
272 );
273
274 FreePool (Configuration);
275 }
276
277
278 //
279 // Set password
280 //
281 EncodePassword (Password, PasswordSize);
282 Status = gRT->SetVariable(
283 VariableName,
284 &mFormSetGuid,
285 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
286 sizeof (DRIVER_SAMPLE_CONFIGURATION),
287 &PrivateData->Configuration
288 );
289 return Status;
290 }
291
292
293 /**
294 This function allows a caller to extract the current configuration for one
295 or more named elements from the target driver.
296
297 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
298 @param Request A null-terminated Unicode string in
299 <ConfigRequest> format.
300 @param Progress On return, points to a character in the Request
301 string. Points to the string's null terminator if
302 request was successful. Points to the most recent
303 '&' before the first failing name/value pair (or
304 the beginning of the string if the failure is in
305 the first name/value pair) if the request was not
306 successful.
307 @param Results A null-terminated Unicode string in
308 <ConfigAltResp> format which has all values filled
309 in for the names in the Request string. String to
310 be allocated by the called function.
311
312 @retval EFI_SUCCESS The Results is filled with the requested values.
313 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
314 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
315 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
316 driver.
317
318 **/
319 EFI_STATUS
320 EFIAPI
321 ExtractConfig (
322 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
323 IN CONST EFI_STRING Request,
324 OUT EFI_STRING *Progress,
325 OUT EFI_STRING *Results
326 )
327 {
328 EFI_STATUS Status;
329 UINTN BufferSize;
330 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
331 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
332
333 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
334 HiiConfigRouting = PrivateData->HiiConfigRouting;
335
336 //
337 //
338 // Get Buffer Storage data from EFI variable
339 //
340 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
341 Status = gRT->GetVariable (
342 VariableName,
343 &mFormSetGuid,
344 NULL,
345 &BufferSize,
346 &PrivateData->Configuration
347 );
348 if (EFI_ERROR (Status)) {
349 return Status;
350 }
351
352 if (Request == NULL) {
353 //
354 // Request is set to NULL, return all configurable elements together with ALTCFG
355 //
356 *Results = HiiConstructConfigAltResp (
357 &mFormSetGuid,
358 VariableName,
359 PrivateData->DriverHandle[0],
360 &PrivateData->Configuration,
361 BufferSize,
362 VfrMyIfrNVDataBlockName,
363 STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT),
364 VfrMyIfrNVDataDefault0000,
365 STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT),
366 VfrMyIfrNVDataDefault0001,
367 0,
368 NULL
369 );
370
371 //
372 // No matched storage is found.
373 //
374 if (*Results == NULL) {
375 return EFI_NOT_FOUND;
376 }
377
378 return EFI_SUCCESS;
379 }
380
381 //
382 // Check routing data in <ConfigHdr>.
383 // Note: if only one Storage is used, then this checking could be skipped.
384 //
385 if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {
386 *Progress = Request;
387 return EFI_NOT_FOUND;
388 }
389
390 //
391 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
392 //
393 Status = HiiConfigRouting->BlockToConfig (
394 HiiConfigRouting,
395 Request,
396 (UINT8 *) &PrivateData->Configuration,
397 BufferSize,
398 Results,
399 Progress
400 );
401 return Status;
402 }
403
404
405 /**
406 This function processes the results of changes in configuration.
407
408 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
409 @param Configuration A null-terminated Unicode string in <ConfigResp>
410 format.
411 @param Progress A pointer to a string filled in with the offset of
412 the most recent '&' before the first failing
413 name/value pair (or the beginning of the string if
414 the failure is in the first name/value pair) or
415 the terminating NULL if all was successful.
416
417 @retval EFI_SUCCESS The Results is processed successfully.
418 @retval EFI_INVALID_PARAMETER Configuration is NULL.
419 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
420 driver.
421
422 **/
423 EFI_STATUS
424 EFIAPI
425 RouteConfig (
426 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
427 IN CONST EFI_STRING Configuration,
428 OUT EFI_STRING *Progress
429 )
430 {
431 EFI_STATUS Status;
432 UINTN BufferSize;
433 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
434 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
435
436 if (Configuration == NULL) {
437 return EFI_INVALID_PARAMETER;
438 }
439
440 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
441 HiiConfigRouting = PrivateData->HiiConfigRouting;
442
443 // Check routing data in <ConfigHdr>.
444 // Note: if only one Storage is used, then this checking could be skipped.
445 //
446 if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {
447 *Progress = Configuration;
448 return EFI_NOT_FOUND;
449 }
450
451 //
452 // Get Buffer Storage data from EFI variable
453 //
454 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
455 Status = gRT->GetVariable (
456 VariableName,
457 &mFormSetGuid,
458 NULL,
459 &BufferSize,
460 &PrivateData->Configuration
461 );
462 if (EFI_ERROR (Status)) {
463 return Status;
464 }
465
466 //
467 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
468 //
469 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
470 Status = HiiConfigRouting->ConfigToBlock (
471 HiiConfigRouting,
472 Configuration,
473 (UINT8 *) &PrivateData->Configuration,
474 &BufferSize,
475 Progress
476 );
477 if (EFI_ERROR (Status)) {
478 return Status;
479 }
480
481 //
482 // Store Buffer Storage back to EFI variable
483 //
484 Status = gRT->SetVariable(
485 VariableName,
486 &mFormSetGuid,
487 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
488 sizeof (DRIVER_SAMPLE_CONFIGURATION),
489 &PrivateData->Configuration
490 );
491
492 return Status;
493 }
494
495
496 /**
497 This function processes the results of changes in configuration.
498
499 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
500 @param Action Specifies the type of action taken by the browser.
501 @param QuestionId A unique value which is sent to the original
502 exporting driver so that it can identify the type
503 of data to expect.
504 @param Type The type of value for the question.
505 @param Value A pointer to the data being sent to the original
506 exporting driver.
507 @param ActionRequest On return, points to the action requested by the
508 callback function.
509
510 @retval EFI_SUCCESS The callback successfully handled the action.
511 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
512 variable and its data.
513 @retval EFI_DEVICE_ERROR The variable could not be saved.
514 @retval EFI_UNSUPPORTED The specified Action is not supported by the
515 callback.
516
517 **/
518 EFI_STATUS
519 EFIAPI
520 DriverCallback (
521 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
522 IN EFI_BROWSER_ACTION Action,
523 IN EFI_QUESTION_ID QuestionId,
524 IN UINT8 Type,
525 IN EFI_IFR_TYPE_VALUE *Value,
526 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
527 )
528 {
529 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
530 EFI_STATUS Status;
531 UINT8 MyVar;
532 VOID *StartOpCodeHandle;
533 VOID *OptionsOpCodeHandle;
534 EFI_IFR_GUID_LABEL *StartLabel;
535 VOID *EndOpCodeHandle;
536 EFI_IFR_GUID_LABEL *EndLabel;
537
538 if ((Value == NULL) || (ActionRequest == NULL)) {
539 return EFI_INVALID_PARAMETER;
540 }
541
542 Status = EFI_SUCCESS;
543 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
544
545 switch (QuestionId) {
546 case 0x1234:
547 //
548 // Initialize the container for dynamic opcodes
549 //
550 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
551 ASSERT (StartOpCodeHandle != NULL);
552
553 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
554 ASSERT (EndOpCodeHandle != NULL);
555
556 //
557 // Create Hii Extend Label OpCode as the start opcode
558 //
559 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
560 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
561 StartLabel->Number = LABEL_UPDATE1;
562
563 //
564 // Create Hii Extend Label OpCode as the end opcode
565 //
566 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
567 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
568 EndLabel->Number = LABEL_END;
569
570 HiiCreateActionOpCode (
571 StartOpCodeHandle, // Container for dynamic created opcodes
572 0x1237, // Question ID
573 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
574 STRING_TOKEN(STR_EXIT_TEXT), // Help text
575 EFI_IFR_FLAG_CALLBACK, // Question flag
576 0 // Action String ID
577 );
578
579 //
580 // Create Option OpCode
581 //
582 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
583 ASSERT (OptionsOpCodeHandle != NULL);
584
585 HiiCreateOneOfOptionOpCode (
586 OptionsOpCodeHandle,
587 STRING_TOKEN (STR_BOOT_OPTION1),
588 0,
589 EFI_IFR_NUMERIC_SIZE_1,
590 1
591 );
592
593 HiiCreateOneOfOptionOpCode (
594 OptionsOpCodeHandle,
595 STRING_TOKEN (STR_BOOT_OPTION2),
596 0,
597 EFI_IFR_NUMERIC_SIZE_1,
598 2
599 );
600
601 //
602 // Prepare initial value for the dynamic created oneof Question
603 //
604 PrivateData->Configuration.DynamicOneof = 2;
605 Status = gRT->SetVariable(
606 VariableName,
607 &mFormSetGuid,
608 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
609 sizeof (DRIVER_SAMPLE_CONFIGURATION),
610 &PrivateData->Configuration
611 );
612
613 HiiCreateOneOfOpCode (
614 StartOpCodeHandle, // Container for dynamic created opcodes
615 0x8001, // Question ID (or call it "key")
616 CONFIGURATION_VARSTORE_ID, // VarStore ID
617 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage
618 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text
619 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text
620 EFI_IFR_FLAG_CALLBACK, // Question flag
621 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value
622 OptionsOpCodeHandle, // Option Opcode list
623 NULL // Default Opcode is NULl
624 );
625
626 HiiCreateOrderedListOpCode (
627 StartOpCodeHandle, // Container for dynamic created opcodes
628 0x8002, // Question ID
629 CONFIGURATION_VARSTORE_ID, // VarStore ID
630 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage
631 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text
632 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text
633 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
634 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
635 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value
636 5, // Maximum container
637 OptionsOpCodeHandle, // Option Opcode list
638 NULL // Default Opcode is NULl
639 );
640
641 HiiCreateGotoOpCode (
642 StartOpCodeHandle, // Container for dynamic created opcodes
643 1, // Target Form ID
644 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
645 STRING_TOKEN (STR_GOTO_HELP), // Help text
646 0, // Question flag
647 0x8003 // Question ID
648 );
649
650 HiiUpdateForm (
651 PrivateData->HiiHandle[0], // HII handle
652 &mFormSetGuid, // Formset GUID
653 0x1234, // Form ID
654 StartOpCodeHandle, // Label for where to insert opcodes
655 EndOpCodeHandle // Replace data
656 );
657
658 HiiFreeOpCodeHandle (StartOpCodeHandle);
659 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
660 break;
661
662 case 0x5678:
663 //
664 // We will reach here once the Question is refreshed
665 //
666
667 //
668 // Initialize the container for dynamic opcodes
669 //
670 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
671 ASSERT (StartOpCodeHandle != NULL);
672
673 //
674 // Create Hii Extend Label OpCode as the start opcode
675 //
676 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
677 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
678 StartLabel->Number = LABEL_UPDATE2;
679
680 HiiCreateActionOpCode (
681 StartOpCodeHandle, // Container for dynamic created opcodes
682 0x1237, // Question ID
683 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
684 STRING_TOKEN(STR_EXIT_TEXT), // Help text
685 EFI_IFR_FLAG_CALLBACK, // Question flag
686 0 // Action String ID
687 );
688
689 HiiUpdateForm (
690 PrivateData->HiiHandle[0], // HII handle
691 &mFormSetGuid, // Formset GUID
692 0x3, // Form ID
693 StartOpCodeHandle, // Label for where to insert opcodes
694 NULL // Insert data
695 );
696
697 HiiFreeOpCodeHandle (StartOpCodeHandle);
698
699 //
700 // Refresh the Question value
701 //
702 PrivateData->Configuration.DynamicRefresh++;
703 Status = gRT->SetVariable(
704 VariableName,
705 &mFormSetGuid,
706 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
707 sizeof (DRIVER_SAMPLE_CONFIGURATION),
708 &PrivateData->Configuration
709 );
710
711 //
712 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
713 // the first statement in Form 3 be suppressed
714 //
715 MyVar = 111;
716 Status = gRT->SetVariable(
717 L"MyVar",
718 &mFormSetGuid,
719 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
720 1,
721 &MyVar
722 );
723 break;
724
725 case 0x1237:
726 //
727 // User press "Exit now", request Browser to exit
728 //
729 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
730 break;
731
732 case 0x1238:
733 //
734 // User press "Save now", request Browser to save the uncommitted data.
735 //
736 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
737 break;
738
739 case 0x2000:
740 //
741 // When try to set a new password, user will be chanlleged with old password.
742 // The Callback is responsible for validating old password input by user,
743 // If Callback return EFI_SUCCESS, it indicates validation pass.
744 //
745 switch (PrivateData->PasswordState) {
746 case BROWSER_STATE_VALIDATE_PASSWORD:
747 Status = ValidatePassword (PrivateData, Value->string);
748 if (Status == EFI_SUCCESS) {
749 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;
750 }
751 break;
752
753 case BROWSER_STATE_SET_PASSWORD:
754 Status = SetPassword (PrivateData, Value->string);
755 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
756 break;
757
758 default:
759 break;
760 }
761
762 break;
763
764 default:
765 break;
766 }
767
768 return Status;
769 }
770
771 /**
772 Main entry for this driver.
773
774 @param ImageHandle Image handle this driver.
775 @param SystemTable Pointer to SystemTable.
776
777 @retval EFI_SUCESS This function always complete successfully.
778
779 **/
780 EFI_STATUS
781 EFIAPI
782 DriverSampleInit (
783 IN EFI_HANDLE ImageHandle,
784 IN EFI_SYSTEM_TABLE *SystemTable
785 )
786 {
787 EFI_STATUS Status;
788 EFI_STATUS SavedStatus;
789 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
790 EFI_HII_HANDLE HiiHandle[2];
791 EFI_SCREEN_DESCRIPTOR Screen;
792 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
793 EFI_HII_STRING_PROTOCOL *HiiString;
794 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
795 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
796 CHAR16 *NewString;
797 UINTN BufferSize;
798 DRIVER_SAMPLE_CONFIGURATION *Configuration;
799 BOOLEAN ExtractIfrDefault;
800
801 //
802 // Initialize the library and our protocol.
803 //
804
805 //
806 // Initialize screen dimensions for SendForm().
807 // Remove 3 characters from top and bottom
808 //
809 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
810 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
811
812 Screen.TopRow = 3;
813 Screen.BottomRow = Screen.BottomRow - 3;
814
815 //
816 // Initialize driver private data
817 //
818 PrivateData = AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
819 if (PrivateData == NULL) {
820 return EFI_OUT_OF_RESOURCES;
821 }
822
823 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
824
825 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
826 PrivateData->ConfigAccess.RouteConfig = RouteConfig;
827 PrivateData->ConfigAccess.Callback = DriverCallback;
828 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
829
830 //
831 // Locate Hii Database protocol
832 //
833 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
834 if (EFI_ERROR (Status)) {
835 return Status;
836 }
837 PrivateData->HiiDatabase = HiiDatabase;
838
839 //
840 // Locate HiiString protocol
841 //
842 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
843 if (EFI_ERROR (Status)) {
844 return Status;
845 }
846 PrivateData->HiiString = HiiString;
847
848 //
849 // Locate Formbrowser2 protocol
850 //
851 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
852 if (EFI_ERROR (Status)) {
853 return Status;
854 }
855 PrivateData->FormBrowser2 = FormBrowser2;
856
857 //
858 // Locate ConfigRouting protocol
859 //
860 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
861 if (EFI_ERROR (Status)) {
862 return Status;
863 }
864 PrivateData->HiiConfigRouting = HiiConfigRouting;
865
866 Status = gBS->InstallMultipleProtocolInterfaces (
867 &DriverHandle[0],
868 &gEfiDevicePathProtocolGuid,
869 &mHiiVendorDevicePath0,
870 &gEfiHiiConfigAccessProtocolGuid,
871 &PrivateData->ConfigAccess,
872 NULL
873 );
874 ASSERT_EFI_ERROR (Status);
875
876 PrivateData->DriverHandle[0] = DriverHandle[0];
877
878 //
879 // Publish our HII data
880 //
881 PackageList = HiiLibPreparePackageList (
882 2,
883 &mFormSetGuid,
884 DriverSampleStrings,
885 VfrBin
886 );
887 if (PackageList == NULL) {
888 return EFI_OUT_OF_RESOURCES;
889 }
890
891 Status = HiiDatabase->NewPackageList (
892 HiiDatabase,
893 PackageList,
894 DriverHandle[0],
895 &HiiHandle[0]
896 );
897 FreePool (PackageList);
898 if (EFI_ERROR (Status)) {
899 return Status;
900 }
901 PrivateData->HiiHandle[0] = HiiHandle[0];
902
903 //
904 // Publish another Fromset
905 //
906 Status = gBS->InstallMultipleProtocolInterfaces (
907 &DriverHandle[1],
908 &gEfiDevicePathProtocolGuid,
909 &mHiiVendorDevicePath1,
910 NULL
911 );
912 ASSERT_EFI_ERROR (Status);
913
914 PrivateData->DriverHandle[1] = DriverHandle[1];
915
916 PackageList = HiiLibPreparePackageList (
917 2,
918 &mInventoryGuid,
919 DriverSampleStrings,
920 InventoryBin
921 );
922 if (PackageList == NULL) {
923 return EFI_OUT_OF_RESOURCES;
924 }
925
926 Status = HiiDatabase->NewPackageList (
927 HiiDatabase,
928 PackageList,
929 DriverHandle[1],
930 &HiiHandle[1]
931 );
932 FreePool (PackageList);
933 if (EFI_ERROR (Status)) {
934 return Status;
935 }
936 PrivateData->HiiHandle[1] = HiiHandle[1];
937
938 //
939 // Very simple example of how one would update a string that is already
940 // in the HII database
941 //
942 NewString = L"700 Mhz";
943
944 Status = HiiLibSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString);
945 if (EFI_ERROR (Status)) {
946 return Status;
947 }
948
949 //
950 // Initialize configuration data
951 //
952 Configuration = &PrivateData->Configuration;
953 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
954
955 //
956 // Try to read NV config EFI variable first
957 //
958 ExtractIfrDefault = TRUE;
959 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
960 Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);
961 if (!EFI_ERROR (Status) && (BufferSize == sizeof (DRIVER_SAMPLE_CONFIGURATION))) {
962 ExtractIfrDefault = FALSE;
963 }
964
965 if (ExtractIfrDefault) {
966 //
967 // EFI variable for NV config doesn't exit, we should build this variable
968 // based on default values stored in IFR
969 //
970 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
971 Status = HiiIfrLibExtractDefault (Configuration, &BufferSize, 1, VfrMyIfrNVDataDefault0000);
972
973 if (!EFI_ERROR (Status)) {
974 gRT->SetVariable(
975 VariableName,
976 &mFormSetGuid,
977 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
978 sizeof (DRIVER_SAMPLE_CONFIGURATION),
979 Configuration
980 );
981 }
982 }
983
984 SavedStatus = EFI_SUCCESS;
985
986 //
987 // Default this driver is built into Flash device image,
988 // the following code doesn't run.
989 //
990
991 //
992 // Example of how to display only the item we sent to HII
993 // When this driver is not built into Flash device image,
994 // it need to call SendForm to show front page by itself.
995 //
996 if (DISPLAY_ONLY_MY_ITEM <= 1) {
997 //
998 // Have the browser pull out our copy of the data, and only display our data
999 //
1000 Status = FormBrowser2->SendForm (
1001 FormBrowser2,
1002 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
1003 1,
1004 NULL,
1005 0,
1006 NULL,
1007 NULL
1008 );
1009 SavedStatus = Status;
1010
1011 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]);
1012 if (EFI_ERROR (Status)) {
1013 return Status;
1014 }
1015
1016 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]);
1017 if (EFI_ERROR (Status)) {
1018 return Status;
1019 }
1020 }
1021
1022 return SavedStatus;
1023 }
1024
1025 /**
1026 Unloads the application and its installed protocol.
1027
1028 @param[in] ImageHandle Handle that identifies the image to be unloaded.
1029
1030 @retval EFI_SUCCESS The image has been unloaded.
1031 **/
1032 EFI_STATUS
1033 EFIAPI
1034 DriverSampleUnload (
1035 IN EFI_HANDLE ImageHandle
1036 )
1037 {
1038 if (DriverHandle[0] != NULL) {
1039 gBS->UninstallMultipleProtocolInterfaces (
1040 DriverHandle[0],
1041 &gEfiDevicePathProtocolGuid,
1042 &mHiiVendorDevicePath0,
1043 &gEfiHiiConfigAccessProtocolGuid,
1044 &PrivateData->ConfigAccess,
1045 NULL
1046 );
1047 }
1048
1049 if (DriverHandle[1] != NULL) {
1050 gBS->UninstallMultipleProtocolInterfaces (
1051 DriverHandle[1],
1052 &gEfiDevicePathProtocolGuid,
1053 &mHiiVendorDevicePath1,
1054 NULL
1055 );
1056 }
1057
1058 if (PrivateData != NULL) {
1059 FreePool (PrivateData);
1060 }
1061
1062 return EFI_SUCCESS;
1063 }