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