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') {
78 return EFI_INVALID_PARAMETER
;
82 while ((*Str
>= L
'0') && (*Str
<= L
'9')) {
83 Number
= Number
* 10 + (*Str
- L
'0');
88 return EFI_INVALID_PARAMETER
;
91 Ip
->Addr
[Index
] = (UINT8
) Number
;
93 if ((*Str
!= L
'\0') && (*Str
!= L
'.')) {
95 // The current character should be either the NULL terminator or
98 return EFI_INVALID_PARAMETER
;
103 // Skip the delimiter.
112 return EFI_INVALID_PARAMETER
;
119 Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.
121 @param[in] Str The UNICODE string contains IPv4 addresses.
122 @param[out] PtrIpList The storage to return the IPv4 address list.
123 @param[out] IpCount The size of the IPv4 address list.
125 @retval EFI_SUCCESS The binary IP address list is returned in PtrIpList.
126 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.
127 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
131 Ip4Config2StrToIpList (
133 OUT EFI_IPv4_ADDRESS
**PtrIpList
,
145 EndIndex
= BeginIndex
;
159 // Get the number of Ip.
161 while (*(Str
+ Index
) != L
'\0') {
162 if (*(Str
+ Index
) == L
' ') {
179 // Allocate buffer for IpList.
181 *PtrIpList
= AllocateZeroPool(*IpCount
* sizeof(EFI_IPv4_ADDRESS
));
182 if (*PtrIpList
== NULL
) {
183 return EFI_OUT_OF_RESOURCES
;
187 // Get IpList from Str.
190 while (*(Str
+ Index
) != L
'\0') {
191 if (*(Str
+ Index
) == L
' ') {
193 StrTemp
= AllocateZeroPool((EndIndex
- BeginIndex
+ 1) * sizeof(CHAR16
));
194 if (StrTemp
== NULL
) {
195 FreePool(*PtrIpList
);
198 return EFI_OUT_OF_RESOURCES
;
201 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof(CHAR16
));
202 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
204 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
206 FreePool(*PtrIpList
);
209 return EFI_INVALID_PARAMETER
;
212 BeginIndex
= EndIndex
;
228 if (*(Str
+ Index
) == L
'\0') {
230 StrTemp
= AllocateZeroPool((EndIndex
- BeginIndex
+ 1) * sizeof(CHAR16
));
231 if (StrTemp
== NULL
) {
232 FreePool(*PtrIpList
);
235 return EFI_OUT_OF_RESOURCES
;
238 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof(CHAR16
));
239 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
241 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
243 FreePool(*PtrIpList
);
246 return EFI_INVALID_PARAMETER
;
258 Convert the IPv4 address into a dotted string.
260 @param[in] Ip The IPv4 address.
261 @param[out] Str The dotted IP string.
266 IN EFI_IPv4_ADDRESS
*Ip
,
272 2 * IP4_STR_MAX_SIZE
,
283 Convert the IPv4 address list into string consists of several decimal
284 dotted IPv4 addresses separated by space.
286 @param[in] Ip The IPv4 address list.
287 @param[in] IpCount The size of IPv4 address list.
288 @param[out] Str The string contains several decimal dotted
289 IPv4 addresses separated by space.
291 @retval EFI_SUCCESS Operation is success.
292 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.
296 Ip4Config2IpListToStr (
297 IN EFI_IPv4_ADDRESS
*Ip
,
306 EFI_IPv4_ADDRESS
*TempIp
;
314 for (Index
= 0; Index
< IpCount
; Index
++) {
316 if (TempStr
== NULL
) {
317 TempStr
= AllocateZeroPool(2 * IP4_STR_MAX_SIZE
);
318 if (TempStr
== NULL
) {
319 return EFI_OUT_OF_RESOURCES
;
325 2 * IP4_STR_MAX_SIZE
,
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';
338 Str
[StrIndex
++] = L
' ';
342 Str
[StrIndex
++] = *(TempStr
+ TemIndex
);
347 if (TempStr
!= NULL
) {
355 The notify function of create event when performing a manual configuration.
357 @param[in] Event The pointer of Event.
358 @param[in] Context The pointer of Context.
363 Ip4Config2ManualAddressNotify (
368 *((BOOLEAN
*) Context
) = TRUE
;
372 Convert the network configuration data into the IFR data.
374 @param[in] Instance The IP4 config2 instance.
375 @param[in, out] IfrNvData The IFR nv data.
377 @retval EFI_SUCCESS The configure parameter to IFR data was
379 @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not available.
380 @retval Others Other errors as indicated.
384 Ip4Config2ConvertConfigNvDataToIfrNvData (
385 IN IP4_CONFIG2_INSTANCE
*Instance
,
386 IN OUT IP4_CONFIG2_IFR_NVDATA
*IfrNvData
390 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
391 EFI_IP4_CONFIG2_INTERFACE_INFO
*Ip4Info
;
392 EFI_IP4_CONFIG2_POLICY Policy
;
395 EFI_IPv4_ADDRESS GatewayAddress
;
399 EFI_IPv4_ADDRESS
*DnsAddress
;
401 Status
= EFI_SUCCESS
;
402 Ip4Config2
= &Instance
->Ip4Config2
;
405 GatewaySize
= sizeof (EFI_IPv4_ADDRESS
);
407 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
408 return EFI_INVALID_PARAMETER
;
411 NET_CHECK_SIGNATURE (Instance
, IP4_CONFIG2_INSTANCE_SIGNATURE
);
413 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
415 if (IpSb
->DefaultInterface
->Configured
) {
416 IfrNvData
->Configure
= 1;
418 IfrNvData
->Configure
= 0;
423 // Get the Policy info.
425 DataSize
= sizeof (EFI_IP4_CONFIG2_POLICY
);
426 Status
= Ip4Config2
->GetData (
428 Ip4Config2DataTypePolicy
,
432 if (EFI_ERROR (Status
)) {
436 if (Policy
== Ip4Config2PolicyStatic
) {
437 IfrNvData
->DhcpEnable
= FALSE
;
438 } else if (Policy
== Ip4Config2PolicyDhcp
) {
439 IfrNvData
->DhcpEnable
= TRUE
;
444 // Get the interface info.
447 Status
= Ip4Config2
->GetData (
449 Ip4Config2DataTypeInterfaceInfo
,
453 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
457 Ip4Info
= AllocateZeroPool (DataSize
);
458 if (Ip4Info
== NULL
) {
459 Status
= EFI_OUT_OF_RESOURCES
;
463 Status
= Ip4Config2
->GetData (
465 Ip4Config2DataTypeInterfaceInfo
,
469 if (EFI_ERROR (Status
)) {
474 // Get the Gateway info.
476 Status
= Ip4Config2
->GetData (
478 Ip4Config2DataTypeGateway
,
482 if (EFI_ERROR (Status
)) {
490 Status
= Ip4Config2
->GetData (
492 Ip4Config2DataTypeDnsServer
,
496 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
500 DnsCount
= (UINT32
) (DnsSize
/ sizeof (EFI_IPv4_ADDRESS
));
503 DnsAddress
= AllocateZeroPool(DnsSize
);
504 if (DnsAddress
== NULL
) {
505 Status
= EFI_OUT_OF_RESOURCES
;
509 Status
= Ip4Config2
->GetData (
511 Ip4Config2DataTypeDnsServer
,
515 if (EFI_ERROR (Status
)) {
520 Ip4Config2IpToStr (&Ip4Info
->StationAddress
, IfrNvData
->StationAddress
);
521 Ip4Config2IpToStr (&Ip4Info
->SubnetMask
, IfrNvData
->SubnetMask
);
522 Ip4Config2IpToStr (&GatewayAddress
, IfrNvData
->GatewayAddress
);
523 Status
= Ip4Config2IpListToStr (DnsAddress
, DnsCount
, IfrNvData
->DnsAddress
);
527 if (DnsAddress
!= NULL
) {
528 FreePool(DnsAddress
);
531 if (Ip4Info
!= NULL
) {
539 Convert the IFR data into the network configuration data and set the IP
540 configure parameters for the NIC.
542 @param[in] IfrFormNvData The IFR NV data.
543 @param[in, out] Instance The IP4 config2 instance.
545 @retval EFI_SUCCESS The configure parameter for this NIC was
547 @retval EFI_INVALID_PARAMETER The address information for setting is invalid.
548 @retval Others Other errors as indicated.
552 Ip4Config2ConvertIfrNvDataToConfigNvData (
553 IN IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
,
554 IN OUT IP4_CONFIG2_INSTANCE
*Instance
558 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Cfg2
;
559 IP4_CONFIG2_NVDATA
*Ip4NvData
;
561 EFI_IP_ADDRESS StationAddress
;
562 EFI_IP_ADDRESS SubnetMask
;
563 EFI_IP_ADDRESS Gateway
;
565 EFI_IPv4_ADDRESS
*DnsAddress
;
569 EFI_EVENT TimeoutEvent
;
570 EFI_EVENT SetAddressEvent
;
575 Status
= EFI_SUCCESS
;
576 Ip4Cfg2
= &Instance
->Ip4Config2
;
577 Ip4NvData
= &Instance
->Ip4NvData
;
583 SetAddressEvent
= NULL
;
587 if (Instance
== NULL
|| IfrFormNvData
== NULL
) {
588 return EFI_INVALID_PARAMETER
;
591 if (IfrFormNvData
->Configure
!= TRUE
) {
595 if (IfrFormNvData
->DhcpEnable
== TRUE
) {
596 Ip4NvData
->Policy
= Ip4Config2PolicyDhcp
;
598 Status
= Ip4Cfg2
->SetData (
600 Ip4Config2DataTypePolicy
,
601 sizeof (EFI_IP4_CONFIG2_POLICY
),
604 if (EFI_ERROR(Status
)) {
609 // Get Ip4NvData from IfrFormNvData if it is valid.
611 Ip4NvData
->Policy
= Ip4Config2PolicyStatic
;
613 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
614 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
615 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
616 return EFI_INVALID_PARAMETER
;
619 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
620 if (EFI_ERROR (Status
) ||
621 (SubnetMask
.Addr
[0] != 0 && !NetIp4IsUnicast (NTOHL (StationAddress
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0]))) ||
622 !Ip4StationAddressValid (NTOHL (StationAddress
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0]))) {
623 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
624 return EFI_INVALID_PARAMETER
;
627 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
628 if (EFI_ERROR (Status
) ||
629 (Gateway
.Addr
[0] != 0 && SubnetMask
.Addr
[0] != 0 && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0])))) {
630 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
631 return EFI_INVALID_PARAMETER
;
634 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
635 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
636 for (Index
= 0; Index
< DnsCount
; Index
++) {
637 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
638 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
639 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
640 FreePool(DnsAddress
);
641 return EFI_INVALID_PARAMETER
;
645 if (EFI_ERROR (Status
)) {
646 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
650 if (Ip4NvData
->ManualAddress
!= NULL
) {
651 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
;
662 CopyMem(&Ip4NvData
->ManualAddress
->Address
, &StationAddress
.v4
, sizeof(EFI_IPv4_ADDRESS
));
663 CopyMem(&Ip4NvData
->ManualAddress
->SubnetMask
, &SubnetMask
.v4
, sizeof(EFI_IPv4_ADDRESS
));
665 if (Ip4NvData
->GatewayAddress
!= NULL
) {
666 FreePool(Ip4NvData
->GatewayAddress
);
668 Ip4NvData
->GatewayAddressCount
= 1;
669 Ip4NvData
->GatewayAddress
= AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS
));
670 if (Ip4NvData
->GatewayAddress
== NULL
) {
671 if (DnsAddress
!= NULL
) {
672 FreePool(DnsAddress
);
674 return EFI_OUT_OF_RESOURCES
;
676 CopyMem(Ip4NvData
->GatewayAddress
, &Gateway
.v4
, sizeof(EFI_IPv4_ADDRESS
));
678 if (Ip4NvData
->DnsAddress
!= NULL
) {
679 FreePool(Ip4NvData
->DnsAddress
);
681 Ip4NvData
->DnsAddressCount
= (UINT32
) DnsCount
;
682 Ip4NvData
->DnsAddress
= DnsAddress
;
685 // Setting Ip4NvData.
687 Status
= Ip4Cfg2
->SetData (
689 Ip4Config2DataTypePolicy
,
690 sizeof (EFI_IP4_CONFIG2_POLICY
),
693 if (EFI_ERROR(Status
)) {
698 // Create events & timers for asynchronous settings.
700 Status
= gBS
->CreateEvent (
707 if (EFI_ERROR (Status
)) {
708 return EFI_OUT_OF_RESOURCES
;
711 Status
= gBS
->CreateEvent (
714 Ip4Config2ManualAddressNotify
,
718 if (EFI_ERROR (Status
)) {
724 Status
= Ip4Cfg2
->RegisterDataNotify (
726 Ip4Config2DataTypeManualAddress
,
729 if (EFI_ERROR (Status
)) {
734 // Set ManualAddress.
736 DataSize
= Ip4NvData
->ManualAddressCount
* sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
);
737 Status
= Ip4Cfg2
->SetData (
739 Ip4Config2DataTypeManualAddress
,
741 (VOID
*) Ip4NvData
->ManualAddress
744 if (Status
== EFI_NOT_READY
) {
745 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
746 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
748 Status
= EFI_SUCCESS
;
754 Ip4Cfg2
->UnregisterDataNotify (
756 Ip4Config2DataTypeManualAddress
,
759 if (EFI_ERROR (Status
)) {
766 DataSize
= Ip4NvData
->GatewayAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
767 Status
= Ip4Cfg2
->SetData (
769 Ip4Config2DataTypeGateway
,
771 Ip4NvData
->GatewayAddress
773 if (EFI_ERROR (Status
)) {
778 // Set DNS addresses.
780 if (Ip4NvData
->DnsAddressCount
> 0 && Ip4NvData
->DnsAddress
!= NULL
) {
781 DataSize
= Ip4NvData
->DnsAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
782 Status
= Ip4Cfg2
->SetData (
784 Ip4Config2DataTypeDnsServer
,
786 Ip4NvData
->DnsAddress
789 if (EFI_ERROR (Status
)) {
796 if (SetAddressEvent
!= NULL
) {
797 gBS
->CloseEvent (SetAddressEvent
);
800 if (TimeoutEvent
!= NULL
) {
801 gBS
->CloseEvent (TimeoutEvent
);
808 This function allows the caller to request the current
809 configuration for one or more named elements. The resulting
810 string is in <ConfigAltResp> format. Any and all alternative
811 configuration strings shall also be appended to the end of the
812 current configuration string. If they are, they must appear
813 after the current configuration. They must contain the same
814 routing (GUID, NAME, PATH) as the current configuration string.
815 They must have an additional description indicating the type of
816 alternative configuration the string represents,
817 "ALTCFG=<StringToken>". That <StringToken> (when
818 converted from Hex UNICODE to binary) is a reference to a
819 string in the associated string pack.
821 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
822 @param[in] Request A null-terminated Unicode string in
823 <ConfigRequest> format. Note that this
824 includes the routing information as well as
825 the configurable name / value pairs. It is
826 invalid for this string to be in
827 <MultiConfigRequest> format.
828 @param[out] Progress On return, points to a character in the
829 Request string. Points to the string's null
830 terminator if request was successful. Points
831 to the most recent "&" before the first
832 failing name / value pair (or the beginning
833 of the string if the failure is in the first
834 name / value pair) if the request was not
836 @param[out] Results A null-terminated Unicode string in
837 <ConfigAltResp> format which has all values
838 filled in for the names in the Request string.
839 String to be allocated by the called function.
841 @retval EFI_SUCCESS The Results string is filled with the
842 values corresponding to all requested
844 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
845 parts of the results that must be
846 stored awaiting possible future
848 @retval EFI_NOT_FOUND Routing data doesn't match any
849 known driver. Progress set to the
850 first character in the routing header.
851 Note: There is no requirement that the
852 driver validate the routing data. It
853 must skip the <ConfigHdr> in order to
855 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
856 to most recent & before the
857 error or the beginning of the
859 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
860 to the & before the name in
861 question.Currently not implemented.
865 Ip4FormExtractConfig (
866 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
867 IN CONST EFI_STRING Request
,
868 OUT EFI_STRING
*Progress
,
869 OUT EFI_STRING
*Results
873 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
874 IP4_FORM_CALLBACK_INFO
*Private
;
875 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
876 EFI_STRING ConfigRequestHdr
;
877 EFI_STRING ConfigRequest
;
878 BOOLEAN AllocatedRequest
;
879 EFI_STRING FormResult
;
883 if (Progress
== NULL
|| Results
== NULL
) {
884 return EFI_INVALID_PARAMETER
;
887 Status
= EFI_SUCCESS
;
888 IfrFormNvData
= NULL
;
889 ConfigRequest
= NULL
;
892 AllocatedRequest
= FALSE
;
893 ConfigRequest
= Request
;
894 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
895 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
896 BufferSize
= sizeof (IP4_CONFIG2_IFR_NVDATA
);
900 // Check Request data in <ConfigHdr>.
902 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
903 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
904 if (IfrFormNvData
== NULL
) {
905 return EFI_OUT_OF_RESOURCES
;
908 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance
, IfrFormNvData
);
910 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
912 // Request has no request element, construct full request string.
913 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
914 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
916 ConfigRequestHdr
= HiiConstructConfigHdr (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, Private
->ChildHandle
);
917 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
918 ConfigRequest
= AllocateZeroPool (Size
);
919 if (ConfigRequest
== NULL
) {
920 Status
= EFI_OUT_OF_RESOURCES
;
923 AllocatedRequest
= TRUE
;
925 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
926 FreePool (ConfigRequestHdr
);
930 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
932 Status
= gHiiConfigRouting
->BlockToConfig (
935 (UINT8
*) IfrFormNvData
,
941 FreePool (IfrFormNvData
);
944 // Free the allocated config request string.
946 if (AllocatedRequest
) {
947 FreePool (ConfigRequest
);
948 ConfigRequest
= NULL
;
951 if (EFI_ERROR (Status
)) {
956 if (Request
== NULL
|| HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
957 *Results
= FormResult
;
959 return EFI_NOT_FOUND
;
964 // Set Progress string to the original request string.
966 if (Request
== NULL
) {
968 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
969 *Progress
= Request
+ StrLen (Request
);
976 This function applies changes in a driver's configuration.
977 Input is a Configuration, which has the routing data for this
978 driver followed by name / value configuration pairs. The driver
979 must apply those pairs to its configurable storage. If the
980 driver's configuration is stored in a linear block of data
981 and the driver's name / value pairs are in <BlockConfig>
982 format, it may use the ConfigToBlock helper function (above) to
983 simplify the job. Currently not implemented.
985 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
986 @param[in] Configuration A null-terminated Unicode string in
987 <ConfigString> format.
988 @param[out] Progress A pointer to a string filled in with the
989 offset of the most recent '&' before the
990 first failing name / value pair (or the
991 beginn ing of the string if the failure
992 is in the first name / value pair) or
993 the terminating NULL if all was
996 @retval EFI_SUCCESS The results have been distributed or are
997 awaiting distribution.
998 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
999 parts of the results that must be
1000 stored awaiting possible future
1002 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1003 Results parameter would result
1004 in this type of error.
1005 @retval EFI_NOT_FOUND Target for the specified routing data
1010 Ip4FormRouteConfig (
1011 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1012 IN CONST EFI_STRING Configuration
,
1013 OUT EFI_STRING
*Progress
1018 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1019 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
1020 IP4_FORM_CALLBACK_INFO
*Private
;
1022 Status
= EFI_SUCCESS
;
1023 IfrFormNvData
= NULL
;
1025 if (Configuration
== NULL
|| Progress
== NULL
) {
1026 return EFI_INVALID_PARAMETER
;
1029 *Progress
= Configuration
;
1031 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1032 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1035 // Check Routing data in <ConfigHdr>.
1037 if (HiiIsConfigHdrMatch (Configuration
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
1039 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1041 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1042 if (IfrFormNvData
== NULL
) {
1043 return EFI_OUT_OF_RESOURCES
;
1048 Status
= gHiiConfigRouting
->ConfigToBlock (
1051 (UINT8
*) IfrFormNvData
,
1055 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1059 Status
= gHiiConfigRouting
->ConfigToBlock (
1062 (UINT8
*) IfrFormNvData
,
1066 if (!EFI_ERROR (Status
)) {
1067 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Ip4Config2Instance
);
1070 FreePool (IfrFormNvData
);
1072 return EFI_NOT_FOUND
;
1080 This function is called to provide results data to the driver.
1081 This data consists of a unique key that is used to identify
1082 which data is either being passed back or being asked for.
1084 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1085 @param[in] Action Specifies the type of action taken by the browser.
1086 @param[in] QuestionId A unique value which is sent to the original
1087 exporting driver so that it can identify the type
1088 of data to expect. The format of the data tends to
1089 vary based on the opcode that enerated the callback.
1090 @param[in] Type The type of value for the question.
1091 @param[in] Value A pointer to the data being sent to the original
1093 @param[out] ActionRequest On return, points to the action requested by the
1096 @retval EFI_SUCCESS The callback successfully handled the action.
1097 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1098 variable and its data.
1099 @retval EFI_DEVICE_ERROR The variable could not be saved.
1100 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1101 callback.Currently not implemented.
1102 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
1103 @retval Others Other errors as indicated.
1109 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1110 IN EFI_BROWSER_ACTION Action
,
1111 IN EFI_QUESTION_ID QuestionId
,
1113 IN EFI_IFR_TYPE_VALUE
*Value
,
1114 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1118 IP4_CONFIG2_INSTANCE
*Instance
;
1119 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1120 IP4_FORM_CALLBACK_INFO
*Private
;
1122 EFI_IP_ADDRESS StationAddress
;
1123 EFI_IP_ADDRESS SubnetMask
;
1124 EFI_IP_ADDRESS Gateway
;
1126 EFI_IPv4_ADDRESS
*DnsAddress
;
1131 IfrFormNvData
= NULL
;
1135 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1136 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1137 Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1139 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1140 if (IfrFormNvData
== NULL
) {
1141 return EFI_OUT_OF_RESOURCES
;
1145 // Retrieve uncommitted data from Browser
1147 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, sizeof (IP4_CONFIG2_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
1148 FreePool (IfrFormNvData
);
1149 return EFI_NOT_FOUND
;
1152 Status
= EFI_SUCCESS
;
1154 switch (QuestionId
) {
1156 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
1157 if (EFI_ERROR (Status
) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress
.Addr
[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress
.Addr
[0]))) {
1158 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
1159 Status
= EFI_INVALID_PARAMETER
;
1163 case KEY_SUBNET_MASK
:
1164 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
1165 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
1166 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
1167 Status
= EFI_INVALID_PARAMETER
;
1172 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
1173 if (EFI_ERROR (Status
) || IP4_IS_LOCAL_BROADCAST(NTOHL(Gateway
.Addr
[0]))) {
1174 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
1175 Status
= EFI_INVALID_PARAMETER
;
1180 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
1181 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
1182 for (Index
= 0; Index
< DnsCount
; Index
++) {
1183 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
1184 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
1185 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1186 Status
= EFI_INVALID_PARAMETER
;
1191 if (EFI_ERROR (Status
)) {
1192 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1196 if(DnsAddress
!= NULL
) {
1197 FreePool(DnsAddress
);
1201 case KEY_SAVE_CHANGES
:
1202 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Instance
);
1203 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1210 FreePool (IfrFormNvData
);
1216 // All other action return unsupported.
1218 return EFI_UNSUPPORTED
;
1222 Install HII Config Access protocol for network device and allocate resource.
1224 @param[in, out] Instance The IP4 config2 Instance.
1226 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1227 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1228 @retval Others Other errors as indicated.
1232 Ip4Config2FormInit (
1233 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1238 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1239 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1240 VENDOR_DEVICE_PATH VendorDeviceNode
;
1241 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1243 CHAR16 MenuString
[128];
1244 CHAR16 PortString
[128];
1245 CHAR16
*OldMenuString
;
1246 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1248 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1249 ASSERT (IpSb
!= NULL
);
1251 CallbackInfo
= &Instance
->CallbackInfo
;
1253 CallbackInfo
->Signature
= IP4_FORM_CALLBACK_INFO_SIGNATURE
;
1255 Status
= gBS
->HandleProtocol (
1257 &gEfiDevicePathProtocolGuid
,
1258 (VOID
**) &ParentDevicePath
1260 if (EFI_ERROR (Status
)) {
1265 // Construct device path node for EFI HII Config Access protocol,
1266 // which consists of controller physical device path and one hardware
1267 // vendor guid node.
1269 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1270 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1271 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1273 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1275 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1276 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1278 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1280 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1281 Status
= EFI_OUT_OF_RESOURCES
;
1285 ConfigAccess
= &CallbackInfo
->HiiConfigAccessProtocol
;
1286 ConfigAccess
->ExtractConfig
= Ip4FormExtractConfig
;
1287 ConfigAccess
->RouteConfig
= Ip4FormRouteConfig
;
1288 ConfigAccess
->Callback
= Ip4FormCallback
;
1291 // Install Device Path Protocol and Config Access protocol on new handle
1293 Status
= gBS
->InstallMultipleProtocolInterfaces (
1294 &CallbackInfo
->ChildHandle
,
1295 &gEfiDevicePathProtocolGuid
,
1296 CallbackInfo
->HiiVendorDevicePath
,
1297 &gEfiHiiConfigAccessProtocolGuid
,
1302 if (!EFI_ERROR (Status
)) {
1304 // Open the Parent Handle for the child
1306 Status
= gBS
->OpenProtocol (
1308 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1311 CallbackInfo
->ChildHandle
,
1312 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1316 if (EFI_ERROR (Status
)) {
1321 // Publish our HII data
1323 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1324 &gIp4Config2NvDataGuid
,
1325 CallbackInfo
->ChildHandle
,
1330 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1331 Status
= EFI_OUT_OF_RESOURCES
;
1336 // Append MAC string in the menu help string and tile help string
1338 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1339 if (!EFI_ERROR (Status
)) {
1340 OldMenuString
= HiiGetString (
1341 CallbackInfo
->RegisteredHandle
,
1342 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1345 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
1347 CallbackInfo
->RegisteredHandle
,
1348 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1353 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
1355 CallbackInfo
->RegisteredHandle
,
1356 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
),
1361 FreePool (MacString
);
1362 FreePool (OldMenuString
);
1368 Ip4Config2FormUnload (Instance
);
1373 Uninstall the HII Config Access protocol for network devices and free up the resources.
1375 @param[in, out] Instance The IP4 config2 instance to unload a form.
1379 Ip4Config2FormUnload (
1380 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1384 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1385 IP4_CONFIG2_NVDATA
*Ip4NvData
;
1387 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1388 ASSERT (IpSb
!= NULL
);
1390 CallbackInfo
= &Instance
->CallbackInfo
;
1392 if (CallbackInfo
->ChildHandle
!= NULL
) {
1394 // Close the child handle
1396 gBS
->CloseProtocol (
1398 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1400 CallbackInfo
->ChildHandle
1404 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1406 gBS
->UninstallMultipleProtocolInterfaces (
1407 CallbackInfo
->ChildHandle
,
1408 &gEfiDevicePathProtocolGuid
,
1409 CallbackInfo
->HiiVendorDevicePath
,
1410 &gEfiHiiConfigAccessProtocolGuid
,
1411 &CallbackInfo
->HiiConfigAccessProtocol
,
1416 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
1417 FreePool (CallbackInfo
->HiiVendorDevicePath
);
1420 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
1422 // Remove HII package list
1424 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
1427 Ip4NvData
= &Instance
->Ip4NvData
;
1429 if(Ip4NvData
->ManualAddress
!= NULL
) {
1430 FreePool(Ip4NvData
->ManualAddress
);
1433 if(Ip4NvData
->GatewayAddress
!= NULL
) {
1434 FreePool(Ip4NvData
->GatewayAddress
);
1437 if(Ip4NvData
->DnsAddress
!= NULL
) {
1438 FreePool(Ip4NvData
->DnsAddress
);
1441 Ip4NvData
->ManualAddressCount
= 0;
1442 Ip4NvData
->GatewayAddressCount
= 0;
1443 Ip4NvData
->DnsAddressCount
= 0;