Home | History | Annotate | Download | only in UefiShellDebug1CommandsLib
      1 /** @file
      2   Main file for EfiDecompress shell Debug1 function.
      3 
      4   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
      5   Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "UefiShellDebug1CommandsLib.h"
     17 #include <Protocol/Decompress.h>
     18 
     19 
     20 /**
     21   Function for 'decompress' command.
     22 
     23   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
     24   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
     25 **/
     26 SHELL_STATUS
     27 EFIAPI
     28 ShellCommandRunEfiDecompress (
     29   IN EFI_HANDLE        ImageHandle,
     30   IN EFI_SYSTEM_TABLE  *SystemTable
     31   )
     32 {
     33   EFI_STATUS          Status;
     34   LIST_ENTRY          *Package;
     35   CHAR16              *ProblemParam;
     36   SHELL_STATUS        ShellStatus;
     37   SHELL_FILE_HANDLE   InFileHandle;
     38   SHELL_FILE_HANDLE   OutFileHandle;
     39   UINT32              OutSize;
     40   UINTN               OutSizeTemp;
     41   VOID                *OutBuffer;
     42   UINTN               InSize;
     43   VOID                *InBuffer;
     44   CHAR16              *InFileName;
     45   CONST CHAR16        *OutFileName;
     46   UINT64              Temp64Bit;
     47   UINT32              ScratchSize;
     48   VOID                *ScratchBuffer;
     49   EFI_DECOMPRESS_PROTOCOL *Decompress;
     50   CONST CHAR16        *TempParam;
     51 
     52   InFileName          = NULL;
     53   OutFileName         = NULL;
     54   OutSize             = 0;
     55   ScratchSize         = 0;
     56   ShellStatus         = SHELL_SUCCESS;
     57   Status              = EFI_SUCCESS;
     58   OutBuffer           = NULL;
     59   InBuffer            = NULL;
     60   ScratchBuffer       = NULL;
     61   InFileHandle        = NULL;
     62   OutFileHandle       = NULL;
     63   Decompress          = NULL;
     64 
     65   //
     66   // initialize the shell lib (we must be in non-auto-init...)
     67   //
     68   Status = ShellInitialize();
     69   ASSERT_EFI_ERROR(Status);
     70 
     71   Status = CommandInit();
     72   ASSERT_EFI_ERROR(Status);
     73 
     74   //
     75   // parse the command line
     76   //
     77   Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
     78   if (EFI_ERROR(Status)) {
     79     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
     80       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"efidecompress", ProblemParam);
     81       FreePool(ProblemParam);
     82       ShellStatus = SHELL_INVALID_PARAMETER;
     83     } else {
     84       ASSERT(FALSE);
     85     }
     86   } else {
     87     if (ShellCommandLineGetCount(Package) > 3) {
     88       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"efidecompress");
     89       ShellStatus = SHELL_INVALID_PARAMETER;
     90     } else if (ShellCommandLineGetCount(Package) < 3) {
     91       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"efidecompress");
     92       ShellStatus = SHELL_INVALID_PARAMETER;
     93     } else {
     94       TempParam = ShellCommandLineGetRawValue(Package, 1);
     95       ASSERT(TempParam != NULL);
     96       InFileName = ShellFindFilePath(TempParam);
     97       OutFileName = ShellCommandLineGetRawValue(Package, 2);
     98       if (InFileName == NULL) {
     99         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"efidecompress", TempParam);
    100         ShellStatus = SHELL_NOT_FOUND;
    101       } else {
    102         if (ShellIsDirectory(InFileName) == EFI_SUCCESS){
    103           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", InFileName);
    104           ShellStatus = SHELL_INVALID_PARAMETER;
    105         }
    106         if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){
    107           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", OutFileName);
    108           ShellStatus = SHELL_INVALID_PARAMETER;
    109         }
    110         if (ShellStatus == SHELL_SUCCESS) {
    111           Status = ShellOpenFileByName(InFileName, &InFileHandle, EFI_FILE_MODE_READ, 0);
    112           if (EFI_ERROR(Status)) {
    113             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"efidecompress", ShellCommandLineGetRawValue(Package, 1));
    114             ShellStatus = SHELL_NOT_FOUND;
    115           }
    116         }
    117 
    118         if (ShellStatus == SHELL_SUCCESS) {
    119           Status = FileHandleGetSize(InFileHandle, &Temp64Bit);
    120           ASSERT(Temp64Bit <= (UINT32)(-1));
    121           InSize = (UINTN)Temp64Bit;
    122           ASSERT_EFI_ERROR(Status);
    123           InBuffer = AllocateZeroPool(InSize);
    124           if (InBuffer == NULL) {
    125             Status = EFI_OUT_OF_RESOURCES;
    126           } else {
    127             Status = gEfiShellProtocol->ReadFile (InFileHandle, &InSize, InBuffer);
    128             ASSERT_EFI_ERROR (Status);
    129 
    130             Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID**) &Decompress);
    131             ASSERT_EFI_ERROR (Status);
    132 
    133             Status = Decompress->GetInfo (Decompress, InBuffer, (UINT32) InSize, &OutSize, &ScratchSize);
    134           }
    135 
    136           if (EFI_ERROR(Status) || OutSize == 0) {
    137             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_NOPE), gShellDebug1HiiHandle, InFileName);
    138             ShellStatus = SHELL_NOT_FOUND;
    139           } else {
    140             Status = ShellOpenFileByName(OutFileName, &OutFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
    141             if (EFI_ERROR(Status)) {
    142               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, 2), Status);
    143               ShellStatus = SHELL_NOT_FOUND;
    144             } else {
    145               OutBuffer = AllocateZeroPool(OutSize);
    146               ScratchBuffer = AllocateZeroPool(ScratchSize);
    147               if (OutBuffer == NULL || ScratchBuffer == NULL) {
    148                 Status = EFI_OUT_OF_RESOURCES;
    149               } else {
    150                 Status = Decompress->Decompress (Decompress, InBuffer, (UINT32) InSize, OutBuffer, OutSize, ScratchBuffer, ScratchSize);
    151               }
    152             }
    153           }
    154 
    155           if (EFI_ERROR (Status)) {
    156             ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_FAIL), gShellDebug1HiiHandle, Status);
    157             ShellStatus = ((Status == EFI_OUT_OF_RESOURCES) ? SHELL_OUT_OF_RESOURCES : SHELL_DEVICE_ERROR);
    158           } else {
    159             OutSizeTemp = OutSize;
    160             Status = gEfiShellProtocol->WriteFile (OutFileHandle, &OutSizeTemp, OutBuffer);
    161             OutSize = (UINT32) OutSizeTemp;
    162             if (EFI_ERROR (Status)) {
    163               ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"efidecompress", OutFileName, Status);
    164               ShellStatus = SHELL_DEVICE_ERROR;
    165             }
    166           }
    167         }
    168       }
    169     }
    170 
    171     ShellCommandLineFreeVarList (Package);
    172   }
    173   if (InFileHandle != NULL) {
    174     gEfiShellProtocol->CloseFile(InFileHandle);
    175   }
    176   if (OutFileHandle != NULL) {
    177     gEfiShellProtocol->CloseFile(OutFileHandle);
    178   }
    179 
    180   SHELL_FREE_NON_NULL(InFileName);
    181   SHELL_FREE_NON_NULL(InBuffer);
    182   SHELL_FREE_NON_NULL(OutBuffer);
    183   SHELL_FREE_NON_NULL(ScratchBuffer);
    184 
    185   return (ShellStatus);
    186 }
    187