1 /** @file 2 Helper functions for configuring or getting the parameters relating to Ip4. 3 4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "Ip4Impl.h" 16 17 CHAR16 mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA"; 18 19 /** 20 Calculate the prefix length of the IPv4 subnet mask. 21 22 @param[in] SubnetMask The IPv4 subnet mask. 23 24 @return The prefix length of the subnet mask. 25 @retval 0 Other errors as indicated. 26 27 **/ 28 UINT8 29 GetSubnetMaskPrefixLength ( 30 IN EFI_IPv4_ADDRESS *SubnetMask 31 ) 32 { 33 UINT8 Len; 34 UINT32 ReverseMask; 35 36 // 37 // The SubnetMask is in network byte order. 38 // 39 ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]); 40 41 // 42 // Reverse it. 43 // 44 ReverseMask = ~ReverseMask; 45 46 if ((ReverseMask & (ReverseMask + 1)) != 0) { 47 return 0; 48 } 49 50 Len = 0; 51 52 while (ReverseMask != 0) { 53 ReverseMask = ReverseMask >> 1; 54 Len++; 55 } 56 57 return (UINT8) (32 - Len); 58 } 59 60 /** 61 Convert the decimal dotted IPv4 address into the binary IPv4 address. 62 63 @param[in] Str The UNICODE string. 64 @param[out] Ip The storage to return the IPv4 address. 65 66 @retval EFI_SUCCESS The binary IP address is returned in Ip. 67 @retval EFI_INVALID_PARAMETER The IP string is malformatted. 68 69 **/ 70 EFI_STATUS 71 Ip4Config2StrToIp ( 72 IN CHAR16 *Str, 73 OUT EFI_IPv4_ADDRESS *Ip 74 ) 75 { 76 UINTN Index; 77 UINTN Number; 78 79 Index = 0; 80 81 while (*Str != L'\0') { 82 83 if (Index > 3) { 84 return EFI_INVALID_PARAMETER; 85 } 86 87 Number = 0; 88 while ((*Str >= L'0') && (*Str <= L'9')) { 89 Number = Number * 10 + (*Str - L'0'); 90 Str++; 91 } 92 93 if (Number > 0xFF) { 94 return EFI_INVALID_PARAMETER; 95 } 96 97 Ip->Addr[Index] = (UINT8) Number; 98 99 if ((*Str != L'\0') && (*Str != L'.')) { 100 // 101 // The current character should be either the NULL terminator or 102 // the dot delimiter. 103 // 104 return EFI_INVALID_PARAMETER; 105 } 106 107 if (*Str == L'.') { 108 // 109 // Skip the delimiter. 110 // 111 Str++; 112 } 113 114 Index++; 115 } 116 117 if (Index != 4) { 118 return EFI_INVALID_PARAMETER; 119 } 120 121 return EFI_SUCCESS; 122 } 123 124 /** 125 Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list. 126 127 @param[in] Str The UNICODE string contains IPv4 addresses. 128 @param[out] PtrIpList The storage to return the IPv4 address list. 129 @param[out] IpCount The size of the IPv4 address list. 130 131 @retval EFI_SUCCESS The binary IP address list is returned in PtrIpList. 132 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory. 133 @retval EFI_INVALID_PARAMETER The IP string is malformatted. 134 135 **/ 136 EFI_STATUS 137 Ip4Config2StrToIpList ( 138 IN CHAR16 *Str, 139 OUT EFI_IPv4_ADDRESS **PtrIpList, 140 OUT UINTN *IpCount 141 ) 142 { 143 UINTN BeginIndex; 144 UINTN EndIndex; 145 UINTN Index; 146 UINTN IpIndex; 147 CHAR16 *StrTemp; 148 BOOLEAN SpaceTag; 149 150 BeginIndex = 0; 151 EndIndex = BeginIndex; 152 Index = 0; 153 IpIndex = 0; 154 StrTemp = NULL; 155 SpaceTag = TRUE; 156 157 *PtrIpList = NULL; 158 *IpCount = 0; 159 160 if (Str == NULL) { 161 return EFI_SUCCESS; 162 } 163 164 // 165 // Get the number of Ip. 166 // 167 while (*(Str + Index) != L'\0') { 168 if (*(Str + Index) == L' ') { 169 SpaceTag = TRUE; 170 } else { 171 if (SpaceTag) { 172 (*IpCount)++; 173 SpaceTag = FALSE; 174 } 175 } 176 177 Index++; 178 } 179 180 if (*IpCount == 0) { 181 return EFI_SUCCESS; 182 } 183 184 // 185 // Allocate buffer for IpList. 186 // 187 *PtrIpList = AllocateZeroPool(*IpCount * sizeof(EFI_IPv4_ADDRESS)); 188 if (*PtrIpList == NULL) { 189 return EFI_OUT_OF_RESOURCES; 190 } 191 192 // 193 // Get IpList from Str. 194 // 195 Index = 0; 196 while (*(Str + Index) != L'\0') { 197 if (*(Str + Index) == L' ') { 198 if(!SpaceTag) { 199 StrTemp = AllocateZeroPool((EndIndex - BeginIndex + 1) * sizeof(CHAR16)); 200 if (StrTemp == NULL) { 201 FreePool(*PtrIpList); 202 *PtrIpList = NULL; 203 *IpCount = 0; 204 return EFI_OUT_OF_RESOURCES; 205 } 206 207 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof(CHAR16)); 208 *(StrTemp + (EndIndex - BeginIndex)) = L'\0'; 209 210 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) { 211 FreePool(StrTemp); 212 FreePool(*PtrIpList); 213 *PtrIpList = NULL; 214 *IpCount = 0; 215 return EFI_INVALID_PARAMETER; 216 } 217 218 BeginIndex = EndIndex; 219 IpIndex++; 220 221 FreePool(StrTemp); 222 } 223 224 BeginIndex++; 225 EndIndex++; 226 SpaceTag = TRUE; 227 } else { 228 EndIndex++; 229 SpaceTag = FALSE; 230 } 231 232 Index++; 233 234 if (*(Str + Index) == L'\0') { 235 if (!SpaceTag) { 236 StrTemp = AllocateZeroPool((EndIndex - BeginIndex + 1) * sizeof(CHAR16)); 237 if (StrTemp == NULL) { 238 FreePool(*PtrIpList); 239 *PtrIpList = NULL; 240 *IpCount = 0; 241 return EFI_OUT_OF_RESOURCES; 242 } 243 244 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof(CHAR16)); 245 *(StrTemp + (EndIndex - BeginIndex)) = L'\0'; 246 247 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) { 248 FreePool(StrTemp); 249 FreePool(*PtrIpList); 250 *PtrIpList = NULL; 251 *IpCount = 0; 252 return EFI_INVALID_PARAMETER; 253 } 254 255 FreePool(StrTemp); 256 } 257 } 258 } 259 260 return EFI_SUCCESS; 261 } 262 263 /** 264 Convert the IPv4 address into a dotted string. 265 266 @param[in] Ip The IPv4 address. 267 @param[out] Str The dotted IP string. 268 269 **/ 270 VOID 271 Ip4Config2IpToStr ( 272 IN EFI_IPv4_ADDRESS *Ip, 273 OUT CHAR16 *Str 274 ) 275 { 276 UnicodeSPrint ( 277 Str, 278 2 * IP4_STR_MAX_SIZE, 279 L"%d.%d.%d.%d", 280 Ip->Addr[0], 281 Ip->Addr[1], 282 Ip->Addr[2], 283 Ip->Addr[3] 284 ); 285 } 286 287 288 /** 289 Convert the IPv4 address list into string consists of several decimal 290 dotted IPv4 addresses separated by space. 291 292 @param[in] Ip The IPv4 address list. 293 @param[in] IpCount The size of IPv4 address list. 294 @param[out] Str The string contains several decimal dotted 295 IPv4 addresses separated by space. 296 **/ 297 VOID 298 Ip4Config2IpListToStr ( 299 IN EFI_IPv4_ADDRESS *Ip, 300 IN UINTN IpCount, 301 OUT CHAR16 *Str 302 ) 303 { 304 UINTN Index; 305 UINTN TemIndex; 306 UINTN StrIndex; 307 CHAR16 *TempStr; 308 EFI_IPv4_ADDRESS *TempIp; 309 310 Index = 0; 311 TemIndex = 0; 312 StrIndex = 0; 313 TempStr = NULL; 314 TempIp = NULL; 315 316 for (Index = 0; Index < IpCount; Index ++) { 317 TempIp = Ip + Index; 318 if (TempStr == NULL) { 319 TempStr = AllocateZeroPool(2 * IP4_STR_MAX_SIZE); 320 ASSERT(TempStr != NULL); 321 } 322 323 UnicodeSPrint ( 324 TempStr, 325 2 * IP4_STR_MAX_SIZE, 326 L"%d.%d.%d.%d", 327 TempIp->Addr[0], 328 TempIp->Addr[1], 329 TempIp->Addr[2], 330 TempIp->Addr[3] 331 ); 332 333 for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex ++) { 334 if (*(TempStr + TemIndex) == L'\0') { 335 if (Index == IpCount - 1) { 336 Str[StrIndex++] = L'\0'; 337 } else { 338 Str[StrIndex++] = L' '; 339 } 340 break; 341 } else { 342 Str[StrIndex++] = *(TempStr + TemIndex); 343 } 344 } 345 } 346 347 if (TempStr != NULL) { 348 FreePool(TempStr); 349 } 350 } 351 352 /** 353 The notify function of create event when performing a manual configuration. 354 355 @param[in] Event The pointer of Event. 356 @param[in] Context The pointer of Context. 357 358 **/ 359 VOID 360 EFIAPI 361 Ip4Config2ManualAddressNotify ( 362 IN EFI_EVENT Event, 363 IN VOID *Context 364 ) 365 { 366 *((BOOLEAN *) Context) = TRUE; 367 } 368 369 /** 370 Convert the network configuration data into the IFR data. 371 372 @param[in] Instance The IP4 config2 instance. 373 @param[in, out] IfrNvData The IFR nv data. 374 375 @retval EFI_SUCCESS The configure parameter to IFR data was 376 set successfully. 377 @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not available. 378 @retval Others Other errors as indicated. 379 380 **/ 381 EFI_STATUS 382 Ip4Config2ConvertConfigNvDataToIfrNvData ( 383 IN IP4_CONFIG2_INSTANCE *Instance, 384 IN OUT IP4_CONFIG2_IFR_NVDATA *IfrNvData 385 ) 386 { 387 IP4_SERVICE *IpSb; 388 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; 389 EFI_IP4_CONFIG2_INTERFACE_INFO *Ip4Info; 390 EFI_IP4_CONFIG2_POLICY Policy; 391 UINTN DataSize; 392 UINTN GatewaySize; 393 EFI_IPv4_ADDRESS GatewayAddress; 394 EFI_STATUS Status; 395 UINTN DnsSize; 396 UINTN DnsCount; 397 EFI_IPv4_ADDRESS *DnsAddress; 398 399 Status = EFI_SUCCESS; 400 Ip4Config2 = &Instance->Ip4Config2; 401 Ip4Info = NULL; 402 DnsAddress = NULL; 403 GatewaySize = sizeof (EFI_IPv4_ADDRESS); 404 405 if ((IfrNvData == NULL) || (Instance == NULL)) { 406 return EFI_INVALID_PARAMETER; 407 } 408 409 NET_CHECK_SIGNATURE (Instance, IP4_CONFIG2_INSTANCE_SIGNATURE); 410 411 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); 412 413 if (IpSb->DefaultInterface->Configured) { 414 IfrNvData->Configure = 1; 415 } else { 416 IfrNvData->Configure = 0; 417 goto Exit; 418 } 419 420 // 421 // Get the Policy info. 422 // 423 DataSize = sizeof (EFI_IP4_CONFIG2_POLICY); 424 Status = Ip4Config2->GetData ( 425 Ip4Config2, 426 Ip4Config2DataTypePolicy, 427 &DataSize, 428 &Policy 429 ); 430 if (EFI_ERROR (Status)) { 431 goto Exit; 432 } 433 434 if (Policy == Ip4Config2PolicyStatic) { 435 IfrNvData->DhcpEnable = FALSE; 436 } else if (Policy == Ip4Config2PolicyDhcp) { 437 IfrNvData->DhcpEnable = TRUE; 438 goto Exit; 439 } 440 441 // 442 // Get the interface info. 443 // 444 DataSize = 0; 445 Status = Ip4Config2->GetData ( 446 Ip4Config2, 447 Ip4Config2DataTypeInterfaceInfo, 448 &DataSize, 449 NULL 450 ); 451 if (Status != EFI_BUFFER_TOO_SMALL) { 452 return Status; 453 } 454 455 Ip4Info = AllocateZeroPool (DataSize); 456 if (Ip4Info == NULL) { 457 Status = EFI_OUT_OF_RESOURCES; 458 return Status; 459 } 460 461 Status = Ip4Config2->GetData ( 462 Ip4Config2, 463 Ip4Config2DataTypeInterfaceInfo, 464 &DataSize, 465 Ip4Info 466 ); 467 if (EFI_ERROR (Status)) { 468 goto Exit; 469 } 470 471 // 472 // Get the Gateway info. 473 // 474 Status = Ip4Config2->GetData ( 475 Ip4Config2, 476 Ip4Config2DataTypeGateway, 477 &GatewaySize, 478 &GatewayAddress 479 ); 480 if (EFI_ERROR (Status)) { 481 goto Exit; 482 } 483 484 // 485 // Get the Dns info. 486 // 487 DnsSize = 0; 488 Status = Ip4Config2->GetData ( 489 Ip4Config2, 490 Ip4Config2DataTypeDnsServer, 491 &DnsSize, 492 NULL 493 ); 494 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) { 495 goto Exit; 496 } 497 498 DnsCount = (UINT32) (DnsSize / sizeof (EFI_IPv4_ADDRESS)); 499 500 if (DnsSize > 0) { 501 DnsAddress = AllocateZeroPool(DnsSize); 502 if (DnsAddress == NULL) { 503 Status = EFI_OUT_OF_RESOURCES; 504 goto Exit; 505 } 506 507 Status = Ip4Config2->GetData ( 508 Ip4Config2, 509 Ip4Config2DataTypeDnsServer, 510 &DnsSize, 511 DnsAddress 512 ); 513 if (EFI_ERROR (Status)) { 514 goto Exit; 515 } 516 } 517 518 Ip4Config2IpToStr (&Ip4Info->StationAddress, IfrNvData->StationAddress); 519 Ip4Config2IpToStr (&Ip4Info->SubnetMask, IfrNvData->SubnetMask); 520 Ip4Config2IpToStr (&GatewayAddress, IfrNvData->GatewayAddress); 521 Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress); 522 523 Exit: 524 525 if (DnsAddress != NULL) { 526 FreePool(DnsAddress); 527 } 528 529 if (Ip4Info != NULL) { 530 FreePool(Ip4Info); 531 } 532 533 return Status; 534 } 535 536 /** 537 Convert the IFR data into the network configuration data and set the IP 538 configure parameters for the NIC. 539 540 @param[in] IfrFormNvData The IFR NV data. 541 @param[in, out] Instance The IP4 config2 instance. 542 543 @retval EFI_SUCCESS The configure parameter for this NIC was 544 set successfully. 545 @retval EFI_INVALID_PARAMETER The address information for setting is invalid. 546 @retval Others Other errors as indicated. 547 548 **/ 549 EFI_STATUS 550 Ip4Config2ConvertIfrNvDataToConfigNvData ( 551 IN IP4_CONFIG2_IFR_NVDATA *IfrFormNvData, 552 IN OUT IP4_CONFIG2_INSTANCE *Instance 553 ) 554 { 555 EFI_STATUS Status; 556 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2; 557 IP4_CONFIG2_NVDATA *Ip4NvData; 558 559 EFI_IP_ADDRESS StationAddress; 560 EFI_IP_ADDRESS SubnetMask; 561 EFI_IP_ADDRESS Gateway; 562 IP4_ADDR Ip; 563 EFI_IPv4_ADDRESS *DnsAddress; 564 UINTN DnsCount; 565 UINTN Index; 566 567 EFI_EVENT TimeoutEvent; 568 EFI_EVENT SetAddressEvent; 569 BOOLEAN IsAddressOk; 570 UINTN DataSize; 571 EFI_INPUT_KEY Key; 572 573 Status = EFI_SUCCESS; 574 Ip4Cfg2 = &Instance->Ip4Config2; 575 Ip4NvData = &Instance->Ip4NvData; 576 577 DnsCount = 0; 578 DnsAddress = NULL; 579 580 TimeoutEvent = NULL; 581 SetAddressEvent = NULL; 582 583 584 585 if (Instance == NULL || IfrFormNvData == NULL) { 586 return EFI_INVALID_PARAMETER; 587 } 588 589 if (IfrFormNvData->Configure != TRUE) { 590 return EFI_SUCCESS; 591 } 592 593 if (IfrFormNvData->DhcpEnable == TRUE) { 594 Ip4NvData->Policy = Ip4Config2PolicyDhcp; 595 596 Status = Ip4Cfg2->SetData ( 597 Ip4Cfg2, 598 Ip4Config2DataTypePolicy, 599 sizeof (EFI_IP4_CONFIG2_POLICY), 600 &Ip4NvData->Policy 601 ); 602 if (EFI_ERROR(Status)) { 603 return Status; 604 } 605 } else { 606 // 607 // Get Ip4NvData from IfrFormNvData if it is valid. 608 // 609 Ip4NvData->Policy = Ip4Config2PolicyStatic; 610 611 Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4); 612 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { 613 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); 614 return EFI_INVALID_PARAMETER; 615 } 616 617 Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4); 618 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) { 619 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); 620 return EFI_INVALID_PARAMETER; 621 } 622 623 Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4); 624 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0])))) { 625 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); 626 return EFI_INVALID_PARAMETER; 627 } 628 629 Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount); 630 if (!EFI_ERROR (Status) && DnsCount > 0) { 631 for (Index = 0; Index < DnsCount; Index ++) { 632 CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR)); 633 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) { 634 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); 635 FreePool(DnsAddress); 636 return EFI_INVALID_PARAMETER; 637 } 638 } 639 } else { 640 if (EFI_ERROR (Status)) { 641 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); 642 } 643 } 644 645 if (Ip4NvData->ManualAddress != NULL) { 646 FreePool(Ip4NvData->ManualAddress); 647 } 648 Ip4NvData->ManualAddressCount = 1; 649 Ip4NvData->ManualAddress = AllocateZeroPool(sizeof(EFI_IP4_CONFIG2_MANUAL_ADDRESS)); 650 if (Ip4NvData->ManualAddress == NULL) { 651 if (DnsAddress != NULL) { 652 FreePool(DnsAddress); 653 } 654 655 return EFI_OUT_OF_RESOURCES; 656 } 657 CopyMem(&Ip4NvData->ManualAddress->Address, &StationAddress.v4, sizeof(EFI_IPv4_ADDRESS)); 658 CopyMem(&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4, sizeof(EFI_IPv4_ADDRESS)); 659 660 if (Ip4NvData->GatewayAddress != NULL) { 661 FreePool(Ip4NvData->GatewayAddress); 662 } 663 Ip4NvData->GatewayAddressCount = 1; 664 Ip4NvData->GatewayAddress = AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS)); 665 if (Ip4NvData->GatewayAddress == NULL) { 666 if (DnsAddress != NULL) { 667 FreePool(DnsAddress); 668 } 669 return EFI_OUT_OF_RESOURCES; 670 } 671 CopyMem(Ip4NvData->GatewayAddress, &Gateway.v4, sizeof(EFI_IPv4_ADDRESS)); 672 673 if (Ip4NvData->DnsAddress != NULL) { 674 FreePool(Ip4NvData->DnsAddress); 675 } 676 Ip4NvData->DnsAddressCount = (UINT32) DnsCount; 677 Ip4NvData->DnsAddress = DnsAddress; 678 679 // 680 // Setting Ip4NvData. 681 // 682 Status = Ip4Cfg2->SetData ( 683 Ip4Cfg2, 684 Ip4Config2DataTypePolicy, 685 sizeof (EFI_IP4_CONFIG2_POLICY), 686 &Ip4NvData->Policy 687 ); 688 if (EFI_ERROR(Status)) { 689 return Status; 690 } 691 692 // 693 // Create events & timers for asynchronous settings. 694 // 695 Status = gBS->CreateEvent ( 696 EVT_TIMER, 697 TPL_CALLBACK, 698 NULL, 699 NULL, 700 &TimeoutEvent 701 ); 702 if (EFI_ERROR (Status)) { 703 return EFI_OUT_OF_RESOURCES; 704 } 705 706 Status = gBS->CreateEvent ( 707 EVT_NOTIFY_SIGNAL, 708 TPL_NOTIFY, 709 Ip4Config2ManualAddressNotify, 710 &IsAddressOk, 711 &SetAddressEvent 712 ); 713 if (EFI_ERROR (Status)) { 714 goto Exit; 715 } 716 717 IsAddressOk = FALSE; 718 719 Status = Ip4Cfg2->RegisterDataNotify ( 720 Ip4Cfg2, 721 Ip4Config2DataTypeManualAddress, 722 SetAddressEvent 723 ); 724 if (EFI_ERROR (Status)) { 725 goto Exit; 726 } 727 728 // 729 // Set ManualAddress. 730 // 731 DataSize = Ip4NvData->ManualAddressCount * sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS); 732 Status = Ip4Cfg2->SetData ( 733 Ip4Cfg2, 734 Ip4Config2DataTypeManualAddress, 735 DataSize, 736 (VOID *) Ip4NvData->ManualAddress 737 ); 738 739 if (Status == EFI_NOT_READY) { 740 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000); 741 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) { 742 if (IsAddressOk) { 743 Status = EFI_SUCCESS; 744 break; 745 } 746 } 747 } 748 749 Ip4Cfg2->UnregisterDataNotify ( 750 Ip4Cfg2, 751 Ip4Config2DataTypeManualAddress, 752 SetAddressEvent 753 ); 754 if (EFI_ERROR (Status)) { 755 goto Exit; 756 } 757 758 // 759 // Set gateway. 760 // 761 DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS); 762 Status = Ip4Cfg2->SetData ( 763 Ip4Cfg2, 764 Ip4Config2DataTypeGateway, 765 DataSize, 766 Ip4NvData->GatewayAddress 767 ); 768 if (EFI_ERROR (Status)) { 769 goto Exit; 770 } 771 772 // 773 // Set DNS addresses. 774 // 775 if (Ip4NvData->DnsAddressCount > 0 && Ip4NvData->DnsAddress != NULL) { 776 DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS); 777 Status = Ip4Cfg2->SetData ( 778 Ip4Cfg2, 779 Ip4Config2DataTypeDnsServer, 780 DataSize, 781 Ip4NvData->DnsAddress 782 ); 783 784 if (EFI_ERROR (Status)) { 785 goto Exit; 786 } 787 } 788 } 789 790 Exit: 791 if (SetAddressEvent != NULL) { 792 gBS->CloseEvent (SetAddressEvent); 793 } 794 795 if (TimeoutEvent != NULL) { 796 gBS->CloseEvent (TimeoutEvent); 797 } 798 799 return Status; 800 } 801 802 /** 803 This function allows the caller to request the current 804 configuration for one or more named elements. The resulting 805 string is in <ConfigAltResp> format. Any and all alternative 806 configuration strings shall also be appended to the end of the 807 current configuration string. If they are, they must appear 808 after the current configuration. They must contain the same 809 routing (GUID, NAME, PATH) as the current configuration string. 810 They must have an additional description indicating the type of 811 alternative configuration the string represents, 812 "ALTCFG=<StringToken>". That <StringToken> (when 813 converted from Hex UNICODE to binary) is a reference to a 814 string in the associated string pack. 815 816 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 817 @param[in] Request A null-terminated Unicode string in 818 <ConfigRequest> format. Note that this 819 includes the routing information as well as 820 the configurable name / value pairs. It is 821 invalid for this string to be in 822 <MultiConfigRequest> format. 823 @param[out] Progress On return, points to a character in the 824 Request string. Points to the string's null 825 terminator if request was successful. Points 826 to the most recent "&" before the first 827 failing name / value pair (or the beginning 828 of the string if the failure is in the first 829 name / value pair) if the request was not 830 successful. 831 @param[out] Results A null-terminated Unicode string in 832 <ConfigAltResp> format which has all values 833 filled in for the names in the Request string. 834 String to be allocated by the called function. 835 836 @retval EFI_SUCCESS The Results string is filled with the 837 values corresponding to all requested 838 names. 839 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the 840 parts of the results that must be 841 stored awaiting possible future 842 protocols. 843 @retval EFI_NOT_FOUND Routing data doesn't match any 844 known driver. Progress set to the 845 first character in the routing header. 846 Note: There is no requirement that the 847 driver validate the routing data. It 848 must skip the <ConfigHdr> in order to 849 process the names. 850 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set 851 to most recent & before the 852 error or the beginning of the 853 string. 854 @retval EFI_INVALID_PARAMETER Unknown name. Progress points 855 to the & before the name in 856 question.Currently not implemented. 857 **/ 858 EFI_STATUS 859 EFIAPI 860 Ip4FormExtractConfig ( 861 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 862 IN CONST EFI_STRING Request, 863 OUT EFI_STRING *Progress, 864 OUT EFI_STRING *Results 865 ) 866 { 867 EFI_STATUS Status; 868 IP4_CONFIG2_INSTANCE *Ip4Config2Instance; 869 IP4_FORM_CALLBACK_INFO *Private; 870 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData; 871 EFI_STRING ConfigRequestHdr; 872 EFI_STRING ConfigRequest; 873 BOOLEAN AllocatedRequest; 874 EFI_STRING FormResult; 875 UINTN Size; 876 UINTN BufferSize; 877 878 if (Progress == NULL || Results == NULL) { 879 return EFI_INVALID_PARAMETER; 880 } 881 882 Status = EFI_SUCCESS; 883 IfrFormNvData = NULL; 884 ConfigRequest = NULL; 885 FormResult = NULL; 886 Size = 0; 887 AllocatedRequest = FALSE; 888 ConfigRequest = Request; 889 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This); 890 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private); 891 BufferSize = sizeof (IP4_CONFIG2_IFR_NVDATA); 892 *Progress = Request; 893 894 // 895 // Check Request data in <ConfigHdr>. 896 // 897 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) { 898 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA)); 899 if (IfrFormNvData == NULL) { 900 return EFI_OUT_OF_RESOURCES; 901 } 902 903 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance, IfrFormNvData); 904 905 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { 906 // 907 // Request has no request element, construct full request string. 908 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template 909 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator 910 // 911 ConfigRequestHdr = HiiConstructConfigHdr (&gIp4Config2NvDataGuid, mIp4Config2StorageName, Private->ChildHandle); 912 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); 913 ConfigRequest = AllocateZeroPool (Size); 914 ASSERT (ConfigRequest != NULL); 915 AllocatedRequest = TRUE; 916 917 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); 918 FreePool (ConfigRequestHdr); 919 } 920 921 // 922 // Convert buffer data to <ConfigResp> by helper function BlockToConfig() 923 // 924 Status = gHiiConfigRouting->BlockToConfig ( 925 gHiiConfigRouting, 926 ConfigRequest, 927 (UINT8 *) IfrFormNvData, 928 BufferSize, 929 &FormResult, 930 Progress 931 ); 932 933 FreePool (IfrFormNvData); 934 935 // 936 // Free the allocated config request string. 937 // 938 if (AllocatedRequest) { 939 FreePool (ConfigRequest); 940 ConfigRequest = NULL; 941 } 942 943 if (EFI_ERROR (Status)) { 944 goto Failure; 945 } 946 } 947 948 if (Request == NULL || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) { 949 *Results = FormResult; 950 } else { 951 return EFI_NOT_FOUND; 952 } 953 954 Failure: 955 // 956 // Set Progress string to the original request string. 957 // 958 if (Request == NULL) { 959 *Progress = NULL; 960 } else if (StrStr (Request, L"OFFSET") == NULL) { 961 *Progress = Request + StrLen (Request); 962 } 963 964 return Status; 965 } 966 967 /** 968 This function applies changes in a driver's configuration. 969 Input is a Configuration, which has the routing data for this 970 driver followed by name / value configuration pairs. The driver 971 must apply those pairs to its configurable storage. If the 972 driver's configuration is stored in a linear block of data 973 and the driver's name / value pairs are in <BlockConfig> 974 format, it may use the ConfigToBlock helper function (above) to 975 simplify the job. Currently not implemented. 976 977 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 978 @param[in] Configuration A null-terminated Unicode string in 979 <ConfigString> format. 980 @param[out] Progress A pointer to a string filled in with the 981 offset of the most recent '&' before the 982 first failing name / value pair (or the 983 beginn ing of the string if the failure 984 is in the first name / value pair) or 985 the terminating NULL if all was 986 successful. 987 988 @retval EFI_SUCCESS The results have been distributed or are 989 awaiting distribution. 990 @retval EFI_OUT_OF_MEMORY Not enough memory to store the 991 parts of the results that must be 992 stored awaiting possible future 993 protocols. 994 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the 995 Results parameter would result 996 in this type of error. 997 @retval EFI_NOT_FOUND Target for the specified routing data 998 was not found. 999 **/ 1000 EFI_STATUS 1001 EFIAPI 1002 Ip4FormRouteConfig ( 1003 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 1004 IN CONST EFI_STRING Configuration, 1005 OUT EFI_STRING *Progress 1006 ) 1007 { 1008 EFI_STATUS Status; 1009 UINTN BufferSize; 1010 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData; 1011 IP4_CONFIG2_INSTANCE *Ip4Config2Instance; 1012 IP4_FORM_CALLBACK_INFO *Private; 1013 1014 Status = EFI_SUCCESS; 1015 IfrFormNvData = NULL; 1016 1017 if (Configuration == NULL || Progress == NULL) { 1018 return EFI_INVALID_PARAMETER; 1019 } 1020 1021 *Progress = Configuration; 1022 1023 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This); 1024 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private); 1025 1026 // 1027 // Check Routing data in <ConfigHdr>. 1028 // 1029 if (HiiIsConfigHdrMatch (Configuration, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) { 1030 // 1031 // Convert buffer data to <ConfigResp> by helper function BlockToConfig() 1032 // 1033 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA)); 1034 if (IfrFormNvData == NULL) { 1035 return EFI_OUT_OF_RESOURCES; 1036 } 1037 1038 BufferSize = 0; 1039 1040 Status = gHiiConfigRouting->ConfigToBlock ( 1041 gHiiConfigRouting, 1042 Configuration, 1043 (UINT8 *) IfrFormNvData, 1044 &BufferSize, 1045 Progress 1046 ); 1047 if (Status != EFI_BUFFER_TOO_SMALL) { 1048 return Status; 1049 } 1050 1051 Status = gHiiConfigRouting->ConfigToBlock ( 1052 gHiiConfigRouting, 1053 Configuration, 1054 (UINT8 *) IfrFormNvData, 1055 &BufferSize, 1056 Progress 1057 ); 1058 if (!EFI_ERROR (Status)) { 1059 Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Ip4Config2Instance); 1060 } 1061 1062 FreePool (IfrFormNvData); 1063 } else { 1064 return EFI_NOT_FOUND; 1065 } 1066 1067 return Status; 1068 1069 } 1070 1071 /** 1072 This function is called to provide results data to the driver. 1073 This data consists of a unique key that is used to identify 1074 which data is either being passed back or being asked for. 1075 1076 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 1077 @param[in] Action Specifies the type of action taken by the browser. 1078 @param[in] QuestionId A unique value which is sent to the original 1079 exporting driver so that it can identify the type 1080 of data to expect. The format of the data tends to 1081 vary based on the opcode that enerated the callback. 1082 @param[in] Type The type of value for the question. 1083 @param[in] Value A pointer to the data being sent to the original 1084 exporting driver. 1085 @param[out] ActionRequest On return, points to the action requested by the 1086 callback function. 1087 1088 @retval EFI_SUCCESS The callback successfully handled the action. 1089 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the 1090 variable and its data. 1091 @retval EFI_DEVICE_ERROR The variable could not be saved. 1092 @retval EFI_UNSUPPORTED The specified Action is not supported by the 1093 callback.Currently not implemented. 1094 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. 1095 @retval Others Other errors as indicated. 1096 1097 **/ 1098 EFI_STATUS 1099 EFIAPI 1100 Ip4FormCallback ( 1101 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 1102 IN EFI_BROWSER_ACTION Action, 1103 IN EFI_QUESTION_ID QuestionId, 1104 IN UINT8 Type, 1105 IN EFI_IFR_TYPE_VALUE *Value, 1106 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest 1107 ) 1108 { 1109 EFI_STATUS Status; 1110 IP4_CONFIG2_INSTANCE *Instance; 1111 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData; 1112 IP4_FORM_CALLBACK_INFO *Private; 1113 1114 EFI_IP_ADDRESS StationAddress; 1115 EFI_IP_ADDRESS SubnetMask; 1116 EFI_IP_ADDRESS Gateway; 1117 IP4_ADDR Ip; 1118 EFI_IPv4_ADDRESS *DnsAddress; 1119 UINTN DnsCount; 1120 UINTN Index; 1121 EFI_INPUT_KEY Key; 1122 1123 IfrFormNvData = NULL; 1124 DnsCount = 0; 1125 DnsAddress = NULL; 1126 1127 if (Action == EFI_BROWSER_ACTION_CHANGED) { 1128 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This); 1129 Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private); 1130 1131 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA)); 1132 if (IfrFormNvData == NULL) { 1133 return EFI_OUT_OF_RESOURCES; 1134 } 1135 1136 // 1137 // Retrieve uncommitted data from Browser 1138 // 1139 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *) IfrFormNvData)) { 1140 FreePool (IfrFormNvData); 1141 return EFI_NOT_FOUND; 1142 } 1143 1144 Status = EFI_SUCCESS; 1145 1146 switch (QuestionId) { 1147 case KEY_LOCAL_IP: 1148 Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4); 1149 if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) { 1150 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); 1151 Status = EFI_INVALID_PARAMETER; 1152 } 1153 break; 1154 1155 case KEY_SUBNET_MASK: 1156 Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4); 1157 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { 1158 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL); 1159 Status = EFI_INVALID_PARAMETER; 1160 } 1161 break; 1162 1163 case KEY_GATE_WAY: 1164 Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4); 1165 if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST(NTOHL(Gateway.Addr[0]))) { 1166 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); 1167 Status = EFI_INVALID_PARAMETER; 1168 } 1169 break; 1170 1171 case KEY_DNS: 1172 Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount); 1173 if (!EFI_ERROR (Status) && DnsCount > 0) { 1174 for (Index = 0; Index < DnsCount; Index ++) { 1175 CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR)); 1176 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) { 1177 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); 1178 Status = EFI_INVALID_PARAMETER; 1179 break; 1180 } 1181 } 1182 } else { 1183 if (EFI_ERROR (Status)) { 1184 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL); 1185 } 1186 } 1187 1188 if(DnsAddress != NULL) { 1189 FreePool(DnsAddress); 1190 } 1191 break; 1192 1193 case KEY_SAVE_CHANGES: 1194 Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance); 1195 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; 1196 break; 1197 1198 default: 1199 break; 1200 } 1201 1202 FreePool (IfrFormNvData); 1203 1204 return Status; 1205 } 1206 1207 // 1208 // All other action return unsupported. 1209 // 1210 return EFI_UNSUPPORTED; 1211 } 1212 1213 /** 1214 Install HII Config Access protocol for network device and allocate resource. 1215 1216 @param[in, out] Instance The IP4 config2 Instance. 1217 1218 @retval EFI_SUCCESS The HII Config Access protocol is installed. 1219 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 1220 @retval Others Other errors as indicated. 1221 1222 **/ 1223 EFI_STATUS 1224 Ip4Config2FormInit ( 1225 IN OUT IP4_CONFIG2_INSTANCE *Instance 1226 ) 1227 { 1228 EFI_STATUS Status; 1229 IP4_SERVICE *IpSb; 1230 IP4_FORM_CALLBACK_INFO *CallbackInfo; 1231 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; 1232 VENDOR_DEVICE_PATH VendorDeviceNode; 1233 EFI_SERVICE_BINDING_PROTOCOL *MnpSb; 1234 CHAR16 *MacString; 1235 CHAR16 MenuString[128]; 1236 CHAR16 PortString[128]; 1237 CHAR16 *OldMenuString; 1238 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; 1239 1240 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); 1241 ASSERT (IpSb != NULL); 1242 1243 CallbackInfo = &Instance->CallbackInfo; 1244 1245 CallbackInfo->Signature = IP4_FORM_CALLBACK_INFO_SIGNATURE; 1246 1247 Status = gBS->HandleProtocol ( 1248 IpSb->Controller, 1249 &gEfiDevicePathProtocolGuid, 1250 (VOID **) &ParentDevicePath 1251 ); 1252 if (EFI_ERROR (Status)) { 1253 return Status; 1254 } 1255 1256 // 1257 // Construct device path node for EFI HII Config Access protocol, 1258 // which consists of controller physical device path and one hardware 1259 // vendor guid node. 1260 // 1261 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH)); 1262 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH; 1263 VendorDeviceNode.Header.SubType = HW_VENDOR_DP; 1264 1265 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid); 1266 1267 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH)); 1268 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode ( 1269 ParentDevicePath, 1270 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode 1271 ); 1272 if (CallbackInfo->HiiVendorDevicePath == NULL) { 1273 Status = EFI_OUT_OF_RESOURCES; 1274 goto Error; 1275 } 1276 1277 ConfigAccess = &CallbackInfo->HiiConfigAccessProtocol; 1278 ConfigAccess->ExtractConfig = Ip4FormExtractConfig; 1279 ConfigAccess->RouteConfig = Ip4FormRouteConfig; 1280 ConfigAccess->Callback = Ip4FormCallback; 1281 1282 // 1283 // Install Device Path Protocol and Config Access protocol on new handle 1284 // 1285 Status = gBS->InstallMultipleProtocolInterfaces ( 1286 &CallbackInfo->ChildHandle, 1287 &gEfiDevicePathProtocolGuid, 1288 CallbackInfo->HiiVendorDevicePath, 1289 &gEfiHiiConfigAccessProtocolGuid, 1290 ConfigAccess, 1291 NULL 1292 ); 1293 1294 if (!EFI_ERROR (Status)) { 1295 // 1296 // Open the Parent Handle for the child 1297 // 1298 Status = gBS->OpenProtocol ( 1299 IpSb->Controller, 1300 &gEfiManagedNetworkServiceBindingProtocolGuid, 1301 (VOID **) &MnpSb, 1302 IpSb->Image, 1303 CallbackInfo->ChildHandle, 1304 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 1305 ); 1306 } 1307 1308 if (EFI_ERROR (Status)) { 1309 goto Error; 1310 } 1311 1312 // 1313 // Publish our HII data 1314 // 1315 CallbackInfo->RegisteredHandle = HiiAddPackages ( 1316 &gIp4Config2NvDataGuid, 1317 CallbackInfo->ChildHandle, 1318 Ip4DxeStrings, 1319 Ip4Config2Bin, 1320 NULL 1321 ); 1322 if (CallbackInfo->RegisteredHandle == NULL) { 1323 Status = EFI_OUT_OF_RESOURCES; 1324 goto Error; 1325 } 1326 1327 // 1328 // Append MAC string in the menu help string and tile help string 1329 // 1330 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString); 1331 if (!EFI_ERROR (Status)) { 1332 OldMenuString = HiiGetString ( 1333 CallbackInfo->RegisteredHandle, 1334 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP), 1335 NULL 1336 ); 1337 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString); 1338 HiiSetString ( 1339 CallbackInfo->RegisteredHandle, 1340 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP), 1341 MenuString, 1342 NULL 1343 ); 1344 1345 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString); 1346 HiiSetString ( 1347 CallbackInfo->RegisteredHandle, 1348 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP), 1349 PortString, 1350 NULL 1351 ); 1352 1353 FreePool (MacString); 1354 FreePool (OldMenuString); 1355 1356 return EFI_SUCCESS; 1357 } 1358 1359 Error: 1360 Ip4Config2FormUnload (Instance); 1361 return Status; 1362 } 1363 1364 /** 1365 Uninstall the HII Config Access protocol for network devices and free up the resources. 1366 1367 @param[in, out] Instance The IP4 config2 instance to unload a form. 1368 1369 **/ 1370 VOID 1371 Ip4Config2FormUnload ( 1372 IN OUT IP4_CONFIG2_INSTANCE *Instance 1373 ) 1374 { 1375 IP4_SERVICE *IpSb; 1376 IP4_FORM_CALLBACK_INFO *CallbackInfo; 1377 IP4_CONFIG2_NVDATA *Ip4NvData; 1378 1379 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); 1380 ASSERT (IpSb != NULL); 1381 1382 CallbackInfo = &Instance->CallbackInfo; 1383 1384 if (CallbackInfo->ChildHandle != NULL) { 1385 // 1386 // Close the child handle 1387 // 1388 gBS->CloseProtocol ( 1389 IpSb->Controller, 1390 &gEfiManagedNetworkServiceBindingProtocolGuid, 1391 IpSb->Image, 1392 CallbackInfo->ChildHandle 1393 ); 1394 1395 // 1396 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL 1397 // 1398 gBS->UninstallMultipleProtocolInterfaces ( 1399 CallbackInfo->ChildHandle, 1400 &gEfiDevicePathProtocolGuid, 1401 CallbackInfo->HiiVendorDevicePath, 1402 &gEfiHiiConfigAccessProtocolGuid, 1403 &CallbackInfo->HiiConfigAccessProtocol, 1404 NULL 1405 ); 1406 } 1407 1408 if (CallbackInfo->HiiVendorDevicePath != NULL) { 1409 FreePool (CallbackInfo->HiiVendorDevicePath); 1410 } 1411 1412 if (CallbackInfo->RegisteredHandle != NULL) { 1413 // 1414 // Remove HII package list 1415 // 1416 HiiRemovePackages (CallbackInfo->RegisteredHandle); 1417 } 1418 1419 Ip4NvData = &Instance->Ip4NvData; 1420 1421 if(Ip4NvData->ManualAddress != NULL) { 1422 FreePool(Ip4NvData->ManualAddress); 1423 } 1424 1425 if(Ip4NvData->GatewayAddress != NULL) { 1426 FreePool(Ip4NvData->GatewayAddress); 1427 } 1428 1429 if(Ip4NvData->DnsAddress != NULL) { 1430 FreePool(Ip4NvData->DnsAddress); 1431 } 1432 1433 Ip4NvData->ManualAddressCount = 0; 1434 Ip4NvData->GatewayAddressCount = 0; 1435 Ip4NvData->DnsAddressCount = 0; 1436 } 1437