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 - 2015, Intel Corporation. All rights reserved.<BR> 6 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 CHAR16 VariableName[] = L"MyIfrNVData"; 22 CHAR16 MyEfiVar[] = L"MyEfiVar"; 23 EFI_HANDLE DriverHandle[2] = {NULL, NULL}; 24 DRIVER_SAMPLE_PRIVATE_DATA *mPrivateData = NULL; 25 EFI_EVENT mEvent; 26 27 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = { 28 { 29 { 30 HARDWARE_DEVICE_PATH, 31 HW_VENDOR_DP, 32 { 33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), 34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) 35 } 36 }, 37 DRIVER_SAMPLE_FORMSET_GUID 38 }, 39 { 40 END_DEVICE_PATH_TYPE, 41 END_ENTIRE_DEVICE_PATH_SUBTYPE, 42 { 43 (UINT8) (END_DEVICE_PATH_LENGTH), 44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) 45 } 46 } 47 }; 48 49 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = { 50 { 51 { 52 HARDWARE_DEVICE_PATH, 53 HW_VENDOR_DP, 54 { 55 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), 56 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) 57 } 58 }, 59 DRIVER_SAMPLE_INVENTORY_GUID 60 }, 61 { 62 END_DEVICE_PATH_TYPE, 63 END_ENTIRE_DEVICE_PATH_SUBTYPE, 64 { 65 (UINT8) (END_DEVICE_PATH_LENGTH), 66 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) 67 } 68 } 69 }; 70 71 /** 72 Add empty function for event process function. 73 74 @param Event The Event need to be process 75 @param Context The context of the event. 76 77 **/ 78 VOID 79 EFIAPI 80 DriverSampleInternalEmptyFunction ( 81 IN EFI_EVENT Event, 82 IN VOID *Context 83 ) 84 { 85 } 86 87 /** 88 Notification function for keystrokes. 89 90 @param[in] KeyData The key that was pressed. 91 92 @retval EFI_SUCCESS The operation was successful. 93 **/ 94 EFI_STATUS 95 EFIAPI 96 NotificationFunction( 97 IN EFI_KEY_DATA *KeyData 98 ) 99 { 100 gBS->SignalEvent (mEvent); 101 102 return EFI_SUCCESS; 103 } 104 105 /** 106 Function to start monitoring for CTRL-C using SimpleTextInputEx. 107 108 @retval EFI_SUCCESS The feature is enabled. 109 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available. 110 **/ 111 EFI_STATUS 112 EFIAPI 113 InternalStartMonitor( 114 VOID 115 ) 116 { 117 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; 118 EFI_KEY_DATA KeyData; 119 EFI_STATUS Status; 120 EFI_HANDLE *Handles; 121 UINTN HandleCount; 122 UINTN HandleIndex; 123 EFI_HANDLE NotifyHandle; 124 125 Status = gBS->LocateHandleBuffer ( 126 ByProtocol, 127 &gEfiSimpleTextInputExProtocolGuid, 128 NULL, 129 &HandleCount, 130 &Handles 131 ); 132 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { 133 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx); 134 ASSERT_EFI_ERROR (Status); 135 136 KeyData.KeyState.KeyToggleState = 0; 137 KeyData.Key.ScanCode = 0; 138 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED; 139 KeyData.Key.UnicodeChar = L'c'; 140 141 Status = SimpleEx->RegisterKeyNotify( 142 SimpleEx, 143 &KeyData, 144 NotificationFunction, 145 &NotifyHandle); 146 if (EFI_ERROR (Status)) { 147 break; 148 } 149 150 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED; 151 Status = SimpleEx->RegisterKeyNotify( 152 SimpleEx, 153 &KeyData, 154 NotificationFunction, 155 &NotifyHandle); 156 if (EFI_ERROR (Status)) { 157 break; 158 } 159 } 160 161 return EFI_SUCCESS; 162 } 163 164 /** 165 Function to stop monitoring for CTRL-C using SimpleTextInputEx. 166 167 @retval EFI_SUCCESS The feature is enabled. 168 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available. 169 **/ 170 EFI_STATUS 171 EFIAPI 172 InternalStopMonitor( 173 VOID 174 ) 175 { 176 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx; 177 EFI_STATUS Status; 178 EFI_HANDLE *Handles; 179 EFI_KEY_DATA KeyData; 180 UINTN HandleCount; 181 UINTN HandleIndex; 182 EFI_HANDLE NotifyHandle; 183 184 Status = gBS->LocateHandleBuffer ( 185 ByProtocol, 186 &gEfiSimpleTextInputExProtocolGuid, 187 NULL, 188 &HandleCount, 189 &Handles 190 ); 191 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { 192 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx); 193 ASSERT_EFI_ERROR (Status); 194 195 KeyData.KeyState.KeyToggleState = 0; 196 KeyData.Key.ScanCode = 0; 197 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED; 198 KeyData.Key.UnicodeChar = L'c'; 199 200 Status = SimpleEx->RegisterKeyNotify( 201 SimpleEx, 202 &KeyData, 203 NotificationFunction, 204 &NotifyHandle); 205 if (!EFI_ERROR (Status)) { 206 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle); 207 } 208 209 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED; 210 Status = SimpleEx->RegisterKeyNotify( 211 SimpleEx, 212 &KeyData, 213 NotificationFunction, 214 &NotifyHandle); 215 if (!EFI_ERROR (Status)) { 216 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle); 217 } 218 } 219 return EFI_SUCCESS; 220 } 221 222 223 /** 224 Encode the password using a simple algorithm. 225 226 @param Password The string to be encoded. 227 @param MaxSize The size of the string. 228 229 **/ 230 VOID 231 EncodePassword ( 232 IN CHAR16 *Password, 233 IN UINTN MaxSize 234 ) 235 { 236 UINTN Index; 237 UINTN Loop; 238 CHAR16 *Buffer; 239 CHAR16 *Key; 240 241 Key = L"MAR10648567"; 242 Buffer = AllocateZeroPool (MaxSize); 243 ASSERT (Buffer != NULL); 244 245 for (Index = 0; Key[Index] != 0; Index++) { 246 for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) { 247 Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]); 248 } 249 } 250 251 CopyMem (Password, Buffer, MaxSize); 252 253 FreePool (Buffer); 254 return ; 255 } 256 257 /** 258 Validate the user's password. 259 260 @param PrivateData This driver's private context data. 261 @param StringId The user's input. 262 263 @retval EFI_SUCCESS The user's input matches the password. 264 @retval EFI_NOT_READY The user's input does not match the password. 265 **/ 266 EFI_STATUS 267 ValidatePassword ( 268 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData, 269 IN EFI_STRING_ID StringId 270 ) 271 { 272 EFI_STATUS Status; 273 UINTN Index; 274 UINTN BufferSize; 275 UINTN PasswordMaxSize; 276 CHAR16 *Password; 277 CHAR16 *EncodedPassword; 278 BOOLEAN OldPassword; 279 280 // 281 // Get encoded password first 282 // 283 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 284 Status = gRT->GetVariable ( 285 VariableName, 286 &gDriverSampleFormSetGuid, 287 NULL, 288 &BufferSize, 289 &PrivateData->Configuration 290 ); 291 if (EFI_ERROR (Status)) { 292 // 293 // Old password not exist, prompt for new password 294 // 295 return EFI_SUCCESS; 296 } 297 298 OldPassword = FALSE; 299 PasswordMaxSize = sizeof (PrivateData->Configuration.WhatIsThePassword2); 300 // 301 // Check whether we have any old password set 302 // 303 for (Index = 0; Index < PasswordMaxSize / sizeof (UINT16); Index++) { 304 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) { 305 OldPassword = TRUE; 306 break; 307 } 308 } 309 if (!OldPassword) { 310 // 311 // Old password not exist, return EFI_SUCCESS to prompt for new password 312 // 313 return EFI_SUCCESS; 314 } 315 316 // 317 // Get user input password 318 // 319 Password = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL); 320 if (Password == NULL) { 321 return EFI_NOT_READY; 322 } 323 if (StrSize (Password) > PasswordMaxSize) { 324 FreePool (Password); 325 return EFI_NOT_READY; 326 } 327 328 // 329 // Validate old password 330 // 331 EncodedPassword = AllocateZeroPool (PasswordMaxSize); 332 ASSERT (EncodedPassword != NULL); 333 StrnCpyS (EncodedPassword, PasswordMaxSize / sizeof (CHAR16), Password, StrLen (Password)); 334 EncodePassword (EncodedPassword, StrLen (EncodedPassword) * sizeof (CHAR16)); 335 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, PasswordMaxSize) != 0) { 336 // 337 // Old password mismatch, return EFI_NOT_READY to prompt for error message 338 // 339 Status = EFI_NOT_READY; 340 } else { 341 Status = EFI_SUCCESS; 342 } 343 344 FreePool (Password); 345 FreePool (EncodedPassword); 346 347 return Status; 348 } 349 350 /** 351 Encode the password using a simple algorithm. 352 353 @param PrivateData This driver's private context data. 354 @param StringId The password from User. 355 356 @retval EFI_SUCESS The operation is successful. 357 @return Other value if gRT->SetVariable () fails. 358 359 **/ 360 EFI_STATUS 361 SetPassword ( 362 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData, 363 IN EFI_STRING_ID StringId 364 ) 365 { 366 EFI_STATUS Status; 367 CHAR16 *Password; 368 CHAR16 *TempPassword; 369 UINTN PasswordSize; 370 DRIVER_SAMPLE_CONFIGURATION *Configuration; 371 UINTN BufferSize; 372 373 // 374 // Get Buffer Storage data from EFI variable 375 // 376 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 377 Status = gRT->GetVariable ( 378 VariableName, 379 &gDriverSampleFormSetGuid, 380 NULL, 381 &BufferSize, 382 &PrivateData->Configuration 383 ); 384 if (EFI_ERROR (Status)) { 385 return Status; 386 } 387 388 // 389 // Get user input password 390 // 391 Password = PrivateData->Configuration.WhatIsThePassword2; 392 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2); 393 ZeroMem (Password, PasswordSize); 394 395 TempPassword = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL); 396 if (TempPassword == NULL) { 397 return EFI_NOT_READY; 398 } 399 if (StrSize (TempPassword) > PasswordSize) { 400 FreePool (TempPassword); 401 return EFI_NOT_READY; 402 } 403 StrnCpyS (Password, PasswordSize / sizeof (CHAR16), TempPassword, StrLen (TempPassword)); 404 FreePool (TempPassword); 405 406 // 407 // Retrive uncommitted data from Browser 408 // 409 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION)); 410 ASSERT (Configuration != NULL); 411 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) { 412 // 413 // Update password's clear text in the screen 414 // 415 CopyMem (Configuration->PasswordClearText, Password, StrSize (Password)); 416 417 // 418 // Update uncommitted data of Browser 419 // 420 HiiSetBrowserData ( 421 &gDriverSampleFormSetGuid, 422 VariableName, 423 sizeof (DRIVER_SAMPLE_CONFIGURATION), 424 (UINT8 *) Configuration, 425 NULL 426 ); 427 } 428 429 // 430 // Free Configuration Buffer 431 // 432 FreePool (Configuration); 433 434 435 // 436 // Set password 437 // 438 EncodePassword (Password, StrLen (Password) * 2); 439 Status = gRT->SetVariable( 440 VariableName, 441 &gDriverSampleFormSetGuid, 442 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 443 sizeof (DRIVER_SAMPLE_CONFIGURATION), 444 &PrivateData->Configuration 445 ); 446 return Status; 447 } 448 449 /** 450 Update names of Name/Value storage to current language. 451 452 @param PrivateData Points to the driver private data. 453 454 @retval EFI_SUCCESS All names are successfully updated. 455 @retval EFI_NOT_FOUND Failed to get Name from HII database. 456 457 **/ 458 EFI_STATUS 459 LoadNameValueNames ( 460 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData 461 ) 462 { 463 UINTN Index; 464 465 // 466 // Get Name/Value name string of current language 467 // 468 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) { 469 PrivateData->NameValueName[Index] = HiiGetString ( 470 PrivateData->HiiHandle[0], 471 PrivateData->NameStringId[Index], 472 NULL 473 ); 474 if (PrivateData->NameValueName[Index] == NULL) { 475 return EFI_NOT_FOUND; 476 } 477 } 478 479 return EFI_SUCCESS; 480 } 481 482 483 /** 484 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET 485 or WIDTH or VALUE. 486 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number> 487 488 This is a internal function. 489 490 @param StringPtr String in <BlockConfig> format and points to the 491 first character of <Number>. 492 @param Number The output value. Caller takes the responsibility 493 to free memory. 494 @param Len Length of the <Number>, in characters. 495 496 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary 497 structures. 498 @retval EFI_SUCCESS Value of <Number> is outputted in Number 499 successfully. 500 501 **/ 502 EFI_STATUS 503 GetValueOfNumber ( 504 IN EFI_STRING StringPtr, 505 OUT UINT8 **Number, 506 OUT UINTN *Len 507 ) 508 { 509 EFI_STRING TmpPtr; 510 UINTN Length; 511 EFI_STRING Str; 512 UINT8 *Buf; 513 EFI_STATUS Status; 514 UINT8 DigitUint8; 515 UINTN Index; 516 CHAR16 TemStr[2]; 517 518 if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) { 519 return EFI_INVALID_PARAMETER; 520 } 521 522 Buf = NULL; 523 524 TmpPtr = StringPtr; 525 while (*StringPtr != L'\0' && *StringPtr != L'&') { 526 StringPtr++; 527 } 528 *Len = StringPtr - TmpPtr; 529 Length = *Len + 1; 530 531 Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16)); 532 if (Str == NULL) { 533 Status = EFI_OUT_OF_RESOURCES; 534 goto Exit; 535 } 536 CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16)); 537 *(Str + *Len) = L'\0'; 538 539 Length = (Length + 1) / 2; 540 Buf = (UINT8 *) AllocateZeroPool (Length); 541 if (Buf == NULL) { 542 Status = EFI_OUT_OF_RESOURCES; 543 goto Exit; 544 } 545 546 Length = *Len; 547 ZeroMem (TemStr, sizeof (TemStr)); 548 for (Index = 0; Index < Length; Index ++) { 549 TemStr[0] = Str[Length - Index - 1]; 550 DigitUint8 = (UINT8) StrHexToUint64 (TemStr); 551 if ((Index & 1) == 0) { 552 Buf [Index/2] = DigitUint8; 553 } else { 554 Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]); 555 } 556 } 557 558 *Number = Buf; 559 Status = EFI_SUCCESS; 560 561 Exit: 562 if (Str != NULL) { 563 FreePool (Str); 564 } 565 566 return Status; 567 } 568 569 /** 570 Create altcfg string. 571 572 @param Result The request result string. 573 @param ConfigHdr The request head info. <ConfigHdr> format. 574 @param Offset The offset of the parameter int he structure. 575 @param Width The width of the parameter. 576 577 578 @retval The string with altcfg info append at the end. 579 **/ 580 EFI_STRING 581 CreateAltCfgString ( 582 IN EFI_STRING Result, 583 IN EFI_STRING ConfigHdr, 584 IN UINTN Offset, 585 IN UINTN Width 586 ) 587 { 588 EFI_STRING StringPtr; 589 EFI_STRING TmpStr; 590 UINTN NewLen; 591 592 NewLen = StrLen (Result); 593 // 594 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0") 595 // 596 NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16); 597 StringPtr = AllocateZeroPool (NewLen); 598 if (StringPtr == NULL) { 599 return NULL; 600 } 601 602 TmpStr = StringPtr; 603 if (Result != NULL) { 604 StrCpyS (StringPtr, NewLen / sizeof (CHAR16), Result); 605 StringPtr += StrLen (Result); 606 FreePool (Result); 607 } 608 609 UnicodeSPrint ( 610 StringPtr, 611 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), 612 L"&%s&ALTCFG=%04x", 613 ConfigHdr, 614 EFI_HII_DEFAULT_CLASS_STANDARD 615 ); 616 StringPtr += StrLen (StringPtr); 617 618 UnicodeSPrint ( 619 StringPtr, 620 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16), 621 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", 622 Offset, 623 Width, 624 DEFAULT_CLASS_STANDARD_VALUE 625 ); 626 StringPtr += StrLen (StringPtr); 627 628 UnicodeSPrint ( 629 StringPtr, 630 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), 631 L"&%s&ALTCFG=%04x", 632 ConfigHdr, 633 EFI_HII_DEFAULT_CLASS_MANUFACTURING 634 ); 635 StringPtr += StrLen (StringPtr); 636 637 UnicodeSPrint ( 638 StringPtr, 639 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16), 640 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x", 641 Offset, 642 Width, 643 DEFAULT_CLASS_MANUFACTURING_VALUE 644 ); 645 StringPtr += StrLen (StringPtr); 646 647 return TmpStr; 648 } 649 650 /** 651 Check whether need to add the altcfg string. if need to add, add the altcfg 652 string. 653 654 @param RequestResult The request result string. 655 @param ConfigRequestHdr The request head info. <ConfigHdr> format. 656 657 **/ 658 VOID 659 AppendAltCfgString ( 660 IN OUT EFI_STRING *RequestResult, 661 IN EFI_STRING ConfigRequestHdr 662 ) 663 { 664 EFI_STRING StringPtr; 665 UINTN Length; 666 UINT8 *TmpBuffer; 667 UINTN Offset; 668 UINTN Width; 669 UINTN BlockSize; 670 UINTN ValueOffset; 671 UINTN ValueWidth; 672 EFI_STATUS Status; 673 674 TmpBuffer = NULL; 675 StringPtr = *RequestResult; 676 StringPtr = StrStr (StringPtr, L"OFFSET"); 677 BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 678 ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess); 679 ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess); 680 681 if (StringPtr == NULL) { 682 return; 683 } 684 685 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) { 686 StringPtr += StrLen (L"OFFSET="); 687 // 688 // Get Offset 689 // 690 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); 691 if (EFI_ERROR (Status)) { 692 return; 693 } 694 Offset = 0; 695 CopyMem ( 696 &Offset, 697 TmpBuffer, 698 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN) 699 ); 700 FreePool (TmpBuffer); 701 702 StringPtr += Length; 703 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) { 704 return; 705 } 706 StringPtr += StrLen (L"&WIDTH="); 707 708 // 709 // Get Width 710 // 711 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); 712 if (EFI_ERROR (Status)) { 713 return; 714 } 715 Width = 0; 716 CopyMem ( 717 &Width, 718 TmpBuffer, 719 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN) 720 ); 721 FreePool (TmpBuffer); 722 723 StringPtr += Length; 724 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) { 725 return; 726 } 727 StringPtr += StrLen (L"&VALUE="); 728 729 // 730 // Get Value 731 // 732 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); 733 if (EFI_ERROR (Status)) { 734 return; 735 } 736 StringPtr += Length; 737 738 // 739 // Calculate Value and convert it to hex string. 740 // 741 if (Offset + Width > BlockSize) { 742 return; 743 } 744 745 if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) { 746 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth); 747 return; 748 } 749 } 750 } 751 752 /** 753 This function allows a caller to extract the current configuration for one 754 or more named elements from the target driver. 755 756 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 757 @param Request A null-terminated Unicode string in 758 <ConfigRequest> format. 759 @param Progress On return, points to a character in the Request 760 string. Points to the string's null terminator if 761 request was successful. Points to the most recent 762 '&' before the first failing name/value pair (or 763 the beginning of the string if the failure is in 764 the first name/value pair) if the request was not 765 successful. 766 @param Results A null-terminated Unicode string in 767 <ConfigAltResp> format which has all values filled 768 in for the names in the Request string. String to 769 be allocated by the called function. 770 771 @retval EFI_SUCCESS The Results is filled with the requested values. 772 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. 773 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. 774 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this 775 driver. 776 777 **/ 778 EFI_STATUS 779 EFIAPI 780 ExtractConfig ( 781 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 782 IN CONST EFI_STRING Request, 783 OUT EFI_STRING *Progress, 784 OUT EFI_STRING *Results 785 ) 786 { 787 EFI_STATUS Status; 788 UINTN BufferSize; 789 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; 790 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; 791 EFI_STRING ConfigRequest; 792 EFI_STRING ConfigRequestHdr; 793 UINTN Size; 794 EFI_STRING Value; 795 UINTN ValueStrLen; 796 CHAR16 BackupChar; 797 CHAR16 *StrPointer; 798 BOOLEAN AllocatedRequest; 799 800 if (Progress == NULL || Results == NULL) { 801 return EFI_INVALID_PARAMETER; 802 } 803 // 804 // Initialize the local variables. 805 // 806 ConfigRequestHdr = NULL; 807 ConfigRequest = NULL; 808 Size = 0; 809 *Progress = Request; 810 AllocatedRequest = FALSE; 811 812 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); 813 HiiConfigRouting = PrivateData->HiiConfigRouting; 814 815 // 816 // Get Buffer Storage data from EFI variable. 817 // Try to get the current setting from variable. 818 // 819 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 820 Status = gRT->GetVariable ( 821 VariableName, 822 &gDriverSampleFormSetGuid, 823 NULL, 824 &BufferSize, 825 &PrivateData->Configuration 826 ); 827 if (EFI_ERROR (Status)) { 828 return EFI_NOT_FOUND; 829 } 830 831 if (Request == NULL) { 832 // 833 // Request is set to NULL, construct full request string. 834 // 835 836 // 837 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template 838 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator 839 // 840 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]); 841 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); 842 ConfigRequest = AllocateZeroPool (Size); 843 ASSERT (ConfigRequest != NULL); 844 AllocatedRequest = TRUE; 845 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); 846 FreePool (ConfigRequestHdr); 847 ConfigRequestHdr = NULL; 848 } else { 849 // 850 // Check routing data in <ConfigHdr>. 851 // Note: if only one Storage is used, then this checking could be skipped. 852 // 853 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) { 854 return EFI_NOT_FOUND; 855 } 856 // 857 // Check whether request for EFI Varstore. EFI varstore get data 858 // through hii database, not support in this path. 859 // 860 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) { 861 return EFI_UNSUPPORTED; 862 } 863 // 864 // Set Request to the unified request string. 865 // 866 ConfigRequest = Request; 867 // 868 // Check whether Request includes Request Element. 869 // 870 if (StrStr (Request, L"OFFSET") == NULL) { 871 // 872 // Check Request Element does exist in Reques String 873 // 874 StrPointer = StrStr (Request, L"PATH"); 875 if (StrPointer == NULL) { 876 return EFI_INVALID_PARAMETER; 877 } 878 if (StrStr (StrPointer, L"&") == NULL) { 879 Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16); 880 ConfigRequest = AllocateZeroPool (Size); 881 ASSERT (ConfigRequest != NULL); 882 AllocatedRequest = TRUE; 883 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize); 884 } 885 } 886 } 887 888 // 889 // Check if requesting Name/Value storage 890 // 891 if (StrStr (ConfigRequest, L"OFFSET") == NULL) { 892 // 893 // Update Name/Value storage Names 894 // 895 Status = LoadNameValueNames (PrivateData); 896 if (EFI_ERROR (Status)) { 897 return Status; 898 } 899 900 // 901 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD" 902 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2 903 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044 904 // 905 BufferSize = (StrLen (ConfigRequest) + 906 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 + 907 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 + 908 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16); 909 *Results = AllocateZeroPool (BufferSize); 910 ASSERT (*Results != NULL); 911 StrCpyS (*Results, BufferSize / sizeof (CHAR16), ConfigRequest); 912 Value = *Results; 913 914 // 915 // Append value of NameValueVar0, type is UINT8 916 // 917 if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) { 918 Value += StrLen (PrivateData->NameValueName[0]); 919 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1); 920 CopyMem (Value + ValueStrLen, Value, StrSize (Value)); 921 922 BackupChar = Value[ValueStrLen]; 923 *Value++ = L'='; 924 Value += UnicodeValueToString ( 925 Value, 926 PREFIX_ZERO | RADIX_HEX, 927 PrivateData->Configuration.NameValueVar0, 928 sizeof (PrivateData->Configuration.NameValueVar0) * 2 929 ); 930 *Value = BackupChar; 931 } 932 933 // 934 // Append value of NameValueVar1, type is UINT16 935 // 936 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) { 937 Value += StrLen (PrivateData->NameValueName[1]); 938 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1); 939 CopyMem (Value + ValueStrLen, Value, StrSize (Value)); 940 941 BackupChar = Value[ValueStrLen]; 942 *Value++ = L'='; 943 Value += UnicodeValueToString ( 944 Value, 945 PREFIX_ZERO | RADIX_HEX, 946 PrivateData->Configuration.NameValueVar1, 947 sizeof (PrivateData->Configuration.NameValueVar1) * 2 948 ); 949 *Value = BackupChar; 950 } 951 952 // 953 // Append value of NameValueVar2, type is CHAR16 * 954 // 955 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) { 956 Value += StrLen (PrivateData->NameValueName[2]); 957 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1; 958 CopyMem (Value + ValueStrLen, Value, StrSize (Value)); 959 960 *Value++ = L'='; 961 // 962 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044" 963 // 964 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2; 965 for (; *StrPointer != L'\0'; StrPointer++) { 966 Value += UnicodeValueToString (Value, PREFIX_ZERO | RADIX_HEX, *StrPointer, 4); 967 } 968 } 969 970 Status = EFI_SUCCESS; 971 } else { 972 // 973 // Convert buffer data to <ConfigResp> by helper function BlockToConfig() 974 // 975 Status = HiiConfigRouting->BlockToConfig ( 976 HiiConfigRouting, 977 ConfigRequest, 978 (UINT8 *) &PrivateData->Configuration, 979 BufferSize, 980 Results, 981 Progress 982 ); 983 if (!EFI_ERROR (Status)) { 984 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]); 985 AppendAltCfgString(Results, ConfigRequestHdr); 986 } 987 } 988 989 // 990 // Free the allocated config request string. 991 // 992 if (AllocatedRequest) { 993 FreePool (ConfigRequest); 994 } 995 996 if (ConfigRequestHdr != NULL) { 997 FreePool (ConfigRequestHdr); 998 } 999 // 1000 // Set Progress string to the original request string. 1001 // 1002 if (Request == NULL) { 1003 *Progress = NULL; 1004 } else if (StrStr (Request, L"OFFSET") == NULL) { 1005 *Progress = Request + StrLen (Request); 1006 } 1007 1008 return Status; 1009 } 1010 1011 1012 /** 1013 This function processes the results of changes in configuration. 1014 1015 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 1016 @param Configuration A null-terminated Unicode string in <ConfigResp> 1017 format. 1018 @param Progress A pointer to a string filled in with the offset of 1019 the most recent '&' before the first failing 1020 name/value pair (or the beginning of the string if 1021 the failure is in the first name/value pair) or 1022 the terminating NULL if all was successful. 1023 1024 @retval EFI_SUCCESS The Results is processed successfully. 1025 @retval EFI_INVALID_PARAMETER Configuration is NULL. 1026 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this 1027 driver. 1028 1029 **/ 1030 EFI_STATUS 1031 EFIAPI 1032 RouteConfig ( 1033 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 1034 IN CONST EFI_STRING Configuration, 1035 OUT EFI_STRING *Progress 1036 ) 1037 { 1038 EFI_STATUS Status; 1039 UINTN BufferSize; 1040 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; 1041 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; 1042 CHAR16 *Value; 1043 CHAR16 *StrPtr; 1044 CHAR16 TemStr[5]; 1045 UINT8 *DataBuffer; 1046 UINT8 DigitUint8; 1047 UINTN Index; 1048 CHAR16 *StrBuffer; 1049 1050 if (Configuration == NULL || Progress == NULL) { 1051 return EFI_INVALID_PARAMETER; 1052 } 1053 1054 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); 1055 HiiConfigRouting = PrivateData->HiiConfigRouting; 1056 *Progress = Configuration; 1057 1058 // 1059 // Check routing data in <ConfigHdr>. 1060 // Note: if only one Storage is used, then this checking could be skipped. 1061 // 1062 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) { 1063 return EFI_NOT_FOUND; 1064 } 1065 1066 // 1067 // Check whether request for EFI Varstore. EFI varstore get data 1068 // through hii database, not support in this path. 1069 // 1070 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) { 1071 return EFI_UNSUPPORTED; 1072 } 1073 1074 // 1075 // Get Buffer Storage data from EFI variable 1076 // 1077 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 1078 Status = gRT->GetVariable ( 1079 VariableName, 1080 &gDriverSampleFormSetGuid, 1081 NULL, 1082 &BufferSize, 1083 &PrivateData->Configuration 1084 ); 1085 if (EFI_ERROR (Status)) { 1086 return Status; 1087 } 1088 1089 // 1090 // Check if configuring Name/Value storage 1091 // 1092 if (StrStr (Configuration, L"OFFSET") == NULL) { 1093 // 1094 // Update Name/Value storage Names 1095 // 1096 Status = LoadNameValueNames (PrivateData); 1097 if (EFI_ERROR (Status)) { 1098 return Status; 1099 } 1100 1101 // 1102 // Convert value for NameValueVar0 1103 // 1104 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) { 1105 // 1106 // Skip "Name=" 1107 // 1108 Value += StrLen (PrivateData->NameValueName[0]); 1109 Value++; 1110 // 1111 // Get Value String 1112 // 1113 StrPtr = StrStr (Value, L"&"); 1114 if (StrPtr == NULL) { 1115 StrPtr = Value + StrLen (Value); 1116 } 1117 // 1118 // Convert Value to Buffer data 1119 // 1120 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0; 1121 ZeroMem (TemStr, sizeof (TemStr)); 1122 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) { 1123 TemStr[0] = *StrPtr; 1124 DigitUint8 = (UINT8) StrHexToUint64 (TemStr); 1125 if ((Index & 1) == 0) { 1126 DataBuffer [Index/2] = DigitUint8; 1127 } else { 1128 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]); 1129 } 1130 } 1131 } 1132 1133 // 1134 // Convert value for NameValueVar1 1135 // 1136 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) { 1137 // 1138 // Skip "Name=" 1139 // 1140 Value += StrLen (PrivateData->NameValueName[1]); 1141 Value++; 1142 // 1143 // Get Value String 1144 // 1145 StrPtr = StrStr (Value, L"&"); 1146 if (StrPtr == NULL) { 1147 StrPtr = Value + StrLen (Value); 1148 } 1149 // 1150 // Convert Value to Buffer data 1151 // 1152 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1; 1153 ZeroMem (TemStr, sizeof (TemStr)); 1154 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) { 1155 TemStr[0] = *StrPtr; 1156 DigitUint8 = (UINT8) StrHexToUint64 (TemStr); 1157 if ((Index & 1) == 0) { 1158 DataBuffer [Index/2] = DigitUint8; 1159 } else { 1160 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]); 1161 } 1162 } 1163 } 1164 1165 // 1166 // Convert value for NameValueVar2 1167 // 1168 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) { 1169 // 1170 // Skip "Name=" 1171 // 1172 Value += StrLen (PrivateData->NameValueName[2]); 1173 Value++; 1174 // 1175 // Get Value String 1176 // 1177 StrPtr = StrStr (Value, L"&"); 1178 if (StrPtr == NULL) { 1179 StrPtr = Value + StrLen (Value); 1180 } 1181 // 1182 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD" 1183 // 1184 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2; 1185 ZeroMem (TemStr, sizeof (TemStr)); 1186 while (Value < StrPtr) { 1187 StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value, 4); 1188 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr); 1189 Value += 4; 1190 } 1191 *StrBuffer = L'\0'; 1192 } 1193 1194 // 1195 // Store Buffer Storage back to EFI variable 1196 // 1197 Status = gRT->SetVariable( 1198 VariableName, 1199 &gDriverSampleFormSetGuid, 1200 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1201 sizeof (DRIVER_SAMPLE_CONFIGURATION), 1202 &PrivateData->Configuration 1203 ); 1204 1205 return Status; 1206 } 1207 1208 // 1209 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock() 1210 // 1211 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 1212 Status = HiiConfigRouting->ConfigToBlock ( 1213 HiiConfigRouting, 1214 Configuration, 1215 (UINT8 *) &PrivateData->Configuration, 1216 &BufferSize, 1217 Progress 1218 ); 1219 if (EFI_ERROR (Status)) { 1220 return Status; 1221 } 1222 1223 // 1224 // Store Buffer Storage back to EFI variable 1225 // 1226 Status = gRT->SetVariable( 1227 VariableName, 1228 &gDriverSampleFormSetGuid, 1229 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1230 sizeof (DRIVER_SAMPLE_CONFIGURATION), 1231 &PrivateData->Configuration 1232 ); 1233 1234 return Status; 1235 } 1236 1237 1238 /** 1239 This function processes the results of changes in configuration. 1240 1241 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 1242 @param Action Specifies the type of action taken by the browser. 1243 @param QuestionId A unique value which is sent to the original 1244 exporting driver so that it can identify the type 1245 of data to expect. 1246 @param Type The type of value for the question. 1247 @param Value A pointer to the data being sent to the original 1248 exporting driver. 1249 @param ActionRequest On return, points to the action requested by the 1250 callback function. 1251 1252 @retval EFI_SUCCESS The callback successfully handled the action. 1253 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the 1254 variable and its data. 1255 @retval EFI_DEVICE_ERROR The variable could not be saved. 1256 @retval EFI_UNSUPPORTED The specified Action is not supported by the 1257 callback. 1258 1259 **/ 1260 EFI_STATUS 1261 EFIAPI 1262 DriverCallback ( 1263 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 1264 IN EFI_BROWSER_ACTION Action, 1265 IN EFI_QUESTION_ID QuestionId, 1266 IN UINT8 Type, 1267 IN EFI_IFR_TYPE_VALUE *Value, 1268 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest 1269 ) 1270 { 1271 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData; 1272 EFI_STATUS Status; 1273 VOID *StartOpCodeHandle; 1274 VOID *OptionsOpCodeHandle; 1275 EFI_IFR_GUID_LABEL *StartLabel; 1276 VOID *EndOpCodeHandle; 1277 EFI_IFR_GUID_LABEL *EndLabel; 1278 EFI_INPUT_KEY Key; 1279 DRIVER_SAMPLE_CONFIGURATION *Configuration; 1280 MY_EFI_VARSTORE_DATA *EfiData; 1281 EFI_FORM_ID FormId; 1282 EFI_STRING Progress; 1283 EFI_STRING Results; 1284 UINT32 ProgressErr; 1285 CHAR16 *TmpStr; 1286 1287 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))|| 1288 (ActionRequest == NULL)) { 1289 return EFI_INVALID_PARAMETER; 1290 } 1291 1292 1293 FormId = 0; 1294 ProgressErr = 0; 1295 Status = EFI_SUCCESS; 1296 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); 1297 1298 switch (Action) { 1299 case EFI_BROWSER_ACTION_FORM_OPEN: 1300 { 1301 if (QuestionId == 0x1234) { 1302 // 1303 // Sample CallBack for UEFI FORM_OPEN action: 1304 // Add Save action into Form 3 when Form 1 is opened. 1305 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1. 1306 // 1307 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); 1308 1309 // 1310 // Initialize the container for dynamic opcodes 1311 // 1312 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 1313 ASSERT (StartOpCodeHandle != NULL); 1314 1315 // 1316 // Create Hii Extend Label OpCode as the start opcode 1317 // 1318 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 1319 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 1320 StartLabel->Number = LABEL_UPDATE2; 1321 1322 HiiCreateActionOpCode ( 1323 StartOpCodeHandle, // Container for dynamic created opcodes 1324 0x1238, // Question ID 1325 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text 1326 STRING_TOKEN(STR_SAVE_TEXT), // Help text 1327 EFI_IFR_FLAG_CALLBACK, // Question flag 1328 0 // Action String ID 1329 ); 1330 1331 HiiUpdateForm ( 1332 PrivateData->HiiHandle[0], // HII handle 1333 &gDriverSampleFormSetGuid, // Formset GUID 1334 0x3, // Form ID 1335 StartOpCodeHandle, // Label for where to insert opcodes 1336 NULL // Insert data 1337 ); 1338 1339 HiiFreeOpCodeHandle (StartOpCodeHandle); 1340 } 1341 1342 if (QuestionId == 0x1247) { 1343 Status = InternalStartMonitor (); 1344 ASSERT_EFI_ERROR (Status); 1345 } 1346 } 1347 break; 1348 1349 case EFI_BROWSER_ACTION_FORM_CLOSE: 1350 { 1351 if (QuestionId == 0x5678) { 1352 // 1353 // Sample CallBack for UEFI FORM_CLOSE action: 1354 // Show up a pop-up to specify Form 3 will be closed when exit Form 3. 1355 // 1356 do { 1357 CreatePopUp ( 1358 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 1359 &Key, 1360 L"", 1361 L"You are going to leave third Form!", 1362 L"Press ESC or ENTER to continue ...", 1363 L"", 1364 NULL 1365 ); 1366 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); 1367 } 1368 1369 if (QuestionId == 0x1247) { 1370 Status = InternalStopMonitor (); 1371 ASSERT_EFI_ERROR (Status); 1372 } 1373 } 1374 break; 1375 1376 case EFI_BROWSER_ACTION_RETRIEVE: 1377 { 1378 switch (QuestionId ) { 1379 case 0x1248: 1380 if (Type != EFI_IFR_TYPE_REF) { 1381 return EFI_INVALID_PARAMETER; 1382 } 1383 Value->ref.FormId = 0x3; 1384 break; 1385 1386 case 0x5678: 1387 case 0x1247: 1388 // 1389 // We will reach here once the Question is refreshed 1390 // 1391 1392 // 1393 // Initialize the container for dynamic opcodes 1394 // 1395 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 1396 ASSERT (StartOpCodeHandle != NULL); 1397 1398 // 1399 // Create Hii Extend Label OpCode as the start opcode 1400 // 1401 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 1402 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 1403 if (QuestionId == 0x5678) { 1404 StartLabel->Number = LABEL_UPDATE2; 1405 FormId = 0x03; 1406 PrivateData->Configuration.DynamicRefresh++; 1407 } else if (QuestionId == 0x1247 ) { 1408 StartLabel->Number = LABEL_UPDATE3; 1409 FormId = 0x06; 1410 PrivateData->Configuration.RefreshGuidCount++; 1411 } 1412 1413 HiiCreateActionOpCode ( 1414 StartOpCodeHandle, // Container for dynamic created opcodes 1415 0x1237, // Question ID 1416 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text 1417 STRING_TOKEN(STR_EXIT_TEXT), // Help text 1418 EFI_IFR_FLAG_CALLBACK, // Question flag 1419 0 // Action String ID 1420 ); 1421 1422 HiiUpdateForm ( 1423 PrivateData->HiiHandle[0], // HII handle 1424 &gDriverSampleFormSetGuid, // Formset GUID 1425 FormId, // Form ID 1426 StartOpCodeHandle, // Label for where to insert opcodes 1427 NULL // Insert data 1428 ); 1429 1430 HiiFreeOpCodeHandle (StartOpCodeHandle); 1431 1432 // 1433 // Refresh the Question value 1434 // 1435 Status = gRT->SetVariable( 1436 VariableName, 1437 &gDriverSampleFormSetGuid, 1438 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1439 sizeof (DRIVER_SAMPLE_CONFIGURATION), 1440 &PrivateData->Configuration 1441 ); 1442 1443 if (QuestionId == 0x5678) { 1444 // 1445 // Update uncommitted data of Browser 1446 // 1447 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA)); 1448 ASSERT (EfiData != NULL); 1449 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) { 1450 EfiData->Field8 = 111; 1451 HiiSetBrowserData ( 1452 &gDriverSampleFormSetGuid, 1453 MyEfiVar, 1454 sizeof (MY_EFI_VARSTORE_DATA), 1455 (UINT8 *) EfiData, 1456 NULL 1457 ); 1458 } 1459 FreePool (EfiData); 1460 } 1461 break; 1462 } 1463 } 1464 break; 1465 1466 case EFI_BROWSER_ACTION_DEFAULT_STANDARD: 1467 { 1468 switch (QuestionId) { 1469 case 0x1240: 1470 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE; 1471 break; 1472 1473 default: 1474 Status = EFI_UNSUPPORTED; 1475 break; 1476 } 1477 } 1478 break; 1479 1480 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING: 1481 { 1482 switch (QuestionId) { 1483 case 0x1240: 1484 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE; 1485 break; 1486 1487 default: 1488 Status = EFI_UNSUPPORTED; 1489 break; 1490 } 1491 } 1492 break; 1493 1494 case EFI_BROWSER_ACTION_CHANGING: 1495 { 1496 switch (QuestionId) { 1497 case 0x1249: 1498 { 1499 if (Type != EFI_IFR_TYPE_REF) { 1500 return EFI_INVALID_PARAMETER; 1501 } 1502 1503 Value->ref.FormId = 0x1234; 1504 } 1505 break; 1506 case 0x1234: 1507 // 1508 // Initialize the container for dynamic opcodes 1509 // 1510 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 1511 ASSERT (StartOpCodeHandle != NULL); 1512 1513 EndOpCodeHandle = HiiAllocateOpCodeHandle (); 1514 ASSERT (EndOpCodeHandle != NULL); 1515 1516 // 1517 // Create Hii Extend Label OpCode as the start opcode 1518 // 1519 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 1520 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 1521 StartLabel->Number = LABEL_UPDATE1; 1522 1523 // 1524 // Create Hii Extend Label OpCode as the end opcode 1525 // 1526 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 1527 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 1528 EndLabel->Number = LABEL_END; 1529 1530 HiiCreateActionOpCode ( 1531 StartOpCodeHandle, // Container for dynamic created opcodes 1532 0x1237, // Question ID 1533 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text 1534 STRING_TOKEN(STR_EXIT_TEXT), // Help text 1535 EFI_IFR_FLAG_CALLBACK, // Question flag 1536 0 // Action String ID 1537 ); 1538 1539 // 1540 // Create Option OpCode 1541 // 1542 OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); 1543 ASSERT (OptionsOpCodeHandle != NULL); 1544 1545 HiiCreateOneOfOptionOpCode ( 1546 OptionsOpCodeHandle, 1547 STRING_TOKEN (STR_BOOT_OPTION1), 1548 0, 1549 EFI_IFR_NUMERIC_SIZE_1, 1550 1 1551 ); 1552 1553 HiiCreateOneOfOptionOpCode ( 1554 OptionsOpCodeHandle, 1555 STRING_TOKEN (STR_BOOT_OPTION2), 1556 0, 1557 EFI_IFR_NUMERIC_SIZE_1, 1558 2 1559 ); 1560 1561 // 1562 // Prepare initial value for the dynamic created oneof Question 1563 // 1564 PrivateData->Configuration.DynamicOneof = 2; 1565 Status = gRT->SetVariable( 1566 VariableName, 1567 &gDriverSampleFormSetGuid, 1568 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1569 sizeof (DRIVER_SAMPLE_CONFIGURATION), 1570 &PrivateData->Configuration 1571 ); 1572 1573 // 1574 // Set initial vlaue of dynamic created oneof Question in Form Browser 1575 // 1576 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION)); 1577 ASSERT (Configuration != NULL); 1578 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) { 1579 Configuration->DynamicOneof = 2; 1580 1581 // 1582 // Update uncommitted data of Browser 1583 // 1584 HiiSetBrowserData ( 1585 &gDriverSampleFormSetGuid, 1586 VariableName, 1587 sizeof (DRIVER_SAMPLE_CONFIGURATION), 1588 (UINT8 *) Configuration, 1589 NULL 1590 ); 1591 } 1592 FreePool (Configuration); 1593 1594 HiiCreateOneOfOpCode ( 1595 StartOpCodeHandle, // Container for dynamic created opcodes 1596 0x8001, // Question ID (or call it "key") 1597 CONFIGURATION_VARSTORE_ID, // VarStore ID 1598 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage 1599 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text 1600 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text 1601 EFI_IFR_FLAG_CALLBACK, // Question flag 1602 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value 1603 OptionsOpCodeHandle, // Option Opcode list 1604 NULL // Default Opcode is NULl 1605 ); 1606 1607 HiiCreateOrderedListOpCode ( 1608 StartOpCodeHandle, // Container for dynamic created opcodes 1609 0x8002, // Question ID 1610 CONFIGURATION_VARSTORE_ID, // VarStore ID 1611 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage 1612 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text 1613 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text 1614 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag 1615 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET 1616 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value 1617 5, // Maximum container 1618 OptionsOpCodeHandle, // Option Opcode list 1619 NULL // Default Opcode is NULl 1620 ); 1621 1622 HiiCreateTextOpCode ( 1623 StartOpCodeHandle, 1624 STRING_TOKEN(STR_TEXT_SAMPLE_HELP), 1625 STRING_TOKEN(STR_TEXT_SAMPLE_HELP), 1626 STRING_TOKEN(STR_TEXT_SAMPLE_STRING) 1627 ); 1628 1629 HiiCreateDateOpCode ( 1630 StartOpCodeHandle, 1631 0x8004, 1632 0x0, 1633 0x0, 1634 STRING_TOKEN(STR_DATE_SAMPLE_HELP), 1635 STRING_TOKEN(STR_DATE_SAMPLE_HELP), 1636 0, 1637 QF_DATE_STORAGE_TIME, 1638 NULL 1639 ); 1640 1641 HiiCreateTimeOpCode ( 1642 StartOpCodeHandle, 1643 0x8005, 1644 0x0, 1645 0x0, 1646 STRING_TOKEN(STR_TIME_SAMPLE_HELP), 1647 STRING_TOKEN(STR_TIME_SAMPLE_HELP), 1648 0, 1649 QF_TIME_STORAGE_TIME, 1650 NULL 1651 ); 1652 1653 HiiCreateGotoOpCode ( 1654 StartOpCodeHandle, // Container for dynamic created opcodes 1655 1, // Target Form ID 1656 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text 1657 STRING_TOKEN (STR_GOTO_HELP), // Help text 1658 0, // Question flag 1659 0x8003 // Question ID 1660 ); 1661 1662 HiiUpdateForm ( 1663 PrivateData->HiiHandle[0], // HII handle 1664 &gDriverSampleFormSetGuid, // Formset GUID 1665 0x1234, // Form ID 1666 StartOpCodeHandle, // Label for where to insert opcodes 1667 EndOpCodeHandle // Replace data 1668 ); 1669 1670 HiiFreeOpCodeHandle (StartOpCodeHandle); 1671 HiiFreeOpCodeHandle (OptionsOpCodeHandle); 1672 HiiFreeOpCodeHandle (EndOpCodeHandle); 1673 break; 1674 1675 case 0x2000: 1676 // 1677 // Only used to update the state. 1678 // 1679 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) && 1680 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) { 1681 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD; 1682 return EFI_INVALID_PARAMETER; 1683 } 1684 1685 // 1686 // When try to set a new password, user will be chanlleged with old password. 1687 // The Callback is responsible for validating old password input by user, 1688 // If Callback return EFI_SUCCESS, it indicates validation pass. 1689 // 1690 switch (PrivateData->PasswordState) { 1691 case BROWSER_STATE_VALIDATE_PASSWORD: 1692 Status = ValidatePassword (PrivateData, Value->string); 1693 if (Status == EFI_SUCCESS) { 1694 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD; 1695 } 1696 break; 1697 1698 case BROWSER_STATE_SET_PASSWORD: 1699 Status = SetPassword (PrivateData, Value->string); 1700 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD; 1701 break; 1702 1703 default: 1704 break; 1705 } 1706 1707 break; 1708 1709 default: 1710 break; 1711 } 1712 } 1713 break; 1714 1715 case EFI_BROWSER_ACTION_CHANGED: 1716 switch (QuestionId) { 1717 case 0x1237: 1718 // 1719 // User press "Exit now", request Browser to exit 1720 // 1721 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; 1722 break; 1723 1724 case 0x1238: 1725 // 1726 // User press "Save now", request Browser to save the uncommitted data. 1727 // 1728 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; 1729 break; 1730 1731 case 0x1241: 1732 case 0x1246: 1733 // 1734 // User press "Submit current form and Exit now", request Browser to submit current form and exit 1735 // 1736 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; 1737 break; 1738 1739 case 0x1242: 1740 // 1741 // User press "Discard current form now", request Browser to discard the uncommitted data. 1742 // 1743 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD; 1744 break; 1745 1746 case 0x1243: 1747 // 1748 // User press "Submit current form now", request Browser to save the uncommitted data. 1749 // 1750 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; 1751 break; 1752 1753 case 0x1244: 1754 case 0x1245: 1755 // 1756 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit. 1757 // 1758 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; 1759 break; 1760 1761 case 0x1231: 1762 // 1763 // 1. Check to see whether system support keyword. 1764 // 1765 Status = PrivateData->HiiKeywordHandler->GetData (PrivateData->HiiKeywordHandler, 1766 L"NAMESPACE=x-UEFI-ns", 1767 L"KEYWORD=iSCSIBootEnable", 1768 &Progress, 1769 &ProgressErr, 1770 &Results 1771 ); 1772 if (EFI_ERROR (Status)) { 1773 do { 1774 CreatePopUp ( 1775 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 1776 &Key, 1777 L"", 1778 L"This system not support this keyword!", 1779 L"Press ENTER to continue ...", 1780 L"", 1781 NULL 1782 ); 1783 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); 1784 1785 Status = EFI_SUCCESS; 1786 break; 1787 } 1788 1789 // 1790 // 2. If system support this keyword, just try to change value. 1791 // 1792 1793 // 1794 // Change value from '0' to '1' or from '1' to '0' 1795 // 1796 TmpStr = StrStr (Results, L"&VALUE="); 1797 ASSERT (TmpStr != NULL); 1798 TmpStr += StrLen (L"&VALUE="); 1799 TmpStr++; 1800 if (*TmpStr == L'0') { 1801 *TmpStr = L'1'; 1802 } else { 1803 *TmpStr = L'0'; 1804 } 1805 1806 // 1807 // 3. Call the keyword handler protocol to change the value. 1808 // 1809 Status = PrivateData->HiiKeywordHandler->SetData (PrivateData->HiiKeywordHandler, 1810 Results, 1811 &Progress, 1812 &ProgressErr 1813 ); 1814 if (EFI_ERROR (Status)) { 1815 do { 1816 CreatePopUp ( 1817 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 1818 &Key, 1819 L"", 1820 L"Set keyword to the system failed!", 1821 L"Press ENTER to continue ...", 1822 L"", 1823 NULL 1824 ); 1825 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); 1826 1827 Status = EFI_SUCCESS; 1828 break; 1829 } 1830 break; 1831 1832 default: 1833 break; 1834 } 1835 break; 1836 1837 default: 1838 Status = EFI_UNSUPPORTED; 1839 break; 1840 } 1841 1842 return Status; 1843 } 1844 1845 /** 1846 Main entry for this driver. 1847 1848 @param ImageHandle Image handle this driver. 1849 @param SystemTable Pointer to SystemTable. 1850 1851 @retval EFI_SUCESS This function always complete successfully. 1852 1853 **/ 1854 EFI_STATUS 1855 EFIAPI 1856 DriverSampleInit ( 1857 IN EFI_HANDLE ImageHandle, 1858 IN EFI_SYSTEM_TABLE *SystemTable 1859 ) 1860 { 1861 EFI_STATUS Status; 1862 EFI_HII_HANDLE HiiHandle[2]; 1863 EFI_SCREEN_DESCRIPTOR Screen; 1864 EFI_HII_DATABASE_PROTOCOL *HiiDatabase; 1865 EFI_HII_STRING_PROTOCOL *HiiString; 1866 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2; 1867 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; 1868 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; 1869 CHAR16 *NewString; 1870 UINTN BufferSize; 1871 DRIVER_SAMPLE_CONFIGURATION *Configuration; 1872 BOOLEAN ActionFlag; 1873 EFI_STRING ConfigRequestHdr; 1874 EFI_STRING NameRequestHdr; 1875 MY_EFI_VARSTORE_DATA *VarStoreConfig; 1876 EFI_INPUT_KEY HotKey; 1877 EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx; 1878 1879 // 1880 // Initialize the local variables. 1881 // 1882 ConfigRequestHdr = NULL; 1883 NewString = NULL; 1884 1885 // 1886 // Initialize screen dimensions for SendForm(). 1887 // Remove 3 characters from top and bottom 1888 // 1889 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR)); 1890 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow); 1891 1892 Screen.TopRow = 3; 1893 Screen.BottomRow = Screen.BottomRow - 3; 1894 1895 // 1896 // Initialize driver private data 1897 // 1898 mPrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA)); 1899 if (mPrivateData == NULL) { 1900 return EFI_OUT_OF_RESOURCES; 1901 } 1902 1903 mPrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE; 1904 1905 mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig; 1906 mPrivateData->ConfigAccess.RouteConfig = RouteConfig; 1907 mPrivateData->ConfigAccess.Callback = DriverCallback; 1908 mPrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD; 1909 1910 // 1911 // Locate Hii Database protocol 1912 // 1913 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase); 1914 if (EFI_ERROR (Status)) { 1915 return Status; 1916 } 1917 mPrivateData->HiiDatabase = HiiDatabase; 1918 1919 // 1920 // Locate HiiString protocol 1921 // 1922 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString); 1923 if (EFI_ERROR (Status)) { 1924 return Status; 1925 } 1926 mPrivateData->HiiString = HiiString; 1927 1928 // 1929 // Locate Formbrowser2 protocol 1930 // 1931 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2); 1932 if (EFI_ERROR (Status)) { 1933 return Status; 1934 } 1935 mPrivateData->FormBrowser2 = FormBrowser2; 1936 1937 // 1938 // Locate ConfigRouting protocol 1939 // 1940 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting); 1941 if (EFI_ERROR (Status)) { 1942 return Status; 1943 } 1944 mPrivateData->HiiConfigRouting = HiiConfigRouting; 1945 1946 // 1947 // Locate keyword handler protocol 1948 // 1949 Status = gBS->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid, NULL, (VOID **) &HiiKeywordHandler); 1950 if (EFI_ERROR (Status)) { 1951 return Status; 1952 } 1953 mPrivateData->HiiKeywordHandler = HiiKeywordHandler; 1954 1955 Status = gBS->InstallMultipleProtocolInterfaces ( 1956 &DriverHandle[0], 1957 &gEfiDevicePathProtocolGuid, 1958 &mHiiVendorDevicePath0, 1959 &gEfiHiiConfigAccessProtocolGuid, 1960 &mPrivateData->ConfigAccess, 1961 NULL 1962 ); 1963 ASSERT_EFI_ERROR (Status); 1964 1965 mPrivateData->DriverHandle[0] = DriverHandle[0]; 1966 1967 // 1968 // Publish our HII data 1969 // 1970 HiiHandle[0] = HiiAddPackages ( 1971 &gDriverSampleFormSetGuid, 1972 DriverHandle[0], 1973 DriverSampleStrings, 1974 VfrBin, 1975 NULL 1976 ); 1977 if (HiiHandle[0] == NULL) { 1978 return EFI_OUT_OF_RESOURCES; 1979 } 1980 1981 mPrivateData->HiiHandle[0] = HiiHandle[0]; 1982 1983 // 1984 // Publish another Fromset 1985 // 1986 Status = gBS->InstallMultipleProtocolInterfaces ( 1987 &DriverHandle[1], 1988 &gEfiDevicePathProtocolGuid, 1989 &mHiiVendorDevicePath1, 1990 &gEfiHiiConfigAccessProtocolGuid, 1991 &mPrivateData->ConfigAccess, 1992 NULL 1993 ); 1994 ASSERT_EFI_ERROR (Status); 1995 1996 mPrivateData->DriverHandle[1] = DriverHandle[1]; 1997 1998 HiiHandle[1] = HiiAddPackages ( 1999 &gDriverSampleInventoryGuid, 2000 DriverHandle[1], 2001 DriverSampleStrings, 2002 InventoryBin, 2003 NULL 2004 ); 2005 if (HiiHandle[1] == NULL) { 2006 DriverSampleUnload (ImageHandle); 2007 return EFI_OUT_OF_RESOURCES; 2008 } 2009 2010 mPrivateData->HiiHandle[1] = HiiHandle[1]; 2011 2012 // 2013 // Update the device path string. 2014 // 2015 NewString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)&mHiiVendorDevicePath0, FALSE, FALSE); 2016 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) { 2017 DriverSampleUnload (ImageHandle); 2018 return EFI_OUT_OF_RESOURCES; 2019 } 2020 if (NewString != NULL) { 2021 FreePool (NewString); 2022 } 2023 2024 // 2025 // Very simple example of how one would update a string that is already 2026 // in the HII database 2027 // 2028 NewString = L"700 Mhz"; 2029 2030 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) { 2031 DriverSampleUnload (ImageHandle); 2032 return EFI_OUT_OF_RESOURCES; 2033 } 2034 2035 HiiSetString (HiiHandle[0], 0, NewString, NULL); 2036 2037 // 2038 // Initialize Name/Value name String ID 2039 // 2040 mPrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0; 2041 mPrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1; 2042 mPrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2; 2043 2044 // 2045 // Initialize configuration data 2046 // 2047 Configuration = &mPrivateData->Configuration; 2048 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION)); 2049 2050 // 2051 // Try to read NV config EFI variable first 2052 // 2053 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]); 2054 ASSERT (ConfigRequestHdr != NULL); 2055 2056 NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]); 2057 ASSERT (NameRequestHdr != NULL); 2058 2059 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION); 2060 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration); 2061 if (EFI_ERROR (Status)) { 2062 // 2063 // Store zero data Buffer Storage to EFI variable 2064 // 2065 Status = gRT->SetVariable( 2066 VariableName, 2067 &gDriverSampleFormSetGuid, 2068 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 2069 sizeof (DRIVER_SAMPLE_CONFIGURATION), 2070 Configuration 2071 ); 2072 if (EFI_ERROR (Status)) { 2073 DriverSampleUnload (ImageHandle); 2074 return Status; 2075 } 2076 // 2077 // EFI variable for NV config doesn't exit, we should build this variable 2078 // based on default values stored in IFR 2079 // 2080 ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); 2081 if (!ActionFlag) { 2082 DriverSampleUnload (ImageHandle); 2083 return EFI_INVALID_PARAMETER; 2084 } 2085 2086 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); 2087 if (!ActionFlag) { 2088 DriverSampleUnload (ImageHandle); 2089 return EFI_INVALID_PARAMETER; 2090 } 2091 } else { 2092 // 2093 // EFI variable does exist and Validate Current Setting 2094 // 2095 ActionFlag = HiiValidateSettings (NameRequestHdr); 2096 if (!ActionFlag) { 2097 DriverSampleUnload (ImageHandle); 2098 return EFI_INVALID_PARAMETER; 2099 } 2100 2101 ActionFlag = HiiValidateSettings (ConfigRequestHdr); 2102 if (!ActionFlag) { 2103 DriverSampleUnload (ImageHandle); 2104 return EFI_INVALID_PARAMETER; 2105 } 2106 } 2107 FreePool (ConfigRequestHdr); 2108 2109 // 2110 // Initialize efi varstore configuration data 2111 // 2112 VarStoreConfig = &mPrivateData->VarStoreConfig; 2113 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA)); 2114 2115 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]); 2116 ASSERT (ConfigRequestHdr != NULL); 2117 2118 BufferSize = sizeof (MY_EFI_VARSTORE_DATA); 2119 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig); 2120 if (EFI_ERROR (Status)) { 2121 // 2122 // Store zero data to EFI variable Storage. 2123 // 2124 Status = gRT->SetVariable( 2125 MyEfiVar, 2126 &gDriverSampleFormSetGuid, 2127 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 2128 sizeof (MY_EFI_VARSTORE_DATA), 2129 VarStoreConfig 2130 ); 2131 if (EFI_ERROR (Status)) { 2132 DriverSampleUnload (ImageHandle); 2133 return Status; 2134 } 2135 // 2136 // EFI variable for NV config doesn't exit, we should build this variable 2137 // based on default values stored in IFR 2138 // 2139 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD); 2140 if (!ActionFlag) { 2141 DriverSampleUnload (ImageHandle); 2142 return EFI_INVALID_PARAMETER; 2143 } 2144 } else { 2145 // 2146 // EFI variable does exist and Validate Current Setting 2147 // 2148 ActionFlag = HiiValidateSettings (ConfigRequestHdr); 2149 if (!ActionFlag) { 2150 DriverSampleUnload (ImageHandle); 2151 return EFI_INVALID_PARAMETER; 2152 } 2153 } 2154 FreePool (ConfigRequestHdr); 2155 2156 Status = gBS->CreateEventEx ( 2157 EVT_NOTIFY_SIGNAL, 2158 TPL_NOTIFY, 2159 DriverSampleInternalEmptyFunction, 2160 NULL, 2161 &gEfiIfrRefreshIdOpGuid, 2162 &mEvent 2163 ); 2164 ASSERT_EFI_ERROR (Status); 2165 2166 // 2167 // Example of how to use BrowserEx protocol to register HotKey. 2168 // 2169 Status = gBS->LocateProtocol (&gEfiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx); 2170 if (!EFI_ERROR (Status)) { 2171 // 2172 // First unregister the default hot key F9 and F10. 2173 // 2174 HotKey.UnicodeChar = CHAR_NULL; 2175 HotKey.ScanCode = SCAN_F9; 2176 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL); 2177 HotKey.ScanCode = SCAN_F10; 2178 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL); 2179 2180 // 2181 // Register the default HotKey F9 and F10 again. 2182 // 2183 HotKey.ScanCode = SCAN_F10; 2184 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL); 2185 ASSERT (NewString != NULL); 2186 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString); 2187 HotKey.ScanCode = SCAN_F9; 2188 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL); 2189 ASSERT (NewString != NULL); 2190 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString); 2191 } 2192 2193 // 2194 // In default, this driver is built into Flash device image, 2195 // the following code doesn't run. 2196 // 2197 2198 // 2199 // Example of how to display only the item we sent to HII 2200 // When this driver is not built into Flash device image, 2201 // it need to call SendForm to show front page by itself. 2202 // 2203 if (DISPLAY_ONLY_MY_ITEM <= 1) { 2204 // 2205 // Have the browser pull out our copy of the data, and only display our data 2206 // 2207 Status = FormBrowser2->SendForm ( 2208 FormBrowser2, 2209 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]), 2210 1, 2211 NULL, 2212 0, 2213 NULL, 2214 NULL 2215 ); 2216 2217 HiiRemovePackages (HiiHandle[0]); 2218 2219 HiiRemovePackages (HiiHandle[1]); 2220 } 2221 2222 return EFI_SUCCESS; 2223 } 2224 2225 /** 2226 Unloads the application and its installed protocol. 2227 2228 @param[in] ImageHandle Handle that identifies the image to be unloaded. 2229 2230 @retval EFI_SUCCESS The image has been unloaded. 2231 **/ 2232 EFI_STATUS 2233 EFIAPI 2234 DriverSampleUnload ( 2235 IN EFI_HANDLE ImageHandle 2236 ) 2237 { 2238 UINTN Index; 2239 2240 ASSERT (mPrivateData != NULL); 2241 2242 if (DriverHandle[0] != NULL) { 2243 gBS->UninstallMultipleProtocolInterfaces ( 2244 DriverHandle[0], 2245 &gEfiDevicePathProtocolGuid, 2246 &mHiiVendorDevicePath0, 2247 &gEfiHiiConfigAccessProtocolGuid, 2248 &mPrivateData->ConfigAccess, 2249 NULL 2250 ); 2251 DriverHandle[0] = NULL; 2252 } 2253 2254 if (DriverHandle[1] != NULL) { 2255 gBS->UninstallMultipleProtocolInterfaces ( 2256 DriverHandle[1], 2257 &gEfiDevicePathProtocolGuid, 2258 &mHiiVendorDevicePath1, 2259 NULL 2260 ); 2261 DriverHandle[1] = NULL; 2262 } 2263 2264 if (mPrivateData->HiiHandle[0] != NULL) { 2265 HiiRemovePackages (mPrivateData->HiiHandle[0]); 2266 } 2267 2268 if (mPrivateData->HiiHandle[1] != NULL) { 2269 HiiRemovePackages (mPrivateData->HiiHandle[1]); 2270 } 2271 2272 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) { 2273 if (mPrivateData->NameValueName[Index] != NULL) { 2274 FreePool (mPrivateData->NameValueName[Index]); 2275 } 2276 } 2277 FreePool (mPrivateData); 2278 mPrivateData = NULL; 2279 2280 gBS->CloseEvent (mEvent); 2281 2282 return EFI_SUCCESS; 2283 } 2284