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
] = {
82 Converts the low nibble of a byte to hex unicode character.
84 @param Nibble lower nibble of a byte.
86 @return Hex unicode character.
96 // This library interface is simply obsolete.
97 // Include the source code to user code.
102 return (CHAR16
)(Nibble
+ L
'0');
105 return (CHAR16
)(Nibble
- 0xA + L
'A');
109 Return the length of the mask. If the mask is invalid,
110 return the invalid length 33, which is IP4_MASK_NUM.
111 NetMask is in the host byte order.
113 @param NetMask The netmask to get the length from
115 @return The length of the netmask, IP4_MASK_NUM if the mask isn't
126 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
127 if (NetMask
== mIp4AllMasks
[Index
]) {
138 Return the class of the address, such as class a, b, c.
139 Addr is in host byte order.
141 @param Addr The address to get the class from
143 @return IP address class, such as IP4_ADDR_CLASSA
153 ByteOne
= (UINT8
) (Addr
>> 24);
155 if ((ByteOne
& 0x80) == 0) {
156 return IP4_ADDR_CLASSA
;
158 } else if ((ByteOne
& 0xC0) == 0x80) {
159 return IP4_ADDR_CLASSB
;
161 } else if ((ByteOne
& 0xE0) == 0xC0) {
162 return IP4_ADDR_CLASSC
;
164 } else if ((ByteOne
& 0xF0) == 0xE0) {
165 return IP4_ADDR_CLASSD
;
168 return IP4_ADDR_CLASSE
;
175 Check whether the IP is a valid unicast address according to
176 the netmask. If NetMask is zero, use the IP address's class to
177 get the default mask.
179 @param Ip The IP to check againist
180 @param NetMask The mask of the IP
182 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE
193 Class
= NetGetIpClass (Ip
);
195 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
200 NetMask
= mIp4AllMasks
[Class
<< 3];
203 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
212 Initialize a random seed using current time.
216 @return The random seed initialized with current time.
227 gRT
->GetTime (&Time
, NULL
);
228 Seed
= (~Time
.Hour
<< 24 | Time
.Second
<< 16 | Time
.Minute
<< 8 | Time
.Day
);
229 Seed
^= Time
.Nanosecond
;
230 Seed
^= Time
.Year
<< 7;
237 Extract a UINT32 from a byte stream, then convert it to host
238 byte order. Use this function to avoid alignment error.
240 @param Buf The buffer to extract the UINT32.
242 @return The UINT32 extracted.
252 NetCopyMem (&Value
, Buf
, sizeof (UINT32
));
253 return NTOHL (Value
);
258 Put a UINT32 to the byte stream. Convert it from host byte order
259 to network byte order before putting.
261 @param Buf The buffer to put the UINT32
262 @param Data The data to put
274 NetCopyMem (Buf
, &Data
, sizeof (UINT32
));
279 Remove the first entry on the list
281 @param Head The list header
283 @return The entry that is removed from the list, NULL if the list is empty.
291 NET_LIST_ENTRY
*First
;
293 ASSERT (Head
!= NULL
);
295 if (NetListIsEmpty (Head
)) {
299 First
= Head
->ForwardLink
;
300 Head
->ForwardLink
= First
->ForwardLink
;
301 First
->ForwardLink
->BackLink
= Head
;
304 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
305 First
->BackLink
= (LIST_ENTRY
*) NULL
;
313 Remove the last entry on the list
315 @param Head The list head
317 @return The entry that is removed from the list, NULL if the list is empty.
325 NET_LIST_ENTRY
*Last
;
327 ASSERT (Head
!= NULL
);
329 if (NetListIsEmpty (Head
)) {
333 Last
= Head
->BackLink
;
334 Head
->BackLink
= Last
->BackLink
;
335 Last
->BackLink
->ForwardLink
= Head
;
338 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
339 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
347 Insert the NewEntry after the PrevEntry
349 @param PrevEntry The previous entry to insert after
350 @param NewEntry The new entry to insert
357 IN NET_LIST_ENTRY
*PrevEntry
,
358 IN NET_LIST_ENTRY
*NewEntry
361 NewEntry
->BackLink
= PrevEntry
;
362 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
363 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
364 PrevEntry
->ForwardLink
= NewEntry
;
369 Insert the NewEntry before the PostEntry
371 @param PostEntry The entry to insert before
372 @param NewEntry The new entry to insert
378 NetListInsertBefore (
379 IN NET_LIST_ENTRY
*PostEntry
,
380 IN NET_LIST_ENTRY
*NewEntry
383 NewEntry
->ForwardLink
= PostEntry
;
384 NewEntry
->BackLink
= PostEntry
->BackLink
;
385 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
386 PostEntry
->BackLink
= NewEntry
;
391 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
393 @param Map The netmap to initialize
403 ASSERT (Map
!= NULL
);
405 NetListInit (&Map
->Used
);
406 NetListInit (&Map
->Recycled
);
412 To clean up the netmap, that is, release allocated memories.
414 @param Map The netmap to clean up.
425 NET_LIST_ENTRY
*Entry
;
426 NET_LIST_ENTRY
*Next
;
428 ASSERT (Map
!= NULL
);
430 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
431 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
433 NetListRemoveEntry (&Item
->Link
);
439 ASSERT ((Map
->Count
== 0) && NetListIsEmpty (&Map
->Used
));
441 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
442 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
444 NetListRemoveEntry (&Item
->Link
);
448 ASSERT (NetListIsEmpty (&Map
->Recycled
));
453 Test whether the netmap is empty
455 @param Map The net map to test
457 @return TRUE if the netmap is empty, otherwise FALSE.
465 ASSERT (Map
!= NULL
);
466 return (BOOLEAN
) (Map
->Count
== 0);
471 Return the number of the <Key, Value> pairs in the netmap.
473 @param Map The netmap to get the entry number
475 @return The entry number in the netmap.
488 Allocate an item for the netmap. It will try to allocate
489 a batch of items and return one.
491 @param Map The netmap to allocate item for
493 @return The allocated item or NULL
503 NET_LIST_ENTRY
*Head
;
506 ASSERT (Map
!= NULL
);
508 Head
= &Map
->Recycled
;
510 if (NetListIsEmpty (Head
)) {
511 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
512 Item
= NetAllocatePool (sizeof (NET_MAP_ITEM
));
522 NetListInsertHead (Head
, &Item
->Link
);
526 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
527 NetListRemoveHead (Head
);
534 Allocate an item to save the <Key, Value> pair to the head of the netmap.
536 @param Map The netmap to insert into
537 @param Key The user's key
538 @param Value The user's value for the key
540 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
541 @retval EFI_SUCCESS The item is inserted to the head
548 IN VOID
*Value OPTIONAL
553 ASSERT (Map
!= NULL
);
555 Item
= NetMapAllocItem (Map
);
558 return EFI_OUT_OF_RESOURCES
;
563 NetListInsertHead (&Map
->Used
, &Item
->Link
);
571 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
573 @param Map The netmap to insert into
574 @param Key The user's key
575 @param Value The user's value for the key
577 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
578 @retval EFI_SUCCESS The item is inserted to the tail
585 IN VOID
*Value OPTIONAL
590 ASSERT (Map
!= NULL
);
592 Item
= NetMapAllocItem (Map
);
595 return EFI_OUT_OF_RESOURCES
;
600 NetListInsertTail (&Map
->Used
, &Item
->Link
);
609 Check whther the item is in the Map
611 @param Map The netmap to search within
612 @param Item The item to search
614 @return TRUE if the item is in the netmap, otherwise FALSE.
621 IN NET_MAP_ITEM
*Item
624 NET_LIST_ENTRY
*ListEntry
;
626 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
627 if (ListEntry
== &Item
->Link
) {
637 Find the key in the netmap
639 @param Map The netmap to search within
640 @param Key The key to search
642 @return The point to the item contains the Key, or NULL if Key isn't in the map.
651 NET_LIST_ENTRY
*Entry
;
654 ASSERT (Map
!= NULL
);
656 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
657 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
659 if (Item
->Key
== Key
) {
669 Remove the item from the netmap
671 @param Map The netmap to remove the item from
672 @param Item The item to remove
673 @param Value The variable to receive the value if not NULL
675 @return The key of the removed item.
681 IN NET_MAP_ITEM
*Item
,
682 OUT VOID
**Value OPTIONAL
685 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
686 ASSERT (NetItemInMap (Map
, Item
));
688 NetListRemoveEntry (&Item
->Link
);
690 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
693 *Value
= Item
->Value
;
701 Remove the first entry on the netmap
703 @param Map The netmap to remove the head from
704 @param Value The variable to receive the value if not NULL
706 @return The key of the item removed
712 OUT VOID
**Value OPTIONAL
718 // Often, it indicates a programming error to remove
719 // the first entry in an empty list
721 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
723 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
724 NetListRemoveEntry (&Item
->Link
);
726 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
729 *Value
= Item
->Value
;
737 Remove the last entry on the netmap
739 @param Map The netmap to remove the tail from
740 @param Value The variable to receive the value if not NULL
742 @return The key of the item removed
748 OUT VOID
**Value OPTIONAL
754 // Often, it indicates a programming error to remove
755 // the last entry in an empty list
757 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
759 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
760 NetListRemoveEntry (&Item
->Link
);
762 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
765 *Value
= Item
->Value
;
773 Iterate through the netmap and call CallBack for each item. It will
774 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
775 from the loop. It returns the CallBack's last return value. This
776 function is delete safe for the current item.
778 @param Map The Map to iterate through
779 @param CallBack The callback function to call for each item.
780 @param Arg The opaque parameter to the callback
782 @return It returns the CallBack's last return value.
788 IN NET_MAP_CALLBACK CallBack
,
793 NET_LIST_ENTRY
*Entry
;
794 NET_LIST_ENTRY
*Next
;
795 NET_LIST_ENTRY
*Head
;
799 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
803 if (NetListIsEmpty (Head
)) {
807 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
808 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
809 Result
= CallBack (Map
, Item
, Arg
);
811 if (EFI_ERROR (Result
)) {
821 This is the default unload handle for all the network drivers.
823 @param ImageHandle The drivers' driver image.
825 @retval EFI_SUCCESS The image is unloaded.
826 @retval Others Failed to unload the image.
831 NetLibDefaultUnload (
832 IN EFI_HANDLE ImageHandle
836 EFI_HANDLE
*DeviceHandleBuffer
;
837 UINTN DeviceHandleCount
;
839 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
840 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
841 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName
;
843 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
845 EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
;
846 EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
;
849 // Get the list of all the handles in the handle database.
850 // If there is an error getting the list, then the unload
853 Status
= gBS
->LocateHandleBuffer (
861 if (EFI_ERROR (Status
)) {
866 // Disconnect the driver specified by ImageHandle from all
867 // the devices in the handle database.
869 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
870 Status
= gBS
->DisconnectController (
871 DeviceHandleBuffer
[Index
],
878 // Uninstall all the protocols installed in the driver entry point
880 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
881 Status
= gBS
->HandleProtocol (
882 DeviceHandleBuffer
[Index
],
883 &gEfiDriverBindingProtocolGuid
,
887 if (EFI_ERROR (Status
)) {
891 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
895 gBS
->UninstallProtocolInterface (
897 &gEfiDriverBindingProtocolGuid
,
900 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
901 Status
= gBS
->HandleProtocol (
902 DeviceHandleBuffer
[Index
],
903 &gEfiComponentName2ProtocolGuid
,
906 if (!EFI_ERROR (Status
)) {
907 gBS
->UninstallProtocolInterface (
909 &gEfiComponentName2ProtocolGuid
,
914 Status
= gBS
->HandleProtocol (
915 DeviceHandleBuffer
[Index
],
916 &gEfiComponentNameProtocolGuid
,
919 if (!EFI_ERROR (Status
)) {
920 gBS
->UninstallProtocolInterface (
922 &gEfiComponentNameProtocolGuid
,
928 Status
= gBS
->HandleProtocol (
929 DeviceHandleBuffer
[Index
],
930 &gEfiDriverConfigurationProtocolGuid
,
934 if (!EFI_ERROR (Status
)) {
935 gBS
->UninstallProtocolInterface (
937 &gEfiDriverConfigurationProtocolGuid
,
942 Status
= gBS
->HandleProtocol (
943 DeviceHandleBuffer
[Index
],
944 &gEfiDriverDiagnosticsProtocolGuid
,
948 if (!EFI_ERROR (Status
)) {
949 gBS
->UninstallProtocolInterface (
951 &gEfiDriverDiagnosticsProtocolGuid
,
958 // Free the buffer containing the list of handles from the handle database
960 if (DeviceHandleBuffer
!= NULL
) {
961 gBS
->FreePool (DeviceHandleBuffer
);
970 Create a child of the service that is identified by ServiceBindingGuid.
972 @param Controller The controller which has the service installed.
973 @param Image The image handle used to open service.
974 @param ServiceBindingGuid The service's Guid.
975 @param ChildHandle The handle to receive the create child
977 @retval EFI_SUCCESS The child is successfully created.
978 @retval Others Failed to create the child.
982 NetLibCreateServiceChild (
983 IN EFI_HANDLE Controller
,
985 IN EFI_GUID
*ServiceBindingGuid
,
986 OUT EFI_HANDLE
*ChildHandle
990 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
993 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
996 // Get the ServiceBinding Protocol
998 Status
= gBS
->OpenProtocol (
1004 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1007 if (EFI_ERROR (Status
)) {
1014 Status
= Service
->CreateChild (Service
, ChildHandle
);
1020 Destory a child of the service that is identified by ServiceBindingGuid.
1022 @param Controller The controller which has the service installed.
1023 @param Image The image handle used to open service.
1024 @param ServiceBindingGuid The service's Guid.
1025 @param ChildHandle The child to destory
1027 @retval EFI_SUCCESS The child is successfully destoried.
1028 @retval Others Failed to destory the child.
1032 NetLibDestroyServiceChild (
1033 IN EFI_HANDLE Controller
,
1034 IN EFI_HANDLE Image
,
1035 IN EFI_GUID
*ServiceBindingGuid
,
1036 IN EFI_HANDLE ChildHandle
1040 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1042 ASSERT (ServiceBindingGuid
!= NULL
);
1045 // Get the ServiceBinding Protocol
1047 Status
= gBS
->OpenProtocol (
1053 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1056 if (EFI_ERROR (Status
)) {
1061 // destory the child
1063 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1069 Convert the mac address of the simple network protocol installed on
1070 SnpHandle to a unicode string. Callers are responsible for freeing the
1073 @param SnpHandle The handle where the simple network protocol is
1075 @param ImageHandle The image handle used to act as the agent handle to
1076 get the simple network protocol.
1077 @param MacString The pointer to store the address of the string
1078 representation of the mac address.
1080 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1081 @retval other Failed to open the simple network protocol.
1085 NetLibGetMacString (
1086 IN EFI_HANDLE SnpHandle
,
1087 IN EFI_HANDLE ImageHandle
,
1088 IN OUT CONST CHAR16
**MacString
1092 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1093 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1100 // Get the Simple Network protocol from the SnpHandle.
1102 Status
= gBS
->OpenProtocol (
1104 &gEfiSimpleNetworkProtocolGuid
,
1108 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1110 if (EFI_ERROR (Status
)) {
1117 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1118 // Plus one unicode character for the null-terminator.
1120 MacAddress
= NetAllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1121 if (MacAddress
== NULL
) {
1122 return EFI_OUT_OF_RESOURCES
;
1126 // Convert the mac address into a unicode string.
1128 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1129 MacAddress
[Index
* 2] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
] >> 4);
1130 MacAddress
[Index
* 2 + 1] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
]);
1133 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1135 *MacString
= MacAddress
;
1142 Find the UNDI/SNP handle from controller and protocol GUID.
1143 For example, IP will open a MNP child to transmit/receive
1144 packets, when MNP is stopped, IP should also be stopped. IP
1145 needs to find its own private data which is related the IP's
1146 service binding instance that is install on UNDI/SNP handle.
1147 Now, the controller is either a MNP or ARP child handle. But
1148 IP opens these handle BY_DRIVER, use that info, we can get the
1151 @param Controller Then protocol handle to check
1152 @param ProtocolGuid The protocol that is related with the handle.
1154 @return The UNDI/SNP handle or NULL.
1158 NetLibGetNicHandle (
1159 IN EFI_HANDLE Controller
,
1160 IN EFI_GUID
*ProtocolGuid
1163 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1169 Status
= gBS
->OpenProtocolInformation (
1176 if (EFI_ERROR (Status
)) {
1182 for (Index
= 0; Index
< OpenCount
; Index
++) {
1183 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1184 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1189 gBS
->FreePool (OpenBuffer
);
1194 NetLibInstallAllDriverProtocols (
1195 IN EFI_HANDLE ImageHandle
,
1196 IN EFI_SYSTEM_TABLE
*SystemTable
,
1197 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
1198 IN EFI_HANDLE DriverBindingHandle
,
1199 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
1200 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
1201 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics OPTIONAL
1205 Routine Description:
1207 Intialize a driver by installing the Driver Binding Protocol onto the
1208 driver's DriverBindingHandle. This is typically the same as the driver's
1209 ImageHandle, but it can be different if the driver produces multiple
1210 DriverBinding Protocols. This function also initializes the EFI Driver
1211 Library that initializes the global variables gST, gBS, gRT.
1215 ImageHandle - The image handle of the driver
1216 SystemTable - The EFI System Table that was passed to the driver's
1218 DriverBinding - A Driver Binding Protocol instance that this driver
1220 DriverBindingHandle - The handle that DriverBinding is to be installe onto.
1221 If this parameter is NULL, then a new handle is created.
1222 ComponentName - A Component Name Protocol instance that this driver is
1224 DriverConfiguration - A Driver Configuration Protocol instance that this
1225 driver is producing.
1226 DriverDiagnostics - A Driver Diagnostics Protocol instance that this
1227 driver is producing.
1231 EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
1232 Otherwise, then return status from gBS->InstallProtocolInterface()
1236 return NetLibInstallAllDriverProtocolsWithUnload (
1240 DriverBindingHandle
,
1242 DriverConfiguration
,
1249 NetLibInstallAllDriverProtocolsWithUnload (
1250 IN EFI_HANDLE ImageHandle
,
1251 IN EFI_SYSTEM_TABLE
*SystemTable
,
1252 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
1253 IN EFI_HANDLE DriverBindingHandle
,
1254 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
1255 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
1256 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
, OPTIONAL
1257 IN NET_LIB_DRIVER_UNLOAD Unload
1261 Routine Description:
1263 Intialize a driver by installing the Driver Binding Protocol onto the
1264 driver's DriverBindingHandle. This is typically the same as the driver's
1265 ImageHandle, but it can be different if the driver produces multiple
1266 DriverBinding Protocols. This function also initializes the EFI Driver
1267 Library that initializes the global variables gST, gBS, gRT.
1271 ImageHandle - The image handle of the driver
1272 SystemTable - The EFI System Table that was passed to the driver's
1274 DriverBinding - A Driver Binding Protocol instance that this driver
1276 DriverBindingHandle - The handle that DriverBinding is to be installe onto.
1277 If this parameter is NULL, then a new handle is created.
1278 ComponentName - A Component Name Protocol instance that this driver is
1280 DriverConfiguration - A Driver Configuration Protocol instance that this
1281 driver is producing.
1282 DriverDiagnostics - A Driver Diagnostics Protocol instance that this
1283 driver is producing.
1284 Unload - The customized unload to install.
1288 EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
1289 Otherwise, then return status from gBS->InstallProtocolInterface()
1294 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
1296 Status
= EfiLibInstallAllDriverProtocols (
1300 DriverBindingHandle
,
1302 DriverConfiguration
,
1306 if (EFI_ERROR (Status
)) {
1311 // Retrieve the Loaded Image Protocol from Image Handle
1313 Status
= gBS
->OpenProtocol (
1315 &gEfiLoadedImageProtocolGuid
,
1316 (VOID
**) &LoadedImage
,
1319 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1322 if (EFI_ERROR (Status
)) {
1327 // Fill in the Unload() service of the Loaded Image Protocol
1329 LoadedImage
->Unload
= (Unload
== NULL
) ? NetLibDefaultUnload
: Unload
;