1 /** @file
2   Main file for EfiCompress shell Debug1 function.
3 
4   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2005 - 2011, 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 "Compress.h"
18 
19 /**
20   Function for 'compress' command.
21 
22   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
23   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
24 **/
25 SHELL_STATUS
26 EFIAPI
ShellCommandRunEfiCompress(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)27 ShellCommandRunEfiCompress (
28   IN EFI_HANDLE        ImageHandle,
29   IN EFI_SYSTEM_TABLE  *SystemTable
30   )
31 {
32   EFI_STATUS          Status;
33   LIST_ENTRY          *Package;
34   CHAR16              *ProblemParam;
35   SHELL_STATUS        ShellStatus;
36   SHELL_FILE_HANDLE   InShellFileHandle;
37   SHELL_FILE_HANDLE   OutShellFileHandle;
38   UINT64              OutSize;
39   UINTN               OutSize2;
40   VOID                *OutBuffer;
41   UINT64              InSize;
42   UINTN               InSize2;
43   VOID                *InBuffer;
44   CHAR16              *InFileName;
45   CONST CHAR16        *OutFileName;
46   CONST CHAR16        *TempParam;
47 
48   InFileName          = NULL;
49   OutFileName         = NULL;
50   OutSize             = 0;
51   ShellStatus         = SHELL_SUCCESS;
52   Status              = EFI_SUCCESS;
53   OutBuffer           = NULL;
54   InShellFileHandle   = NULL;
55   OutShellFileHandle  = NULL;
56   InBuffer            = NULL;
57 
58   //
59   // initialize the shell lib (we must be in non-auto-init...)
60   //
61   Status = ShellInitialize();
62   ASSERT_EFI_ERROR(Status);
63 
64   Status = CommandInit();
65   ASSERT_EFI_ERROR(Status);
66 
67   //
68   // parse the command line
69   //
70   Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);
71   if (EFI_ERROR(Status)) {
72     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
73       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"eficompress", ProblemParam);
74       FreePool(ProblemParam);
75       ShellStatus = SHELL_INVALID_PARAMETER;
76     } else {
77       ASSERT(FALSE);
78     }
79   } else {
80     if (ShellCommandLineGetCount(Package) > 3) {
81       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"eficompress");
82       ShellStatus = SHELL_INVALID_PARAMETER;
83     } else if (ShellCommandLineGetCount(Package) < 3) {
84       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"eficompress");
85       ShellStatus = SHELL_INVALID_PARAMETER;
86     } else {
87       TempParam = ShellCommandLineGetRawValue(Package, 1);
88       ASSERT(TempParam != NULL);
89       InFileName = ShellFindFilePath(TempParam);
90       OutFileName = ShellCommandLineGetRawValue(Package, 2);
91       if (InFileName == NULL) {
92         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"eficompress", TempParam);
93         ShellStatus = SHELL_NOT_FOUND;
94       } else {
95         if (ShellIsDirectory(InFileName) == EFI_SUCCESS){
96           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", InFileName);
97           ShellStatus = SHELL_INVALID_PARAMETER;
98         }
99         if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){
100           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", OutFileName);
101           ShellStatus = SHELL_INVALID_PARAMETER;
102         }
103         if (ShellStatus == SHELL_SUCCESS) {
104           Status = ShellOpenFileByName(InFileName, &InShellFileHandle, EFI_FILE_MODE_READ, 0);
105           if (EFI_ERROR(Status)) {
106             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 1));
107             ShellStatus = SHELL_NOT_FOUND;
108           }
109           Status = ShellOpenFileByName(OutFileName, &OutShellFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
110           if (EFI_ERROR(Status)) {
111             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 2));
112             ShellStatus = SHELL_NOT_FOUND;
113           }
114         }
115         if (ShellStatus == SHELL_SUCCESS) {
116           Status = gEfiShellProtocol->GetFileSize(InShellFileHandle, &InSize);
117           ASSERT_EFI_ERROR(Status);
118           InBuffer = AllocateZeroPool((UINTN)InSize);
119           ASSERT(InBuffer != NULL);
120           InSize2 = (UINTN)InSize;
121           Status = gEfiShellProtocol->ReadFile(InShellFileHandle, &InSize2, InBuffer);
122           InSize = InSize2;
123           ASSERT_EFI_ERROR(Status);
124           Status = Compress(InBuffer, InSize, OutBuffer, &OutSize);
125           if (Status == EFI_BUFFER_TOO_SMALL) {
126             OutBuffer = AllocateZeroPool((UINTN)OutSize);
127             ASSERT(OutBuffer != NULL);
128             Status = Compress(InBuffer, InSize, OutBuffer, &OutSize);
129           }
130           if (EFI_ERROR(Status)) {
131             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status);
132             ShellStatus = SHELL_DEVICE_ERROR;
133           } else {
134             OutSize2 = (UINTN)OutSize;
135             Status = gEfiShellProtocol->WriteFile(OutShellFileHandle, &OutSize2, OutBuffer);
136             if (EFI_ERROR(Status)) {
137               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"eficompress", OutFileName);
138               ShellStatus = SHELL_DEVICE_ERROR;
139             }
140           }
141         }
142       }
143     }
144 
145     ShellCommandLineFreeVarList (Package);
146   }
147   if (InShellFileHandle != NULL) {
148     gEfiShellProtocol->CloseFile(InShellFileHandle);
149   }
150   if (OutShellFileHandle != NULL) {
151     gEfiShellProtocol->CloseFile(OutShellFileHandle);
152   }
153   SHELL_FREE_NON_NULL(InFileName);
154   SHELL_FREE_NON_NULL(InBuffer);
155   SHELL_FREE_NON_NULL(OutBuffer);
156 
157   return (ShellStatus);
158 }
159