2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2015 - 2017, 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
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.
17 CHAR16 mIp4Config2StorageName
[] = L
"IP4_CONFIG2_IFR_NVDATA";
20 Calculate the prefix length of the IPv4 subnet mask.
22 @param[in] SubnetMask The IPv4 subnet mask.
24 @return The prefix length of the subnet mask.
25 @retval 0 Other errors as indicated.
29 GetSubnetMaskPrefixLength (
30 IN EFI_IPv4_ADDRESS
*SubnetMask
37 // The SubnetMask is in network byte order.
39 ReverseMask
= SwapBytes32 (*(UINT32
*)&SubnetMask
[0]);
44 ReverseMask
= ~ReverseMask
;
46 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
52 while (ReverseMask
!= 0) {
53 ReverseMask
= ReverseMask
>> 1;
57 return (UINT8
) (32 - Len
);
61 Convert the decimal dotted IPv4 address into the binary IPv4 address.
63 @param[in] Str The UNICODE string.
64 @param[out] Ip The storage to return the IPv4 address.
66 @retval EFI_SUCCESS The binary IP address is returned in Ip.
67 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
73 OUT EFI_IPv4_ADDRESS
*Ip
81 while (*Str
!= L
'\0') {
84 return EFI_INVALID_PARAMETER
;
88 while ((*Str
>= L
'0') && (*Str
<= L
'9')) {
89 Number
= Number
* 10 + (*Str
- L
'0');
94 return EFI_INVALID_PARAMETER
;
97 Ip
->Addr
[Index
] = (UINT8
) Number
;
99 if ((*Str
!= L
'\0') && (*Str
!= L
'.')) {
101 // The current character should be either the NULL terminator or
102 // the dot delimiter.
104 return EFI_INVALID_PARAMETER
;
109 // Skip the delimiter.
118 return EFI_INVALID_PARAMETER
;
125 Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.
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.
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.
137 Ip4Config2StrToIpList (
139 OUT EFI_IPv4_ADDRESS
**PtrIpList
,
151 EndIndex
= BeginIndex
;
165 // Get the number of Ip.
167 while (*(Str
+ Index
) != L
'\0') {
168 if (*(Str
+ Index
) == L
' ') {
185 // Allocate buffer for IpList.
187 *PtrIpList
= AllocateZeroPool(*IpCount
* sizeof(EFI_IPv4_ADDRESS
));
188 if (*PtrIpList
== NULL
) {
189 return EFI_OUT_OF_RESOURCES
;
193 // Get IpList from Str.
196 while (*(Str
+ Index
) != L
'\0') {
197 if (*(Str
+ Index
) == L
' ') {
199 StrTemp
= AllocateZeroPool((EndIndex
- BeginIndex
+ 1) * sizeof(CHAR16
));
200 if (StrTemp
== NULL
) {
201 FreePool(*PtrIpList
);
204 return EFI_OUT_OF_RESOURCES
;
207 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof(CHAR16
));
208 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
210 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
212 FreePool(*PtrIpList
);
215 return EFI_INVALID_PARAMETER
;
218 BeginIndex
= EndIndex
;
234 if (*(Str
+ Index
) == L
'\0') {
236 StrTemp
= AllocateZeroPool((EndIndex
- BeginIndex
+ 1) * sizeof(CHAR16
));
237 if (StrTemp
== NULL
) {
238 FreePool(*PtrIpList
);
241 return EFI_OUT_OF_RESOURCES
;
244 CopyMem (StrTemp
, Str
+ BeginIndex
, (EndIndex
- BeginIndex
) * sizeof(CHAR16
));
245 *(StrTemp
+ (EndIndex
- BeginIndex
)) = L
'\0';
247 if (Ip4Config2StrToIp (StrTemp
, &((*PtrIpList
)[IpIndex
])) != EFI_SUCCESS
) {
249 FreePool(*PtrIpList
);
252 return EFI_INVALID_PARAMETER
;
264 Convert the IPv4 address into a dotted string.
266 @param[in] Ip The IPv4 address.
267 @param[out] Str The dotted IP string.
272 IN EFI_IPv4_ADDRESS
*Ip
,
278 2 * IP4_STR_MAX_SIZE
,
289 Convert the IPv4 address list into string consists of several decimal
290 dotted IPv4 addresses separated by space.
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.
298 Ip4Config2IpListToStr (
299 IN EFI_IPv4_ADDRESS
*Ip
,
308 EFI_IPv4_ADDRESS
*TempIp
;
316 for (Index
= 0; Index
< IpCount
; Index
++) {
318 if (TempStr
== NULL
) {
319 TempStr
= AllocateZeroPool(2 * IP4_STR_MAX_SIZE
);
320 ASSERT(TempStr
!= NULL
);
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
) {
353 The notify function of create event when performing a manual configuration.
355 @param[in] Event The pointer of Event.
356 @param[in] Context The pointer of Context.
361 Ip4Config2ManualAddressNotify (
366 *((BOOLEAN
*) Context
) = TRUE
;
370 Convert the network configuration data into the IFR data.
372 @param[in] Instance The IP4 config2 instance.
373 @param[in, out] IfrNvData The IFR nv data.
375 @retval EFI_SUCCESS The configure parameter to IFR data was
377 @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not available.
378 @retval Others Other errors as indicated.
382 Ip4Config2ConvertConfigNvDataToIfrNvData (
383 IN IP4_CONFIG2_INSTANCE
*Instance
,
384 IN OUT IP4_CONFIG2_IFR_NVDATA
*IfrNvData
388 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
389 EFI_IP4_CONFIG2_INTERFACE_INFO
*Ip4Info
;
390 EFI_IP4_CONFIG2_POLICY Policy
;
393 EFI_IPv4_ADDRESS GatewayAddress
;
397 EFI_IPv4_ADDRESS
*DnsAddress
;
399 Status
= EFI_SUCCESS
;
400 Ip4Config2
= &Instance
->Ip4Config2
;
403 GatewaySize
= sizeof (EFI_IPv4_ADDRESS
);
405 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
406 return EFI_INVALID_PARAMETER
;
409 NET_CHECK_SIGNATURE (Instance
, IP4_CONFIG2_INSTANCE_SIGNATURE
);
411 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
413 if (IpSb
->DefaultInterface
->Configured
) {
414 IfrNvData
->Configure
= 1;
416 IfrNvData
->Configure
= 0;
421 // Get the Policy info.
423 DataSize
= sizeof (EFI_IP4_CONFIG2_POLICY
);
424 Status
= Ip4Config2
->GetData (
426 Ip4Config2DataTypePolicy
,
430 if (EFI_ERROR (Status
)) {
434 if (Policy
== Ip4Config2PolicyStatic
) {
435 IfrNvData
->DhcpEnable
= FALSE
;
436 } else if (Policy
== Ip4Config2PolicyDhcp
) {
437 IfrNvData
->DhcpEnable
= TRUE
;
442 // Get the interface info.
445 Status
= Ip4Config2
->GetData (
447 Ip4Config2DataTypeInterfaceInfo
,
451 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
455 Ip4Info
= AllocateZeroPool (DataSize
);
456 if (Ip4Info
== NULL
) {
457 Status
= EFI_OUT_OF_RESOURCES
;
461 Status
= Ip4Config2
->GetData (
463 Ip4Config2DataTypeInterfaceInfo
,
467 if (EFI_ERROR (Status
)) {
472 // Get the Gateway info.
474 Status
= Ip4Config2
->GetData (
476 Ip4Config2DataTypeGateway
,
480 if (EFI_ERROR (Status
)) {
488 Status
= Ip4Config2
->GetData (
490 Ip4Config2DataTypeDnsServer
,
494 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
498 DnsCount
= (UINT32
) (DnsSize
/ sizeof (EFI_IPv4_ADDRESS
));
501 DnsAddress
= AllocateZeroPool(DnsSize
);
502 if (DnsAddress
== NULL
) {
503 Status
= EFI_OUT_OF_RESOURCES
;
507 Status
= Ip4Config2
->GetData (
509 Ip4Config2DataTypeDnsServer
,
513 if (EFI_ERROR (Status
)) {
518 Ip4Config2IpToStr (&Ip4Info
->StationAddress
, IfrNvData
->StationAddress
);
519 Ip4Config2IpToStr (&Ip4Info
->SubnetMask
, IfrNvData
->SubnetMask
);
520 Ip4Config2IpToStr (&GatewayAddress
, IfrNvData
->GatewayAddress
);
521 Ip4Config2IpListToStr (DnsAddress
, DnsCount
, IfrNvData
->DnsAddress
);
525 if (DnsAddress
!= NULL
) {
526 FreePool(DnsAddress
);
529 if (Ip4Info
!= NULL
) {
537 Convert the IFR data into the network configuration data and set the IP
538 configure parameters for the NIC.
540 @param[in] IfrFormNvData The IFR NV data.
541 @param[in, out] Instance The IP4 config2 instance.
543 @retval EFI_SUCCESS The configure parameter for this NIC was
545 @retval EFI_INVALID_PARAMETER The address information for setting is invalid.
546 @retval Others Other errors as indicated.
550 Ip4Config2ConvertIfrNvDataToConfigNvData (
551 IN IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
,
552 IN OUT IP4_CONFIG2_INSTANCE
*Instance
556 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Cfg2
;
557 IP4_CONFIG2_NVDATA
*Ip4NvData
;
559 EFI_IP_ADDRESS StationAddress
;
560 EFI_IP_ADDRESS SubnetMask
;
561 EFI_IP_ADDRESS Gateway
;
563 EFI_IPv4_ADDRESS
*DnsAddress
;
567 EFI_EVENT TimeoutEvent
;
568 EFI_EVENT SetAddressEvent
;
573 Status
= EFI_SUCCESS
;
574 Ip4Cfg2
= &Instance
->Ip4Config2
;
575 Ip4NvData
= &Instance
->Ip4NvData
;
581 SetAddressEvent
= NULL
;
585 if (Instance
== NULL
|| IfrFormNvData
== NULL
) {
586 return EFI_INVALID_PARAMETER
;
589 if (IfrFormNvData
->Configure
!= TRUE
) {
593 if (IfrFormNvData
->DhcpEnable
== TRUE
) {
594 Ip4NvData
->Policy
= Ip4Config2PolicyDhcp
;
596 Status
= Ip4Cfg2
->SetData (
598 Ip4Config2DataTypePolicy
,
599 sizeof (EFI_IP4_CONFIG2_POLICY
),
602 if (EFI_ERROR(Status
)) {
607 // Get Ip4NvData from IfrFormNvData if it is valid.
609 Ip4NvData
->Policy
= Ip4Config2PolicyStatic
;
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
;
617 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
618 if (EFI_ERROR (Status
) ||
619 (SubnetMask
.Addr
[0] != 0 && !NetIp4IsUnicast (NTOHL (StationAddress
.Addr
[0]), NTOHL (SubnetMask
.Addr
[0]))) ||
620 !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])))) {
628 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
629 return EFI_INVALID_PARAMETER
;
632 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
633 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
634 for (Index
= 0; Index
< DnsCount
; Index
++) {
635 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
636 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
637 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
638 FreePool(DnsAddress
);
639 return EFI_INVALID_PARAMETER
;
643 if (EFI_ERROR (Status
)) {
644 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
648 if (Ip4NvData
->ManualAddress
!= NULL
) {
649 FreePool(Ip4NvData
->ManualAddress
);
651 Ip4NvData
->ManualAddressCount
= 1;
652 Ip4NvData
->ManualAddress
= AllocateZeroPool(sizeof(EFI_IP4_CONFIG2_MANUAL_ADDRESS
));
653 if (Ip4NvData
->ManualAddress
== NULL
) {
654 if (DnsAddress
!= NULL
) {
655 FreePool(DnsAddress
);
658 return EFI_OUT_OF_RESOURCES
;
660 CopyMem(&Ip4NvData
->ManualAddress
->Address
, &StationAddress
.v4
, sizeof(EFI_IPv4_ADDRESS
));
661 CopyMem(&Ip4NvData
->ManualAddress
->SubnetMask
, &SubnetMask
.v4
, sizeof(EFI_IPv4_ADDRESS
));
663 if (Ip4NvData
->GatewayAddress
!= NULL
) {
664 FreePool(Ip4NvData
->GatewayAddress
);
666 Ip4NvData
->GatewayAddressCount
= 1;
667 Ip4NvData
->GatewayAddress
= AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS
));
668 if (Ip4NvData
->GatewayAddress
== NULL
) {
669 if (DnsAddress
!= NULL
) {
670 FreePool(DnsAddress
);
672 return EFI_OUT_OF_RESOURCES
;
674 CopyMem(Ip4NvData
->GatewayAddress
, &Gateway
.v4
, sizeof(EFI_IPv4_ADDRESS
));
676 if (Ip4NvData
->DnsAddress
!= NULL
) {
677 FreePool(Ip4NvData
->DnsAddress
);
679 Ip4NvData
->DnsAddressCount
= (UINT32
) DnsCount
;
680 Ip4NvData
->DnsAddress
= DnsAddress
;
683 // Setting Ip4NvData.
685 Status
= Ip4Cfg2
->SetData (
687 Ip4Config2DataTypePolicy
,
688 sizeof (EFI_IP4_CONFIG2_POLICY
),
691 if (EFI_ERROR(Status
)) {
696 // Create events & timers for asynchronous settings.
698 Status
= gBS
->CreateEvent (
705 if (EFI_ERROR (Status
)) {
706 return EFI_OUT_OF_RESOURCES
;
709 Status
= gBS
->CreateEvent (
712 Ip4Config2ManualAddressNotify
,
716 if (EFI_ERROR (Status
)) {
722 Status
= Ip4Cfg2
->RegisterDataNotify (
724 Ip4Config2DataTypeManualAddress
,
727 if (EFI_ERROR (Status
)) {
732 // Set ManualAddress.
734 DataSize
= Ip4NvData
->ManualAddressCount
* sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
);
735 Status
= Ip4Cfg2
->SetData (
737 Ip4Config2DataTypeManualAddress
,
739 (VOID
*) Ip4NvData
->ManualAddress
742 if (Status
== EFI_NOT_READY
) {
743 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
744 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
746 Status
= EFI_SUCCESS
;
752 Ip4Cfg2
->UnregisterDataNotify (
754 Ip4Config2DataTypeManualAddress
,
757 if (EFI_ERROR (Status
)) {
764 DataSize
= Ip4NvData
->GatewayAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
765 Status
= Ip4Cfg2
->SetData (
767 Ip4Config2DataTypeGateway
,
769 Ip4NvData
->GatewayAddress
771 if (EFI_ERROR (Status
)) {
776 // Set DNS addresses.
778 if (Ip4NvData
->DnsAddressCount
> 0 && Ip4NvData
->DnsAddress
!= NULL
) {
779 DataSize
= Ip4NvData
->DnsAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
780 Status
= Ip4Cfg2
->SetData (
782 Ip4Config2DataTypeDnsServer
,
784 Ip4NvData
->DnsAddress
787 if (EFI_ERROR (Status
)) {
794 if (SetAddressEvent
!= NULL
) {
795 gBS
->CloseEvent (SetAddressEvent
);
798 if (TimeoutEvent
!= NULL
) {
799 gBS
->CloseEvent (TimeoutEvent
);
806 This function allows the caller to request the current
807 configuration for one or more named elements. The resulting
808 string is in <ConfigAltResp> format. Any and all alternative
809 configuration strings shall also be appended to the end of the
810 current configuration string. If they are, they must appear
811 after the current configuration. They must contain the same
812 routing (GUID, NAME, PATH) as the current configuration string.
813 They must have an additional description indicating the type of
814 alternative configuration the string represents,
815 "ALTCFG=<StringToken>". That <StringToken> (when
816 converted from Hex UNICODE to binary) is a reference to a
817 string in the associated string pack.
819 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
820 @param[in] Request A null-terminated Unicode string in
821 <ConfigRequest> format. Note that this
822 includes the routing information as well as
823 the configurable name / value pairs. It is
824 invalid for this string to be in
825 <MultiConfigRequest> format.
826 @param[out] Progress On return, points to a character in the
827 Request string. Points to the string's null
828 terminator if request was successful. Points
829 to the most recent "&" before the first
830 failing name / value pair (or the beginning
831 of the string if the failure is in the first
832 name / value pair) if the request was not
834 @param[out] Results A null-terminated Unicode string in
835 <ConfigAltResp> format which has all values
836 filled in for the names in the Request string.
837 String to be allocated by the called function.
839 @retval EFI_SUCCESS The Results string is filled with the
840 values corresponding to all requested
842 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
843 parts of the results that must be
844 stored awaiting possible future
846 @retval EFI_NOT_FOUND Routing data doesn't match any
847 known driver. Progress set to the
848 first character in the routing header.
849 Note: There is no requirement that the
850 driver validate the routing data. It
851 must skip the <ConfigHdr> in order to
853 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
854 to most recent & before the
855 error or the beginning of the
857 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
858 to the & before the name in
859 question.Currently not implemented.
863 Ip4FormExtractConfig (
864 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
865 IN CONST EFI_STRING Request
,
866 OUT EFI_STRING
*Progress
,
867 OUT EFI_STRING
*Results
871 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
872 IP4_FORM_CALLBACK_INFO
*Private
;
873 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
874 EFI_STRING ConfigRequestHdr
;
875 EFI_STRING ConfigRequest
;
876 BOOLEAN AllocatedRequest
;
877 EFI_STRING FormResult
;
881 if (Progress
== NULL
|| Results
== NULL
) {
882 return EFI_INVALID_PARAMETER
;
885 Status
= EFI_SUCCESS
;
886 IfrFormNvData
= NULL
;
887 ConfigRequest
= NULL
;
890 AllocatedRequest
= FALSE
;
891 ConfigRequest
= Request
;
892 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
893 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
894 BufferSize
= sizeof (IP4_CONFIG2_IFR_NVDATA
);
898 // Check Request data in <ConfigHdr>.
900 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
901 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
902 if (IfrFormNvData
== NULL
) {
903 return EFI_OUT_OF_RESOURCES
;
906 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance
, IfrFormNvData
);
908 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
910 // Request has no request element, construct full request string.
911 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
912 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
914 ConfigRequestHdr
= HiiConstructConfigHdr (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, Private
->ChildHandle
);
915 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
916 ConfigRequest
= AllocateZeroPool (Size
);
917 ASSERT (ConfigRequest
!= NULL
);
918 AllocatedRequest
= TRUE
;
920 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
921 FreePool (ConfigRequestHdr
);
925 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
927 Status
= gHiiConfigRouting
->BlockToConfig (
930 (UINT8
*) IfrFormNvData
,
936 FreePool (IfrFormNvData
);
939 // Free the allocated config request string.
941 if (AllocatedRequest
) {
942 FreePool (ConfigRequest
);
943 ConfigRequest
= NULL
;
946 if (EFI_ERROR (Status
)) {
951 if (Request
== NULL
|| HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
952 *Results
= FormResult
;
954 return EFI_NOT_FOUND
;
959 // Set Progress string to the original request string.
961 if (Request
== NULL
) {
963 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
964 *Progress
= Request
+ StrLen (Request
);
971 This function applies changes in a driver's configuration.
972 Input is a Configuration, which has the routing data for this
973 driver followed by name / value configuration pairs. The driver
974 must apply those pairs to its configurable storage. If the
975 driver's configuration is stored in a linear block of data
976 and the driver's name / value pairs are in <BlockConfig>
977 format, it may use the ConfigToBlock helper function (above) to
978 simplify the job. Currently not implemented.
980 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
981 @param[in] Configuration A null-terminated Unicode string in
982 <ConfigString> format.
983 @param[out] Progress A pointer to a string filled in with the
984 offset of the most recent '&' before the
985 first failing name / value pair (or the
986 beginn ing of the string if the failure
987 is in the first name / value pair) or
988 the terminating NULL if all was
991 @retval EFI_SUCCESS The results have been distributed or are
992 awaiting distribution.
993 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
994 parts of the results that must be
995 stored awaiting possible future
997 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
998 Results parameter would result
999 in this type of error.
1000 @retval EFI_NOT_FOUND Target for the specified routing data
1005 Ip4FormRouteConfig (
1006 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1007 IN CONST EFI_STRING Configuration
,
1008 OUT EFI_STRING
*Progress
1013 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1014 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
1015 IP4_FORM_CALLBACK_INFO
*Private
;
1017 Status
= EFI_SUCCESS
;
1018 IfrFormNvData
= NULL
;
1020 if (Configuration
== NULL
|| Progress
== NULL
) {
1021 return EFI_INVALID_PARAMETER
;
1024 *Progress
= Configuration
;
1026 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1027 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1030 // Check Routing data in <ConfigHdr>.
1032 if (HiiIsConfigHdrMatch (Configuration
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
1034 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1036 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1037 if (IfrFormNvData
== NULL
) {
1038 return EFI_OUT_OF_RESOURCES
;
1043 Status
= gHiiConfigRouting
->ConfigToBlock (
1046 (UINT8
*) IfrFormNvData
,
1050 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1054 Status
= gHiiConfigRouting
->ConfigToBlock (
1057 (UINT8
*) IfrFormNvData
,
1061 if (!EFI_ERROR (Status
)) {
1062 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Ip4Config2Instance
);
1065 FreePool (IfrFormNvData
);
1067 return EFI_NOT_FOUND
;
1075 This function is called to provide results data to the driver.
1076 This data consists of a unique key that is used to identify
1077 which data is either being passed back or being asked for.
1079 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1080 @param[in] Action Specifies the type of action taken by the browser.
1081 @param[in] QuestionId A unique value which is sent to the original
1082 exporting driver so that it can identify the type
1083 of data to expect. The format of the data tends to
1084 vary based on the opcode that enerated the callback.
1085 @param[in] Type The type of value for the question.
1086 @param[in] Value A pointer to the data being sent to the original
1088 @param[out] ActionRequest On return, points to the action requested by the
1091 @retval EFI_SUCCESS The callback successfully handled the action.
1092 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1093 variable and its data.
1094 @retval EFI_DEVICE_ERROR The variable could not be saved.
1095 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1096 callback.Currently not implemented.
1097 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
1098 @retval Others Other errors as indicated.
1104 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1105 IN EFI_BROWSER_ACTION Action
,
1106 IN EFI_QUESTION_ID QuestionId
,
1108 IN EFI_IFR_TYPE_VALUE
*Value
,
1109 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1113 IP4_CONFIG2_INSTANCE
*Instance
;
1114 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1115 IP4_FORM_CALLBACK_INFO
*Private
;
1117 EFI_IP_ADDRESS StationAddress
;
1118 EFI_IP_ADDRESS SubnetMask
;
1119 EFI_IP_ADDRESS Gateway
;
1121 EFI_IPv4_ADDRESS
*DnsAddress
;
1126 IfrFormNvData
= NULL
;
1130 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1131 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1132 Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1134 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1135 if (IfrFormNvData
== NULL
) {
1136 return EFI_OUT_OF_RESOURCES
;
1140 // Retrieve uncommitted data from Browser
1142 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, sizeof (IP4_CONFIG2_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
1143 FreePool (IfrFormNvData
);
1144 return EFI_NOT_FOUND
;
1147 Status
= EFI_SUCCESS
;
1149 switch (QuestionId
) {
1151 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
1152 if (EFI_ERROR (Status
) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress
.Addr
[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress
.Addr
[0]))) {
1153 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
1154 Status
= EFI_INVALID_PARAMETER
;
1158 case KEY_SUBNET_MASK
:
1159 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
1160 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
1161 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
1162 Status
= EFI_INVALID_PARAMETER
;
1167 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
1168 if (EFI_ERROR (Status
) || IP4_IS_LOCAL_BROADCAST(NTOHL(Gateway
.Addr
[0]))) {
1169 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
1170 Status
= EFI_INVALID_PARAMETER
;
1175 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
1176 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
1177 for (Index
= 0; Index
< DnsCount
; Index
++) {
1178 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
1179 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
))) {
1180 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1181 Status
= EFI_INVALID_PARAMETER
;
1186 if (EFI_ERROR (Status
)) {
1187 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1191 if(DnsAddress
!= NULL
) {
1192 FreePool(DnsAddress
);
1196 case KEY_SAVE_CHANGES
:
1197 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Instance
);
1198 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1205 FreePool (IfrFormNvData
);
1211 // All other action return unsupported.
1213 return EFI_UNSUPPORTED
;
1217 Install HII Config Access protocol for network device and allocate resource.
1219 @param[in, out] Instance The IP4 config2 Instance.
1221 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1222 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1223 @retval Others Other errors as indicated.
1227 Ip4Config2FormInit (
1228 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1233 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1234 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1235 VENDOR_DEVICE_PATH VendorDeviceNode
;
1236 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1238 CHAR16 MenuString
[128];
1239 CHAR16 PortString
[128];
1240 CHAR16
*OldMenuString
;
1241 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1243 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1244 ASSERT (IpSb
!= NULL
);
1246 CallbackInfo
= &Instance
->CallbackInfo
;
1248 CallbackInfo
->Signature
= IP4_FORM_CALLBACK_INFO_SIGNATURE
;
1250 Status
= gBS
->HandleProtocol (
1252 &gEfiDevicePathProtocolGuid
,
1253 (VOID
**) &ParentDevicePath
1255 if (EFI_ERROR (Status
)) {
1260 // Construct device path node for EFI HII Config Access protocol,
1261 // which consists of controller physical device path and one hardware
1262 // vendor guid node.
1264 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1265 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1266 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1268 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1270 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1271 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1273 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1275 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1276 Status
= EFI_OUT_OF_RESOURCES
;
1280 ConfigAccess
= &CallbackInfo
->HiiConfigAccessProtocol
;
1281 ConfigAccess
->ExtractConfig
= Ip4FormExtractConfig
;
1282 ConfigAccess
->RouteConfig
= Ip4FormRouteConfig
;
1283 ConfigAccess
->Callback
= Ip4FormCallback
;
1286 // Install Device Path Protocol and Config Access protocol on new handle
1288 Status
= gBS
->InstallMultipleProtocolInterfaces (
1289 &CallbackInfo
->ChildHandle
,
1290 &gEfiDevicePathProtocolGuid
,
1291 CallbackInfo
->HiiVendorDevicePath
,
1292 &gEfiHiiConfigAccessProtocolGuid
,
1297 if (!EFI_ERROR (Status
)) {
1299 // Open the Parent Handle for the child
1301 Status
= gBS
->OpenProtocol (
1303 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1306 CallbackInfo
->ChildHandle
,
1307 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1311 if (EFI_ERROR (Status
)) {
1316 // Publish our HII data
1318 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1319 &gIp4Config2NvDataGuid
,
1320 CallbackInfo
->ChildHandle
,
1325 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1326 Status
= EFI_OUT_OF_RESOURCES
;
1331 // Append MAC string in the menu help string and tile help string
1333 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1334 if (!EFI_ERROR (Status
)) {
1335 OldMenuString
= HiiGetString (
1336 CallbackInfo
->RegisteredHandle
,
1337 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1340 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
1342 CallbackInfo
->RegisteredHandle
,
1343 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1348 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
1350 CallbackInfo
->RegisteredHandle
,
1351 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
),
1356 FreePool (MacString
);
1357 FreePool (OldMenuString
);
1363 Ip4Config2FormUnload (Instance
);
1368 Uninstall the HII Config Access protocol for network devices and free up the resources.
1370 @param[in, out] Instance The IP4 config2 instance to unload a form.
1374 Ip4Config2FormUnload (
1375 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1379 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1380 IP4_CONFIG2_NVDATA
*Ip4NvData
;
1382 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1383 ASSERT (IpSb
!= NULL
);
1385 CallbackInfo
= &Instance
->CallbackInfo
;
1387 if (CallbackInfo
->ChildHandle
!= NULL
) {
1389 // Close the child handle
1391 gBS
->CloseProtocol (
1393 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1395 CallbackInfo
->ChildHandle
1399 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1401 gBS
->UninstallMultipleProtocolInterfaces (
1402 CallbackInfo
->ChildHandle
,
1403 &gEfiDevicePathProtocolGuid
,
1404 CallbackInfo
->HiiVendorDevicePath
,
1405 &gEfiHiiConfigAccessProtocolGuid
,
1406 &CallbackInfo
->HiiConfigAccessProtocol
,
1411 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
1412 FreePool (CallbackInfo
->HiiVendorDevicePath
);
1415 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
1417 // Remove HII package list
1419 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
1422 Ip4NvData
= &Instance
->Ip4NvData
;
1424 if(Ip4NvData
->ManualAddress
!= NULL
) {
1425 FreePool(Ip4NvData
->ManualAddress
);
1428 if(Ip4NvData
->GatewayAddress
!= NULL
) {
1429 FreePool(Ip4NvData
->GatewayAddress
);
1432 if(Ip4NvData
->DnsAddress
!= NULL
) {
1433 FreePool(Ip4NvData
->DnsAddress
);
1436 Ip4NvData
->ManualAddressCount
= 0;
1437 Ip4NvData
->GatewayAddressCount
= 0;
1438 Ip4NvData
->DnsAddressCount
= 0;