]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Application/CapsuleApp/AppSupport.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / AppSupport.c
index a5fd0ca3164909af99464386911d8887e9c6e483..d9ce1b4843f8544b9d269d3f511264b0772fbd25 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   A shell application that triggers capsule update process.\r
 \r
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Protocol/LoadedImage.h>\r
 #include <Protocol/SimpleFileSystem.h>\r
 #include <Protocol/ShellParameters.h>\r
+#include <Protocol/Shell.h>\r
 #include <Guid/FileInfo.h>\r
-#include <Guid/Gpt.h>\r
-\r
-#define IS_HYPHEN(a)               ((a) == L'-')\r
-#define IS_NULL(a)                 ((a) == L'\0')\r
-\r
-#define MAX_ARG_NUM     11\r
 \r
 UINTN  Argc;\r
 CHAR16 **Argv;\r
+EFI_SHELL_PROTOCOL      *mShellProtocol = NULL;\r
 \r
 /**\r
 \r
@@ -64,435 +50,109 @@ GetArg (
 }\r
 \r
 /**\r
-  Converts a list of string to a specified buffer.\r
-\r
-  @param[out] Buf             The output buffer that contains the string.\r
-  @param[in]  BufferLength    The length of the buffer\r
-  @param[in]  Str             The input string that contains the hex number\r
-\r
-  @retval EFI_SUCCESS    The string was successfully converted to the buffer.\r
-\r
-**/\r
-EFI_STATUS\r
-InternalStrToBuf (\r
-  OUT UINT8    *Buf,\r
-  IN  UINTN    BufferLength,\r
-  IN  CHAR16   *Str\r
-  )\r
-{\r
-  UINTN       Index;\r
-  UINTN       StrLength;\r
-  UINT8       Digit;\r
-  UINT8       Byte;\r
-\r
-  Digit = 0;\r
-\r
-  //\r
-  // Two hex char make up one byte\r
-  //\r
-  StrLength = BufferLength * sizeof (CHAR16);\r
-\r
-  for(Index = 0; Index < StrLength; Index++, Str++) {\r
-\r
-    if ((*Str >= L'a') && (*Str <= L'f')) {\r
-      Digit = (UINT8) (*Str - L'a' + 0x0A);\r
-    } else if ((*Str >= L'A') && (*Str <= L'F')) {\r
-      Digit = (UINT8) (*Str - L'A' + 0x0A);\r
-    } else if ((*Str >= L'0') && (*Str <= L'9')) {\r
-      Digit = (UINT8) (*Str - L'0');\r
-    } else {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    //\r
-    // For odd characters, write the upper nibble for each buffer byte,\r
-    // and for even characters, the lower nibble.\r
-    //\r
-    if ((Index & 1) == 0) {\r
-      Byte = (UINT8) (Digit << 4);\r
-    } else {\r
-      Byte = Buf[Index / 2];\r
-      Byte &= 0xF0;\r
-      Byte = (UINT8) (Byte | Digit);\r
-    }\r
-\r
-    Buf[Index / 2] = Byte;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Converts a string to GUID value.\r
-  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\r
-\r
-  @param[in]  Str              The registry format GUID string that contains the GUID value.\r
-  @param[out] Guid             A pointer to the converted GUID value.\r
-\r
-  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.\r
-  @retval EFI_UNSUPPORTED The input string is not in registry format.\r
-  @return others          Some error occurred when converting part of GUID value.\r
+  Get shell protocol.\r
 \r
+  @return Pointer to shell protocol.\r
 **/\r
-EFI_STATUS\r
-InternalStrToGuid (\r
-  IN  CHAR16   *Str,\r
-  OUT EFI_GUID *Guid\r
-  )\r
-{\r
-  //\r
-  // Get the first UINT32 data\r
-  //\r
-  Guid->Data1 = (UINT32) StrHexToUint64  (Str);\r
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {\r
-    Str ++;\r
-  }\r
-\r
-  if (IS_HYPHEN (*Str)) {\r
-    Str++;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Get the second UINT16 data\r
-  //\r
-  Guid->Data2 = (UINT16) StrHexToUint64  (Str);\r
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {\r
-    Str ++;\r
-  }\r
-\r
-  if (IS_HYPHEN (*Str)) {\r
-    Str++;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Get the third UINT16 data\r
-  //\r
-  Guid->Data3 = (UINT16) StrHexToUint64  (Str);\r
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {\r
-    Str ++;\r
-  }\r
-\r
-  if (IS_HYPHEN (*Str)) {\r
-    Str++;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Get the following 8 bytes data\r
-  //\r
-  InternalStrToBuf (&Guid->Data4[0], 2, Str);\r
-  //\r
-  // Skip 2 byte hex chars\r
-  //\r
-  Str += 2 * 2;\r
-\r
-  if (IS_HYPHEN (*Str)) {\r
-    Str++;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  InternalStrToBuf (&Guid->Data4[2], 6, Str);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Return File System Volume containing this shell application.\r
-\r
-  @return File System Volume containing this shell application.\r
-**/\r
-EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *\r
-GetMyVol (\r
+EFI_SHELL_PROTOCOL *\r
+GetShellProtocol (\r
   VOID\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;\r
+  EFI_STATUS            Status;\r
 \r
-  Status = gBS->HandleProtocol (\r
-                  gImageHandle,\r
-                  &gEfiLoadedImageProtocolGuid,\r
-                  (VOID **)&LoadedImage\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = gBS->HandleProtocol (\r
-                  LoadedImage->DeviceHandle,\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  (VOID **)&Vol\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    return Vol;\r
+  if (mShellProtocol == NULL) {\r
+    Status = gBS->LocateProtocol (\r
+                    &gEfiShellProtocolGuid,\r
+                    NULL,\r
+                    (VOID **) &mShellProtocol\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      mShellProtocol = NULL;\r
+    }\r
   }\r
 \r
-  return NULL;\r
+  return mShellProtocol;\r
 }\r
 \r
 /**\r
-  Read a file from this volume.\r
+  Read a file.\r
 \r
-  @param[in]  Vol             File System Volume\r
   @param[in]  FileName        The file to be read.\r
   @param[out] BufferSize      The file buffer size\r
   @param[out] Buffer          The file buffer\r
 \r
   @retval EFI_SUCCESS    Read file successfully\r
-  @retval EFI_NOT_FOUND  File not found\r
+  @retval EFI_NOT_FOUND  Shell protocol or file not found\r
+  @retval others         Read file failed\r
 **/\r
 EFI_STATUS\r
-ReadFileFromVol (\r
-  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol,\r
-  IN  CHAR16                            *FileName,\r
-  OUT UINTN                             *BufferSize,\r
-  OUT VOID                              **Buffer\r
+ReadFileToBuffer (\r
+  IN  CHAR16                               *FileName,\r
+  OUT UINTN                                *BufferSize,\r
+  OUT VOID                                 **Buffer\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  EFI_FILE_HANDLE                   RootDir;\r
-  EFI_FILE_HANDLE                   Handle;\r
-  UINTN                             FileInfoSize;\r
-  EFI_FILE_INFO                     *FileInfo;\r
+  EFI_SHELL_PROTOCOL                *ShellProtocol;\r
+  SHELL_FILE_HANDLE                 Handle;\r
+  UINT64                            FileSize;\r
   UINTN                             TempBufferSize;\r
   VOID                              *TempBuffer;\r
 \r
-  //\r
-  // Open the root directory\r
-  //\r
-  Status = Vol->OpenVolume (Vol, &RootDir);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+  ShellProtocol = GetShellProtocol();\r
+  if (ShellProtocol == NULL) {\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
   //\r
-  // Open the file\r
+  // Open file by FileName.\r
   //\r
-  Status = RootDir->Open (\r
-                      RootDir,\r
-                      &Handle,\r
-                      FileName,\r
-                      EFI_FILE_MODE_READ,\r
-                      0\r
-                      );\r
+  Status = ShellProtocol->OpenFileByName (\r
+                            FileName,\r
+                            &Handle,\r
+                            EFI_FILE_MODE_READ\r
+                            );\r
   if (EFI_ERROR (Status)) {\r
-    RootDir->Close (RootDir);\r
     return Status;\r
   }\r
 \r
-  RootDir->Close (RootDir);\r
-\r
   //\r
-  // Get the file information\r
+  // Get the file size.\r
   //\r
-  FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;\r
-\r
-  FileInfo = AllocateZeroPool (FileInfoSize);\r
-  if (FileInfo == NULL) {\r
-    Handle->Close (Handle);\r
-    return Status;\r
-  }\r
-\r
-  Status = Handle->GetInfo (\r
-                     Handle,\r
-                     &gEfiFileInfoGuid,\r
-                     &FileInfoSize,\r
-                     FileInfo\r
-                     );\r
+  Status = ShellProtocol->GetFileSize (Handle, &FileSize);\r
   if (EFI_ERROR (Status)) {\r
-    Handle->Close (Handle);\r
-    gBS->FreePool (FileInfo);\r
+    ShellProtocol->CloseFile (Handle);\r
     return Status;\r
   }\r
 \r
-  //\r
-  // Allocate buffer for the file data. The last CHAR16 is for L'\0'\r
-  //\r
-  TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);\r
+  TempBufferSize = (UINTN) FileSize;\r
   TempBuffer = AllocateZeroPool (TempBufferSize);\r
   if (TempBuffer == NULL) {\r
-    Handle->Close (Handle);\r
-    gBS->FreePool (FileInfo);\r
-    return Status;\r
+    ShellProtocol->CloseFile (Handle);\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  gBS->FreePool (FileInfo);\r
-\r
   //\r
   // Read the file data to the buffer\r
   //\r
-  Status = Handle->Read (\r
-                     Handle,\r
-                     &TempBufferSize,\r
-                     TempBuffer\r
-                     );\r
+  Status = ShellProtocol->ReadFile (\r
+                            Handle,\r
+                            &TempBufferSize,\r
+                            TempBuffer\r
+                            );\r
   if (EFI_ERROR (Status)) {\r
-    Handle->Close (Handle);\r
-    gBS->FreePool (TempBuffer);\r
+    ShellProtocol->CloseFile (Handle);\r
     return Status;\r
   }\r
 \r
-  Handle->Close (Handle);\r
+  ShellProtocol->CloseFile (Handle);\r
 \r
   *BufferSize = TempBufferSize;\r
   *Buffer     = TempBuffer;\r
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Read a file.\r
-  If ScanFs is FLASE, it will use this Vol as default Fs.\r
-  If ScanFs is TRUE, it will scan all FS and check the file.\r
-    If there is only one file match the name, it will be read.\r
-    If there is more than one file match the name, it will return Error.\r
-\r
-  @param[in]  ThisVol         File System Volume\r
-  @param[in]  FileName        The file to be read.\r
-  @param[out] BufferSize      The file buffer size\r
-  @param[out] Buffer          The file buffer\r
-  @param[in]  ScanFs          Need Scan all FS\r
-\r
-  @retval EFI_SUCCESS    Read file successfully\r
-  @retval EFI_NOT_FOUND  File not found\r
-  @retval EFI_NO_MAPPING There is duplicated files found\r
-**/\r
-EFI_STATUS\r
-ReadFileToBufferEx (\r
-  IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   **ThisVol,\r
-  IN  CHAR16                               *FileName,\r
-  OUT UINTN                                *BufferSize,\r
-  OUT VOID                                 **Buffer,\r
-  IN  BOOLEAN                              ScanFs\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;\r
-  UINTN                             TempBufferSize;\r
-  VOID                              *TempBuffer;\r
-  UINTN                             NoHandles;\r
-  EFI_HANDLE                        *HandleBuffer;\r
-  UINTN                             Index;\r
-\r
-  //\r
-  // Check parameters\r
-  //\r
-  if ((FileName == NULL) || (Buffer == NULL) || (ThisVol == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // not scan fs\r
-  //\r
-  if (!ScanFs) {\r
-    if (*ThisVol == NULL) {\r
-      *ThisVol = GetMyVol ();\r
-      if (*ThisVol == NULL) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-    //\r
-    // Read file directly from Vol\r
-    //\r
-    return ReadFileFromVol (*ThisVol, FileName, BufferSize, Buffer);\r
-  }\r
-\r
-  //\r
-  // need scan fs\r
-  //\r
-\r
-  //\r
-  // Get all Vol handle\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                   ByProtocol,\r
-                   &gEfiSimpleFileSystemProtocolGuid,\r
-                   NULL,\r
-                   &NoHandles,\r
-                   &HandleBuffer\r
-                   );\r
-  if (EFI_ERROR (Status) && (NoHandles == 0)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Walk through each Vol\r
-  //\r
-  *ThisVol = NULL;\r
-  *BufferSize = 0;\r
-  *Buffer     = NULL;\r
-  for (Index = 0; Index < NoHandles; Index++) {\r
-    Status = gBS->HandleProtocol (\r
-                    HandleBuffer[Index],\r
-                    &gEfiSimpleFileSystemProtocolGuid,\r
-                    (VOID **)&Vol\r
-                    );\r
-    if (EFI_ERROR(Status)) {\r
-      continue;\r
-    }\r
-\r
-    Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);\r
-    if (!EFI_ERROR (Status)) {\r
-      //\r
-      // Read file OK, check duplication\r
-      //\r
-      if (*ThisVol != NULL) {\r
-        //\r
-        // Find the duplicated file\r
-        //\r
-        gBS->FreePool (TempBuffer);\r
-        gBS->FreePool (*Buffer);\r
-        Print (L"Duplicated FileName found!\n");\r
-        return EFI_NO_MAPPING;\r
-      } else {\r
-        //\r
-        // Record value\r
-        //\r
-        *ThisVol = Vol;\r
-        *BufferSize = TempBufferSize;\r
-        *Buffer     = TempBuffer;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Scan Fs done\r
-  //\r
-  if (*ThisVol == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Done\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Read a file.\r
-\r
-  @param[in]  FileName        The file to be read.\r
-  @param[out] BufferSize      The file buffer size\r
-  @param[out] Buffer          The file buffer\r
-\r
-  @retval EFI_SUCCESS    Read file successfully\r
-  @retval EFI_NOT_FOUND  File not found\r
-**/\r
-EFI_STATUS\r
-ReadFileToBuffer (\r
-  IN  CHAR16                               *FileName,\r
-  OUT UINTN                                *BufferSize,\r
-  OUT VOID                                 **Buffer\r
-  )\r
-{\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;\r
-  Vol = NULL;\r
-  return ReadFileToBufferEx(&Vol, FileName, BufferSize, Buffer, FALSE);\r
-}\r
-\r
 /**\r
   Write a file.\r
 \r
@@ -501,6 +161,8 @@ ReadFileToBuffer (
   @param[in] Buffer          The file buffer\r
 \r
   @retval EFI_SUCCESS    Write file successfully\r
+  @retval EFI_NOT_FOUND  Shell protocol not found\r
+  @retval others         Write file failed\r
 **/\r
 EFI_STATUS\r
 WriteFileFromBuffer (\r
@@ -510,79 +172,69 @@ WriteFileFromBuffer (
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  EFI_FILE_HANDLE                   RootDir;\r
-  EFI_FILE_HANDLE                   Handle;\r
+  EFI_SHELL_PROTOCOL                *ShellProtocol;\r
+  SHELL_FILE_HANDLE                 Handle;\r
+  EFI_FILE_INFO                     *FileInfo;\r
   UINTN                             TempBufferSize;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;\r
 \r
-  Vol = GetMyVol();\r
-  if (Vol == NULL) {\r
+  ShellProtocol = GetShellProtocol();\r
+  if (ShellProtocol == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
   //\r
-  // Open the root directory\r
-  //\r
-  Status = Vol->OpenVolume (Vol, &RootDir);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Open the file\r
+  // Open file by FileName.\r
   //\r
-  Status = RootDir->Open (\r
-                      RootDir,\r
-                      &Handle,\r
-                      FileName,\r
-                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
-                      0\r
-                      );\r
+  Status = ShellProtocol->OpenFileByName (\r
+                            FileName,\r
+                            &Handle,\r
+                            EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE\r
+                            );\r
   if (EFI_ERROR (Status)) {\r
-    RootDir->Close (RootDir);\r
     return Status;\r
   }\r
 \r
   //\r
-  // Delete file\r
+  // Empty the file contents.\r
   //\r
-  Status = Handle->Delete(Handle);\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
+  FileInfo = ShellProtocol->GetFileInfo (Handle);\r
+  if (FileInfo == NULL) {\r
+    ShellProtocol->CloseFile (Handle);\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   //\r
-  // Open the file again\r
+  // If the file size is already 0, then it has been empty.\r
   //\r
-  Status = RootDir->Open (\r
-                      RootDir,\r
-                      &Handle,\r
-                      FileName,\r
-                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
-                      0\r
-                      );\r
-  if (EFI_ERROR (Status)) {\r
-    RootDir->Close (RootDir);\r
-    return Status;\r
+  if (FileInfo->FileSize != 0) {\r
+    //\r
+    // Set the file size to 0.\r
+    //\r
+    FileInfo->FileSize = 0;\r
+    Status = ShellProtocol->SetFileInfo (Handle, FileInfo);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (FileInfo);\r
+      ShellProtocol->CloseFile (Handle);\r
+      return Status;\r
+    }\r
   }\r
-\r
-  RootDir->Close (RootDir);\r
+  FreePool (FileInfo);\r
 \r
   //\r
   // Write the file data from the buffer\r
   //\r
   TempBufferSize = BufferSize;\r
-  Status = Handle->Write (\r
-                     Handle,\r
-                     &TempBufferSize,\r
-                     Buffer\r
-                     );\r
+  Status = ShellProtocol->WriteFile (\r
+                            Handle,\r
+                            &TempBufferSize,\r
+                            Buffer\r
+                            );\r
   if (EFI_ERROR (Status)) {\r
-    Handle->Close (Handle);\r
+    ShellProtocol->CloseFile (Handle);\r
     return Status;\r
   }\r
 \r
-  Handle->Close (Handle);\r
+  ShellProtocol->CloseFile (Handle);\r
 \r
   return EFI_SUCCESS;\r
 }\r