/* Parse the FFS and find the GUID address. There may be multiple Guids matching the searched Guid. */
EFI_STATUS GetAddressByGuid(IN VOID *Ffs, IN EFI_GUID *Guid, IN UINTN Length, OUT UINTN **Offset, OUT UINT8 *NumOfMatchingGuid)
/* Parse the FFS and find the GUID address. There may be multiple Guids matching the searched Guid. */
EFI_STATUS GetAddressByGuid(IN VOID *Ffs, IN EFI_GUID *Guid, IN UINTN Length, OUT UINTN **Offset, OUT UINT8 *NumOfMatchingGuid)
{
  UINTN    LoopControl;
  BOOLEAN  Found;
  if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) {
    return EFI_NOT_FOUND;
  }
  if (NumOfMatchingGuid != NULL) {
    *NumOfMatchingGuid = 0;
  }
  Found = FALSE;
  for (LoopControl = 0; LoopControl < Length; LoopControl++) {
    if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) {
      Found = TRUE;
      if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {
        if (*NumOfMatchingGuid == 0) {
          *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
          ASSERT (*Offset != NULL);
        }
        *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);
        (*NumOfMatchingGuid)++;
      } else {
        break;
      }
    }
  }
  return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
}