DxeRestExLib.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /** @file
  2. This library provides help functions for REST EX Protocol.
  3. (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Uefi.h>
  7. #include <Library/BaseMemoryLib.h>
  8. #include <Library/MemoryAllocationLib.h>
  9. #include <Library/NetLib.h>
  10. #include <Library/UefiBootServicesTableLib.h>
  11. #include <Protocol/Http.h>
  12. #include <Protocol/RestEx.h>
  13. #define REST_EX_CONFIG_DATA_LEN_UNKNOWN 0xff
  14. /**
  15. This function allows the caller to create child handle for specific
  16. REST server.
  17. @param[in] Image The image handle used to open service.
  18. @param[in] AccessMode Access mode of REST server.
  19. @param[in] ConfigType Underlying configuration to communicate with REST server.
  20. @param[in] ServiceType REST service type.
  21. @param[out] ChildInstanceHandle The handle to receive the create child.
  22. @retval EFI_SUCCESS Can't create the corresponding REST EX child instance.
  23. @retval EFI_INVALID_PARAMETERS Any of input parameters is improper.
  24. **/
  25. EFI_STATUS
  26. RestExLibCreateChild (
  27. IN EFI_HANDLE Image,
  28. IN EFI_REST_EX_SERVICE_ACCESS_MODE AccessMode,
  29. IN EFI_REST_EX_CONFIG_TYPE ConfigType,
  30. IN EFI_REST_EX_SERVICE_TYPE ServiceType,
  31. OUT EFI_HANDLE *ChildInstanceHandle
  32. )
  33. {
  34. EFI_STATUS Status;
  35. UINTN NoBuffer;
  36. EFI_HANDLE *Handle;
  37. EFI_HANDLE ChildHandle;
  38. EFI_REST_EX_PROTOCOL *RestEx;
  39. EFI_REST_EX_SERVICE_INFO *RestExServiceInfo;
  40. UINT8 LenOfConfig;
  41. if ((Image == NULL) ||
  42. (AccessMode >= EfiRestExServiceModeMax) ||
  43. (ConfigType >= EfiRestExConfigTypeMax) ||
  44. (ServiceType >= EfiRestExServiceTypeMax) ||
  45. (ChildInstanceHandle == NULL)
  46. )
  47. {
  48. return EFI_INVALID_PARAMETER;
  49. }
  50. *ChildInstanceHandle = NULL;
  51. //
  52. // Locate all REST EX binding service.
  53. //
  54. Handle = NULL;
  55. NoBuffer = 0;
  56. Status = gBS->LocateHandleBuffer (
  57. ByProtocol,
  58. &gEfiRestExServiceBindingProtocolGuid,
  59. NULL,
  60. &NoBuffer,
  61. &Handle
  62. );
  63. if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
  64. return Status;
  65. }
  66. Handle = (EFI_HANDLE *)AllocateZeroPool (sizeof (EFI_HANDLE) * NoBuffer);
  67. if (Handle == NULL) {
  68. return EFI_OUT_OF_RESOURCES;
  69. }
  70. Status = gBS->LocateHandleBuffer (
  71. ByProtocol,
  72. &gEfiRestExServiceBindingProtocolGuid,
  73. NULL,
  74. &NoBuffer,
  75. &Handle
  76. );
  77. if (EFI_ERROR (Status)) {
  78. FreePool (Handle);
  79. return Status;
  80. }
  81. //
  82. // Search for the proper REST EX instance.
  83. //
  84. while (NoBuffer != 0) {
  85. ChildHandle = NULL;
  86. Status = NetLibCreateServiceChild (
  87. *(Handle + (NoBuffer - 1)),
  88. Image,
  89. &gEfiRestExServiceBindingProtocolGuid,
  90. &ChildHandle
  91. );
  92. if (!EFI_ERROR (Status)) {
  93. Status = gBS->OpenProtocol (
  94. ChildHandle,
  95. &gEfiRestExProtocolGuid,
  96. (VOID **)&RestEx,
  97. Image,
  98. NULL,
  99. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  100. );
  101. if (EFI_ERROR (Status)) {
  102. goto ON_ERROR;
  103. }
  104. //
  105. // Get the information of REST service provided by this EFI REST EX driver
  106. //
  107. Status = RestEx->GetService (
  108. RestEx,
  109. &RestExServiceInfo
  110. );
  111. if (EFI_ERROR (Status)) {
  112. goto ON_ERROR;
  113. }
  114. //
  115. // Check REST EX property.
  116. //
  117. switch (ConfigType) {
  118. case EfiRestExConfigHttp:
  119. LenOfConfig = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA);
  120. break;
  121. case EfiRestExConfigUnspecific:
  122. LenOfConfig = REST_EX_CONFIG_DATA_LEN_UNKNOWN;
  123. break;
  124. default:
  125. goto ON_ERROR;
  126. }
  127. if ((RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceAccessMode != AccessMode) ||
  128. (RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceType != ServiceType) ||
  129. (RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigType != ConfigType) ||
  130. ((LenOfConfig != REST_EX_CONFIG_DATA_LEN_UNKNOWN) && (RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigDataLength != LenOfConfig)))
  131. {
  132. goto ON_ERROR;
  133. }
  134. }
  135. //
  136. // This is proper REST EX instance.
  137. //
  138. *ChildInstanceHandle = ChildHandle;
  139. FreePool (Handle);
  140. return EFI_SUCCESS;
  141. ON_ERROR:;
  142. NetLibDestroyServiceChild (
  143. *(Handle + (NoBuffer - 1)),
  144. Image,
  145. &gEfiRestExServiceBindingProtocolGuid,
  146. ChildHandle
  147. );
  148. NoBuffer--;
  149. }
  150. FreePool (Handle);
  151. return EFI_NOT_FOUND;
  152. }