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