| /** @file | |
| The implementation of EFI REST Resource JSON to C structure convertor | |
| Protocol. | |
| (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <Uefi.h> | |
| #include <Protocol/RestJsonStructure.h> | |
| #include "RestJsonStructureInternal.h" | |
| LIST_ENTRY mRestJsonStructureList; | |
| EFI_HANDLE mProtocolHandle; | |
| /** | |
| This function registers Restful resource interpreter for the | |
| specific schema. | |
| @param[in] This This is the EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] JsonStructureSupported The type and version of REST JSON resource which this converter | |
| supports. | |
| @param[in] ToStructure The function to convert REST JSON resource to structure. | |
| @param[in] ToJson The function to convert REST JSON structure to JSON in text format. | |
| @param[in] DestroyStructure Destroy REST JSON structure returned in ToStructure() function. | |
| @retval EFI_SUCCESS Register successfully. | |
| @retval Others Fail to register. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureRegister ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN EFI_REST_JSON_STRUCTURE_SUPPORTED *JsonStructureSupported, | |
| IN EFI_REST_JSON_STRUCTURE_TO_STRUCTURE ToStructure, | |
| IN EFI_REST_JSON_STRUCTURE_TO_JSON ToJson, | |
| IN EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE DestroyStructure | |
| ) | |
| { | |
| UINTN NumberOfNS; | |
| UINTN Index; | |
| LIST_ENTRY *ThisList; | |
| REST_JSON_STRUCTURE_INSTANCE *Instance; | |
| EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *CloneSupportedInterpId; | |
| EFI_REST_JSON_STRUCTURE_SUPPORTED *ThisSupportedInterp; | |
| if ((This == NULL) || | |
| (ToStructure == NULL) || | |
| (ToJson == NULL) || | |
| (DestroyStructure == NULL) || | |
| (JsonStructureSupported == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| // | |
| // Check how many name space interpreter can interpret. | |
| // | |
| ThisList = &JsonStructureSupported->NextSupportedRsrcInterp; | |
| NumberOfNS = 1; | |
| while (TRUE) { | |
| if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) { | |
| break; | |
| } else { | |
| ThisList = ThisList->ForwardLink; | |
| NumberOfNS++; | |
| } | |
| } | |
| Instance = | |
| (REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); | |
| if (Instance == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| InitializeListHead (&Instance->NextRestJsonStructureInstance); | |
| Instance->NumberOfNameSpaceToConvert = NumberOfNS; | |
| Instance->SupportedRsrcIndentifier = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1); | |
| // | |
| // Copy supported resource identifer interpreter. | |
| // | |
| CloneSupportedInterpId = Instance->SupportedRsrcIndentifier; | |
| ThisSupportedInterp = JsonStructureSupported; | |
| for (Index = 0; Index < NumberOfNS; Index++) { | |
| CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); | |
| ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink; | |
| CloneSupportedInterpId++; | |
| } | |
| Instance->JsonToStructure = ToStructure; | |
| Instance->StructureToJson = ToJson; | |
| Instance->DestroyStructure = DestroyStructure; | |
| InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| This function check if this interpreter instance support the given namesapce. | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
| @param[in] RsrcTypeIdentifier Resource type identifier. | |
| @param[in] ResourceRaw Given Restful resource. | |
| @param[out] RestJSonHeader Property interpreted from given ResourceRaw. | |
| @retval EFI_SUCCESS | |
| @retval Others. | |
| **/ | |
| EFI_STATUS | |
| InterpreterInstanceToStruct ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
| IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, | |
| IN CHAR8 *ResourceRaw, | |
| OUT EFI_REST_JSON_STRUCTURE_HEADER **RestJSonHeader | |
| ) | |
| { | |
| UINTN Index; | |
| EFI_STATUS Status; | |
| EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
| if ((This == NULL) || | |
| (InterpreterInstance == NULL) || | |
| (ResourceRaw == NULL) || | |
| (RestJSonHeader == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EFI_UNSUPPORTED; | |
| if (RsrcTypeIdentifier == NULL) { | |
| // | |
| // No resource type identifier, send to intepreter anyway. | |
| // Interpreter may recognize this resource. | |
| // | |
| Status = InterpreterInstance->JsonToStructure ( | |
| This, | |
| NULL, | |
| ResourceRaw, | |
| RestJSonHeader | |
| ); | |
| } else { | |
| // | |
| // Check if the namesapce and version is supported by this interpreter. | |
| // | |
| ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
| for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
| if (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.ResourceTypeName, | |
| ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
| ) == 0) | |
| { | |
| if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) && | |
| (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) && | |
| (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL) | |
| ) | |
| { | |
| // | |
| // Don't check version of this resource type identifier. | |
| // | |
| Status = InterpreterInstance->JsonToStructure ( | |
| This, | |
| RsrcTypeIdentifier, | |
| ResourceRaw, | |
| RestJSonHeader | |
| ); | |
| break; | |
| } else { | |
| // | |
| // Check version. | |
| // | |
| if ((AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.MajorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.MinorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.ErrataVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
| ) == 0)) | |
| { | |
| Status = InterpreterInstance->JsonToStructure ( | |
| This, | |
| RsrcTypeIdentifier, | |
| ResourceRaw, | |
| RestJSonHeader | |
| ); | |
| break; | |
| } | |
| } | |
| } | |
| ThisSupportedRsrcTypeId++; | |
| } | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function converts JSON C structure to JSON property. | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
| @param[in] RestJSonHeader Resource type identifier. | |
| @param[out] ResourceRaw Output in JSON text format. | |
| @retval EFI_SUCCESS | |
| @retval Others. | |
| **/ | |
| EFI_STATUS | |
| InterpreterEfiStructToInstance ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
| IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, | |
| OUT CHAR8 **ResourceRaw | |
| ) | |
| { | |
| UINTN Index; | |
| EFI_STATUS Status; | |
| EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
| EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier; | |
| if ((This == NULL) || | |
| (InterpreterInstance == NULL) || | |
| (RestJSonHeader == NULL) || | |
| (ResourceRaw == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier; | |
| if ((RsrcTypeIdentifier == NULL) || | |
| (RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL) || | |
| (RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) || | |
| (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) || | |
| (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| // | |
| // Check if the namesapce and version is supported by this interpreter. | |
| // | |
| Status = EFI_UNSUPPORTED; | |
| ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
| for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
| if (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.ResourceTypeName, | |
| ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
| ) == 0) | |
| { | |
| // | |
| // Check version. | |
| // | |
| if ((AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.MajorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.MinorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RsrcTypeIdentifier->NameSpace.ErrataVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
| ) == 0)) | |
| { | |
| Status = InterpreterInstance->StructureToJson ( | |
| This, | |
| RestJSonHeader, | |
| ResourceRaw | |
| ); | |
| break; | |
| } | |
| } | |
| ThisSupportedRsrcTypeId++; | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function destory REST property structure. | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE | |
| @param[in] RestJSonHeader Property interpreted from given ResourceRaw. | |
| @retval EFI_SUCCESS | |
| @retval Others. | |
| **/ | |
| EFI_STATUS | |
| InterpreterInstanceDestoryJsonStruct ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, | |
| IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader | |
| ) | |
| { | |
| UINTN Index; | |
| EFI_STATUS Status; | |
| EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; | |
| if ((This == NULL) || | |
| (InterpreterInstance == NULL) || | |
| (RestJSonHeader == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EFI_UNSUPPORTED; | |
| // | |
| // Check if the namesapce and version is supported by this interpreter. | |
| // | |
| ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; | |
| for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) { | |
| if (AsciiStrCmp ( | |
| RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName, | |
| ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName | |
| ) == 0) | |
| { | |
| if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) && | |
| (RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) && | |
| (RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL) | |
| ) | |
| { | |
| // | |
| // Don't check version of this resource type identifier. | |
| // | |
| Status = InterpreterInstance->DestroyStructure ( | |
| This, | |
| RestJSonHeader | |
| ); | |
| break; | |
| } else { | |
| // | |
| // Check version. | |
| // | |
| if ((AsciiStrCmp ( | |
| RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MajorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.MinorVersion | |
| ) == 0) && | |
| (AsciiStrCmp ( | |
| RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion, | |
| ThisSupportedRsrcTypeId->NameSpace.ErrataVersion | |
| ) == 0)) | |
| { | |
| Status = InterpreterInstance->DestroyStructure ( | |
| This, | |
| RestJSonHeader | |
| ); | |
| break; | |
| } | |
| } | |
| } | |
| ThisSupportedRsrcTypeId++; | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function translates the given JSON text to JSON C Structure. | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] RsrcTypeIdentifier Resource type identifier. | |
| @param[in] ResourceJsonText Given Restful resource. | |
| @param[out] JsonStructure Property interpreted from given ResourceRaw. | |
| @retval EFI_SUCCESS | |
| @retval Others. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureToStruct ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, | |
| IN CHAR8 *ResourceJsonText, | |
| OUT EFI_REST_JSON_STRUCTURE_HEADER **JsonStructure | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| REST_JSON_STRUCTURE_INSTANCE *Instance; | |
| if ((This == NULL) || | |
| (ResourceJsonText == NULL) || | |
| (JsonStructure == NULL) | |
| ) | |
| { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (IsListEmpty (&mRestJsonStructureList)) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| Status = EFI_SUCCESS; | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
| while (TRUE) { | |
| Status = InterpreterInstanceToStruct ( | |
| This, | |
| Instance, | |
| RsrcTypeIdentifier, | |
| ResourceJsonText, | |
| JsonStructure | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| break; | |
| } | |
| if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
| Status = EFI_UNSUPPORTED; | |
| break; | |
| } | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function destory REST property EFI structure which returned in | |
| JsonToStructure(). | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] RestJSonHeader Property to destory. | |
| @retval EFI_SUCCESS | |
| @retval Others | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureDestroyStruct ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| REST_JSON_STRUCTURE_INSTANCE *Instance; | |
| if ((This == NULL) || (RestJSonHeader == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (IsListEmpty (&mRestJsonStructureList)) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| Status = EFI_SUCCESS; | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
| while (TRUE) { | |
| Status = InterpreterInstanceDestoryJsonStruct ( | |
| This, | |
| Instance, | |
| RestJSonHeader | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| break; | |
| } | |
| if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
| Status = EFI_UNSUPPORTED; | |
| break; | |
| } | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function translates the given JSON C Structure to JSON text. | |
| @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. | |
| @param[in] RestJSonHeader Given Restful resource. | |
| @param[out] ResourceRaw Resource in RESTfuls service oriented. | |
| @retval EFI_SUCCESS | |
| @retval Others Fail to remove the entry | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureToJson ( | |
| IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, | |
| IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, | |
| OUT CHAR8 **ResourceRaw | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| REST_JSON_STRUCTURE_INSTANCE *Instance; | |
| if ((This == NULL) || (RestJSonHeader == NULL) || (ResourceRaw == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (IsListEmpty (&mRestJsonStructureList)) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| Status = EFI_SUCCESS; | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
| while (TRUE) { | |
| Status = InterpreterEfiStructToInstance ( | |
| This, | |
| Instance, | |
| RestJSonHeader, | |
| ResourceRaw | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| break; | |
| } | |
| if (IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
| Status = EFI_UNSUPPORTED; | |
| break; | |
| } | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
| } | |
| return Status; | |
| } | |
| EFI_REST_JSON_STRUCTURE_PROTOCOL mRestJsonStructureProtocol = { | |
| RestJsonStructureRegister, | |
| RestJsonStructureToStruct, | |
| RestJsonStructureToJson, | |
| RestJsonStructureDestroyStruct | |
| }; | |
| /** | |
| This is the declaration of an EFI image entry point. | |
| @param ImageHandle The firmware allocated handle for the UEFI image. | |
| @param SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The operation completed successfully. | |
| @retval Others An unexpected error occurred. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureEntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| InitializeListHead (&mRestJsonStructureList); | |
| // | |
| // Install the Restful Resource Interpreter Protocol. | |
| // | |
| mProtocolHandle = NULL; | |
| Status = gBS->InstallProtocolInterface ( | |
| &mProtocolHandle, | |
| &gEfiRestJsonStructureProtocolGuid, | |
| EFI_NATIVE_INTERFACE, | |
| (VOID *)&mRestJsonStructureProtocol | |
| ); | |
| return Status; | |
| } | |
| /** | |
| This is the unload handle for Redfish discover module. | |
| Disconnect the driver specified by ImageHandle from all the devices in the handle database. | |
| Uninstall all the protocols installed in the driver entry point. | |
| @param[in] ImageHandle The drivers' driver image. | |
| @retval EFI_SUCCESS The image is unloaded. | |
| @retval Others Failed to unload the image. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| RestJsonStructureUnload ( | |
| IN EFI_HANDLE ImageHandle | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| REST_JSON_STRUCTURE_INSTANCE *Instance; | |
| REST_JSON_STRUCTURE_INSTANCE *NextInstance; | |
| Status = gBS->UninstallProtocolInterface ( | |
| mProtocolHandle, | |
| &gEfiRestJsonStructureProtocolGuid, | |
| (VOID *)&mRestJsonStructureProtocol | |
| ); | |
| if (IsListEmpty (&mRestJsonStructureList)) { | |
| return Status; | |
| } | |
| // | |
| // Free memory of REST_JSON_STRUCTURE_INSTANCE instance. | |
| // | |
| Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); | |
| do { | |
| NextInstance = NULL; | |
| if (!IsNodeAtEnd (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { | |
| NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); | |
| } | |
| FreePool ((VOID *)Instance); | |
| Instance = NextInstance; | |
| } while (Instance != NULL); | |
| return Status; | |
| } |