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