3 Copyright (c) 2006, 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.
18 EFI handle & protocol handling
30 // mProtocolDatabase - A list of all protocols in the system. (simple list for now)
31 // gHandleList - A list of all the handles in the system
32 // gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
33 // gHandleDatabaseKey - The Key to show that the handle has been created/modified
35 static LIST_ENTRY mProtocolDatabase
= INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase
);
36 LIST_ENTRY gHandleList
= INITIALIZE_LIST_HEAD_VARIABLE (gHandleList
);
37 EFI_LOCK gProtocolDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY
);
38 UINT64 gHandleDatabaseKey
= 0;
42 CoreAcquireProtocolLock (
49 Acquire lock on gProtocolDatabaseLock.
61 CoreAcquireLock (&gProtocolDatabaseLock
);
66 CoreReleaseProtocolLock (
73 Release lock on gProtocolDatabaseLock.
85 CoreReleaseLock (&gProtocolDatabaseLock
);
91 IN EFI_HANDLE UserHandle
97 Check whether a handle is a valid EFI_HANDLE
101 UserHandle - The handle to check
105 EFI_INVALID_PARAMETER - The handle is NULL or not a valid EFI_HANDLE.
107 EFI_SUCCESS - The handle is valid EFI_HANDLE.
113 Handle
= (IHANDLE
*)UserHandle
;
114 if (Handle
== NULL
) {
115 return EFI_INVALID_PARAMETER
;
117 if (Handle
->Signature
!= EFI_HANDLE_SIGNATURE
) {
118 return EFI_INVALID_PARAMETER
;
125 CoreFindProtocolEntry (
126 IN EFI_GUID
*Protocol
,
133 Finds the protocol entry for the requested protocol.
135 The gProtocolDatabaseLock must be owned
139 Protocol - The ID of the protocol
141 Create - Create a new entry if not found
150 PROTOCOL_ENTRY
*Item
;
151 PROTOCOL_ENTRY
*ProtEntry
;
153 ASSERT_LOCKED(&gProtocolDatabaseLock
);
156 // Search the database for the matching GUID
160 for (Link
= mProtocolDatabase
.ForwardLink
;
161 Link
!= &mProtocolDatabase
;
162 Link
= Link
->ForwardLink
) {
164 Item
= CR(Link
, PROTOCOL_ENTRY
, AllEntries
, PROTOCOL_ENTRY_SIGNATURE
);
165 if (CompareGuid (&Item
->ProtocolID
, Protocol
)) {
168 // This is the protocol entry
177 // If the protocol entry was not found and Create is TRUE, then
178 // allocate a new entry
180 if ((ProtEntry
== NULL
) && Create
) {
181 ProtEntry
= CoreAllocateBootServicesPool (sizeof(PROTOCOL_ENTRY
));
183 if (ProtEntry
!= NULL
) {
185 // Initialize new protocol entry structure
187 ProtEntry
->Signature
= PROTOCOL_ENTRY_SIGNATURE
;
188 CopyMem ((VOID
*)&ProtEntry
->ProtocolID
, Protocol
, sizeof (EFI_GUID
));
189 InitializeListHead (&ProtEntry
->Protocols
);
190 InitializeListHead (&ProtEntry
->Notify
);
193 // Add it to protocol database
195 InsertTailList (&mProtocolDatabase
, &ProtEntry
->AllEntries
);
204 CoreFindProtocolInterface (
206 IN EFI_GUID
*Protocol
,
213 Finds the protocol instance for the requested handle and protocol.
215 Note: This function doesn't do parameters checking, it's caller's responsibility
216 to pass in valid parameters.
220 Handle - The handle to search the protocol on
222 Protocol - GUID of the protocol
224 Interface - The interface for the protocol being searched
228 Protocol instance (NULL: Not found)
232 PROTOCOL_INTERFACE
*Prot
;
233 PROTOCOL_ENTRY
*ProtEntry
;
236 ASSERT_LOCKED(&gProtocolDatabaseLock
);
240 // Lookup the protocol entry for this protocol ID
243 ProtEntry
= CoreFindProtocolEntry (Protocol
, FALSE
);
244 if (ProtEntry
!= NULL
) {
247 // Look at each protocol interface for any matches
249 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
=Link
->ForwardLink
) {
252 // If this protocol interface matches, remove it
254 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
255 if (Prot
->Interface
== Interface
&& Prot
->Protocol
== ProtEntry
) {
268 CoreUnregisterProtocolNotifyEvent (
275 Removes an event from a register protocol notify list on a protocol.
279 Event - The event to search for in the protocol database.
283 EFI_SUCCESS if the event was found and removed.
284 EFI_NOT_FOUND if the event was not found in the protocl database.
289 PROTOCOL_ENTRY
*ProtEntry
;
290 LIST_ENTRY
*NotifyLink
;
291 PROTOCOL_NOTIFY
*ProtNotify
;
293 CoreAcquireProtocolLock ();
295 for ( Link
= mProtocolDatabase
.ForwardLink
;
296 Link
!= &mProtocolDatabase
;
297 Link
= Link
->ForwardLink
) {
299 ProtEntry
= CR(Link
, PROTOCOL_ENTRY
, AllEntries
, PROTOCOL_ENTRY_SIGNATURE
);
301 for ( NotifyLink
= ProtEntry
->Notify
.ForwardLink
;
302 NotifyLink
!= &ProtEntry
->Notify
;
303 NotifyLink
= NotifyLink
->ForwardLink
) {
305 ProtNotify
= CR(NotifyLink
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
307 if (ProtNotify
->Event
== Event
) {
308 RemoveEntryList(&ProtNotify
->Link
);
309 CoreFreePool(ProtNotify
);
310 CoreReleaseProtocolLock ();
316 CoreReleaseProtocolLock ();
317 return EFI_NOT_FOUND
;
322 CoreUnregisterProtocolNotify (
329 Removes all the events in the protocol database that match Event.
333 Event - The event to search for in the protocol database.
337 EFI_SUCCESS when done searching the entire database.
344 Status
= CoreUnregisterProtocolNotifyEvent (Event
);
345 } while (!EFI_ERROR (Status
));
354 CoreInstallProtocolInterface (
355 IN OUT EFI_HANDLE
*UserHandle
,
356 IN EFI_GUID
*Protocol
,
357 IN EFI_INTERFACE_TYPE InterfaceType
,
364 Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which
365 Calls the private one which contains a BOOLEAN parameter for notifications
369 UserHandle - The handle to install the protocol handler on,
370 or NULL if a new handle is to be allocated
372 Protocol - The protocol to add to the handle
374 InterfaceType - Indicates whether Interface is supplied in native form.
376 Interface - The interface for the protocol being added
384 return CoreInstallProtocolInterfaceNotify (
394 CoreInstallProtocolInterfaceNotify (
395 IN OUT EFI_HANDLE
*UserHandle
,
396 IN EFI_GUID
*Protocol
,
397 IN EFI_INTERFACE_TYPE InterfaceType
,
405 Installs a protocol interface into the boot services environment.
409 UserHandle - The handle to install the protocol handler on,
410 or NULL if a new handle is to be allocated
412 Protocol - The protocol to add to the handle
414 InterfaceType - Indicates whether Interface is supplied in native form.
416 Interface - The interface for the protocol being added
418 Notify - indicates whether notify the notification list
423 EFI_INVALID_PARAMETER - Invalid parameter
425 EFI_OUT_OF_RESOURCES - No enough buffer to allocate
427 EFI_SUCCESS - Protocol interface successfully installed
431 PROTOCOL_INTERFACE
*Prot
;
432 PROTOCOL_ENTRY
*ProtEntry
;
435 VOID
*ExistingInterface
;
438 // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
439 // Also added check for invalid UserHandle and Protocol pointers.
441 if (UserHandle
== NULL
|| Protocol
== NULL
) {
442 return EFI_INVALID_PARAMETER
;
445 if (InterfaceType
!= EFI_NATIVE_INTERFACE
) {
446 return EFI_INVALID_PARAMETER
;
450 // Print debug message
452 DEBUG((EFI_D_ERROR
| EFI_D_INFO
, "InstallProtocolInterface: %g %p\n", Protocol
, Interface
));
454 Status
= EFI_OUT_OF_RESOURCES
;
458 ASSERT (NULL
!= gBS
);
460 if (*UserHandle
!= NULL_HANDLE
) {
461 Status
= CoreHandleProtocol (*UserHandle
, Protocol
, (VOID
**)&ExistingInterface
);
462 if (!EFI_ERROR (Status
)) {
463 return EFI_INVALID_PARAMETER
;
468 // Lock the protocol database
470 CoreAcquireProtocolLock ();
473 // Lookup the Protocol Entry for the requested protocol
475 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
476 if (ProtEntry
== NULL
) {
481 // Allocate a new protocol interface structure
483 Prot
= CoreAllocateZeroBootServicesPool (sizeof(PROTOCOL_INTERFACE
));
485 Status
= EFI_OUT_OF_RESOURCES
;
490 // If caller didn't supply a handle, allocate a new one
492 Handle
= (IHANDLE
*)*UserHandle
;
493 if (Handle
== NULL
) {
494 Handle
= CoreAllocateZeroBootServicesPool (sizeof(IHANDLE
));
495 if (Handle
== NULL
) {
496 Status
= EFI_OUT_OF_RESOURCES
;
501 // Initialize new handler structure
503 Handle
->Signature
= EFI_HANDLE_SIGNATURE
;
504 InitializeListHead (&Handle
->Protocols
);
507 // Initialize the Key to show that the handle has been created/modified
509 gHandleDatabaseKey
++;
510 Handle
->Key
= gHandleDatabaseKey
;
513 // Add this handle to the list global list of all handles
516 InsertTailList (&gHandleList
, &Handle
->AllHandles
);
519 Status
= CoreValidateHandle (Handle
);
520 if (EFI_ERROR (Status
)) {
525 // Each interface that is added must be unique
527 ASSERT (CoreFindProtocolInterface (Handle
, Protocol
, Interface
) == NULL
);
530 // Initialize the protocol interface structure
532 Prot
->Signature
= PROTOCOL_INTERFACE_SIGNATURE
;
533 Prot
->Handle
= Handle
;
534 Prot
->Protocol
= ProtEntry
;
535 Prot
->Interface
= Interface
;
538 // Initalize OpenProtocol Data base
540 InitializeListHead (&Prot
->OpenList
);
541 Prot
->OpenListCount
= 0;
544 // Add this protocol interface to the head of the supported
545 // protocol list for this handle
547 InsertHeadList (&Handle
->Protocols
, &Prot
->Link
);
550 // Add this protocol interface to the tail of the
553 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
556 // Notify the notification list for this protocol
559 CoreNotifyProtocolEntry (ProtEntry
);
561 Status
= EFI_SUCCESS
;
565 // Done, unlock the database and return
567 CoreReleaseProtocolLock ();
568 if (!EFI_ERROR (Status
)) {
570 // Return the new handle back to the caller
572 *UserHandle
= Handle
;
575 // There was an error, clean up
589 CoreInstallMultipleProtocolInterfaces (
590 IN OUT EFI_HANDLE
*Handle
,
597 Installs a list of protocol interface into the boot services environment.
598 This function calls InstallProtocolInterface() in a loop. If any error
599 occures all the protocols added by this function are removed. This is
600 basically a lib function to save space.
604 Handle - The handle to install the protocol handlers on,
605 or NULL if a new handle is to be allocated
606 ... - EFI_GUID followed by protocol instance. A NULL terminates the
607 list. The pairs are the arguments to InstallProtocolInterface().
608 All the protocols are added to Handle.
612 EFI_INVALID_PARAMETER - Handle is NULL.
614 EFI_SUCCESS - Protocol interfaces successfully installed.
624 EFI_HANDLE OldHandle
;
625 EFI_HANDLE DeviceHandle
;
626 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
628 if (Handle
== NULL
) {
629 return EFI_INVALID_PARAMETER
;
633 // Syncronize with notifcations.
635 OldTpl
= CoreRaiseTpl (EFI_TPL_NOTIFY
);
639 // Check for duplicate device path and install the protocol interfaces
641 VA_START (args
, Handle
);
642 for (Index
= 0, Status
= EFI_SUCCESS
; !EFI_ERROR (Status
); Index
++) {
644 // If protocol is NULL, then it's the end of the list
646 Protocol
= VA_ARG (args
, EFI_GUID
*);
647 if (Protocol
== NULL
) {
651 Interface
= VA_ARG (args
, VOID
*);
654 // Make sure you are installing on top a device path that has already been added.
656 if (CompareGuid (Protocol
, &gEfiDevicePathProtocolGuid
)) {
658 DevicePath
= Interface
;
659 Status
= CoreLocateDevicePath (&gEfiDevicePathProtocolGuid
, &DevicePath
, &DeviceHandle
);
660 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL_HANDLE
) && IsDevicePathEnd(DevicePath
)) {
661 Status
= EFI_ALREADY_STARTED
;
669 Status
= CoreInstallProtocolInterface (Handle
, Protocol
, EFI_NATIVE_INTERFACE
, Interface
);
673 // If there was an error, remove all the interfaces that were installed without any errors
675 if (EFI_ERROR (Status
)) {
677 // Reset the va_arg back to the first argument.
679 VA_START (args
, Handle
);
680 for (; Index
> 1; Index
--) {
681 Protocol
= VA_ARG (args
, EFI_GUID
*);
682 Interface
= VA_ARG (args
, VOID
*);
683 CoreUninstallProtocolInterface (*Handle
, Protocol
, Interface
);
691 CoreRestoreTpl (OldTpl
);
696 CoreDisconnectControllersUsingProtocolInterface (
697 IN EFI_HANDLE UserHandle
,
698 IN PROTOCOL_INTERFACE
*Prot
704 Attempts to disconnect all drivers that are using the protocol interface being queried.
705 If failed, reconnect all drivers disconnected.
707 Note: This function doesn't do parameters checking, it's caller's responsibility
708 to pass in valid parameters.
712 UserHandle - The handle on which the protocol is installed
713 Prot - The protocol to disconnect drivers from
717 EFI_SUCCESS - Drivers using the protocol interface are all disconnected
718 EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers
725 OPEN_PROTOCOL_DATA
*OpenData
;
727 Status
= EFI_SUCCESS
;
730 // Attempt to disconnect all drivers from this protocol interface
734 for ( Link
= Prot
->OpenList
.ForwardLink
;
735 (Link
!= &Prot
->OpenList
) && !ItemFound
;
736 Link
= Link
->ForwardLink
) {
737 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
738 if (OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
740 CoreReleaseProtocolLock ();
741 Status
= CoreDisconnectController (UserHandle
, OpenData
->AgentHandle
, NULL
);
742 CoreAcquireProtocolLock ();
743 if (EFI_ERROR (Status
)) {
751 if (!EFI_ERROR (Status
)) {
753 // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items
757 for ( Link
= Prot
->OpenList
.ForwardLink
;
758 (Link
!= &Prot
->OpenList
) && !ItemFound
;
759 Link
= Link
->ForwardLink
) {
760 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
761 if (OpenData
->Attributes
&
762 (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
| EFI_OPEN_PROTOCOL_GET_PROTOCOL
| EFI_OPEN_PROTOCOL_TEST_PROTOCOL
)) {
764 RemoveEntryList (&OpenData
->Link
);
765 Prot
->OpenListCount
--;
766 CoreFreePool (OpenData
);
773 // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
775 if (EFI_ERROR (Status
) || (Prot
->OpenListCount
> 0)) {
776 CoreReleaseProtocolLock ();
777 CoreConnectController (UserHandle
, NULL
, NULL
, TRUE
);
778 CoreAcquireProtocolLock ();
779 Status
= EFI_ACCESS_DENIED
;
788 CoreUninstallProtocolInterface (
789 IN EFI_HANDLE UserHandle
,
790 IN EFI_GUID
*Protocol
,
797 Uninstalls all instances of a protocol:interfacer from a handle.
798 If the last protocol interface is remove from the handle, the
803 UserHandle - The handle to remove the protocol handler from
805 Protocol - The protocol, of protocol:interface, to remove
807 Interface - The interface, of protocol:interface, to remove
811 EFI_INVALID_PARAMETER - Protocol is NULL.
813 EFI_SUCCESS - Protocol interface successfully uninstalled.
819 PROTOCOL_INTERFACE
*Prot
;
822 // Check that Protocol is valid
824 if (Protocol
== NULL
) {
825 return EFI_INVALID_PARAMETER
;
829 // Check that UserHandle is a valid handle
831 Status
= CoreValidateHandle (UserHandle
);
832 if (EFI_ERROR (Status
)) {
837 // Lock the protocol database
839 CoreAcquireProtocolLock ();
842 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
844 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, Interface
);
846 Status
= EFI_NOT_FOUND
;
851 // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
853 Status
= CoreDisconnectControllersUsingProtocolInterface (
857 if (EFI_ERROR (Status
)) {
859 // One or more drivers refused to release, so return the error
865 // Remove the protocol interface from the protocol
867 Status
= EFI_NOT_FOUND
;
868 Handle
= (IHANDLE
*)UserHandle
;
869 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, Interface
);
873 // Update the Key to show that the handle has been created/modified
875 gHandleDatabaseKey
++;
876 Handle
->Key
= gHandleDatabaseKey
;
879 // Remove the protocol interface from the handle
881 RemoveEntryList (&Prot
->Link
);
888 Status
= EFI_SUCCESS
;
892 // If there are no more handlers for the handle, free the handle
894 if (IsListEmpty (&Handle
->Protocols
)) {
895 Handle
->Signature
= 0;
896 RemoveEntryList (&Handle
->AllHandles
);
897 CoreFreePool (Handle
);
902 // Done, unlock the database and return
904 CoreReleaseProtocolLock ();
912 CoreUninstallMultipleProtocolInterfaces (
913 IN EFI_HANDLE Handle
,
920 Uninstalls a list of protocol interface in the boot services environment.
921 This function calls UnisatllProtocolInterface() in a loop. This is
922 basically a lib function to save space.
926 Handle - The handle to uninstall the protocol
928 ... - EFI_GUID followed by protocol instance. A NULL terminates the
929 list. The pairs are the arguments to UninstallProtocolInterface().
930 All the protocols are added to Handle.
944 VA_START (args
, Handle
);
945 for (Index
= 0, Status
= EFI_SUCCESS
; !EFI_ERROR (Status
); Index
++) {
947 // If protocol is NULL, then it's the end of the list
949 Protocol
= VA_ARG (args
, EFI_GUID
*);
950 if (Protocol
== NULL
) {
954 Interface
= VA_ARG (args
, VOID
*);
959 Status
= CoreUninstallProtocolInterface (Handle
, Protocol
, Interface
);
963 // If there was an error, add all the interfaces that were
964 // uninstalled without any errors
966 if (EFI_ERROR (Status
)) {
968 // Reset the va_arg back to the first argument.
970 VA_START (args
, Handle
);
971 for (; Index
> 1; Index
--) {
972 Protocol
= VA_ARG(args
, EFI_GUID
*);
973 Interface
= VA_ARG(args
, VOID
*);
974 CoreInstallProtocolInterface (&Handle
, Protocol
, EFI_NATIVE_INTERFACE
, Interface
);
982 CoreGetProtocolInterface (
983 IN EFI_HANDLE UserHandle
,
984 IN EFI_GUID
*Protocol
990 Locate a certain GUID protocol interface in a Handle's protocols.
994 UserHandle - The handle to obtain the protocol interface on
996 Protocol - The GUID of the protocol
1000 The requested protocol interface for the handle
1005 PROTOCOL_ENTRY
*ProtEntry
;
1006 PROTOCOL_INTERFACE
*Prot
;
1010 Status
= CoreValidateHandle (UserHandle
);
1011 if (EFI_ERROR (Status
)) {
1015 Handle
= (IHANDLE
*)UserHandle
;
1018 // Look at each protocol interface for a match
1020 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
1021 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
1022 ProtEntry
= Prot
->Protocol
;
1023 if (CompareGuid (&ProtEntry
->ProtocolID
, Protocol
)) {
1033 CoreHandleProtocol (
1034 IN EFI_HANDLE UserHandle
,
1035 IN EFI_GUID
*Protocol
,
1036 OUT VOID
**Interface
1040 Routine Description:
1042 Queries a handle to determine if it supports a specified protocol.
1046 UserHandle - The handle being queried.
1048 Protocol - The published unique identifier of the protocol.
1050 Interface - Supplies the address where a pointer to the corresponding Protocol
1051 Interface is returned.
1055 The requested protocol interface for the handle
1059 return CoreOpenProtocol (
1063 gDxeCoreImageHandle
,
1065 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
1073 IN EFI_HANDLE UserHandle
,
1074 IN EFI_GUID
*Protocol
,
1075 OUT VOID
**Interface OPTIONAL
,
1076 IN EFI_HANDLE ImageHandle
,
1077 IN EFI_HANDLE ControllerHandle
,
1078 IN UINT32 Attributes
1082 Routine Description:
1084 Locates the installed protocol handler for the handle, and
1085 invokes it to obtain the protocol interface. Usage information
1086 is registered in the protocol data base.
1090 UserHandle - The handle to obtain the protocol interface on
1092 Protocol - The ID of the protocol
1094 Interface - The location to return the protocol interface
1096 ImageHandle - The handle of the Image that is opening the protocol interface
1097 specified by Protocol and Interface.
1099 ControllerHandle - The controller handle that is requiring this interface.
1101 Attributes - The open mode of the protocol interface specified by Handle
1106 EFI_INVALID_PARAMETER - Protocol is NULL.
1108 EFI_SUCCESS - Get the protocol interface.
1113 PROTOCOL_INTERFACE
*Prot
;
1115 OPEN_PROTOCOL_DATA
*OpenData
;
1122 // Check for invalid Protocol
1124 if (Protocol
== NULL
) {
1125 return EFI_INVALID_PARAMETER
;
1129 // Check for invalid Interface
1131 if (Attributes
!= EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) {
1132 if (Interface
== NULL
) {
1133 return EFI_INVALID_PARAMETER
;
1140 // Check for invalid UserHandle
1142 Status
= CoreValidateHandle (UserHandle
);
1143 if (EFI_ERROR (Status
)) {
1148 // Check for invalid Attributes
1150 switch (Attributes
) {
1151 case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
:
1152 Status
= CoreValidateHandle (ImageHandle
);
1153 if (EFI_ERROR (Status
)) {
1156 Status
= CoreValidateHandle (ControllerHandle
);
1157 if (EFI_ERROR (Status
)) {
1160 if (UserHandle
== ControllerHandle
) {
1161 return EFI_INVALID_PARAMETER
;
1164 case EFI_OPEN_PROTOCOL_BY_DRIVER
:
1165 case EFI_OPEN_PROTOCOL_BY_DRIVER
| EFI_OPEN_PROTOCOL_EXCLUSIVE
:
1166 Status
= CoreValidateHandle (ImageHandle
);
1167 if (EFI_ERROR (Status
)) {
1170 Status
= CoreValidateHandle (ControllerHandle
);
1171 if (EFI_ERROR (Status
)) {
1175 case EFI_OPEN_PROTOCOL_EXCLUSIVE
:
1176 Status
= CoreValidateHandle (ImageHandle
);
1177 if (EFI_ERROR (Status
)) {
1181 case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
:
1182 case EFI_OPEN_PROTOCOL_GET_PROTOCOL
:
1183 case EFI_OPEN_PROTOCOL_TEST_PROTOCOL
:
1186 return EFI_INVALID_PARAMETER
;
1190 // Lock the protocol database
1192 CoreAcquireProtocolLock ();
1195 // Look at each protocol interface for a match
1197 Prot
= CoreGetProtocolInterface (UserHandle
, Protocol
);
1199 Status
= EFI_UNSUPPORTED
;
1204 // This is the protocol interface entry for this protocol
1206 if (Attributes
!= EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) {
1207 *Interface
= Prot
->Interface
;
1209 Status
= EFI_SUCCESS
;
1213 for ( Link
= Prot
->OpenList
.ForwardLink
; Link
!= &Prot
->OpenList
; Link
= Link
->ForwardLink
) {
1214 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
1215 ExactMatch
= (BOOLEAN
)((OpenData
->AgentHandle
== ImageHandle
) &&
1216 (OpenData
->Attributes
== Attributes
) &&
1217 (OpenData
->ControllerHandle
== ControllerHandle
));
1218 if (OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1221 Status
= EFI_ALREADY_STARTED
;
1225 if (OpenData
->Attributes
& EFI_OPEN_PROTOCOL_EXCLUSIVE
) {
1227 } else if (ExactMatch
) {
1228 OpenData
->OpenCount
++;
1229 Status
= EFI_SUCCESS
;
1235 // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)
1236 // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)
1237 // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)
1238 // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
1241 switch (Attributes
) {
1242 case EFI_OPEN_PROTOCOL_BY_DRIVER
:
1243 if (Exclusive
|| ByDriver
) {
1244 Status
= EFI_ACCESS_DENIED
;
1248 case EFI_OPEN_PROTOCOL_BY_DRIVER
| EFI_OPEN_PROTOCOL_EXCLUSIVE
:
1249 case EFI_OPEN_PROTOCOL_EXCLUSIVE
:
1251 Status
= EFI_ACCESS_DENIED
;
1257 for ( Link
= Prot
->OpenList
.ForwardLink
; (Link
!= &Prot
->OpenList
) && (!Disconnect
); Link
= Link
->ForwardLink
) {
1258 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
1259 if (OpenData
->Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1261 CoreReleaseProtocolLock ();
1262 Status
= CoreDisconnectController (UserHandle
, OpenData
->AgentHandle
, NULL
);
1263 CoreAcquireProtocolLock ();
1264 if (EFI_ERROR (Status
)) {
1265 Status
= EFI_ACCESS_DENIED
;
1270 } while (Disconnect
);
1273 case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
:
1274 case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
:
1275 case EFI_OPEN_PROTOCOL_GET_PROTOCOL
:
1276 case EFI_OPEN_PROTOCOL_TEST_PROTOCOL
:
1280 if (ImageHandle
== NULL
) {
1281 Status
= EFI_SUCCESS
;
1287 OpenData
= CoreAllocateBootServicesPool (sizeof(OPEN_PROTOCOL_DATA
));
1288 if (OpenData
== NULL
) {
1289 Status
= EFI_OUT_OF_RESOURCES
;
1291 OpenData
->Signature
= OPEN_PROTOCOL_DATA_SIGNATURE
;
1292 OpenData
->AgentHandle
= ImageHandle
;
1293 OpenData
->ControllerHandle
= ControllerHandle
;
1294 OpenData
->Attributes
= Attributes
;
1295 OpenData
->OpenCount
= 1;
1296 InsertTailList (&Prot
->OpenList
, &OpenData
->Link
);
1297 Prot
->OpenListCount
++;
1298 Status
= EFI_SUCCESS
;
1303 // Done. Release the database lock are return
1305 CoreReleaseProtocolLock ();
1313 IN EFI_HANDLE UserHandle
,
1314 IN EFI_GUID
*Protocol
,
1315 IN EFI_HANDLE AgentHandle
,
1316 IN EFI_HANDLE ControllerHandle
1320 Routine Description:
1322 Closes a protocol on a handle that was opened using OpenProtocol().
1326 UserHandle - The handle for the protocol interface that was previously opened
1327 with OpenProtocol(), and is now being closed.
1328 Protocol - The published unique identifier of the protocol. It is the caller's
1329 responsibility to pass in a valid GUID.
1330 AgentHandle - The handle of the agent that is closing the protocol interface.
1331 ControllerHandle - If the agent that opened a protocol is a driver that follows the
1332 EFI Driver Model, then this parameter is the controller handle
1333 that required the protocol interface. If the agent does not follow
1334 the EFI Driver Model, then this parameter is optional and may be NULL.
1338 EFI_SUCCESS - The protocol instance was closed.
1339 EFI_INVALID_PARAMETER - Handle, AgentHandle or ControllerHandle is not a valid EFI_HANDLE.
1340 EFI_NOT_FOUND - Can not find the specified protocol or AgentHandle.
1345 PROTOCOL_INTERFACE
*ProtocolInterface
;
1347 OPEN_PROTOCOL_DATA
*OpenData
;
1350 // Check for invalid parameters
1352 Status
= CoreValidateHandle (UserHandle
);
1353 if (EFI_ERROR (Status
)) {
1356 Status
= CoreValidateHandle (AgentHandle
);
1357 if (EFI_ERROR (Status
)) {
1360 if (ControllerHandle
!= NULL_HANDLE
) {
1361 Status
= CoreValidateHandle (ControllerHandle
);
1362 if (EFI_ERROR (Status
)) {
1366 if (Protocol
== NULL
) {
1367 return EFI_INVALID_PARAMETER
;
1371 // Lock the protocol database
1373 CoreAcquireProtocolLock ();
1376 // Look at each protocol interface for a match
1378 Status
= EFI_NOT_FOUND
;
1379 ProtocolInterface
= CoreGetProtocolInterface (UserHandle
, Protocol
);
1380 if (ProtocolInterface
== NULL
) {
1385 // Walk the Open data base looking for AgentHandle
1387 Link
= ProtocolInterface
->OpenList
.ForwardLink
;
1388 while (Link
!= &ProtocolInterface
->OpenList
) {
1389 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
1390 Link
= Link
->ForwardLink
;
1391 if ((OpenData
->AgentHandle
== AgentHandle
) && (OpenData
->ControllerHandle
== ControllerHandle
)) {
1392 RemoveEntryList (&OpenData
->Link
);
1393 ProtocolInterface
->OpenListCount
--;
1394 CoreFreePool (OpenData
);
1395 Status
= EFI_SUCCESS
;
1401 // Done. Release the database lock and return.
1403 CoreReleaseProtocolLock ();
1411 CoreOpenProtocolInformation (
1412 IN EFI_HANDLE UserHandle
,
1413 IN EFI_GUID
*Protocol
,
1414 OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
**EntryBuffer
,
1415 OUT UINTN
*EntryCount
1419 Routine Description:
1421 Return information about Opened protocols in the system
1425 UserHandle - The handle to close the protocol interface on
1427 Protocol - The ID of the protocol
1429 EntryBuffer - A pointer to a buffer of open protocol information in the form of
1430 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
1432 EntryCount - Number of EntryBuffer entries
1440 PROTOCOL_INTERFACE
*ProtocolInterface
;
1442 OPEN_PROTOCOL_DATA
*OpenData
;
1443 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*Buffer
;
1447 *EntryBuffer
= NULL
;
1451 // Lock the protocol database
1453 CoreAcquireProtocolLock ();
1456 // Look at each protocol interface for a match
1458 Status
= EFI_NOT_FOUND
;
1459 ProtocolInterface
= CoreGetProtocolInterface (UserHandle
, Protocol
);
1460 if (ProtocolInterface
== NULL
) {
1465 // Count the number of Open Entries
1467 for ( Link
= ProtocolInterface
->OpenList
.ForwardLink
, Count
= 0;
1468 (Link
!= &ProtocolInterface
->OpenList
) ;
1469 Link
= Link
->ForwardLink
) {
1473 ASSERT (Count
== ProtocolInterface
->OpenListCount
);
1476 Size
= sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
);
1478 Size
= Count
* sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
);
1481 Buffer
= CoreAllocateBootServicesPool (Size
);
1482 if (Buffer
== NULL
) {
1483 Status
= EFI_OUT_OF_RESOURCES
;
1487 Status
= EFI_SUCCESS
;
1488 for ( Link
= ProtocolInterface
->OpenList
.ForwardLink
, Count
= 0;
1489 (Link
!= &ProtocolInterface
->OpenList
);
1490 Link
= Link
->ForwardLink
, Count
++ ) {
1491 OpenData
= CR (Link
, OPEN_PROTOCOL_DATA
, Link
, OPEN_PROTOCOL_DATA_SIGNATURE
);
1493 Buffer
[Count
].AgentHandle
= OpenData
->AgentHandle
;
1494 Buffer
[Count
].ControllerHandle
= OpenData
->ControllerHandle
;
1495 Buffer
[Count
].Attributes
= OpenData
->Attributes
;
1496 Buffer
[Count
].OpenCount
= OpenData
->OpenCount
;
1499 *EntryBuffer
= Buffer
;
1500 *EntryCount
= Count
;
1504 // Done. Release the database lock are return
1506 CoreReleaseProtocolLock ();
1514 CoreProtocolsPerHandle (
1515 IN EFI_HANDLE UserHandle
,
1516 OUT EFI_GUID
***ProtocolBuffer
,
1517 OUT UINTN
*ProtocolBufferCount
1521 Routine Description:
1523 Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
1528 UserHandle - The handle from which to retrieve the list of protocol interface
1531 ProtocolBuffer - A pointer to the list of protocol interface GUID pointers that are
1532 installed on Handle.
1534 ProtocolBufferCount - A pointer to the number of GUID pointers present in
1538 EFI_SUCCESS - The list of protocol interface GUIDs installed on Handle was returned in
1539 ProtocolBuffer. The number of protocol interface GUIDs was
1540 returned in ProtocolBufferCount.
1541 EFI_INVALID_PARAMETER - Handle is NULL.
1542 EFI_INVALID_PARAMETER - Handle is not a valid EFI_HANDLE.
1543 EFI_INVALID_PARAMETER - ProtocolBuffer is NULL.
1544 EFI_INVALID_PARAMETER - ProtocolBufferCount is NULL.
1545 EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the results.
1551 PROTOCOL_INTERFACE
*Prot
;
1553 UINTN ProtocolCount
;
1556 Status
= CoreValidateHandle (UserHandle
);
1557 if (EFI_ERROR (Status
)) {
1561 Handle
= (IHANDLE
*)UserHandle
;
1563 if (ProtocolBuffer
== NULL
) {
1564 return EFI_INVALID_PARAMETER
;
1567 if (ProtocolBufferCount
== NULL
) {
1568 return EFI_INVALID_PARAMETER
;
1571 *ProtocolBufferCount
= 0;
1575 CoreAcquireProtocolLock ();
1577 for (Link
= Handle
->Protocols
.ForwardLink
; Link
!= &Handle
->Protocols
; Link
= Link
->ForwardLink
) {
1582 // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE
1584 if (ProtocolCount
== 0) {
1585 Status
= EFI_INVALID_PARAMETER
;
1589 Buffer
= CoreAllocateBootServicesPool (sizeof (EFI_GUID
*) * ProtocolCount
);
1590 if (Buffer
== NULL
) {
1591 Status
= EFI_OUT_OF_RESOURCES
;
1595 *ProtocolBuffer
= Buffer
;
1596 *ProtocolBufferCount
= ProtocolCount
;
1598 for ( Link
= Handle
->Protocols
.ForwardLink
, ProtocolCount
= 0;
1599 Link
!= &Handle
->Protocols
;
1600 Link
= Link
->ForwardLink
, ProtocolCount
++) {
1601 Prot
= CR(Link
, PROTOCOL_INTERFACE
, Link
, PROTOCOL_INTERFACE_SIGNATURE
);
1602 Buffer
[ProtocolCount
] = &(Prot
->Protocol
->ProtocolID
);
1604 Status
= EFI_SUCCESS
;
1607 CoreReleaseProtocolLock ();
1613 CoreGetHandleDatabaseKey (
1618 Routine Description:
1620 return handle database key.
1628 Handle database key.
1632 return gHandleDatabaseKey
;
1637 CoreConnectHandlesByKey (
1642 Routine Description:
1644 Go connect any handles that were created or modified while a image executed.
1648 Key - The Key to show that the handle has been created/modified
1657 EFI_HANDLE
*HandleBuffer
;
1662 // Lock the protocol database
1664 CoreAcquireProtocolLock ();
1666 for (Link
= gHandleList
.ForwardLink
, Count
= 0; Link
!= &gHandleList
; Link
= Link
->ForwardLink
) {
1667 Handle
= CR (Link
, IHANDLE
, AllHandles
, EFI_HANDLE_SIGNATURE
);
1668 if (Handle
->Key
> Key
) {
1673 HandleBuffer
= CoreAllocateBootServicesPool (Count
* sizeof (EFI_HANDLE
));
1674 if (HandleBuffer
== NULL
) {
1675 CoreReleaseProtocolLock ();
1679 for (Link
= gHandleList
.ForwardLink
, Count
= 0; Link
!= &gHandleList
; Link
= Link
->ForwardLink
) {
1680 Handle
= CR (Link
, IHANDLE
, AllHandles
, EFI_HANDLE_SIGNATURE
);
1681 if (Handle
->Key
> Key
) {
1682 HandleBuffer
[Count
++] = Handle
;
1687 // Unlock the protocol database
1689 CoreReleaseProtocolLock ();
1692 // Connect all handles whose Key value is greater than Key
1694 for (Index
= 0; Index
< Count
; Index
++) {
1695 CoreConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
1698 CoreFreePool(HandleBuffer
);