--- /dev/null
+/** @file\r
+ This library supports a Boot Services table library implementation that allows code dependent\r
+ upon UefiBootServicesTableLib to operate in an isolated execution environment such as within\r
+ the context of a host-based unit test framework.\r
+\r
+ The unit test should initialize the Boot Services database with any required elements\r
+ (e.g. protocols, events, handles, etc.) prior to the services being invoked by code under test.\r
+\r
+ It is strongly recommended to clean any global databases (e.g. protocol, event, handles, etc.) after\r
+ every unit test so the tests execute in a predictable manner from a clean state.\r
+\r
+ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+EFI_HANDLE gImageHandle = NULL;\r
+EFI_SYSTEM_TABLE *gST = NULL;\r
+\r
+STATIC EFI_BOOT_SERVICES mBootServices = {\r
+ {\r
+ EFI_BOOT_SERVICES_SIGNATURE, // Signature\r
+ EFI_BOOT_SERVICES_REVISION, // Revision\r
+ sizeof (EFI_BOOT_SERVICES), // HeaderSize\r
+ 0, // CRC32\r
+ 0 // Reserved\r
+ },\r
+ (EFI_RAISE_TPL)UnitTestRaiseTpl, // RaiseTPL\r
+ (EFI_RESTORE_TPL)UnitTestRestoreTpl, // RestoreTPL\r
+ (EFI_ALLOCATE_PAGES)UnitTestAllocatePages, // AllocatePages\r
+ (EFI_FREE_PAGES)UnitTestFreePages, // FreePages\r
+ (EFI_GET_MEMORY_MAP)UnitTestGetMemoryMap, // GetMemoryMap\r
+ (EFI_ALLOCATE_POOL)UnitTestAllocatePool, // AllocatePool\r
+ (EFI_FREE_POOL)UnitTestFreePool, // FreePool\r
+ (EFI_CREATE_EVENT)UnitTestCreateEvent, // CreateEvent\r
+ (EFI_SET_TIMER)UnitTestSetTimer, // SetTimer\r
+ (EFI_WAIT_FOR_EVENT)UnitTestWaitForEvent, // WaitForEvent\r
+ (EFI_SIGNAL_EVENT)UnitTestSignalEvent, // SignalEvent\r
+ (EFI_CLOSE_EVENT)UnitTestCloseEvent, // CloseEvent\r
+ (EFI_CHECK_EVENT)UnitTestCheckEvent, // CheckEvent\r
+ (EFI_INSTALL_PROTOCOL_INTERFACE)UnitTestInstallProtocolInterface, // InstallProtocolInterface\r
+ (EFI_REINSTALL_PROTOCOL_INTERFACE)UnitTestReinstallProtocolInterface, // ReinstallProtocolInterface\r
+ (EFI_UNINSTALL_PROTOCOL_INTERFACE)UnitTestUninstallProtocolInterface, // UninstallProtocolInterface\r
+ (EFI_HANDLE_PROTOCOL)UnitTestHandleProtocol, // HandleProtocol\r
+ (VOID *)NULL, // Reserved\r
+ (EFI_REGISTER_PROTOCOL_NOTIFY)UnitTestRegisterProtocolNotify, // RegisterProtocolNotify\r
+ (EFI_LOCATE_HANDLE)UnitTestLocateHandle, // LocateHandle\r
+ (EFI_LOCATE_DEVICE_PATH)UnitTestLocateDevicePath, // LocateDevicePath\r
+ (EFI_INSTALL_CONFIGURATION_TABLE)UnitTestInstallConfigurationTable, // InstallConfigurationTable\r
+ (EFI_IMAGE_LOAD)UnitTestLoadImage, // LoadImage\r
+ (EFI_IMAGE_START)UnitTestStartImage, // StartImage\r
+ (EFI_EXIT)UnitTestExit, // Exit\r
+ (EFI_IMAGE_UNLOAD)UnitTestUnloadImage, // UnloadImage\r
+ (EFI_EXIT_BOOT_SERVICES)UnitTestExitBootServices, // ExitBootServices\r
+ (EFI_GET_NEXT_MONOTONIC_COUNT)UnitTestGetNextMonotonicCount, // GetNextMonotonicCount\r
+ (EFI_STALL)UnitTestStall, // Stall\r
+ (EFI_SET_WATCHDOG_TIMER)UnitTestSetWatchdogTimer, // SetWatchdogTimer\r
+ (EFI_CONNECT_CONTROLLER)UnitTestConnectController, // ConnectController\r
+ (EFI_DISCONNECT_CONTROLLER)UnitTestDisconnectController, // DisconnectController\r
+ (EFI_OPEN_PROTOCOL)UnitTestOpenProtocol, // OpenProtocol\r
+ (EFI_CLOSE_PROTOCOL)UnitTestCloseProtocol, // CloseProtocol\r
+ (EFI_OPEN_PROTOCOL_INFORMATION)UnitTestOpenProtocolInformation, // OpenProtocolInformation\r
+ (EFI_PROTOCOLS_PER_HANDLE)UnitTestProtocolsPerHandle, // ProtocolsPerHandle\r
+ (EFI_LOCATE_HANDLE_BUFFER)UnitTestLocateHandleBuffer, // LocateHandleBuffer\r
+ (EFI_LOCATE_PROTOCOL)UnitTestLocateProtocol, // LocateProtocol\r
+ (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces\r
+ (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces\r
+ (EFI_CALCULATE_CRC32)UnitTestCalculateCrc32, // CalculateCrc32\r
+ (EFI_COPY_MEM)CopyMem, // CopyMem\r
+ (EFI_SET_MEM)SetMem, // SetMem\r
+ (EFI_CREATE_EVENT_EX)UnitTestCreateEventEx // CreateEventEx\r
+};\r
+\r
+EFI_BOOT_SERVICES *gBS = &mBootServices;\r
+\r
+/**\r
+ The constructor function caches the pointer of Boot Services Table.\r
+\r
+ The constructor function caches the pointer of Boot Services Table through System Table.\r
+ It will ASSERT() if the pointer of System Table is NULL.\r
+ It will ASSERT() if the pointer of Boot Services Table is NULL.\r
+ It will always return EFI_SUCCESS.\r
+\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUefiBootServicesTableLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ //\r
+ // Cache the Image Handle\r
+ //\r
+ gImageHandle = ImageHandle;\r
+ ASSERT (gImageHandle != NULL);\r
+\r
+ //\r
+ // Cache pointer to the EFI System Table\r
+ //\r
+\r
+ // Note: The system table is not implemented\r
+ gST = NULL;\r
+\r
+ //\r
+ // Cache pointer to the EFI Boot Services Table\r
+ //\r
+ gBS = SystemTable->BootServices;\r
+ ASSERT (gBS != NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.\r
+\r
+ This file includes common header files, defines internal structure and functions used by\r
+ the library implementation.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_\r
+#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Pi/PiMultiPhase.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UnitTestLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+/**\r
+ Raise the task priority level to the new level.\r
+ High level is implemented by disabling processor interrupts.\r
+\r
+ @param NewTpl New task priority level\r
+\r
+ @return The previous task priority level\r
+\r
+**/\r
+EFI_TPL\r
+EFIAPI\r
+UnitTestRaiseTpl (\r
+ IN EFI_TPL NewTpl\r
+ );\r
+\r
+/**\r
+ Lowers the task priority to the previous value. If the new\r
+ priority unmasks events at a higher priority, they are dispatched.\r
+\r
+ @param NewTpl New, lower, task priority\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestRestoreTpl (\r
+ IN EFI_TPL NewTpl\r
+ );\r
+\r
+/**\r
+ Allocates pages from the memory map.\r
+\r
+ @param Type The type of allocation to perform\r
+ @param MemoryType The type of memory to turn the allocated pages\r
+ into\r
+ @param NumberOfPages The number of pages to allocate\r
+ @param Memory A pointer to receive the base allocated memory\r
+ address\r
+\r
+ @return Status. On success, Memory is filled in with the base address allocated\r
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in\r
+ spec.\r
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.\r
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.\r
+ @retval EFI_SUCCESS Pages successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestAllocatePages (\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN NumberOfPages,\r
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory\r
+ );\r
+\r
+/**\r
+ Frees previous allocated pages.\r
+\r
+ @param Memory Base address of memory being freed\r
+ @param NumberOfPages The number of pages to free\r
+\r
+ @retval EFI_NOT_FOUND Could not find the entry that covers the range\r
+ @retval EFI_INVALID_PARAMETER Address not aligned\r
+ @return EFI_SUCCESS -Pages successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestFreePages (\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NumberOfPages\r
+ );\r
+\r
+/**\r
+ This function returns a copy of the current memory map. The map is an array of\r
+ memory descriptors, each of which describes a contiguous block of memory.\r
+\r
+ @param MemoryMapSize A pointer to the size, in bytes, of the\r
+ MemoryMap buffer. On input, this is the size of\r
+ the buffer allocated by the caller. On output,\r
+ it is the size of the buffer returned by the\r
+ firmware if the buffer was large enough, or the\r
+ size of the buffer needed to contain the map if\r
+ the buffer was too small.\r
+ @param MemoryMap A pointer to the buffer in which firmware places\r
+ the current memory map.\r
+ @param MapKey A pointer to the location in which firmware\r
+ returns the key for the current memory map.\r
+ @param DescriptorSize A pointer to the location in which firmware\r
+ returns the size, in bytes, of an individual\r
+ EFI_MEMORY_DESCRIPTOR.\r
+ @param DescriptorVersion A pointer to the location in which firmware\r
+ returns the version number associated with the\r
+ EFI_MEMORY_DESCRIPTOR.\r
+\r
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap\r
+ buffer.\r
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current\r
+ buffer size needed to hold the memory map is\r
+ returned in MemoryMapSize.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestGetMemoryMap (\r
+ IN OUT UINTN *MemoryMapSize,\r
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
+ OUT UINTN *MapKey,\r
+ OUT UINTN *DescriptorSize,\r
+ OUT UINT32 *DescriptorVersion\r
+ );\r
+\r
+/**\r
+ Allocate pool of a particular type.\r
+\r
+ @param PoolType Type of pool to allocate\r
+ @param Size The amount of pool to allocate\r
+ @param Buffer The address to return a pointer to the allocated\r
+ pool\r
+\r
+ @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL\r
+ @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.\r
+ @retval EFI_SUCCESS Pool successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestAllocatePool (\r
+ IN EFI_MEMORY_TYPE PoolType,\r
+ IN UINTN Size,\r
+ OUT VOID **Buffer\r
+ );\r
+\r
+/**\r
+ Frees pool.\r
+\r
+ @param Buffer The allocated pool entry to free\r
+\r
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.\r
+ @retval EFI_SUCCESS Pool successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestFreePool (\r
+ IN VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Frees pool.\r
+\r
+ @param Buffer The allocated pool entry to free\r
+ @param PoolType Pointer to pool type\r
+\r
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.\r
+ @retval EFI_SUCCESS Pool successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInternalFreePool (\r
+ IN VOID *Buffer,\r
+ OUT EFI_MEMORY_TYPE *PoolType OPTIONAL\r
+ );\r
+\r
+/**\r
+ Creates an event.\r
+\r
+ @param Type The type of event to create and its mode and\r
+ attributes\r
+ @param NotifyTpl The task priority level of event notifications\r
+ @param NotifyFunction Pointer to the events notification function\r
+ @param NotifyContext Pointer to the notification functions context;\r
+ corresponds to parameter "Context" in the\r
+ notification function\r
+ @param Event Pointer to the newly created event if the call\r
+ succeeds; undefined otherwise\r
+\r
+ @retval EFI_SUCCESS The event structure was created\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCreateEvent (\r
+ IN UINT32 Type,\r
+ IN EFI_TPL NotifyTpl,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
+ IN VOID *NotifyContext, OPTIONAL\r
+ OUT EFI_EVENT *Event\r
+ );\r
+\r
+/**\r
+ Sets the type of timer and the trigger time for a timer event.\r
+\r
+ @param UserEvent The timer event that is to be signaled at the\r
+ specified time\r
+ @param Type The type of time that is specified in\r
+ TriggerTime\r
+ @param TriggerTime The number of 100ns units until the timer\r
+ expires\r
+\r
+ @retval EFI_SUCCESS The event has been set to be signaled at the\r
+ requested time\r
+ @retval EFI_INVALID_PARAMETER Event or Type is not valid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSetTimer (\r
+ IN EFI_EVENT UserEvent,\r
+ IN EFI_TIMER_DELAY Type,\r
+ IN UINT64 TriggerTime\r
+ );\r
+\r
+/**\r
+ Stops execution until an event is signaled.\r
+\r
+ @param NumberOfEvents The number of events in the UserEvents array\r
+ @param UserEvents An array of EFI_EVENT\r
+ @param UserIndex Pointer to the index of the event which\r
+ satisfied the wait condition\r
+\r
+ @retval EFI_SUCCESS The event indicated by Index was signaled.\r
+ @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification\r
+ function or Event was not a valid type\r
+ @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestWaitForEvent (\r
+ IN UINTN NumberOfEvents,\r
+ IN EFI_EVENT *UserEvents,\r
+ OUT UINTN *UserIndex\r
+ );\r
+\r
+/**\r
+ Signals the event. Queues the event to be notified if needed.\r
+\r
+ @param UserEvent The event to signal .\r
+\r
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.\r
+ @retval EFI_SUCCESS The event was signaled.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSignalEvent (\r
+ IN EFI_EVENT UserEvent\r
+ );\r
+\r
+/**\r
+ Closes an event and frees the event structure.\r
+\r
+ @param UserEvent Event to close\r
+\r
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.\r
+ @retval EFI_SUCCESS The event has been closed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCloseEvent (\r
+ IN EFI_EVENT UserEvent\r
+ );\r
+\r
+/**\r
+ Check the status of an event.\r
+\r
+ @param UserEvent The event to check\r
+\r
+ @retval EFI_SUCCESS The event is in the signaled state\r
+ @retval EFI_NOT_READY The event is not in the signaled state\r
+ @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCheckEvent (\r
+ IN EFI_EVENT UserEvent\r
+ );\r
+\r
+/**\r
+ Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which\r
+ Calls the private one which contains a BOOLEAN parameter for notifications\r
+\r
+ @param UserHandle The handle to install the protocol handler on,\r
+ or NULL if a new handle is to be allocated\r
+ @param Protocol The protocol to add to the handle\r
+ @param InterfaceType Indicates whether Interface is supplied in\r
+ native form.\r
+ @param Interface The interface for the protocol being added\r
+\r
+ @return Status code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallProtocolInterface (\r
+ IN OUT EFI_HANDLE *UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_INTERFACE_TYPE InterfaceType,\r
+ IN VOID *Interface\r
+ );\r
+\r
+/**\r
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
+\r
+ @param UserHandle Handle on which the interface is to be\r
+ reinstalled\r
+ @param Protocol The numeric ID of the interface\r
+ @param OldInterface A pointer to the old interface\r
+ @param NewInterface A pointer to the new interface\r
+\r
+ @retval EFI_SUCCESS The protocol interface was installed\r
+ @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestReinstallProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *OldInterface,\r
+ IN VOID *NewInterface\r
+ );\r
+\r
+/**\r
+ Uninstalls all instances of a protocol:interfacer from a handle.\r
+ If the last protocol interface is remove from the handle, the\r
+ handle is freed.\r
+\r
+ @param UserHandle The handle to remove the protocol handler from\r
+ @param Protocol The protocol, of protocol:interface, to remove\r
+ @param Interface The interface, of protocol:interface, to remove\r
+\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_SUCCESS Protocol interface successfully uninstalled.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUninstallProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Interface\r
+ );\r
+\r
+/**\r
+ Queries a handle to determine if it supports a specified protocol.\r
+\r
+ @param UserHandle The handle being queried.\r
+ @param Protocol The published unique identifier of the protocol.\r
+ @param Interface Supplies the address where a pointer to the\r
+ corresponding Protocol Interface is returned.\r
+\r
+ @return The requested protocol interface for the handle\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestHandleProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT VOID **Interface\r
+ );\r
+\r
+/**\r
+ Add a new protocol notification record for the request protocol.\r
+\r
+ @param Protocol The requested protocol to add the notify\r
+ registration\r
+ @param Event The event to signal\r
+ @param Registration Returns the registration record\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_SUCCESS Successfully returned the registration record\r
+ that has been added\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestRegisterProtocolNotify (\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_EVENT Event,\r
+ OUT VOID **Registration\r
+ );\r
+\r
+/**\r
+ Locates the requested handle(s) and returns them in Buffer.\r
+\r
+ @param SearchType The type of search to perform to locate the\r
+ handles\r
+ @param Protocol The protocol to search for\r
+ @param SearchKey Dependant on SearchType\r
+ @param BufferSize On input the size of Buffer. On output the\r
+ size of data returned.\r
+ @param Buffer The buffer to return the results in\r
+\r
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is\r
+ returned in BufferSize.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_SUCCESS Successfully found the requested handle(s) and\r
+ returns them in Buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateHandle (\r
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
+ IN EFI_GUID *Protocol OPTIONAL,\r
+ IN VOID *SearchKey OPTIONAL,\r
+ IN OUT UINTN *BufferSize,\r
+ OUT EFI_HANDLE *Buffer\r
+ );\r
+\r
+/**\r
+ Locates the handle to a device on the device path that best matches the specified protocol.\r
+\r
+ @param Protocol The protocol to search for.\r
+ @param DevicePath On input, a pointer to a pointer to the device\r
+ path. On output, the device path pointer is\r
+ modified to point to the remaining part of the\r
+ devicepath.\r
+ @param Device A pointer to the returned device handle.\r
+\r
+ @retval EFI_SUCCESS The resulting handle was returned.\r
+ @retval EFI_NOT_FOUND No handles matched the search.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateDevicePath (\r
+ IN EFI_GUID *Protocol,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
+ OUT EFI_HANDLE *Device\r
+ );\r
+\r
+/**\r
+ Boot Service called to add, modify, or remove a system configuration table from\r
+ the EFI System Table.\r
+\r
+ @param Guid Pointer to the GUID for the entry to add, update, or\r
+ remove\r
+ @param Table Pointer to the configuration table for the entry to add,\r
+ update, or remove, may be NULL.\r
+\r
+ @return EFI_SUCCESS Guid, Table pair added, updated, or removed.\r
+ @return EFI_INVALID_PARAMETER Input GUID not valid.\r
+ @return EFI_NOT_FOUND Attempted to delete non-existant entry\r
+ @return EFI_OUT_OF_RESOURCES Not enough memory available\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallConfigurationTable (\r
+ IN EFI_GUID *Guid,\r
+ IN VOID *Table\r
+ );\r
+\r
+/**\r
+ Loads an EFI image into memory and returns a handle to the image.\r
+\r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param ImageHandle Pointer to the returned image handle that is\r
+ created when the image is successfully loaded.\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
+ resources.\r
+ @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not\r
+ understood.\r
+ @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.\r
+ @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the\r
+ image from being loaded. NULL is returned in *ImageHandle.\r
+ @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a\r
+ valid EFI_LOADED_IMAGE_PROTOCOL. However, the current\r
+ platform policy specifies that the image should not be started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLoadImage (\r
+ IN BOOLEAN BootPolicy,\r
+ IN EFI_HANDLE ParentImageHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ IN VOID *SourceBuffer OPTIONAL,\r
+ IN UINTN SourceSize,\r
+ OUT EFI_HANDLE *ImageHandle\r
+ );\r
+\r
+/**\r
+ Transfer control to a loaded image's entry point.\r
+\r
+ @param ImageHandle Handle of image to be started.\r
+ @param ExitDataSize Pointer of the size to ExitData\r
+ @param ExitData Pointer to a pointer to a data buffer that\r
+ includes a Null-terminated string,\r
+ optionally followed by additional binary data.\r
+ The string is a description that the caller may\r
+ use to further indicate the reason for the\r
+ image's exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate\r
+ @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.\r
+ @retval EFI_SUCCESS Successfully transfer control to the image's\r
+ entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestStartImage (\r
+ IN EFI_HANDLE ImageHandle,\r
+ OUT UINTN *ExitDataSize,\r
+ OUT CHAR16 **ExitData OPTIONAL\r
+ );\r
+\r
+/**\r
+ Terminates the currently loaded EFI image and returns control to boot services.\r
+\r
+ @param ImageHandle Handle that identifies the image. This\r
+ parameter is passed to the image on entry.\r
+ @param Status The image's exit code.\r
+ @param ExitDataSize The size, in bytes, of ExitData. Ignored if\r
+ ExitStatus is EFI_SUCCESS.\r
+ @param ExitData Pointer to a data buffer that includes a\r
+ Null-terminated Unicode string, optionally\r
+ followed by additional binary data. The string\r
+ is a description that the caller may use to\r
+ further indicate the reason for the image's\r
+ exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current\r
+ image.\r
+ @retval EFI_SUCCESS Successfully terminates the currently loaded\r
+ EFI image.\r
+ @retval EFI_ACCESS_DENIED Should never reach there.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate pool\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestExit (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_STATUS Status,\r
+ IN UINTN ExitDataSize,\r
+ IN CHAR16 *ExitData OPTIONAL\r
+ );\r
+\r
+/**\r
+ Unloads an image.\r
+\r
+ @param ImageHandle Handle that identifies the image to be\r
+ unloaded.\r
+\r
+ @retval EFI_SUCCESS The image has been unloaded.\r
+ @retval EFI_UNSUPPORTED The image has been started, and does not support\r
+ unload.\r
+ @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUnloadImage (\r
+ IN EFI_HANDLE ImageHandle\r
+ );\r
+\r
+/**\r
+ Terminates all boot services.\r
+\r
+ @param ImageHandle Handle that identifies the exiting image.\r
+ @param MapKey Key to the latest memory map.\r
+\r
+ @retval EFI_SUCCESS Boot Services terminated\r
+ @retval EFI_INVALID_PARAMETER MapKey is incorrect.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestExitBootServices (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN UINTN MapKey\r
+ );\r
+\r
+/**\r
+ Returns a monotonically increasing count for the platform.\r
+\r
+ @param[out] Count The pointer to returned value.\r
+\r
+ @retval EFI_SUCCESS The next monotonic count was returned.\r
+ @retval EFI_INVALID_PARAMETER Count is NULL.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestGetNextMonotonicCount (\r
+ OUT UINT64 *Count\r
+ );\r
+\r
+/**\r
+ Introduces a fine-grained stall.\r
+\r
+ @param Microseconds The number of microseconds to stall execution.\r
+\r
+ @retval EFI_SUCCESS Execution was stalled for at least the requested\r
+ amount of microseconds.\r
+ @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestStall (\r
+ IN UINTN Microseconds\r
+ );\r
+\r
+/**\r
+ Sets the system's watchdog timer.\r
+\r
+ @param Timeout The number of seconds to set the watchdog timer to.\r
+ A value of zero disables the timer.\r
+ @param WatchdogCode The numeric code to log on a watchdog timer timeout\r
+ event. The firmware reserves codes 0x0000 to 0xFFFF.\r
+ Loaders and operating systems may use other timeout\r
+ codes.\r
+ @param DataSize The size, in bytes, of WatchdogData.\r
+ @param WatchdogData A data buffer that includes a Null-terminated Unicode\r
+ string, optionally followed by additional binary data.\r
+ The string is a description that the call may use to\r
+ further indicate the reason to be logged with a\r
+ watchdog event.\r
+\r
+ @return EFI_SUCCESS Timeout has been set\r
+ @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet\r
+ @return EFI_UNSUPPORTED System does not have a timer (currently not used)\r
+ @return EFI_DEVICE_ERROR Could not complete due to hardware error\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSetWatchdogTimer (\r
+ IN UINTN Timeout,\r
+ IN UINT64 WatchdogCode,\r
+ IN UINTN DataSize,\r
+ IN CHAR16 *WatchdogData OPTIONAL\r
+ );\r
+\r
+/**\r
+ Connects one or more drivers to a controller.\r
+\r
+ @param ControllerHandle The handle of the controller to which driver(s) are to be connected.\r
+ @param DriverImageHandle A pointer to an ordered list handles that support the\r
+ EFI_DRIVER_BINDING_PROTOCOL.\r
+ @param RemainingDevicePath A pointer to the device path that specifies a child of the\r
+ controller specified by ControllerHandle.\r
+ @param Recursive If TRUE, then ConnectController() is called recursively\r
+ until the entire tree of controllers below the controller specified\r
+ by ControllerHandle have been created. If FALSE, then\r
+ the tree of controllers is only expanded one level.\r
+\r
+ @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.\r
+ 2) No drivers were connected to ControllerHandle, but\r
+ RemainingDevicePath is not NULL, and it is an End Device\r
+ Path Node.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances\r
+ present in the system.\r
+ 2) No drivers were connected to ControllerHandle.\r
+ @retval EFI_SECURITY_VIOLATION\r
+ The user has no permission to start UEFI device drivers on the device path\r
+ associated with the ControllerHandle or specified by the RemainingDevicePath.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestConnectController (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
+ IN BOOLEAN Recursive\r
+ );\r
+\r
+/**\r
+ Disconnects a controller from a driver\r
+\r
+ @param ControllerHandle ControllerHandle The handle of\r
+ the controller from which\r
+ driver(s) are to be\r
+ disconnected.\r
+ @param DriverImageHandle DriverImageHandle The driver to\r
+ disconnect from ControllerHandle.\r
+ @param ChildHandle ChildHandle The handle of the\r
+ child to destroy.\r
+\r
+ @retval EFI_SUCCESS One or more drivers were\r
+ disconnected from the controller.\r
+ @retval EFI_SUCCESS On entry, no drivers are managing\r
+ ControllerHandle.\r
+ @retval EFI_SUCCESS DriverImageHandle is not NULL,\r
+ and on entry DriverImageHandle is\r
+ not managing ControllerHandle.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,\r
+ and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it\r
+ is not a valid EFI_HANDLE.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources\r
+ available to disconnect any\r
+ drivers from ControllerHandle.\r
+ @retval EFI_DEVICE_ERROR The controller could not be\r
+ disconnected because of a device\r
+ error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestDisconnectController (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL\r
+ );\r
+\r
+/**\r
+ Locates the installed protocol handler for the handle, and\r
+ invokes it to obtain the protocol interface. Usage information\r
+ is registered in the protocol data base.\r
+\r
+ @param UserHandle The handle to obtain the protocol interface on\r
+ @param Protocol The ID of the protocol\r
+ @param Interface The location to return the protocol interface\r
+ @param ImageHandle The handle of the Image that is opening the\r
+ protocol interface specified by Protocol and\r
+ Interface.\r
+ @param ControllerHandle The controller handle that is requiring this\r
+ interface.\r
+ @param Attributes The open mode of the protocol interface\r
+ specified by Handle and Protocol.\r
+\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_SUCCESS Get the protocol interface.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestOpenProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT VOID **Interface OPTIONAL,\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINT32 Attributes\r
+ );\r
+\r
+/**\r
+ Closes a protocol on a handle that was opened using OpenProtocol().\r
+\r
+ @param UserHandle The handle for the protocol interface that was\r
+ previously opened with OpenProtocol(), and is\r
+ now being closed.\r
+ @param Protocol The published unique identifier of the protocol.\r
+ It is the caller's responsibility to pass in a\r
+ valid GUID.\r
+ @param AgentHandle The handle of the agent that is closing the\r
+ protocol interface.\r
+ @param ControllerHandle If the agent that opened a protocol is a driver\r
+ that follows the EFI Driver Model, then this\r
+ parameter is the controller handle that required\r
+ the protocol interface. If the agent does not\r
+ follow the EFI Driver Model, then this parameter\r
+ is optional and may be NULL.\r
+\r
+ @retval EFI_SUCCESS The protocol instance was closed.\r
+ @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a\r
+ valid EFI_HANDLE.\r
+ @retval EFI_NOT_FOUND Can not find the specified protocol or\r
+ AgentHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCloseProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_HANDLE AgentHandle,\r
+ IN EFI_HANDLE ControllerHandle\r
+ );\r
+\r
+/**\r
+ Return information about Opened protocols in the system\r
+\r
+ @param UserHandle The handle to close the protocol interface on\r
+ @param Protocol The ID of the protocol\r
+ @param EntryBuffer A pointer to a buffer of open protocol\r
+ information in the form of\r
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.\r
+ @param EntryCount Number of EntryBuffer entries\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestOpenProtocolInformation (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,\r
+ OUT UINTN *EntryCount\r
+ );\r
+\r
+/**\r
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated\r
+ from pool.\r
+\r
+ @param UserHandle The handle from which to retrieve the list of\r
+ protocol interface GUIDs.\r
+ @param ProtocolBuffer A pointer to the list of protocol interface GUID\r
+ pointers that are installed on Handle.\r
+ @param ProtocolBufferCount A pointer to the number of GUID pointers present\r
+ in ProtocolBuffer.\r
+\r
+ @retval EFI_SUCCESS The list of protocol interface GUIDs installed\r
+ on Handle was returned in ProtocolBuffer. The\r
+ number of protocol interface GUIDs was returned\r
+ in ProtocolBufferCount.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL.\r
+ @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.\r
+ @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the\r
+ results.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestProtocolsPerHandle (\r
+ IN EFI_HANDLE UserHandle,\r
+ OUT EFI_GUID ***ProtocolBuffer,\r
+ OUT UINTN *ProtocolBufferCount\r
+ );\r
+\r
+/**\r
+ Function returns an array of handles that support the requested protocol\r
+ in a buffer allocated from pool. This is a version of UnitTestLocateHandle()\r
+ that allocates a buffer for the caller.\r
+\r
+ @param SearchType Specifies which handle(s) are to be returned.\r
+ @param Protocol Provides the protocol to search by. This\r
+ parameter is only valid for SearchType\r
+ ByProtocol.\r
+ @param SearchKey Supplies the search key depending on the\r
+ SearchType.\r
+ @param NumberHandles The number of handles returned in Buffer.\r
+ @param Buffer A pointer to the buffer to return the requested\r
+ array of handles that support Protocol.\r
+\r
+ @retval EFI_SUCCESS The result array of handles was returned.\r
+ @retval EFI_NOT_FOUND No handles match the search.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the\r
+ matching results.\r
+ @retval EFI_INVALID_PARAMETER One or more parameters are not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateHandleBuffer (\r
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
+ IN EFI_GUID *Protocol OPTIONAL,\r
+ IN VOID *SearchKey OPTIONAL,\r
+ IN OUT UINTN *NumberHandles,\r
+ OUT EFI_HANDLE **Buffer\r
+ );\r
+\r
+/**\r
+ Return the first Protocol Interface that matches the Protocol GUID. If\r
+ Registration is passed in, return a Protocol Instance that was just add\r
+ to the system. If Registration is NULL return the first Protocol Interface\r
+ you find.\r
+\r
+ @param Protocol The protocol to search for\r
+ @param Registration Optional Registration Key returned from\r
+ RegisterProtocolNotify()\r
+ @param Interface Return the Protocol interface (instance).\r
+\r
+ @retval EFI_SUCCESS If a valid Interface is returned\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_NOT_FOUND Protocol interface not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateProtocol (\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Registration OPTIONAL,\r
+ OUT VOID **Interface\r
+ );\r
+\r
+/**\r
+ Installs a list of protocol interface into the boot services environment.\r
+ This function calls InstallProtocolInterface() in a loop. If any error\r
+ occurs all the protocols added by this function are removed. This is\r
+ basically a lib function to save space.\r
+\r
+ @param Handle The handle to install the protocol handlers on,\r
+ or NULL if a new handle is to be allocated\r
+ @param ... EFI_GUID followed by protocol instance. A NULL\r
+ terminates the list. The pairs are the\r
+ arguments to InstallProtocolInterface(). All the\r
+ protocols are added to Handle.\r
+\r
+ @retval EFI_SUCCESS All the protocol interface was installed.\r
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.\r
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in\r
+ the handle database.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL.\r
+ @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallMultipleProtocolInterfaces (\r
+ IN OUT EFI_HANDLE *Handle,\r
+ ...\r
+ );\r
+\r
+/**\r
+ Uninstalls a list of protocol interface in the boot services environment.\r
+ This function calls UninstallProtocolInterface() in a loop. This is\r
+ basically a lib function to save space.\r
+\r
+ @param Handle The handle to uninstall the protocol\r
+ @param ... EFI_GUID followed by protocol instance. A NULL\r
+ terminates the list. The pairs are the\r
+ arguments to UninstallProtocolInterface(). All\r
+ the protocols are added to Handle.\r
+\r
+ @return Status code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUninstallMultipleProtocolInterfaces (\r
+ IN EFI_HANDLE Handle,\r
+ ...\r
+ );\r
+\r
+/**\r
+ Computes and returns a 32-bit CRC for a data buffer.\r
+\r
+ @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.\r
+ @param[in] DataSize The number of bytes in the buffer Data.\r
+ @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data\r
+ and DataSize.\r
+\r
+ @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in\r
+ Crc32.\r
+ @retval EFI_INVALID_PARAMETER Data is NULL.\r
+ @retval EFI_INVALID_PARAMETER Crc32 is NULL.\r
+ @retval EFI_INVALID_PARAMETER DataSize is 0.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCalculateCrc32 (\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ OUT UINT32 *Crc32\r
+ );\r
+\r
+/**\r
+ Creates an event in a group.\r
+\r
+ @param Type The type of event to create and its mode and\r
+ attributes\r
+ @param NotifyTpl The task priority level of event notifications\r
+ @param NotifyFunction Pointer to the events notification function\r
+ @param NotifyContext Pointer to the notification functions context;\r
+ corresponds to parameter "Context" in the\r
+ notification function\r
+ @param EventGroup GUID for EventGroup if NULL act the same as\r
+ gBS->CreateEvent().\r
+ @param Event Pointer to the newly created event if the call\r
+ succeeds; undefined otherwise\r
+\r
+ @retval EFI_SUCCESS The event structure was created\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCreateEventEx (\r
+ IN UINT32 Type,\r
+ IN EFI_TPL NotifyTpl,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
+ IN CONST VOID *NotifyContext, OPTIONAL\r
+ IN CONST EFI_GUID *EventGroup, OPTIONAL\r
+ OUT EFI_EVENT *Event\r
+ );\r
+\r
+#endif\r
--- /dev/null
+## @file\r
+# UEFI Boot Services Table Library for unit tests implementation.\r
+#\r
+# Copyright (c) Microsoft Corporation\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = UnitTestUefiBootServicesTableLib\r
+ MODULE_UNI_FILE = UefiBootServicesTableLibTest.uni\r
+ FILE_GUID = AA3A0651-89EB-4951-9D68-50F27360EBC2\r
+ MODULE_TYPE = UEFI_DRIVER\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = UefiBootServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE\r
+\r
+ CONSTRUCTOR = UnitTestUefiBootServicesTableLibConstructor\r
+\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 EBC\r
+#\r
+\r
+[Sources]\r
+ UnitTestUefiBootServicesTableLib.h\r
+ UnitTestUefiBootServicesTableLib.c\r
+ UnitTestUefiBootServicesTableLibEventTimer.c\r
+ UnitTestUefiBootServicesTableLibImage.c\r
+ UnitTestUefiBootServicesTableLibMemory.c\r
+ UnitTestUefiBootServicesTableLibProtocol.h\r
+ UnitTestUefiBootServicesTableLibProtocol.c\r
+ UnitTestUefiBootServicesTableLibMisc.c\r
+ UnitTestUefiBootServicesTableLibTpl.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ MemoryAllocationLib\r
+ UnitTestLib\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+ TimerExtra.uni\r
--- /dev/null
+// /** @file\r
+// UEFI Boot Services Table Library for unit tests implementation.\r
+//\r
+// Copyright (c) Microsoft Corporation\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "UEFI Boot Services Table Library for unit tests"\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "UEFI Boot Services Table Library for unit tests."\r
--- /dev/null
+/** @file\r
+ Implementation of event and timer related services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+/**\r
+ Creates an event.\r
+\r
+ @param Type The type of event to create and its mode and\r
+ attributes\r
+ @param NotifyTpl The task priority level of event notifications\r
+ @param NotifyFunction Pointer to the events notification function\r
+ @param NotifyContext Pointer to the notification functions context\r
+ corresponds to parameter "Context" in the\r
+ notification function\r
+ @param Event Pointer to the newly created event if the call\r
+ succeeds undefined otherwise\r
+\r
+ @retval EFI_SUCCESS The event structure was created\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCreateEvent (\r
+ IN UINT32 Type,\r
+ IN EFI_TPL NotifyTpl,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
+ IN VOID *NotifyContext, OPTIONAL\r
+ OUT EFI_EVENT *Event\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Sets the type of timer and the trigger time for a timer event.\r
+\r
+ @param UserEvent The timer event that is to be signaled at the\r
+ specified time\r
+ @param Type The type of time that is specified in\r
+ TriggerTime\r
+ @param TriggerTime The number of 100ns units until the timer\r
+ expires\r
+\r
+ @retval EFI_SUCCESS The event has been set to be signaled at the\r
+ requested time\r
+ @retval EFI_INVALID_PARAMETER Event or Type is not valid\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSetTimer (\r
+ IN EFI_EVENT UserEvent,\r
+ IN EFI_TIMER_DELAY Type,\r
+ IN UINT64 TriggerTime\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Stops execution until an event is signaled.\r
+\r
+ @param NumberOfEvents The number of events in the UserEvents array\r
+ @param UserEvents An array of EFI_EVENT\r
+ @param UserIndex Pointer to the index of the event which\r
+ satisfied the wait condition\r
+\r
+ @retval EFI_SUCCESS The event indicated by Index was signaled.\r
+ @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification\r
+ function or Event was not a valid type\r
+ @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestWaitForEvent (\r
+ IN UINTN NumberOfEvents,\r
+ IN EFI_EVENT *UserEvents,\r
+ OUT UINTN *UserIndex\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Signals the event. Queues the event to be notified if needed.\r
+\r
+ @param UserEvent The event to signal .\r
+\r
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.\r
+ @retval EFI_SUCCESS The event was signaled.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSignalEvent (\r
+ IN EFI_EVENT UserEvent\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Closes an event and frees the event structure.\r
+\r
+ @param UserEvent Event to close\r
+\r
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.\r
+ @retval EFI_SUCCESS The event has been closed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCloseEvent (\r
+ IN EFI_EVENT UserEvent\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Check the status of an event.\r
+\r
+ @param UserEvent The event to check\r
+\r
+ @retval EFI_SUCCESS The event is in the signaled state\r
+ @retval EFI_NOT_READY The event is not in the signaled state\r
+ @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCheckEvent (\r
+ IN EFI_EVENT UserEvent\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Creates an event in a group.\r
+\r
+ @param Type The type of event to create and its mode and\r
+ attributes\r
+ @param NotifyTpl The task priority level of event notifications\r
+ @param NotifyFunction Pointer to the events notification function\r
+ @param NotifyContext Pointer to the notification functions context\r
+ corresponds to parameter "Context" in the\r
+ notification function\r
+ @param EventGroup GUID for EventGroup if NULL act the same as\r
+ gBS->CreateEvent().\r
+ @param Event Pointer to the newly created event if the call\r
+ succeeds undefined otherwise\r
+\r
+ @retval EFI_SUCCESS The event structure was created\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCreateEventEx (\r
+ IN UINT32 Type,\r
+ IN EFI_TPL NotifyTpl,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
+ IN CONST VOID *NotifyContext, OPTIONAL\r
+ IN CONST EFI_GUID *EventGroup, OPTIONAL\r
+ OUT EFI_EVENT *Event\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
--- /dev/null
+/** @file\r
+ Implementation of image related services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+/**\r
+ Loads an EFI image into memory and returns a handle to the image.\r
+\r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param ImageHandle Pointer to the returned image handle that is\r
+ created when the image is successfully loaded.\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
+ resources.\r
+ @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not\r
+ understood.\r
+ @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.\r
+ @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the\r
+ image from being loaded. NULL is returned in *ImageHandle.\r
+ @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a\r
+ valid EFI_LOADED_IMAGE_PROTOCOL. However, the current\r
+ platform policy specifies that the image should not be started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLoadImage (\r
+ IN BOOLEAN BootPolicy,\r
+ IN EFI_HANDLE ParentImageHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ IN VOID *SourceBuffer OPTIONAL,\r
+ IN UINTN SourceSize,\r
+ OUT EFI_HANDLE *ImageHandle\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Transfer control to a loaded image's entry point.\r
+\r
+ @param ImageHandle Handle of image to be started.\r
+ @param ExitDataSize Pointer of the size to ExitData\r
+ @param ExitData Pointer to a pointer to a data buffer that\r
+ includes a Null-terminated string,\r
+ optionally followed by additional binary data.\r
+ The string is a description that the caller may\r
+ use to further indicate the reason for the\r
+ image's exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate\r
+ @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.\r
+ @retval EFI_SUCCESS Successfully transfer control to the image's\r
+ entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestStartImage (\r
+ IN EFI_HANDLE ImageHandle,\r
+ OUT UINTN *ExitDataSize,\r
+ OUT CHAR16 **ExitData OPTIONAL\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Terminates the currently loaded EFI image and returns control to boot services.\r
+\r
+ @param ImageHandle Handle that identifies the image. This\r
+ parameter is passed to the image on entry.\r
+ @param Status The image's exit code.\r
+ @param ExitDataSize The size, in bytes, of ExitData. Ignored if\r
+ ExitStatus is EFI_SUCCESS.\r
+ @param ExitData Pointer to a data buffer that includes a\r
+ Null-terminated Unicode string, optionally\r
+ followed by additional binary data. The string\r
+ is a description that the caller may use to\r
+ further indicate the reason for the image's\r
+ exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current\r
+ image.\r
+ @retval EFI_SUCCESS Successfully terminates the currently loaded\r
+ EFI image.\r
+ @retval EFI_ACCESS_DENIED Should never reach there.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate pool\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestExit (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_STATUS Status,\r
+ IN UINTN ExitDataSize,\r
+ IN CHAR16 *ExitData OPTIONAL\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Unloads an image.\r
+\r
+ @param ImageHandle Handle that identifies the image to be\r
+ unloaded.\r
+\r
+ @retval EFI_SUCCESS The image has been unloaded.\r
+ @retval EFI_UNSUPPORTED The image has been started, and does not support\r
+ unload.\r
+ @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUnloadImage (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Terminates all boot services.\r
+\r
+ @param ImageHandle Handle that identifies the exiting image.\r
+ @param MapKey Key to the latest memory map.\r
+\r
+ @retval EFI_SUCCESS Boot Services terminated\r
+ @retval EFI_INVALID_PARAMETER MapKey is incorrect.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestExitBootServices (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN UINTN MapKey\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
--- /dev/null
+/** @file\r
+ Implementation of memory related services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+/**\r
+ Allocates pages from the memory map.\r
+\r
+ @param Type The type of allocation to perform\r
+ @param MemoryType The type of memory to turn the allocated pages\r
+ into\r
+ @param NumberOfPages The number of pages to allocate\r
+ @param Memory A pointer to receive the base allocated memory\r
+ address\r
+\r
+ @return Status. On success, Memory is filled in with the base address allocated\r
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in\r
+ spec.\r
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.\r
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.\r
+ @retval EFI_SUCCESS Pages successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestAllocatePages (\r
+ IN EFI_ALLOCATE_TYPE Type,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN NumberOfPages,\r
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Frees previous allocated pages.\r
+\r
+ @param Memory Base address of memory being freed\r
+ @param NumberOfPages The number of pages to free\r
+\r
+ @retval EFI_NOT_FOUND Could not find the entry that covers the range\r
+ @retval EFI_INVALID_PARAMETER Address not aligned\r
+ @return EFI_SUCCESS -Pages successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestFreePages (\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NumberOfPages\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ This function returns a copy of the current memory map. The map is an array of\r
+ memory descriptors, each of which describes a contiguous block of memory.\r
+\r
+ @param MemoryMapSize A pointer to the size, in bytes, of the\r
+ MemoryMap buffer. On input, this is the size of\r
+ the buffer allocated by the caller. On output,\r
+ it is the size of the buffer returned by the\r
+ firmware if the buffer was large enough, or the\r
+ size of the buffer needed to contain the map if\r
+ the buffer was too small.\r
+ @param MemoryMap A pointer to the buffer in which firmware places\r
+ the current memory map.\r
+ @param MapKey A pointer to the location in which firmware\r
+ returns the key for the current memory map.\r
+ @param DescriptorSize A pointer to the location in which firmware\r
+ returns the size, in bytes, of an individual\r
+ EFI_MEMORY_DESCRIPTOR.\r
+ @param DescriptorVersion A pointer to the location in which firmware\r
+ returns the version number associated with the\r
+ EFI_MEMORY_DESCRIPTOR.\r
+\r
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap\r
+ buffer.\r
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current\r
+ buffer size needed to hold the memory map is\r
+ returned in MemoryMapSize.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestGetMemoryMap (\r
+ IN OUT UINTN *MemoryMapSize,\r
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
+ OUT UINTN *MapKey,\r
+ OUT UINTN *DescriptorSize,\r
+ OUT UINT32 *DescriptorVersion\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Allocate pool of a particular type.\r
+\r
+ @param PoolType Type of pool to allocate\r
+ @param Size The amount of pool to allocate\r
+ @param Buffer The address to return a pointer to the allocated\r
+ pool\r
+\r
+ @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL\r
+ @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.\r
+ @retval EFI_SUCCESS Pool successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestAllocatePool (\r
+ IN EFI_MEMORY_TYPE PoolType,\r
+ IN UINTN Size,\r
+ OUT VOID **Buffer\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Frees pool.\r
+\r
+ @param Buffer The allocated pool entry to free\r
+\r
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.\r
+ @retval EFI_SUCCESS Pool successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestFreePool (\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
--- /dev/null
+/** @file\r
+ Implementation of miscellaneous services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+/**\r
+ Returns a monotonically increasing count for the platform.\r
+\r
+ @param[out] Count The pointer to returned value.\r
+\r
+ @retval EFI_SUCCESS The next monotonic count was returned.\r
+ @retval EFI_INVALID_PARAMETER Count is NULL.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestGetNextMonotonicCount (\r
+ OUT UINT64 *Count\r
+ )\r
+{\r
+ STATIC UINT64 StaticCount = 0;\r
+\r
+ *Count = StaticCount++;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Introduces a fine-grained stall.\r
+\r
+ @param Microseconds The number of microseconds to stall execution.\r
+\r
+ @retval EFI_SUCCESS Execution was stalled for at least the requested\r
+ amount of microseconds.\r
+ @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestStall (\r
+ IN UINTN Microseconds\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Sets the system's watchdog timer.\r
+\r
+ @param Timeout The number of seconds to set the watchdog timer to.\r
+ A value of zero disables the timer.\r
+ @param WatchdogCode The numeric code to log on a watchdog timer timeout\r
+ event. The firmware reserves codes 0x0000 to 0xFFFF.\r
+ Loaders and operating systems may use other timeout\r
+ codes.\r
+ @param DataSize The size, in bytes, of WatchdogData.\r
+ @param WatchdogData A data buffer that includes a Null-terminated Unicode\r
+ string, optionally followed by additional binary data.\r
+ The string is a description that the call may use to\r
+ further indicate the reason to be logged with a\r
+ watchdog event.\r
+\r
+ @return EFI_SUCCESS Timeout has been set\r
+ @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet\r
+ @return EFI_UNSUPPORTED System does not have a timer (currently not used)\r
+ @return EFI_DEVICE_ERROR Could not complete due to hardware error\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestSetWatchdogTimer (\r
+ IN UINTN Timeout,\r
+ IN UINT64 WatchdogCode,\r
+ IN UINTN DataSize,\r
+ IN CHAR16 *WatchdogData OPTIONAL\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Connects one or more drivers to a controller.\r
+\r
+ @param ControllerHandle The handle of the controller to which driver(s) are to be connected.\r
+ @param DriverImageHandle A pointer to an ordered list handles that support the\r
+ EFI_DRIVER_BINDING_PROTOCOL.\r
+ @param RemainingDevicePath A pointer to the device path that specifies a child of the\r
+ controller specified by ControllerHandle.\r
+ @param Recursive If TRUE, then ConnectController() is called recursively\r
+ until the entire tree of controllers below the controller specified\r
+ by ControllerHandle have been created. If FALSE, then\r
+ the tree of controllers is only expanded one level.\r
+\r
+ @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.\r
+ 2) No drivers were connected to ControllerHandle, but\r
+ RemainingDevicePath is not NULL, and it is an End Device\r
+ Path Node.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances\r
+ present in the system.\r
+ 2) No drivers were connected to ControllerHandle.\r
+ @retval EFI_SECURITY_VIOLATION\r
+ The user has no permission to start UEFI device drivers on the device path\r
+ associated with the ControllerHandle or specified by the RemainingDevicePath.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestConnectController (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
+ IN BOOLEAN Recursive\r
+ )\r
+{\r
+ return EFI_SUCCESS; // Return success for now\r
+}\r
+\r
+/**\r
+ Disconnects a controller from a driver\r
+\r
+ @param ControllerHandle ControllerHandle The handle of\r
+ the controller from which\r
+ driver(s) are to be\r
+ disconnected.\r
+ @param DriverImageHandle DriverImageHandle The driver to\r
+ disconnect from ControllerHandle.\r
+ @param ChildHandle ChildHandle The handle of the\r
+ child to destroy.\r
+\r
+ @retval EFI_SUCCESS One or more drivers were\r
+ disconnected from the controller.\r
+ @retval EFI_SUCCESS On entry, no drivers are managing\r
+ ControllerHandle.\r
+ @retval EFI_SUCCESS DriverImageHandle is not NULL,\r
+ and on entry DriverImageHandle is\r
+ not managing ControllerHandle.\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+ @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,\r
+ and it is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it\r
+ is not a valid EFI_HANDLE.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources\r
+ available to disconnect any\r
+ drivers from ControllerHandle.\r
+ @retval EFI_DEVICE_ERROR The controller could not be\r
+ disconnected because of a device\r
+ error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestDisconnectController (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL\r
+ )\r
+{\r
+ return EFI_SUCCESS; // Return success for now\r
+}\r
+\r
+/**\r
+ Computes and returns a 32-bit CRC for a data buffer.\r
+\r
+ @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.\r
+ @param[in] DataSize The number of bytes in the buffer Data.\r
+ @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data\r
+ and DataSize.\r
+\r
+ @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in\r
+ Crc32.\r
+ @retval EFI_INVALID_PARAMETER Data is NULL.\r
+ @retval EFI_INVALID_PARAMETER Crc32 is NULL.\r
+ @retval EFI_INVALID_PARAMETER DataSize is 0.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCalculateCrc32 (\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ OUT UINT32 *Crc32\r
+ )\r
+{\r
+ if ((Data == NULL) || (Crc32 == NULL) || (DataSize == 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Crc32 = CalculateCrc32 (Data, DataSize);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ Implementation of protocol related services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLibProtocol.h"\r
+\r
+STATIC LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);\r
+STATIC LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);\r
+STATIC UINT64 gHandleDatabaseKey = 0;\r
+STATIC UINTN mEfiLocateHandleRequest = 0;\r
+\r
+//\r
+// Helper Functions\r
+//\r
+\r
+/**\r
+ Check whether a handle is a valid EFI_HANDLE\r
+\r
+ @param UserHandle The handle to check\r
+\r
+ @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE.\r
+ @retval EFI_SUCCESS The handle is valid EFI_HANDLE.\r
+\r
+**/\r
+EFI_STATUS\r
+UnitTestValidateHandle (\r
+ IN EFI_HANDLE UserHandle\r
+ )\r
+{\r
+ IHANDLE *Handle;\r
+ LIST_ENTRY *Link;\r
+\r
+ if (UserHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {\r
+ Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
+ if (Handle == (IHANDLE *)UserHandle) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+/**\r
+ Finds the protocol entry for the requested protocol.\r
+\r
+ @param Protocol The ID of the protocol\r
+ @param Create Create a new entry if not found\r
+\r
+ @return Protocol entry\r
+\r
+**/\r
+PROTOCOL_ENTRY *\r
+UnitTestFindProtocolEntry (\r
+ IN EFI_GUID *Protocol,\r
+ IN BOOLEAN Create\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ PROTOCOL_ENTRY *Item;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+\r
+ //\r
+ // Search the database for the matching GUID\r
+ //\r
+\r
+ ProtEntry = NULL;\r
+ for (Link = mProtocolDatabase.ForwardLink;\r
+ Link != &mProtocolDatabase;\r
+ Link = Link->ForwardLink)\r
+ {\r
+ Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);\r
+ if (CompareGuid (&Item->ProtocolID, Protocol)) {\r
+ //\r
+ // This is the protocol entry\r
+ //\r
+\r
+ ProtEntry = Item;\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If the protocol entry was not found and Create is TRUE, then\r
+ // allocate a new entry\r
+ //\r
+ if ((ProtEntry == NULL) && Create) {\r
+ ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));\r
+\r
+ if (ProtEntry != NULL) {\r
+ //\r
+ // Initialize new protocol entry structure\r
+ //\r
+ ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;\r
+ CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol);\r
+ InitializeListHead (&ProtEntry->Protocols);\r
+ InitializeListHead (&ProtEntry->Notify);\r
+\r
+ //\r
+ // Add it to protocol database\r
+ //\r
+ InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);\r
+ }\r
+ }\r
+\r
+ return ProtEntry;\r
+}\r
+\r
+/**\r
+ Finds the protocol instance for the requested handle and protocol.\r
+ Note: This function doesn't do parameters checking, it's caller's responsibility\r
+ to pass in valid parameters.\r
+\r
+ @param Handle The handle to search the protocol on\r
+ @param Protocol GUID of the protocol\r
+ @param Interface The interface for the protocol being searched\r
+\r
+ @return Protocol instance (NULL: Not found)\r
+\r
+**/\r
+PROTOCOL_INTERFACE *\r
+UnitTestFindProtocolInterface (\r
+ IN IHANDLE *Handle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Interface\r
+ )\r
+{\r
+ PROTOCOL_INTERFACE *Prot;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+ LIST_ENTRY *Link;\r
+\r
+ Prot = NULL;\r
+\r
+ //\r
+ // Lookup the protocol entry for this protocol ID\r
+ //\r
+\r
+ ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);\r
+ if (ProtEntry != NULL) {\r
+ //\r
+ // Look at each protocol interface for any matches\r
+ //\r
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
+ //\r
+ // If this protocol interface matches, remove it\r
+ //\r
+ Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
+ if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) {\r
+ break;\r
+ }\r
+\r
+ Prot = NULL;\r
+ }\r
+ }\r
+\r
+ return Prot;\r
+}\r
+\r
+/**\r
+ Signal event for every protocol in protocol entry.\r
+\r
+ @param ProtEntry Protocol entry\r
+\r
+**/\r
+VOID\r
+UnitTestNotifyProtocolEntry (\r
+ IN PROTOCOL_ENTRY *ProtEntry\r
+ )\r
+{\r
+ PROTOCOL_NOTIFY *ProtNotify;\r
+ LIST_ENTRY *Link;\r
+\r
+ for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
+ ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
+ UnitTestSignalEvent (ProtNotify->Event);\r
+ }\r
+}\r
+\r
+/**\r
+ Routine to get the next Handle, when you are searching for all handles.\r
+\r
+ @param Position Information about which Handle to seach for.\r
+ @param Interface Return the interface structure for the matching\r
+ protocol.\r
+\r
+ @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+ Otherwise,NULL is returned.\r
+\r
+**/\r
+IHANDLE *\r
+UnitTestGetNextLocateAllHandles (\r
+ IN OUT LOCATE_POSITION *Position,\r
+ OUT VOID **Interface\r
+ )\r
+{\r
+ IHANDLE *Handle;\r
+\r
+ //\r
+ // Next handle\r
+ //\r
+ Position->Position = Position->Position->ForwardLink;\r
+\r
+ //\r
+ // If not at the end of the list, get the handle\r
+ //\r
+ Handle = NULL;\r
+ *Interface = NULL;\r
+ if (Position->Position != &gHandleList) {\r
+ Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
+ }\r
+\r
+ return Handle;\r
+}\r
+\r
+/**\r
+ Routine to get the next Handle, when you are searching for register protocol\r
+ notifies.\r
+\r
+ @param Position Information about which Handle to seach for.\r
+ @param Interface Return the interface structure for the matching\r
+ protocol.\r
+\r
+ @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+ Otherwise,NULL is returned.\r
+\r
+**/\r
+IHANDLE *\r
+UnitTestGetNextLocateByRegisterNotify (\r
+ IN OUT LOCATE_POSITION *Position,\r
+ OUT VOID **Interface\r
+ )\r
+{\r
+ IHANDLE *Handle;\r
+ PROTOCOL_NOTIFY *ProtNotify;\r
+ PROTOCOL_INTERFACE *Prot;\r
+ LIST_ENTRY *Link;\r
+\r
+ Handle = NULL;\r
+ *Interface = NULL;\r
+ ProtNotify = Position->SearchKey;\r
+\r
+ //\r
+ // If this is the first request, get the next handle\r
+ //\r
+ if (ProtNotify != NULL) {\r
+ ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);\r
+ Position->SearchKey = NULL;\r
+\r
+ //\r
+ // If not at the end of the list, get the next handle\r
+ //\r
+ Link = ProtNotify->Position->ForwardLink;\r
+ if (Link != &ProtNotify->Protocol->Protocols) {\r
+ Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
+ Handle = Prot->Handle;\r
+ *Interface = Prot->Interface;\r
+ }\r
+ }\r
+\r
+ return Handle;\r
+}\r
+\r
+/**\r
+ Routine to get the next Handle, when you are searching for a given protocol.\r
+\r
+ @param Position Information about which Handle to seach for.\r
+ @param Interface Return the interface structure for the matching\r
+ protocol.\r
+\r
+ @return An pointer to IHANDLE if the next Position is not the end of the list.\r
+ Otherwise,NULL is returned.\r
+\r
+**/\r
+IHANDLE *\r
+UnitTestGetNextLocateByProtocol (\r
+ IN OUT LOCATE_POSITION *Position,\r
+ OUT VOID **Interface\r
+ )\r
+{\r
+ IHANDLE *Handle;\r
+ LIST_ENTRY *Link;\r
+ PROTOCOL_INTERFACE *Prot;\r
+\r
+ Handle = NULL;\r
+ *Interface = NULL;\r
+ for ( ; ;) {\r
+ //\r
+ // Next entry\r
+ //\r
+ Link = Position->Position->ForwardLink;\r
+ Position->Position = Link;\r
+\r
+ //\r
+ // If not at the end, return the handle\r
+ //\r
+ if (Link == &Position->ProtEntry->Protocols) {\r
+ Handle = NULL;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the handle\r
+ //\r
+ Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
+ Handle = Prot->Handle;\r
+ *Interface = Prot->Interface;\r
+\r
+ //\r
+ // If this handle has not been returned this request, then\r
+ // return it now\r
+ //\r
+ if (Handle->LocateRequest != mEfiLocateHandleRequest) {\r
+ Handle->LocateRequest = mEfiLocateHandleRequest;\r
+ break;\r
+ }\r
+ }\r
+\r
+ return Handle;\r
+}\r
+\r
+/**\r
+ Attempts to disconnect all drivers that are using the protocol interface being queried.\r
+ If failed, reconnect all drivers disconnected.\r
+ Note: This function doesn't do parameters checking, it's caller's responsibility\r
+ to pass in valid parameters.\r
+\r
+ @param UserHandle The handle on which the protocol is installed\r
+ @param Prot The protocol to disconnect drivers from\r
+\r
+ @retval EFI_SUCCESS Drivers using the protocol interface are all\r
+ disconnected\r
+ @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers\r
+\r
+**/\r
+EFI_STATUS\r
+UnitTestDisconnectControllersUsingProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN PROTOCOL_INTERFACE *Prot\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN ItemFound;\r
+ LIST_ENTRY *Link;\r
+ OPEN_PROTOCOL_DATA *OpenData;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Attempt to disconnect all drivers from this protocol interface\r
+ //\r
+ do {\r
+ ItemFound = FALSE;\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
+ Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ ItemFound = TRUE;\r
+ }\r
+\r
+ break;\r
+ }\r
+ }\r
+ } while (ItemFound);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Attempt to remove BY_HANDLE_PROTOCOL and GET_PROTOCOL and TEST_PROTOCOL Open List items\r
+ //\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {\r
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+ if ((OpenData->Attributes &\r
+ (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0)\r
+ {\r
+ Link = RemoveEntryList (&OpenData->Link);\r
+ Prot->OpenListCount--;\r
+ FreePool (OpenData);\r
+ } else {\r
+ Link = Link->ForwardLink;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // If there are errors or still has open items in the list, then reconnect all the drivers and return an error\r
+ //\r
+ if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {\r
+ UnitTestConnectController (UserHandle, NULL, NULL, TRUE);\r
+ Status = EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Removes Protocol from the protocol list (but not the handle list).\r
+\r
+ @param Handle The handle to remove protocol on.\r
+ @param Protocol GUID of the protocol to be moved\r
+ @param Interface The interface of the protocol\r
+\r
+ @return Protocol Entry\r
+\r
+**/\r
+PROTOCOL_INTERFACE *\r
+UnitTestRemoveInterfaceFromProtocol (\r
+ IN IHANDLE *Handle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Interface\r
+ )\r
+{\r
+ PROTOCOL_INTERFACE *Prot;\r
+ PROTOCOL_NOTIFY *ProtNotify;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+ LIST_ENTRY *Link;\r
+\r
+ Prot = UnitTestFindProtocolInterface (Handle, Protocol, Interface);\r
+ if (Prot != NULL) {\r
+ ProtEntry = Prot->Protocol;\r
+\r
+ //\r
+ // If there's a protocol notify location pointing to this entry, back it up one\r
+ //\r
+ for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
+ ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
+\r
+ if (ProtNotify->Position == &Prot->ByProtocol) {\r
+ ProtNotify->Position = Prot->ByProtocol.BackLink;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Remove the protocol interface entry\r
+ //\r
+ RemoveEntryList (&Prot->ByProtocol);\r
+ }\r
+\r
+ return Prot;\r
+}\r
+\r
+//\r
+// Boot Services Function Implementation\r
+//\r
+\r
+/**\r
+ Locate a certain GUID protocol interface in a Handle's protocols.\r
+\r
+ @param UserHandle The handle to obtain the protocol interface on\r
+ @param Protocol The GUID of the protocol\r
+\r
+ @return The requested protocol interface for the handle\r
+\r
+**/\r
+PROTOCOL_INTERFACE *\r
+UnitTestGetProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+ PROTOCOL_INTERFACE *Prot;\r
+ IHANDLE *Handle;\r
+ LIST_ENTRY *Link;\r
+\r
+ Status = UnitTestValidateHandle (UserHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ Handle = (IHANDLE *)UserHandle;\r
+\r
+ //\r
+ // Look at each protocol interface for a match\r
+ //\r
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
+ Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
+ ProtEntry = Prot->Protocol;\r
+ if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {\r
+ return Prot;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Installs a protocol interface into the boot services environment.\r
+\r
+ @param UserHandle The handle to install the protocol handler on,\r
+ or NULL if a new handle is to be allocated\r
+ @param Protocol The protocol to add to the handle\r
+ @param InterfaceType Indicates whether Interface is supplied in\r
+ native form.\r
+ @param Interface The interface for the protocol being added\r
+ @param Notify indicates whether notify the notification list\r
+ for this protocol\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate\r
+ @retval EFI_SUCCESS Protocol interface successfully installed\r
+\r
+**/\r
+EFI_STATUS\r
+UnitTestInstallProtocolInterfaceNotify (\r
+ IN OUT EFI_HANDLE *UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_INTERFACE_TYPE InterfaceType,\r
+ IN VOID *Interface,\r
+ IN BOOLEAN Notify\r
+ )\r
+{\r
+ PROTOCOL_INTERFACE *Prot;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+ IHANDLE *Handle;\r
+ EFI_STATUS Status;\r
+ VOID *ExistingInterface;\r
+\r
+ //\r
+ // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.\r
+ // Also added check for invalid UserHandle and Protocol pointers.\r
+ //\r
+ if ((UserHandle == NULL) || (Protocol == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (InterfaceType != EFI_NATIVE_INTERFACE) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Print debug message\r
+ //\r
+ UT_LOG_INFO ("InstallProtocolInterface: %g %p\n", Protocol, Interface);\r
+\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ Prot = NULL;\r
+ Handle = NULL;\r
+\r
+ if (*UserHandle != NULL) {\r
+ Status = UnitTestHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Lookup the Protocol Entry for the requested protocol\r
+ //\r
+ ProtEntry = UnitTestFindProtocolEntry (Protocol, TRUE);\r
+ if (ProtEntry == NULL) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Allocate a new protocol interface structure\r
+ //\r
+ Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));\r
+ if (Prot == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // If caller didn't supply a handle, allocate a new one\r
+ //\r
+ Handle = (IHANDLE *)*UserHandle;\r
+ if (Handle == NULL) {\r
+ Handle = AllocateZeroPool (sizeof (IHANDLE));\r
+ if (Handle == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Initialize new handler structure\r
+ //\r
+ Handle->Signature = EFI_HANDLE_SIGNATURE;\r
+ InitializeListHead (&Handle->Protocols);\r
+\r
+ //\r
+ // Initialize the Key to show that the handle has been created/modified\r
+ //\r
+ gHandleDatabaseKey++;\r
+ Handle->Key = gHandleDatabaseKey;\r
+\r
+ //\r
+ // Add this handle to the list global list of all handles\r
+ // in the system\r
+ //\r
+ InsertTailList (&gHandleList, &Handle->AllHandles);\r
+ } else {\r
+ Status = UnitTestValidateHandle (Handle);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Each interface that is added must be unique\r
+ //\r
+ ASSERT (UnitTestFindProtocolInterface (Handle, Protocol, Interface) == NULL);\r
+\r
+ //\r
+ // Initialize the protocol interface structure\r
+ //\r
+ Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;\r
+ Prot->Handle = Handle;\r
+ Prot->Protocol = ProtEntry;\r
+ Prot->Interface = Interface;\r
+\r
+ //\r
+ // Initialize OpenProtocol Data base\r
+ //\r
+ InitializeListHead (&Prot->OpenList);\r
+ Prot->OpenListCount = 0;\r
+\r
+ //\r
+ // Add this protocol interface to the head of the supported\r
+ // protocol list for this handle\r
+ //\r
+ InsertHeadList (&Handle->Protocols, &Prot->Link);\r
+\r
+ //\r
+ // Add this protocol interface to the tail of the\r
+ // protocol entry\r
+ //\r
+ InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);\r
+\r
+ //\r
+ // Notify the notification list for this protocol\r
+ //\r
+ if (Notify) {\r
+ UnitTestNotifyProtocolEntry (ProtEntry);\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+Done:\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Return the new handle back to the caller\r
+ //\r
+ *UserHandle = Handle;\r
+ } else {\r
+ //\r
+ // There was an error, clean up\r
+ //\r
+ if (Prot != NULL) {\r
+ UnitTestFreePool (Prot);\r
+ }\r
+\r
+ DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which\r
+ Calls the private one which contains a BOOLEAN parameter for notifications\r
+\r
+ @param UserHandle The handle to install the protocol handler on,\r
+ or NULL if a new handle is to be allocated\r
+ @param Protocol The protocol to add to the handle\r
+ @param InterfaceType Indicates whether Interface is supplied in\r
+ native form.\r
+ @param Interface The interface for the protocol being added\r
+\r
+ @return Status code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallProtocolInterface (\r
+ IN OUT EFI_HANDLE *UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_INTERFACE_TYPE InterfaceType,\r
+ IN VOID *Interface\r
+ )\r
+{\r
+ return UnitTestInstallProtocolInterfaceNotify (\r
+ UserHandle,\r
+ Protocol,\r
+ InterfaceType,\r
+ Interface,\r
+ TRUE\r
+ );\r
+}\r
+\r
+/**\r
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
+\r
+ @param UserHandle Handle on which the interface is to be\r
+ reinstalled\r
+ @param Protocol The numeric ID of the interface\r
+ @param OldInterface A pointer to the old interface\r
+ @param NewInterface A pointer to the new interface\r
+\r
+ @retval EFI_SUCCESS The protocol interface was installed\r
+ @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestReinstallProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *OldInterface,\r
+ IN VOID *NewInterface\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Uninstalls all instances of a protocol:interfacer from a handle.\r
+ If the last protocol interface is remove from the handle, the\r
+ handle is freed.\r
+\r
+ @param UserHandle The handle to remove the protocol handler from\r
+ @param Protocol The protocol, of protocol:interface, to remove\r
+ @param Interface The interface, of protocol:interface, to remove\r
+\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_SUCCESS Protocol interface successfully uninstalled.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUninstallProtocolInterface (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Interface\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ IHANDLE *Handle;\r
+ PROTOCOL_INTERFACE *Prot;\r
+\r
+ //\r
+ // Check that Protocol is valid\r
+ //\r
+ if (Protocol == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check that UserHandle is a valid handle\r
+ //\r
+ Status = UnitTestValidateHandle (UserHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
+ //\r
+ Prot = UnitTestFindProtocolInterface (UserHandle, Protocol, Interface);\r
+ if (Prot == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed\r
+ //\r
+ Status = UnitTestDisconnectControllersUsingProtocolInterface (\r
+ UserHandle,\r
+ Prot\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // One or more drivers refused to release, so return the error\r
+ //\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Remove the protocol interface from the protocol\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ Handle = (IHANDLE *)UserHandle;\r
+ Prot = UnitTestRemoveInterfaceFromProtocol (Handle, Protocol, Interface);\r
+\r
+ if (Prot != NULL) {\r
+ //\r
+ // Update the Key to show that the handle has been created/modified\r
+ //\r
+ gHandleDatabaseKey++;\r
+ Handle->Key = gHandleDatabaseKey;\r
+\r
+ //\r
+ // Remove the protocol interface from the handle\r
+ //\r
+ RemoveEntryList (&Prot->Link);\r
+\r
+ //\r
+ // Free the memory\r
+ //\r
+ Prot->Signature = 0;\r
+ FreePool (Prot);\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If there are no more handlers for the handle, free the handle\r
+ //\r
+ if (IsListEmpty (&Handle->Protocols)) {\r
+ Handle->Signature = 0;\r
+ RemoveEntryList (&Handle->AllHandles);\r
+ FreePool (Handle);\r
+ }\r
+\r
+Done:\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Queries a handle to determine if it supports a specified protocol.\r
+\r
+ @param UserHandle The handle being queried.\r
+ @param Protocol The published unique identifier of the protocol.\r
+ @param Interface Supplies the address where a pointer to the\r
+ corresponding Protocol Interface is returned.\r
+\r
+ @return The requested protocol interface for the handle\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestHandleProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT VOID **Interface\r
+ )\r
+{\r
+ return UnitTestOpenProtocol (\r
+ UserHandle,\r
+ Protocol,\r
+ Interface,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL\r
+ );\r
+}\r
+\r
+/**\r
+ Add a new protocol notification record for the request protocol.\r
+\r
+ @param Protocol The requested protocol to add the notify\r
+ registration\r
+ @param Event The event to signal\r
+ @param Registration Returns the registration record\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_SUCCESS Successfully returned the registration record\r
+ that has been added\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestRegisterProtocolNotify (\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_EVENT Event,\r
+ OUT VOID **Registration\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Locates the requested handle(s) and returns them in Buffer.\r
+\r
+ @param SearchType The type of search to perform to locate the\r
+ handles\r
+ @param Protocol The protocol to search for\r
+ @param SearchKey Dependant on SearchType\r
+ @param BufferSize On input the size of Buffer. On output the\r
+ size of data returned.\r
+ @param Buffer The buffer to return the results in\r
+\r
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is\r
+ returned in BufferSize.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_SUCCESS Successfully found the requested handle(s) and\r
+ returns them in Buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateHandle (\r
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
+ IN EFI_GUID *Protocol OPTIONAL,\r
+ IN VOID *SearchKey OPTIONAL,\r
+ IN OUT UINTN *BufferSize,\r
+ OUT EFI_HANDLE *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LOCATE_POSITION Position;\r
+ PROTOCOL_NOTIFY *ProtNotify;\r
+ UNIT_TEST_GET_NEXT GetNext;\r
+ UINTN ResultSize;\r
+ IHANDLE *Handle;\r
+ IHANDLE **ResultBuffer;\r
+ VOID *Interface;\r
+\r
+ if (BufferSize == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((*BufferSize > 0) && (Buffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ GetNext = NULL;\r
+\r
+ //\r
+ // Set initial position\r
+ //\r
+ Position.Protocol = Protocol;\r
+ Position.SearchKey = SearchKey;\r
+ Position.Position = &gHandleList;\r
+\r
+ ResultSize = 0;\r
+ ResultBuffer = (IHANDLE **)Buffer;\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Get the search function based on type\r
+ //\r
+ switch (SearchType) {\r
+ case AllHandles:\r
+ GetNext = UnitTestGetNextLocateAllHandles;\r
+ break;\r
+\r
+ case ByRegisterNotify:\r
+ //\r
+ // Must have SearchKey for locate ByRegisterNotify\r
+ //\r
+ if (SearchKey == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ break;\r
+ }\r
+\r
+ GetNext = UnitTestGetNextLocateByRegisterNotify;\r
+ break;\r
+\r
+ case ByProtocol:\r
+ GetNext = UnitTestGetNextLocateByProtocol;\r
+ if (Protocol == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Look up the protocol entry and set the head pointer\r
+ //\r
+ Position.ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);\r
+ if (Position.ProtEntry == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ break;\r
+ }\r
+\r
+ Position.Position = &Position.ProtEntry->Protocols;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ break;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (GetNext != NULL);\r
+ //\r
+ // Enumerate out the matching handles\r
+ //\r
+ mEfiLocateHandleRequest += 1;\r
+ for ( ; ;) {\r
+ //\r
+ // Get the next handle. If no more handles, stop\r
+ //\r
+ Handle = GetNext (&Position, &Interface);\r
+ if (NULL == Handle) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Increase the resulting buffer size, and if this handle\r
+ // fits return it\r
+ //\r
+ ResultSize += sizeof (Handle);\r
+ if (ResultSize <= *BufferSize) {\r
+ *ResultBuffer = Handle;\r
+ ResultBuffer += 1;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If the result is a zero length buffer, then there were no\r
+ // matching handles\r
+ //\r
+ if (ResultSize == 0) {\r
+ Status = EFI_NOT_FOUND;\r
+ } else {\r
+ //\r
+ // Return the resulting buffer size. If it's larger than what\r
+ // was passed, then set the error code\r
+ //\r
+ if (ResultSize > *BufferSize) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *BufferSize = ResultSize;\r
+\r
+ if ((SearchType == ByRegisterNotify) && !EFI_ERROR (Status)) {\r
+ //\r
+ // If this is a search by register notify and a handle was\r
+ // returned, update the register notification position\r
+ //\r
+ ASSERT (SearchKey != NULL);\r
+ ProtNotify = SearchKey;\r
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Locates the handle to a device on the device path that best matches the specified protocol.\r
+\r
+ @param Protocol The protocol to search for.\r
+ @param DevicePath On input, a pointer to a pointer to the device\r
+ path. On output, the device path pointer is\r
+ modified to point to the remaining part of the\r
+ devicepath.\r
+ @param Device A pointer to the returned device handle.\r
+\r
+ @retval EFI_SUCCESS The resulting handle was returned.\r
+ @retval EFI_NOT_FOUND No handles matched the search.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateDevicePath (\r
+ IN EFI_GUID *Protocol,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
+ OUT EFI_HANDLE *Device\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Boot Service called to add, modify, or remove a system configuration table from\r
+ the EFI System Table.\r
+\r
+ @param Guid Pointer to the GUID for the entry to add, update, or\r
+ remove\r
+ @param Table Pointer to the configuration table for the entry to add,\r
+ update, or remove, may be NULL.\r
+\r
+ @return EFI_SUCCESS Guid, Table pair added, updated, or removed.\r
+ @return EFI_INVALID_PARAMETER Input GUID not valid.\r
+ @return EFI_NOT_FOUND Attempted to delete non-existant entry\r
+ @return EFI_OUT_OF_RESOURCES Not enough memory available\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallConfigurationTable (\r
+ IN EFI_GUID *Guid,\r
+ IN VOID *Table\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Locates the installed protocol handler for the handle, and\r
+ invokes it to obtain the protocol interface. Usage information\r
+ is registered in the protocol data base.\r
+\r
+ @param UserHandle The handle to obtain the protocol interface on\r
+ @param Protocol The ID of the protocol\r
+ @param Interface The location to return the protocol interface\r
+ @param ImageHandle The handle of the Image that is opening the\r
+ protocol interface specified by Protocol and\r
+ Interface.\r
+ @param ControllerHandle The controller handle that is requiring this\r
+ interface.\r
+ @param Attributes The open mode of the protocol interface\r
+ specified by Handle and Protocol.\r
+\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_SUCCESS Get the protocol interface.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestOpenProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT VOID **Interface OPTIONAL,\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINT32 Attributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ PROTOCOL_INTERFACE *Prot;\r
+ LIST_ENTRY *Link;\r
+ OPEN_PROTOCOL_DATA *OpenData;\r
+ BOOLEAN ByDriver;\r
+ BOOLEAN Exclusive;\r
+ BOOLEAN Disconnect;\r
+ BOOLEAN ExactMatch;\r
+\r
+ //\r
+ // Check for invalid Protocol\r
+ //\r
+ if (Protocol == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check for invalid Interface\r
+ //\r
+ if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check for invalid UserHandle\r
+ //\r
+ Status = UnitTestValidateHandle (UserHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Check for invalid Attributes\r
+ //\r
+ switch (Attributes) {\r
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:\r
+ Status = UnitTestValidateHandle (ImageHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = UnitTestValidateHandle (ControllerHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (UserHandle == ControllerHandle) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ break;\r
+ case EFI_OPEN_PROTOCOL_BY_DRIVER:\r
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:\r
+ Status = UnitTestValidateHandle (ImageHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = UnitTestValidateHandle (ControllerHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ break;\r
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE:\r
+ Status = UnitTestValidateHandle (ImageHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ break;\r
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:\r
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL:\r
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:\r
+ break;\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Look at each protocol interface for a match\r
+ //\r
+ Prot = UnitTestGetProtocolInterface (UserHandle, Protocol);\r
+ if (Prot == NULL) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ ByDriver = FALSE;\r
+ Exclusive = FALSE;\r
+ for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+ ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&\r
+ (OpenData->Attributes == Attributes) &&\r
+ (OpenData->ControllerHandle == ControllerHandle));\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
+ ByDriver = TRUE;\r
+ if (ExactMatch) {\r
+ Status = EFI_ALREADY_STARTED;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {\r
+ Exclusive = TRUE;\r
+ } else if (ExactMatch) {\r
+ OpenData->OpenCount++;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ //\r
+ // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)\r
+ // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)\r
+ // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)\r
+ // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)\r
+ //\r
+\r
+ switch (Attributes) {\r
+ case EFI_OPEN_PROTOCOL_BY_DRIVER:\r
+ if (Exclusive || ByDriver) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:\r
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE:\r
+ if (Exclusive) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto Done;\r
+ }\r
+\r
+ if (ByDriver) {\r
+ do {\r
+ Disconnect = FALSE;\r
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
+ Disconnect = TRUE;\r
+ Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto Done;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ } while (Disconnect);\r
+ }\r
+\r
+ break;\r
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:\r
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:\r
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL:\r
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:\r
+ break;\r
+ }\r
+\r
+ if (ImageHandle == NULL) {\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Create new entry\r
+ //\r
+ OpenData = AllocatePool (sizeof (OPEN_PROTOCOL_DATA));\r
+ if (OpenData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE;\r
+ OpenData->AgentHandle = ImageHandle;\r
+ OpenData->ControllerHandle = ControllerHandle;\r
+ OpenData->Attributes = Attributes;\r
+ OpenData->OpenCount = 1;\r
+ InsertTailList (&Prot->OpenList, &OpenData->Link);\r
+ Prot->OpenListCount++;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+Done:\r
+\r
+ if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
+ //\r
+ // Keep Interface unmodified in case of any Error\r
+ // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.\r
+ //\r
+ if (!EFI_ERROR (Status) || (Status == EFI_ALREADY_STARTED)) {\r
+ //\r
+ // According to above logic, if 'Prot' is NULL, then the 'Status' must be\r
+ // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'\r
+ // must be not NULL.\r
+ //\r
+ // The ASSERT here is for addressing a false positive NULL pointer\r
+ // dereference issue raised from static analysis.\r
+ //\r
+ ASSERT (Prot != NULL);\r
+ //\r
+ // EFI_ALREADY_STARTED is not an error for bus driver.\r
+ // Return the corresponding protocol interface.\r
+ //\r
+ *Interface = Prot->Interface;\r
+ } else if (Status == EFI_UNSUPPORTED) {\r
+ //\r
+ // Return NULL Interface if Unsupported Protocol.\r
+ //\r
+ *Interface = NULL;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Closes a protocol on a handle that was opened using OpenProtocol().\r
+\r
+ @param UserHandle The handle for the protocol interface that was\r
+ previously opened with OpenProtocol(), and is\r
+ now being closed.\r
+ @param Protocol The published unique identifier of the protocol.\r
+ It is the caller's responsibility to pass in a\r
+ valid GUID.\r
+ @param AgentHandle The handle of the agent that is closing the\r
+ protocol interface.\r
+ @param ControllerHandle If the agent that opened a protocol is a driver\r
+ that follows the EFI Driver Model, then this\r
+ parameter is the controller handle that required\r
+ the protocol interface. If the agent does not\r
+ follow the EFI Driver Model, then this parameter\r
+ is optional and may be NULL.\r
+\r
+ @retval EFI_SUCCESS The protocol instance was closed.\r
+ @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a\r
+ valid EFI_HANDLE.\r
+ @retval EFI_NOT_FOUND Can not find the specified protocol or\r
+ AgentHandle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestCloseProtocol (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ IN EFI_HANDLE AgentHandle,\r
+ IN EFI_HANDLE ControllerHandle\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Return information about Opened protocols in the system\r
+\r
+ @param UserHandle The handle to close the protocol interface on\r
+ @param Protocol The ID of the protocol\r
+ @param EntryBuffer A pointer to a buffer of open protocol\r
+ information in the form of\r
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.\r
+ @param EntryCount Number of EntryBuffer entries\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestOpenProtocolInformation (\r
+ IN EFI_HANDLE UserHandle,\r
+ IN EFI_GUID *Protocol,\r
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,\r
+ OUT UINTN *EntryCount\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated\r
+ from pool.\r
+\r
+ @param UserHandle The handle from which to retrieve the list of\r
+ protocol interface GUIDs.\r
+ @param ProtocolBuffer A pointer to the list of protocol interface GUID\r
+ pointers that are installed on Handle.\r
+ @param ProtocolBufferCount A pointer to the number of GUID pointers present\r
+ in ProtocolBuffer.\r
+\r
+ @retval EFI_SUCCESS The list of protocol interface GUIDs installed\r
+ on Handle was returned in ProtocolBuffer. The\r
+ number of protocol interface GUIDs was returned\r
+ in ProtocolBufferCount.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL.\r
+ @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.\r
+ @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.\r
+ @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the\r
+ results.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestProtocolsPerHandle (\r
+ IN EFI_HANDLE UserHandle,\r
+ OUT EFI_GUID ***ProtocolBuffer,\r
+ OUT UINTN *ProtocolBufferCount\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Function returns an array of handles that support the requested protocol\r
+ in a buffer allocated from pool. This is a version of UnitTestLocateHandle()\r
+ that allocates a buffer for the caller.\r
+\r
+ @param SearchType Specifies which handle(s) are to be returned.\r
+ @param Protocol Provides the protocol to search by. This\r
+ parameter is only valid for SearchType\r
+ ByProtocol.\r
+ @param SearchKey Supplies the search key depending on the\r
+ SearchType.\r
+ @param NumberHandles The number of handles returned in Buffer.\r
+ @param Buffer A pointer to the buffer to return the requested\r
+ array of handles that support Protocol.\r
+\r
+ @retval EFI_SUCCESS The result array of handles was returned.\r
+ @retval EFI_NOT_FOUND No handles match the search.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the\r
+ matching results.\r
+ @retval EFI_INVALID_PARAMETER One or more parameters are not valid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateHandleBuffer (\r
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
+ IN EFI_GUID *Protocol OPTIONAL,\r
+ IN VOID *SearchKey OPTIONAL,\r
+ IN OUT UINTN *NumberHandles,\r
+ OUT EFI_HANDLE **Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+\r
+ if (NumberHandles == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ BufferSize = 0;\r
+ *NumberHandles = 0;\r
+ *Buffer = NULL;\r
+ Status = UnitTestLocateHandle (\r
+ SearchType,\r
+ Protocol,\r
+ SearchKey,\r
+ &BufferSize,\r
+ *Buffer\r
+ );\r
+ //\r
+ // LocateHandleBuffer() returns incorrect status code if SearchType is\r
+ // invalid.\r
+ //\r
+ // Add code to correctly handle expected errors from UnitTestLocateHandle().\r
+ //\r
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
+ if (Status != EFI_INVALID_PARAMETER) {\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+\r
+ return Status;\r
+ }\r
+\r
+ *Buffer = AllocatePool (BufferSize);\r
+ if (*Buffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = UnitTestLocateHandle (\r
+ SearchType,\r
+ Protocol,\r
+ SearchKey,\r
+ &BufferSize,\r
+ *Buffer\r
+ );\r
+\r
+ *NumberHandles = BufferSize / sizeof (EFI_HANDLE);\r
+ if (EFI_ERROR (Status)) {\r
+ *NumberHandles = 0;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Return the first Protocol Interface that matches the Protocol GUID. If\r
+ Registration is passed in, return a Protocol Instance that was just add\r
+ to the system. If Registration is NULL return the first Protocol Interface\r
+ you find.\r
+\r
+ @param Protocol The protocol to search for\r
+ @param Registration Optional Registration Key returned from\r
+ RegisterProtocolNotify()\r
+ @param Interface Return the Protocol interface (instance).\r
+\r
+ @retval EFI_SUCCESS If a valid Interface is returned\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_NOT_FOUND Protocol interface not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestLocateProtocol (\r
+ IN EFI_GUID *Protocol,\r
+ IN VOID *Registration OPTIONAL,\r
+ OUT VOID **Interface\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Installs a list of protocol interface into the boot services environment.\r
+ This function calls InstallProtocolInterface() in a loop. If any error\r
+ occurs all the protocols added by this function are removed. This is\r
+ basically a lib function to save space.\r
+\r
+ @param Handle The handle to install the protocol handlers on,\r
+ or NULL if a new handle is to be allocated\r
+ @param ... EFI_GUID followed by protocol instance. A NULL\r
+ terminates the list. The pairs are the\r
+ arguments to InstallProtocolInterface(). All the\r
+ protocols are added to Handle.\r
+\r
+ @retval EFI_SUCCESS All the protocol interface was installed.\r
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.\r
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in\r
+ the handle database.\r
+ @retval EFI_INVALID_PARAMETER Handle is NULL.\r
+ @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestInstallMultipleProtocolInterfaces (\r
+ IN OUT EFI_HANDLE *Handle,\r
+ ...\r
+ )\r
+{\r
+ return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+/**\r
+ Uninstalls a list of protocol interface in the boot services environment.\r
+ This function calls UninstallProtocolInterface() in a loop. This is\r
+ basically a lib function to save space.\r
+\r
+ @param Handle The handle to uninstall the protocol\r
+ @param ... EFI_GUID followed by protocol instance. A NULL\r
+ terminates the list. The pairs are the\r
+ arguments to UninstallProtocolInterface(). All\r
+ the protocols are added to Handle.\r
+\r
+ @return Status code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestUninstallMultipleProtocolInterfaces (\r
+ IN EFI_HANDLE Handle,\r
+ ...\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VA_LIST Args;\r
+ EFI_GUID *Protocol;\r
+ VOID *Interface;\r
+ UINTN Index;\r
+\r
+ VA_START (Args, Handle);\r
+ for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
+ //\r
+ // If protocol is NULL, then it's the end of the list\r
+ //\r
+ Protocol = VA_ARG (Args, EFI_GUID *);\r
+ if (Protocol == NULL) {\r
+ break;\r
+ }\r
+\r
+ Interface = VA_ARG (Args, VOID *);\r
+\r
+ //\r
+ // Uninstall it\r
+ //\r
+ Status = UnitTestUninstallProtocolInterface (Handle, Protocol, Interface);\r
+ }\r
+\r
+ VA_END (Args);\r
+\r
+ //\r
+ // If there was an error, add all the interfaces that were\r
+ // uninstalled without any errors\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Reset the va_arg back to the first argument.\r
+ //\r
+ VA_START (Args, Handle);\r
+ for ( ; Index > 1; Index--) {\r
+ Protocol = VA_ARG (Args, EFI_GUID *);\r
+ Interface = VA_ARG (Args, VOID *);\r
+ UnitTestInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);\r
+ }\r
+\r
+ VA_END (Args);\r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.\r
+\r
+ This file includes common header files, defines internal structure and functions used by\r
+ the library implementation.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_\r
+#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l')\r
+\r
+///\r
+/// IHANDLE - contains a list of protocol handles\r
+///\r
+typedef struct {\r
+ UINTN Signature;\r
+ /// All handles list of IHANDLE\r
+ LIST_ENTRY AllHandles;\r
+ /// List of PROTOCOL_INTERFACE's for this handle\r
+ LIST_ENTRY Protocols;\r
+ UINTN LocateRequest;\r
+ /// The Handle Database Key value when this handle was last created or modified\r
+ UINT64 Key;\r
+} IHANDLE;\r
+\r
+#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)\r
+\r
+#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e')\r
+\r
+///\r
+/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol\r
+/// database. Each handler that supports this protocol is listed, along\r
+/// with a list of registered notifies.\r
+///\r
+typedef struct {\r
+ UINTN Signature;\r
+ /// Link Entry inserted to mProtocolDatabase\r
+ LIST_ENTRY AllEntries;\r
+ /// ID of the protocol\r
+ EFI_GUID ProtocolID;\r
+ /// All protocol interfaces\r
+ LIST_ENTRY Protocols;\r
+ /// Registered notification handlers\r
+ LIST_ENTRY Notify;\r
+} PROTOCOL_ENTRY;\r
+\r
+#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c')\r
+\r
+///\r
+/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked\r
+/// with a protocol interface structure\r
+///\r
+typedef struct {\r
+ UINTN Signature;\r
+ /// Link on IHANDLE.Protocols\r
+ LIST_ENTRY Link;\r
+ /// Back pointer\r
+ IHANDLE *Handle;\r
+ /// Link on PROTOCOL_ENTRY.Protocols\r
+ LIST_ENTRY ByProtocol;\r
+ /// The protocol ID\r
+ PROTOCOL_ENTRY *Protocol;\r
+ /// The interface value\r
+ VOID *Interface;\r
+ /// OPEN_PROTOCOL_DATA list\r
+ LIST_ENTRY OpenList;\r
+ UINTN OpenListCount;\r
+} PROTOCOL_INTERFACE;\r
+\r
+#define OPEN_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('p','o','d','l')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ /// Link on PROTOCOL_INTERFACE.OpenList\r
+ LIST_ENTRY Link;\r
+\r
+ EFI_HANDLE AgentHandle;\r
+ EFI_HANDLE ControllerHandle;\r
+ UINT32 Attributes;\r
+ UINT32 OpenCount;\r
+} OPEN_PROTOCOL_DATA;\r
+\r
+#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n')\r
+\r
+///\r
+/// PROTOCOL_NOTIFY - used for each register notification for a protocol\r
+///\r
+typedef struct {\r
+ UINTN Signature;\r
+ PROTOCOL_ENTRY *Protocol;\r
+ /// All notifications for this protocol\r
+ LIST_ENTRY Link;\r
+ /// Event to notify\r
+ EFI_EVENT Event;\r
+ /// Last position notified\r
+ LIST_ENTRY *Position;\r
+} PROTOCOL_NOTIFY;\r
+\r
+typedef struct {\r
+ EFI_GUID *Protocol;\r
+ VOID *SearchKey;\r
+ LIST_ENTRY *Position;\r
+ PROTOCOL_ENTRY *ProtEntry;\r
+} LOCATE_POSITION;\r
+\r
+typedef\r
+IHANDLE *\r
+(*UNIT_TEST_GET_NEXT) (\r
+ IN OUT LOCATE_POSITION *Position,\r
+ OUT VOID **Interface\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Implementation of Task Priority Level (TPL) related services in the UEFI Boot Services table for use in unit tests.\r
+\r
+Copyright (c) Microsoft Corporation\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestUefiBootServicesTableLib.h"\r
+\r
+/**\r
+ Raise the task priority level to the new level.\r
+ High level is implemented by disabling processor interrupts.\r
+\r
+ @param NewTpl New task priority level\r
+\r
+ @return The previous task priority level\r
+\r
+**/\r
+EFI_TPL\r
+EFIAPI\r
+UnitTestRaiseTpl (\r
+ IN EFI_TPL NewTpl\r
+ )\r
+{\r
+ return TPL_APPLICATION;\r
+}\r
+\r
+/**\r
+ Lowers the task priority to the previous value. If the new\r
+ priority unmasks events at a higher priority, they are dispatched.\r
+\r
+ @param NewTpl New, lower, task priority\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestRestoreTpl (\r
+ IN EFI_TPL NewTpl\r
+ )\r
+{\r
+ return;\r
+}\r
UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf\r
UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf\r
UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf\r
+ UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf\r
\r
UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf\r
UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf\r
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf\r
DebugLib|UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf\r
MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf\r
+ UefiBootServicesTableLib|UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf\r
\r
[BuildOptions]\r
GCC:*_*_*_CC_FLAGS = -fno-pie\r