1*48704958Sjmcneill /* $NetBSD: hand.c,v 1.5 2021/09/30 19:02:48 jmcneill Exp $ */
201d0c315Sjakllsch
301d0c315Sjakllsch /*++
401d0c315Sjakllsch
501d0c315Sjakllsch Copyright (c) 1998 Intel Corporation
601d0c315Sjakllsch
701d0c315Sjakllsch Module Name:
801d0c315Sjakllsch
901d0c315Sjakllsch hand.c
1001d0c315Sjakllsch
1101d0c315Sjakllsch Abstract:
1201d0c315Sjakllsch
1301d0c315Sjakllsch
1401d0c315Sjakllsch
1501d0c315Sjakllsch
1601d0c315Sjakllsch Revision History
1701d0c315Sjakllsch
1801d0c315Sjakllsch --*/
1901d0c315Sjakllsch
2001d0c315Sjakllsch #include "lib.h"
2101d0c315Sjakllsch #include "efistdarg.h" // !!!
2201d0c315Sjakllsch
2301d0c315Sjakllsch
2401d0c315Sjakllsch EFI_STATUS
LibLocateProtocol(IN EFI_GUID * ProtocolGuid,OUT VOID ** Interface)2501d0c315Sjakllsch LibLocateProtocol (
2601d0c315Sjakllsch IN EFI_GUID *ProtocolGuid,
2701d0c315Sjakllsch OUT VOID **Interface
2801d0c315Sjakllsch )
2901d0c315Sjakllsch //
3001d0c315Sjakllsch // Find the first instance of this Protocol in the system and return it's interface
3101d0c315Sjakllsch //
3201d0c315Sjakllsch {
3301d0c315Sjakllsch EFI_STATUS Status;
3401d0c315Sjakllsch UINTN NumberHandles, Index;
3501d0c315Sjakllsch EFI_HANDLE *Handles;
3601d0c315Sjakllsch
3701d0c315Sjakllsch
3801d0c315Sjakllsch *Interface = NULL;
3901d0c315Sjakllsch Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
4001d0c315Sjakllsch if (EFI_ERROR(Status)) {
4101d0c315Sjakllsch DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
4201d0c315Sjakllsch return Status;
4301d0c315Sjakllsch }
4401d0c315Sjakllsch
4501d0c315Sjakllsch for (Index=0; Index < NumberHandles; Index++) {
4601d0c315Sjakllsch Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface);
4701d0c315Sjakllsch if (!EFI_ERROR(Status)) {
4801d0c315Sjakllsch break;
4901d0c315Sjakllsch }
5001d0c315Sjakllsch }
5101d0c315Sjakllsch
5201d0c315Sjakllsch if (Handles) {
5301d0c315Sjakllsch FreePool (Handles);
5401d0c315Sjakllsch }
5501d0c315Sjakllsch
5601d0c315Sjakllsch return Status;
5701d0c315Sjakllsch }
5801d0c315Sjakllsch
5901d0c315Sjakllsch EFI_STATUS
LibLocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType,IN EFI_GUID * Protocol OPTIONAL,IN VOID * SearchKey OPTIONAL,IN OUT UINTN * NoHandles,OUT EFI_HANDLE ** Buffer)6001d0c315Sjakllsch LibLocateHandle (
6101d0c315Sjakllsch IN EFI_LOCATE_SEARCH_TYPE SearchType,
6201d0c315Sjakllsch IN EFI_GUID *Protocol OPTIONAL,
6301d0c315Sjakllsch IN VOID *SearchKey OPTIONAL,
6401d0c315Sjakllsch IN OUT UINTN *NoHandles,
6501d0c315Sjakllsch OUT EFI_HANDLE **Buffer
6601d0c315Sjakllsch )
6701d0c315Sjakllsch
6801d0c315Sjakllsch {
6901d0c315Sjakllsch EFI_STATUS Status;
7001d0c315Sjakllsch UINTN BufferSize;
7101d0c315Sjakllsch
7201d0c315Sjakllsch //
7301d0c315Sjakllsch // Initialize for GrowBuffer loop
7401d0c315Sjakllsch //
7501d0c315Sjakllsch
7601d0c315Sjakllsch Status = EFI_SUCCESS;
7701d0c315Sjakllsch *Buffer = NULL;
7801d0c315Sjakllsch BufferSize = 50 * sizeof(EFI_HANDLE);
7901d0c315Sjakllsch
8001d0c315Sjakllsch //
8101d0c315Sjakllsch // Call the real function
8201d0c315Sjakllsch //
8301d0c315Sjakllsch
8401d0c315Sjakllsch while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
8501d0c315Sjakllsch
8601d0c315Sjakllsch Status = uefi_call_wrapper(
8701d0c315Sjakllsch BS->LocateHandle,
8801d0c315Sjakllsch 5,
8901d0c315Sjakllsch SearchType,
9001d0c315Sjakllsch Protocol,
9101d0c315Sjakllsch SearchKey,
9201d0c315Sjakllsch &BufferSize,
9301d0c315Sjakllsch *Buffer
9401d0c315Sjakllsch );
9501d0c315Sjakllsch
9601d0c315Sjakllsch }
9701d0c315Sjakllsch
9801d0c315Sjakllsch *NoHandles = BufferSize / sizeof (EFI_HANDLE);
9901d0c315Sjakllsch if (EFI_ERROR(Status)) {
10001d0c315Sjakllsch *NoHandles = 0;
10101d0c315Sjakllsch }
10201d0c315Sjakllsch
10301d0c315Sjakllsch return Status;
10401d0c315Sjakllsch }
10501d0c315Sjakllsch
10601d0c315Sjakllsch EFI_STATUS
LibLocateHandleByDiskSignature(IN UINT8 MBRType,IN UINT8 SignatureType,IN VOID * Signature,IN OUT UINTN * NoHandles,OUT EFI_HANDLE ** Buffer)10701d0c315Sjakllsch LibLocateHandleByDiskSignature (
10801d0c315Sjakllsch IN UINT8 MBRType,
10901d0c315Sjakllsch IN UINT8 SignatureType,
11001d0c315Sjakllsch IN VOID *Signature,
11101d0c315Sjakllsch IN OUT UINTN *NoHandles,
11201d0c315Sjakllsch OUT EFI_HANDLE **Buffer
11301d0c315Sjakllsch )
11401d0c315Sjakllsch
11501d0c315Sjakllsch {
11601d0c315Sjakllsch EFI_STATUS Status;
11701d0c315Sjakllsch UINTN BufferSize;
11801d0c315Sjakllsch UINTN NoBlockIoHandles;
11901d0c315Sjakllsch EFI_HANDLE *BlockIoBuffer;
12001d0c315Sjakllsch EFI_DEVICE_PATH *DevicePath;
12101d0c315Sjakllsch UINTN Index;
1224d6ac919Sjmcneill EFI_DEVICE_PATH *Next, *DevPath;
12301d0c315Sjakllsch HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
12401d0c315Sjakllsch BOOLEAN Match;
12501d0c315Sjakllsch BOOLEAN PreviousNodeIsHardDriveDevicePath;
12601d0c315Sjakllsch
12701d0c315Sjakllsch //
12801d0c315Sjakllsch // Initialize for GrowBuffer loop
12901d0c315Sjakllsch //
13001d0c315Sjakllsch
1314d6ac919Sjmcneill Status = EFI_SUCCESS;
13201d0c315Sjakllsch BlockIoBuffer = NULL;
13301d0c315Sjakllsch BufferSize = 50 * sizeof(EFI_HANDLE);
13401d0c315Sjakllsch
13501d0c315Sjakllsch //
13601d0c315Sjakllsch // Call the real function
13701d0c315Sjakllsch //
13801d0c315Sjakllsch
13901d0c315Sjakllsch while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
14001d0c315Sjakllsch
14101d0c315Sjakllsch //
14201d0c315Sjakllsch // Get list of device handles that support the BLOCK_IO Protocol.
14301d0c315Sjakllsch //
14401d0c315Sjakllsch
14501d0c315Sjakllsch Status = uefi_call_wrapper(
14601d0c315Sjakllsch BS->LocateHandle,
14701d0c315Sjakllsch 5,
14801d0c315Sjakllsch ByProtocol,
14901d0c315Sjakllsch &BlockIoProtocol,
15001d0c315Sjakllsch NULL,
15101d0c315Sjakllsch &BufferSize,
15201d0c315Sjakllsch BlockIoBuffer
15301d0c315Sjakllsch );
15401d0c315Sjakllsch
15501d0c315Sjakllsch }
15601d0c315Sjakllsch
15701d0c315Sjakllsch NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
15801d0c315Sjakllsch if (EFI_ERROR(Status)) {
15901d0c315Sjakllsch NoBlockIoHandles = 0;
16001d0c315Sjakllsch }
16101d0c315Sjakllsch
16201d0c315Sjakllsch //
16301d0c315Sjakllsch // If there was an error or there are no device handles that support
16401d0c315Sjakllsch // the BLOCK_IO Protocol, then return.
16501d0c315Sjakllsch //
16601d0c315Sjakllsch
16701d0c315Sjakllsch if (NoBlockIoHandles == 0) {
16801d0c315Sjakllsch FreePool(BlockIoBuffer);
16901d0c315Sjakllsch *NoHandles = 0;
17001d0c315Sjakllsch *Buffer = NULL;
17101d0c315Sjakllsch return Status;
17201d0c315Sjakllsch }
17301d0c315Sjakllsch
17401d0c315Sjakllsch //
17501d0c315Sjakllsch // Loop through all the device handles that support the BLOCK_IO Protocol
17601d0c315Sjakllsch //
17701d0c315Sjakllsch
17801d0c315Sjakllsch *NoHandles = 0;
17901d0c315Sjakllsch
18001d0c315Sjakllsch for(Index=0;Index<NoBlockIoHandles;Index++) {
18101d0c315Sjakllsch
18201d0c315Sjakllsch Status = uefi_call_wrapper(
18301d0c315Sjakllsch BS->HandleProtocol,
18401d0c315Sjakllsch 3,
18501d0c315Sjakllsch BlockIoBuffer[Index],
18601d0c315Sjakllsch &DevicePathProtocol,
18701d0c315Sjakllsch (VOID*)&DevicePath
18801d0c315Sjakllsch );
18901d0c315Sjakllsch
19001d0c315Sjakllsch //
19101d0c315Sjakllsch // Search DevicePath for a Hard Drive Media Device Path node.
19201d0c315Sjakllsch // If one is found, then see if it matches the signature that was
19301d0c315Sjakllsch // passed in. If it does match, and the next node is the End of the
19401d0c315Sjakllsch // device path, and the previous node is not a Hard Drive Media Device
19501d0c315Sjakllsch // Path, then we have found a match.
19601d0c315Sjakllsch //
19701d0c315Sjakllsch
19801d0c315Sjakllsch Match = FALSE;
19901d0c315Sjakllsch
20001d0c315Sjakllsch if (DevicePath != NULL) {
20101d0c315Sjakllsch
20201d0c315Sjakllsch PreviousNodeIsHardDriveDevicePath = FALSE;
20301d0c315Sjakllsch
20401d0c315Sjakllsch DevPath = DevicePath;
20501d0c315Sjakllsch
20601d0c315Sjakllsch //
20701d0c315Sjakllsch // Check for end of device path type
20801d0c315Sjakllsch //
20901d0c315Sjakllsch
21001d0c315Sjakllsch for (; ;) {
21101d0c315Sjakllsch
21201d0c315Sjakllsch if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
21301d0c315Sjakllsch (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
21401d0c315Sjakllsch
21501d0c315Sjakllsch HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
21601d0c315Sjakllsch
21701d0c315Sjakllsch if (PreviousNodeIsHardDriveDevicePath == FALSE) {
21801d0c315Sjakllsch
21901d0c315Sjakllsch Next = NextDevicePathNode(DevPath);
22001d0c315Sjakllsch if (IsDevicePathEndType(Next)) {
22101d0c315Sjakllsch if ((HardDriveDevicePath->MBRType == MBRType) &&
22201d0c315Sjakllsch (HardDriveDevicePath->SignatureType == SignatureType)) {
22301d0c315Sjakllsch switch(SignatureType) {
22401d0c315Sjakllsch case SIGNATURE_TYPE_MBR:
22501d0c315Sjakllsch if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
22601d0c315Sjakllsch Match = TRUE;
22701d0c315Sjakllsch }
22801d0c315Sjakllsch break;
22901d0c315Sjakllsch case SIGNATURE_TYPE_GUID:
23001d0c315Sjakllsch if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) {
23101d0c315Sjakllsch Match = TRUE;
23201d0c315Sjakllsch }
23301d0c315Sjakllsch break;
23401d0c315Sjakllsch }
23501d0c315Sjakllsch }
23601d0c315Sjakllsch }
23701d0c315Sjakllsch }
23801d0c315Sjakllsch PreviousNodeIsHardDriveDevicePath = TRUE;
23901d0c315Sjakllsch } else {
24001d0c315Sjakllsch PreviousNodeIsHardDriveDevicePath = FALSE;
24101d0c315Sjakllsch }
24201d0c315Sjakllsch
24301d0c315Sjakllsch if (IsDevicePathEnd(DevPath)) {
24401d0c315Sjakllsch break;
24501d0c315Sjakllsch }
24601d0c315Sjakllsch
24701d0c315Sjakllsch DevPath = NextDevicePathNode(DevPath);
24801d0c315Sjakllsch }
24901d0c315Sjakllsch
25001d0c315Sjakllsch }
25101d0c315Sjakllsch
25201d0c315Sjakllsch if (Match == FALSE) {
25301d0c315Sjakllsch BlockIoBuffer[Index] = NULL;
25401d0c315Sjakllsch } else {
25501d0c315Sjakllsch *NoHandles = *NoHandles + 1;
25601d0c315Sjakllsch }
25701d0c315Sjakllsch }
25801d0c315Sjakllsch
25901d0c315Sjakllsch //
26001d0c315Sjakllsch // If there are no matches, then return
26101d0c315Sjakllsch //
26201d0c315Sjakllsch
26301d0c315Sjakllsch if (*NoHandles == 0) {
26401d0c315Sjakllsch FreePool(BlockIoBuffer);
26501d0c315Sjakllsch *NoHandles = 0;
26601d0c315Sjakllsch *Buffer = NULL;
26701d0c315Sjakllsch return EFI_SUCCESS;
26801d0c315Sjakllsch }
26901d0c315Sjakllsch
27001d0c315Sjakllsch //
27101d0c315Sjakllsch // Allocate space for the return buffer of device handles.
27201d0c315Sjakllsch //
27301d0c315Sjakllsch
27401d0c315Sjakllsch *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
27501d0c315Sjakllsch
27601d0c315Sjakllsch if (*Buffer == NULL) {
27701d0c315Sjakllsch FreePool(BlockIoBuffer);
27801d0c315Sjakllsch *NoHandles = 0;
27901d0c315Sjakllsch *Buffer = NULL;
28001d0c315Sjakllsch return EFI_OUT_OF_RESOURCES;
28101d0c315Sjakllsch }
28201d0c315Sjakllsch
28301d0c315Sjakllsch //
28401d0c315Sjakllsch // Build list of matching device handles.
28501d0c315Sjakllsch //
28601d0c315Sjakllsch
28701d0c315Sjakllsch *NoHandles = 0;
28801d0c315Sjakllsch for(Index=0;Index<NoBlockIoHandles;Index++) {
28901d0c315Sjakllsch if (BlockIoBuffer[Index] != NULL) {
29001d0c315Sjakllsch (*Buffer)[*NoHandles] = BlockIoBuffer[Index];
29101d0c315Sjakllsch *NoHandles = *NoHandles + 1;
29201d0c315Sjakllsch }
29301d0c315Sjakllsch }
29401d0c315Sjakllsch
29501d0c315Sjakllsch FreePool(BlockIoBuffer);
29601d0c315Sjakllsch
29701d0c315Sjakllsch return EFI_SUCCESS;
29801d0c315Sjakllsch }
29901d0c315Sjakllsch
30001d0c315Sjakllsch EFI_FILE_HANDLE
LibOpenRoot(IN EFI_HANDLE DeviceHandle)30101d0c315Sjakllsch LibOpenRoot (
30201d0c315Sjakllsch IN EFI_HANDLE DeviceHandle
30301d0c315Sjakllsch )
30401d0c315Sjakllsch {
30501d0c315Sjakllsch EFI_STATUS Status;
30601d0c315Sjakllsch EFI_FILE_IO_INTERFACE *Volume;
30701d0c315Sjakllsch EFI_FILE_HANDLE File;
30801d0c315Sjakllsch
30901d0c315Sjakllsch
31001d0c315Sjakllsch //
31101d0c315Sjakllsch // File the file system interface to the device
31201d0c315Sjakllsch //
31301d0c315Sjakllsch
31401d0c315Sjakllsch Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
31501d0c315Sjakllsch
31601d0c315Sjakllsch //
31701d0c315Sjakllsch // Open the root directory of the volume
31801d0c315Sjakllsch //
31901d0c315Sjakllsch
32001d0c315Sjakllsch if (!EFI_ERROR(Status)) {
32101d0c315Sjakllsch Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File);
32201d0c315Sjakllsch }
32301d0c315Sjakllsch
32401d0c315Sjakllsch //
32501d0c315Sjakllsch // Done
32601d0c315Sjakllsch //
32701d0c315Sjakllsch
32801d0c315Sjakllsch return EFI_ERROR(Status) ? NULL : File;
32901d0c315Sjakllsch }
33001d0c315Sjakllsch
33101d0c315Sjakllsch EFI_FILE_INFO *
LibFileInfo(IN EFI_FILE_HANDLE FHand)33201d0c315Sjakllsch LibFileInfo (
33301d0c315Sjakllsch IN EFI_FILE_HANDLE FHand
33401d0c315Sjakllsch )
33501d0c315Sjakllsch {
33601d0c315Sjakllsch EFI_STATUS Status;
33701d0c315Sjakllsch EFI_FILE_INFO *Buffer;
33801d0c315Sjakllsch UINTN BufferSize;
33901d0c315Sjakllsch
34001d0c315Sjakllsch //
34101d0c315Sjakllsch // Initialize for GrowBuffer loop
34201d0c315Sjakllsch //
34301d0c315Sjakllsch
3444d6ac919Sjmcneill Status = EFI_SUCCESS;
34501d0c315Sjakllsch Buffer = NULL;
34601d0c315Sjakllsch BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
34701d0c315Sjakllsch
34801d0c315Sjakllsch //
34901d0c315Sjakllsch // Call the real function
35001d0c315Sjakllsch //
35101d0c315Sjakllsch
35201d0c315Sjakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
35301d0c315Sjakllsch Status = uefi_call_wrapper(
35401d0c315Sjakllsch FHand->GetInfo,
35501d0c315Sjakllsch 4,
35601d0c315Sjakllsch FHand,
35701d0c315Sjakllsch &GenericFileInfo,
35801d0c315Sjakllsch &BufferSize,
35901d0c315Sjakllsch Buffer
36001d0c315Sjakllsch );
36101d0c315Sjakllsch }
36201d0c315Sjakllsch
36301d0c315Sjakllsch return Buffer;
36401d0c315Sjakllsch }
36501d0c315Sjakllsch
36601d0c315Sjakllsch
36701d0c315Sjakllsch EFI_FILE_SYSTEM_INFO *
LibFileSystemInfo(IN EFI_FILE_HANDLE FHand)36801d0c315Sjakllsch LibFileSystemInfo (
36901d0c315Sjakllsch IN EFI_FILE_HANDLE FHand
37001d0c315Sjakllsch )
37101d0c315Sjakllsch {
37201d0c315Sjakllsch EFI_STATUS Status;
37301d0c315Sjakllsch EFI_FILE_SYSTEM_INFO *Buffer;
37401d0c315Sjakllsch UINTN BufferSize;
37501d0c315Sjakllsch
37601d0c315Sjakllsch //
37701d0c315Sjakllsch // Initialize for GrowBuffer loop
37801d0c315Sjakllsch //
37901d0c315Sjakllsch
3804d6ac919Sjmcneill Status = EFI_SUCCESS;
38101d0c315Sjakllsch Buffer = NULL;
38201d0c315Sjakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
38301d0c315Sjakllsch
38401d0c315Sjakllsch //
38501d0c315Sjakllsch // Call the real function
38601d0c315Sjakllsch //
38701d0c315Sjakllsch
38801d0c315Sjakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
38901d0c315Sjakllsch Status = uefi_call_wrapper(
39001d0c315Sjakllsch FHand->GetInfo,
39101d0c315Sjakllsch 4,
39201d0c315Sjakllsch FHand,
39301d0c315Sjakllsch &FileSystemInfo,
39401d0c315Sjakllsch &BufferSize,
39501d0c315Sjakllsch Buffer
39601d0c315Sjakllsch );
39701d0c315Sjakllsch }
39801d0c315Sjakllsch
39901d0c315Sjakllsch return Buffer;
40001d0c315Sjakllsch }
40101d0c315Sjakllsch
40201d0c315Sjakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
LibFileSystemVolumeLabelInfo(IN EFI_FILE_HANDLE FHand)40301d0c315Sjakllsch LibFileSystemVolumeLabelInfo (
40401d0c315Sjakllsch IN EFI_FILE_HANDLE FHand
40501d0c315Sjakllsch )
40601d0c315Sjakllsch {
40701d0c315Sjakllsch EFI_STATUS Status;
40801d0c315Sjakllsch EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
40901d0c315Sjakllsch UINTN BufferSize;
41001d0c315Sjakllsch
41101d0c315Sjakllsch //
41201d0c315Sjakllsch // Initialize for GrowBuffer loop
41301d0c315Sjakllsch //
41401d0c315Sjakllsch
4154d6ac919Sjmcneill Status = EFI_SUCCESS;
41601d0c315Sjakllsch Buffer = NULL;
41701d0c315Sjakllsch BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
41801d0c315Sjakllsch
41901d0c315Sjakllsch //
42001d0c315Sjakllsch // Call the real function
42101d0c315Sjakllsch //
42201d0c315Sjakllsch
42301d0c315Sjakllsch while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
42401d0c315Sjakllsch Status = uefi_call_wrapper(
42501d0c315Sjakllsch FHand->GetInfo,
42601d0c315Sjakllsch 4,
42701d0c315Sjakllsch FHand,
42801d0c315Sjakllsch &FileSystemVolumeLabelInfo,
42901d0c315Sjakllsch &BufferSize,
43001d0c315Sjakllsch Buffer
43101d0c315Sjakllsch );
43201d0c315Sjakllsch }
43301d0c315Sjakllsch
43401d0c315Sjakllsch return Buffer;
43501d0c315Sjakllsch }
43601d0c315Sjakllsch
43701d0c315Sjakllsch
43801d0c315Sjakllsch
43901d0c315Sjakllsch EFI_STATUS
LibInstallProtocolInterfaces(IN OUT EFI_HANDLE * Handle,...)44001d0c315Sjakllsch LibInstallProtocolInterfaces (
44101d0c315Sjakllsch IN OUT EFI_HANDLE *Handle,
44201d0c315Sjakllsch ...
44301d0c315Sjakllsch )
44401d0c315Sjakllsch {
44501d0c315Sjakllsch va_list args;
44601d0c315Sjakllsch EFI_STATUS Status;
44701d0c315Sjakllsch EFI_GUID *Protocol;
44801d0c315Sjakllsch VOID *Interface;
44901d0c315Sjakllsch EFI_TPL OldTpl;
45001d0c315Sjakllsch UINTN Index;
45101d0c315Sjakllsch EFI_HANDLE OldHandle;
45201d0c315Sjakllsch
45301d0c315Sjakllsch //
45401d0c315Sjakllsch // Syncronize with notifcations
45501d0c315Sjakllsch //
45601d0c315Sjakllsch
45701d0c315Sjakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
45801d0c315Sjakllsch OldHandle = *Handle;
45901d0c315Sjakllsch
46001d0c315Sjakllsch //
46101d0c315Sjakllsch // Install the protocol interfaces
46201d0c315Sjakllsch //
46301d0c315Sjakllsch
46401d0c315Sjakllsch Index = 0;
46501d0c315Sjakllsch Status = EFI_SUCCESS;
46601d0c315Sjakllsch va_start (args, Handle);
46701d0c315Sjakllsch
46801d0c315Sjakllsch while (!EFI_ERROR(Status)) {
46901d0c315Sjakllsch
47001d0c315Sjakllsch //
47101d0c315Sjakllsch // If protocol is NULL, then it's the end of the list
47201d0c315Sjakllsch //
47301d0c315Sjakllsch
47401d0c315Sjakllsch Protocol = va_arg(args, EFI_GUID *);
47501d0c315Sjakllsch if (!Protocol) {
47601d0c315Sjakllsch break;
47701d0c315Sjakllsch }
47801d0c315Sjakllsch
47901d0c315Sjakllsch Interface = va_arg(args, VOID *);
48001d0c315Sjakllsch
48101d0c315Sjakllsch //
48201d0c315Sjakllsch // Install it
48301d0c315Sjakllsch //
48401d0c315Sjakllsch
48501d0c315Sjakllsch DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
48601d0c315Sjakllsch Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
48701d0c315Sjakllsch if (EFI_ERROR(Status)) {
48801d0c315Sjakllsch break;
48901d0c315Sjakllsch }
49001d0c315Sjakllsch
49101d0c315Sjakllsch Index += 1;
49201d0c315Sjakllsch }
493*48704958Sjmcneill va_end (args);
49401d0c315Sjakllsch
49570763d92Schristos va_end (args);
49670763d92Schristos
49701d0c315Sjakllsch //
49801d0c315Sjakllsch // If there was an error, remove all the interfaces that were
49901d0c315Sjakllsch // installed without any errors
50001d0c315Sjakllsch //
50101d0c315Sjakllsch
50201d0c315Sjakllsch if (EFI_ERROR(Status)) {
50301d0c315Sjakllsch va_start (args, Handle);
50401d0c315Sjakllsch while (Index) {
50501d0c315Sjakllsch
50601d0c315Sjakllsch Protocol = va_arg(args, EFI_GUID *);
50701d0c315Sjakllsch Interface = va_arg(args, VOID *);
50801d0c315Sjakllsch uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface);
50901d0c315Sjakllsch
51001d0c315Sjakllsch Index -= 1;
51101d0c315Sjakllsch }
51270763d92Schristos va_end (args);
51301d0c315Sjakllsch
51401d0c315Sjakllsch *Handle = OldHandle;
515*48704958Sjmcneill va_end (args);
51601d0c315Sjakllsch }
51701d0c315Sjakllsch
51801d0c315Sjakllsch //
51901d0c315Sjakllsch // Done
52001d0c315Sjakllsch //
52101d0c315Sjakllsch
52201d0c315Sjakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
52301d0c315Sjakllsch return Status;
52401d0c315Sjakllsch }
52501d0c315Sjakllsch
52601d0c315Sjakllsch
52701d0c315Sjakllsch VOID
LibUninstallProtocolInterfaces(IN EFI_HANDLE Handle,...)52801d0c315Sjakllsch LibUninstallProtocolInterfaces (
52901d0c315Sjakllsch IN EFI_HANDLE Handle,
53001d0c315Sjakllsch ...
53101d0c315Sjakllsch )
53201d0c315Sjakllsch {
53301d0c315Sjakllsch va_list args;
53401d0c315Sjakllsch EFI_STATUS Status;
53501d0c315Sjakllsch EFI_GUID *Protocol;
53601d0c315Sjakllsch VOID *Interface;
53701d0c315Sjakllsch
53801d0c315Sjakllsch
53901d0c315Sjakllsch va_start (args, Handle);
54001d0c315Sjakllsch for (; ;) {
54101d0c315Sjakllsch
54201d0c315Sjakllsch //
54301d0c315Sjakllsch // If protocol is NULL, then it's the end of the list
54401d0c315Sjakllsch //
54501d0c315Sjakllsch
54601d0c315Sjakllsch Protocol = va_arg(args, EFI_GUID *);
54701d0c315Sjakllsch if (!Protocol) {
54801d0c315Sjakllsch break;
54901d0c315Sjakllsch }
55001d0c315Sjakllsch
55101d0c315Sjakllsch Interface = va_arg(args, VOID *);
55201d0c315Sjakllsch
55301d0c315Sjakllsch //
55401d0c315Sjakllsch // Uninstall it
55501d0c315Sjakllsch //
55601d0c315Sjakllsch
55701d0c315Sjakllsch Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface);
55801d0c315Sjakllsch if (EFI_ERROR(Status)) {
55901d0c315Sjakllsch DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
56001d0c315Sjakllsch }
56101d0c315Sjakllsch }
56270763d92Schristos va_end (args);
56301d0c315Sjakllsch }
56401d0c315Sjakllsch
56501d0c315Sjakllsch
56601d0c315Sjakllsch EFI_STATUS
LibReinstallProtocolInterfaces(IN OUT EFI_HANDLE * Handle,...)56701d0c315Sjakllsch LibReinstallProtocolInterfaces (
56801d0c315Sjakllsch IN OUT EFI_HANDLE *Handle,
56901d0c315Sjakllsch ...
57001d0c315Sjakllsch )
57101d0c315Sjakllsch {
57201d0c315Sjakllsch va_list args;
57301d0c315Sjakllsch EFI_STATUS Status;
57401d0c315Sjakllsch EFI_GUID *Protocol;
57501d0c315Sjakllsch VOID *OldInterface, *NewInterface;
57601d0c315Sjakllsch EFI_TPL OldTpl;
57701d0c315Sjakllsch UINTN Index;
57801d0c315Sjakllsch
57901d0c315Sjakllsch //
58001d0c315Sjakllsch // Syncronize with notifcations
58101d0c315Sjakllsch //
58201d0c315Sjakllsch
58301d0c315Sjakllsch OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
58401d0c315Sjakllsch
58501d0c315Sjakllsch //
58601d0c315Sjakllsch // Install the protocol interfaces
58701d0c315Sjakllsch //
58801d0c315Sjakllsch
58901d0c315Sjakllsch Index = 0;
59001d0c315Sjakllsch Status = EFI_SUCCESS;
59101d0c315Sjakllsch va_start (args, Handle);
59201d0c315Sjakllsch
59301d0c315Sjakllsch while (!EFI_ERROR(Status)) {
59401d0c315Sjakllsch
59501d0c315Sjakllsch //
59601d0c315Sjakllsch // If protocol is NULL, then it's the end of the list
59701d0c315Sjakllsch //
59801d0c315Sjakllsch
59901d0c315Sjakllsch Protocol = va_arg(args, EFI_GUID *);
60001d0c315Sjakllsch if (!Protocol) {
60101d0c315Sjakllsch break;
60201d0c315Sjakllsch }
60301d0c315Sjakllsch
60401d0c315Sjakllsch OldInterface = va_arg(args, VOID *);
60501d0c315Sjakllsch NewInterface = va_arg(args, VOID *);
60601d0c315Sjakllsch
60701d0c315Sjakllsch //
60801d0c315Sjakllsch // Reinstall it
60901d0c315Sjakllsch //
61001d0c315Sjakllsch
61101d0c315Sjakllsch Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface);
61201d0c315Sjakllsch if (EFI_ERROR(Status)) {
61301d0c315Sjakllsch break;
61401d0c315Sjakllsch }
61501d0c315Sjakllsch
61601d0c315Sjakllsch Index += 1;
61701d0c315Sjakllsch }
618*48704958Sjmcneill va_end (args);
61901d0c315Sjakllsch
62070763d92Schristos va_end (args);
62170763d92Schristos
62201d0c315Sjakllsch //
62301d0c315Sjakllsch // If there was an error, undo all the interfaces that were
62401d0c315Sjakllsch // reinstalled without any errors
62501d0c315Sjakllsch //
62601d0c315Sjakllsch
62701d0c315Sjakllsch if (EFI_ERROR(Status)) {
62801d0c315Sjakllsch va_start (args, Handle);
62901d0c315Sjakllsch while (Index) {
63001d0c315Sjakllsch
63101d0c315Sjakllsch Protocol = va_arg(args, EFI_GUID *);
63201d0c315Sjakllsch OldInterface = va_arg(args, VOID *);
63301d0c315Sjakllsch NewInterface = va_arg(args, VOID *);
63401d0c315Sjakllsch
63501d0c315Sjakllsch uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface);
63601d0c315Sjakllsch
63701d0c315Sjakllsch Index -= 1;
63801d0c315Sjakllsch }
63970763d92Schristos va_end (args);
64001d0c315Sjakllsch }
64101d0c315Sjakllsch
64201d0c315Sjakllsch //
64301d0c315Sjakllsch // Done
64401d0c315Sjakllsch //
64501d0c315Sjakllsch
64601d0c315Sjakllsch uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
64701d0c315Sjakllsch return Status;
64801d0c315Sjakllsch }
649