2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2015, 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
->StationAddress
, &StationAddress
.v4
);
612 if (EFI_ERROR (Status
) || !NetIp4IsUnicast (NTOHL (StationAddress
.Addr
[0]), 0)) {
613 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
614 return EFI_INVALID_PARAMETER
;
617 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
618 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
619 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
620 return EFI_INVALID_PARAMETER
;
623 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
624 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
625 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
626 return EFI_INVALID_PARAMETER
;
629 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
630 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
631 for (Index
= 0; Index
< DnsCount
; Index
++) {
632 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
633 if (!NetIp4IsUnicast (NTOHL (Ip
), 0)) {
634 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
635 FreePool(DnsAddress
);
636 return EFI_INVALID_PARAMETER
;
640 if (EFI_ERROR (Status
)) {
641 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
645 if (Ip4NvData
->ManualAddress
!= NULL
) {
646 FreePool(Ip4NvData
->ManualAddress
);
648 Ip4NvData
->ManualAddressCount
= 1;
649 Ip4NvData
->ManualAddress
= AllocateZeroPool(sizeof(EFI_IP4_CONFIG2_MANUAL_ADDRESS
));
650 if (Ip4NvData
->ManualAddress
== NULL
) {
651 if (DnsAddress
!= NULL
) {
652 FreePool(DnsAddress
);
655 return EFI_OUT_OF_RESOURCES
;
657 CopyMem(&Ip4NvData
->ManualAddress
->Address
, &StationAddress
.v4
, sizeof(EFI_IPv4_ADDRESS
));
658 CopyMem(&Ip4NvData
->ManualAddress
->SubnetMask
, &SubnetMask
.v4
, sizeof(EFI_IPv4_ADDRESS
));
660 if (Ip4NvData
->GatewayAddress
!= NULL
) {
661 FreePool(Ip4NvData
->GatewayAddress
);
663 Ip4NvData
->GatewayAddressCount
= 1;
664 Ip4NvData
->GatewayAddress
= AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS
));
665 if (Ip4NvData
->GatewayAddress
== NULL
) {
666 if (DnsAddress
!= NULL
) {
667 FreePool(DnsAddress
);
669 return EFI_OUT_OF_RESOURCES
;
671 CopyMem(Ip4NvData
->GatewayAddress
, &Gateway
.v4
, sizeof(EFI_IPv4_ADDRESS
));
673 if (Ip4NvData
->DnsAddress
!= NULL
) {
674 FreePool(Ip4NvData
->DnsAddress
);
676 Ip4NvData
->DnsAddressCount
= (UINT32
) DnsCount
;
677 Ip4NvData
->DnsAddress
= DnsAddress
;
680 // Setting Ip4NvData.
682 Status
= Ip4Cfg2
->SetData (
684 Ip4Config2DataTypePolicy
,
685 sizeof (EFI_IP4_CONFIG2_POLICY
),
688 if (EFI_ERROR(Status
)) {
693 // Create events & timers for asynchronous settings.
695 Status
= gBS
->CreateEvent (
702 if (EFI_ERROR (Status
)) {
703 return EFI_OUT_OF_RESOURCES
;
706 Status
= gBS
->CreateEvent (
709 Ip4Config2ManualAddressNotify
,
713 if (EFI_ERROR (Status
)) {
719 Status
= Ip4Cfg2
->RegisterDataNotify (
721 Ip4Config2DataTypeManualAddress
,
724 if (EFI_ERROR (Status
)) {
729 // Set ManualAddress.
731 DataSize
= Ip4NvData
->ManualAddressCount
* sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
);
732 Status
= Ip4Cfg2
->SetData (
734 Ip4Config2DataTypeManualAddress
,
736 (VOID
*) Ip4NvData
->ManualAddress
739 if (Status
== EFI_NOT_READY
) {
740 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
741 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
743 Status
= EFI_SUCCESS
;
749 Ip4Cfg2
->UnregisterDataNotify (
751 Ip4Config2DataTypeManualAddress
,
754 if (EFI_ERROR (Status
)) {
761 DataSize
= Ip4NvData
->GatewayAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
762 Status
= Ip4Cfg2
->SetData (
764 Ip4Config2DataTypeGateway
,
766 Ip4NvData
->GatewayAddress
768 if (EFI_ERROR (Status
)) {
773 // Set DNS addresses.
775 if (Ip4NvData
->DnsAddressCount
> 0 && Ip4NvData
->DnsAddress
!= NULL
) {
776 DataSize
= Ip4NvData
->DnsAddressCount
* sizeof (EFI_IPv4_ADDRESS
);
777 Status
= Ip4Cfg2
->SetData (
779 Ip4Config2DataTypeDnsServer
,
781 Ip4NvData
->DnsAddress
784 if (EFI_ERROR (Status
)) {
791 if (SetAddressEvent
!= NULL
) {
792 gBS
->CloseEvent (SetAddressEvent
);
795 if (TimeoutEvent
!= NULL
) {
796 gBS
->CloseEvent (TimeoutEvent
);
803 This function allows the caller to request the current
804 configuration for one or more named elements. The resulting
805 string is in <ConfigAltResp> format. Any and all alternative
806 configuration strings shall also be appended to the end of the
807 current configuration string. If they are, they must appear
808 after the current configuration. They must contain the same
809 routing (GUID, NAME, PATH) as the current configuration string.
810 They must have an additional description indicating the type of
811 alternative configuration the string represents,
812 "ALTCFG=<StringToken>". That <StringToken> (when
813 converted from Hex UNICODE to binary) is a reference to a
814 string in the associated string pack.
816 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
817 @param[in] Request A null-terminated Unicode string in
818 <ConfigRequest> format. Note that this
819 includes the routing information as well as
820 the configurable name / value pairs. It is
821 invalid for this string to be in
822 <MultiConfigRequest> format.
823 @param[out] Progress On return, points to a character in the
824 Request string. Points to the string's null
825 terminator if request was successful. Points
826 to the most recent "&" before the first
827 failing name / value pair (or the beginning
828 of the string if the failure is in the first
829 name / value pair) if the request was not
831 @param[out] Results A null-terminated Unicode string in
832 <ConfigAltResp> format which has all values
833 filled in for the names in the Request string.
834 String to be allocated by the called function.
836 @retval EFI_SUCCESS The Results string is filled with the
837 values corresponding to all requested
839 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
840 parts of the results that must be
841 stored awaiting possible future
843 @retval EFI_NOT_FOUND Routing data doesn't match any
844 known driver. Progress set to the
845 first character in the routing header.
846 Note: There is no requirement that the
847 driver validate the routing data. It
848 must skip the <ConfigHdr> in order to
850 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
851 to most recent & before the
852 error or the beginning of the
854 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
855 to the & before the name in
856 question.Currently not implemented.
860 Ip4FormExtractConfig (
861 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
862 IN CONST EFI_STRING Request
,
863 OUT EFI_STRING
*Progress
,
864 OUT EFI_STRING
*Results
868 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
869 IP4_FORM_CALLBACK_INFO
*Private
;
870 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
871 EFI_STRING ConfigRequestHdr
;
872 EFI_STRING ConfigRequest
;
873 BOOLEAN AllocatedRequest
;
874 EFI_STRING FormResult
;
878 if (Progress
== NULL
|| Results
== NULL
) {
879 return EFI_INVALID_PARAMETER
;
882 Status
= EFI_SUCCESS
;
883 IfrFormNvData
= NULL
;
884 ConfigRequest
= NULL
;
887 AllocatedRequest
= FALSE
;
888 ConfigRequest
= Request
;
889 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
890 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
891 BufferSize
= sizeof (IP4_CONFIG2_IFR_NVDATA
);
895 // Check Request data in <ConfigHdr>.
897 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
898 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
899 if (IfrFormNvData
== NULL
) {
900 return EFI_OUT_OF_RESOURCES
;
903 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance
, IfrFormNvData
);
905 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
907 // Request has no request element, construct full request string.
908 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
909 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
911 ConfigRequestHdr
= HiiConstructConfigHdr (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, Private
->ChildHandle
);
912 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
913 ConfigRequest
= AllocateZeroPool (Size
);
914 ASSERT (ConfigRequest
!= NULL
);
915 AllocatedRequest
= TRUE
;
917 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
918 FreePool (ConfigRequestHdr
);
922 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
924 Status
= gHiiConfigRouting
->BlockToConfig (
927 (UINT8
*) IfrFormNvData
,
933 FreePool (IfrFormNvData
);
936 // Free the allocated config request string.
938 if (AllocatedRequest
) {
939 FreePool (ConfigRequest
);
940 ConfigRequest
= NULL
;
943 if (EFI_ERROR (Status
)) {
948 if (Request
== NULL
|| HiiIsConfigHdrMatch (Request
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
949 *Results
= FormResult
;
951 return EFI_NOT_FOUND
;
956 // Set Progress string to the original request string.
958 if (Request
== NULL
) {
960 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
961 *Progress
= Request
+ StrLen (Request
);
968 This function applies changes in a driver's configuration.
969 Input is a Configuration, which has the routing data for this
970 driver followed by name / value configuration pairs. The driver
971 must apply those pairs to its configurable storage. If the
972 driver's configuration is stored in a linear block of data
973 and the driver's name / value pairs are in <BlockConfig>
974 format, it may use the ConfigToBlock helper function (above) to
975 simplify the job. Currently not implemented.
977 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
978 @param[in] Configuration A null-terminated Unicode string in
979 <ConfigString> format.
980 @param[out] Progress A pointer to a string filled in with the
981 offset of the most recent '&' before the
982 first failing name / value pair (or the
983 beginn ing of the string if the failure
984 is in the first name / value pair) or
985 the terminating NULL if all was
988 @retval EFI_SUCCESS The results have been distributed or are
989 awaiting distribution.
990 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
991 parts of the results that must be
992 stored awaiting possible future
994 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
995 Results parameter would result
996 in this type of error.
997 @retval EFI_NOT_FOUND Target for the specified routing data
1002 Ip4FormRouteConfig (
1003 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1004 IN CONST EFI_STRING Configuration
,
1005 OUT EFI_STRING
*Progress
1010 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1011 IP4_CONFIG2_INSTANCE
*Ip4Config2Instance
;
1012 IP4_FORM_CALLBACK_INFO
*Private
;
1014 Status
= EFI_SUCCESS
;
1015 IfrFormNvData
= NULL
;
1017 if (Configuration
== NULL
|| Progress
== NULL
) {
1018 return EFI_INVALID_PARAMETER
;
1021 *Progress
= Configuration
;
1023 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1024 Ip4Config2Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1027 // Check Routing data in <ConfigHdr>.
1029 if (HiiIsConfigHdrMatch (Configuration
, &gIp4Config2NvDataGuid
, mIp4Config2StorageName
)) {
1031 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1033 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1034 if (IfrFormNvData
== NULL
) {
1035 return EFI_OUT_OF_RESOURCES
;
1040 Status
= gHiiConfigRouting
->ConfigToBlock (
1043 (UINT8
*) IfrFormNvData
,
1047 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1051 Status
= gHiiConfigRouting
->ConfigToBlock (
1054 (UINT8
*) IfrFormNvData
,
1058 if (!EFI_ERROR (Status
)) {
1059 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Ip4Config2Instance
);
1062 FreePool (IfrFormNvData
);
1064 return EFI_NOT_FOUND
;
1072 This function is called to provide results data to the driver.
1073 This data consists of a unique key that is used to identify
1074 which data is either being passed back or being asked for.
1076 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1077 @param[in] Action Specifies the type of action taken by the browser.
1078 @param[in] QuestionId A unique value which is sent to the original
1079 exporting driver so that it can identify the type
1080 of data to expect. The format of the data tends to
1081 vary based on the opcode that enerated the callback.
1082 @param[in] Type The type of value for the question.
1083 @param[in] Value A pointer to the data being sent to the original
1085 @param[out] ActionRequest On return, points to the action requested by the
1088 @retval EFI_SUCCESS The callback successfully handled the action.
1089 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1090 variable and its data.
1091 @retval EFI_DEVICE_ERROR The variable could not be saved.
1092 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1093 callback.Currently not implemented.
1094 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
1095 @retval Others Other errors as indicated.
1101 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1102 IN EFI_BROWSER_ACTION Action
,
1103 IN EFI_QUESTION_ID QuestionId
,
1105 IN EFI_IFR_TYPE_VALUE
*Value
,
1106 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1110 IP4_CONFIG2_INSTANCE
*Instance
;
1111 IP4_CONFIG2_IFR_NVDATA
*IfrFormNvData
;
1112 IP4_FORM_CALLBACK_INFO
*Private
;
1114 EFI_IP_ADDRESS StationAddress
;
1115 EFI_IP_ADDRESS SubnetMask
;
1116 EFI_IP_ADDRESS Gateway
;
1118 EFI_IPv4_ADDRESS
*DnsAddress
;
1123 IfrFormNvData
= NULL
;
1127 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1128 Private
= IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This
);
1129 Instance
= IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private
);
1131 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA
));
1132 if (IfrFormNvData
== NULL
) {
1133 return EFI_OUT_OF_RESOURCES
;
1137 // Retrive uncommitted data from Browser
1139 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid
, mIp4Config2StorageName
, sizeof (IP4_CONFIG2_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
1140 FreePool (IfrFormNvData
);
1141 return EFI_NOT_FOUND
;
1144 Status
= EFI_SUCCESS
;
1146 switch (QuestionId
) {
1148 Status
= Ip4Config2StrToIp (IfrFormNvData
->StationAddress
, &StationAddress
.v4
);
1149 if (EFI_ERROR (Status
) || !NetIp4IsUnicast (NTOHL (StationAddress
.Addr
[0]), 0)) {
1150 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
1151 Status
= EFI_INVALID_PARAMETER
;
1155 case KEY_SUBNET_MASK
:
1156 Status
= Ip4Config2StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
1157 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
1158 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
1159 Status
= EFI_INVALID_PARAMETER
;
1164 Status
= Ip4Config2StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
1165 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
1166 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
1167 Status
= EFI_INVALID_PARAMETER
;
1172 Status
= Ip4Config2StrToIpList (IfrFormNvData
->DnsAddress
, &DnsAddress
, &DnsCount
);
1173 if (!EFI_ERROR (Status
) && DnsCount
> 0) {
1174 for (Index
= 0; Index
< DnsCount
; Index
++) {
1175 CopyMem (&Ip
, &DnsAddress
[Index
], sizeof (IP4_ADDR
));
1176 if (!NetIp4IsUnicast (NTOHL (Ip
), 0)) {
1177 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1178 Status
= EFI_INVALID_PARAMETER
;
1183 if (EFI_ERROR (Status
)) {
1184 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Dns Server!", NULL
);
1188 if(DnsAddress
!= NULL
) {
1189 FreePool(DnsAddress
);
1193 case KEY_SAVE_CHANGES
:
1194 Status
= Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData
, Instance
);
1195 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1202 FreePool (IfrFormNvData
);
1208 // All other action return unsupported.
1210 return EFI_UNSUPPORTED
;
1214 Install HII Config Access protocol for network device and allocate resource.
1216 @param[in, out] Instance The IP4 config2 Instance.
1218 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1219 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1220 @retval Others Other errors as indicated.
1224 Ip4Config2FormInit (
1225 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1230 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1231 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1232 VENDOR_DEVICE_PATH VendorDeviceNode
;
1233 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1235 CHAR16 MenuString
[128];
1236 CHAR16 PortString
[128];
1237 CHAR16
*OldMenuString
;
1238 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1240 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1241 ASSERT (IpSb
!= NULL
);
1243 CallbackInfo
= &Instance
->CallbackInfo
;
1245 CallbackInfo
->Signature
= IP4_FORM_CALLBACK_INFO_SIGNATURE
;
1247 Status
= gBS
->HandleProtocol (
1249 &gEfiDevicePathProtocolGuid
,
1250 (VOID
**) &ParentDevicePath
1252 if (EFI_ERROR (Status
)) {
1257 // Construct device path node for EFI HII Config Access protocol,
1258 // which consists of controller physical device path and one hardware
1259 // vendor guid node.
1261 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1262 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1263 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1265 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1267 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1268 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1270 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1272 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1273 Status
= EFI_OUT_OF_RESOURCES
;
1277 ConfigAccess
= &CallbackInfo
->HiiConfigAccessProtocol
;
1278 ConfigAccess
->ExtractConfig
= Ip4FormExtractConfig
;
1279 ConfigAccess
->RouteConfig
= Ip4FormRouteConfig
;
1280 ConfigAccess
->Callback
= Ip4FormCallback
;
1283 // Install Device Path Protocol and Config Access protocol on new handle
1285 Status
= gBS
->InstallMultipleProtocolInterfaces (
1286 &CallbackInfo
->ChildHandle
,
1287 &gEfiDevicePathProtocolGuid
,
1288 CallbackInfo
->HiiVendorDevicePath
,
1289 &gEfiHiiConfigAccessProtocolGuid
,
1294 if (!EFI_ERROR (Status
)) {
1296 // Open the Parent Handle for the child
1298 Status
= gBS
->OpenProtocol (
1300 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1303 CallbackInfo
->ChildHandle
,
1304 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1308 if (EFI_ERROR (Status
)) {
1313 // Publish our HII data
1315 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1316 &gIp4Config2NvDataGuid
,
1317 CallbackInfo
->ChildHandle
,
1322 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1323 Status
= EFI_OUT_OF_RESOURCES
;
1328 // Append MAC string in the menu help string and tile help string
1330 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1331 if (!EFI_ERROR (Status
)) {
1332 OldMenuString
= HiiGetString (
1333 CallbackInfo
->RegisteredHandle
,
1334 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1337 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
1339 CallbackInfo
->RegisteredHandle
,
1340 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP
),
1345 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
1347 CallbackInfo
->RegisteredHandle
,
1348 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
),
1353 FreePool (MacString
);
1354 FreePool (OldMenuString
);
1360 Ip4Config2FormUnload (Instance
);
1365 Uninstall the HII Config Access protocol for network devices and free up the resources.
1367 @param[in, out] Instance The IP4 config2 instance to unload a form.
1371 Ip4Config2FormUnload (
1372 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1376 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1377 IP4_CONFIG2_NVDATA
*Ip4NvData
;
1379 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1380 ASSERT (IpSb
!= NULL
);
1382 CallbackInfo
= &Instance
->CallbackInfo
;
1384 if (CallbackInfo
->ChildHandle
!= NULL
) {
1386 // Close the child handle
1388 gBS
->CloseProtocol (
1390 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1392 CallbackInfo
->ChildHandle
1396 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1398 gBS
->UninstallMultipleProtocolInterfaces (
1399 CallbackInfo
->ChildHandle
,
1400 &gEfiDevicePathProtocolGuid
,
1401 CallbackInfo
->HiiVendorDevicePath
,
1402 &gEfiHiiConfigAccessProtocolGuid
,
1403 &CallbackInfo
->HiiConfigAccessProtocol
,
1408 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
1409 FreePool (CallbackInfo
->HiiVendorDevicePath
);
1412 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
1414 // Remove HII package list
1416 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
1419 Ip4NvData
= &Instance
->Ip4NvData
;
1421 if(Ip4NvData
->ManualAddress
!= NULL
) {
1422 FreePool(Ip4NvData
->ManualAddress
);
1425 if(Ip4NvData
->GatewayAddress
!= NULL
) {
1426 FreePool(Ip4NvData
->GatewayAddress
);
1429 if(Ip4NvData
->DnsAddress
!= NULL
) {
1430 FreePool(Ip4NvData
->DnsAddress
);
1433 Ip4NvData
->ManualAddressCount
= 0;
1434 Ip4NvData
->GatewayAddressCount
= 0;
1435 Ip4NvData
->DnsAddressCount
= 0;