|
@@ -1,1650 +0,0 @@
|
|
|
-/** @file
|
|
|
- Implementation of protocol related services in the UEFI Boot Services table for use in unit tests.
|
|
|
-
|
|
|
-Copyright (c) Microsoft Corporation
|
|
|
-SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
-
|
|
|
-**/
|
|
|
-
|
|
|
-#include "UefiBootServicesTableLibUnitTestProtocol.h"
|
|
|
-
|
|
|
-STATIC LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
|
|
|
-STATIC LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
|
|
|
-STATIC UINT64 gHandleDatabaseKey = 0;
|
|
|
-STATIC UINTN mEfiLocateHandleRequest = 0;
|
|
|
-
|
|
|
-//
|
|
|
-// Helper Functions
|
|
|
-//
|
|
|
-
|
|
|
-/**
|
|
|
- Check whether a handle is a valid EFI_HANDLE
|
|
|
-
|
|
|
- @param UserHandle The handle to check
|
|
|
-
|
|
|
- @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE.
|
|
|
- @retval EFI_SUCCESS The handle is valid EFI_HANDLE.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-UnitTestValidateHandle (
|
|
|
- IN EFI_HANDLE UserHandle
|
|
|
- )
|
|
|
-{
|
|
|
- IHANDLE *Handle;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- if (UserHandle == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
|
|
|
- Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
|
|
|
- if (Handle == (IHANDLE *)UserHandle) {
|
|
|
- return EFI_SUCCESS;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Finds the protocol entry for the requested protocol.
|
|
|
-
|
|
|
- @param Protocol The ID of the protocol
|
|
|
- @param Create Create a new entry if not found
|
|
|
-
|
|
|
- @return Protocol entry
|
|
|
-
|
|
|
-**/
|
|
|
-PROTOCOL_ENTRY *
|
|
|
-UnitTestFindProtocolEntry (
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN BOOLEAN Create
|
|
|
- )
|
|
|
-{
|
|
|
- LIST_ENTRY *Link;
|
|
|
- PROTOCOL_ENTRY *Item;
|
|
|
- PROTOCOL_ENTRY *ProtEntry;
|
|
|
-
|
|
|
- //
|
|
|
- // Search the database for the matching GUID
|
|
|
- //
|
|
|
-
|
|
|
- ProtEntry = NULL;
|
|
|
- for (Link = mProtocolDatabase.ForwardLink;
|
|
|
- Link != &mProtocolDatabase;
|
|
|
- Link = Link->ForwardLink)
|
|
|
- {
|
|
|
- Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
|
|
|
- if (CompareGuid (&Item->ProtocolID, Protocol)) {
|
|
|
- //
|
|
|
- // This is the protocol entry
|
|
|
- //
|
|
|
-
|
|
|
- ProtEntry = Item;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // If the protocol entry was not found and Create is TRUE, then
|
|
|
- // allocate a new entry
|
|
|
- //
|
|
|
- if ((ProtEntry == NULL) && Create) {
|
|
|
- ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));
|
|
|
-
|
|
|
- if (ProtEntry != NULL) {
|
|
|
- //
|
|
|
- // Initialize new protocol entry structure
|
|
|
- //
|
|
|
- ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
|
|
|
- CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol);
|
|
|
- InitializeListHead (&ProtEntry->Protocols);
|
|
|
- InitializeListHead (&ProtEntry->Notify);
|
|
|
-
|
|
|
- //
|
|
|
- // Add it to protocol database
|
|
|
- //
|
|
|
- InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return ProtEntry;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Finds the protocol instance for the requested handle and protocol.
|
|
|
- Note: This function doesn't do parameters checking, it's caller's responsibility
|
|
|
- to pass in valid parameters.
|
|
|
-
|
|
|
- @param Handle The handle to search the protocol on
|
|
|
- @param Protocol GUID of the protocol
|
|
|
- @param Interface The interface for the protocol being searched
|
|
|
-
|
|
|
- @return Protocol instance (NULL: Not found)
|
|
|
-
|
|
|
-**/
|
|
|
-PROTOCOL_INTERFACE *
|
|
|
-UnitTestFindProtocolInterface (
|
|
|
- IN IHANDLE *Handle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN VOID *Interface
|
|
|
- )
|
|
|
-{
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- PROTOCOL_ENTRY *ProtEntry;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- Prot = NULL;
|
|
|
-
|
|
|
- //
|
|
|
- // Lookup the protocol entry for this protocol ID
|
|
|
- //
|
|
|
-
|
|
|
- ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
|
|
|
- if (ProtEntry != NULL) {
|
|
|
- //
|
|
|
- // Look at each protocol interface for any matches
|
|
|
- //
|
|
|
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
|
|
- //
|
|
|
- // If this protocol interface matches, remove it
|
|
|
- //
|
|
|
- Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
|
|
- if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- Prot = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Prot;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Signal event for every protocol in protocol entry.
|
|
|
-
|
|
|
- @param ProtEntry Protocol entry
|
|
|
-
|
|
|
-**/
|
|
|
-VOID
|
|
|
-UnitTestNotifyProtocolEntry (
|
|
|
- IN PROTOCOL_ENTRY *ProtEntry
|
|
|
- )
|
|
|
-{
|
|
|
- PROTOCOL_NOTIFY *ProtNotify;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {
|
|
|
- ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
|
|
|
- UnitTestSignalEvent (ProtNotify->Event);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Routine to get the next Handle, when you are searching for all handles.
|
|
|
-
|
|
|
- @param Position Information about which Handle to seach for.
|
|
|
- @param Interface Return the interface structure for the matching
|
|
|
- protocol.
|
|
|
-
|
|
|
- @return An pointer to IHANDLE if the next Position is not the end of the list.
|
|
|
- Otherwise,NULL is returned.
|
|
|
-
|
|
|
-**/
|
|
|
-IHANDLE *
|
|
|
-UnitTestGetNextLocateAllHandles (
|
|
|
- IN OUT LOCATE_POSITION *Position,
|
|
|
- OUT VOID **Interface
|
|
|
- )
|
|
|
-{
|
|
|
- IHANDLE *Handle;
|
|
|
-
|
|
|
- //
|
|
|
- // Next handle
|
|
|
- //
|
|
|
- Position->Position = Position->Position->ForwardLink;
|
|
|
-
|
|
|
- //
|
|
|
- // If not at the end of the list, get the handle
|
|
|
- //
|
|
|
- Handle = NULL;
|
|
|
- *Interface = NULL;
|
|
|
- if (Position->Position != &gHandleList) {
|
|
|
- Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
|
|
|
- }
|
|
|
-
|
|
|
- return Handle;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Routine to get the next Handle, when you are searching for register protocol
|
|
|
- notifies.
|
|
|
-
|
|
|
- @param Position Information about which Handle to seach for.
|
|
|
- @param Interface Return the interface structure for the matching
|
|
|
- protocol.
|
|
|
-
|
|
|
- @return An pointer to IHANDLE if the next Position is not the end of the list.
|
|
|
- Otherwise,NULL is returned.
|
|
|
-
|
|
|
-**/
|
|
|
-IHANDLE *
|
|
|
-UnitTestGetNextLocateByRegisterNotify (
|
|
|
- IN OUT LOCATE_POSITION *Position,
|
|
|
- OUT VOID **Interface
|
|
|
- )
|
|
|
-{
|
|
|
- IHANDLE *Handle;
|
|
|
- PROTOCOL_NOTIFY *ProtNotify;
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- Handle = NULL;
|
|
|
- *Interface = NULL;
|
|
|
- ProtNotify = Position->SearchKey;
|
|
|
-
|
|
|
- //
|
|
|
- // If this is the first request, get the next handle
|
|
|
- //
|
|
|
- if (ProtNotify != NULL) {
|
|
|
- ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
|
|
|
- Position->SearchKey = NULL;
|
|
|
-
|
|
|
- //
|
|
|
- // If not at the end of the list, get the next handle
|
|
|
- //
|
|
|
- Link = ProtNotify->Position->ForwardLink;
|
|
|
- if (Link != &ProtNotify->Protocol->Protocols) {
|
|
|
- Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
|
|
|
- Handle = Prot->Handle;
|
|
|
- *Interface = Prot->Interface;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Handle;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Routine to get the next Handle, when you are searching for a given protocol.
|
|
|
-
|
|
|
- @param Position Information about which Handle to seach for.
|
|
|
- @param Interface Return the interface structure for the matching
|
|
|
- protocol.
|
|
|
-
|
|
|
- @return An pointer to IHANDLE if the next Position is not the end of the list.
|
|
|
- Otherwise,NULL is returned.
|
|
|
-
|
|
|
-**/
|
|
|
-IHANDLE *
|
|
|
-UnitTestGetNextLocateByProtocol (
|
|
|
- IN OUT LOCATE_POSITION *Position,
|
|
|
- OUT VOID **Interface
|
|
|
- )
|
|
|
-{
|
|
|
- IHANDLE *Handle;
|
|
|
- LIST_ENTRY *Link;
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
-
|
|
|
- Handle = NULL;
|
|
|
- *Interface = NULL;
|
|
|
- for ( ; ;) {
|
|
|
- //
|
|
|
- // Next entry
|
|
|
- //
|
|
|
- Link = Position->Position->ForwardLink;
|
|
|
- Position->Position = Link;
|
|
|
-
|
|
|
- //
|
|
|
- // If not at the end, return the handle
|
|
|
- //
|
|
|
- if (Link == &Position->ProtEntry->Protocols) {
|
|
|
- Handle = NULL;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Get the handle
|
|
|
- //
|
|
|
- Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
|
|
|
- Handle = Prot->Handle;
|
|
|
- *Interface = Prot->Interface;
|
|
|
-
|
|
|
- //
|
|
|
- // If this handle has not been returned this request, then
|
|
|
- // return it now
|
|
|
- //
|
|
|
- if (Handle->LocateRequest != mEfiLocateHandleRequest) {
|
|
|
- Handle->LocateRequest = mEfiLocateHandleRequest;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Handle;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Attempts to disconnect all drivers that are using the protocol interface being queried.
|
|
|
- If failed, reconnect all drivers disconnected.
|
|
|
- Note: This function doesn't do parameters checking, it's caller's responsibility
|
|
|
- to pass in valid parameters.
|
|
|
-
|
|
|
- @param UserHandle The handle on which the protocol is installed
|
|
|
- @param Prot The protocol to disconnect drivers from
|
|
|
-
|
|
|
- @retval EFI_SUCCESS Drivers using the protocol interface are all
|
|
|
- disconnected
|
|
|
- @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-UnitTestDisconnectControllersUsingProtocolInterface (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN PROTOCOL_INTERFACE *Prot
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- BOOLEAN ItemFound;
|
|
|
- LIST_ENTRY *Link;
|
|
|
- OPEN_PROTOCOL_DATA *OpenData;
|
|
|
-
|
|
|
- Status = EFI_SUCCESS;
|
|
|
-
|
|
|
- //
|
|
|
- // Attempt to disconnect all drivers from this protocol interface
|
|
|
- //
|
|
|
- do {
|
|
|
- ItemFound = FALSE;
|
|
|
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
|
|
|
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
|
|
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
|
|
- Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
|
|
|
- if (!EFI_ERROR (Status)) {
|
|
|
- ItemFound = TRUE;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- } while (ItemFound);
|
|
|
-
|
|
|
- if (!EFI_ERROR (Status)) {
|
|
|
- //
|
|
|
- // Attempt to remove BY_HANDLE_PROTOCOL and GET_PROTOCOL and TEST_PROTOCOL Open List items
|
|
|
- //
|
|
|
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {
|
|
|
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
|
|
- if ((OpenData->Attributes &
|
|
|
- (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0)
|
|
|
- {
|
|
|
- Link = RemoveEntryList (&OpenData->Link);
|
|
|
- Prot->OpenListCount--;
|
|
|
- FreePool (OpenData);
|
|
|
- } else {
|
|
|
- Link = Link->ForwardLink;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
|
|
|
- //
|
|
|
- if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
|
|
|
- UnitTestConnectController (UserHandle, NULL, NULL, TRUE);
|
|
|
- Status = EFI_ACCESS_DENIED;
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Removes Protocol from the protocol list (but not the handle list).
|
|
|
-
|
|
|
- @param Handle The handle to remove protocol on.
|
|
|
- @param Protocol GUID of the protocol to be moved
|
|
|
- @param Interface The interface of the protocol
|
|
|
-
|
|
|
- @return Protocol Entry
|
|
|
-
|
|
|
-**/
|
|
|
-PROTOCOL_INTERFACE *
|
|
|
-UnitTestRemoveInterfaceFromProtocol (
|
|
|
- IN IHANDLE *Handle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN VOID *Interface
|
|
|
- )
|
|
|
-{
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- PROTOCOL_NOTIFY *ProtNotify;
|
|
|
- PROTOCOL_ENTRY *ProtEntry;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- Prot = UnitTestFindProtocolInterface (Handle, Protocol, Interface);
|
|
|
- if (Prot != NULL) {
|
|
|
- ProtEntry = Prot->Protocol;
|
|
|
-
|
|
|
- //
|
|
|
- // If there's a protocol notify location pointing to this entry, back it up one
|
|
|
- //
|
|
|
- for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {
|
|
|
- ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
|
|
|
-
|
|
|
- if (ProtNotify->Position == &Prot->ByProtocol) {
|
|
|
- ProtNotify->Position = Prot->ByProtocol.BackLink;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Remove the protocol interface entry
|
|
|
- //
|
|
|
- RemoveEntryList (&Prot->ByProtocol);
|
|
|
- }
|
|
|
-
|
|
|
- return Prot;
|
|
|
-}
|
|
|
-
|
|
|
-//
|
|
|
-// Boot Services Function Implementation
|
|
|
-//
|
|
|
-
|
|
|
-/**
|
|
|
- Locate a certain GUID protocol interface in a Handle's protocols.
|
|
|
-
|
|
|
- @param UserHandle The handle to obtain the protocol interface on
|
|
|
- @param Protocol The GUID of the protocol
|
|
|
-
|
|
|
- @return The requested protocol interface for the handle
|
|
|
-
|
|
|
-**/
|
|
|
-PROTOCOL_INTERFACE *
|
|
|
-UnitTestGetProtocolInterface (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- PROTOCOL_ENTRY *ProtEntry;
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- IHANDLE *Handle;
|
|
|
- LIST_ENTRY *Link;
|
|
|
-
|
|
|
- Status = UnitTestValidateHandle (UserHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- Handle = (IHANDLE *)UserHandle;
|
|
|
-
|
|
|
- //
|
|
|
- // Look at each protocol interface for a match
|
|
|
- //
|
|
|
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
|
|
- Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
|
|
- ProtEntry = Prot->Protocol;
|
|
|
- if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {
|
|
|
- return Prot;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Installs a protocol interface into the boot services environment.
|
|
|
-
|
|
|
- @param UserHandle The handle to install the protocol handler on,
|
|
|
- or NULL if a new handle is to be allocated
|
|
|
- @param Protocol The protocol to add to the handle
|
|
|
- @param InterfaceType Indicates whether Interface is supplied in
|
|
|
- native form.
|
|
|
- @param Interface The interface for the protocol being added
|
|
|
- @param Notify indicates whether notify the notification list
|
|
|
- for this protocol
|
|
|
-
|
|
|
- @retval EFI_INVALID_PARAMETER Invalid parameter
|
|
|
- @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
|
|
|
- @retval EFI_SUCCESS Protocol interface successfully installed
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-UnitTestInstallProtocolInterfaceNotify (
|
|
|
- IN OUT EFI_HANDLE *UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN EFI_INTERFACE_TYPE InterfaceType,
|
|
|
- IN VOID *Interface,
|
|
|
- IN BOOLEAN Notify
|
|
|
- )
|
|
|
-{
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- PROTOCOL_ENTRY *ProtEntry;
|
|
|
- IHANDLE *Handle;
|
|
|
- EFI_STATUS Status;
|
|
|
- VOID *ExistingInterface;
|
|
|
-
|
|
|
- //
|
|
|
- // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
|
|
|
- // Also added check for invalid UserHandle and Protocol pointers.
|
|
|
- //
|
|
|
- if ((UserHandle == NULL) || (Protocol == NULL)) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- if (InterfaceType != EFI_NATIVE_INTERFACE) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Print debug message
|
|
|
- //
|
|
|
- UT_LOG_INFO ("InstallProtocolInterface: %g %p\n", Protocol, Interface);
|
|
|
-
|
|
|
- Status = EFI_OUT_OF_RESOURCES;
|
|
|
- Prot = NULL;
|
|
|
- Handle = NULL;
|
|
|
-
|
|
|
- if (*UserHandle != NULL) {
|
|
|
- Status = UnitTestHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
|
|
|
- if (!EFI_ERROR (Status)) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Lookup the Protocol Entry for the requested protocol
|
|
|
- //
|
|
|
- ProtEntry = UnitTestFindProtocolEntry (Protocol, TRUE);
|
|
|
- if (ProtEntry == NULL) {
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Allocate a new protocol interface structure
|
|
|
- //
|
|
|
- Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));
|
|
|
- if (Prot == NULL) {
|
|
|
- Status = EFI_OUT_OF_RESOURCES;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // If caller didn't supply a handle, allocate a new one
|
|
|
- //
|
|
|
- Handle = (IHANDLE *)*UserHandle;
|
|
|
- if (Handle == NULL) {
|
|
|
- Handle = AllocateZeroPool (sizeof (IHANDLE));
|
|
|
- if (Handle == NULL) {
|
|
|
- Status = EFI_OUT_OF_RESOURCES;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Initialize new handler structure
|
|
|
- //
|
|
|
- Handle->Signature = EFI_HANDLE_SIGNATURE;
|
|
|
- InitializeListHead (&Handle->Protocols);
|
|
|
-
|
|
|
- //
|
|
|
- // Initialize the Key to show that the handle has been created/modified
|
|
|
- //
|
|
|
- gHandleDatabaseKey++;
|
|
|
- Handle->Key = gHandleDatabaseKey;
|
|
|
-
|
|
|
- //
|
|
|
- // Add this handle to the list global list of all handles
|
|
|
- // in the system
|
|
|
- //
|
|
|
- InsertTailList (&gHandleList, &Handle->AllHandles);
|
|
|
- } else {
|
|
|
- Status = UnitTestValidateHandle (Handle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
|
|
|
- goto Done;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Each interface that is added must be unique
|
|
|
- //
|
|
|
- ASSERT (UnitTestFindProtocolInterface (Handle, Protocol, Interface) == NULL);
|
|
|
-
|
|
|
- //
|
|
|
- // Initialize the protocol interface structure
|
|
|
- //
|
|
|
- Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
|
|
|
- Prot->Handle = Handle;
|
|
|
- Prot->Protocol = ProtEntry;
|
|
|
- Prot->Interface = Interface;
|
|
|
-
|
|
|
- //
|
|
|
- // Initialize OpenProtocol Data base
|
|
|
- //
|
|
|
- InitializeListHead (&Prot->OpenList);
|
|
|
- Prot->OpenListCount = 0;
|
|
|
-
|
|
|
- //
|
|
|
- // Add this protocol interface to the head of the supported
|
|
|
- // protocol list for this handle
|
|
|
- //
|
|
|
- InsertHeadList (&Handle->Protocols, &Prot->Link);
|
|
|
-
|
|
|
- //
|
|
|
- // Add this protocol interface to the tail of the
|
|
|
- // protocol entry
|
|
|
- //
|
|
|
- InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
|
|
|
-
|
|
|
- //
|
|
|
- // Notify the notification list for this protocol
|
|
|
- //
|
|
|
- if (Notify) {
|
|
|
- UnitTestNotifyProtocolEntry (ProtEntry);
|
|
|
- }
|
|
|
-
|
|
|
- Status = EFI_SUCCESS;
|
|
|
-
|
|
|
-Done:
|
|
|
- if (!EFI_ERROR (Status)) {
|
|
|
- //
|
|
|
- // Return the new handle back to the caller
|
|
|
- //
|
|
|
- *UserHandle = Handle;
|
|
|
- } else {
|
|
|
- //
|
|
|
- // There was an error, clean up
|
|
|
- //
|
|
|
- if (Prot != NULL) {
|
|
|
- UnitTestFreePool (Prot);
|
|
|
- }
|
|
|
-
|
|
|
- DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which
|
|
|
- Calls the private one which contains a BOOLEAN parameter for notifications
|
|
|
-
|
|
|
- @param UserHandle The handle to install the protocol handler on,
|
|
|
- or NULL if a new handle is to be allocated
|
|
|
- @param Protocol The protocol to add to the handle
|
|
|
- @param InterfaceType Indicates whether Interface is supplied in
|
|
|
- native form.
|
|
|
- @param Interface The interface for the protocol being added
|
|
|
-
|
|
|
- @return Status code
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestInstallProtocolInterface (
|
|
|
- IN OUT EFI_HANDLE *UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN EFI_INTERFACE_TYPE InterfaceType,
|
|
|
- IN VOID *Interface
|
|
|
- )
|
|
|
-{
|
|
|
- return UnitTestInstallProtocolInterfaceNotify (
|
|
|
- UserHandle,
|
|
|
- Protocol,
|
|
|
- InterfaceType,
|
|
|
- Interface,
|
|
|
- TRUE
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
|
|
|
-
|
|
|
- @param UserHandle Handle on which the interface is to be
|
|
|
- reinstalled
|
|
|
- @param Protocol The numeric ID of the interface
|
|
|
- @param OldInterface A pointer to the old interface
|
|
|
- @param NewInterface A pointer to the new interface
|
|
|
-
|
|
|
- @retval EFI_SUCCESS The protocol interface was installed
|
|
|
- @retval EFI_NOT_FOUND The OldInterface on the handle was not found
|
|
|
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestReinstallProtocolInterface (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN VOID *OldInterface,
|
|
|
- IN VOID *NewInterface
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Uninstalls all instances of a protocol:interfacer from a handle.
|
|
|
- If the last protocol interface is remove from the handle, the
|
|
|
- handle is freed.
|
|
|
-
|
|
|
- @param UserHandle The handle to remove the protocol handler from
|
|
|
- @param Protocol The protocol, of protocol:interface, to remove
|
|
|
- @param Interface The interface, of protocol:interface, to remove
|
|
|
-
|
|
|
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
|
|
|
- @retval EFI_SUCCESS Protocol interface successfully uninstalled.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestUninstallProtocolInterface (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN VOID *Interface
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- IHANDLE *Handle;
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
-
|
|
|
- //
|
|
|
- // Check that Protocol is valid
|
|
|
- //
|
|
|
- if (Protocol == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Check that UserHandle is a valid handle
|
|
|
- //
|
|
|
- Status = UnitTestValidateHandle (UserHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
|
|
|
- //
|
|
|
- Prot = UnitTestFindProtocolInterface (UserHandle, Protocol, Interface);
|
|
|
- if (Prot == NULL) {
|
|
|
- Status = EFI_NOT_FOUND;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
|
|
|
- //
|
|
|
- Status = UnitTestDisconnectControllersUsingProtocolInterface (
|
|
|
- UserHandle,
|
|
|
- Prot
|
|
|
- );
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- //
|
|
|
- // One or more drivers refused to release, so return the error
|
|
|
- //
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Remove the protocol interface from the protocol
|
|
|
- //
|
|
|
- Status = EFI_NOT_FOUND;
|
|
|
- Handle = (IHANDLE *)UserHandle;
|
|
|
- Prot = UnitTestRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
|
|
|
-
|
|
|
- if (Prot != NULL) {
|
|
|
- //
|
|
|
- // Update the Key to show that the handle has been created/modified
|
|
|
- //
|
|
|
- gHandleDatabaseKey++;
|
|
|
- Handle->Key = gHandleDatabaseKey;
|
|
|
-
|
|
|
- //
|
|
|
- // Remove the protocol interface from the handle
|
|
|
- //
|
|
|
- RemoveEntryList (&Prot->Link);
|
|
|
-
|
|
|
- //
|
|
|
- // Free the memory
|
|
|
- //
|
|
|
- Prot->Signature = 0;
|
|
|
- FreePool (Prot);
|
|
|
- Status = EFI_SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // If there are no more handlers for the handle, free the handle
|
|
|
- //
|
|
|
- if (IsListEmpty (&Handle->Protocols)) {
|
|
|
- Handle->Signature = 0;
|
|
|
- RemoveEntryList (&Handle->AllHandles);
|
|
|
- FreePool (Handle);
|
|
|
- }
|
|
|
-
|
|
|
-Done:
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Queries a handle to determine if it supports a specified protocol.
|
|
|
-
|
|
|
- @param UserHandle The handle being queried.
|
|
|
- @param Protocol The published unique identifier of the protocol.
|
|
|
- @param Interface Supplies the address where a pointer to the
|
|
|
- corresponding Protocol Interface is returned.
|
|
|
-
|
|
|
- @return The requested protocol interface for the handle
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestHandleProtocol (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- OUT VOID **Interface
|
|
|
- )
|
|
|
-{
|
|
|
- return UnitTestOpenProtocol (
|
|
|
- UserHandle,
|
|
|
- Protocol,
|
|
|
- Interface,
|
|
|
- gImageHandle,
|
|
|
- NULL,
|
|
|
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
|
|
|
- );
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Add a new protocol notification record for the request protocol.
|
|
|
-
|
|
|
- @param Protocol The requested protocol to add the notify
|
|
|
- registration
|
|
|
- @param Event The event to signal
|
|
|
- @param Registration Returns the registration record
|
|
|
-
|
|
|
- @retval EFI_INVALID_PARAMETER Invalid parameter
|
|
|
- @retval EFI_SUCCESS Successfully returned the registration record
|
|
|
- that has been added
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestRegisterProtocolNotify (
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN EFI_EVENT Event,
|
|
|
- OUT VOID **Registration
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Locates the requested handle(s) and returns them in Buffer.
|
|
|
-
|
|
|
- @param SearchType The type of search to perform to locate the
|
|
|
- handles
|
|
|
- @param Protocol The protocol to search for
|
|
|
- @param SearchKey Dependant on SearchType
|
|
|
- @param BufferSize On input the size of Buffer. On output the
|
|
|
- size of data returned.
|
|
|
- @param Buffer The buffer to return the results in
|
|
|
-
|
|
|
- @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is
|
|
|
- returned in BufferSize.
|
|
|
- @retval EFI_INVALID_PARAMETER Invalid parameter
|
|
|
- @retval EFI_SUCCESS Successfully found the requested handle(s) and
|
|
|
- returns them in Buffer.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestLocateHandle (
|
|
|
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
|
|
- IN EFI_GUID *Protocol OPTIONAL,
|
|
|
- IN VOID *SearchKey OPTIONAL,
|
|
|
- IN OUT UINTN *BufferSize,
|
|
|
- OUT EFI_HANDLE *Buffer
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- LOCATE_POSITION Position;
|
|
|
- PROTOCOL_NOTIFY *ProtNotify;
|
|
|
- UNIT_TEST_GET_NEXT GetNext;
|
|
|
- UINTN ResultSize;
|
|
|
- IHANDLE *Handle;
|
|
|
- IHANDLE **ResultBuffer;
|
|
|
- VOID *Interface;
|
|
|
-
|
|
|
- if (BufferSize == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- if ((*BufferSize > 0) && (Buffer == NULL)) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- GetNext = NULL;
|
|
|
-
|
|
|
- //
|
|
|
- // Set initial position
|
|
|
- //
|
|
|
- Position.Protocol = Protocol;
|
|
|
- Position.SearchKey = SearchKey;
|
|
|
- Position.Position = &gHandleList;
|
|
|
-
|
|
|
- ResultSize = 0;
|
|
|
- ResultBuffer = (IHANDLE **)Buffer;
|
|
|
- Status = EFI_SUCCESS;
|
|
|
-
|
|
|
- //
|
|
|
- // Get the search function based on type
|
|
|
- //
|
|
|
- switch (SearchType) {
|
|
|
- case AllHandles:
|
|
|
- GetNext = UnitTestGetNextLocateAllHandles;
|
|
|
- break;
|
|
|
-
|
|
|
- case ByRegisterNotify:
|
|
|
- //
|
|
|
- // Must have SearchKey for locate ByRegisterNotify
|
|
|
- //
|
|
|
- if (SearchKey == NULL) {
|
|
|
- Status = EFI_INVALID_PARAMETER;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- GetNext = UnitTestGetNextLocateByRegisterNotify;
|
|
|
- break;
|
|
|
-
|
|
|
- case ByProtocol:
|
|
|
- GetNext = UnitTestGetNextLocateByProtocol;
|
|
|
- if (Protocol == NULL) {
|
|
|
- Status = EFI_INVALID_PARAMETER;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Look up the protocol entry and set the head pointer
|
|
|
- //
|
|
|
- Position.ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
|
|
|
- if (Position.ProtEntry == NULL) {
|
|
|
- Status = EFI_NOT_FOUND;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- Position.Position = &Position.ProtEntry->Protocols;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- Status = EFI_INVALID_PARAMETER;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- ASSERT (GetNext != NULL);
|
|
|
- //
|
|
|
- // Enumerate out the matching handles
|
|
|
- //
|
|
|
- mEfiLocateHandleRequest += 1;
|
|
|
- for ( ; ;) {
|
|
|
- //
|
|
|
- // Get the next handle. If no more handles, stop
|
|
|
- //
|
|
|
- Handle = GetNext (&Position, &Interface);
|
|
|
- if (NULL == Handle) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Increase the resulting buffer size, and if this handle
|
|
|
- // fits return it
|
|
|
- //
|
|
|
- ResultSize += sizeof (Handle);
|
|
|
- if (ResultSize <= *BufferSize) {
|
|
|
- *ResultBuffer = Handle;
|
|
|
- ResultBuffer += 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // If the result is a zero length buffer, then there were no
|
|
|
- // matching handles
|
|
|
- //
|
|
|
- if (ResultSize == 0) {
|
|
|
- Status = EFI_NOT_FOUND;
|
|
|
- } else {
|
|
|
- //
|
|
|
- // Return the resulting buffer size. If it's larger than what
|
|
|
- // was passed, then set the error code
|
|
|
- //
|
|
|
- if (ResultSize > *BufferSize) {
|
|
|
- Status = EFI_BUFFER_TOO_SMALL;
|
|
|
- }
|
|
|
-
|
|
|
- *BufferSize = ResultSize;
|
|
|
-
|
|
|
- if ((SearchType == ByRegisterNotify) && !EFI_ERROR (Status)) {
|
|
|
- //
|
|
|
- // If this is a search by register notify and a handle was
|
|
|
- // returned, update the register notification position
|
|
|
- //
|
|
|
- ASSERT (SearchKey != NULL);
|
|
|
- ProtNotify = SearchKey;
|
|
|
- ProtNotify->Position = ProtNotify->Position->ForwardLink;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Locates the handle to a device on the device path that best matches the specified protocol.
|
|
|
-
|
|
|
- @param Protocol The protocol to search for.
|
|
|
- @param DevicePath On input, a pointer to a pointer to the device
|
|
|
- path. On output, the device path pointer is
|
|
|
- modified to point to the remaining part of the
|
|
|
- devicepath.
|
|
|
- @param Device A pointer to the returned device handle.
|
|
|
-
|
|
|
- @retval EFI_SUCCESS The resulting handle was returned.
|
|
|
- @retval EFI_NOT_FOUND No handles matched the search.
|
|
|
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestLocateDevicePath (
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
|
|
|
- OUT EFI_HANDLE *Device
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Boot Service called to add, modify, or remove a system configuration table from
|
|
|
- the EFI System Table.
|
|
|
-
|
|
|
- @param Guid Pointer to the GUID for the entry to add, update, or
|
|
|
- remove
|
|
|
- @param Table Pointer to the configuration table for the entry to add,
|
|
|
- update, or remove, may be NULL.
|
|
|
-
|
|
|
- @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
|
|
|
- @return EFI_INVALID_PARAMETER Input GUID not valid.
|
|
|
- @return EFI_NOT_FOUND Attempted to delete non-existant entry
|
|
|
- @return EFI_OUT_OF_RESOURCES Not enough memory available
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestInstallConfigurationTable (
|
|
|
- IN EFI_GUID *Guid,
|
|
|
- IN VOID *Table
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Locates the installed protocol handler for the handle, and
|
|
|
- invokes it to obtain the protocol interface. Usage information
|
|
|
- is registered in the protocol data base.
|
|
|
-
|
|
|
- @param UserHandle The handle to obtain the protocol interface on
|
|
|
- @param Protocol The ID of the protocol
|
|
|
- @param Interface The location to return the protocol interface
|
|
|
- @param ImageHandle The handle of the Image that is opening the
|
|
|
- protocol interface specified by Protocol and
|
|
|
- Interface.
|
|
|
- @param ControllerHandle The controller handle that is requiring this
|
|
|
- interface.
|
|
|
- @param Attributes The open mode of the protocol interface
|
|
|
- specified by Handle and Protocol.
|
|
|
-
|
|
|
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
|
|
|
- @retval EFI_SUCCESS Get the protocol interface.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestOpenProtocol (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- OUT VOID **Interface OPTIONAL,
|
|
|
- IN EFI_HANDLE ImageHandle,
|
|
|
- IN EFI_HANDLE ControllerHandle,
|
|
|
- IN UINT32 Attributes
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- PROTOCOL_INTERFACE *Prot;
|
|
|
- LIST_ENTRY *Link;
|
|
|
- OPEN_PROTOCOL_DATA *OpenData;
|
|
|
- BOOLEAN ByDriver;
|
|
|
- BOOLEAN Exclusive;
|
|
|
- BOOLEAN Disconnect;
|
|
|
- BOOLEAN ExactMatch;
|
|
|
-
|
|
|
- //
|
|
|
- // Check for invalid Protocol
|
|
|
- //
|
|
|
- if (Protocol == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Check for invalid Interface
|
|
|
- //
|
|
|
- if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Check for invalid UserHandle
|
|
|
- //
|
|
|
- Status = UnitTestValidateHandle (UserHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Check for invalid Attributes
|
|
|
- //
|
|
|
- switch (Attributes) {
|
|
|
- case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
|
|
|
- Status = UnitTestValidateHandle (ImageHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- Status = UnitTestValidateHandle (ControllerHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- if (UserHandle == ControllerHandle) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- case EFI_OPEN_PROTOCOL_BY_DRIVER:
|
|
|
- case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
|
|
|
- Status = UnitTestValidateHandle (ImageHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- Status = UnitTestValidateHandle (ControllerHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- case EFI_OPEN_PROTOCOL_EXCLUSIVE:
|
|
|
- Status = UnitTestValidateHandle (ImageHandle);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
|
|
|
- case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
|
|
|
- case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
|
|
|
- break;
|
|
|
- default:
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Look at each protocol interface for a match
|
|
|
- //
|
|
|
- Prot = UnitTestGetProtocolInterface (UserHandle, Protocol);
|
|
|
- if (Prot == NULL) {
|
|
|
- Status = EFI_UNSUPPORTED;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- Status = EFI_SUCCESS;
|
|
|
-
|
|
|
- ByDriver = FALSE;
|
|
|
- Exclusive = FALSE;
|
|
|
- for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
|
|
|
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
|
|
- ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&
|
|
|
- (OpenData->Attributes == Attributes) &&
|
|
|
- (OpenData->ControllerHandle == ControllerHandle));
|
|
|
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
|
|
- ByDriver = TRUE;
|
|
|
- if (ExactMatch) {
|
|
|
- Status = EFI_ALREADY_STARTED;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {
|
|
|
- Exclusive = TRUE;
|
|
|
- } else if (ExactMatch) {
|
|
|
- OpenData->OpenCount++;
|
|
|
- Status = EFI_SUCCESS;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)
|
|
|
- // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)
|
|
|
- // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)
|
|
|
- // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
|
|
|
- //
|
|
|
-
|
|
|
- switch (Attributes) {
|
|
|
- case EFI_OPEN_PROTOCOL_BY_DRIVER:
|
|
|
- if (Exclusive || ByDriver) {
|
|
|
- Status = EFI_ACCESS_DENIED;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
|
|
|
- case EFI_OPEN_PROTOCOL_EXCLUSIVE:
|
|
|
- if (Exclusive) {
|
|
|
- Status = EFI_ACCESS_DENIED;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- if (ByDriver) {
|
|
|
- do {
|
|
|
- Disconnect = FALSE;
|
|
|
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
|
|
|
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
|
|
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
|
|
- Disconnect = TRUE;
|
|
|
- Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- Status = EFI_ACCESS_DENIED;
|
|
|
- goto Done;
|
|
|
- } else {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- } while (Disconnect);
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
|
|
|
- case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
|
|
|
- case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
|
|
|
- case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (ImageHandle == NULL) {
|
|
|
- Status = EFI_SUCCESS;
|
|
|
- goto Done;
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- // Create new entry
|
|
|
- //
|
|
|
- OpenData = AllocatePool (sizeof (OPEN_PROTOCOL_DATA));
|
|
|
- if (OpenData == NULL) {
|
|
|
- Status = EFI_OUT_OF_RESOURCES;
|
|
|
- } else {
|
|
|
- OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE;
|
|
|
- OpenData->AgentHandle = ImageHandle;
|
|
|
- OpenData->ControllerHandle = ControllerHandle;
|
|
|
- OpenData->Attributes = Attributes;
|
|
|
- OpenData->OpenCount = 1;
|
|
|
- InsertTailList (&Prot->OpenList, &OpenData->Link);
|
|
|
- Prot->OpenListCount++;
|
|
|
- Status = EFI_SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
-Done:
|
|
|
-
|
|
|
- if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
|
|
|
- //
|
|
|
- // Keep Interface unmodified in case of any Error
|
|
|
- // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.
|
|
|
- //
|
|
|
- if (!EFI_ERROR (Status) || (Status == EFI_ALREADY_STARTED)) {
|
|
|
- //
|
|
|
- // According to above logic, if 'Prot' is NULL, then the 'Status' must be
|
|
|
- // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'
|
|
|
- // must be not NULL.
|
|
|
- //
|
|
|
- // The ASSERT here is for addressing a false positive NULL pointer
|
|
|
- // dereference issue raised from static analysis.
|
|
|
- //
|
|
|
- ASSERT (Prot != NULL);
|
|
|
- //
|
|
|
- // EFI_ALREADY_STARTED is not an error for bus driver.
|
|
|
- // Return the corresponding protocol interface.
|
|
|
- //
|
|
|
- *Interface = Prot->Interface;
|
|
|
- } else if (Status == EFI_UNSUPPORTED) {
|
|
|
- //
|
|
|
- // Return NULL Interface if Unsupported Protocol.
|
|
|
- //
|
|
|
- *Interface = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Closes a protocol on a handle that was opened using OpenProtocol().
|
|
|
-
|
|
|
- @param UserHandle The handle for the protocol interface that was
|
|
|
- previously opened with OpenProtocol(), and is
|
|
|
- now being closed.
|
|
|
- @param Protocol The published unique identifier of the protocol.
|
|
|
- It is the caller's responsibility to pass in a
|
|
|
- valid GUID.
|
|
|
- @param AgentHandle The handle of the agent that is closing the
|
|
|
- protocol interface.
|
|
|
- @param ControllerHandle If the agent that opened a protocol is a driver
|
|
|
- that follows the EFI Driver Model, then this
|
|
|
- parameter is the controller handle that required
|
|
|
- the protocol interface. If the agent does not
|
|
|
- follow the EFI Driver Model, then this parameter
|
|
|
- is optional and may be NULL.
|
|
|
-
|
|
|
- @retval EFI_SUCCESS The protocol instance was closed.
|
|
|
- @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a
|
|
|
- valid EFI_HANDLE.
|
|
|
- @retval EFI_NOT_FOUND Can not find the specified protocol or
|
|
|
- AgentHandle.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestCloseProtocol (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN EFI_HANDLE AgentHandle,
|
|
|
- IN EFI_HANDLE ControllerHandle
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Return information about Opened protocols in the system
|
|
|
-
|
|
|
- @param UserHandle The handle to close the protocol interface on
|
|
|
- @param Protocol The ID of the protocol
|
|
|
- @param EntryBuffer A pointer to a buffer of open protocol
|
|
|
- information in the form of
|
|
|
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
|
|
|
- @param EntryCount Number of EntryBuffer entries
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestOpenProtocolInformation (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
|
|
|
- OUT UINTN *EntryCount
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
|
|
|
- from pool.
|
|
|
-
|
|
|
- @param UserHandle The handle from which to retrieve the list of
|
|
|
- protocol interface GUIDs.
|
|
|
- @param ProtocolBuffer A pointer to the list of protocol interface GUID
|
|
|
- pointers that are installed on Handle.
|
|
|
- @param ProtocolBufferCount A pointer to the number of GUID pointers present
|
|
|
- in ProtocolBuffer.
|
|
|
-
|
|
|
- @retval EFI_SUCCESS The list of protocol interface GUIDs installed
|
|
|
- on Handle was returned in ProtocolBuffer. The
|
|
|
- number of protocol interface GUIDs was returned
|
|
|
- in ProtocolBufferCount.
|
|
|
- @retval EFI_INVALID_PARAMETER Handle is NULL.
|
|
|
- @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
|
|
|
- @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
|
|
|
- @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
|
|
|
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
|
|
|
- results.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestProtocolsPerHandle (
|
|
|
- IN EFI_HANDLE UserHandle,
|
|
|
- OUT EFI_GUID ***ProtocolBuffer,
|
|
|
- OUT UINTN *ProtocolBufferCount
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Function returns an array of handles that support the requested protocol
|
|
|
- in a buffer allocated from pool. This is a version of UnitTestLocateHandle()
|
|
|
- that allocates a buffer for the caller.
|
|
|
-
|
|
|
- @param SearchType Specifies which handle(s) are to be returned.
|
|
|
- @param Protocol Provides the protocol to search by. This
|
|
|
- parameter is only valid for SearchType
|
|
|
- ByProtocol.
|
|
|
- @param SearchKey Supplies the search key depending on the
|
|
|
- SearchType.
|
|
|
- @param NumberHandles The number of handles returned in Buffer.
|
|
|
- @param Buffer A pointer to the buffer to return the requested
|
|
|
- array of handles that support Protocol.
|
|
|
-
|
|
|
- @retval EFI_SUCCESS The result array of handles was returned.
|
|
|
- @retval EFI_NOT_FOUND No handles match the search.
|
|
|
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
|
|
|
- matching results.
|
|
|
- @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestLocateHandleBuffer (
|
|
|
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
|
|
- IN EFI_GUID *Protocol OPTIONAL,
|
|
|
- IN VOID *SearchKey OPTIONAL,
|
|
|
- IN OUT UINTN *NumberHandles,
|
|
|
- OUT EFI_HANDLE **Buffer
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- UINTN BufferSize;
|
|
|
-
|
|
|
- if (NumberHandles == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- if (Buffer == NULL) {
|
|
|
- return EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- BufferSize = 0;
|
|
|
- *NumberHandles = 0;
|
|
|
- *Buffer = NULL;
|
|
|
- Status = UnitTestLocateHandle (
|
|
|
- SearchType,
|
|
|
- Protocol,
|
|
|
- SearchKey,
|
|
|
- &BufferSize,
|
|
|
- *Buffer
|
|
|
- );
|
|
|
- //
|
|
|
- // LocateHandleBuffer() returns incorrect status code if SearchType is
|
|
|
- // invalid.
|
|
|
- //
|
|
|
- // Add code to correctly handle expected errors from UnitTestLocateHandle().
|
|
|
- //
|
|
|
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
|
|
|
- if (Status != EFI_INVALID_PARAMETER) {
|
|
|
- Status = EFI_NOT_FOUND;
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
- }
|
|
|
-
|
|
|
- *Buffer = AllocatePool (BufferSize);
|
|
|
- if (*Buffer == NULL) {
|
|
|
- return EFI_OUT_OF_RESOURCES;
|
|
|
- }
|
|
|
-
|
|
|
- Status = UnitTestLocateHandle (
|
|
|
- SearchType,
|
|
|
- Protocol,
|
|
|
- SearchKey,
|
|
|
- &BufferSize,
|
|
|
- *Buffer
|
|
|
- );
|
|
|
-
|
|
|
- *NumberHandles = BufferSize / sizeof (EFI_HANDLE);
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- *NumberHandles = 0;
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Return the first Protocol Interface that matches the Protocol GUID. If
|
|
|
- Registration is passed in, return a Protocol Instance that was just add
|
|
|
- to the system. If Registration is NULL return the first Protocol Interface
|
|
|
- you find.
|
|
|
-
|
|
|
- @param Protocol The protocol to search for
|
|
|
- @param Registration Optional Registration Key returned from
|
|
|
- RegisterProtocolNotify()
|
|
|
- @param Interface Return the Protocol interface (instance).
|
|
|
-
|
|
|
- @retval EFI_SUCCESS If a valid Interface is returned
|
|
|
- @retval EFI_INVALID_PARAMETER Invalid parameter
|
|
|
- @retval EFI_NOT_FOUND Protocol interface not found
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestLocateProtocol (
|
|
|
- IN EFI_GUID *Protocol,
|
|
|
- IN VOID *Registration OPTIONAL,
|
|
|
- OUT VOID **Interface
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Installs a list of protocol interface into the boot services environment.
|
|
|
- This function calls InstallProtocolInterface() in a loop. If any error
|
|
|
- occurs all the protocols added by this function are removed. This is
|
|
|
- basically a lib function to save space.
|
|
|
-
|
|
|
- @param Handle The handle to install the protocol handlers on,
|
|
|
- or NULL if a new handle is to be allocated
|
|
|
- @param ... EFI_GUID followed by protocol instance. A NULL
|
|
|
- terminates the list. The pairs are the
|
|
|
- arguments to InstallProtocolInterface(). All the
|
|
|
- protocols are added to Handle.
|
|
|
-
|
|
|
- @retval EFI_SUCCESS All the protocol interface was installed.
|
|
|
- @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.
|
|
|
- @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in
|
|
|
- the handle database.
|
|
|
- @retval EFI_INVALID_PARAMETER Handle is NULL.
|
|
|
- @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestInstallMultipleProtocolInterfaces (
|
|
|
- IN OUT EFI_HANDLE *Handle,
|
|
|
- ...
|
|
|
- )
|
|
|
-{
|
|
|
- return EFI_NOT_AVAILABLE_YET;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- Uninstalls a list of protocol interface in the boot services environment.
|
|
|
- This function calls UninstallProtocolInterface() in a loop. This is
|
|
|
- basically a lib function to save space.
|
|
|
-
|
|
|
- @param Handle The handle to uninstall the protocol
|
|
|
- @param ... EFI_GUID followed by protocol instance. A NULL
|
|
|
- terminates the list. The pairs are the
|
|
|
- arguments to UninstallProtocolInterface(). All
|
|
|
- the protocols are added to Handle.
|
|
|
-
|
|
|
- @return Status code
|
|
|
-
|
|
|
-**/
|
|
|
-EFI_STATUS
|
|
|
-EFIAPI
|
|
|
-UnitTestUninstallMultipleProtocolInterfaces (
|
|
|
- IN EFI_HANDLE Handle,
|
|
|
- ...
|
|
|
- )
|
|
|
-{
|
|
|
- EFI_STATUS Status;
|
|
|
- VA_LIST Args;
|
|
|
- EFI_GUID *Protocol;
|
|
|
- VOID *Interface;
|
|
|
- UINTN Index;
|
|
|
-
|
|
|
- VA_START (Args, Handle);
|
|
|
- for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
|
|
|
- //
|
|
|
- // If protocol is NULL, then it's the end of the list
|
|
|
- //
|
|
|
- Protocol = VA_ARG (Args, EFI_GUID *);
|
|
|
- if (Protocol == NULL) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- Interface = VA_ARG (Args, VOID *);
|
|
|
-
|
|
|
- //
|
|
|
- // Uninstall it
|
|
|
- //
|
|
|
- Status = UnitTestUninstallProtocolInterface (Handle, Protocol, Interface);
|
|
|
- }
|
|
|
-
|
|
|
- VA_END (Args);
|
|
|
-
|
|
|
- //
|
|
|
- // If there was an error, add all the interfaces that were
|
|
|
- // uninstalled without any errors
|
|
|
- //
|
|
|
- if (EFI_ERROR (Status)) {
|
|
|
- //
|
|
|
- // Reset the va_arg back to the first argument.
|
|
|
- //
|
|
|
- VA_START (Args, Handle);
|
|
|
- for ( ; Index > 1; Index--) {
|
|
|
- Protocol = VA_ARG (Args, EFI_GUID *);
|
|
|
- Interface = VA_ARG (Args, VOID *);
|
|
|
- UnitTestInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
|
|
|
- }
|
|
|
-
|
|
|
- VA_END (Args);
|
|
|
- Status = EFI_INVALID_PARAMETER;
|
|
|
- }
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|