2 The driver binding and service binding protocol for DnsDxe driver.
4 Copyright (c) 2015 - 2018, 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 EFI_DRIVER_BINDING_PROTOCOL gDns4DriverBinding
= {
18 Dns4DriverBindingSupported
,
19 Dns4DriverBindingStart
,
20 Dns4DriverBindingStop
,
26 EFI_DRIVER_BINDING_PROTOCOL gDns6DriverBinding
= {
27 Dns6DriverBindingSupported
,
28 Dns6DriverBindingStart
,
29 Dns6DriverBindingStop
,
35 EFI_SERVICE_BINDING_PROTOCOL mDns4ServiceBinding
= {
36 Dns4ServiceBindingCreateChild
,
37 Dns4ServiceBindingDestroyChild
40 EFI_SERVICE_BINDING_PROTOCOL mDns6ServiceBinding
= {
41 Dns6ServiceBindingCreateChild
,
42 Dns6ServiceBindingDestroyChild
45 DNS_DRIVER_DATA
*mDriverData
= NULL
;
48 Destroy the DNS instance and recycle the resources.
50 @param[in] Instance The pointer to the DNS instance.
55 IN DNS_INSTANCE
*Instance
58 ZeroMem (&Instance
->Dns4CfgData
, sizeof (EFI_DNS4_CONFIG_DATA
));
60 ZeroMem (&Instance
->Dns6CfgData
, sizeof (EFI_DNS6_CONFIG_DATA
));
62 if (!NetMapIsEmpty (&Instance
->Dns4TxTokens
)) {
63 Dns4InstanceCancelToken (Instance
, NULL
);
66 if (!NetMapIsEmpty (&Instance
->Dns6TxTokens
)) {
67 Dns6InstanceCancelToken (Instance
, NULL
);
70 if (Instance
->UdpIo
!= NULL
) {
71 UdpIoFreeIo (Instance
->UdpIo
);
78 Create the DNS instance and initialize it.
80 @param[in] Service The pointer to the DNS service.
81 @param[out] Instance The pointer to the DNS instance.
83 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
84 @retval EFI_SUCCESS The DNS instance is created.
89 IN DNS_SERVICE
*Service
,
90 OUT DNS_INSTANCE
**Instance
97 DnsIns
= AllocateZeroPool (sizeof (DNS_INSTANCE
));
99 return EFI_OUT_OF_RESOURCES
;
102 DnsIns
->Signature
= DNS_INSTANCE_SIGNATURE
;
103 InitializeListHead (&DnsIns
->Link
);
104 DnsIns
->State
= DNS_STATE_UNCONFIGED
;
105 DnsIns
->InDestroy
= FALSE
;
106 DnsIns
->Service
= Service
;
108 if (Service
->IpVersion
== IP_VERSION_4
) {
109 CopyMem (&DnsIns
->Dns4
, &mDns4Protocol
, sizeof (DnsIns
->Dns4
));
110 NetMapInit (&DnsIns
->Dns4TxTokens
);
112 CopyMem (&DnsIns
->Dns6
, &mDns6Protocol
, sizeof (DnsIns
->Dns6
));
113 NetMapInit (&DnsIns
->Dns6TxTokens
);
116 DnsIns
->UdpIo
= UdpIoCreateIo (
117 Service
->ControllerHandle
, /// NicHandle
118 Service
->ImageHandle
,
123 if (DnsIns
->UdpIo
== NULL
) {
125 return EFI_OUT_OF_RESOURCES
;
134 Callback function which provided by user to remove one node in NetDestroyLinkList process.
136 @param[in] Entry The entry to be removed.
137 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
139 @retval EFI_SUCCESS The entry has been removed successfully.
140 @retval Others Fail to remove the entry.
145 DnsDestroyChildEntryInHandleBuffer (
146 IN LIST_ENTRY
*Entry
,
150 DNS_INSTANCE
*Instance
;
151 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
152 UINTN NumberOfChildren
;
153 EFI_HANDLE
*ChildHandleBuffer
;
155 if (Entry
== NULL
|| Context
== NULL
) {
156 return EFI_INVALID_PARAMETER
;
159 Instance
= NET_LIST_USER_STRUCT_S (Entry
, DNS_INSTANCE
, Link
, DNS_INSTANCE_SIGNATURE
);
160 ServiceBinding
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
161 NumberOfChildren
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
162 ChildHandleBuffer
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
164 if (!NetIsInHandleBuffer (Instance
->ChildHandle
, NumberOfChildren
, ChildHandleBuffer
)) {
168 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->ChildHandle
);
172 Config a NULL UDP that is used to keep the connection between UDP and DNS.
174 Just leave the Udp child unconfigured. When UDP is unloaded,
175 DNS will be informed with DriverBinding Stop.
177 @param UdpIo The UDP_IO to configure
178 @param Context The opaque parameter to the callback
180 @retval EFI_SUCCESS It always return EFI_SUCCESS directly.
194 Release all the resource used the DNS service binding instance.
196 @param DnsSb The Dns service binding instance.
201 IN DNS_SERVICE
*DnsSb
204 UdpIoFreeIo (DnsSb
->ConnectUdp
);
206 if (DnsSb
->TimerToGetMap
!= NULL
){
207 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
210 if (DnsSb
->Timer
!= NULL
){
211 gBS
->CloseEvent (DnsSb
->Timer
);
218 Create then initialize a Dns service binding instance.
220 @param Controller The controller to install the DNS service
222 @param Image The driver binding image of the DNS driver
223 @param IpVersion IpVersion for this service
224 @param Service The variable to receive the created service
227 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.
228 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep
230 @retval EFI_SUCCESS The service instance is created for the
236 IN EFI_HANDLE Controller
,
239 OUT DNS_SERVICE
**Service
245 Status
= EFI_SUCCESS
;
250 DnsSb
= AllocateZeroPool (sizeof (DNS_SERVICE
));
252 return EFI_OUT_OF_RESOURCES
;
255 DnsSb
->Signature
= DNS_SERVICE_SIGNATURE
;
257 if (IpVersion
== IP_VERSION_4
) {
258 DnsSb
->ServiceBinding
= mDns4ServiceBinding
;
260 DnsSb
->ServiceBinding
= mDns6ServiceBinding
;
263 DnsSb
->Dns4ChildrenNum
= 0;
264 InitializeListHead (&DnsSb
->Dns4ChildrenList
);
266 DnsSb
->Dns6ChildrenNum
= 0;
267 InitializeListHead (&DnsSb
->Dns6ChildrenList
);
269 DnsSb
->ControllerHandle
= Controller
;
270 DnsSb
->ImageHandle
= Image
;
272 DnsSb
->TimerToGetMap
= NULL
;
276 DnsSb
->IpVersion
= IpVersion
;
279 // Create the timer used to time out the procedure which is used to
280 // get the default IP address.
282 Status
= gBS
->CreateEvent (
287 &DnsSb
->TimerToGetMap
289 if (EFI_ERROR (Status
)) {
295 // Create the timer to retransmit packets.
297 Status
= gBS
->CreateEvent (
298 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
300 DnsOnTimerRetransmit
,
304 if (EFI_ERROR (Status
)) {
305 if (DnsSb
->TimerToGetMap
!= NULL
) {
306 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
312 DnsSb
->ConnectUdp
= NULL
;
313 DnsSb
->ConnectUdp
= UdpIoCreateIo (
320 if (DnsSb
->ConnectUdp
== NULL
) {
321 if (DnsSb
->TimerToGetMap
!= NULL
) {
322 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
324 gBS
->CloseEvent (DnsSb
->Timer
);
326 return EFI_DEVICE_ERROR
;
336 @param ImageHandle Handle that identifies the image to be unloaded.
338 @retval EFI_SUCCESS The image has been unloaded.
339 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
345 IN EFI_HANDLE ImageHandle
351 DNS4_CACHE
*ItemCache4
;
352 DNS4_SERVER_IP
*ItemServerIp4
;
353 DNS6_CACHE
*ItemCache6
;
354 DNS6_SERVER_IP
*ItemServerIp6
;
357 ItemServerIp4
= NULL
;
359 ItemServerIp6
= NULL
;
362 // Disconnect the driver specified by ImageHandle
364 Status
= NetLibDefaultUnload(ImageHandle
);
365 if (EFI_ERROR (Status
)) {
372 if (mDriverData
!= NULL
) {
373 if (mDriverData
->Timer
!= NULL
) {
374 gBS
->CloseEvent (mDriverData
->Timer
);
377 while (!IsListEmpty (&mDriverData
->Dns4CacheList
)) {
378 Entry
= NetListRemoveHead (&mDriverData
->Dns4CacheList
);
379 ItemCache4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
380 if (ItemCache4
->DnsCache
.HostName
!= NULL
) {
381 FreePool (ItemCache4
->DnsCache
.HostName
);
383 if (ItemCache4
->DnsCache
.IpAddress
!= NULL
) {
384 FreePool (ItemCache4
->DnsCache
.IpAddress
);
386 FreePool (ItemCache4
);
389 while (!IsListEmpty (&mDriverData
->Dns4ServerList
)) {
390 Entry
= NetListRemoveHead (&mDriverData
->Dns4ServerList
);
391 ItemServerIp4
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
392 FreePool (ItemServerIp4
);
395 while (!IsListEmpty (&mDriverData
->Dns6CacheList
)) {
396 Entry
= NetListRemoveHead (&mDriverData
->Dns6CacheList
);
397 ItemCache6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
398 if (ItemCache6
->DnsCache
.HostName
!= NULL
) {
399 FreePool (ItemCache6
->DnsCache
.HostName
);
401 if (ItemCache6
->DnsCache
.IpAddress
!= NULL
) {
402 FreePool (ItemCache6
->DnsCache
.IpAddress
);
404 FreePool (ItemCache6
);
407 while (!IsListEmpty (&mDriverData
->Dns6ServerList
)) {
408 Entry
= NetListRemoveHead (&mDriverData
->Dns6ServerList
);
409 ItemServerIp6
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
410 FreePool (ItemServerIp6
);
413 FreePool (mDriverData
);
420 This is the declaration of an EFI image entry point. This entry point is
421 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
422 both device drivers and bus drivers.
424 @param ImageHandle The firmware allocated handle for the UEFI image.
425 @param SystemTable A pointer to the EFI System Table.
427 @retval EFI_SUCCESS The operation completed successfully.
428 @retval Others An unexpected error occurred.
432 DnsDriverEntryPoint (
433 IN EFI_HANDLE ImageHandle
,
434 IN EFI_SYSTEM_TABLE
*SystemTable
439 Status
= EFI_SUCCESS
;
442 // Install the Dns4 Driver Binding Protocol.
444 Status
= EfiLibInstallDriverBindingComponentName2 (
452 if (EFI_ERROR (Status
)) {
457 // Install the Dns6 Driver Binding Protocol.
459 Status
= EfiLibInstallDriverBindingComponentName2 (
467 if (EFI_ERROR (Status
)) {
472 // Create the driver data structures.
474 mDriverData
= AllocateZeroPool (sizeof (DNS_DRIVER_DATA
));
475 if (mDriverData
== NULL
) {
476 Status
= EFI_OUT_OF_RESOURCES
;
481 // Create the timer event to update DNS cache list.
483 Status
= gBS
->CreateEvent (
484 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
490 if (EFI_ERROR (Status
)) {
494 Status
= gBS
->SetTimer (mDriverData
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
495 if (EFI_ERROR (Status
)) {
499 InitializeListHead (&mDriverData
->Dns4CacheList
);
500 InitializeListHead (&mDriverData
->Dns4ServerList
);
501 InitializeListHead (&mDriverData
->Dns6CacheList
);
502 InitializeListHead (&mDriverData
->Dns6ServerList
);
507 gBS
->CloseEvent (mDriverData
->Timer
);
510 FreePool (mDriverData
);
513 gBS
->UninstallMultipleProtocolInterfaces (
514 gDns6DriverBinding
.DriverBindingHandle
,
515 &gEfiDriverBindingProtocolGuid
,
517 &gEfiComponentName2ProtocolGuid
,
519 &gEfiComponentNameProtocolGuid
,
525 gBS
->UninstallMultipleProtocolInterfaces (
527 &gEfiDriverBindingProtocolGuid
,
529 &gEfiComponentName2ProtocolGuid
,
531 &gEfiComponentNameProtocolGuid
,
540 Tests to see if this driver supports a given controller. If a child device is provided,
541 it further tests to see if this driver supports creating a handle for the specified child device.
543 This function checks to see if the driver specified by This supports the device specified by
544 ControllerHandle. Drivers will typically use the device path attached to
545 ControllerHandle and/or the services from the bus I/O abstraction attached to
546 ControllerHandle to determine if the driver supports ControllerHandle. This function
547 may be called many times during platform initialization. In order to reduce boot times, the tests
548 performed by this function must be very small, and take as little time as possible to execute. This
549 function must not change the state of any hardware devices, and this function must be aware that the
550 device specified by ControllerHandle may already be managed by the same driver or a
551 different driver. This function must match its calls to AllocatePages() with FreePages(),
552 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
553 Because ControllerHandle may have been previously started by the same driver, if a protocol is
554 already in the opened state, then it must not be closed with CloseProtocol(). This is required
555 to guarantee the state of ControllerHandle is not modified by this function.
557 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
558 @param[in] ControllerHandle The handle of the controller to test. This handle
559 must support a protocol interface that supplies
560 an I/O abstraction to the driver.
561 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
562 parameter is ignored by device drivers, and is optional for bus
563 drivers. For bus drivers, if this parameter is not NULL, then
564 the bus driver must determine if the bus controller specified
565 by ControllerHandle and the child controller specified
566 by RemainingDevicePath are both supported by this
569 @retval EFI_SUCCESS The device specified by ControllerHandle and
570 RemainingDevicePath is supported by the driver specified by This.
571 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
572 RemainingDevicePath is already being managed by the driver
574 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
575 RemainingDevicePath is already being managed by a different
576 driver or an application that requires exclusive access.
577 Currently not implemented.
578 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
579 RemainingDevicePath is not supported by the driver specified by This.
583 Dns4DriverBindingSupported (
584 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
585 IN EFI_HANDLE ControllerHandle
,
586 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
592 // Test for the Dns4ServiceBinding Protocol.
594 Status
= gBS
->OpenProtocol (
596 &gEfiDns4ServiceBindingProtocolGuid
,
598 This
->DriverBindingHandle
,
600 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
602 if (!EFI_ERROR (Status
)) {
603 return EFI_ALREADY_STARTED
;
607 // Test for the Udp4ServiceBinding Protocol.
609 Status
= gBS
->OpenProtocol (
611 &gEfiUdp4ServiceBindingProtocolGuid
,
613 This
->DriverBindingHandle
,
615 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
622 Starts a device controller or a bus controller.
624 The Start() function is designed to be invoked from the EFI boot service ConnectController().
625 As a result, much of the error checking on the parameters to Start() has been moved into this
626 common boot service. It is legal to call Start() from other locations,
627 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
628 1. ControllerHandle must be a valid EFI_HANDLE.
629 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
630 EFI_DEVICE_PATH_PROTOCOL.
631 3. Prior to calling Start(), the Supported() function for the driver specified by This must
632 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
634 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
635 @param[in] ControllerHandle The handle of the controller to start. This handle
636 must support a protocol interface that supplies
637 an I/O abstraction to the driver.
638 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
639 parameter is ignored by device drivers, and is optional for bus
640 drivers. For a bus driver, if this parameter is NULL, then handles
641 for all the children of Controller are created by this driver.
642 If this parameter is not NULL and the first Device Path Node is
643 not the End of Device Path Node, then only the handle for the
644 child device specified by the first Device Path Node of
645 RemainingDevicePath is created by this driver.
646 If the first Device Path Node of RemainingDevicePath is
647 the End of Device Path Node, no child handle is created by this
650 @retval EFI_SUCCESS The device was started.
651 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
652 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
653 @retval Others The driver failded to start the device.
658 Dns4DriverBindingStart (
659 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
660 IN EFI_HANDLE ControllerHandle
,
661 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
667 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
, &DnsSb
);
668 if (EFI_ERROR (Status
)) {
672 ASSERT (DnsSb
!= NULL
);
674 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
675 if (EFI_ERROR (Status
)) {
680 // Install the Dns4ServiceBinding Protocol onto ControllerHandle.
682 Status
= gBS
->InstallMultipleProtocolInterfaces (
684 &gEfiDns4ServiceBindingProtocolGuid
,
685 &DnsSb
->ServiceBinding
,
688 if (EFI_ERROR (Status
)) {
695 DnsDestroyService (DnsSb
);
701 Stops a device controller or a bus controller.
703 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
704 As a result, much of the error checking on the parameters to Stop() has been moved
705 into this common boot service. It is legal to call Stop() from other locations,
706 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
707 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
708 same driver's Start() function.
709 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
710 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
711 Start() function, and the Start() function must have called OpenProtocol() on
712 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
714 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
715 @param[in] ControllerHandle A handle to the device being stopped. The handle must
716 support a bus specific I/O protocol for the driver
717 to use to stop the device.
718 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
719 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
720 if NumberOfChildren is 0.
722 @retval EFI_SUCCESS The device was stopped.
723 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
728 Dns4DriverBindingStop (
729 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
730 IN EFI_HANDLE ControllerHandle
,
731 IN UINTN NumberOfChildren
,
732 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
735 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
737 EFI_HANDLE NicHandle
;
740 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
743 // DNS driver opens UDP child, So, Controller is a UDP
744 // child handle. Locate the Nic handle first. Then get the
745 // DNS private data back.
747 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
749 if (NicHandle
== NULL
) {
753 Status
= gBS
->OpenProtocol (
755 &gEfiDns4ServiceBindingProtocolGuid
,
756 (VOID
**) &ServiceBinding
,
757 This
->DriverBindingHandle
,
759 EFI_OPEN_PROTOCOL_GET_PROTOCOL
761 if (EFI_ERROR (Status
)) {
762 return EFI_DEVICE_ERROR
;
765 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
767 if (!IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
769 // Destroy the Dns child instance in ChildHandleBuffer.
771 List
= &DnsSb
->Dns4ChildrenList
;
772 Context
.ServiceBinding
= ServiceBinding
;
773 Context
.NumberOfChildren
= NumberOfChildren
;
774 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
775 Status
= NetDestroyLinkList (
777 DnsDestroyChildEntryInHandleBuffer
,
783 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
784 gBS
->UninstallProtocolInterface (
786 &gEfiDns4ServiceBindingProtocolGuid
,
790 DnsDestroyService (DnsSb
);
792 if (gDnsControllerNameTable
!= NULL
) {
793 FreeUnicodeStringTable (gDnsControllerNameTable
);
794 gDnsControllerNameTable
= NULL
;
797 Status
= EFI_SUCCESS
;
804 Tests to see if this driver supports a given controller. If a child device is provided,
805 it further tests to see if this driver supports creating a handle for the specified child device.
807 This function checks to see if the driver specified by This supports the device specified by
808 ControllerHandle. Drivers will typically use the device path attached to
809 ControllerHandle and/or the services from the bus I/O abstraction attached to
810 ControllerHandle to determine if the driver supports ControllerHandle. This function
811 may be called many times during platform initialization. In order to reduce boot times, the tests
812 performed by this function must be very small, and take as little time as possible to execute. This
813 function must not change the state of any hardware devices, and this function must be aware that the
814 device specified by ControllerHandle may already be managed by the same driver or a
815 different driver. This function must match its calls to AllocatePages() with FreePages(),
816 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
817 Because ControllerHandle may have been previously started by the same driver, if a protocol is
818 already in the opened state, then it must not be closed with CloseProtocol(). This is required
819 to guarantee the state of ControllerHandle is not modified by this function.
821 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
822 @param[in] ControllerHandle The handle of the controller to test. This handle
823 must support a protocol interface that supplies
824 an I/O abstraction to the driver.
825 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
826 parameter is ignored by device drivers, and is optional for bus
827 drivers. For bus drivers, if this parameter is not NULL, then
828 the bus driver must determine if the bus controller specified
829 by ControllerHandle and the child controller specified
830 by RemainingDevicePath are both supported by this
833 @retval EFI_SUCCESS The device specified by ControllerHandle and
834 RemainingDevicePath is supported by the driver specified by This.
835 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
836 RemainingDevicePath is already being managed by the driver
838 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
839 RemainingDevicePath is already being managed by a different
840 driver or an application that requires exclusive access.
841 Currently not implemented.
842 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
843 RemainingDevicePath is not supported by the driver specified by This.
847 Dns6DriverBindingSupported (
848 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
849 IN EFI_HANDLE ControllerHandle
,
850 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
856 // Test for the Dns6ServiceBinding Protocol
858 Status
= gBS
->OpenProtocol (
860 &gEfiDns6ServiceBindingProtocolGuid
,
862 This
->DriverBindingHandle
,
864 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
866 if (!EFI_ERROR (Status
)) {
867 return EFI_ALREADY_STARTED
;
871 // Test for the Udp6ServiceBinding Protocol
873 Status
= gBS
->OpenProtocol (
875 &gEfiUdp6ServiceBindingProtocolGuid
,
877 This
->DriverBindingHandle
,
879 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
886 Starts a device controller or a bus controller.
888 The Start() function is designed to be invoked from the EFI boot service ConnectController().
889 As a result, much of the error checking on the parameters to Start() has been moved into this
890 common boot service. It is legal to call Start() from other locations,
891 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
892 1. ControllerHandle must be a valid EFI_HANDLE.
893 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
894 EFI_DEVICE_PATH_PROTOCOL.
895 3. Prior to calling Start(), the Supported() function for the driver specified by This must
896 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
898 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
899 @param[in] ControllerHandle The handle of the controller to start. This handle
900 must support a protocol interface that supplies
901 an I/O abstraction to the driver.
902 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
903 parameter is ignored by device drivers, and is optional for bus
904 drivers. For a bus driver, if this parameter is NULL, then handles
905 for all the children of Controller are created by this driver.
906 If this parameter is not NULL and the first Device Path Node is
907 not the End of Device Path Node, then only the handle for the
908 child device specified by the first Device Path Node of
909 RemainingDevicePath is created by this driver.
910 If the first Device Path Node of RemainingDevicePath is
911 the End of Device Path Node, no child handle is created by this
914 @retval EFI_SUCCESS The device was started.
915 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
916 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
917 @retval Others The driver failded to start the device.
922 Dns6DriverBindingStart (
923 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
924 IN EFI_HANDLE ControllerHandle
,
925 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
931 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
, &DnsSb
);
932 if (EFI_ERROR (Status
)) {
936 ASSERT (DnsSb
!= NULL
);
938 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
939 if (EFI_ERROR (Status
)) {
944 // Install the Dns6ServiceBinding Protocol onto ControllerHandle
946 Status
= gBS
->InstallMultipleProtocolInterfaces (
948 &gEfiDns6ServiceBindingProtocolGuid
,
949 &DnsSb
->ServiceBinding
,
953 if (EFI_ERROR (Status
)) {
960 DnsDestroyService (DnsSb
);
966 Stops a device controller or a bus controller.
968 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
969 As a result, much of the error checking on the parameters to Stop() has been moved
970 into this common boot service. It is legal to call Stop() from other locations,
971 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
972 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
973 same driver's Start() function.
974 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
975 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
976 Start() function, and the Start() function must have called OpenProtocol() on
977 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
979 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
980 @param[in] ControllerHandle A handle to the device being stopped. The handle must
981 support a bus specific I/O protocol for the driver
982 to use to stop the device.
983 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
984 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
985 if NumberOfChildren is 0.
987 @retval EFI_SUCCESS The device was stopped.
988 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
993 Dns6DriverBindingStop (
994 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
995 IN EFI_HANDLE ControllerHandle
,
996 IN UINTN NumberOfChildren
,
997 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
1000 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
1002 EFI_HANDLE NicHandle
;
1005 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
1008 // DNS driver opens UDP child, So, Controller is a UDP
1009 // child handle. Locate the Nic handle first. Then get the
1010 // DNS private data back.
1012 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp6ProtocolGuid
);
1014 if (NicHandle
== NULL
) {
1018 Status
= gBS
->OpenProtocol (
1020 &gEfiDns6ServiceBindingProtocolGuid
,
1021 (VOID
**) &ServiceBinding
,
1022 This
->DriverBindingHandle
,
1024 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1026 if (EFI_ERROR (Status
)) {
1027 return EFI_DEVICE_ERROR
;
1030 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
1032 if (!IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1034 // Destroy the Dns child instance in ChildHandleBuffer.
1036 List
= &DnsSb
->Dns6ChildrenList
;
1037 Context
.ServiceBinding
= ServiceBinding
;
1038 Context
.NumberOfChildren
= NumberOfChildren
;
1039 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
1040 Status
= NetDestroyLinkList (
1042 DnsDestroyChildEntryInHandleBuffer
,
1048 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1049 gBS
->UninstallProtocolInterface (
1051 &gEfiDns6ServiceBindingProtocolGuid
,
1055 DnsDestroyService (DnsSb
);
1057 if (gDnsControllerNameTable
!= NULL
) {
1058 FreeUnicodeStringTable (gDnsControllerNameTable
);
1059 gDnsControllerNameTable
= NULL
;
1062 Status
= EFI_SUCCESS
;
1069 Creates a child handle and installs a protocol.
1071 The CreateChild() function installs a protocol on ChildHandle.
1072 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1073 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1075 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1076 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1077 then a new handle is created. If it is a pointer to an existing UEFI handle,
1078 then the protocol is added to the existing UEFI handle.
1080 @retval EFI_SUCCES The protocol was added to ChildHandle.
1081 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1082 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1084 @retval other The child handle was not created
1089 Dns4ServiceBindingCreateChild (
1090 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1091 IN EFI_HANDLE
*ChildHandle
1095 DNS_INSTANCE
*Instance
;
1100 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1101 return EFI_INVALID_PARAMETER
;
1104 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1106 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1107 if (EFI_ERROR (Status
)) {
1110 ASSERT (Instance
!= NULL
);
1113 // Install the DNS protocol onto ChildHandle
1115 Status
= gBS
->InstallMultipleProtocolInterfaces (
1117 &gEfiDns4ProtocolGuid
,
1121 if (EFI_ERROR (Status
)) {
1125 Instance
->ChildHandle
= *ChildHandle
;
1128 // Open the Udp4 protocol BY_CHILD.
1130 Status
= gBS
->OpenProtocol (
1131 DnsSb
->ConnectUdp
->UdpHandle
,
1132 &gEfiUdp4ProtocolGuid
,
1134 gDns4DriverBinding
.DriverBindingHandle
,
1135 Instance
->ChildHandle
,
1136 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1138 if (EFI_ERROR (Status
)) {
1139 gBS
->UninstallMultipleProtocolInterfaces (
1140 Instance
->ChildHandle
,
1141 &gEfiDns4ProtocolGuid
,
1150 // Open the Udp4 protocol by child.
1152 Status
= gBS
->OpenProtocol (
1153 Instance
->UdpIo
->UdpHandle
,
1154 &gEfiUdp4ProtocolGuid
,
1156 gDns4DriverBinding
.DriverBindingHandle
,
1157 Instance
->ChildHandle
,
1158 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1160 if (EFI_ERROR (Status
)) {
1162 // Close the Udp4 protocol.
1164 gBS
->CloseProtocol (
1165 DnsSb
->ConnectUdp
->UdpHandle
,
1166 &gEfiUdp4ProtocolGuid
,
1167 gDns4DriverBinding
.DriverBindingHandle
,
1171 gBS
->UninstallMultipleProtocolInterfaces (
1172 Instance
->ChildHandle
,
1173 &gEfiDns4ProtocolGuid
,
1182 // Add it to the parent's child list.
1184 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1186 InsertTailList (&DnsSb
->Dns4ChildrenList
, &Instance
->Link
);
1187 DnsSb
->Dns4ChildrenNum
++;
1189 gBS
->RestoreTPL (OldTpl
);
1195 DnsDestroyInstance (Instance
);
1200 Destroys a child handle with a protocol installed on it.
1202 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1203 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1204 last protocol on ChildHandle, then ChildHandle is destroyed.
1206 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1207 @param[in] ChildHandle Handle of the child to destroy
1209 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1210 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1211 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1212 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1213 because its services are being used.
1214 @retval other The child handle was not destroyed
1219 Dns4ServiceBindingDestroyChild (
1220 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1221 IN EFI_HANDLE ChildHandle
1225 DNS_INSTANCE
*Instance
;
1227 EFI_DNS4_PROTOCOL
*Dns4
;
1231 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1232 return EFI_INVALID_PARAMETER
;
1236 // Retrieve the private context data structures
1238 Status
= gBS
->OpenProtocol (
1240 &gEfiDns4ProtocolGuid
,
1242 gDns4DriverBinding
.DriverBindingHandle
,
1244 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1247 if (EFI_ERROR (Status
)) {
1248 return EFI_UNSUPPORTED
;
1251 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL4 (Dns4
);
1252 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1254 if (Instance
->Service
!= DnsSb
) {
1255 return EFI_INVALID_PARAMETER
;
1258 if (Instance
->InDestroy
) {
1262 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1264 Instance
->InDestroy
= TRUE
;
1267 // Close the Udp4 protocol.
1269 gBS
->CloseProtocol (
1270 DnsSb
->ConnectUdp
->UdpHandle
,
1271 &gEfiUdp4ProtocolGuid
,
1272 gDns4DriverBinding
.DriverBindingHandle
,
1276 gBS
->CloseProtocol (
1277 Instance
->UdpIo
->UdpHandle
,
1278 &gEfiUdp4ProtocolGuid
,
1279 gDns4DriverBinding
.DriverBindingHandle
,
1283 gBS
->RestoreTPL (OldTpl
);
1286 // Uninstall the DNS protocol first to enable a top down destruction.
1288 Status
= gBS
->UninstallProtocolInterface (
1290 &gEfiDns4ProtocolGuid
,
1294 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1296 if (EFI_ERROR (Status
)) {
1297 Instance
->InDestroy
= FALSE
;
1298 gBS
->RestoreTPL (OldTpl
);
1302 RemoveEntryList (&Instance
->Link
);
1303 DnsSb
->Dns4ChildrenNum
--;
1305 gBS
->RestoreTPL (OldTpl
);
1307 DnsDestroyInstance (Instance
);
1312 Creates a child handle and installs a protocol.
1314 The CreateChild() function installs a protocol on ChildHandle.
1315 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1316 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1318 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1319 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1320 then a new handle is created. If it is a pointer to an existing UEFI handle,
1321 then the protocol is added to the existing UEFI handle.
1323 @retval EFI_SUCCES The protocol was added to ChildHandle.
1324 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1325 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1327 @retval other The child handle was not created
1332 Dns6ServiceBindingCreateChild (
1333 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1334 IN EFI_HANDLE
*ChildHandle
1338 DNS_INSTANCE
*Instance
;
1343 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1344 return EFI_INVALID_PARAMETER
;
1347 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1349 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1350 if (EFI_ERROR (Status
)) {
1353 ASSERT (Instance
!= NULL
);
1356 // Install the DNS protocol onto ChildHandle
1358 Status
= gBS
->InstallMultipleProtocolInterfaces (
1360 &gEfiDns6ProtocolGuid
,
1364 if (EFI_ERROR (Status
)) {
1368 Instance
->ChildHandle
= *ChildHandle
;
1371 // Open the Udp6 protocol BY_CHILD.
1373 Status
= gBS
->OpenProtocol (
1374 DnsSb
->ConnectUdp
->UdpHandle
,
1375 &gEfiUdp6ProtocolGuid
,
1377 gDns6DriverBinding
.DriverBindingHandle
,
1378 Instance
->ChildHandle
,
1379 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1381 if (EFI_ERROR (Status
)) {
1382 gBS
->UninstallMultipleProtocolInterfaces (
1383 Instance
->ChildHandle
,
1384 &gEfiDns6ProtocolGuid
,
1393 // Open the Udp6 protocol by child.
1395 Status
= gBS
->OpenProtocol (
1396 Instance
->UdpIo
->UdpHandle
,
1397 &gEfiUdp6ProtocolGuid
,
1399 gDns6DriverBinding
.DriverBindingHandle
,
1400 Instance
->ChildHandle
,
1401 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1403 if (EFI_ERROR (Status
)) {
1405 // Close the Udp6 protocol.
1407 gBS
->CloseProtocol (
1408 DnsSb
->ConnectUdp
->UdpHandle
,
1409 &gEfiUdp6ProtocolGuid
,
1410 gDns6DriverBinding
.DriverBindingHandle
,
1414 gBS
->UninstallMultipleProtocolInterfaces (
1415 Instance
->ChildHandle
,
1416 &gEfiDns6ProtocolGuid
,
1425 // Add it to the parent's child list.
1427 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1429 InsertTailList (&DnsSb
->Dns6ChildrenList
, &Instance
->Link
);
1430 DnsSb
->Dns6ChildrenNum
++;
1432 gBS
->RestoreTPL (OldTpl
);
1438 DnsDestroyInstance (Instance
);
1443 Destroys a child handle with a protocol installed on it.
1445 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1446 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1447 last protocol on ChildHandle, then ChildHandle is destroyed.
1449 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1450 @param[in] ChildHandle Handle of the child to destroy
1452 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1453 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1454 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1455 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1456 because its services are being used.
1457 @retval other The child handle was not destroyed
1462 Dns6ServiceBindingDestroyChild (
1463 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1464 IN EFI_HANDLE ChildHandle
1468 DNS_INSTANCE
*Instance
;
1470 EFI_DNS6_PROTOCOL
*Dns6
;
1474 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1475 return EFI_INVALID_PARAMETER
;
1479 // Retrieve the private context data structures
1481 Status
= gBS
->OpenProtocol (
1483 &gEfiDns6ProtocolGuid
,
1485 gDns6DriverBinding
.DriverBindingHandle
,
1487 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1490 if (EFI_ERROR (Status
)) {
1491 return EFI_UNSUPPORTED
;
1494 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL6 (Dns6
);
1495 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1497 if (Instance
->Service
!= DnsSb
) {
1498 return EFI_INVALID_PARAMETER
;
1501 if (Instance
->InDestroy
) {
1505 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1507 Instance
->InDestroy
= TRUE
;
1510 // Close the Udp6 protocol.
1512 gBS
->CloseProtocol (
1513 DnsSb
->ConnectUdp
->UdpHandle
,
1514 &gEfiUdp6ProtocolGuid
,
1515 gDns6DriverBinding
.DriverBindingHandle
,
1519 gBS
->CloseProtocol (
1520 Instance
->UdpIo
->UdpHandle
,
1521 &gEfiUdp6ProtocolGuid
,
1522 gDns6DriverBinding
.DriverBindingHandle
,
1526 gBS
->RestoreTPL (OldTpl
);
1529 // Uninstall the DNS protocol first to enable a top down destruction.
1531 Status
= gBS
->UninstallProtocolInterface (
1533 &gEfiDns6ProtocolGuid
,
1537 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1539 if (EFI_ERROR (Status
)) {
1540 Instance
->InDestroy
= FALSE
;
1541 gBS
->RestoreTPL (OldTpl
);
1545 RemoveEntryList (&Instance
->Link
);
1546 DnsSb
->Dns6ChildrenNum
--;
1548 gBS
->RestoreTPL (OldTpl
);
1550 DnsDestroyInstance (Instance
);