RestJsonStructureDxe.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. /** @file
  2. The implementation of EFI REST Resource JSON to C structure convertor
  3. Protocol.
  4. (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Uefi.h>
  8. #include <Protocol/RestJsonStructure.h>
  9. #include "RestJsonStructureInternal.h"
  10. LIST_ENTRY mRestJsonStructureList;
  11. EFI_HANDLE mProtocolHandle;
  12. /**
  13. This function registers Restful resource interpreter for the
  14. specific schema.
  15. @param[in] This This is the EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  16. @param[in] JsonStructureSupported The type and version of REST JSON resource which this converter
  17. supports.
  18. @param[in] ToStructure The function to convert REST JSON resource to structure.
  19. @param[in] ToJson The function to convert REST JSON structure to JSON in text format.
  20. @param[in] DestroyStructure Destroy REST JSON structure returned in ToStructure() function.
  21. @retval EFI_SUCCESS Register successfully.
  22. @retval Others Fail to register.
  23. **/
  24. EFI_STATUS
  25. EFIAPI
  26. RestJsonStructureRegister (
  27. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  28. IN EFI_REST_JSON_STRUCTURE_SUPPORTED *JsonStructureSupported,
  29. IN EFI_REST_JSON_STRUCTURE_TO_STRUCTURE ToStructure,
  30. IN EFI_REST_JSON_STRUCTURE_TO_JSON ToJson,
  31. IN EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE DestroyStructure
  32. )
  33. {
  34. UINTN NumberOfNS;
  35. UINTN Index;
  36. LIST_ENTRY *ThisList;
  37. REST_JSON_STRUCTURE_INSTANCE *Instance;
  38. EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *CloneSupportedInterpId;
  39. EFI_REST_JSON_STRUCTURE_SUPPORTED *ThisSupportedInterp;
  40. if ((This == NULL) ||
  41. (ToStructure == NULL) ||
  42. (ToJson == NULL) ||
  43. (DestroyStructure == NULL) ||
  44. (JsonStructureSupported == NULL)
  45. )
  46. {
  47. return EFI_INVALID_PARAMETER;
  48. }
  49. //
  50. // Check how many name space interpreter can interpret.
  51. //
  52. ThisList = &JsonStructureSupported->NextSupportedRsrcInterp;
  53. NumberOfNS = 1;
  54. while (TRUE) {
  55. if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) {
  56. break;
  57. } else {
  58. ThisList = ThisList->ForwardLink;
  59. NumberOfNS++;
  60. }
  61. }
  62. Instance =
  63. (REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));
  64. if (Instance == NULL) {
  65. return EFI_OUT_OF_RESOURCES;
  66. }
  67. InitializeListHead (&Instance->NextRestJsonStructureInstance);
  68. Instance->NumberOfNameSpaceToConvert = NumberOfNS;
  69. Instance->SupportedRsrcIndentifier = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1);
  70. //
  71. // Copy supported resource identifer interpreter.
  72. //
  73. CloneSupportedInterpId = Instance->SupportedRsrcIndentifier;
  74. ThisSupportedInterp = JsonStructureSupported;
  75. for (Index = 0; Index < NumberOfNS; Index++) {
  76. CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER));
  77. ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink;
  78. CloneSupportedInterpId++;
  79. }
  80. Instance->JsonToStructure = ToStructure;
  81. Instance->StructureToJson = ToJson;
  82. Instance->DestroyStructure = DestroyStructure;
  83. InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  84. return EFI_SUCCESS;
  85. }
  86. /**
  87. This function check if this interpreter instance support the given namesapce.
  88. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  89. @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE
  90. @param[in] RsrcTypeIdentifier Resource type identifier.
  91. @param[in] ResourceRaw Given Restful resource.
  92. @param[out] RestJSonHeader Property interpreted from given ResourceRaw.
  93. @retval EFI_SUCCESS
  94. @retval Others.
  95. **/
  96. EFI_STATUS
  97. InterpreterInstanceToStruct (
  98. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  99. IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance,
  100. IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL,
  101. IN CHAR8 *ResourceRaw,
  102. OUT EFI_REST_JSON_STRUCTURE_HEADER **RestJSonHeader
  103. )
  104. {
  105. UINTN Index;
  106. EFI_STATUS Status;
  107. EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;
  108. if ((This == NULL) ||
  109. (InterpreterInstance == NULL) ||
  110. (ResourceRaw == NULL) ||
  111. (RestJSonHeader == NULL)
  112. )
  113. {
  114. return EFI_INVALID_PARAMETER;
  115. }
  116. Status = EFI_UNSUPPORTED;
  117. if (RsrcTypeIdentifier == NULL) {
  118. //
  119. // No resource type identifier, send to intepreter anyway.
  120. // Interpreter may recognize this resource.
  121. //
  122. Status = InterpreterInstance->JsonToStructure (
  123. This,
  124. NULL,
  125. ResourceRaw,
  126. RestJSonHeader
  127. );
  128. } else {
  129. //
  130. // Check if the namesapce and version is supported by this interpreter.
  131. //
  132. ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
  133. for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
  134. if (AsciiStrCmp (
  135. RsrcTypeIdentifier->NameSpace.ResourceTypeName,
  136. ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
  137. ) == 0)
  138. {
  139. if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) &&
  140. (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) &&
  141. (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL)
  142. )
  143. {
  144. //
  145. // Don't check version of this resource type identifier.
  146. //
  147. Status = InterpreterInstance->JsonToStructure (
  148. This,
  149. RsrcTypeIdentifier,
  150. ResourceRaw,
  151. RestJSonHeader
  152. );
  153. break;
  154. } else {
  155. //
  156. // Check version.
  157. //
  158. if ((AsciiStrCmp (
  159. RsrcTypeIdentifier->NameSpace.MajorVersion,
  160. ThisSupportedRsrcTypeId->NameSpace.MajorVersion
  161. ) == 0) &&
  162. (AsciiStrCmp (
  163. RsrcTypeIdentifier->NameSpace.MinorVersion,
  164. ThisSupportedRsrcTypeId->NameSpace.MinorVersion
  165. ) == 0) &&
  166. (AsciiStrCmp (
  167. RsrcTypeIdentifier->NameSpace.ErrataVersion,
  168. ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
  169. ) == 0))
  170. {
  171. Status = InterpreterInstance->JsonToStructure (
  172. This,
  173. RsrcTypeIdentifier,
  174. ResourceRaw,
  175. RestJSonHeader
  176. );
  177. break;
  178. }
  179. }
  180. }
  181. ThisSupportedRsrcTypeId++;
  182. }
  183. }
  184. return Status;
  185. }
  186. /**
  187. This function converts JSON C structure to JSON property.
  188. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  189. @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE
  190. @param[in] RestJSonHeader Resource type identifier.
  191. @param[out] ResourceRaw Output in JSON text format.
  192. @retval EFI_SUCCESS
  193. @retval Others.
  194. **/
  195. EFI_STATUS
  196. InterpreterEfiStructToInstance (
  197. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  198. IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance,
  199. IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader,
  200. OUT CHAR8 **ResourceRaw
  201. )
  202. {
  203. UINTN Index;
  204. EFI_STATUS Status;
  205. EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;
  206. EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier;
  207. if ((This == NULL) ||
  208. (InterpreterInstance == NULL) ||
  209. (RestJSonHeader == NULL) ||
  210. (ResourceRaw == NULL)
  211. )
  212. {
  213. return EFI_INVALID_PARAMETER;
  214. }
  215. RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier;
  216. if ((RsrcTypeIdentifier == NULL) ||
  217. (RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL) ||
  218. (RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) ||
  219. (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) ||
  220. (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL)
  221. )
  222. {
  223. return EFI_INVALID_PARAMETER;
  224. }
  225. //
  226. // Check if the namesapce and version is supported by this interpreter.
  227. //
  228. Status = EFI_UNSUPPORTED;
  229. ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
  230. for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
  231. if (AsciiStrCmp (
  232. RsrcTypeIdentifier->NameSpace.ResourceTypeName,
  233. ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
  234. ) == 0)
  235. {
  236. //
  237. // Check version.
  238. //
  239. if ((AsciiStrCmp (
  240. RsrcTypeIdentifier->NameSpace.MajorVersion,
  241. ThisSupportedRsrcTypeId->NameSpace.MajorVersion
  242. ) == 0) &&
  243. (AsciiStrCmp (
  244. RsrcTypeIdentifier->NameSpace.MinorVersion,
  245. ThisSupportedRsrcTypeId->NameSpace.MinorVersion
  246. ) == 0) &&
  247. (AsciiStrCmp (
  248. RsrcTypeIdentifier->NameSpace.ErrataVersion,
  249. ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
  250. ) == 0))
  251. {
  252. Status = InterpreterInstance->StructureToJson (
  253. This,
  254. RestJSonHeader,
  255. ResourceRaw
  256. );
  257. break;
  258. }
  259. }
  260. ThisSupportedRsrcTypeId++;
  261. }
  262. return Status;
  263. }
  264. /**
  265. This function destory REST property structure.
  266. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  267. @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE
  268. @param[in] RestJSonHeader Property interpreted from given ResourceRaw.
  269. @retval EFI_SUCCESS
  270. @retval Others.
  271. **/
  272. EFI_STATUS
  273. InterpreterInstanceDestoryJsonStruct (
  274. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  275. IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance,
  276. IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader
  277. )
  278. {
  279. UINTN Index;
  280. EFI_STATUS Status;
  281. EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId;
  282. if ((This == NULL) ||
  283. (InterpreterInstance == NULL) ||
  284. (RestJSonHeader == NULL)
  285. )
  286. {
  287. return EFI_INVALID_PARAMETER;
  288. }
  289. Status = EFI_UNSUPPORTED;
  290. //
  291. // Check if the namesapce and version is supported by this interpreter.
  292. //
  293. ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
  294. for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
  295. if (AsciiStrCmp (
  296. RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName,
  297. ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName
  298. ) == 0)
  299. {
  300. if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) &&
  301. (RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) &&
  302. (RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL)
  303. )
  304. {
  305. //
  306. // Don't check version of this resource type identifier.
  307. //
  308. Status = InterpreterInstance->DestroyStructure (
  309. This,
  310. RestJSonHeader
  311. );
  312. break;
  313. } else {
  314. //
  315. // Check version.
  316. //
  317. if ((AsciiStrCmp (
  318. RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion,
  319. ThisSupportedRsrcTypeId->NameSpace.MajorVersion
  320. ) == 0) &&
  321. (AsciiStrCmp (
  322. RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion,
  323. ThisSupportedRsrcTypeId->NameSpace.MinorVersion
  324. ) == 0) &&
  325. (AsciiStrCmp (
  326. RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion,
  327. ThisSupportedRsrcTypeId->NameSpace.ErrataVersion
  328. ) == 0))
  329. {
  330. Status = InterpreterInstance->DestroyStructure (
  331. This,
  332. RestJSonHeader
  333. );
  334. break;
  335. }
  336. }
  337. }
  338. ThisSupportedRsrcTypeId++;
  339. }
  340. return Status;
  341. }
  342. /**
  343. This function translates the given JSON text to JSON C Structure.
  344. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  345. @param[in] RsrcTypeIdentifier Resource type identifier.
  346. @param[in] ResourceJsonText Given Restful resource.
  347. @param[out] JsonStructure Property interpreted from given ResourceRaw.
  348. @retval EFI_SUCCESS
  349. @retval Others.
  350. **/
  351. EFI_STATUS
  352. EFIAPI
  353. RestJsonStructureToStruct (
  354. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  355. IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL,
  356. IN CHAR8 *ResourceJsonText,
  357. OUT EFI_REST_JSON_STRUCTURE_HEADER **JsonStructure
  358. )
  359. {
  360. EFI_STATUS Status;
  361. REST_JSON_STRUCTURE_INSTANCE *Instance;
  362. if ((This == NULL) ||
  363. (ResourceJsonText == NULL) ||
  364. (JsonStructure == NULL)
  365. )
  366. {
  367. return EFI_INVALID_PARAMETER;
  368. }
  369. if (IsListEmpty (&mRestJsonStructureList)) {
  370. return EFI_UNSUPPORTED;
  371. }
  372. Status = EFI_SUCCESS;
  373. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  374. while (TRUE) {
  375. Status = InterpreterInstanceToStruct (
  376. This,
  377. Instance,
  378. RsrcTypeIdentifier,
  379. ResourceJsonText,
  380. JsonStructure
  381. );
  382. if (!EFI_ERROR (Status)) {
  383. break;
  384. }
  385. if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
  386. Status = EFI_UNSUPPORTED;
  387. break;
  388. }
  389. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  390. }
  391. return Status;
  392. }
  393. /**
  394. This function destory REST property EFI structure which returned in
  395. JsonToStructure().
  396. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  397. @param[in] RestJSonHeader Property to destory.
  398. @retval EFI_SUCCESS
  399. @retval Others
  400. **/
  401. EFI_STATUS
  402. EFIAPI
  403. RestJsonStructureDestroyStruct (
  404. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  405. IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader
  406. )
  407. {
  408. EFI_STATUS Status;
  409. REST_JSON_STRUCTURE_INSTANCE *Instance;
  410. if ((This == NULL) || (RestJSonHeader == NULL)) {
  411. return EFI_INVALID_PARAMETER;
  412. }
  413. if (IsListEmpty (&mRestJsonStructureList)) {
  414. return EFI_UNSUPPORTED;
  415. }
  416. Status = EFI_SUCCESS;
  417. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  418. while (TRUE) {
  419. Status = InterpreterInstanceDestoryJsonStruct (
  420. This,
  421. Instance,
  422. RestJSonHeader
  423. );
  424. if (!EFI_ERROR (Status)) {
  425. break;
  426. }
  427. if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
  428. Status = EFI_UNSUPPORTED;
  429. break;
  430. }
  431. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  432. }
  433. return Status;
  434. }
  435. /**
  436. This function translates the given JSON C Structure to JSON text.
  437. @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance.
  438. @param[in] RestJSonHeader Given Restful resource.
  439. @param[out] ResourceRaw Resource in RESTfuls service oriented.
  440. @retval EFI_SUCCESS
  441. @retval Others Fail to remove the entry
  442. **/
  443. EFI_STATUS
  444. EFIAPI
  445. RestJsonStructureToJson (
  446. IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This,
  447. IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader,
  448. OUT CHAR8 **ResourceRaw
  449. )
  450. {
  451. EFI_STATUS Status;
  452. REST_JSON_STRUCTURE_INSTANCE *Instance;
  453. if ((This == NULL) || (RestJSonHeader == NULL) || (ResourceRaw == NULL)) {
  454. return EFI_INVALID_PARAMETER;
  455. }
  456. if (IsListEmpty (&mRestJsonStructureList)) {
  457. return EFI_UNSUPPORTED;
  458. }
  459. Status = EFI_SUCCESS;
  460. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  461. while (TRUE) {
  462. Status = InterpreterEfiStructToInstance (
  463. This,
  464. Instance,
  465. RestJSonHeader,
  466. ResourceRaw
  467. );
  468. if (!EFI_ERROR (Status)) {
  469. break;
  470. }
  471. if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
  472. Status = EFI_UNSUPPORTED;
  473. break;
  474. }
  475. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  476. }
  477. return Status;
  478. }
  479. EFI_REST_JSON_STRUCTURE_PROTOCOL mRestJsonStructureProtocol = {
  480. RestJsonStructureRegister,
  481. RestJsonStructureToStruct,
  482. RestJsonStructureToJson,
  483. RestJsonStructureDestroyStruct
  484. };
  485. /**
  486. This is the declaration of an EFI image entry point.
  487. @param ImageHandle The firmware allocated handle for the UEFI image.
  488. @param SystemTable A pointer to the EFI System Table.
  489. @retval EFI_SUCCESS The operation completed successfully.
  490. @retval Others An unexpected error occurred.
  491. **/
  492. EFI_STATUS
  493. EFIAPI
  494. RestJsonStructureEntryPoint (
  495. IN EFI_HANDLE ImageHandle,
  496. IN EFI_SYSTEM_TABLE *SystemTable
  497. )
  498. {
  499. EFI_STATUS Status;
  500. InitializeListHead (&mRestJsonStructureList);
  501. //
  502. // Install the Restful Resource Interpreter Protocol.
  503. //
  504. mProtocolHandle = NULL;
  505. Status = gBS->InstallProtocolInterface (
  506. &mProtocolHandle,
  507. &gEfiRestJsonStructureProtocolGuid,
  508. EFI_NATIVE_INTERFACE,
  509. (VOID *)&mRestJsonStructureProtocol
  510. );
  511. return Status;
  512. }
  513. /**
  514. This is the unload handle for Redfish discover module.
  515. Disconnect the driver specified by ImageHandle from all the devices in the handle database.
  516. Uninstall all the protocols installed in the driver entry point.
  517. @param[in] ImageHandle The drivers' driver image.
  518. @retval EFI_SUCCESS The image is unloaded.
  519. @retval Others Failed to unload the image.
  520. **/
  521. EFI_STATUS
  522. EFIAPI
  523. RestJsonStructureUnload (
  524. IN EFI_HANDLE ImageHandle
  525. )
  526. {
  527. EFI_STATUS Status;
  528. REST_JSON_STRUCTURE_INSTANCE *Instance;
  529. REST_JSON_STRUCTURE_INSTANCE *NextInstance;
  530. Status = gBS->UninstallProtocolInterface (
  531. mProtocolHandle,
  532. &gEfiRestJsonStructureProtocolGuid,
  533. (VOID *)&mRestJsonStructureProtocol
  534. );
  535. if (IsListEmpty (&mRestJsonStructureList)) {
  536. return Status;
  537. }
  538. //
  539. // Free memory of REST_JSON_STRUCTURE_INSTANCE instance.
  540. //
  541. Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList);
  542. do {
  543. NextInstance = NULL;
  544. if (!IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) {
  545. NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance);
  546. }
  547. FreePool ((VOID *)Instance);
  548. Instance = NextInstance;
  549. } while (Instance != NULL);
  550. return Status;
  551. }