Reviewed-by: Fu Siyuan <[email protected]>

> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, February 24, 2016 3:40 PM
> To: [email protected]
> Cc: Ni, Ruiyu <[email protected]>; Fu, Siyuan <[email protected]>
> Subject: [Patch 2/4] MdeModulePkg/Bds: Wide match HTTP boot option.
> 
> Enhance BDS to wide match the HTTP boot option without matching
> the specific device path data in IP device path and URI device
> path node.
> It's to follow UEFI Spec 2.6.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <[email protected]>
> Cc: Siyuan Fu <[email protected]>
> ---
>  MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c | 149
> +++++++++++++++++++++--
>  1 file changed, 137 insertions(+), 12 deletions(-)
> 
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> index a6826f6..35234ba 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> @@ -1528,6 +1528,136 @@ BmExpandMediaDevicePath (
>  }
> 
>  /**
> +  Check whether Left and Right are the same without matching the specific
> +  device path data in IP device path and URI device path node.
> +
> +  @retval TRUE  Left and Right are the same.
> +  @retval FALSE Left and Right are the different.
> +**/
> +BOOLEAN
> +BmMatchHttpBootDevicePath (
> +  IN EFI_DEVICE_PATH_PROTOCOL *Left,
> +  IN EFI_DEVICE_PATH_PROTOCOL *Right
> +  )
> +{
> +  for (;  !IsDevicePathEnd (Left) && !IsDevicePathEnd (Right)
> +       ;  Left = NextDevicePathNode (Left), Right = NextDevicePathNode 
> (Right)
> +       ) {
> +    if (CompareMem (Left, Right, DevicePathNodeLength (Left)) != 0) {
> +      if ((DevicePathType (Left) != MESSAGING_DEVICE_PATH) ||
> (DevicePathType (Right) != MESSAGING_DEVICE_PATH)) {
> +        return FALSE;
> +      }
> +
> +      if (((DevicePathSubType (Left) != MSG_IPv4_DP) || (DevicePathSubType
> (Right) != MSG_IPv4_DP)) &&
> +          ((DevicePathSubType (Left) != MSG_IPv6_DP) || (DevicePathSubType
> (Right) != MSG_IPv6_DP)) &&
> +          ((DevicePathSubType (Left) != MSG_URI_DP)  || (DevicePathSubType
> (Right) != MSG_URI_DP))
> +          ) {
> +        return FALSE;
> +      }
> +    }
> +  }
> +  return (BOOLEAN) (IsDevicePathEnd (Left) && IsDevicePathEnd (Right));
> +}
> +
> +/**
> +  Get the file buffer from Load File instance.
> +
> +  @param FilePath    The media device path pointing to a LoadFile instance.
> +  @param FullPath    Return the full device path pointing to the load option.
> +  @param FileSize    Return the size of the load option.
> +
> +  @return  The load option buffer.
> +**/
> +VOID *
> +BmGetFileBufferFromLoadFile (
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath,
> +  OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,
> +  OUT UINTN                           *FileSize
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      Handle;
> +  VOID                            *FileBuffer;
> +  EFI_HANDLE                      *Handles;
> +  UINTN                           HandleCount;
> +  UINTN                           Index;
> +  EFI_DEVICE_PATH_PROTOCOL        *Node;
> +  EFI_LOAD_FILE_PROTOCOL          *LoadFile;
> +  UINTN                           BufferSize;
> +
> +  //
> +  // Get file buffer from load file instance.
> +  //
> +  Node = FilePath;
> +  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node,
> &Handle);
> +  if (!EFI_ERROR (Status) && IsDevicePathEnd (Node)) {
> +    //
> +    // When wide match happens, pass full device path to LoadFile (),
> +    // otherwise, pass remaining device path to LoadFile ().
> +    //
> +    FilePath = Node;
> +  } else {
> +    Handle = NULL;
> +    //
> +    // Use wide match algorithm to find one when
> +    //  cannot find a LoadFile instance to exactly match the FilePath
> +    //
> +    Status = gBS->LocateHandleBuffer (
> +                    ByProtocol,
> +                    &gEfiLoadFileProtocolGuid,
> +                    NULL,
> +                    &HandleCount,
> +                    &Handles
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      Handles = NULL;
> +      HandleCount = 0;
> +    }
> +    for (Index = 0; Index < HandleCount; Index++) {
> +      if (BmMatchHttpBootDevicePath (DevicePathFromHandle
> (Handles[Index]), FilePath)) {
> +        Handle = Handles[Index];
> +        break;
> +      }
> +    }
> +    if (Handles != NULL) {
> +      FreePool (Handles);
> +    }
> +  }
> +
> +  if (Handle == NULL) {
> +    return NULL;
> +  }
> +
> +  Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID
> **) &LoadFile);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  BufferSize = 0;
> +  FileBuffer = NULL;
> +  Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize,
> FileBuffer);
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    FileBuffer = AllocatePool (BufferSize);
> +    if (FileBuffer != NULL) {
> +      Status = EFI_SUCCESS;
> +    }
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize,
> FileBuffer);
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // LoadFile () may cause the device path of the Handle be updated.
> +    //
> +    *FullPath = DuplicateDevicePath (DevicePathFromHandle (Handle));
> +    *FileSize = BufferSize;
> +    return FileBuffer;
> +  } else {
> +    return NULL;
> +  }
> +}
> +
> +/**
>    Get the load option by its device path.
> 
>    @param FilePath  The device path pointing to a load option.
> @@ -1622,24 +1752,19 @@ BmGetLoadOptionBuffer (
>    }
> 
>    //
> -  // Directly reads the load option when it doesn't reside in simple file 
> system
> instance (LoadFile/LoadFile2),
> -  //   or it directly points to a file in simple file system instance.
> +  // Get file buffer from simple file system.
>    //
>    Node   = FilePath;
> -  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node,
> &Handle);
> -  FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize,
> &AuthenticationStatus);
> -  if (FileBuffer != NULL) {
> -    if (EFI_ERROR (Status)) {
> +  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid,
> &Node, &Handle);
> +  if (!EFI_ERROR (Status)) {
> +    FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize,
> &AuthenticationStatus);
> +    if (FileBuffer != NULL) {
>        *FullPath = DuplicateDevicePath (FilePath);
> -    } else {
> -      //
> -      // LoadFile () may cause the device path of the Handle be updated.
> -      //
> -      *FullPath = AppendDevicePath (DevicePathFromHandle (Handle), Node);
>      }
> +    return FileBuffer;
>    }
> 
> -  return FileBuffer;
> +  return BmGetFileBufferFromLoadFile (FilePath, FullPath, FileSize);
>  }
> 
>  /**
> --
> 2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to