• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ShellCommandRunEfiDecompress(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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