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 - 2014, 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   ShellStatus         = SHELL_SUCCESS;
     56   Status              = EFI_SUCCESS;
     57   OutBuffer           = NULL;
     58   InBuffer            = NULL;
     59   ScratchBuffer       = NULL;
     60   InFileHandle        = NULL;
     61   OutFileHandle       = NULL;
     62 
     63   //
     64   // initialize the shell lib (we must be in non-auto-init...)
     65   //
     66   Status = ShellInitialize();
     67   ASSERT_EFI_ERROR(Status);
     68 
     69   Status = CommandInit();
     70   ASSERT_EFI_ERROR(Status);
     71 
     72   //
     73   // parse the command line
     74   //
     75   Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
     76   if (EFI_ERROR(Status)) {
     77     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
     78       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"efidecompress", ProblemParam);
     79       FreePool(ProblemParam);
     80       ShellStatus = SHELL_INVALID_PARAMETER;
     81     } else {
     82       ASSERT(FALSE);
     83     }
     84   } else {
     85     if (ShellCommandLineGetCount(Package) > 3) {
     86       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"efidecompress");
     87       ShellStatus = SHELL_INVALID_PARAMETER;
     88     } else if (ShellCommandLineGetCount(Package) < 3) {
     89       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"efidecompress");
     90       ShellStatus = SHELL_INVALID_PARAMETER;
     91     } else {
     92       TempParam = ShellCommandLineGetRawValue(Package, 1);
     93       ASSERT(TempParam != NULL);
     94       InFileName = ShellFindFilePath(TempParam);
     95       OutFileName = ShellCommandLineGetRawValue(Package, 2);
     96       if (InFileName == NULL) {
     97         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"efidecompress", TempParam);
     98         ShellStatus = SHELL_NOT_FOUND;
     99       } else {
    100         if (ShellIsDirectory(InFileName) == EFI_SUCCESS){
    101           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", InFileName);
    102           ShellStatus = SHELL_INVALID_PARAMETER;
    103         }
    104         if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){
    105           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"efidecompress", OutFileName);
    106           ShellStatus = SHELL_INVALID_PARAMETER;
    107         }
    108         if (ShellStatus == SHELL_SUCCESS) {
    109           Status = ShellOpenFileByName(InFileName, &InFileHandle, EFI_FILE_MODE_READ, 0);
    110           if (EFI_ERROR(Status)) {
    111             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"efidecompress", ShellCommandLineGetRawValue(Package, 1));
    112             ShellStatus = SHELL_NOT_FOUND;
    113           }
    114         }
    115 
    116         if (ShellStatus == SHELL_SUCCESS) {
    117           Status = FileHandleGetSize(InFileHandle, &Temp64Bit);
    118           ASSERT(Temp64Bit <= (UINT32)(-1));
    119           InSize = (UINTN)Temp64Bit;
    120           ASSERT_EFI_ERROR(Status);
    121           InBuffer = AllocateZeroPool(InSize);
    122           ASSERT(InBuffer != NULL);
    123           Status = gEfiShellProtocol->ReadFile(InFileHandle, &InSize, InBuffer);
    124           ASSERT_EFI_ERROR(Status);
    125 
    126           Status = gBS->LocateProtocol(&gEfiDecompressProtocolGuid, NULL, (VOID**)&Decompress);
    127           ASSERT_EFI_ERROR(Status);
    128 
    129           Status = Decompress->GetInfo(Decompress, InBuffer, (UINT32)InSize, &OutSize, &ScratchSize);
    130           if (EFI_ERROR(Status) || OutSize == 0) {
    131             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_NOPE), gShellDebug1HiiHandle, InFileName);
    132             ShellStatus = SHELL_NOT_FOUND;
    133           } else {
    134             Status = ShellOpenFileByName(OutFileName, &OutFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
    135             if (EFI_ERROR(Status)) {
    136               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, 2), Status);
    137               ShellStatus = SHELL_NOT_FOUND;
    138             } else {
    139               OutBuffer = AllocateZeroPool(OutSize);
    140               ScratchBuffer = AllocateZeroPool(ScratchSize);
    141               ASSERT(OutBuffer != NULL);
    142               ASSERT(ScratchBuffer != NULL);
    143 
    144               Status = Decompress->Decompress(Decompress, InBuffer, (UINT32)InSize, OutBuffer, OutSize, ScratchBuffer, ScratchSize);
    145               ASSERT_EFI_ERROR(Status);
    146 
    147               if (EFI_ERROR(Status)) {
    148                 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_FAIL), gShellDebug1HiiHandle, Status);
    149                 ShellStatus = SHELL_DEVICE_ERROR;
    150               } else {
    151                 OutSizeTemp = OutSize;
    152                 Status = gEfiShellProtocol->WriteFile(OutFileHandle, &OutSizeTemp, OutBuffer);
    153                 OutSize = (UINT32)OutSizeTemp;
    154                 if (EFI_ERROR(Status)) {
    155                   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"efidecompress", OutFileName, Status);
    156                   ShellStatus = SHELL_DEVICE_ERROR;
    157                 }
    158               }
    159             }
    160           }
    161         }
    162       }
    163     }
    164 
    165     ShellCommandLineFreeVarList (Package);
    166   }
    167   if (InFileHandle != NULL) {
    168     gEfiShellProtocol->CloseFile(InFileHandle);
    169   }
    170   if (OutFileHandle != NULL) {
    171     gEfiShellProtocol->CloseFile(OutFileHandle);
    172   }
    173 
    174   SHELL_FREE_NON_NULL(InFileName);
    175   SHELL_FREE_NON_NULL(InBuffer);
    176   SHELL_FREE_NON_NULL(OutBuffer);
    177   SHELL_FREE_NON_NULL(ScratchBuffer);
    178 
    179   return (ShellStatus);
    180 }
    181