3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 #include <Protocol/ServiceBinding.h>
25 #include <Protocol/SimpleNetwork.h>
26 #include <Protocol/LoadedImage.h>
28 #include <Library/NetLib.h>
29 #include <Library/BaseLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/UefiRuntimeServicesTableLib.h>
34 #include <Library/UefiLib.h>
35 #include <Library/MemoryAllocationLib.h>
39 // All the supported IP4 maskes in host byte order.
41 IP4_ADDR mIp4AllMasks
[IP4_MASK_NUM
] = {
80 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
83 Converts the low nibble of a byte to hex unicode character.
85 @param Nibble lower nibble of a byte.
87 @return Hex unicode character.
97 // This library interface is simply obsolete.
98 // Include the source code to user code.
103 return (CHAR16
)(Nibble
+ L
'0');
106 return (CHAR16
)(Nibble
- 0xA + L
'A');
110 Return the length of the mask. If the mask is invalid,
111 return the invalid length 33, which is IP4_MASK_NUM.
112 NetMask is in the host byte order.
114 @param NetMask The netmask to get the length from
116 @return The length of the netmask, IP4_MASK_NUM if the mask isn't
127 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
128 if (NetMask
== mIp4AllMasks
[Index
]) {
139 Return the class of the address, such as class a, b, c.
140 Addr is in host byte order.
142 @param Addr The address to get the class from
144 @return IP address class, such as IP4_ADDR_CLASSA
154 ByteOne
= (UINT8
) (Addr
>> 24);
156 if ((ByteOne
& 0x80) == 0) {
157 return IP4_ADDR_CLASSA
;
159 } else if ((ByteOne
& 0xC0) == 0x80) {
160 return IP4_ADDR_CLASSB
;
162 } else if ((ByteOne
& 0xE0) == 0xC0) {
163 return IP4_ADDR_CLASSC
;
165 } else if ((ByteOne
& 0xF0) == 0xE0) {
166 return IP4_ADDR_CLASSD
;
169 return IP4_ADDR_CLASSE
;
176 Check whether the IP is a valid unicast address according to
177 the netmask. If NetMask is zero, use the IP address's class to
178 get the default mask.
180 @param Ip The IP to check againist
181 @param NetMask The mask of the IP
183 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE
194 Class
= NetGetIpClass (Ip
);
196 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
201 NetMask
= mIp4AllMasks
[Class
<< 3];
204 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
213 Initialize a random seed using current time.
217 @return The random seed initialized with current time.
228 gRT
->GetTime (&Time
, NULL
);
229 Seed
= (~Time
.Hour
<< 24 | Time
.Second
<< 16 | Time
.Minute
<< 8 | Time
.Day
);
230 Seed
^= Time
.Nanosecond
;
231 Seed
^= Time
.Year
<< 7;
238 Extract a UINT32 from a byte stream, then convert it to host
239 byte order. Use this function to avoid alignment error.
241 @param Buf The buffer to extract the UINT32.
243 @return The UINT32 extracted.
253 NetCopyMem (&Value
, Buf
, sizeof (UINT32
));
254 return NTOHL (Value
);
259 Put a UINT32 to the byte stream. Convert it from host byte order
260 to network byte order before putting.
262 @param Buf The buffer to put the UINT32
263 @param Data The data to put
275 NetCopyMem (Buf
, &Data
, sizeof (UINT32
));
280 Remove the first entry on the list
282 @param Head The list header
284 @return The entry that is removed from the list, NULL if the list is empty.
292 NET_LIST_ENTRY
*First
;
294 ASSERT (Head
!= NULL
);
296 if (NetListIsEmpty (Head
)) {
300 First
= Head
->ForwardLink
;
301 Head
->ForwardLink
= First
->ForwardLink
;
302 First
->ForwardLink
->BackLink
= Head
;
305 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
306 First
->BackLink
= (LIST_ENTRY
*) NULL
;
314 Remove the last entry on the list
316 @param Head The list head
318 @return The entry that is removed from the list, NULL if the list is empty.
326 NET_LIST_ENTRY
*Last
;
328 ASSERT (Head
!= NULL
);
330 if (NetListIsEmpty (Head
)) {
334 Last
= Head
->BackLink
;
335 Head
->BackLink
= Last
->BackLink
;
336 Last
->BackLink
->ForwardLink
= Head
;
339 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
340 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
348 Insert the NewEntry after the PrevEntry
350 @param PrevEntry The previous entry to insert after
351 @param NewEntry The new entry to insert
358 IN NET_LIST_ENTRY
*PrevEntry
,
359 IN NET_LIST_ENTRY
*NewEntry
362 NewEntry
->BackLink
= PrevEntry
;
363 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
364 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
365 PrevEntry
->ForwardLink
= NewEntry
;
370 Insert the NewEntry before the PostEntry
372 @param PostEntry The entry to insert before
373 @param NewEntry The new entry to insert
379 NetListInsertBefore (
380 IN NET_LIST_ENTRY
*PostEntry
,
381 IN NET_LIST_ENTRY
*NewEntry
384 NewEntry
->ForwardLink
= PostEntry
;
385 NewEntry
->BackLink
= PostEntry
->BackLink
;
386 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
387 PostEntry
->BackLink
= NewEntry
;
392 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
394 @param Map The netmap to initialize
404 ASSERT (Map
!= NULL
);
406 NetListInit (&Map
->Used
);
407 NetListInit (&Map
->Recycled
);
413 To clean up the netmap, that is, release allocated memories.
415 @param Map The netmap to clean up.
426 NET_LIST_ENTRY
*Entry
;
427 NET_LIST_ENTRY
*Next
;
429 ASSERT (Map
!= NULL
);
431 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
432 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
434 NetListRemoveEntry (&Item
->Link
);
440 ASSERT ((Map
->Count
== 0) && NetListIsEmpty (&Map
->Used
));
442 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
443 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
445 NetListRemoveEntry (&Item
->Link
);
449 ASSERT (NetListIsEmpty (&Map
->Recycled
));
454 Test whether the netmap is empty
456 @param Map The net map to test
458 @return TRUE if the netmap is empty, otherwise FALSE.
466 ASSERT (Map
!= NULL
);
467 return (BOOLEAN
) (Map
->Count
== 0);
472 Return the number of the <Key, Value> pairs in the netmap.
474 @param Map The netmap to get the entry number
476 @return The entry number in the netmap.
489 Allocate an item for the netmap. It will try to allocate
490 a batch of items and return one.
492 @param Map The netmap to allocate item for
494 @return The allocated item or NULL
504 NET_LIST_ENTRY
*Head
;
507 ASSERT (Map
!= NULL
);
509 Head
= &Map
->Recycled
;
511 if (NetListIsEmpty (Head
)) {
512 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
513 Item
= NetAllocatePool (sizeof (NET_MAP_ITEM
));
523 NetListInsertHead (Head
, &Item
->Link
);
527 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
528 NetListRemoveHead (Head
);
535 Allocate an item to save the <Key, Value> pair to the head of the netmap.
537 @param Map The netmap to insert into
538 @param Key The user's key
539 @param Value The user's value for the key
541 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
542 @retval EFI_SUCCESS The item is inserted to the head
549 IN VOID
*Value OPTIONAL
554 ASSERT (Map
!= NULL
);
556 Item
= NetMapAllocItem (Map
);
559 return EFI_OUT_OF_RESOURCES
;
564 NetListInsertHead (&Map
->Used
, &Item
->Link
);
572 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
574 @param Map The netmap to insert into
575 @param Key The user's key
576 @param Value The user's value for the key
578 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
579 @retval EFI_SUCCESS The item is inserted to the tail
586 IN VOID
*Value OPTIONAL
591 ASSERT (Map
!= NULL
);
593 Item
= NetMapAllocItem (Map
);
596 return EFI_OUT_OF_RESOURCES
;
601 NetListInsertTail (&Map
->Used
, &Item
->Link
);
610 Check whther the item is in the Map
612 @param Map The netmap to search within
613 @param Item The item to search
615 @return TRUE if the item is in the netmap, otherwise FALSE.
622 IN NET_MAP_ITEM
*Item
625 NET_LIST_ENTRY
*ListEntry
;
627 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
628 if (ListEntry
== &Item
->Link
) {
638 Find the key in the netmap
640 @param Map The netmap to search within
641 @param Key The key to search
643 @return The point to the item contains the Key, or NULL if Key isn't in the map.
652 NET_LIST_ENTRY
*Entry
;
655 ASSERT (Map
!= NULL
);
657 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
658 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
660 if (Item
->Key
== Key
) {
670 Remove the item from the netmap
672 @param Map The netmap to remove the item from
673 @param Item The item to remove
674 @param Value The variable to receive the value if not NULL
676 @return The key of the removed item.
682 IN NET_MAP_ITEM
*Item
,
683 OUT VOID
**Value OPTIONAL
686 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
687 ASSERT (NetItemInMap (Map
, Item
));
689 NetListRemoveEntry (&Item
->Link
);
691 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
694 *Value
= Item
->Value
;
702 Remove the first entry on the netmap
704 @param Map The netmap to remove the head from
705 @param Value The variable to receive the value if not NULL
707 @return The key of the item removed
713 OUT VOID
**Value OPTIONAL
719 // Often, it indicates a programming error to remove
720 // the first entry in an empty list
722 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
724 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
725 NetListRemoveEntry (&Item
->Link
);
727 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
730 *Value
= Item
->Value
;
738 Remove the last entry on the netmap
740 @param Map The netmap to remove the tail from
741 @param Value The variable to receive the value if not NULL
743 @return The key of the item removed
749 OUT VOID
**Value OPTIONAL
755 // Often, it indicates a programming error to remove
756 // the last entry in an empty list
758 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
760 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
761 NetListRemoveEntry (&Item
->Link
);
763 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
766 *Value
= Item
->Value
;
774 Iterate through the netmap and call CallBack for each item. It will
775 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
776 from the loop. It returns the CallBack's last return value. This
777 function is delete safe for the current item.
779 @param Map The Map to iterate through
780 @param CallBack The callback function to call for each item.
781 @param Arg The opaque parameter to the callback
783 @return It returns the CallBack's last return value.
789 IN NET_MAP_CALLBACK CallBack
,
794 NET_LIST_ENTRY
*Entry
;
795 NET_LIST_ENTRY
*Next
;
796 NET_LIST_ENTRY
*Head
;
800 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
804 if (NetListIsEmpty (Head
)) {
808 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
809 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
810 Result
= CallBack (Map
, Item
, Arg
);
812 if (EFI_ERROR (Result
)) {
822 This is the default unload handle for all the network drivers.
824 @param ImageHandle The drivers' driver image.
826 @retval EFI_SUCCESS The image is unloaded.
827 @retval Others Failed to unload the image.
832 NetLibDefaultUnload (
833 IN EFI_HANDLE ImageHandle
837 EFI_HANDLE
*DeviceHandleBuffer
;
838 UINTN DeviceHandleCount
;
840 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
841 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
842 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName
;
844 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
846 EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
;
847 EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
;
850 // Get the list of all the handles in the handle database.
851 // If there is an error getting the list, then the unload
854 Status
= gBS
->LocateHandleBuffer (
862 if (EFI_ERROR (Status
)) {
867 // Disconnect the driver specified by ImageHandle from all
868 // the devices in the handle database.
870 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
871 Status
= gBS
->DisconnectController (
872 DeviceHandleBuffer
[Index
],
879 // Uninstall all the protocols installed in the driver entry point
881 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
882 Status
= gBS
->HandleProtocol (
883 DeviceHandleBuffer
[Index
],
884 &gEfiDriverBindingProtocolGuid
,
885 (VOID
**) &DriverBinding
888 if (EFI_ERROR (Status
)) {
892 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
896 gBS
->UninstallProtocolInterface (
898 &gEfiDriverBindingProtocolGuid
,
901 Status
= gBS
->HandleProtocol (
902 DeviceHandleBuffer
[Index
],
903 &gEfiComponentNameProtocolGuid
,
904 (VOID
**) &ComponentName
906 if (!EFI_ERROR (Status
)) {
907 gBS
->UninstallProtocolInterface (
909 &gEfiComponentNameProtocolGuid
,
914 Status
= gBS
->HandleProtocol (
915 DeviceHandleBuffer
[Index
],
916 &gEfiDriverConfigurationProtocolGuid
,
917 (VOID
**) &DriverConfiguration
920 if (!EFI_ERROR (Status
)) {
921 gBS
->UninstallProtocolInterface (
923 &gEfiDriverConfigurationProtocolGuid
,
928 Status
= gBS
->HandleProtocol (
929 DeviceHandleBuffer
[Index
],
930 &gEfiDriverDiagnosticsProtocolGuid
,
931 (VOID
**) &DriverDiagnostics
934 if (!EFI_ERROR (Status
)) {
935 gBS
->UninstallProtocolInterface (
937 &gEfiDriverDiagnosticsProtocolGuid
,
944 // Free the buffer containing the list of handles from the handle database
946 if (DeviceHandleBuffer
!= NULL
) {
947 gBS
->FreePool (DeviceHandleBuffer
);
956 Create a child of the service that is identified by ServiceBindingGuid.
958 @param Controller The controller which has the service installed.
959 @param Image The image handle used to open service.
960 @param ServiceBindingGuid The service's Guid.
961 @param ChildHandle The handle to receive the create child
963 @retval EFI_SUCCESS The child is successfully created.
964 @retval Others Failed to create the child.
968 NetLibCreateServiceChild (
969 IN EFI_HANDLE Controller
,
971 IN EFI_GUID
*ServiceBindingGuid
,
972 OUT EFI_HANDLE
*ChildHandle
976 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
979 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
982 // Get the ServiceBinding Protocol
984 Status
= gBS
->OpenProtocol (
990 EFI_OPEN_PROTOCOL_GET_PROTOCOL
993 if (EFI_ERROR (Status
)) {
1000 Status
= Service
->CreateChild (Service
, ChildHandle
);
1006 Destory a child of the service that is identified by ServiceBindingGuid.
1008 @param Controller The controller which has the service installed.
1009 @param Image The image handle used to open service.
1010 @param ServiceBindingGuid The service's Guid.
1011 @param ChildHandle The child to destory
1013 @retval EFI_SUCCESS The child is successfully destoried.
1014 @retval Others Failed to destory the child.
1018 NetLibDestroyServiceChild (
1019 IN EFI_HANDLE Controller
,
1020 IN EFI_HANDLE Image
,
1021 IN EFI_GUID
*ServiceBindingGuid
,
1022 IN EFI_HANDLE ChildHandle
1026 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1028 ASSERT (ServiceBindingGuid
!= NULL
);
1031 // Get the ServiceBinding Protocol
1033 Status
= gBS
->OpenProtocol (
1039 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1042 if (EFI_ERROR (Status
)) {
1047 // destory the child
1049 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1055 Convert the mac address of the simple network protocol installed on
1056 SnpHandle to a unicode string. Callers are responsible for freeing the
1059 @param SnpHandle The handle where the simple network protocol is
1061 @param ImageHandle The image handle used to act as the agent handle to
1062 get the simple network protocol.
1063 @param MacString The pointer to store the address of the string
1064 representation of the mac address.
1066 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1067 @retval other Failed to open the simple network protocol.
1071 NetLibGetMacString (
1072 IN EFI_HANDLE SnpHandle
,
1073 IN EFI_HANDLE ImageHandle
,
1074 IN OUT CHAR16
**MacString
1078 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1079 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1086 // Get the Simple Network protocol from the SnpHandle.
1088 Status
= gBS
->OpenProtocol (
1090 &gEfiSimpleNetworkProtocolGuid
,
1094 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1096 if (EFI_ERROR (Status
)) {
1103 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1104 // Plus one unicode character for the null-terminator.
1106 MacAddress
= NetAllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1107 if (MacAddress
== NULL
) {
1108 return EFI_OUT_OF_RESOURCES
;
1112 // Convert the mac address into a unicode string.
1114 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1115 MacAddress
[Index
* 2] = NibbleToHexChar ((UINT8
) (Mode
->CurrentAddress
.Addr
[Index
] >> 4));
1116 MacAddress
[Index
* 2 + 1] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
]);
1119 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1121 *MacString
= MacAddress
;
1128 Find the UNDI/SNP handle from controller and protocol GUID.
1129 For example, IP will open a MNP child to transmit/receive
1130 packets, when MNP is stopped, IP should also be stopped. IP
1131 needs to find its own private data which is related the IP's
1132 service binding instance that is install on UNDI/SNP handle.
1133 Now, the controller is either a MNP or ARP child handle. But
1134 IP opens these handle BY_DRIVER, use that info, we can get the
1137 @param Controller Then protocol handle to check
1138 @param ProtocolGuid The protocol that is related with the handle.
1140 @return The UNDI/SNP handle or NULL.
1144 NetLibGetNicHandle (
1145 IN EFI_HANDLE Controller
,
1146 IN EFI_GUID
*ProtocolGuid
1149 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1155 Status
= gBS
->OpenProtocolInformation (
1162 if (EFI_ERROR (Status
)) {
1168 for (Index
= 0; Index
< OpenCount
; Index
++) {
1169 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1170 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1175 gBS
->FreePool (OpenBuffer
);
1180 NetLibInstallAllDriverProtocols (
1181 IN EFI_HANDLE ImageHandle
,
1182 IN EFI_SYSTEM_TABLE
*SystemTable
,
1183 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
1184 IN EFI_HANDLE DriverBindingHandle
,
1185 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
1186 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
1187 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics OPTIONAL
1191 Routine Description:
1193 Intialize a driver by installing the Driver Binding Protocol onto the
1194 driver's DriverBindingHandle. This is typically the same as the driver's
1195 ImageHandle, but it can be different if the driver produces multiple
1196 DriverBinding Protocols. This function also initializes the EFI Driver
1197 Library that initializes the global variables gST, gBS, gRT.
1201 ImageHandle - The image handle of the driver
1202 SystemTable - The EFI System Table that was passed to the driver's
1204 DriverBinding - A Driver Binding Protocol instance that this driver
1206 DriverBindingHandle - The handle that DriverBinding is to be installe onto.
1207 If this parameter is NULL, then a new handle is created.
1208 ComponentName - A Component Name Protocol instance that this driver is
1210 DriverConfiguration - A Driver Configuration Protocol instance that this
1211 driver is producing.
1212 DriverDiagnostics - A Driver Diagnostics Protocol instance that this
1213 driver is producing.
1217 EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
1218 Otherwise, then return status from gBS->InstallProtocolInterface()
1222 return NetLibInstallAllDriverProtocolsWithUnload (
1226 DriverBindingHandle
,
1228 DriverConfiguration
,
1235 NetLibInstallAllDriverProtocolsWithUnload (
1236 IN EFI_HANDLE ImageHandle
,
1237 IN EFI_SYSTEM_TABLE
*SystemTable
,
1238 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
1239 IN EFI_HANDLE DriverBindingHandle
,
1240 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
1241 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
1242 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
, OPTIONAL
1243 IN NET_LIB_DRIVER_UNLOAD Unload
1247 Routine Description:
1249 Intialize a driver by installing the Driver Binding Protocol onto the
1250 driver's DriverBindingHandle. This is typically the same as the driver's
1251 ImageHandle, but it can be different if the driver produces multiple
1252 DriverBinding Protocols. This function also initializes the EFI Driver
1253 Library that initializes the global variables gST, gBS, gRT.
1257 ImageHandle - The image handle of the driver
1258 SystemTable - The EFI System Table that was passed to the driver's
1260 DriverBinding - A Driver Binding Protocol instance that this driver
1262 DriverBindingHandle - The handle that DriverBinding is to be installe onto.
1263 If this parameter is NULL, then a new handle is created.
1264 ComponentName - A Component Name Protocol instance that this driver is
1266 DriverConfiguration - A Driver Configuration Protocol instance that this
1267 driver is producing.
1268 DriverDiagnostics - A Driver Diagnostics Protocol instance that this
1269 driver is producing.
1270 Unload - The customized unload to install.
1274 EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
1275 Otherwise, then return status from gBS->InstallProtocolInterface()
1280 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
1282 Status
= EfiLibInstallAllDriverProtocols (
1286 DriverBindingHandle
,
1288 DriverConfiguration
,
1292 if (EFI_ERROR (Status
)) {
1297 // Retrieve the Loaded Image Protocol from Image Handle
1299 Status
= gBS
->OpenProtocol (
1301 &gEfiLoadedImageProtocolGuid
,
1302 (VOID
**) &LoadedImage
,
1305 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1308 if (EFI_ERROR (Status
)) {
1313 // Fill in the Unload() service of the Loaded Image Protocol
1315 LoadedImage
->Unload
= (Unload
== NULL
) ? NetLibDefaultUnload
: Unload
;