2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 CHAR16 mIp4Config2StorageName
[] = L
"IP4_CONFIG2_IFR_NVDATA";
14 Calculate the prefix length of the IPv4 subnet mask.
16 @param[in] SubnetMask The IPv4 subnet mask.
18 @return The prefix length of the subnet mask.
19 @retval 0 Other errors as indicated.
23 GetSubnetMaskPrefixLength (
24 IN EFI_IPv4_ADDRESS
*SubnetMask
31 // The SubnetMask is in network byte order.
33 ReverseMask
= SwapBytes32 (*(UINT32
*)&SubnetMask
[0]);
38 ReverseMask
= ~ReverseMask
;
40 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
46 while (ReverseMask
!= 0) {
47 ReverseMask
= ReverseMask
>> 1;
51 return (UINT8
)(32 - Len
);
55 Convert the decimal dotted IPv4 address into the binary IPv4 address.
57 @param[in] Str The UNICODE string.
58 @param[out] Ip The storage to return the IPv4 address.
60 @retval EFI_SUCCESS The binary IP address is returned in Ip.
61 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
67 OUT EFI_IPv4_ADDRESS
*Ip
75 while (*Str
!= L
'\0') {
77 return EFI_INVALID_PARAMETER
;
81 while ((*Str
>= L
'0') && (*Str
<= L
'9')) {
82 Number
= Number
* 10 + (*Str
- L
'0');
87 return EFI_INVALID_PARAMETER
;
90 Ip
->Addr
[Index
] = (UINT8
)Number
;
92 if ((*Str
!= L
'\0') && (*Str
!= L
'.')) {
94 // The current character should be either the NULL terminator or
97 return EFI_INVALID_PARAMETER
;
102 // Skip the delimiter.
111 return EFI_INVALID_PARAMETER
;
118 Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.
120 @param[in] Str The UNICODE string contains IPv4 addresses.
121 @param[out] PtrIpList The storage to return the IPv4 address list.
122 @param[out] IpCount The size of the IPv4 address list.
124 @retval EFI_SUCCESS The binary IP address list is returned in PtrIpList.
125 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.
126 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
130 Ip4Config2StrToIpList (
132 OUT EFI_IPv4_ADDRESS
**PtrIpList
,
144 EndIndex
= BeginIndex
;
158 // Get the number of Ip.
160 while (*(Str
+ Index
) != L
'\0') {
161 if (*(Str
+ Index
) == L
' ') {
178 // Allocate buffer for IpList.
180 *PtrIpList
= AllocateZeroPool (*IpCount
* sizeof (EFI_IPv4_ADDRESS
));
181 if (*PtrIpList
== NULL
) {
182 return EFI_OUT_OF_RESOURCES
;
186 // Get IpList from Str.
189 while (*(Str
+ Index
) != L
'\0') {
190 if (*(Str
+ Index
) == L
' ') {
192 StrTemp
= AllocateZeroPool ((EndIndex
- BeginIndex
+ 1) * sizeof (CHAR16
));
193 if (StrTemp
== NULL
) {
194 FreePool (*PtrIpList
);
197 return EFI_OUT_OF_RESOURCES
;
200 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof (CHAR16
));
201 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
203 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
205 FreePool (*PtrIpList
);
208 return EFI_INVALID_PARAMETER
;
211 BeginIndex
= EndIndex
;
227 if (*(Str
+ Index
) == L
'\0') {
229 StrTemp
= AllocateZeroPool ((EndIndex
- BeginIndex
+ 1) * sizeof (CHAR16
));
230 if (StrTemp
== NULL
) {
231 FreePool (*PtrIpList
);
234 return EFI_OUT_OF_RESOURCES
;
237 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof (CHAR16
));
238 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
240 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
242 FreePool (*PtrIpList
);
245 return EFI_INVALID_PARAMETER
;
257 Convert the IPv4 address into a dotted string.
259 @param[in] Ip The IPv4 address.
260 @param[out] Str The dotted IP string.
265 IN EFI_IPv4_ADDRESS
*Ip
,
271 2 * IP4_STR_MAX_SIZE
,
281 Convert the IPv4 address list into string consists of several decimal
282 dotted IPv4 addresses separated by space.
284 @param[in] Ip The IPv4 address list.
285 @param[in] IpCount The size of IPv4 address list.
286 @param[out] Str The string contains several decimal dotted
287 IPv4 addresses separated by space.
289 @retval EFI_SUCCESS Operation is success.
290 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.
294 Ip4Config2IpListToStr (
295 IN EFI_IPv4_ADDRESS
*Ip
,
304 EFI_IPv4_ADDRESS
*TempIp
;
312 for (Index
= 0; Index
< IpCount
; Index
++) {
314 if (TempStr
== NULL
) {
315 TempStr
= AllocateZeroPool (2 * IP4_STR_MAX_SIZE
);
316 if (TempStr
== NULL
) {
317 return EFI_OUT_OF_RESOURCES
;
323 2 * IP4_STR_MAX_SIZE
,
331 for (TemIndex
= 0; TemIndex
< IP4_STR_MAX_SIZE
; TemIndex
++) {
332 if (*(TempStr
+ TemIndex
) == L
'\0') {
333 if (Index
== IpCount
- 1) {
334 Str
[StrIndex
++] = L
'\0';
336 Str
[StrIndex
++] = L
' ';
341 Str
[StrIndex
++] = *(TempStr
+ TemIndex
);
346 if (TempStr
!= NULL
) {
354 The notify function of create event when performing a manual configuration.
356 @param[in] Event The pointer of Event.
357 @param[in] Context The pointer of Context.
362 Ip4Config2ManualAddressNotify (
367 *((BOOLEAN
*)Context
) = TRUE
;
371 Convert the network configuration data into the IFR data.
373 @param[in] Instance The IP4 config2 instance.
374 @param[in, out] IfrNvData The IFR nv data.
376 @retval EFI_SUCCESS The configure parameter to IFR data was
378 @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not available.
379 @retval Others Other errors as indicated.
383 Ip4Config2ConvertConfigNvDataToIfrNvData (
384 IN IP4_CONFIG2_INSTANCE
*Instance
,
385 IN OUT IP4_CONFIG2_IFR_NVDATA
*IfrNvData
389 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
390 EFI_IP4_CONFIG2_INTERFACE_INFO
*Ip4Info
;
391 EFI_IP4_CONFIG2_POLICY Policy
;
394 EFI_IPv4_ADDRESS GatewayAddress
;
398 EFI_IPv4_ADDRESS
*DnsAddress
;
400 Status
= EFI_SUCCESS
;
401 Ip4Config2
= &Instance
->Ip4Config2
;
404 GatewaySize
= sizeof (EFI_IPv4_ADDRESS
);
406 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
407 return EFI_INVALID_PARAMETER
;
410 NET_CHECK_SIGNATURE (Instance
, IP4_CONFIG2_INSTANCE_SIGNATURE
);
412 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
414 if (IpSb
->DefaultInterface
->Configured
) {
415 IfrNvData
->Configure
= 1;
417 IfrNvData
->Configure
= 0;
422 // Get the Policy info.
424 DataSize
= sizeof (EFI_IP4_CONFIG2_POLICY
);
425 Status
= Ip4Config2
->GetData (
427 Ip4Config2DataTypePolicy
,
431 if (EFI_ERROR (Status
)) {
435 if (Policy
== Ip4Config2PolicyStatic
) {
436 IfrNvData
->DhcpEnable
= FALSE
;
437 } else if (Policy
== Ip4Config2PolicyDhcp
) {
438 IfrNvData
->DhcpEnable
= TRUE
;
443 // Get the interface info.
446 Status
= Ip4Config2
->GetData (
448 Ip4Config2DataTypeInterfaceInfo
,
452 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
456 Ip4Info
= AllocateZeroPool (DataSize
);
457 if (Ip4Info
== NULL
) {
458 Status
= EFI_OUT_OF_RESOURCES
;
462 Status
= Ip4Config2
->GetData (
464 Ip4Config2DataTypeInterfaceInfo
,
468 if (EFI_ERROR (Status
)) {
473 // Get the Gateway info.
475 Status
= Ip4Config2
->GetData (
477 Ip4Config2DataTypeGateway
,
481 if (EFI_ERROR (Status
)) {
489 Status
= Ip4Config2
->GetData (
491 Ip4Config2DataTypeDnsServer
,
495 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
499 DnsCount
= (UINT32
)(DnsSize
/ sizeof (EFI_IPv4_ADDRESS
));
502 DnsAddress
= AllocateZeroPool (DnsSize
);
503 if (DnsAddress
== NULL
) {
504 Status
= EFI_OUT_OF_RESOURCES
;
508 Status
= Ip4Config2
->GetData (
510 Ip4Config2DataTypeDnsServer
,
514 if (EFI_ERROR (Status
)) {
519 Ip4Config2IpToStr (&Ip4Info
->StationAddress
, IfrNvData
->StationAddress
);
520 Ip4Config2IpToStr (&Ip4Info
->SubnetMask
, IfrNvData
->SubnetMask
);
521 Ip4Config2IpToStr (&GatewayAddress
, IfrNvData
->GatewayAddress
);
522 Status
= Ip4Config2IpListToStr (DnsAddress
, DnsCount
, IfrNvData
->DnsAddress
);
526 if (DnsAddress
!= NULL
) {
527 FreePool (DnsAddress
);
530 if (Ip4Info
!= NULL
) {
538 Convert the IFR data into the network configuration data and set the IP
539 configure parameters for the NIC.
541 @param[in] IfrFormNvData The IFR NV data.
542 @param[in, out] Instance The IP4 config2 instance.
544 @retval EFI_SUCCESS The configure parameter for this NIC was
546 @retval EFI_INVALID_PARAMETER The address information for setting is invalid.
547 @retval Others Other errors as indicated.
551 Ip4Config2ConvertIfrNvDataToConfigNvData (
552 IN IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
,
553 IN OUT IP4_CONFIG2_INSTANCE
*Instance
557 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Cfg2
;
558 IP4_CONFIG2_NVDATA
*Ip4NvData
;
560 EFI_IP_ADDRESS StationAddress
;
561 EFI_IP_ADDRESS SubnetMask
;
562 EFI_IP_ADDRESS Gateway
;
564 EFI_IPv4_ADDRESS
*DnsAddress
;
568 EFI_EVENT TimeoutEvent
;
569 EFI_EVENT SetAddressEvent
;
574 Status
= EFI_SUCCESS
;
575 Ip4Cfg2
= &Instance
->Ip4Config2
;
576 Ip4NvData
= &Instance
->Ip4NvData
;
582 SetAddressEvent
= NULL
;
584 if ((Instance
== NULL
) || (IfrFormNvData
== NULL
)) {
585 return EFI_INVALID_PARAMETER
;
588 if (IfrFormNvData
->Configure
!= TRUE
) {
592 if (IfrFormNvData
->DhcpEnable
== TRUE
) {
593 Ip4NvData
->Policy
= Ip4Config2PolicyDhcp
;
595 Status
= Ip4Cfg2
->SetData (
597 Ip4Config2DataTypePolicy
,
598 sizeof (EFI_IP4_CONFIG2_POLICY
),
601 if (EFI_ERROR (Status
)) {
606 // Get Ip4NvData from IfrFormNvData if it is valid.
608 Ip4NvData
->Policy
= Ip4Config2PolicyStatic
;
610 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
611 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
612 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
613 return EFI_INVALID_PARAMETER
;
616 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
617 if (EFI_ERROR (Status
) ||
618 ((SubnetMask
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (StationAddress
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0]))) ||
619 !Ip4StationAddressValid (NTOHL (StationAddress
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0])))
621 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
622 return EFI_INVALID_PARAMETER
;
625 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
626 if (EFI_ERROR (Status
) ||
627 ((Gateway
.Addr
[0] != 0) && (SubnetMask
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0]))))
629 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
630 return EFI_INVALID_PARAMETER
;
633 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
634 if (!EFI_ERROR (Status
) && (DnsCount
> 0)) {
635 for (Index
= 0; Index
< DnsCount
; Index
++) {
636 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
637 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
638 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
639 FreePool (DnsAddress
);
640 return EFI_INVALID_PARAMETER
;
644 if (EFI_ERROR (Status
)) {
645 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
649 if (Ip4NvData
->ManualAddress
!= NULL
) {
650 FreePool (Ip4NvData
->ManualAddress
);
653 Ip4NvData
->ManualAddressCount
= 1;
654 Ip4NvData
->ManualAddress
= AllocateZeroPool (sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
));
655 if (Ip4NvData
->ManualAddress
== NULL
) {
656 if (DnsAddress
!= NULL
) {
657 FreePool (DnsAddress
);
660 return EFI_OUT_OF_RESOURCES
;
663 CopyMem (&Ip4NvData
->ManualAddress
->Address
, &StationAddress
.v4
, sizeof (EFI_IPv4_ADDRESS
));
664 CopyMem (&Ip4NvData
->ManualAddress
->SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
666 if (Ip4NvData
->GatewayAddress
!= NULL
) {
667 FreePool (Ip4NvData
->GatewayAddress
);
670 Ip4NvData
->GatewayAddressCount
= 1;
671 Ip4NvData
->GatewayAddress
= AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS
));
672 if (Ip4NvData
->GatewayAddress
== NULL
) {
673 if (DnsAddress
!= NULL
) {
674 FreePool (DnsAddress
);
677 return EFI_OUT_OF_RESOURCES
;
680 CopyMem (Ip4NvData
->GatewayAddress
, &Gateway
.v4
, sizeof (EFI_IPv4_ADDRESS
));
682 if (Ip4NvData
->DnsAddress
!= NULL
) {
683 FreePool (Ip4NvData
->DnsAddress
);
686 Ip4NvData
->DnsAddressCount
= (UINT32
)DnsCount
;
687 Ip4NvData
->DnsAddress
= DnsAddress
;
690 // Setting Ip4NvData.
692 Status
= Ip4Cfg2
->SetData (
694 Ip4Config2DataTypePolicy
,
695 sizeof (EFI_IP4_CONFIG2_POLICY
),
698 if (EFI_ERROR (Status
)) {
703 // Create events & timers for asynchronous settings.
705 Status
= gBS
->CreateEvent (
712 if (EFI_ERROR (Status
)) {
713 return EFI_OUT_OF_RESOURCES
;
716 Status
= gBS
->CreateEvent (
719 Ip4Config2ManualAddressNotify
,
723 if (EFI_ERROR (Status
)) {
729 Status
= Ip4Cfg2
->RegisterDataNotify (
731 Ip4Config2DataTypeManualAddress
,
734 if (EFI_ERROR (Status
)) {
739 // Set ManualAddress.
741 DataSize
= Ip4NvData
->ManualAddressCount
* sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
);
742 Status
= Ip4Cfg2
->SetData (
744 Ip4Config2DataTypeManualAddress
,
746 (VOID
*)Ip4NvData
->ManualAddress
749 if (Status
== EFI_NOT_READY
) {
750 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
751 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
753 Status
= EFI_SUCCESS
;
759 Ip4Cfg2
->UnregisterDataNotify (
761 Ip4Config2DataTypeManualAddress
,
764 if (EFI_ERROR (Status
)) {
771 DataSize
= Ip4NvData
->GatewayAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
772 Status
= Ip4Cfg2
->SetData (
774 Ip4Config2DataTypeGateway
,
776 Ip4NvData
->GatewayAddress
778 if (EFI_ERROR (Status
)) {
783 // Set DNS addresses.
785 if ((Ip4NvData
->DnsAddressCount
> 0) && (Ip4NvData
->DnsAddress
!= NULL
)) {
786 DataSize
= Ip4NvData
->DnsAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
787 Status
= Ip4Cfg2
->SetData (
789 Ip4Config2DataTypeDnsServer
,
791 Ip4NvData
->DnsAddress
794 if (EFI_ERROR (Status
)) {
801 if (SetAddressEvent
!= NULL
) {
802 gBS
->CloseEvent (SetAddressEvent
);
805 if (TimeoutEvent
!= NULL
) {
806 gBS
->CloseEvent (TimeoutEvent
);
813 This function allows the caller to request the current
814 configuration for one or more named elements. The resulting
815 string is in <ConfigAltResp> format. Any and all alternative
816 configuration strings shall also be appended to the end of the
817 current configuration string. If they are, they must appear
818 after the current configuration. They must contain the same
819 routing (GUID, NAME, PATH) as the current configuration string.
820 They must have an additional description indicating the type of
821 alternative configuration the string represents,
822 "ALTCFG=<StringToken>". That <StringToken> (when
823 converted from Hex UNICODE to binary) is a reference to a
824 string in the associated string pack.
826 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
827 @param[in] Request A null-terminated Unicode string in
828 <ConfigRequest> format. Note that this
829 includes the routing information as well as
830 the configurable name / value pairs. It is
831 invalid for this string to be in
832 <MultiConfigRequest> format.
833 @param[out] Progress On return, points to a character in the
834 Request string. Points to the string's null
835 terminator if request was successful. Points
836 to the most recent "&" before the first
837 failing name / value pair (or the beginning
838 of the string if the failure is in the first
839 name / value pair) if the request was not
841 @param[out] Results A null-terminated Unicode string in
842 <ConfigAltResp> format which has all values
843 filled in for the names in the Request string.
844 String to be allocated by the called function.
846 @retval EFI_SUCCESS The Results string is filled with the
847 values corresponding to all requested
849 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
850 parts of the results that must be
851 stored awaiting possible future
853 @retval EFI_NOT_FOUND Routing data doesn't match any
854 known driver. Progress set to the
855 first character in the routing header.
856 Note: There is no requirement that the
857 driver validate the routing data. It
858 must skip the <ConfigHdr> in order to
860 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
861 to most recent & before the
862 error or the beginning of the
864 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
865 to the & before the name in
866 question.Currently not implemented.
870 Ip4FormExtractConfig (
871 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
872 IN CONST EFI_STRING Request
,
873 OUT EFI_STRING
*Progress
,
874 OUT EFI_STRING
*Results
878 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
879 IP4_FORM_CALLBACK_INFO
*Private
;
880 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
881 EFI_STRING ConfigRequestHdr
;
882 EFI_STRING ConfigRequest
;
883 BOOLEAN AllocatedRequest
;
884 EFI_STRING FormResult
;
888 if ((Progress
== NULL
) || (Results
== NULL
)) {
889 return EFI_INVALID_PARAMETER
;
892 Status
= EFI_SUCCESS
;
893 IfrFormNvData
= NULL
;
894 ConfigRequest
= NULL
;
897 AllocatedRequest
= FALSE
;
898 ConfigRequest
= Request
;
899 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
900 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private
);
901 BufferSize
= sizeof (IP4_CONFIG2_IFR_NVDATA
);
905 // Check Request data in <ConfigHdr>.
907 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
908 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
909 if (IfrFormNvData
== NULL
) {
910 return EFI_OUT_OF_RESOURCES
;
913 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance
, IfrFormNvData
);
915 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
917 // Request has no request element, construct full request string.
918 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
919 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
921 ConfigRequestHdr
= HiiConstructConfigHdr (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, Private
->ChildHandle
);
922 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
923 ConfigRequest
= AllocateZeroPool (Size
);
924 if (ConfigRequest
== NULL
) {
925 Status
= EFI_OUT_OF_RESOURCES
;
929 AllocatedRequest
= TRUE
;
931 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
932 FreePool (ConfigRequestHdr
);
936 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
938 Status
= gHiiConfigRouting
->BlockToConfig (
941 (UINT8
*)IfrFormNvData
,
947 FreePool (IfrFormNvData
);
950 // Free the allocated config request string.
952 if (AllocatedRequest
) {
953 FreePool (ConfigRequest
);
954 ConfigRequest
= NULL
;
957 if (EFI_ERROR (Status
)) {
962 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
963 *Results
= FormResult
;
965 return EFI_NOT_FOUND
;
970 // Set Progress string to the original request string.
972 if (Request
== NULL
) {
974 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
975 *Progress
= Request
+ StrLen (Request
);
982 This function applies changes in a driver's configuration.
983 Input is a Configuration, which has the routing data for this
984 driver followed by name / value configuration pairs. The driver
985 must apply those pairs to its configurable storage. If the
986 driver's configuration is stored in a linear block of data
987 and the driver's name / value pairs are in <BlockConfig>
988 format, it may use the ConfigToBlock helper function (above) to
989 simplify the job. Currently not implemented.
991 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
992 @param[in] Configuration A null-terminated Unicode string in
993 <ConfigString> format.
994 @param[out] Progress A pointer to a string filled in with the
995 offset of the most recent '&' before the
996 first failing name / value pair (or the
997 beginning of the string if the failure
998 is in the first name / value pair) or
999 the terminating NULL if all was
1002 @retval EFI_SUCCESS The results have been distributed or are
1003 awaiting distribution.
1004 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1005 parts of the results that must be
1006 stored awaiting possible future
1008 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1009 Results parameter would result
1010 in this type of error.
1011 @retval EFI_NOT_FOUND Target for the specified routing data
1016 Ip4FormRouteConfig (
1017 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1018 IN CONST EFI_STRING Configuration
,
1019 OUT EFI_STRING
*Progress
1024 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1025 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
1026 IP4_FORM_CALLBACK_INFO
*Private
;
1028 Status
= EFI_SUCCESS
;
1029 IfrFormNvData
= NULL
;
1031 if ((Configuration
== NULL
) || (Progress
== NULL
)) {
1032 return EFI_INVALID_PARAMETER
;
1035 *Progress
= Configuration
;
1037 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1038 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private
);
1041 // Check Routing data in <ConfigHdr>.
1043 if (HiiIsConfigHdrMatch (Configuration
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
1045 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1047 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1048 if (IfrFormNvData
== NULL
) {
1049 return EFI_OUT_OF_RESOURCES
;
1054 Status
= gHiiConfigRouting
->ConfigToBlock (
1057 (UINT8
*)IfrFormNvData
,
1061 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1065 Status
= gHiiConfigRouting
->ConfigToBlock (
1068 (UINT8
*)IfrFormNvData
,
1072 if (!EFI_ERROR (Status
)) {
1073 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Ip4Config2Instance
);
1076 FreePool (IfrFormNvData
);
1078 return EFI_NOT_FOUND
;
1085 This function is called to provide results data to the driver.
1086 This data consists of a unique key that is used to identify
1087 which data is either being passed back or being asked for.
1089 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1090 @param[in] Action Specifies the type of action taken by the browser.
1091 @param[in] QuestionId A unique value which is sent to the original
1092 exporting driver so that it can identify the type
1093 of data to expect. The format of the data tends to
1094 vary based on the opcode that enerated the callback.
1095 @param[in] Type The type of value for the question.
1096 @param[in] Value A pointer to the data being sent to the original
1098 @param[out] ActionRequest On return, points to the action requested by the
1101 @retval EFI_SUCCESS The callback successfully handled the action.
1102 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1103 variable and its data.
1104 @retval EFI_DEVICE_ERROR The variable could not be saved.
1105 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1106 callback. Currently not implemented.
1107 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
1108 @retval Others Other errors as indicated.
1114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1115 IN EFI_BROWSER_ACTION Action
,
1116 IN EFI_QUESTION_ID QuestionId
,
1118 IN EFI_IFR_TYPE_VALUE
*Value
,
1119 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1123 IP4_CONFIG2_INSTANCE
*Instance
;
1124 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1125 IP4_FORM_CALLBACK_INFO
*Private
;
1127 EFI_IP_ADDRESS StationAddress
;
1128 EFI_IP_ADDRESS SubnetMask
;
1129 EFI_IP_ADDRESS Gateway
;
1131 EFI_IPv4_ADDRESS
*DnsAddress
;
1136 IfrFormNvData
= NULL
;
1140 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1141 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1142 Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private
);
1144 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1145 if (IfrFormNvData
== NULL
) {
1146 return EFI_OUT_OF_RESOURCES
;
1150 // Retrieve uncommitted data from Browser
1152 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, sizeof (IP4_CONFIG2_IFR_NVDATA
), (UINT8
*)IfrFormNvData
)) {
1153 FreePool (IfrFormNvData
);
1154 return EFI_NOT_FOUND
;
1157 Status
= EFI_SUCCESS
;
1159 switch (QuestionId
) {
1161 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
1162 if (EFI_ERROR (Status
) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress
.Addr
[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress
.Addr
[0]))) {
1163 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
1164 Status
= EFI_INVALID_PARAMETER
;
1169 case KEY_SUBNET_MASK
:
1170 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
1171 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
1172 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
1173 Status
= EFI_INVALID_PARAMETER
;
1179 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
1180 if (EFI_ERROR (Status
) || IP4_IS_LOCAL_BROADCAST (NTOHL (Gateway
.Addr
[0]))) {
1181 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
1182 Status
= EFI_INVALID_PARAMETER
;
1188 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
1189 if (!EFI_ERROR (Status
) && (DnsCount
> 0)) {
1190 for (Index
= 0; Index
< DnsCount
; Index
++) {
1191 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
1192 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
1193 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1194 Status
= EFI_INVALID_PARAMETER
;
1199 if (EFI_ERROR (Status
)) {
1200 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1204 if (DnsAddress
!= NULL
) {
1205 FreePool (DnsAddress
);
1210 case KEY_SAVE_CHANGES
:
1211 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Instance
);
1212 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1219 FreePool (IfrFormNvData
);
1225 // All other action return unsupported.
1227 return EFI_UNSUPPORTED
;
1231 Install HII Config Access protocol for network device and allocate resource.
1233 @param[in, out] Instance The IP4 config2 Instance.
1235 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1236 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1237 @retval Others Other errors as indicated.
1241 Ip4Config2FormInit (
1242 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1247 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1248 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1249 VENDOR_DEVICE_PATH VendorDeviceNode
;
1250 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1252 CHAR16 MenuString
[128];
1253 CHAR16 PortString
[128];
1254 CHAR16
*OldMenuString
;
1255 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1257 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1258 ASSERT (IpSb
!= NULL
);
1260 CallbackInfo
= &Instance
->CallbackInfo
;
1262 CallbackInfo
->Signature
= IP4_FORM_CALLBACK_INFO_SIGNATURE
;
1264 Status
= gBS
->HandleProtocol (
1266 &gEfiDevicePathProtocolGuid
,
1267 (VOID
**)&ParentDevicePath
1269 if (EFI_ERROR (Status
)) {
1274 // Construct device path node for EFI HII Config Access protocol,
1275 // which consists of controller physical device path and one hardware
1276 // vendor guid node.
1278 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1279 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1280 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1282 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1284 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1285 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1287 (EFI_DEVICE_PATH_PROTOCOL
*)&VendorDeviceNode
1289 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1290 Status
= EFI_OUT_OF_RESOURCES
;
1294 ConfigAccess
= &CallbackInfo
->HiiConfigAccessProtocol
;
1295 ConfigAccess
->ExtractConfig
= Ip4FormExtractConfig
;
1296 ConfigAccess
->RouteConfig
= Ip4FormRouteConfig
;
1297 ConfigAccess
->Callback
= Ip4FormCallback
;
1300 // Install Device Path Protocol and Config Access protocol on new handle
1302 Status
= gBS
->InstallMultipleProtocolInterfaces (
1303 &CallbackInfo
->ChildHandle
,
1304 &gEfiDevicePathProtocolGuid
,
1305 CallbackInfo
->HiiVendorDevicePath
,
1306 &gEfiHiiConfigAccessProtocolGuid
,
1311 if (!EFI_ERROR (Status
)) {
1313 // Open the Parent Handle for the child
1315 Status
= gBS
->OpenProtocol (
1317 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1320 CallbackInfo
->ChildHandle
,
1321 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1325 if (EFI_ERROR (Status
)) {
1330 // Publish our HII data
1332 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1333 &gIp4Config2NvDataGuid
,
1334 CallbackInfo
->ChildHandle
,
1339 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1340 Status
= EFI_OUT_OF_RESOURCES
;
1345 // Append MAC string in the menu help string and tile help string
1347 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1348 if (!EFI_ERROR (Status
)) {
1349 OldMenuString
= HiiGetString (
1350 CallbackInfo
->RegisteredHandle
,
1351 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1354 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
1356 CallbackInfo
->RegisteredHandle
,
1357 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1362 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
1364 CallbackInfo
->RegisteredHandle
,
1365 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
),
1370 FreePool (MacString
);
1371 FreePool (OldMenuString
);
1377 Ip4Config2FormUnload (Instance
);
1382 Uninstall the HII Config Access protocol for network devices and free up the resources.
1384 @param[in, out] Instance The IP4 config2 instance to unload a form.
1388 Ip4Config2FormUnload (
1389 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1393 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1394 IP4_CONFIG2_NVDATA
*Ip4NvData
;
1396 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1397 ASSERT (IpSb
!= NULL
);
1399 CallbackInfo
= &Instance
->CallbackInfo
;
1401 if (CallbackInfo
->ChildHandle
!= NULL
) {
1403 // Close the child handle
1405 gBS
->CloseProtocol (
1407 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1409 CallbackInfo
->ChildHandle
1413 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1415 gBS
->UninstallMultipleProtocolInterfaces (
1416 CallbackInfo
->ChildHandle
,
1417 &gEfiDevicePathProtocolGuid
,
1418 CallbackInfo
->HiiVendorDevicePath
,
1419 &gEfiHiiConfigAccessProtocolGuid
,
1420 &CallbackInfo
->HiiConfigAccessProtocol
,
1425 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
1426 FreePool (CallbackInfo
->HiiVendorDevicePath
);
1429 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
1431 // Remove HII package list
1433 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
1436 Ip4NvData
= &Instance
->Ip4NvData
;
1438 if (Ip4NvData
->ManualAddress
!= NULL
) {
1439 FreePool (Ip4NvData
->ManualAddress
);
1442 if (Ip4NvData
->GatewayAddress
!= NULL
) {
1443 FreePool (Ip4NvData
->GatewayAddress
);
1446 if (Ip4NvData
->DnsAddress
!= NULL
) {
1447 FreePool (Ip4NvData
->DnsAddress
);
1450 Ip4NvData
->ManualAddressCount
= 0;
1451 Ip4NvData
->GatewayAddressCount
= 0;
1452 Ip4NvData
->DnsAddressCount
= 0;