/** @file This library provides help functions for REST EX Protocol. (C) Copyright 2020 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #define REST_EX_CONFIG_DATA_LEN_UNKNOWN 0xff /** This function allows the caller to create child handle for specific REST server. @param[in] Image The image handle used to open service. @param[in] AccessMode Access mode of REST server. @param[in] ConfigType Underlying configuration to communicate with REST server. @param[in] ServiceType REST service type. @param[out] ChildInstanceHandle The handle to receive the create child. @retval EFI_SUCCESS Can't create the corresponding REST EX child instance. @retval EFI_INVALID_PARAMETERS Any of input parameters is improper. **/ EFI_STATUS RestExLibCreateChild ( IN EFI_HANDLE Image, IN EFI_REST_EX_SERVICE_ACCESS_MODE AccessMode, IN EFI_REST_EX_CONFIG_TYPE ConfigType, IN EFI_REST_EX_SERVICE_TYPE ServiceType, OUT EFI_HANDLE *ChildInstanceHandle ) { EFI_STATUS Status; UINTN NoBuffer; EFI_HANDLE *Handle; EFI_HANDLE ChildHandle; EFI_REST_EX_PROTOCOL *RestEx; EFI_REST_EX_SERVICE_INFO *RestExServiceInfo; UINT8 LenOfConfig; if (Image == NULL || AccessMode >= EfiRestExServiceModeMax || ConfigType >= EfiRestExConfigTypeMax || ServiceType >= EfiRestExServiceTypeMax || ChildInstanceHandle == NULL ) { return EFI_INVALID_PARAMETER; } *ChildInstanceHandle = NULL; // // Locate all REST EX binding service. // Handle = NULL; NoBuffer = 0; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiRestExServiceBindingProtocolGuid, NULL, &NoBuffer, &Handle ); if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { return Status; } Handle = (EFI_HANDLE *)AllocateZeroPool (sizeof(EFI_HANDLE) * NoBuffer); if (Handle == NULL) { return EFI_OUT_OF_RESOURCES; } Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiRestExServiceBindingProtocolGuid, NULL, &NoBuffer, &Handle ); if (EFI_ERROR (Status)) { FreePool (Handle); return Status; } // // Search for the proper REST EX instance. // while (NoBuffer != 0) { ChildHandle = NULL; Status = NetLibCreateServiceChild ( *(Handle + (NoBuffer - 1)), Image, &gEfiRestExServiceBindingProtocolGuid, &ChildHandle ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( ChildHandle, &gEfiRestExProtocolGuid, (VOID **)&RestEx, Image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Get the information of REST service provided by this EFI REST EX driver // Status = RestEx->GetService ( RestEx, &RestExServiceInfo ); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Check REST EX property. // switch (ConfigType) { case EfiRestExConfigHttp: LenOfConfig = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA); break; case EfiRestExConfigUnspecific: LenOfConfig = REST_EX_CONFIG_DATA_LEN_UNKNOWN; break; default: goto ON_ERROR; } if (RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceAccessMode != AccessMode || RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceType != ServiceType || RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigType != ConfigType || ((LenOfConfig != REST_EX_CONFIG_DATA_LEN_UNKNOWN) && (RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigDataLength != LenOfConfig))) { goto ON_ERROR; } } // // This is proper REST EX instance. // *ChildInstanceHandle = ChildHandle; FreePool (Handle); return EFI_SUCCESS; ON_ERROR:; NetLibDestroyServiceChild ( *(Handle + (NoBuffer - 1)), Image, &gEfiRestExServiceBindingProtocolGuid, ChildHandle ); NoBuffer --; }; FreePool (Handle); return EFI_NOT_FOUND; }