Handle.c revision 5a7b9bbe08a5dfc8de6f5091a4b140818604d403
123c98c9417908188207408afa3f6901b8aca826aqhuang/** @file 2162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang UEFI handle & protocol handling. 328a00297189c323096aae8e2975de94e8549613cyshang 45a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin QiuCopyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR> 5cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis program and the accompanying materials 623c98c9417908188207408afa3f6901b8aca826aqhuangare licensed and made available under the terms and conditions of the BSD License 723c98c9417908188207408afa3f6901b8aca826aqhuangwhich accompanies this distribution. The full text of the license may be found at 823c98c9417908188207408afa3f6901b8aca826aqhuanghttp://opensource.org/licenses/bsd-license.php 923c98c9417908188207408afa3f6901b8aca826aqhuang 1023c98c9417908188207408afa3f6901b8aca826aqhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1123c98c9417908188207408afa3f6901b8aca826aqhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1228a00297189c323096aae8e2975de94e8549613cyshang 13504214c4870e9183418014634268ce630eb5332algao**/ 1428a00297189c323096aae8e2975de94e8549613cyshang 159c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang#include "DxeMain.h" 16ec90508b3d3ff22a698a0446cb09d551d7466045eric_tian#include "Handle.h" 1728a00297189c323096aae8e2975de94e8549613cyshang 1828a00297189c323096aae8e2975de94e8549613cyshang 1928a00297189c323096aae8e2975de94e8549613cyshang// 2028a00297189c323096aae8e2975de94e8549613cyshang// mProtocolDatabase - A list of all protocols in the system. (simple list for now) 2128a00297189c323096aae8e2975de94e8549613cyshang// gHandleList - A list of all the handles in the system 2228a00297189c323096aae8e2975de94e8549613cyshang// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase 2328a00297189c323096aae8e2975de94e8549613cyshang// gHandleDatabaseKey - The Key to show that the handle has been created/modified 2428a00297189c323096aae8e2975de94e8549613cyshang// 25e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuangLIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); 2658125fb3f9dda7f15a540b16595dc24dab0dd423qhuangLIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); 2758125fb3f9dda7f15a540b16595dc24dab0dd423qhuangEFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); 2858125fb3f9dda7f15a540b16595dc24dab0dd423qhuangUINT64 gHandleDatabaseKey = 0; 2928a00297189c323096aae8e2975de94e8549613cyshang 3028a00297189c323096aae8e2975de94e8549613cyshang 31162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 32162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 33162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Acquire lock on gProtocolDatabaseLock. 34162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 35162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 3628a00297189c323096aae8e2975de94e8549613cyshangVOID 3728a00297189c323096aae8e2975de94e8549613cyshangCoreAcquireProtocolLock ( 3828a00297189c323096aae8e2975de94e8549613cyshang VOID 3928a00297189c323096aae8e2975de94e8549613cyshang ) 4028a00297189c323096aae8e2975de94e8549613cyshang{ 4128a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireLock (&gProtocolDatabaseLock); 4228a00297189c323096aae8e2975de94e8549613cyshang} 4328a00297189c323096aae8e2975de94e8549613cyshang 4428a00297189c323096aae8e2975de94e8549613cyshang 45162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 46162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 47162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Release lock on gProtocolDatabaseLock. 48162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 49162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 5028a00297189c323096aae8e2975de94e8549613cyshangVOID 5128a00297189c323096aae8e2975de94e8549613cyshangCoreReleaseProtocolLock ( 5228a00297189c323096aae8e2975de94e8549613cyshang VOID 5328a00297189c323096aae8e2975de94e8549613cyshang ) 5428a00297189c323096aae8e2975de94e8549613cyshang{ 5528a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseLock (&gProtocolDatabaseLock); 5628a00297189c323096aae8e2975de94e8549613cyshang} 5728a00297189c323096aae8e2975de94e8549613cyshang 5828a00297189c323096aae8e2975de94e8549613cyshang 5928a00297189c323096aae8e2975de94e8549613cyshang 60162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 6128a00297189c323096aae8e2975de94e8549613cyshang Check whether a handle is a valid EFI_HANDLE 6228a00297189c323096aae8e2975de94e8549613cyshang 63022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to check 6428a00297189c323096aae8e2975de94e8549613cyshang 65022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE. 66162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @retval EFI_SUCCESS The handle is valid EFI_HANDLE. 6728a00297189c323096aae8e2975de94e8549613cyshang 68162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 69162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS 70162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreValidateHandle ( 71162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN EFI_HANDLE UserHandle 72162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 7328a00297189c323096aae8e2975de94e8549613cyshang{ 7428a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 7528a00297189c323096aae8e2975de94e8549613cyshang 7628a00297189c323096aae8e2975de94e8549613cyshang Handle = (IHANDLE *)UserHandle; 7728a00297189c323096aae8e2975de94e8549613cyshang if (Handle == NULL) { 7828a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 7928a00297189c323096aae8e2975de94e8549613cyshang } 8028a00297189c323096aae8e2975de94e8549613cyshang if (Handle->Signature != EFI_HANDLE_SIGNATURE) { 8128a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 8228a00297189c323096aae8e2975de94e8549613cyshang } 8328a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 8428a00297189c323096aae8e2975de94e8549613cyshang} 8528a00297189c323096aae8e2975de94e8549613cyshang 8628a00297189c323096aae8e2975de94e8549613cyshang 8728a00297189c323096aae8e2975de94e8549613cyshang 88162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 8928a00297189c323096aae8e2975de94e8549613cyshang Finds the protocol entry for the requested protocol. 9028a00297189c323096aae8e2975de94e8549613cyshang The gProtocolDatabaseLock must be owned 9128a00297189c323096aae8e2975de94e8549613cyshang 92022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The ID of the protocol 93022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Create Create a new entry if not found 9428a00297189c323096aae8e2975de94e8549613cyshang 95162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Protocol entry 9628a00297189c323096aae8e2975de94e8549613cyshang 97162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 98162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangPROTOCOL_ENTRY * 99162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreFindProtocolEntry ( 100162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN EFI_GUID *Protocol, 101162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN BOOLEAN Create 102162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 10328a00297189c323096aae8e2975de94e8549613cyshang{ 10428a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 10528a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *Item; 10628a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *ProtEntry; 10728a00297189c323096aae8e2975de94e8549613cyshang 10828a00297189c323096aae8e2975de94e8549613cyshang ASSERT_LOCKED(&gProtocolDatabaseLock); 10928a00297189c323096aae8e2975de94e8549613cyshang 11028a00297189c323096aae8e2975de94e8549613cyshang // 11128a00297189c323096aae8e2975de94e8549613cyshang // Search the database for the matching GUID 11228a00297189c323096aae8e2975de94e8549613cyshang // 11328a00297189c323096aae8e2975de94e8549613cyshang 11428a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = NULL; 115022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (Link = mProtocolDatabase.ForwardLink; 116022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Link != &mProtocolDatabase; 11728a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink) { 11828a00297189c323096aae8e2975de94e8549613cyshang 11928a00297189c323096aae8e2975de94e8549613cyshang Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); 12028a00297189c323096aae8e2975de94e8549613cyshang if (CompareGuid (&Item->ProtocolID, Protocol)) { 12128a00297189c323096aae8e2975de94e8549613cyshang 12228a00297189c323096aae8e2975de94e8549613cyshang // 12328a00297189c323096aae8e2975de94e8549613cyshang // This is the protocol entry 12428a00297189c323096aae8e2975de94e8549613cyshang // 12528a00297189c323096aae8e2975de94e8549613cyshang 12628a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = Item; 12728a00297189c323096aae8e2975de94e8549613cyshang break; 12828a00297189c323096aae8e2975de94e8549613cyshang } 12928a00297189c323096aae8e2975de94e8549613cyshang } 13028a00297189c323096aae8e2975de94e8549613cyshang 13128a00297189c323096aae8e2975de94e8549613cyshang // 132022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // If the protocol entry was not found and Create is TRUE, then 13328a00297189c323096aae8e2975de94e8549613cyshang // allocate a new entry 134022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // 13528a00297189c323096aae8e2975de94e8549613cyshang if ((ProtEntry == NULL) && Create) { 1369c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ProtEntry = AllocatePool (sizeof(PROTOCOL_ENTRY)); 137022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 13828a00297189c323096aae8e2975de94e8549613cyshang if (ProtEntry != NULL) { 13928a00297189c323096aae8e2975de94e8549613cyshang // 14028a00297189c323096aae8e2975de94e8549613cyshang // Initialize new protocol entry structure 14128a00297189c323096aae8e2975de94e8549613cyshang // 14228a00297189c323096aae8e2975de94e8549613cyshang ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE; 143e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol); 14428a00297189c323096aae8e2975de94e8549613cyshang InitializeListHead (&ProtEntry->Protocols); 14528a00297189c323096aae8e2975de94e8549613cyshang InitializeListHead (&ProtEntry->Notify); 14628a00297189c323096aae8e2975de94e8549613cyshang 14728a00297189c323096aae8e2975de94e8549613cyshang // 14828a00297189c323096aae8e2975de94e8549613cyshang // Add it to protocol database 14928a00297189c323096aae8e2975de94e8549613cyshang // 15028a00297189c323096aae8e2975de94e8549613cyshang InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries); 15128a00297189c323096aae8e2975de94e8549613cyshang } 15228a00297189c323096aae8e2975de94e8549613cyshang } 15328a00297189c323096aae8e2975de94e8549613cyshang 15428a00297189c323096aae8e2975de94e8549613cyshang return ProtEntry; 15528a00297189c323096aae8e2975de94e8549613cyshang} 15628a00297189c323096aae8e2975de94e8549613cyshang 15728a00297189c323096aae8e2975de94e8549613cyshang 158162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 159162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 160162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Finds the protocol instance for the requested handle and protocol. 161162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Note: This function doesn't do parameters checking, it's caller's responsibility 162162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang to pass in valid parameters. 163162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 164022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Handle The handle to search the protocol on 165022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol GUID of the protocol 166022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface The interface for the protocol being searched 167162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 168162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Protocol instance (NULL: Not found) 169162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 170162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 17128a00297189c323096aae8e2975de94e8549613cyshangPROTOCOL_INTERFACE * 17228a00297189c323096aae8e2975de94e8549613cyshangCoreFindProtocolInterface ( 17328a00297189c323096aae8e2975de94e8549613cyshang IN IHANDLE *Handle, 17428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 17528a00297189c323096aae8e2975de94e8549613cyshang IN VOID *Interface 17628a00297189c323096aae8e2975de94e8549613cyshang ) 17728a00297189c323096aae8e2975de94e8549613cyshang{ 17828a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 17928a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *ProtEntry; 18028a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 18128a00297189c323096aae8e2975de94e8549613cyshang 18228a00297189c323096aae8e2975de94e8549613cyshang ASSERT_LOCKED(&gProtocolDatabaseLock); 18328a00297189c323096aae8e2975de94e8549613cyshang Prot = NULL; 18428a00297189c323096aae8e2975de94e8549613cyshang 18528a00297189c323096aae8e2975de94e8549613cyshang // 18628a00297189c323096aae8e2975de94e8549613cyshang // Lookup the protocol entry for this protocol ID 18728a00297189c323096aae8e2975de94e8549613cyshang // 18828a00297189c323096aae8e2975de94e8549613cyshang 18928a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); 19028a00297189c323096aae8e2975de94e8549613cyshang if (ProtEntry != NULL) { 19128a00297189c323096aae8e2975de94e8549613cyshang 19228a00297189c323096aae8e2975de94e8549613cyshang // 19328a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for any matches 19428a00297189c323096aae8e2975de94e8549613cyshang // 19528a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) { 19628a00297189c323096aae8e2975de94e8549613cyshang 19728a00297189c323096aae8e2975de94e8549613cyshang // 19828a00297189c323096aae8e2975de94e8549613cyshang // If this protocol interface matches, remove it 19928a00297189c323096aae8e2975de94e8549613cyshang // 20028a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 20128a00297189c323096aae8e2975de94e8549613cyshang if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) { 20228a00297189c323096aae8e2975de94e8549613cyshang break; 20328a00297189c323096aae8e2975de94e8549613cyshang } 20428a00297189c323096aae8e2975de94e8549613cyshang 20528a00297189c323096aae8e2975de94e8549613cyshang Prot = NULL; 20628a00297189c323096aae8e2975de94e8549613cyshang } 20728a00297189c323096aae8e2975de94e8549613cyshang } 20828a00297189c323096aae8e2975de94e8549613cyshang 20928a00297189c323096aae8e2975de94e8549613cyshang return Prot; 21028a00297189c323096aae8e2975de94e8549613cyshang} 21128a00297189c323096aae8e2975de94e8549613cyshang 21228a00297189c323096aae8e2975de94e8549613cyshang 213162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 21428a00297189c323096aae8e2975de94e8549613cyshang Removes an event from a register protocol notify list on a protocol. 21528a00297189c323096aae8e2975de94e8549613cyshang 216022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Event The event to search for in the protocol 217022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang database. 21828a00297189c323096aae8e2975de94e8549613cyshang 219162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return EFI_SUCCESS if the event was found and removed. 220162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return EFI_NOT_FOUND if the event was not found in the protocl database. 22128a00297189c323096aae8e2975de94e8549613cyshang 222162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 223162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS 224162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreUnregisterProtocolNotifyEvent ( 225162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN EFI_EVENT Event 226162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 22728a00297189c323096aae8e2975de94e8549613cyshang{ 22828a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 22928a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *ProtEntry; 23028a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *NotifyLink; 23128a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_NOTIFY *ProtNotify; 23228a00297189c323096aae8e2975de94e8549613cyshang 23328a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 23428a00297189c323096aae8e2975de94e8549613cyshang 235022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for ( Link = mProtocolDatabase.ForwardLink; 236022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Link != &mProtocolDatabase; 23728a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink) { 23828a00297189c323096aae8e2975de94e8549613cyshang 23928a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); 24028a00297189c323096aae8e2975de94e8549613cyshang 241022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for ( NotifyLink = ProtEntry->Notify.ForwardLink; 242022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NotifyLink != &ProtEntry->Notify; 24328a00297189c323096aae8e2975de94e8549613cyshang NotifyLink = NotifyLink->ForwardLink) { 24428a00297189c323096aae8e2975de94e8549613cyshang 24528a00297189c323096aae8e2975de94e8549613cyshang ProtNotify = CR(NotifyLink, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); 24628a00297189c323096aae8e2975de94e8549613cyshang 24728a00297189c323096aae8e2975de94e8549613cyshang if (ProtNotify->Event == Event) { 24828a00297189c323096aae8e2975de94e8549613cyshang RemoveEntryList(&ProtNotify->Link); 24928a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool(ProtNotify); 25028a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 25128a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 25228a00297189c323096aae8e2975de94e8549613cyshang } 25328a00297189c323096aae8e2975de94e8549613cyshang } 25428a00297189c323096aae8e2975de94e8549613cyshang } 25528a00297189c323096aae8e2975de94e8549613cyshang 25628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 25728a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 25828a00297189c323096aae8e2975de94e8549613cyshang} 25928a00297189c323096aae8e2975de94e8549613cyshang 26028a00297189c323096aae8e2975de94e8549613cyshang 26128a00297189c323096aae8e2975de94e8549613cyshang 262162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 26328a00297189c323096aae8e2975de94e8549613cyshang Removes all the events in the protocol database that match Event. 26428a00297189c323096aae8e2975de94e8549613cyshang 265022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Event The event to search for in the protocol 266022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang database. 26728a00297189c323096aae8e2975de94e8549613cyshang 268162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return EFI_SUCCESS when done searching the entire database. 26928a00297189c323096aae8e2975de94e8549613cyshang 270162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 271162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS 272162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreUnregisterProtocolNotify ( 273162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN EFI_EVENT Event 274162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 27528a00297189c323096aae8e2975de94e8549613cyshang{ 27628a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 27728a00297189c323096aae8e2975de94e8549613cyshang 27828a00297189c323096aae8e2975de94e8549613cyshang do { 27928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreUnregisterProtocolNotifyEvent (Event); 28028a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 28128a00297189c323096aae8e2975de94e8549613cyshang 28228a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 28328a00297189c323096aae8e2975de94e8549613cyshang} 28428a00297189c323096aae8e2975de94e8549613cyshang 28528a00297189c323096aae8e2975de94e8549613cyshang 28628a00297189c323096aae8e2975de94e8549613cyshang 287162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 288162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 289162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which 290162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Calls the private one which contains a BOOLEAN parameter for notifications 291162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 292022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to install the protocol handler on, 293022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang or NULL if a new handle is to be allocated 294022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The protocol to add to the handle 295022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param InterfaceType Indicates whether Interface is supplied in 296022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang native form. 297022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface The interface for the protocol being added 298162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 299162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Status code 300162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 301162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 30228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 30328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 30428a00297189c323096aae8e2975de94e8549613cyshangCoreInstallProtocolInterface ( 30528a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_HANDLE *UserHandle, 30628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 30728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_INTERFACE_TYPE InterfaceType, 30828a00297189c323096aae8e2975de94e8549613cyshang IN VOID *Interface 30928a00297189c323096aae8e2975de94e8549613cyshang ) 31028a00297189c323096aae8e2975de94e8549613cyshang{ 31128a00297189c323096aae8e2975de94e8549613cyshang return CoreInstallProtocolInterfaceNotify ( 312022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang UserHandle, 313022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Protocol, 314022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang InterfaceType, 315022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Interface, 31628a00297189c323096aae8e2975de94e8549613cyshang TRUE 31728a00297189c323096aae8e2975de94e8549613cyshang ); 31828a00297189c323096aae8e2975de94e8549613cyshang} 31928a00297189c323096aae8e2975de94e8549613cyshang 320162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 321162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 322162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Installs a protocol interface into the boot services environment. 323162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 324022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to install the protocol handler on, 325022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang or NULL if a new handle is to be allocated 326022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The protocol to add to the handle 327022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param InterfaceType Indicates whether Interface is supplied in 328022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang native form. 329022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface The interface for the protocol being added 330022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Notify indicates whether notify the notification list 331022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for this protocol 332022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 333022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Invalid parameter 334022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate 335162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @retval EFI_SUCCESS Protocol interface successfully installed 336162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 337162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 33828a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 33928a00297189c323096aae8e2975de94e8549613cyshangCoreInstallProtocolInterfaceNotify ( 34028a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_HANDLE *UserHandle, 34128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 34228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_INTERFACE_TYPE InterfaceType, 34328a00297189c323096aae8e2975de94e8549613cyshang IN VOID *Interface, 34428a00297189c323096aae8e2975de94e8549613cyshang IN BOOLEAN Notify 34528a00297189c323096aae8e2975de94e8549613cyshang ) 34628a00297189c323096aae8e2975de94e8549613cyshang{ 34728a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 34828a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *ProtEntry; 34928a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 35028a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 35128a00297189c323096aae8e2975de94e8549613cyshang VOID *ExistingInterface; 35228a00297189c323096aae8e2975de94e8549613cyshang 35328a00297189c323096aae8e2975de94e8549613cyshang // 35428a00297189c323096aae8e2975de94e8549613cyshang // returns EFI_INVALID_PARAMETER if InterfaceType is invalid. 35528a00297189c323096aae8e2975de94e8549613cyshang // Also added check for invalid UserHandle and Protocol pointers. 35628a00297189c323096aae8e2975de94e8549613cyshang // 35728a00297189c323096aae8e2975de94e8549613cyshang if (UserHandle == NULL || Protocol == NULL) { 35828a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 35928a00297189c323096aae8e2975de94e8549613cyshang } 36028a00297189c323096aae8e2975de94e8549613cyshang 36128a00297189c323096aae8e2975de94e8549613cyshang if (InterfaceType != EFI_NATIVE_INTERFACE) { 36228a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 36328a00297189c323096aae8e2975de94e8549613cyshang } 36428a00297189c323096aae8e2975de94e8549613cyshang 36528a00297189c323096aae8e2975de94e8549613cyshang // 36628a00297189c323096aae8e2975de94e8549613cyshang // Print debug message 36728a00297189c323096aae8e2975de94e8549613cyshang // 36858125fb3f9dda7f15a540b16595dc24dab0dd423qhuang DEBUG((DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface)); 36928a00297189c323096aae8e2975de94e8549613cyshang 37028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 37128a00297189c323096aae8e2975de94e8549613cyshang Prot = NULL; 37228a00297189c323096aae8e2975de94e8549613cyshang Handle = NULL; 37328a00297189c323096aae8e2975de94e8549613cyshang 3744008328a99b99770764d1988e9fb2e12ce57e9f3qwang if (*UserHandle != NULL) { 37528a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface); 37628a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 37728a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 37828a00297189c323096aae8e2975de94e8549613cyshang } 37928a00297189c323096aae8e2975de94e8549613cyshang } 38028a00297189c323096aae8e2975de94e8549613cyshang 38128a00297189c323096aae8e2975de94e8549613cyshang // 382022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // Lock the protocol database 38328a00297189c323096aae8e2975de94e8549613cyshang // 38428a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 38528a00297189c323096aae8e2975de94e8549613cyshang 38628a00297189c323096aae8e2975de94e8549613cyshang // 38728a00297189c323096aae8e2975de94e8549613cyshang // Lookup the Protocol Entry for the requested protocol 38828a00297189c323096aae8e2975de94e8549613cyshang // 38928a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = CoreFindProtocolEntry (Protocol, TRUE); 39028a00297189c323096aae8e2975de94e8549613cyshang if (ProtEntry == NULL) { 39128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 39228a00297189c323096aae8e2975de94e8549613cyshang } 39328a00297189c323096aae8e2975de94e8549613cyshang 39428a00297189c323096aae8e2975de94e8549613cyshang // 39528a00297189c323096aae8e2975de94e8549613cyshang // Allocate a new protocol interface structure 39628a00297189c323096aae8e2975de94e8549613cyshang // 3979c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang Prot = AllocateZeroPool (sizeof(PROTOCOL_INTERFACE)); 39828a00297189c323096aae8e2975de94e8549613cyshang if (Prot == NULL) { 39928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 40028a00297189c323096aae8e2975de94e8549613cyshang goto Done; 40128a00297189c323096aae8e2975de94e8549613cyshang } 40228a00297189c323096aae8e2975de94e8549613cyshang 40328a00297189c323096aae8e2975de94e8549613cyshang // 40428a00297189c323096aae8e2975de94e8549613cyshang // If caller didn't supply a handle, allocate a new one 40528a00297189c323096aae8e2975de94e8549613cyshang // 40628a00297189c323096aae8e2975de94e8549613cyshang Handle = (IHANDLE *)*UserHandle; 40728a00297189c323096aae8e2975de94e8549613cyshang if (Handle == NULL) { 4089c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang Handle = AllocateZeroPool (sizeof(IHANDLE)); 40928a00297189c323096aae8e2975de94e8549613cyshang if (Handle == NULL) { 41028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 41128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 41228a00297189c323096aae8e2975de94e8549613cyshang } 41328a00297189c323096aae8e2975de94e8549613cyshang 41428a00297189c323096aae8e2975de94e8549613cyshang // 41528a00297189c323096aae8e2975de94e8549613cyshang // Initialize new handler structure 41628a00297189c323096aae8e2975de94e8549613cyshang // 41728a00297189c323096aae8e2975de94e8549613cyshang Handle->Signature = EFI_HANDLE_SIGNATURE; 41828a00297189c323096aae8e2975de94e8549613cyshang InitializeListHead (&Handle->Protocols); 41928a00297189c323096aae8e2975de94e8549613cyshang 42028a00297189c323096aae8e2975de94e8549613cyshang // 42128a00297189c323096aae8e2975de94e8549613cyshang // Initialize the Key to show that the handle has been created/modified 42228a00297189c323096aae8e2975de94e8549613cyshang // 42328a00297189c323096aae8e2975de94e8549613cyshang gHandleDatabaseKey++; 42428a00297189c323096aae8e2975de94e8549613cyshang Handle->Key = gHandleDatabaseKey; 42528a00297189c323096aae8e2975de94e8549613cyshang 42628a00297189c323096aae8e2975de94e8549613cyshang // 42728a00297189c323096aae8e2975de94e8549613cyshang // Add this handle to the list global list of all handles 42828a00297189c323096aae8e2975de94e8549613cyshang // in the system 42928a00297189c323096aae8e2975de94e8549613cyshang // 43028a00297189c323096aae8e2975de94e8549613cyshang InsertTailList (&gHandleList, &Handle->AllHandles); 431022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 43228a00297189c323096aae8e2975de94e8549613cyshang 43328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (Handle); 43428a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 43528a00297189c323096aae8e2975de94e8549613cyshang goto Done; 43628a00297189c323096aae8e2975de94e8549613cyshang } 43728a00297189c323096aae8e2975de94e8549613cyshang 43828a00297189c323096aae8e2975de94e8549613cyshang // 43928a00297189c323096aae8e2975de94e8549613cyshang // Each interface that is added must be unique 44028a00297189c323096aae8e2975de94e8549613cyshang // 44128a00297189c323096aae8e2975de94e8549613cyshang ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL); 44228a00297189c323096aae8e2975de94e8549613cyshang 44328a00297189c323096aae8e2975de94e8549613cyshang // 44428a00297189c323096aae8e2975de94e8549613cyshang // Initialize the protocol interface structure 44528a00297189c323096aae8e2975de94e8549613cyshang // 44628a00297189c323096aae8e2975de94e8549613cyshang Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE; 44728a00297189c323096aae8e2975de94e8549613cyshang Prot->Handle = Handle; 44828a00297189c323096aae8e2975de94e8549613cyshang Prot->Protocol = ProtEntry; 44928a00297189c323096aae8e2975de94e8549613cyshang Prot->Interface = Interface; 45028a00297189c323096aae8e2975de94e8549613cyshang 45128a00297189c323096aae8e2975de94e8549613cyshang // 45228a00297189c323096aae8e2975de94e8549613cyshang // Initalize OpenProtocol Data base 45328a00297189c323096aae8e2975de94e8549613cyshang // 45428a00297189c323096aae8e2975de94e8549613cyshang InitializeListHead (&Prot->OpenList); 45528a00297189c323096aae8e2975de94e8549613cyshang Prot->OpenListCount = 0; 45628a00297189c323096aae8e2975de94e8549613cyshang 45728a00297189c323096aae8e2975de94e8549613cyshang // 458022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // Add this protocol interface to the head of the supported 45928a00297189c323096aae8e2975de94e8549613cyshang // protocol list for this handle 46028a00297189c323096aae8e2975de94e8549613cyshang // 46128a00297189c323096aae8e2975de94e8549613cyshang InsertHeadList (&Handle->Protocols, &Prot->Link); 46228a00297189c323096aae8e2975de94e8549613cyshang 46328a00297189c323096aae8e2975de94e8549613cyshang // 464022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // Add this protocol interface to the tail of the 46528a00297189c323096aae8e2975de94e8549613cyshang // protocol entry 466022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // 46728a00297189c323096aae8e2975de94e8549613cyshang InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); 46828a00297189c323096aae8e2975de94e8549613cyshang 46928a00297189c323096aae8e2975de94e8549613cyshang // 470022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // Notify the notification list for this protocol 47128a00297189c323096aae8e2975de94e8549613cyshang // 47228a00297189c323096aae8e2975de94e8549613cyshang if (Notify) { 47328a00297189c323096aae8e2975de94e8549613cyshang CoreNotifyProtocolEntry (ProtEntry); 47428a00297189c323096aae8e2975de94e8549613cyshang } 47528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 47628a00297189c323096aae8e2975de94e8549613cyshang 47728a00297189c323096aae8e2975de94e8549613cyshangDone: 47828a00297189c323096aae8e2975de94e8549613cyshang // 47928a00297189c323096aae8e2975de94e8549613cyshang // Done, unlock the database and return 48028a00297189c323096aae8e2975de94e8549613cyshang // 48128a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 48228a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 48328a00297189c323096aae8e2975de94e8549613cyshang // 48428a00297189c323096aae8e2975de94e8549613cyshang // Return the new handle back to the caller 48528a00297189c323096aae8e2975de94e8549613cyshang // 48628a00297189c323096aae8e2975de94e8549613cyshang *UserHandle = Handle; 48728a00297189c323096aae8e2975de94e8549613cyshang } else { 48828a00297189c323096aae8e2975de94e8549613cyshang // 48928a00297189c323096aae8e2975de94e8549613cyshang // There was an error, clean up 49028a00297189c323096aae8e2975de94e8549613cyshang // 49128a00297189c323096aae8e2975de94e8549613cyshang if (Prot != NULL) { 49228a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (Prot); 49328a00297189c323096aae8e2975de94e8549613cyshang } 49428a00297189c323096aae8e2975de94e8549613cyshang } 49528a00297189c323096aae8e2975de94e8549613cyshang 49628a00297189c323096aae8e2975de94e8549613cyshang return Status; 49728a00297189c323096aae8e2975de94e8549613cyshang} 49828a00297189c323096aae8e2975de94e8549613cyshang 49928a00297189c323096aae8e2975de94e8549613cyshang 50028a00297189c323096aae8e2975de94e8549613cyshang 50128a00297189c323096aae8e2975de94e8549613cyshang 502162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 50328a00297189c323096aae8e2975de94e8549613cyshang Installs a list of protocol interface into the boot services environment. 50428a00297189c323096aae8e2975de94e8549613cyshang This function calls InstallProtocolInterface() in a loop. If any error 505162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang occures all the protocols added by this function are removed. This is 50628a00297189c323096aae8e2975de94e8549613cyshang basically a lib function to save space. 50728a00297189c323096aae8e2975de94e8549613cyshang 5084a23eaa9e0400325624e7d45b4a0e1e39c431d30niruiyu @param Handle The pointer to a handle to install the new 5094a23eaa9e0400325624e7d45b4a0e1e39c431d30niruiyu protocol interfaces on, or a pointer to NULL 5104a23eaa9e0400325624e7d45b4a0e1e39c431d30niruiyu if a new handle is to be allocated. 511022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ... EFI_GUID followed by protocol instance. A NULL 512022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang terminates the list. The pairs are the 513022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang arguments to InstallProtocolInterface(). All the 514022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocols are added to Handle. 51528a00297189c323096aae8e2975de94e8549613cyshang 5165a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin Qiu @retval EFI_SUCCESS All the protocol interface was installed. 5175a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin Qiu @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. 5185a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin Qiu @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in 5195a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin Qiu the handle database. 520022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Handle is NULL. 5215a7b9bbe08a5dfc8de6f5091a4b140818604d403Shumin Qiu @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. 52228a00297189c323096aae8e2975de94e8549613cyshang 523162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 524162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS 525162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFIAPI 526162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreInstallMultipleProtocolInterfaces ( 527162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN OUT EFI_HANDLE *Handle, 528162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ... 529162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 53028a00297189c323096aae8e2975de94e8549613cyshang{ 531162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_LIST Args; 53228a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 53328a00297189c323096aae8e2975de94e8549613cyshang EFI_GUID *Protocol; 53428a00297189c323096aae8e2975de94e8549613cyshang VOID *Interface; 53528a00297189c323096aae8e2975de94e8549613cyshang EFI_TPL OldTpl; 53628a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 53728a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE OldHandle; 53828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DeviceHandle; 53928a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_PATH_PROTOCOL *DevicePath; 540022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 54128a00297189c323096aae8e2975de94e8549613cyshang if (Handle == NULL) { 54228a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 54328a00297189c323096aae8e2975de94e8549613cyshang } 544022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 545022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // 546022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // Syncronize with notifcations. 54728a00297189c323096aae8e2975de94e8549613cyshang // 54828a00297189c323096aae8e2975de94e8549613cyshang OldTpl = CoreRaiseTpl (TPL_NOTIFY); 54928a00297189c323096aae8e2975de94e8549613cyshang OldHandle = *Handle; 55028a00297189c323096aae8e2975de94e8549613cyshang 55128a00297189c323096aae8e2975de94e8549613cyshang // 55228a00297189c323096aae8e2975de94e8549613cyshang // Check for duplicate device path and install the protocol interfaces 55328a00297189c323096aae8e2975de94e8549613cyshang // 554162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_START (Args, Handle); 55528a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 55628a00297189c323096aae8e2975de94e8549613cyshang // 55728a00297189c323096aae8e2975de94e8549613cyshang // If protocol is NULL, then it's the end of the list 55828a00297189c323096aae8e2975de94e8549613cyshang // 559162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Protocol = VA_ARG (Args, EFI_GUID *); 56028a00297189c323096aae8e2975de94e8549613cyshang if (Protocol == NULL) { 56128a00297189c323096aae8e2975de94e8549613cyshang break; 56228a00297189c323096aae8e2975de94e8549613cyshang } 56328a00297189c323096aae8e2975de94e8549613cyshang 564162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Interface = VA_ARG (Args, VOID *); 56528a00297189c323096aae8e2975de94e8549613cyshang 56628a00297189c323096aae8e2975de94e8549613cyshang // 56728a00297189c323096aae8e2975de94e8549613cyshang // Make sure you are installing on top a device path that has already been added. 56828a00297189c323096aae8e2975de94e8549613cyshang // 56928a00297189c323096aae8e2975de94e8549613cyshang if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { 57028a00297189c323096aae8e2975de94e8549613cyshang DeviceHandle = NULL; 57128a00297189c323096aae8e2975de94e8549613cyshang DevicePath = Interface; 57228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle); 5734008328a99b99770764d1988e9fb2e12ce57e9f3qwang if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(DevicePath)) { 57428a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ALREADY_STARTED; 57528a00297189c323096aae8e2975de94e8549613cyshang continue; 57628a00297189c323096aae8e2975de94e8549613cyshang } 57728a00297189c323096aae8e2975de94e8549613cyshang } 578022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 57928a00297189c323096aae8e2975de94e8549613cyshang // 58028a00297189c323096aae8e2975de94e8549613cyshang // Install it 58128a00297189c323096aae8e2975de94e8549613cyshang // 58228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); 58328a00297189c323096aae8e2975de94e8549613cyshang } 584a70c0fd846dc339135c0b5607983d20d891dc149qwang VA_END (Args); 585022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 58628a00297189c323096aae8e2975de94e8549613cyshang // 58728a00297189c323096aae8e2975de94e8549613cyshang // If there was an error, remove all the interfaces that were installed without any errors 58828a00297189c323096aae8e2975de94e8549613cyshang // 58928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 59028a00297189c323096aae8e2975de94e8549613cyshang // 59128a00297189c323096aae8e2975de94e8549613cyshang // Reset the va_arg back to the first argument. 59228a00297189c323096aae8e2975de94e8549613cyshang // 593162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_START (Args, Handle); 59428a00297189c323096aae8e2975de94e8549613cyshang for (; Index > 1; Index--) { 595162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Protocol = VA_ARG (Args, EFI_GUID *); 596162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Interface = VA_ARG (Args, VOID *); 59728a00297189c323096aae8e2975de94e8549613cyshang CoreUninstallProtocolInterface (*Handle, Protocol, Interface); 598022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 599a70c0fd846dc339135c0b5607983d20d891dc149qwang VA_END (Args); 600a70c0fd846dc339135c0b5607983d20d891dc149qwang 60128a00297189c323096aae8e2975de94e8549613cyshang *Handle = OldHandle; 60228a00297189c323096aae8e2975de94e8549613cyshang } 60328a00297189c323096aae8e2975de94e8549613cyshang 60428a00297189c323096aae8e2975de94e8549613cyshang // 60528a00297189c323096aae8e2975de94e8549613cyshang // Done 60628a00297189c323096aae8e2975de94e8549613cyshang // 60728a00297189c323096aae8e2975de94e8549613cyshang CoreRestoreTpl (OldTpl); 60828a00297189c323096aae8e2975de94e8549613cyshang return Status; 60928a00297189c323096aae8e2975de94e8549613cyshang} 61028a00297189c323096aae8e2975de94e8549613cyshang 61128a00297189c323096aae8e2975de94e8549613cyshang 612162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 61328a00297189c323096aae8e2975de94e8549613cyshang Attempts to disconnect all drivers that are using the protocol interface being queried. 61428a00297189c323096aae8e2975de94e8549613cyshang If failed, reconnect all drivers disconnected. 615162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Note: This function doesn't do parameters checking, it's caller's responsibility 616162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang to pass in valid parameters. 61728a00297189c323096aae8e2975de94e8549613cyshang 618022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle on which the protocol is installed 619022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Prot The protocol to disconnect drivers from 62028a00297189c323096aae8e2975de94e8549613cyshang 621022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS Drivers using the protocol interface are all 622022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected 623162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers 62428a00297189c323096aae8e2975de94e8549613cyshang 625162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 626162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS 627162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreDisconnectControllersUsingProtocolInterface ( 628162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN EFI_HANDLE UserHandle, 629162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang IN PROTOCOL_INTERFACE *Prot 630162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 63128a00297189c323096aae8e2975de94e8549613cyshang{ 63228a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 63328a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ItemFound; 63428a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 63528a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 63628a00297189c323096aae8e2975de94e8549613cyshang 63728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 638022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 63928a00297189c323096aae8e2975de94e8549613cyshang // 64028a00297189c323096aae8e2975de94e8549613cyshang // Attempt to disconnect all drivers from this protocol interface 64128a00297189c323096aae8e2975de94e8549613cyshang // 64228a00297189c323096aae8e2975de94e8549613cyshang do { 64328a00297189c323096aae8e2975de94e8549613cyshang ItemFound = FALSE; 64428a00297189c323096aae8e2975de94e8549613cyshang for ( Link = Prot->OpenList.ForwardLink; 64528a00297189c323096aae8e2975de94e8549613cyshang (Link != &Prot->OpenList) && !ItemFound; 64628a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink ) { 64728a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 6486e53646837da984d2f5dd64467ba7a8943b459aeqhuang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 64928a00297189c323096aae8e2975de94e8549613cyshang ItemFound = TRUE; 65028a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 65128a00297189c323096aae8e2975de94e8549613cyshang Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL); 65228a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 65328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 65428a00297189c323096aae8e2975de94e8549613cyshang ItemFound = FALSE; 65528a00297189c323096aae8e2975de94e8549613cyshang break; 65628a00297189c323096aae8e2975de94e8549613cyshang } 65728a00297189c323096aae8e2975de94e8549613cyshang } 65828a00297189c323096aae8e2975de94e8549613cyshang } 65928a00297189c323096aae8e2975de94e8549613cyshang } while (ItemFound); 66028a00297189c323096aae8e2975de94e8549613cyshang 66128a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 66228a00297189c323096aae8e2975de94e8549613cyshang // 66328a00297189c323096aae8e2975de94e8549613cyshang // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items 66428a00297189c323096aae8e2975de94e8549613cyshang // 66528a00297189c323096aae8e2975de94e8549613cyshang do { 66628a00297189c323096aae8e2975de94e8549613cyshang ItemFound = FALSE; 66728a00297189c323096aae8e2975de94e8549613cyshang for ( Link = Prot->OpenList.ForwardLink; 66828a00297189c323096aae8e2975de94e8549613cyshang (Link != &Prot->OpenList) && !ItemFound; 66928a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink ) { 67028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 6716e53646837da984d2f5dd64467ba7a8943b459aeqhuang if ((OpenData->Attributes & 6726e53646837da984d2f5dd64467ba7a8943b459aeqhuang (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) { 67328a00297189c323096aae8e2975de94e8549613cyshang ItemFound = TRUE; 674022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang RemoveEntryList (&OpenData->Link); 67528a00297189c323096aae8e2975de94e8549613cyshang Prot->OpenListCount--; 67628a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (OpenData); 67728a00297189c323096aae8e2975de94e8549613cyshang } 67828a00297189c323096aae8e2975de94e8549613cyshang } 67928a00297189c323096aae8e2975de94e8549613cyshang } while (ItemFound); 68028a00297189c323096aae8e2975de94e8549613cyshang } 68128a00297189c323096aae8e2975de94e8549613cyshang 68228a00297189c323096aae8e2975de94e8549613cyshang // 68328a00297189c323096aae8e2975de94e8549613cyshang // If there are errors or still has open items in the list, then reconnect all the drivers and return an error 68428a00297189c323096aae8e2975de94e8549613cyshang // 68528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) { 68628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 68728a00297189c323096aae8e2975de94e8549613cyshang CoreConnectController (UserHandle, NULL, NULL, TRUE); 68828a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 68928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ACCESS_DENIED; 69028a00297189c323096aae8e2975de94e8549613cyshang } 69128a00297189c323096aae8e2975de94e8549613cyshang 69228a00297189c323096aae8e2975de94e8549613cyshang return Status; 69328a00297189c323096aae8e2975de94e8549613cyshang} 69428a00297189c323096aae8e2975de94e8549613cyshang 69528a00297189c323096aae8e2975de94e8549613cyshang 696162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 697162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 698162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Uninstalls all instances of a protocol:interfacer from a handle. 699162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang If the last protocol interface is remove from the handle, the 700162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang handle is freed. 701162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 702022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to remove the protocol handler from 703022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The protocol, of protocol:interface, to remove 704022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface The interface, of protocol:interface, to remove 705162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 706022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Protocol is NULL. 707162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @retval EFI_SUCCESS Protocol interface successfully uninstalled. 708162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 709162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 71028a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 71128a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 71228a00297189c323096aae8e2975de94e8549613cyshangCoreUninstallProtocolInterface ( 71328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 71428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 71528a00297189c323096aae8e2975de94e8549613cyshang IN VOID *Interface 71628a00297189c323096aae8e2975de94e8549613cyshang ) 71728a00297189c323096aae8e2975de94e8549613cyshang{ 71828a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 71928a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 72028a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 72128a00297189c323096aae8e2975de94e8549613cyshang 72228a00297189c323096aae8e2975de94e8549613cyshang // 72328a00297189c323096aae8e2975de94e8549613cyshang // Check that Protocol is valid 72428a00297189c323096aae8e2975de94e8549613cyshang // 72528a00297189c323096aae8e2975de94e8549613cyshang if (Protocol == NULL) { 72628a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 72728a00297189c323096aae8e2975de94e8549613cyshang } 72828a00297189c323096aae8e2975de94e8549613cyshang 72928a00297189c323096aae8e2975de94e8549613cyshang // 73028a00297189c323096aae8e2975de94e8549613cyshang // Check that UserHandle is a valid handle 73128a00297189c323096aae8e2975de94e8549613cyshang // 73228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (UserHandle); 73328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 73428a00297189c323096aae8e2975de94e8549613cyshang return Status; 73528a00297189c323096aae8e2975de94e8549613cyshang } 73628a00297189c323096aae8e2975de94e8549613cyshang 73728a00297189c323096aae8e2975de94e8549613cyshang // 73828a00297189c323096aae8e2975de94e8549613cyshang // Lock the protocol database 73928a00297189c323096aae8e2975de94e8549613cyshang // 74028a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 74128a00297189c323096aae8e2975de94e8549613cyshang 74228a00297189c323096aae8e2975de94e8549613cyshang // 74328a00297189c323096aae8e2975de94e8549613cyshang // Check that Protocol exists on UserHandle, and Interface matches the interface in the database 74428a00297189c323096aae8e2975de94e8549613cyshang // 74528a00297189c323096aae8e2975de94e8549613cyshang Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface); 74628a00297189c323096aae8e2975de94e8549613cyshang if (Prot == NULL) { 74728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 74828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 74928a00297189c323096aae8e2975de94e8549613cyshang } 75028a00297189c323096aae8e2975de94e8549613cyshang 75128a00297189c323096aae8e2975de94e8549613cyshang // 75228a00297189c323096aae8e2975de94e8549613cyshang // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed 75328a00297189c323096aae8e2975de94e8549613cyshang // 75428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreDisconnectControllersUsingProtocolInterface ( 75528a00297189c323096aae8e2975de94e8549613cyshang UserHandle, 75628a00297189c323096aae8e2975de94e8549613cyshang Prot 75728a00297189c323096aae8e2975de94e8549613cyshang ); 75828a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 75928a00297189c323096aae8e2975de94e8549613cyshang // 76028a00297189c323096aae8e2975de94e8549613cyshang // One or more drivers refused to release, so return the error 76128a00297189c323096aae8e2975de94e8549613cyshang // 76228a00297189c323096aae8e2975de94e8549613cyshang goto Done; 76328a00297189c323096aae8e2975de94e8549613cyshang } 76428a00297189c323096aae8e2975de94e8549613cyshang 76528a00297189c323096aae8e2975de94e8549613cyshang // 76628a00297189c323096aae8e2975de94e8549613cyshang // Remove the protocol interface from the protocol 76728a00297189c323096aae8e2975de94e8549613cyshang // 76828a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 76928a00297189c323096aae8e2975de94e8549613cyshang Handle = (IHANDLE *)UserHandle; 77028a00297189c323096aae8e2975de94e8549613cyshang Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface); 77128a00297189c323096aae8e2975de94e8549613cyshang 77228a00297189c323096aae8e2975de94e8549613cyshang if (Prot != NULL) { 77328a00297189c323096aae8e2975de94e8549613cyshang // 77428a00297189c323096aae8e2975de94e8549613cyshang // Update the Key to show that the handle has been created/modified 77528a00297189c323096aae8e2975de94e8549613cyshang // 77628a00297189c323096aae8e2975de94e8549613cyshang gHandleDatabaseKey++; 77728a00297189c323096aae8e2975de94e8549613cyshang Handle->Key = gHandleDatabaseKey; 778022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 77928a00297189c323096aae8e2975de94e8549613cyshang // 78028a00297189c323096aae8e2975de94e8549613cyshang // Remove the protocol interface from the handle 78128a00297189c323096aae8e2975de94e8549613cyshang // 78228a00297189c323096aae8e2975de94e8549613cyshang RemoveEntryList (&Prot->Link); 78328a00297189c323096aae8e2975de94e8549613cyshang 78428a00297189c323096aae8e2975de94e8549613cyshang // 78528a00297189c323096aae8e2975de94e8549613cyshang // Free the memory 78628a00297189c323096aae8e2975de94e8549613cyshang // 78728a00297189c323096aae8e2975de94e8549613cyshang Prot->Signature = 0; 78828a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (Prot); 78928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 79028a00297189c323096aae8e2975de94e8549613cyshang } 79128a00297189c323096aae8e2975de94e8549613cyshang 79228a00297189c323096aae8e2975de94e8549613cyshang // 79328a00297189c323096aae8e2975de94e8549613cyshang // If there are no more handlers for the handle, free the handle 79428a00297189c323096aae8e2975de94e8549613cyshang // 79528a00297189c323096aae8e2975de94e8549613cyshang if (IsListEmpty (&Handle->Protocols)) { 79628a00297189c323096aae8e2975de94e8549613cyshang Handle->Signature = 0; 79728a00297189c323096aae8e2975de94e8549613cyshang RemoveEntryList (&Handle->AllHandles); 79828a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (Handle); 79928a00297189c323096aae8e2975de94e8549613cyshang } 80028a00297189c323096aae8e2975de94e8549613cyshang 801022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangDone: 80228a00297189c323096aae8e2975de94e8549613cyshang // 80328a00297189c323096aae8e2975de94e8549613cyshang // Done, unlock the database and return 80428a00297189c323096aae8e2975de94e8549613cyshang // 80528a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 80628a00297189c323096aae8e2975de94e8549613cyshang return Status; 80728a00297189c323096aae8e2975de94e8549613cyshang} 80828a00297189c323096aae8e2975de94e8549613cyshang 80928a00297189c323096aae8e2975de94e8549613cyshang 81028a00297189c323096aae8e2975de94e8549613cyshang 811162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 812162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 813162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Uninstalls a list of protocol interface in the boot services environment. 814162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang This function calls UnisatllProtocolInterface() in a loop. This is 815162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang basically a lib function to save space. 816162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 817022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Handle The handle to uninstall the protocol 818022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ... EFI_GUID followed by protocol instance. A NULL 819022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang terminates the list. The pairs are the 820022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang arguments to UninstallProtocolInterface(). All 821022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the protocols are added to Handle. 822162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 823162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Status code 824162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 825162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 82628a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 82728a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 82828a00297189c323096aae8e2975de94e8549613cyshangCoreUninstallMultipleProtocolInterfaces ( 82928a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE Handle, 83028a00297189c323096aae8e2975de94e8549613cyshang ... 83128a00297189c323096aae8e2975de94e8549613cyshang ) 83228a00297189c323096aae8e2975de94e8549613cyshang{ 83328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 834162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_LIST Args; 83528a00297189c323096aae8e2975de94e8549613cyshang EFI_GUID *Protocol; 83628a00297189c323096aae8e2975de94e8549613cyshang VOID *Interface; 83728a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 83828a00297189c323096aae8e2975de94e8549613cyshang 839162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_START (Args, Handle); 84028a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { 84128a00297189c323096aae8e2975de94e8549613cyshang // 84228a00297189c323096aae8e2975de94e8549613cyshang // If protocol is NULL, then it's the end of the list 84328a00297189c323096aae8e2975de94e8549613cyshang // 844162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Protocol = VA_ARG (Args, EFI_GUID *); 84528a00297189c323096aae8e2975de94e8549613cyshang if (Protocol == NULL) { 84628a00297189c323096aae8e2975de94e8549613cyshang break; 84728a00297189c323096aae8e2975de94e8549613cyshang } 84828a00297189c323096aae8e2975de94e8549613cyshang 849162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Interface = VA_ARG (Args, VOID *); 85028a00297189c323096aae8e2975de94e8549613cyshang 85128a00297189c323096aae8e2975de94e8549613cyshang // 85228a00297189c323096aae8e2975de94e8549613cyshang // Uninstall it 85328a00297189c323096aae8e2975de94e8549613cyshang // 85428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface); 85528a00297189c323096aae8e2975de94e8549613cyshang } 856a70c0fd846dc339135c0b5607983d20d891dc149qwang VA_END (Args); 85728a00297189c323096aae8e2975de94e8549613cyshang 85828a00297189c323096aae8e2975de94e8549613cyshang // 85928a00297189c323096aae8e2975de94e8549613cyshang // If there was an error, add all the interfaces that were 86028a00297189c323096aae8e2975de94e8549613cyshang // uninstalled without any errors 86128a00297189c323096aae8e2975de94e8549613cyshang // 86228a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 86328a00297189c323096aae8e2975de94e8549613cyshang // 86428a00297189c323096aae8e2975de94e8549613cyshang // Reset the va_arg back to the first argument. 86528a00297189c323096aae8e2975de94e8549613cyshang // 866162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VA_START (Args, Handle); 86728a00297189c323096aae8e2975de94e8549613cyshang for (; Index > 1; Index--) { 868162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Protocol = VA_ARG(Args, EFI_GUID *); 869162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Interface = VA_ARG(Args, VOID *); 87028a00297189c323096aae8e2975de94e8549613cyshang CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); 871022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 872a70c0fd846dc339135c0b5607983d20d891dc149qwang VA_END (Args); 87328a00297189c323096aae8e2975de94e8549613cyshang } 87428a00297189c323096aae8e2975de94e8549613cyshang 87528a00297189c323096aae8e2975de94e8549613cyshang return Status; 876022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang} 87728a00297189c323096aae8e2975de94e8549613cyshang 878162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 879162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 880162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Locate a certain GUID protocol interface in a Handle's protocols. 881162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 882022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to obtain the protocol interface on 883022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The GUID of the protocol 884162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 885162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return The requested protocol interface for the handle 886162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 887162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 88828a00297189c323096aae8e2975de94e8549613cyshangPROTOCOL_INTERFACE * 88928a00297189c323096aae8e2975de94e8549613cyshangCoreGetProtocolInterface ( 89028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 89128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol 89228a00297189c323096aae8e2975de94e8549613cyshang ) 89328a00297189c323096aae8e2975de94e8549613cyshang{ 89428a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 89528a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_ENTRY *ProtEntry; 89628a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 89728a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 89828a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 89928a00297189c323096aae8e2975de94e8549613cyshang 90028a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (UserHandle); 90128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 90228a00297189c323096aae8e2975de94e8549613cyshang return NULL; 90328a00297189c323096aae8e2975de94e8549613cyshang } 904022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 90528a00297189c323096aae8e2975de94e8549613cyshang Handle = (IHANDLE *)UserHandle; 90628a00297189c323096aae8e2975de94e8549613cyshang 90728a00297189c323096aae8e2975de94e8549613cyshang // 90828a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 90928a00297189c323096aae8e2975de94e8549613cyshang // 91028a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 91128a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 91228a00297189c323096aae8e2975de94e8549613cyshang ProtEntry = Prot->Protocol; 91328a00297189c323096aae8e2975de94e8549613cyshang if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) { 91428a00297189c323096aae8e2975de94e8549613cyshang return Prot; 91528a00297189c323096aae8e2975de94e8549613cyshang } 91628a00297189c323096aae8e2975de94e8549613cyshang } 91728a00297189c323096aae8e2975de94e8549613cyshang return NULL; 91828a00297189c323096aae8e2975de94e8549613cyshang} 91928a00297189c323096aae8e2975de94e8549613cyshang 92028a00297189c323096aae8e2975de94e8549613cyshang 921162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 922162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 923162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Queries a handle to determine if it supports a specified protocol. 924162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 925022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle being queried. 926022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The published unique identifier of the protocol. 927022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface Supplies the address where a pointer to the 928022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang corresponding Protocol Interface is returned. 929162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 93011074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_SUCCESS The interface information for the specified protocol was returned. 93111074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_UNSUPPORTED The device does not support the specified protocol. 932284ee2e829ab2453293b7dc4539727ad6c047163niruiyu @retval EFI_INVALID_PARAMETER Handle is NULL.. 93311074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_INVALID_PARAMETER Protocol is NULL. 93411074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_INVALID_PARAMETER Interface is NULL. 935162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 936162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 93728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 93828a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 93928a00297189c323096aae8e2975de94e8549613cyshangCoreHandleProtocol ( 94028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 94128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 94228a00297189c323096aae8e2975de94e8549613cyshang OUT VOID **Interface 94328a00297189c323096aae8e2975de94e8549613cyshang ) 94428a00297189c323096aae8e2975de94e8549613cyshang{ 94528a00297189c323096aae8e2975de94e8549613cyshang return CoreOpenProtocol ( 946022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang UserHandle, 947022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Protocol, 948022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Interface, 949022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang gDxeCoreImageHandle, 950022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NULL, 95128a00297189c323096aae8e2975de94e8549613cyshang EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 95228a00297189c323096aae8e2975de94e8549613cyshang ); 95328a00297189c323096aae8e2975de94e8549613cyshang} 95428a00297189c323096aae8e2975de94e8549613cyshang 95528a00297189c323096aae8e2975de94e8549613cyshang 956162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 957162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 958162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Locates the installed protocol handler for the handle, and 959162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang invokes it to obtain the protocol interface. Usage information 960162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang is registered in the protocol data base. 961162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 962022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to obtain the protocol interface on 963022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The ID of the protocol 964022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Interface The location to return the protocol interface 965022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ImageHandle The handle of the Image that is opening the 966022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol interface specified by Protocol and 967022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Interface. 968022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle The controller handle that is requiring this 969022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang interface. 970022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Attributes The open mode of the protocol interface 971022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang specified by Handle and Protocol. 972022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 973022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Protocol is NULL. 974162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @retval EFI_SUCCESS Get the protocol interface. 975162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 976162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 97728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 97828a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 97928a00297189c323096aae8e2975de94e8549613cyshangCoreOpenProtocol ( 98028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 98128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 98228a00297189c323096aae8e2975de94e8549613cyshang OUT VOID **Interface OPTIONAL, 98328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ImageHandle, 98428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 98528a00297189c323096aae8e2975de94e8549613cyshang IN UINT32 Attributes 98628a00297189c323096aae8e2975de94e8549613cyshang ) 98728a00297189c323096aae8e2975de94e8549613cyshang{ 98828a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 98928a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 99028a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 99128a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 99228a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ByDriver; 99328a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Exclusive; 99428a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Disconnect; 99528a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ExactMatch; 99628a00297189c323096aae8e2975de94e8549613cyshang 99728a00297189c323096aae8e2975de94e8549613cyshang // 99828a00297189c323096aae8e2975de94e8549613cyshang // Check for invalid Protocol 99928a00297189c323096aae8e2975de94e8549613cyshang // 100028a00297189c323096aae8e2975de94e8549613cyshang if (Protocol == NULL) { 100128a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 100228a00297189c323096aae8e2975de94e8549613cyshang } 100328a00297189c323096aae8e2975de94e8549613cyshang 100428a00297189c323096aae8e2975de94e8549613cyshang // 100528a00297189c323096aae8e2975de94e8549613cyshang // Check for invalid Interface 100628a00297189c323096aae8e2975de94e8549613cyshang // 100728a00297189c323096aae8e2975de94e8549613cyshang if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { 100828a00297189c323096aae8e2975de94e8549613cyshang if (Interface == NULL) { 100928a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 101028a00297189c323096aae8e2975de94e8549613cyshang } else { 101128a00297189c323096aae8e2975de94e8549613cyshang *Interface = NULL; 101228a00297189c323096aae8e2975de94e8549613cyshang } 101328a00297189c323096aae8e2975de94e8549613cyshang } 1014022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 101528a00297189c323096aae8e2975de94e8549613cyshang // 101628a00297189c323096aae8e2975de94e8549613cyshang // Check for invalid UserHandle 101728a00297189c323096aae8e2975de94e8549613cyshang // 101828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (UserHandle); 101928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 102028a00297189c323096aae8e2975de94e8549613cyshang return Status; 102128a00297189c323096aae8e2975de94e8549613cyshang } 102228a00297189c323096aae8e2975de94e8549613cyshang 102328a00297189c323096aae8e2975de94e8549613cyshang // 102428a00297189c323096aae8e2975de94e8549613cyshang // Check for invalid Attributes 102528a00297189c323096aae8e2975de94e8549613cyshang // 102628a00297189c323096aae8e2975de94e8549613cyshang switch (Attributes) { 102728a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER : 102828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ImageHandle); 102928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 103028a00297189c323096aae8e2975de94e8549613cyshang return Status; 103128a00297189c323096aae8e2975de94e8549613cyshang } 103228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 103328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 103428a00297189c323096aae8e2975de94e8549613cyshang return Status; 103528a00297189c323096aae8e2975de94e8549613cyshang } 103628a00297189c323096aae8e2975de94e8549613cyshang if (UserHandle == ControllerHandle) { 103728a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 103828a00297189c323096aae8e2975de94e8549613cyshang } 103928a00297189c323096aae8e2975de94e8549613cyshang break; 104028a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_DRIVER : 104128a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE : 104228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ImageHandle); 104328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 104428a00297189c323096aae8e2975de94e8549613cyshang return Status; 104528a00297189c323096aae8e2975de94e8549613cyshang } 104628a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 104728a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 104828a00297189c323096aae8e2975de94e8549613cyshang return Status; 104928a00297189c323096aae8e2975de94e8549613cyshang } 105028a00297189c323096aae8e2975de94e8549613cyshang break; 105128a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_EXCLUSIVE : 105228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ImageHandle); 105328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 105428a00297189c323096aae8e2975de94e8549613cyshang return Status; 105528a00297189c323096aae8e2975de94e8549613cyshang } 105628a00297189c323096aae8e2975de94e8549613cyshang break; 105728a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL : 105828a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_GET_PROTOCOL : 105928a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_TEST_PROTOCOL : 106028a00297189c323096aae8e2975de94e8549613cyshang break; 106128a00297189c323096aae8e2975de94e8549613cyshang default: 106228a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 106328a00297189c323096aae8e2975de94e8549613cyshang } 106428a00297189c323096aae8e2975de94e8549613cyshang 106528a00297189c323096aae8e2975de94e8549613cyshang // 106628a00297189c323096aae8e2975de94e8549613cyshang // Lock the protocol database 106728a00297189c323096aae8e2975de94e8549613cyshang // 106828a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 106928a00297189c323096aae8e2975de94e8549613cyshang 107028a00297189c323096aae8e2975de94e8549613cyshang // 107128a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 107228a00297189c323096aae8e2975de94e8549613cyshang // 107328a00297189c323096aae8e2975de94e8549613cyshang Prot = CoreGetProtocolInterface (UserHandle, Protocol); 107428a00297189c323096aae8e2975de94e8549613cyshang if (Prot == NULL) { 107528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_UNSUPPORTED; 107628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 107728a00297189c323096aae8e2975de94e8549613cyshang } 107828a00297189c323096aae8e2975de94e8549613cyshang 107928a00297189c323096aae8e2975de94e8549613cyshang // 108028a00297189c323096aae8e2975de94e8549613cyshang // This is the protocol interface entry for this protocol 1081022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // 108228a00297189c323096aae8e2975de94e8549613cyshang if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { 108328a00297189c323096aae8e2975de94e8549613cyshang *Interface = Prot->Interface; 108428a00297189c323096aae8e2975de94e8549613cyshang } 108528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 108628a00297189c323096aae8e2975de94e8549613cyshang 108728a00297189c323096aae8e2975de94e8549613cyshang ByDriver = FALSE; 108828a00297189c323096aae8e2975de94e8549613cyshang Exclusive = FALSE; 108928a00297189c323096aae8e2975de94e8549613cyshang for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) { 109028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 1091022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) && 109228a00297189c323096aae8e2975de94e8549613cyshang (OpenData->Attributes == Attributes) && 109328a00297189c323096aae8e2975de94e8549613cyshang (OpenData->ControllerHandle == ControllerHandle)); 10946e53646837da984d2f5dd64467ba7a8943b459aeqhuang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 109528a00297189c323096aae8e2975de94e8549613cyshang ByDriver = TRUE; 109628a00297189c323096aae8e2975de94e8549613cyshang if (ExactMatch) { 109728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ALREADY_STARTED; 109828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 109928a00297189c323096aae8e2975de94e8549613cyshang } 110028a00297189c323096aae8e2975de94e8549613cyshang } 11016e53646837da984d2f5dd64467ba7a8943b459aeqhuang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) { 110228a00297189c323096aae8e2975de94e8549613cyshang Exclusive = TRUE; 110328a00297189c323096aae8e2975de94e8549613cyshang } else if (ExactMatch) { 110428a00297189c323096aae8e2975de94e8549613cyshang OpenData->OpenCount++; 110528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 110628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 110728a00297189c323096aae8e2975de94e8549613cyshang } 110828a00297189c323096aae8e2975de94e8549613cyshang } 110928a00297189c323096aae8e2975de94e8549613cyshang 111028a00297189c323096aae8e2975de94e8549613cyshang // 111128a00297189c323096aae8e2975de94e8549613cyshang // ByDriver TRUE -> A driver is managing (UserHandle, Protocol) 111228a00297189c323096aae8e2975de94e8549613cyshang // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol) 111328a00297189c323096aae8e2975de94e8549613cyshang // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol) 111428a00297189c323096aae8e2975de94e8549613cyshang // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol) 111528a00297189c323096aae8e2975de94e8549613cyshang // 111628a00297189c323096aae8e2975de94e8549613cyshang 111728a00297189c323096aae8e2975de94e8549613cyshang switch (Attributes) { 111828a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_DRIVER : 111928a00297189c323096aae8e2975de94e8549613cyshang if (Exclusive || ByDriver) { 112028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ACCESS_DENIED; 112128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 112228a00297189c323096aae8e2975de94e8549613cyshang } 112328a00297189c323096aae8e2975de94e8549613cyshang break; 112428a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE : 112528a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_EXCLUSIVE : 112628a00297189c323096aae8e2975de94e8549613cyshang if (Exclusive) { 112728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ACCESS_DENIED; 112828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 112928a00297189c323096aae8e2975de94e8549613cyshang } 113028a00297189c323096aae8e2975de94e8549613cyshang if (ByDriver) { 113128a00297189c323096aae8e2975de94e8549613cyshang do { 113228a00297189c323096aae8e2975de94e8549613cyshang Disconnect = FALSE; 113328a00297189c323096aae8e2975de94e8549613cyshang for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) { 113428a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 11356e53646837da984d2f5dd64467ba7a8943b459aeqhuang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 113628a00297189c323096aae8e2975de94e8549613cyshang Disconnect = TRUE; 113728a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 113828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL); 113928a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 114028a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 114128a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_ACCESS_DENIED; 114228a00297189c323096aae8e2975de94e8549613cyshang goto Done; 114328a00297189c323096aae8e2975de94e8549613cyshang } 114428a00297189c323096aae8e2975de94e8549613cyshang } 114528a00297189c323096aae8e2975de94e8549613cyshang } 114628a00297189c323096aae8e2975de94e8549613cyshang } while (Disconnect); 1147022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 114828a00297189c323096aae8e2975de94e8549613cyshang break; 114928a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER : 115028a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL : 115128a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_GET_PROTOCOL : 115228a00297189c323096aae8e2975de94e8549613cyshang case EFI_OPEN_PROTOCOL_TEST_PROTOCOL : 115328a00297189c323096aae8e2975de94e8549613cyshang break; 115428a00297189c323096aae8e2975de94e8549613cyshang } 115528a00297189c323096aae8e2975de94e8549613cyshang 115628a00297189c323096aae8e2975de94e8549613cyshang if (ImageHandle == NULL) { 115728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 115828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 115928a00297189c323096aae8e2975de94e8549613cyshang } 116028a00297189c323096aae8e2975de94e8549613cyshang // 116128a00297189c323096aae8e2975de94e8549613cyshang // Create new entry 116228a00297189c323096aae8e2975de94e8549613cyshang // 11639c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang OpenData = AllocatePool (sizeof(OPEN_PROTOCOL_DATA)); 116428a00297189c323096aae8e2975de94e8549613cyshang if (OpenData == NULL) { 116528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 116628a00297189c323096aae8e2975de94e8549613cyshang } else { 116728a00297189c323096aae8e2975de94e8549613cyshang OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE; 116828a00297189c323096aae8e2975de94e8549613cyshang OpenData->AgentHandle = ImageHandle; 116928a00297189c323096aae8e2975de94e8549613cyshang OpenData->ControllerHandle = ControllerHandle; 117028a00297189c323096aae8e2975de94e8549613cyshang OpenData->Attributes = Attributes; 117128a00297189c323096aae8e2975de94e8549613cyshang OpenData->OpenCount = 1; 117228a00297189c323096aae8e2975de94e8549613cyshang InsertTailList (&Prot->OpenList, &OpenData->Link); 117328a00297189c323096aae8e2975de94e8549613cyshang Prot->OpenListCount++; 117428a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 117528a00297189c323096aae8e2975de94e8549613cyshang } 117628a00297189c323096aae8e2975de94e8549613cyshang 117728a00297189c323096aae8e2975de94e8549613cyshangDone: 117828a00297189c323096aae8e2975de94e8549613cyshang // 117928a00297189c323096aae8e2975de94e8549613cyshang // Done. Release the database lock are return 118028a00297189c323096aae8e2975de94e8549613cyshang // 118128a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 118228a00297189c323096aae8e2975de94e8549613cyshang return Status; 118328a00297189c323096aae8e2975de94e8549613cyshang} 118428a00297189c323096aae8e2975de94e8549613cyshang 118528a00297189c323096aae8e2975de94e8549613cyshang 1186162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1187162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 1188162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Closes a protocol on a handle that was opened using OpenProtocol(). 1189162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1190022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle for the protocol interface that was 1191022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang previously opened with OpenProtocol(), and is 1192022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang now being closed. 1193022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The published unique identifier of the protocol. 1194022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang It is the caller's responsibility to pass in a 1195022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang valid GUID. 1196022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param AgentHandle The handle of the agent that is closing the 1197022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol interface. 1198022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle If the agent that opened a protocol is a driver 1199022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang that follows the EFI Driver Model, then this 1200022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang parameter is the controller handle that required 1201022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the protocol interface. If the agent does not 1202022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang follow the EFI Driver Model, then this parameter 1203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang is optional and may be NULL. 1204022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 1205022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS The protocol instance was closed. 1206022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a 1207022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang valid EFI_HANDLE. 1208022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_NOT_FOUND Can not find the specified protocol or 1209162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang AgentHandle. 1210162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1211162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 121228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 121328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 121428a00297189c323096aae8e2975de94e8549613cyshangCoreCloseProtocol ( 121528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 121628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 121728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE AgentHandle, 1218022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN EFI_HANDLE ControllerHandle 121928a00297189c323096aae8e2975de94e8549613cyshang ) 122028a00297189c323096aae8e2975de94e8549613cyshang{ 122128a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 122228a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *ProtocolInterface; 122328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 122428a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 122528a00297189c323096aae8e2975de94e8549613cyshang 122628a00297189c323096aae8e2975de94e8549613cyshang // 122728a00297189c323096aae8e2975de94e8549613cyshang // Check for invalid parameters 122828a00297189c323096aae8e2975de94e8549613cyshang // 122928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (UserHandle); 123028a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 123128a00297189c323096aae8e2975de94e8549613cyshang return Status; 123228a00297189c323096aae8e2975de94e8549613cyshang } 123328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (AgentHandle); 123428a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 123528a00297189c323096aae8e2975de94e8549613cyshang return Status; 123628a00297189c323096aae8e2975de94e8549613cyshang } 12374008328a99b99770764d1988e9fb2e12ce57e9f3qwang if (ControllerHandle != NULL) { 123828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 123928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 124028a00297189c323096aae8e2975de94e8549613cyshang return Status; 124128a00297189c323096aae8e2975de94e8549613cyshang } 124228a00297189c323096aae8e2975de94e8549613cyshang } 124328a00297189c323096aae8e2975de94e8549613cyshang if (Protocol == NULL) { 124428a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 124528a00297189c323096aae8e2975de94e8549613cyshang } 124628a00297189c323096aae8e2975de94e8549613cyshang 124728a00297189c323096aae8e2975de94e8549613cyshang // 124828a00297189c323096aae8e2975de94e8549613cyshang // Lock the protocol database 124928a00297189c323096aae8e2975de94e8549613cyshang // 125028a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 125128a00297189c323096aae8e2975de94e8549613cyshang 125228a00297189c323096aae8e2975de94e8549613cyshang // 125328a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 125428a00297189c323096aae8e2975de94e8549613cyshang // 125528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 125628a00297189c323096aae8e2975de94e8549613cyshang ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol); 125728a00297189c323096aae8e2975de94e8549613cyshang if (ProtocolInterface == NULL) { 125828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 125928a00297189c323096aae8e2975de94e8549613cyshang } 126028a00297189c323096aae8e2975de94e8549613cyshang 126128a00297189c323096aae8e2975de94e8549613cyshang // 126228a00297189c323096aae8e2975de94e8549613cyshang // Walk the Open data base looking for AgentHandle 126328a00297189c323096aae8e2975de94e8549613cyshang // 126428a00297189c323096aae8e2975de94e8549613cyshang Link = ProtocolInterface->OpenList.ForwardLink; 126528a00297189c323096aae8e2975de94e8549613cyshang while (Link != &ProtocolInterface->OpenList) { 126628a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 126728a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink; 126828a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == AgentHandle) && (OpenData->ControllerHandle == ControllerHandle)) { 1269022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang RemoveEntryList (&OpenData->Link); 127028a00297189c323096aae8e2975de94e8549613cyshang ProtocolInterface->OpenListCount--; 127128a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (OpenData); 127228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 127328a00297189c323096aae8e2975de94e8549613cyshang } 127428a00297189c323096aae8e2975de94e8549613cyshang } 127528a00297189c323096aae8e2975de94e8549613cyshang 127628a00297189c323096aae8e2975de94e8549613cyshangDone: 127728a00297189c323096aae8e2975de94e8549613cyshang // 127828a00297189c323096aae8e2975de94e8549613cyshang // Done. Release the database lock and return. 127928a00297189c323096aae8e2975de94e8549613cyshang // 128028a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 128128a00297189c323096aae8e2975de94e8549613cyshang return Status; 128228a00297189c323096aae8e2975de94e8549613cyshang} 128328a00297189c323096aae8e2975de94e8549613cyshang 128428a00297189c323096aae8e2975de94e8549613cyshang 128528a00297189c323096aae8e2975de94e8549613cyshang 1286162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1287162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 1288162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Return information about Opened protocols in the system 1289162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1290022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle to close the protocol interface on 1291022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Protocol The ID of the protocol 129211074aabe131c7bcc850b1e95f567c205fff64fderic_tian @param EntryBuffer A pointer to a buffer of open protocol information in the 129311074aabe131c7bcc850b1e95f567c205fff64fderic_tian form of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. 1294162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @param EntryCount Number of EntryBuffer entries 1295162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 129611074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_SUCCESS The open protocol information was returned in EntryBuffer, 129711074aabe131c7bcc850b1e95f567c205fff64fderic_tian and the number of entries was returned EntryCount. 129811074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_NOT_FOUND Handle does not support the protocol specified by Protocol. 129911074aabe131c7bcc850b1e95f567c205fff64fderic_tian @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate EntryBuffer. 130011074aabe131c7bcc850b1e95f567c205fff64fderic_tian 1301162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 130228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 130328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 130428a00297189c323096aae8e2975de94e8549613cyshangCoreOpenProtocolInformation ( 130528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 130628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_GUID *Protocol, 130728a00297189c323096aae8e2975de94e8549613cyshang OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, 130828a00297189c323096aae8e2975de94e8549613cyshang OUT UINTN *EntryCount 130928a00297189c323096aae8e2975de94e8549613cyshang ) 131028a00297189c323096aae8e2975de94e8549613cyshang{ 131128a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 131228a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *ProtocolInterface; 131328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 131428a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 131528a00297189c323096aae8e2975de94e8549613cyshang EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Buffer; 131628a00297189c323096aae8e2975de94e8549613cyshang UINTN Count; 131728a00297189c323096aae8e2975de94e8549613cyshang UINTN Size; 131828a00297189c323096aae8e2975de94e8549613cyshang 131928a00297189c323096aae8e2975de94e8549613cyshang *EntryBuffer = NULL; 132028a00297189c323096aae8e2975de94e8549613cyshang *EntryCount = 0; 132128a00297189c323096aae8e2975de94e8549613cyshang 132228a00297189c323096aae8e2975de94e8549613cyshang // 132328a00297189c323096aae8e2975de94e8549613cyshang // Lock the protocol database 132428a00297189c323096aae8e2975de94e8549613cyshang // 132528a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 132628a00297189c323096aae8e2975de94e8549613cyshang 132728a00297189c323096aae8e2975de94e8549613cyshang // 132828a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 132928a00297189c323096aae8e2975de94e8549613cyshang // 133028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 133128a00297189c323096aae8e2975de94e8549613cyshang ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol); 133228a00297189c323096aae8e2975de94e8549613cyshang if (ProtocolInterface == NULL) { 133328a00297189c323096aae8e2975de94e8549613cyshang goto Done; 133428a00297189c323096aae8e2975de94e8549613cyshang } 133528a00297189c323096aae8e2975de94e8549613cyshang 133628a00297189c323096aae8e2975de94e8549613cyshang // 133728a00297189c323096aae8e2975de94e8549613cyshang // Count the number of Open Entries 133828a00297189c323096aae8e2975de94e8549613cyshang // 1339022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; 134028a00297189c323096aae8e2975de94e8549613cyshang (Link != &ProtocolInterface->OpenList) ; 134128a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink ) { 134228a00297189c323096aae8e2975de94e8549613cyshang Count++; 1343022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 134428a00297189c323096aae8e2975de94e8549613cyshang 134528a00297189c323096aae8e2975de94e8549613cyshang ASSERT (Count == ProtocolInterface->OpenListCount); 134628a00297189c323096aae8e2975de94e8549613cyshang 134728a00297189c323096aae8e2975de94e8549613cyshang if (Count == 0) { 134828a00297189c323096aae8e2975de94e8549613cyshang Size = sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY); 134928a00297189c323096aae8e2975de94e8549613cyshang } else { 135028a00297189c323096aae8e2975de94e8549613cyshang Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY); 135128a00297189c323096aae8e2975de94e8549613cyshang } 135228a00297189c323096aae8e2975de94e8549613cyshang 13539c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang Buffer = AllocatePool (Size); 135428a00297189c323096aae8e2975de94e8549613cyshang if (Buffer == NULL) { 135528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 135628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 135728a00297189c323096aae8e2975de94e8549613cyshang } 135828a00297189c323096aae8e2975de94e8549613cyshang 135928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 1360022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; 136128a00297189c323096aae8e2975de94e8549613cyshang (Link != &ProtocolInterface->OpenList); 136228a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink, Count++ ) { 136328a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 136428a00297189c323096aae8e2975de94e8549613cyshang 136528a00297189c323096aae8e2975de94e8549613cyshang Buffer[Count].AgentHandle = OpenData->AgentHandle; 136628a00297189c323096aae8e2975de94e8549613cyshang Buffer[Count].ControllerHandle = OpenData->ControllerHandle; 136728a00297189c323096aae8e2975de94e8549613cyshang Buffer[Count].Attributes = OpenData->Attributes; 136828a00297189c323096aae8e2975de94e8549613cyshang Buffer[Count].OpenCount = OpenData->OpenCount; 1369022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 137028a00297189c323096aae8e2975de94e8549613cyshang 137128a00297189c323096aae8e2975de94e8549613cyshang *EntryBuffer = Buffer; 137228a00297189c323096aae8e2975de94e8549613cyshang *EntryCount = Count; 1373022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 137428a00297189c323096aae8e2975de94e8549613cyshangDone: 137528a00297189c323096aae8e2975de94e8549613cyshang // 13761439777e96797cbf92e9748bd9b8ed1316099e3dqwang // Done. Release the database lock. 137728a00297189c323096aae8e2975de94e8549613cyshang // 137828a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 137928a00297189c323096aae8e2975de94e8549613cyshang return Status; 138028a00297189c323096aae8e2975de94e8549613cyshang} 138128a00297189c323096aae8e2975de94e8549613cyshang 138228a00297189c323096aae8e2975de94e8549613cyshang 138328a00297189c323096aae8e2975de94e8549613cyshang 1384162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1385162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 1386162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated 1387162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang from pool. 1388162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1389022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param UserHandle The handle from which to retrieve the list of 1390022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol interface GUIDs. 1391022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ProtocolBuffer A pointer to the list of protocol interface GUID 1392022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang pointers that are installed on Handle. 1393022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ProtocolBufferCount A pointer to the number of GUID pointers present 1394022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang in ProtocolBuffer. 1395022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 1396022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS The list of protocol interface GUIDs installed 1397022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang on Handle was returned in ProtocolBuffer. The 1398022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang number of protocol interface GUIDs was returned 1399022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang in ProtocolBufferCount. 1400022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Handle is NULL. 1401022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. 1402022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. 1403022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. 1404022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the 1405162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang results. 1406162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1407162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 140828a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 140928a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 141028a00297189c323096aae8e2975de94e8549613cyshangCoreProtocolsPerHandle ( 141128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE UserHandle, 141228a00297189c323096aae8e2975de94e8549613cyshang OUT EFI_GUID ***ProtocolBuffer, 141328a00297189c323096aae8e2975de94e8549613cyshang OUT UINTN *ProtocolBufferCount 141428a00297189c323096aae8e2975de94e8549613cyshang ) 141528a00297189c323096aae8e2975de94e8549613cyshang{ 141628a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 141728a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 141828a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 141928a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 142028a00297189c323096aae8e2975de94e8549613cyshang UINTN ProtocolCount; 142128a00297189c323096aae8e2975de94e8549613cyshang EFI_GUID **Buffer; 142228a00297189c323096aae8e2975de94e8549613cyshang 142328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (UserHandle); 142428a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 142528a00297189c323096aae8e2975de94e8549613cyshang return Status; 142628a00297189c323096aae8e2975de94e8549613cyshang } 142728a00297189c323096aae8e2975de94e8549613cyshang 142828a00297189c323096aae8e2975de94e8549613cyshang Handle = (IHANDLE *)UserHandle; 142928a00297189c323096aae8e2975de94e8549613cyshang 143028a00297189c323096aae8e2975de94e8549613cyshang if (ProtocolBuffer == NULL) { 143128a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 143228a00297189c323096aae8e2975de94e8549613cyshang } 143328a00297189c323096aae8e2975de94e8549613cyshang 143428a00297189c323096aae8e2975de94e8549613cyshang if (ProtocolBufferCount == NULL) { 143528a00297189c323096aae8e2975de94e8549613cyshang return EFI_INVALID_PARAMETER; 143628a00297189c323096aae8e2975de94e8549613cyshang } 143728a00297189c323096aae8e2975de94e8549613cyshang 143828a00297189c323096aae8e2975de94e8549613cyshang *ProtocolBufferCount = 0; 143928a00297189c323096aae8e2975de94e8549613cyshang 144028a00297189c323096aae8e2975de94e8549613cyshang ProtocolCount = 0; 144128a00297189c323096aae8e2975de94e8549613cyshang 144228a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 1443022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 144428a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 144528a00297189c323096aae8e2975de94e8549613cyshang ProtocolCount++; 144628a00297189c323096aae8e2975de94e8549613cyshang } 144728a00297189c323096aae8e2975de94e8549613cyshang 144828a00297189c323096aae8e2975de94e8549613cyshang // 144928a00297189c323096aae8e2975de94e8549613cyshang // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE 145028a00297189c323096aae8e2975de94e8549613cyshang // 145128a00297189c323096aae8e2975de94e8549613cyshang if (ProtocolCount == 0) { 145228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 145328a00297189c323096aae8e2975de94e8549613cyshang goto Done; 145428a00297189c323096aae8e2975de94e8549613cyshang } 145528a00297189c323096aae8e2975de94e8549613cyshang 14569c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang Buffer = AllocatePool (sizeof (EFI_GUID *) * ProtocolCount); 145728a00297189c323096aae8e2975de94e8549613cyshang if (Buffer == NULL) { 145828a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 145928a00297189c323096aae8e2975de94e8549613cyshang goto Done; 146028a00297189c323096aae8e2975de94e8549613cyshang } 146128a00297189c323096aae8e2975de94e8549613cyshang 146228a00297189c323096aae8e2975de94e8549613cyshang *ProtocolBuffer = Buffer; 146328a00297189c323096aae8e2975de94e8549613cyshang *ProtocolBufferCount = ProtocolCount; 146428a00297189c323096aae8e2975de94e8549613cyshang 146528a00297189c323096aae8e2975de94e8549613cyshang for ( Link = Handle->Protocols.ForwardLink, ProtocolCount = 0; 1466022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang Link != &Handle->Protocols; 146728a00297189c323096aae8e2975de94e8549613cyshang Link = Link->ForwardLink, ProtocolCount++) { 146828a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 146928a00297189c323096aae8e2975de94e8549613cyshang Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID); 147028a00297189c323096aae8e2975de94e8549613cyshang } 147128a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 147228a00297189c323096aae8e2975de94e8549613cyshang 147328a00297189c323096aae8e2975de94e8549613cyshangDone: 147428a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 147528a00297189c323096aae8e2975de94e8549613cyshang return Status; 147628a00297189c323096aae8e2975de94e8549613cyshang} 147728a00297189c323096aae8e2975de94e8549613cyshang 147828a00297189c323096aae8e2975de94e8549613cyshang 147928a00297189c323096aae8e2975de94e8549613cyshang 1480162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 148128a00297189c323096aae8e2975de94e8549613cyshang return handle database key. 148228a00297189c323096aae8e2975de94e8549613cyshang 148328a00297189c323096aae8e2975de94e8549613cyshang 1484162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Handle database key. 1485162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 1486162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 1487162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangUINT64 1488162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreGetHandleDatabaseKey ( 1489162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang VOID 1490162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 149128a00297189c323096aae8e2975de94e8549613cyshang{ 149228a00297189c323096aae8e2975de94e8549613cyshang return gHandleDatabaseKey; 149328a00297189c323096aae8e2975de94e8549613cyshang} 149428a00297189c323096aae8e2975de94e8549613cyshang 149528a00297189c323096aae8e2975de94e8549613cyshang 149628a00297189c323096aae8e2975de94e8549613cyshang 1497162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 149828a00297189c323096aae8e2975de94e8549613cyshang Go connect any handles that were created or modified while a image executed. 149928a00297189c323096aae8e2975de94e8549613cyshang 1500022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Key The Key to show that the handle has been 1501162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang created/modified 150228a00297189c323096aae8e2975de94e8549613cyshang 1503162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 1504162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID 1505162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreConnectHandlesByKey ( 1506162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang UINT64 Key 1507162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ) 150828a00297189c323096aae8e2975de94e8549613cyshang{ 150928a00297189c323096aae8e2975de94e8549613cyshang UINTN Count; 151028a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 151128a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *HandleBuffer; 151228a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 151328a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 151428a00297189c323096aae8e2975de94e8549613cyshang 151528a00297189c323096aae8e2975de94e8549613cyshang // 151628a00297189c323096aae8e2975de94e8549613cyshang // Lock the protocol database 151728a00297189c323096aae8e2975de94e8549613cyshang // 151828a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 151928a00297189c323096aae8e2975de94e8549613cyshang 152028a00297189c323096aae8e2975de94e8549613cyshang for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) { 152128a00297189c323096aae8e2975de94e8549613cyshang Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); 152228a00297189c323096aae8e2975de94e8549613cyshang if (Handle->Key > Key) { 152328a00297189c323096aae8e2975de94e8549613cyshang Count++; 152428a00297189c323096aae8e2975de94e8549613cyshang } 152528a00297189c323096aae8e2975de94e8549613cyshang } 152628a00297189c323096aae8e2975de94e8549613cyshang 15279c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang HandleBuffer = AllocatePool (Count * sizeof (EFI_HANDLE)); 152828a00297189c323096aae8e2975de94e8549613cyshang if (HandleBuffer == NULL) { 152928a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 153028a00297189c323096aae8e2975de94e8549613cyshang return; 153128a00297189c323096aae8e2975de94e8549613cyshang } 1532022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 153328a00297189c323096aae8e2975de94e8549613cyshang for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) { 153428a00297189c323096aae8e2975de94e8549613cyshang Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); 153528a00297189c323096aae8e2975de94e8549613cyshang if (Handle->Key > Key) { 153628a00297189c323096aae8e2975de94e8549613cyshang HandleBuffer[Count++] = Handle; 153728a00297189c323096aae8e2975de94e8549613cyshang } 153828a00297189c323096aae8e2975de94e8549613cyshang } 153928a00297189c323096aae8e2975de94e8549613cyshang 154028a00297189c323096aae8e2975de94e8549613cyshang // 154128a00297189c323096aae8e2975de94e8549613cyshang // Unlock the protocol database 154228a00297189c323096aae8e2975de94e8549613cyshang // 154328a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 154428a00297189c323096aae8e2975de94e8549613cyshang 154528a00297189c323096aae8e2975de94e8549613cyshang // 154628a00297189c323096aae8e2975de94e8549613cyshang // Connect all handles whose Key value is greater than Key 154728a00297189c323096aae8e2975de94e8549613cyshang // 154828a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < Count; Index++) { 154928a00297189c323096aae8e2975de94e8549613cyshang CoreConnectController (HandleBuffer[Index], NULL, NULL, TRUE); 155028a00297189c323096aae8e2975de94e8549613cyshang } 1551022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 155228a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool(HandleBuffer); 155328a00297189c323096aae8e2975de94e8549613cyshang} 1554