]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Add unload function for DriverSample
[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 0x0000
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 UINTN BufferSize;
222 CHAR16 *Password;
223 UINTN PasswordSize;
224 DRIVER_SAMPLE_CONFIGURATION *Configuration;
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 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)) {
261 //
262 // Update password's clear text in the screen
263 //
264 CopyMem (Configuration->PasswordClearText, Password, PasswordSize);
265
266 //
267 // Update uncommitted data of Browser
268 //
269 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
270 Status = SetBrowserData (
271 &mFormSetGuid,
272 VariableName,
273 BufferSize,
274 (UINT8 *) Configuration,
275 NULL
276 );
277 }
278 FreePool (Configuration);
279
280 //
281 // Set password
282 //
283 EncodePassword (Password, PasswordSize);
284 Status = gRT->SetVariable(
285 VariableName,
286 &mFormSetGuid,
287 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
288 sizeof (DRIVER_SAMPLE_CONFIGURATION),
289 &PrivateData->Configuration
290 );
291 return Status;
292 }
293
294
295 /**
296 This function allows a caller to extract the current configuration for one
297 or more named elements from the target driver.
298
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
308 successful.
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.
313
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
318 driver.
319
320 **/
321 EFI_STATUS
322 EFIAPI
323 ExtractConfig (
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
328 )
329 {
330 EFI_STATUS Status;
331 UINTN BufferSize;
332 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
333 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
334
335 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
336 HiiConfigRouting = PrivateData->HiiConfigRouting;
337
338 //
339 //
340 // Get Buffer Storage data from EFI variable
341 //
342 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
343 Status = gRT->GetVariable (
344 VariableName,
345 &mFormSetGuid,
346 NULL,
347 &BufferSize,
348 &PrivateData->Configuration
349 );
350 if (EFI_ERROR (Status)) {
351 return Status;
352 }
353
354 if (Request == NULL) {
355 //
356 // Request is set to NULL, return all configurable elements together with ALTCFG
357 //
358 Status = ConstructConfigAltResp (
359 NULL,
360 NULL,
361 Results,
362 &mFormSetGuid,
363 VariableName,
364 PrivateData->DriverHandle[0],
365 &PrivateData->Configuration,
366 BufferSize,
367 VfrMyIfrNVDataBlockName,
368 2,
369 STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT),
370 VfrMyIfrNVDataDefault0000,
371 STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT),
372 VfrMyIfrNVDataDefault0001
373 );
374
375 return Status;
376 }
377
378 //
379 // Check routing data in <ConfigHdr>.
380 // Note: if only one Storage is used, then this checking could be skipped.
381 //
382 if (!IsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {
383 *Progress = Request;
384 return EFI_NOT_FOUND;
385 }
386
387 //
388 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
389 //
390 Status = HiiConfigRouting->BlockToConfig (
391 HiiConfigRouting,
392 Request,
393 (UINT8 *) &PrivateData->Configuration,
394 BufferSize,
395 Results,
396 Progress
397 );
398 return Status;
399 }
400
401
402 /**
403 This function processes the results of changes in configuration.
404
405 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
406 @param Configuration A null-terminated Unicode string in <ConfigResp>
407 format.
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.
413
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
417 driver.
418
419 **/
420 EFI_STATUS
421 EFIAPI
422 RouteConfig (
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
424 IN CONST EFI_STRING Configuration,
425 OUT EFI_STRING *Progress
426 )
427 {
428 EFI_STATUS Status;
429 UINTN BufferSize;
430 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
431 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
432
433 if (Configuration == NULL) {
434 return EFI_INVALID_PARAMETER;
435 }
436
437 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
438 HiiConfigRouting = PrivateData->HiiConfigRouting;
439
440 // Check routing data in <ConfigHdr>.
441 // Note: if only one Storage is used, then this checking could be skipped.
442 //
443 if (!IsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {
444 *Progress = Configuration;
445 return EFI_NOT_FOUND;
446 }
447
448 //
449 // Get Buffer Storage data from EFI variable
450 //
451 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
452 Status = gRT->GetVariable (
453 VariableName,
454 &mFormSetGuid,
455 NULL,
456 &BufferSize,
457 &PrivateData->Configuration
458 );
459 if (EFI_ERROR (Status)) {
460 return Status;
461 }
462
463 //
464 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
465 //
466 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
467 Status = HiiConfigRouting->ConfigToBlock (
468 HiiConfigRouting,
469 Configuration,
470 (UINT8 *) &PrivateData->Configuration,
471 &BufferSize,
472 Progress
473 );
474 if (EFI_ERROR (Status)) {
475 return Status;
476 }
477
478 //
479 // Store Buffer Storage back to EFI variable
480 //
481 Status = gRT->SetVariable(
482 VariableName,
483 &mFormSetGuid,
484 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
485 sizeof (DRIVER_SAMPLE_CONFIGURATION),
486 &PrivateData->Configuration
487 );
488
489 return Status;
490 }
491
492
493 /**
494 This function processes the results of changes in configuration.
495
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
500 of data to expect.
501 @param Type The type of value for the question.
502 @param Value A pointer to the data being sent to the original
503 exporting driver.
504 @param ActionRequest On return, points to the action requested by the
505 callback function.
506
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
512 callback.
513
514 **/
515 EFI_STATUS
516 EFIAPI
517 DriverCallback (
518 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
519 IN EFI_BROWSER_ACTION Action,
520 IN EFI_QUESTION_ID QuestionId,
521 IN UINT8 Type,
522 IN EFI_IFR_TYPE_VALUE *Value,
523 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
524 )
525 {
526 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
527 EFI_STATUS Status;
528 EFI_HII_UPDATE_DATA UpdateData;
529 IFR_OPTION *IfrOptionList;
530 UINT8 MyVar;
531
532 if ((Value == NULL) || (ActionRequest == NULL)) {
533 return EFI_INVALID_PARAMETER;
534 }
535
536 Status = EFI_SUCCESS;
537 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
538
539 switch (QuestionId) {
540 case 0x1234:
541 //
542 // Initialize the container for dynamic opcodes
543 //
544 IfrLibInitUpdateData (&UpdateData, 0x1000);
545
546 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
547 ASSERT (IfrOptionList != NULL);
548
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;
555
556 CreateActionOpCode (
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
563 );
564
565 //
566 // Prepare initial value for the dynamic created oneof Question
567 //
568 PrivateData->Configuration.DynamicOneof = 2;
569 Status = gRT->SetVariable(
570 VariableName,
571 &mFormSetGuid,
572 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
573 sizeof (DRIVER_SAMPLE_CONFIGURATION),
574 &PrivateData->Configuration
575 );
576 CreateOneOfOpCode (
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
587 );
588
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
602 );
603
604 CreateGotoOpCode (
605 1, // Target Form ID
606 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
607 STRING_TOKEN (STR_GOTO_HELP), // Help text
608 0, // Question flag
609 0x8003, // Question ID
610 &UpdateData // Container for dynamic created opcodes
611 );
612
613 Status = IfrLibUpdateForm (
614 PrivateData->HiiHandle[0], // HII handle
615 &mFormSetGuid, // Formset GUID
616 0x1234, // Form ID
617 0x1234, // Label for where to insert opcodes
618 TRUE, // Append or replace
619 &UpdateData // Dynamic created opcodes
620 );
621 FreePool (IfrOptionList);
622 IfrLibFreeUpdateData (&UpdateData);
623 break;
624
625 case 0x5678:
626 //
627 // We will reach here once the Question is refreshed
628 //
629 IfrLibInitUpdateData (&UpdateData, 0x1000);
630
631 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
632 ASSERT (IfrOptionList != NULL);
633
634 CreateActionOpCode (
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
641 );
642
643 Status = IfrLibUpdateForm (
644 PrivateData->HiiHandle[0], // HII handle
645 &mFormSetGuid, // Formset GUID
646 3, // Form ID
647 0x2234, // Label for where to insert opcodes
648 TRUE, // Append or replace
649 &UpdateData // Dynamic created opcodes
650 );
651 IfrLibFreeUpdateData (&UpdateData);
652
653 //
654 // Refresh the Question value
655 //
656 PrivateData->Configuration.DynamicRefresh++;
657 Status = gRT->SetVariable(
658 VariableName,
659 &mFormSetGuid,
660 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
661 sizeof (DRIVER_SAMPLE_CONFIGURATION),
662 &PrivateData->Configuration
663 );
664
665 //
666 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause
667 // the first statement in Form 3 be suppressed
668 //
669 MyVar = 111;
670 Status = gRT->SetVariable(
671 L"MyVar",
672 &mFormSetGuid,
673 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
674 1,
675 &MyVar
676 );
677 break;
678
679 case 0x1237:
680 //
681 // User press "Exit now", request Browser to exit
682 //
683 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
684 break;
685
686 case 0x1238:
687 //
688 // User press "Save now", request Browser to save the uncommitted data.
689 //
690 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
691 break;
692
693 case 0x2000:
694 //
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.
698 //
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;
704 }
705 break;
706
707 case BROWSER_STATE_SET_PASSWORD:
708 Status = SetPassword (PrivateData, Value->string);
709 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
710 break;
711
712 default:
713 break;
714 }
715
716 break;
717
718 default:
719 break;
720 }
721
722 return Status;
723 }
724
725 /**
726 Main entry for this driver.
727
728 @param ImageHandle Image handle this driver.
729 @param SystemTable Pointer to SystemTable.
730
731 @retval EFI_SUCESS This function always complete successfully.
732
733 **/
734 EFI_STATUS
735 EFIAPI
736 DriverSampleInit (
737 IN EFI_HANDLE ImageHandle,
738 IN EFI_SYSTEM_TABLE *SystemTable
739 )
740 {
741 EFI_STATUS Status;
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;
750 CHAR16 *NewString;
751 UINTN BufferSize;
752 DRIVER_SAMPLE_CONFIGURATION *Configuration;
753 BOOLEAN ExtractIfrDefault;
754
755 //
756 // Initialize the library and our protocol.
757 //
758
759 //
760 // Initialize screen dimensions for SendForm().
761 // Remove 3 characters from top and bottom
762 //
763 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
764 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
765
766 Screen.TopRow = 3;
767 Screen.BottomRow = Screen.BottomRow - 3;
768
769 //
770 // Initialize driver private data
771 //
772 PrivateData = AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
773 if (PrivateData == NULL) {
774 return EFI_OUT_OF_RESOURCES;
775 }
776
777 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
778
779 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
780 PrivateData->ConfigAccess.RouteConfig = RouteConfig;
781 PrivateData->ConfigAccess.Callback = DriverCallback;
782 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
783
784 //
785 // Locate Hii Database protocol
786 //
787 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
788 if (EFI_ERROR (Status)) {
789 return Status;
790 }
791 PrivateData->HiiDatabase = HiiDatabase;
792
793 //
794 // Locate HiiString protocol
795 //
796 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
797 if (EFI_ERROR (Status)) {
798 return Status;
799 }
800 PrivateData->HiiString = HiiString;
801
802 //
803 // Locate Formbrowser2 protocol
804 //
805 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
806 if (EFI_ERROR (Status)) {
807 return Status;
808 }
809 PrivateData->FormBrowser2 = FormBrowser2;
810
811 //
812 // Locate ConfigRouting protocol
813 //
814 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
815 if (EFI_ERROR (Status)) {
816 return Status;
817 }
818 PrivateData->HiiConfigRouting = HiiConfigRouting;
819
820 Status = gBS->InstallMultipleProtocolInterfaces (
821 &DriverHandle[0],
822 &gEfiDevicePathProtocolGuid,
823 &mHiiVendorDevicePath0,
824 &gEfiHiiConfigAccessProtocolGuid,
825 &PrivateData->ConfigAccess,
826 NULL
827 );
828 ASSERT_EFI_ERROR (Status);
829
830 PrivateData->DriverHandle[0] = DriverHandle[0];
831
832 //
833 // Publish our HII data
834 //
835 PackageList = HiiLibPreparePackageList (
836 2,
837 &mFormSetGuid,
838 DriverSampleStrings,
839 VfrBin
840 );
841 if (PackageList == NULL) {
842 return EFI_OUT_OF_RESOURCES;
843 }
844
845 Status = HiiDatabase->NewPackageList (
846 HiiDatabase,
847 PackageList,
848 DriverHandle[0],
849 &HiiHandle[0]
850 );
851 FreePool (PackageList);
852 if (EFI_ERROR (Status)) {
853 return Status;
854 }
855 PrivateData->HiiHandle[0] = HiiHandle[0];
856
857 //
858 // Publish another Fromset
859 //
860 Status = gBS->InstallMultipleProtocolInterfaces (
861 &DriverHandle[1],
862 &gEfiDevicePathProtocolGuid,
863 &mHiiVendorDevicePath1,
864 NULL
865 );
866 ASSERT_EFI_ERROR (Status);
867
868 PrivateData->DriverHandle[1] = DriverHandle[1];
869
870 PackageList = HiiLibPreparePackageList (
871 2,
872 &mInventoryGuid,
873 DriverSampleStrings,
874 InventoryBin
875 );
876 if (PackageList == NULL) {
877 return EFI_OUT_OF_RESOURCES;
878 }
879
880 Status = HiiDatabase->NewPackageList (
881 HiiDatabase,
882 PackageList,
883 DriverHandle[1],
884 &HiiHandle[1]
885 );
886 FreePool (PackageList);
887 if (EFI_ERROR (Status)) {
888 return Status;
889 }
890 PrivateData->HiiHandle[1] = HiiHandle[1];
891
892 //
893 // Very simple example of how one would update a string that is already
894 // in the HII database
895 //
896 NewString = L"700 Mhz";
897
898 Status = HiiLibSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString);
899 if (EFI_ERROR (Status)) {
900 return Status;
901 }
902
903 //
904 // Initialize configuration data
905 //
906 Configuration = &PrivateData->Configuration;
907 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
908
909 //
910 // Try to read NV config EFI variable first
911 //
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;
917 }
918
919 if (ExtractIfrDefault) {
920 //
921 // EFI variable for NV config doesn't exit, we should build this variable
922 // based on default values stored in IFR
923 //
924 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
925 Status = IfrLibExtractDefault (Configuration, &BufferSize, 1, VfrMyIfrNVDataDefault0000);
926
927 if (!EFI_ERROR (Status)) {
928 gRT->SetVariable(
929 VariableName,
930 &mFormSetGuid,
931 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
932 sizeof (DRIVER_SAMPLE_CONFIGURATION),
933 Configuration
934 );
935 }
936 }
937
938 //
939 // Example of how to display only the item we sent to HII
940 //
941 //
942 // Have the browser pull out our copy of the data, and only display our data
943 //
944 Status = FormBrowser2->SendForm (
945 FormBrowser2,
946 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
947 1,
948 NULL,
949 0,
950 NULL,
951 NULL
952 );
953 SavedStatus = Status;
954
955 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]);
956 if (EFI_ERROR (Status)) {
957 return Status;
958 }
959
960 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]);
961 if (EFI_ERROR (Status)) {
962 return Status;
963 }
964
965 return SavedStatus;
966 }
967
968 /**
969 Unloads the application and its installed protocol.
970
971 @param[in] ImageHandle Handle that identifies the image to be unloaded.
972
973 @retval EFI_SUCCESS The image has been unloaded.
974 **/
975 EFI_STATUS
976 EFIAPI
977 DriverSampleUnload (
978 IN EFI_HANDLE ImageHandle
979 )
980 {
981 if (DriverHandle[0] != NULL) {
982 gBS->UninstallMultipleProtocolInterfaces (
983 DriverHandle[0],
984 &gEfiDevicePathProtocolGuid,
985 &mHiiVendorDevicePath0,
986 &gEfiHiiConfigAccessProtocolGuid,
987 &PrivateData->ConfigAccess,
988 NULL
989 );
990 }
991
992 if (DriverHandle[1] != NULL) {
993 gBS->UninstallMultipleProtocolInterfaces (
994 DriverHandle[1],
995 &gEfiDevicePathProtocolGuid,
996 &mHiiVendorDevicePath1,
997 NULL
998 );
999 }
1000
1001 if (PrivateData != NULL) {
1002 FreePool (PrivateData);
1003 }
1004
1005 return EFI_SUCCESS;
1006 }