From f260ae0375876d2d8683d7dab54071b1d980b15b Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 6 May 2026 12:37:59 +0200 Subject: [PATCH] ShellPkg/EfiCompress: Extract OpenFileHelper() and CompressFile() Extract file opening and compression code into helpers. Upon calling: - gEfiShellProtocol->GetFileSize() - gEfiShellProtocol->ReadFile() the returned Status is now checked. Upon calling AllocateZeroPool, the failed status is now set to EFI_OUT_OF_RESOURCES. Other than that, no functional change. Signed-off-by: Pierre Gondois --- .../UefiShellDebug1CommandsLib/EfiCompress.c | 199 ++++++++++++------ 1 file changed, 131 insertions(+), 68 deletions(-) diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c index ed4840d434..ff5240baf2 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EfiCompress.c @@ -10,6 +10,133 @@ #include "UefiShellDebug1CommandsLib.h" #include "Compress.h" +/** + Compress the full contents of an input file and write the compressed payload + to an output file handle. + + @param[in] InShellFileHandle Source file to read and compress. + @param[in] OutShellFileHandle Destination file to receive compressed data. + @param[in] OutFileName Name of the output file for error reporting. + + @retval SHELL_SUCCESS Compression and write completed successfully. + @retval SHELL_OUT_OF_RESOURCES A required buffer allocation failed. + @retval SHELL_DEVICE_ERROR Read, compress, or write failed. +**/ +STATIC +SHELL_STATUS +CompressFile ( + IN SHELL_FILE_HANDLE InShellFileHandle, + IN SHELL_FILE_HANDLE OutShellFileHandle, + IN CONST CHAR16 *OutFileName + ) +{ + EFI_STATUS Status; + UINT64 OutSize; + UINTN OutSize2; + VOID *OutBuffer; + UINT64 InSize; + UINTN InSize2; + VOID *InBuffer; + SHELL_STATUS ShellStatus; + + OutSize = 0; + OutBuffer = NULL; + InBuffer = NULL; + ShellStatus = SHELL_SUCCESS; + + Status = gEfiShellProtocol->GetFileSize (InShellFileHandle, &InSize); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); + return SHELL_DEVICE_ERROR; + } + + InBuffer = AllocateZeroPool ((UINTN)InSize); + if (InBuffer == NULL) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, EFI_OUT_OF_RESOURCES); + return SHELL_OUT_OF_RESOURCES; + } + + InSize2 = (UINTN)InSize; + Status = gEfiShellProtocol->ReadFile (InShellFileHandle, &InSize2, InBuffer); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); + ShellStatus = SHELL_DEVICE_ERROR; + goto Exit; + } + + InSize = InSize2; + Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + OutBuffer = AllocateZeroPool ((UINTN)OutSize); + if (OutBuffer == NULL) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, EFI_OUT_OF_RESOURCES); + ShellStatus = SHELL_OUT_OF_RESOURCES; + goto Exit; + } + + Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); + } + + if (EFI_ERROR (Status)) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); + ShellStatus = SHELL_DEVICE_ERROR; + goto Exit; + } + + OutSize2 = (UINTN)OutSize; + Status = gEfiShellProtocol->WriteFile (OutShellFileHandle, &OutSize2, OutBuffer); + if (EFI_ERROR (Status)) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"eficompress", OutFileName); + ShellStatus = SHELL_DEVICE_ERROR; + goto Exit; + } + +Exit: + SHELL_FREE_NON_NULL (InBuffer); + SHELL_FREE_NON_NULL (OutBuffer); + + return ShellStatus; +} + +/** + Validate that a path is not a directory and open it with the requested mode. + + @param[in] FileName Path to open. + @param[in] OpenMode Mode passed to ShellOpenFileByName(). + @param[out] ShellFileHandle Opened shell file handle. + + @retval SHELL_SUCCESS The file was opened successfully. + @retval SHELL_INVALID_PARAMETER FileName names a directory. + @retval SHELL_NOT_FOUND The file could not be opened. +**/ +STATIC +SHELL_STATUS +OpenFileHelper ( + IN CONST CHAR16 *FileName, + IN UINT64 OpenMode, + OUT SHELL_FILE_HANDLE *ShellFileHandle + ) +{ + EFI_STATUS Status; + + ASSERT (ShellFileHandle != NULL); + + if (ShellIsDirectory (FileName) == EFI_SUCCESS) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", FileName); + return SHELL_INVALID_PARAMETER; + } + + Status = ShellOpenFileByName (FileName, ShellFileHandle, OpenMode, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", FileName); + return SHELL_NOT_FOUND; + } + + return SHELL_SUCCESS; +} + /** Main function of the 'EfiCompress' command. @param[in] Package List of input parameter for the command. @@ -20,29 +147,18 @@ MainCmdEfiCompress ( LIST_ENTRY *Package ) { - EFI_STATUS Status; SHELL_STATUS ShellStatus; SHELL_FILE_HANDLE InShellFileHandle; SHELL_FILE_HANDLE OutShellFileHandle; - UINT64 OutSize; - UINTN OutSize2; - VOID *OutBuffer; - UINT64 InSize; - UINTN InSize2; - VOID *InBuffer; CHAR16 *InFileName; CONST CHAR16 *OutFileName; CONST CHAR16 *TempParam; InFileName = NULL; OutFileName = NULL; - OutSize = 0; ShellStatus = SHELL_SUCCESS; - Status = EFI_SUCCESS; - OutBuffer = NULL; InShellFileHandle = NULL; OutShellFileHandle = NULL; - InBuffer = NULL; if (ShellCommandLineGetCount (Package) > 3) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"eficompress"); @@ -60,75 +176,24 @@ MainCmdEfiCompress ( } InFileName = ShellFindFilePath (TempParam); - OutFileName = ShellCommandLineGetRawValue (Package, 2); + OutFileName = (CHAR16 *)ShellCommandLineGetRawValue (Package, 2); if ((InFileName == NULL) || (OutFileName == NULL)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"eficompress", TempParam); ShellStatus = SHELL_NOT_FOUND; goto Exit; } - if (ShellIsDirectory (InFileName) == EFI_SUCCESS) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", InFileName); - ShellStatus = SHELL_INVALID_PARAMETER; - } - - if (ShellIsDirectory (OutFileName) == EFI_SUCCESS) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", OutFileName); - ShellStatus = SHELL_INVALID_PARAMETER; - } - + ShellStatus = OpenFileHelper (InFileName, EFI_FILE_MODE_READ, &InShellFileHandle); if (ShellStatus != SHELL_SUCCESS) { goto Exit; } - Status = ShellOpenFileByName (InFileName, &InShellFileHandle, EFI_FILE_MODE_READ, 0); - if (EFI_ERROR (Status)) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue (Package, 1)); - ShellStatus = SHELL_NOT_FOUND; - } - - Status = ShellOpenFileByName (OutFileName, &OutShellFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); - if (EFI_ERROR (Status)) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue (Package, 2)); - ShellStatus = SHELL_NOT_FOUND; - } - + ShellStatus = OpenFileHelper (OutFileName, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, &OutShellFileHandle); if (ShellStatus != SHELL_SUCCESS) { goto Exit; } - Status = gEfiShellProtocol->GetFileSize (InShellFileHandle, &InSize); - ASSERT_EFI_ERROR (Status); - InBuffer = AllocateZeroPool ((UINTN)InSize); - if (InBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { - InSize2 = (UINTN)InSize; - Status = gEfiShellProtocol->ReadFile (InShellFileHandle, &InSize2, InBuffer); - InSize = InSize2; - ASSERT_EFI_ERROR (Status); - Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); - if (Status == EFI_BUFFER_TOO_SMALL) { - OutBuffer = AllocateZeroPool ((UINTN)OutSize); - if (OutBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { - Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); - } - } - } - - if (EFI_ERROR (Status)) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); - ShellStatus = ((Status == EFI_OUT_OF_RESOURCES) ? SHELL_OUT_OF_RESOURCES : SHELL_DEVICE_ERROR); - } else { - OutSize2 = (UINTN)OutSize; - Status = gEfiShellProtocol->WriteFile (OutShellFileHandle, &OutSize2, OutBuffer); - if (EFI_ERROR (Status)) { - ShellPrintHiiDefaultEx (STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"eficompress", OutFileName); - ShellStatus = SHELL_DEVICE_ERROR; - } - } + ShellStatus = CompressFile (InShellFileHandle, OutShellFileHandle, OutFileName); Exit: if (InShellFileHandle != NULL) { @@ -140,8 +205,6 @@ Exit: } SHELL_FREE_NON_NULL (InFileName); - SHELL_FREE_NON_NULL (InBuffer); - SHELL_FREE_NON_NULL (OutBuffer); return ShellStatus; }