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