1/** @file 2This is an example of how a driver might export data to the HII protocol to be 3later utilized by the Setup Protocol 4 5Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR> 6This program and the accompanying materials 7are licensed and made available under the terms and conditions of the BSD License 8which accompanies this distribution. The full text of the license may be found at 9http://opensource.org/licenses/bsd-license.php 10 11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12WITHOUT 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 21CHAR16 VariableName[] = L"MyIfrNVData"; 22CHAR16 MyEfiVar[] = L"MyEfiVar"; 23EFI_HANDLE DriverHandle[2] = {NULL, NULL}; 24DRIVER_SAMPLE_PRIVATE_DATA *mPrivateData = NULL; 25EFI_EVENT mEvent; 26 27HII_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 49HII_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**/ 78VOID 79EFIAPI 80DriverSampleInternalEmptyFunction ( 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**/ 94EFI_STATUS 95EFIAPI 96NotificationFunction( 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**/ 111EFI_STATUS 112EFIAPI 113InternalStartMonitor( 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**/ 170EFI_STATUS 171EFIAPI 172InternalStopMonitor( 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**/ 230VOID 231EncodePassword ( 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**/ 266EFI_STATUS 267ValidatePassword ( 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**/ 360EFI_STATUS 361SetPassword ( 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**/ 458EFI_STATUS 459LoadNameValueNames ( 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**/ 502EFI_STATUS 503GetValueOfNumber ( 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 561Exit: 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**/ 580EFI_STRING 581CreateAltCfgString ( 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**/ 658VOID 659AppendAltCfgString ( 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**/ 778EFI_STATUS 779EFIAPI 780ExtractConfig ( 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**/ 1030EFI_STATUS 1031EFIAPI 1032RouteConfig ( 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**/ 1260EFI_STATUS 1261EFIAPI 1262DriverCallback ( 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**/ 1854EFI_STATUS 1855EFIAPI 1856DriverSampleInit ( 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**/ 2232EFI_STATUS 2233EFIAPI 2234DriverSampleUnload ( 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