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