From 8165570e3e4a2f834786c67afe16a5d2d55bd65e Mon Sep 17 00:00:00 2001 From: Wei6 Xu Date: Mon, 24 Jun 2019 13:21:35 +0800 Subject: MdeModulePkg/CapsuleApp: Enhance Capsule-On-Disk related functions. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1840 1. Introduce an internal header file to put definitions in it. 2. Add missing '\n' in usage. 3. Fix the dead loop of CapsuleApp -L. 4. Fix the bug that CapsuleApp -OD cannot perform capsules in sub- folder. 5. Optimize the handling for option -NR and -OD to support both 'CapsuleApp -OD -NR' and 'CapsuleApp -NR -OD'. 6. Check if Capsule-On-Disk is supported by "OsIndicationsSupported" variable firstly before processing capsules. If not supported, prompt an error message and quit the process. Cc: Jian J Wang Cc: Hao A Wu Cc: Chao B Zhang Signed-off-by: Wei6 Xu Reviewed-by: Chao B Zhang Acked-by: Hao A Wu --- MdeModulePkg/Application/CapsuleApp/AppSupport.c | 13 +- MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 215 ++---------------- MdeModulePkg/Application/CapsuleApp/CapsuleApp.h | 240 +++++++++++++++++++++ MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 3 +- MdeModulePkg/Application/CapsuleApp/CapsuleDump.c | 98 +-------- .../Application/CapsuleApp/CapsuleOnDisk.c | 86 +++++--- 6 files changed, 323 insertions(+), 332 deletions(-) create mode 100644 MdeModulePkg/Application/CapsuleApp/CapsuleApp.h (limited to 'MdeModulePkg/Application/CapsuleApp') diff --git a/MdeModulePkg/Application/CapsuleApp/AppSupport.c b/MdeModulePkg/Application/CapsuleApp/AppSupport.c index d9ce1b4843..8fe70dc3b6 100644 --- a/MdeModulePkg/Application/CapsuleApp/AppSupport.c +++ b/MdeModulePkg/Application/CapsuleApp/AppSupport.c @@ -1,21 +1,12 @@ /** @file A shell application that triggers capsule update process. - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "CapsuleApp.h" UINTN Argc; CHAR16 **Argv; diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c index e3c591dbf3..3439ce5feb 100644 --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c @@ -6,36 +6,7 @@ **/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CAPSULE_HEADER_SIZE 0x20 - -#define NESTED_CAPSULE_HEADER_SIZE SIZE_4KB -#define SYSTEM_FIRMWARE_FLAG 0x50000 -#define DEVICE_FIRMWARE_FLAG 0x78010 - -#define MAJOR_VERSION 1 -#define MINOR_VERSION 0 - -#define MAX_CAPSULE_NUM 10 - -extern UINTN Argc; -extern CHAR16 **Argv; +#include "CapsuleApp.h" // // Define how many block descriptors we want to test with. @@ -44,149 +15,6 @@ UINTN NumberOfDescriptors = 1; UINTN CapsuleFirstIndex; UINTN CapsuleLastIndex; -/** - Dump capsule information - - @param[in] CapsuleName The name of the capsule image. - - @retval EFI_SUCCESS The capsule information is dumped. - @retval EFI_UNSUPPORTED Input parameter is not valid. -**/ -EFI_STATUS -DumpCapsule ( - IN CHAR16 *CapsuleName - ); - -/** - Dump capsule status variable. - - @retval EFI_SUCCESS The capsule status variable is dumped. - @retval EFI_UNSUPPORTED Input parameter is not valid. -**/ -EFI_STATUS -DumpCapsuleStatusVariable ( - VOID - ); - -/** - Dump FMP protocol info. -**/ -VOID -DumpFmpData ( - VOID - ); - -/** - Dump FMP image data. - - @param[in] ImageTypeId The ImageTypeId of the FMP image. - It is used to identify the FMP protocol. - @param[in] ImageIndex The ImageIndex of the FMP image. - It is the input parameter for FMP->GetImage(). - @param[in] ImageName The file name to hold the output FMP image. -**/ -VOID -DumpFmpImage ( - IN EFI_GUID *ImageTypeId, - IN UINTN ImageIndex, - IN CHAR16 *ImageName - ); - -/** - Dump ESRT info. -**/ -VOID -DumpEsrtData ( - VOID - ); - -/** - Dump Provisioned Capsule. - - @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation. -**/ -VOID -DumpProvisionedCapsule ( - IN BOOLEAN DumpCapsuleInfo - ); - -/** - Dump all EFI System Partition. -**/ -VOID -DumpAllEfiSysPartition ( - VOID - ); - -/** - Process Capsule On Disk. - - @param[in] CapsuleBuffer An array of pointer to capsule images - @param[in] CapsuleBufferSize An array of UINTN to capsule images size - @param[in] FilePath An array of capsule images file path - @param[in] Map File system mapping string - @param[in] CapsuleNum The count of capsule images - - @retval EFI_SUCCESS Capsule on disk success. - @retval others Capsule on disk fail. - -**/ -EFI_STATUS -ProcessCapsuleOnDisk ( - IN VOID **CapsuleBuffer, - IN UINTN *CapsuleBufferSize, - IN CHAR16 **FilePath, - IN CHAR16 *Map, - IN UINTN CapsuleNum - ); - -/** - 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 Shell protocol or file not found - @retval others Read file failed -**/ -EFI_STATUS -ReadFileToBuffer ( - IN CHAR16 *FileName, - OUT UINTN *BufferSize, - OUT VOID **Buffer - ); - -/** - Write a file. - - @param[in] FileName The file to be written. - @param[in] BufferSize The file buffer size - @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 ( - IN CHAR16 *FileName, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - - This function parse application ARG. - - @return Status -**/ -EFI_STATUS -GetArg ( - VOID - ); - /** Create UX capsule. @@ -849,7 +677,7 @@ PrintUsage ( Print(L"Parameter:\n"); Print(L" -NR: No reset will be triggered for the capsule\n"); Print(L" with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and without CAPSULE_FLAGS_INITIATE_RESET.\n"); - Print(L" -OD: Delivery of Capsules via file on Mass Storage device."); + Print(L" -OD: Delivery of Capsules via file on Mass Storage device.\n"); Print(L" -S: Dump capsule report variable (EFI_CAPSULE_REPORT_GUID),\n"); Print(L" which is defined in UEFI specification.\n"); Print(L" -C: Clear capsule report variable (EFI_CAPSULE_REPORT_GUID),\n"); @@ -1020,40 +848,39 @@ UefiMain ( } } - if (ParaOdIndex != 0) { - if (ParaOdIndex == Argc - 1) { + if (ParaOdIndex > ParaNrIndex) { + if (ParaNrIndex != 0) { + CapsuleLastIndex = ParaNrIndex - 1; + } else { + CapsuleLastIndex = ParaOdIndex - 1; + } + + if (ParaOdIndex == Argc -1) { MapFsStr = NULL; } else if (ParaOdIndex == Argc - 2) { MapFsStr = Argv[Argc-1]; } else { - Print (L"CapsuleApp: Invalid Position for -OD Options\n"); + Print (L"CapsuleApp: Cannot specify more than one FS mapping!\n"); Status = EFI_INVALID_PARAMETER; goto Done; } - - if (ParaNrIndex != 0) { - if (ParaNrIndex + 1 == ParaOdIndex) { - CapsuleLastIndex = ParaNrIndex - 1; - } else { - Print (L"CapsuleApp: Invalid Position for -NR Options\n"); - Status = EFI_INVALID_PARAMETER; - goto Done; - } - } else { + } else if (ParaOdIndex < ParaNrIndex) { + if (ParaOdIndex != 0) { CapsuleLastIndex = ParaOdIndex - 1; - } - } else { - if (ParaNrIndex != 0) { - if (ParaNrIndex == Argc -1) { - CapsuleLastIndex = ParaNrIndex - 1; + if (ParaOdIndex == ParaNrIndex - 1) { + MapFsStr = NULL; + } else if (ParaOdIndex == ParaNrIndex - 2) { + MapFsStr = Argv[ParaOdIndex + 1]; } else { - Print (L"CapsuleApp: Invalid Position for -NR Options\n"); + Print (L"CapsuleApp: Cannot specify more than one FS mapping!\n"); Status = EFI_INVALID_PARAMETER; goto Done; } } else { - CapsuleLastIndex = Argc - 1; + CapsuleLastIndex = ParaNrIndex - 1; } + } else { + CapsuleLastIndex = Argc - 1; } CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1; diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.h b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.h new file mode 100644 index 0000000000..270d2359a3 --- /dev/null +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.h @@ -0,0 +1,240 @@ +/** @file + A shell application that triggers capsule update process. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#ifndef _CAPSULE_APP_H_ +#define _CAPSULE_APP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CAPSULE_HEADER_SIZE 0x20 + +#define NESTED_CAPSULE_HEADER_SIZE SIZE_4KB +#define SYSTEM_FIRMWARE_FLAG 0x50000 +#define DEVICE_FIRMWARE_FLAG 0x78010 + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 + +#define MAX_CAPSULE_NUM 10 + +// +// (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes) +// +#define MAX_FILE_NAME_SIZE 522 +#define MAX_FILE_NAME_LEN (MAX_FILE_NAME_SIZE / sizeof(CHAR16)) + +extern UINTN Argc; +extern CHAR16 **Argv; + +/** + + This function parse application ARG. + + @return Status +**/ +EFI_STATUS +GetArg ( + VOID + ); + +/** + Get shell protocol. + + @return Pointer to shell protocol. + +**/ +EFI_SHELL_PROTOCOL * +GetShellProtocol ( + VOID + ); + + +/** + 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 Shell protocol or file not found + @retval others Read file failed +**/ +EFI_STATUS +ReadFileToBuffer ( + IN CHAR16 *FileName, + OUT UINTN *BufferSize, + OUT VOID **Buffer + ); + +/** + Write a file. + + @param[in] FileName The file to be written. + @param[in] BufferSize The file buffer size + @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 ( + IN CHAR16 *FileName, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +/** + Dump capsule information + + @param[in] CapsuleName The name of the capsule image. + + @retval EFI_SUCCESS The capsule information is dumped. + @retval EFI_UNSUPPORTED Input parameter is not valid. +**/ +EFI_STATUS +DumpCapsule ( + IN CHAR16 *CapsuleName + ); + +/** + Dump capsule status variable. + + @retval EFI_SUCCESS The capsule status variable is dumped. + @retval EFI_UNSUPPORTED Input parameter is not valid. +**/ +EFI_STATUS +DumpCapsuleStatusVariable ( + VOID + ); + +/** + Dump FMP protocol info. +**/ +VOID +DumpFmpData ( + VOID + ); + +/** + Dump FMP image data. + + @param[in] ImageTypeId The ImageTypeId of the FMP image. + It is used to identify the FMP protocol. + @param[in] ImageIndex The ImageIndex of the FMP image. + It is the input parameter for FMP->GetImage(). + @param[in] ImageName The file name to hold the output FMP image. +**/ +VOID +DumpFmpImage ( + IN EFI_GUID *ImageTypeId, + IN UINTN ImageIndex, + IN CHAR16 *ImageName + ); + +/** + Dump ESRT info. +**/ +VOID +DumpEsrtData ( + VOID + ); + +/** + Dump Provisioned Capsule. + + @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation. +**/ +VOID +DumpProvisionedCapsule ( + IN BOOLEAN DumpCapsuleInfo + ); + +/** + Dump all EFI System Partition. +**/ +VOID +DumpAllEfiSysPartition ( + VOID + ); + + +/** + Get SimpleFileSystem from boot option file path. + + @param[in] DevicePath The file path of boot option + @param[out] FullPath The full device path of boot device + @param[out] Fs The file system within EfiSysPartition + + @retval EFI_SUCCESS Get file system successfully + @retval EFI_NOT_FOUND No valid file system found + @retval others Get file system failed + +**/ +EFI_STATUS +GetEfiSysPartitionFromBootOptionFilePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, + OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs + ); + + +/** + Process Capsule On Disk. + + @param[in] CapsuleBuffer An array of pointer to capsule images + @param[in] CapsuleBufferSize An array of UINTN to capsule images size + @param[in] FilePath An array of capsule images file path + @param[in] Map File system mapping string + @param[in] CapsuleNum The count of capsule images + + @retval EFI_SUCCESS Capsule on disk success. + @retval others Capsule on disk fail. + +**/ +EFI_STATUS +ProcessCapsuleOnDisk ( + IN VOID **CapsuleBuffer, + IN UINTN *CapsuleBufferSize, + IN CHAR16 **FilePath, + IN CHAR16 *Map, + IN UINTN CapsuleNum + ); + +#endif + diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf index 8ca5e04104..6ed0659835 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 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -26,6 +26,7 @@ [Sources] CapsuleApp.c + CapsuleApp.h CapsuleDump.c CapsuleOnDisk.c AppSupport.c diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c b/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c index b81c5b7b3a..58a93568d0 100644 --- a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c @@ -6,98 +6,7 @@ **/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes) -// -#define MAX_FILE_NAME_SIZE 522 -#define MAX_FILE_NAME_LEN (MAX_FILE_NAME_SIZE / sizeof(CHAR16)) - -/** - 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 - ); - -/** - Write a file. - - @param[in] FileName The file to be written. - @param[in] BufferSize The file buffer size - @param[in] Buffer The file buffer - - @retval EFI_SUCCESS Write file successfully -**/ -EFI_STATUS -WriteFileFromBuffer ( - IN CHAR16 *FileName, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Get shell protocol. - - @return Pointer to shell protocol. - -**/ -EFI_SHELL_PROTOCOL * -GetShellProtocol ( - VOID - ); - -/** - Get SimpleFileSystem from boot option file path. - - @param[in] DevicePath The file path of boot option - @param[out] FullPath The full device path of boot device - @param[out] Fs The file system within EfiSysPartition - - @retval EFI_SUCCESS Get file system successfully - @retval EFI_NOT_FOUND No valid file system found - @retval others Get file system failed - -**/ -EFI_STATUS -EFIAPI -GetEfiSysPartitionFromBootOptionFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, - OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs - ); +#include "CapsuleApp.h" /** Validate if it is valid capsule header @@ -709,7 +618,6 @@ SplitFileNameExtension ( **/ INTN -EFIAPI CompareFileNameInAlphabet ( IN VOID *Left, IN VOID *Right @@ -812,8 +720,8 @@ DumpCapsuleFromDisk ( // // Get file count first // + Status = FileHandleFindFirstFile (DirHandle, &FileInfo); do { - Status = FileHandleFindFirstFile (DirHandle, &FileInfo); if (EFI_ERROR (Status) || FileInfo == NULL) { Print (L"Get File Info Fail. Status = %r\n", Status); goto Done; @@ -846,8 +754,8 @@ DumpCapsuleFromDisk ( // // Get all file info // + Status = FileHandleFindFirstFile (DirHandle, &FileInfo); do { - Status = FileHandleFindFirstFile (DirHandle, &FileInfo); if (EFI_ERROR (Status) || FileInfo == NULL) { Print (L"Get File Info Fail. Status = %r\n", Status); goto Done; diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleOnDisk.c b/MdeModulePkg/Application/CapsuleApp/CapsuleOnDisk.c index a11683d66c..382efa9aa0 100644 --- a/MdeModulePkg/Application/CapsuleApp/CapsuleOnDisk.c +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleOnDisk.c @@ -5,36 +5,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -EFI_GUID mCapsuleOnDiskBootOptionGuid = { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } }; - -/** - Get shell protocol. +#include "CapsuleApp.h" - @return Pointer to shell protocol. - -**/ -EFI_SHELL_PROTOCOL * -GetShellProtocol ( - VOID - ); +EFI_GUID mCapsuleOnDiskBootOptionGuid = { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } }; /** Get file name from file path. @@ -330,7 +304,6 @@ GetEfiSysPartitionFromDevPath ( **/ EFI_STATUS -EFIAPI GetEfiSysPartitionFromBootOptionFilePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, @@ -398,7 +371,6 @@ GetEfiSysPartitionFromBootOptionFilePath ( **/ EFI_STATUS -EFIAPI GetUpdateFileSystem ( IN CHAR16 *Map, OUT UINT16 *BootNext, @@ -744,6 +716,41 @@ SetCapsuleStatusVariable ( return Status; } +/** + Check if Capsule On Disk is supported. + + @retval TRUE Capsule On Disk is supported. + @retval FALSE Capsule On Disk is not supported. + +**/ +BOOLEAN +IsCapsuleOnDiskSupported ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 OsIndicationsSupported; + UINTN DataSize; + + DataSize = sizeof(UINT64); + Status = gRT->GetVariable ( + L"OsIndicationsSupported", + &gEfiGlobalVariableGuid, + NULL, + &DataSize, + &OsIndicationsSupported + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + if (OsIndicationsSupported & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) { + return TRUE; + } + + return FALSE; +} + /** Process Capsule On Disk. @@ -770,6 +777,16 @@ ProcessCapsuleOnDisk ( UINT16 BootNext; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; BOOLEAN UpdateBootNext; + CHAR16 *FileName[MAX_CAPSULE_NUM]; + UINTN Index; + + // + // Check if Capsule On Disk is supported + // + if (!IsCapsuleOnDiskSupported ()) { + Print (L"CapsuleApp: Capsule On Disk is not supported.\n"); + return EFI_UNSUPPORTED; + } // // Get a valid file system from boot path @@ -782,10 +799,17 @@ ProcessCapsuleOnDisk ( return Status; } + // + // Get file name from file path + // + for (Index = 0; Index < CapsuleNum; Index ++) { + FileName[Index] = GetFileNameFromPath (FilePath[Index]); + } + // // Copy capsule image to '\efi\UpdateCapsule\' // - Status = WriteUpdateFile (CapsuleBuffer, CapsuleBufferSize, FilePath, CapsuleNum, Fs); + Status = WriteUpdateFile (CapsuleBuffer, CapsuleBufferSize, FileName, CapsuleNum, Fs); if (EFI_ERROR (Status)) { Print (L"CapsuleApp: capsule image could not be copied for update.\n"); return Status; -- cgit v1.2.3