Reviewed-by: jiewen....@intel.com

> -----Original Message-----
> From: Zeng, Star
> Sent: Thursday, April 13, 2017 1:30 PM
> To: edk2-devel@lists.01.org
> Cc: Zeng, Star <star.z...@intel.com>; Yao, Jiewen <jiewen....@intel.com>; 
> Tian,
> Feng <feng.t...@intel.com>
> Subject: [PATCH] MdeModulePkg CapsuleApp: Add directory support
> 
> Current CapsuleApp only supports input/output file from rootdirectory.
> If the CapsuleApp and related file are put into subdirectory,
> below message will be shown when running the CapsuleApp in shell.
> 
> "CapsuleApp: capsule image (Capsule image file name) is not found."
> 
> This patch is to add directory support for CapsuleApp
> by using shell protocol.
> 
> Cc: Jiewen Yao <jiewen....@intel.com>
> Cc: Feng Tian <feng.t...@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Star Zeng <star.z...@intel.com>
> ---
>  MdeModulePkg/Application/CapsuleApp/AppSupport.c   | 380
> +++++----------------
>  MdeModulePkg/Application/CapsuleApp/CapsuleApp.c   |   9 +-
>  MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf |   7 +-
>  3 files changed, 94 insertions(+), 302 deletions(-)
> 
> diff --git a/MdeModulePkg/Application/CapsuleApp/AppSupport.c
> b/MdeModulePkg/Application/CapsuleApp/AppSupport.c
> index e39ab2037865..fc27343736a4 100644
> --- a/MdeModulePkg/Application/CapsuleApp/AppSupport.c
> +++ b/MdeModulePkg/Application/CapsuleApp/AppSupport.c
> @@ -18,22 +18,14 @@
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/MemoryAllocationLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiRuntimeServicesTableLib.h>
> -#include <Library/UefiLib.h>
> -#include <Library/PrintLib.h>
> -#include <Protocol/LoadedImage.h>
>  #include <Protocol/SimpleFileSystem.h>
>  #include <Protocol/ShellParameters.h>
> +#include <Protocol/Shell.h>
>  #include <Guid/FileInfo.h>
> -#include <Guid/Gpt.h>
> -
> -#define IS_HYPHEN(a)               ((a) == L'-')
> -#define IS_NULL(a)                 ((a) == L'\0')
> -
> -#define MAX_ARG_NUM     11
> 
>  UINTN  Argc;
>  CHAR16 **Argv;
> +EFI_SHELL_PROTOCOL      *mShellProtocol = NULL;
> 
>  /**
> 
> @@ -64,141 +56,103 @@ GetArg (
>  }
> 
>  /**
> -  Return File System Volume containing this shell application.
> +  Get shell protocol.
> 
> -  @return File System Volume containing this shell application.
> +  @return Pointer to shell protocol.
>  **/
> -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *
> -GetMyVol (
> +EFI_SHELL_PROTOCOL *
> +GetShellProtocol (
>    VOID
>    )
>  {
> -  EFI_STATUS                        Status;
> -  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
> -  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
> -
> -  Status = gBS->HandleProtocol (
> -                  gImageHandle,
> -                  &gEfiLoadedImageProtocolGuid,
> -                  (VOID **)&LoadedImage
> -                  );
> -  ASSERT_EFI_ERROR (Status);
> +  EFI_STATUS            Status;
> 
> -  Status = gBS->HandleProtocol (
> -                  LoadedImage->DeviceHandle,
> -                  &gEfiSimpleFileSystemProtocolGuid,
> -                  (VOID **)&Vol
> -                  );
> -  if (!EFI_ERROR (Status)) {
> -    return Vol;
> +  if (mShellProtocol == NULL) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiShellProtocolGuid,
> +                    NULL,
> +                    (VOID **) &mShellProtocol
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      mShellProtocol = NULL;
> +    }
>    }
> 
> -  return NULL;
> +  return mShellProtocol;
>  }
> 
>  /**
> -  Read a file from this volume.
> +  Read a file.
> 
> -  @param[in]  Vol             File System Volume
>    @param[in]  FileName        The file to be read.
>    @param[out] BufferSize      The file buffer size
>    @param[out] Buffer          The file buffer
> 
>    @retval EFI_SUCCESS    Read file successfully
> -  @retval EFI_NOT_FOUND  File not found
> +  @retval EFI_NOT_FOUND  Shell protocol or file not found
> +  @retval others         Read file failed
>  **/
>  EFI_STATUS
> -ReadFileFromVol (
> -  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol,
> -  IN  CHAR16                            *FileName,
> -  OUT UINTN                             *BufferSize,
> -  OUT VOID                              **Buffer
> +ReadFileToBuffer (
> +  IN  CHAR16                               *FileName,
> +  OUT UINTN                                *BufferSize,
> +  OUT VOID                                 **Buffer
>    )
>  {
>    EFI_STATUS                        Status;
> -  EFI_FILE_HANDLE                   RootDir;
> -  EFI_FILE_HANDLE                   Handle;
> -  UINTN                             FileInfoSize;
> -  EFI_FILE_INFO                     *FileInfo;
> +  EFI_SHELL_PROTOCOL                *ShellProtocol;
> +  SHELL_FILE_HANDLE                 Handle;
> +  UINT64                            FileSize;
>    UINTN                             TempBufferSize;
>    VOID                              *TempBuffer;
> 
> -  //
> -  // Open the root directory
> -  //
> -  Status = Vol->OpenVolume (Vol, &RootDir);
> -  if (EFI_ERROR (Status)) {
> -    return Status;
> +  ShellProtocol = GetShellProtocol();
> +  if (ShellProtocol == NULL) {
> +    return EFI_NOT_FOUND;
>    }
> 
>    //
> -  // Open the file
> +  // Open file by FileName.
>    //
> -  Status = RootDir->Open (
> -                      RootDir,
> -                      &Handle,
> -                      FileName,
> -                      EFI_FILE_MODE_READ,
> -                      0
> -                      );
> +  Status = ShellProtocol->OpenFileByName (
> +                            FileName,
> +                            &Handle,
> +                            EFI_FILE_MODE_READ
> +                            );
>    if (EFI_ERROR (Status)) {
> -    RootDir->Close (RootDir);
>      return Status;
>    }
> 
> -  RootDir->Close (RootDir);
> -
>    //
> -  // Get the file information
> +  // Get the file size.
>    //
> -  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;
> -
> -  FileInfo = AllocateZeroPool (FileInfoSize);
> -  if (FileInfo == NULL) {
> -    Handle->Close (Handle);
> +  Status = ShellProtocol->GetFileSize (Handle, &FileSize);
> +  if (EFI_ERROR (Status)) {
> +    ShellProtocol->CloseFile (Handle);
>      return Status;
>    }
> 
> -  Status = Handle->GetInfo (
> -                     Handle,
> -                     &gEfiFileInfoGuid,
> -                     &FileInfoSize,
> -                     FileInfo
> -                     );
> -  if (EFI_ERROR (Status)) {
> -    Handle->Close (Handle);
> -    gBS->FreePool (FileInfo);
> -    return Status;
> -  }
> -
> -  //
> -  // Allocate buffer for the file data. The last CHAR16 is for L'\0'
> -  //
> -  TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);
> +  TempBufferSize = (UINTN) FileSize;
>    TempBuffer = AllocateZeroPool (TempBufferSize);
>    if (TempBuffer == NULL) {
> -    Handle->Close (Handle);
> -    gBS->FreePool (FileInfo);
> -    return Status;
> +    ShellProtocol->CloseFile (Handle);
> +    return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  gBS->FreePool (FileInfo);
> -
>    //
>    // Read the file data to the buffer
>    //
> -  Status = Handle->Read (
> -                     Handle,
> -                     &TempBufferSize,
> -                     TempBuffer
> -                     );
> +  Status = ShellProtocol->ReadFile (
> +                            Handle,
> +                            &TempBufferSize,
> +                            TempBuffer
> +                            );
>    if (EFI_ERROR (Status)) {
> -    Handle->Close (Handle);
> -    gBS->FreePool (TempBuffer);
> +    ShellProtocol->CloseFile (Handle);
>      return Status;
>    }
> 
> -  Handle->Close (Handle);
> +  ShellProtocol->CloseFile (Handle);
> 
>    *BufferSize = TempBufferSize;
>    *Buffer     = TempBuffer;
> @@ -206,156 +160,6 @@ ReadFileFromVol (
>  }
> 
>  /**
> -  Read a file.
> -  If ScanFs is FLASE, it will use this Vol as default Fs.
> -  If ScanFs is TRUE, it will scan all FS and check the file.
> -    If there is only one file match the name, it will be read.
> -    If there is more than one file match the name, it will return Error.
> -
> -  @param[in,out]  ThisVol         File System Volume
> -  @param[in]      FileName        The file to be read.
> -  @param[out]     BufferSize      The file buffer size
> -  @param[out]     Buffer          The file buffer
> -  @param[in]      ScanFs          Need Scan all FS
> -
> -  @retval EFI_SUCCESS    Read file successfully
> -  @retval EFI_NOT_FOUND  File not found
> -  @retval EFI_NO_MAPPING There is duplicated files found
> -**/
> -EFI_STATUS
> -ReadFileToBufferEx (
> -  IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   **ThisVol,
> -  IN  CHAR16                               *FileName,
> -  OUT UINTN                                *BufferSize,
> -  OUT VOID                                 **Buffer,
> -  IN  BOOLEAN                              ScanFs
> -  )
> -{
> -  EFI_STATUS                        Status;
> -  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
> -  UINTN                             TempBufferSize;
> -  VOID                              *TempBuffer;
> -  UINTN                             NoHandles;
> -  EFI_HANDLE                        *HandleBuffer;
> -  UINTN                             Index;
> -
> -  //
> -  // Check parameters
> -  //
> -  if ((FileName == NULL) || (Buffer == NULL) || (ThisVol == NULL)) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // not scan fs
> -  //
> -  if (!ScanFs) {
> -    if (*ThisVol == NULL) {
> -      *ThisVol = GetMyVol ();
> -      if (*ThisVol == NULL) {
> -        return EFI_INVALID_PARAMETER;
> -      }
> -    }
> -    //
> -    // Read file directly from Vol
> -    //
> -    return ReadFileFromVol (*ThisVol, FileName, BufferSize, Buffer);
> -  }
> -
> -  //
> -  // need scan fs
> -  //
> -
> -  //
> -  // Get all Vol handle
> -  //
> -  Status = gBS->LocateHandleBuffer (
> -                   ByProtocol,
> -                   &gEfiSimpleFileSystemProtocolGuid,
> -                   NULL,
> -                   &NoHandles,
> -                   &HandleBuffer
> -                   );
> -  if (EFI_ERROR (Status) && (NoHandles == 0)) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  //
> -  // Walk through each Vol
> -  //
> -  *ThisVol = NULL;
> -  *BufferSize = 0;
> -  *Buffer     = NULL;
> -  for (Index = 0; Index < NoHandles; Index++) {
> -    Status = gBS->HandleProtocol (
> -                    HandleBuffer[Index],
> -                    &gEfiSimpleFileSystemProtocolGuid,
> -                    (VOID **)&Vol
> -                    );
> -    if (EFI_ERROR(Status)) {
> -      continue;
> -    }
> -
> -    Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);
> -    if (!EFI_ERROR (Status)) {
> -      //
> -      // Read file OK, check duplication
> -      //
> -      if (*ThisVol != NULL) {
> -        //
> -        // Find the duplicated file
> -        //
> -        gBS->FreePool (TempBuffer);
> -        gBS->FreePool (*Buffer);
> -        Print (L"Duplicated FileName found!\n");
> -        return EFI_NO_MAPPING;
> -      } else {
> -        //
> -        // Record value
> -        //
> -        *ThisVol = Vol;
> -        *BufferSize = TempBufferSize;
> -        *Buffer     = TempBuffer;
> -      }
> -    }
> -  }
> -
> -  //
> -  // Scan Fs done
> -  //
> -  if (*ThisVol == NULL) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  //
> -  // Done
> -  //
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Read a file.
> -
> -  @param[in]  FileName        The file to be read.
> -  @param[out] BufferSize      The file buffer size
> -  @param[out] Buffer          The file buffer
> -
> -  @retval EFI_SUCCESS    Read file successfully
> -  @retval EFI_NOT_FOUND  File not found
> -**/
> -EFI_STATUS
> -ReadFileToBuffer (
> -  IN  CHAR16                               *FileName,
> -  OUT UINTN                                *BufferSize,
> -  OUT VOID                                 **Buffer
> -  )
> -{
> -  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
> -  Vol = NULL;
> -  return ReadFileToBufferEx(&Vol, FileName, BufferSize, Buffer, FALSE);
> -}
> -
> -/**
>    Write a file.
> 
>    @param[in] FileName        The file to be written.
> @@ -363,6 +167,8 @@ ReadFileToBuffer (
>    @param[in] Buffer          The file buffer
> 
>    @retval EFI_SUCCESS    Write file successfully
> +  @retval EFI_NOT_FOUND  Shell protocol not found
> +  @retval others         Write file failed
>  **/
>  EFI_STATUS
>  WriteFileFromBuffer (
> @@ -372,79 +178,69 @@ WriteFileFromBuffer (
>    )
>  {
>    EFI_STATUS                        Status;
> -  EFI_FILE_HANDLE                   RootDir;
> -  EFI_FILE_HANDLE                   Handle;
> +  EFI_SHELL_PROTOCOL                *ShellProtocol;
> +  SHELL_FILE_HANDLE                 Handle;
> +  EFI_FILE_INFO                     *FileInfo;
>    UINTN                             TempBufferSize;
> -  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
> 
> -  Vol = GetMyVol();
> -  if (Vol == NULL) {
> +  ShellProtocol = GetShellProtocol();
> +  if (ShellProtocol == NULL) {
>      return EFI_NOT_FOUND;
>    }
> 
>    //
> -  // Open the root directory
> +  // Open file by FileName.
>    //
> -  Status = Vol->OpenVolume (Vol, &RootDir);
> +  Status = ShellProtocol->OpenFileByName (
> +                            FileName,
> +                            &Handle,
> +                            EFI_FILE_MODE_READ |
> EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE
> +                            );
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> 
>    //
> -  // Open the file
> +  // Empty the file contents.
>    //
> -  Status = RootDir->Open (
> -                      RootDir,
> -                      &Handle,
> -                      FileName,
> -                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE|
> EFI_FILE_MODE_CREATE,
> -                      0
> -                      );
> -  if (EFI_ERROR (Status)) {
> -    RootDir->Close (RootDir);
> -    return Status;
> -  }
> -
> -  //
> -  // Delete file
> -  //
> -  Status = Handle->Delete(Handle);
> -  if (EFI_ERROR(Status)) {
> -    return Status;
> +  FileInfo = ShellProtocol->GetFileInfo (Handle);
> +  if (FileInfo == NULL) {
> +    ShellProtocol->CloseFile (Handle);
> +    return EFI_DEVICE_ERROR;
>    }
> 
>    //
> -  // Open the file again
> +  // If the file size is already 0, then it has been empty.
>    //
> -  Status = RootDir->Open (
> -                      RootDir,
> -                      &Handle,
> -                      FileName,
> -                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE|
> EFI_FILE_MODE_CREATE,
> -                      0
> -                      );
> -  if (EFI_ERROR (Status)) {
> -    RootDir->Close (RootDir);
> -    return Status;
> +  if (FileInfo->FileSize != 0) {
> +    //
> +    // Set the file size to 0.
> +    //
> +    FileInfo->FileSize = 0;
> +    Status = ShellProtocol->SetFileInfo (Handle, FileInfo);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (FileInfo);
> +      ShellProtocol->CloseFile (Handle);
> +      return Status;
> +    }
>    }
> -
> -  RootDir->Close (RootDir);
> +  FreePool (FileInfo);
> 
>    //
>    // Write the file data from the buffer
>    //
>    TempBufferSize = BufferSize;
> -  Status = Handle->Write (
> -                     Handle,
> -                     &TempBufferSize,
> -                     Buffer
> -                     );
> +  Status = ShellProtocol->WriteFile (
> +                            Handle,
> +                            &TempBufferSize,
> +                            Buffer
> +                            );
>    if (EFI_ERROR (Status)) {
> -    Handle->Close (Handle);
> +    ShellProtocol->CloseFile (Handle);
>      return Status;
>    }
> 
> -  Handle->Close (Handle);
> +  ShellProtocol->CloseFile (Handle);
> 
>    return EFI_SUCCESS;
>  }
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> index 6febe846b140..63c83b1474a5 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> @@ -21,11 +21,7 @@
>  #include <Library/UefiRuntimeServicesTableLib.h>
>  #include <Library/UefiLib.h>
>  #include <Library/PrintLib.h>
> -#include <Protocol/LoadedImage.h>
> -#include <Protocol/SimpleFileSystem.h>
>  #include <Protocol/GraphicsOutput.h>
> -#include <Guid/FileInfo.h>
> -#include <Guid/Gpt.h>
>  #include <Guid/GlobalVariable.h>
>  #include <Guid/CapsuleReport.h>
>  #include <Guid/SystemResourceTable.h>
> @@ -117,7 +113,8 @@ DumpEsrtData (
>    @param[out] Buffer          The file buffer
> 
>    @retval EFI_SUCCESS    Read file successfully
> -  @retval EFI_NOT_FOUND  File not found
> +  @retval EFI_NOT_FOUND  Shell protocol or file not found
> +  @retval others         Read file failed
>  **/
>  EFI_STATUS
>  ReadFileToBuffer (
> @@ -134,6 +131,8 @@ ReadFileToBuffer (
>    @param[in] Buffer          The file buffer
> 
>    @retval EFI_SUCCESS    Write file successfully
> +  @retval EFI_NOT_FOUND  Shell protocol not found
> +  @retval others         Write file failed
>  **/
>  EFI_STATUS
>  WriteFileFromBuffer (
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> index c255096aaeb7..b06c4ea1bc88 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> @@ -4,7 +4,7 @@
>  # This application can trigger capsule update process. It can also
>  # generate capsule image, or dump capsule variable information.
>  #
> -#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
>  #  This program and the accompanying materials
>  #  are licensed and made available under the terms and conditions of the BSD
> License
>  #  which accompanies this distribution.  The full text of the license may be
> found at
> @@ -40,8 +40,6 @@ [Packages]
>    MdeModulePkg/MdeModulePkg.dec
> 
>  [Guids]
> -  gEfiFileInfoGuid                       ## CONSUMES   ## GUID
> -  gEfiPartTypeSystemPartGuid             ## CONSUMES   ## GUID
>    gEfiGlobalVariableGuid                 ## CONSUMES   ## GUID
>    gEfiCapsuleReportGuid                  ## CONSUMES   ## GUID
>    gEfiFmpCapsuleGuid                     ## CONSUMES   ## GUID
> @@ -51,11 +49,10 @@ [Guids]
>    gEfiSystemResourceTableGuid            ## CONSUMES   ## GUID
> 
>  [Protocols]
> -  gEfiLoadedImageProtocolGuid            ## CONSUMES
> -  gEfiSimpleFileSystemProtocolGuid       ## CONSUMES
>    gEfiGraphicsOutputProtocolGuid         ## CONSUMES
>    gEfiFirmwareManagementProtocolGuid     ## CONSUMES
>    gEfiShellParametersProtocolGuid        ## CONSUMES
> +  gEfiShellProtocolGuid                  ## CONSUMES
> 
>  [LibraryClasses]
>    BaseLib
> --
> 2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to