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