]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/EfiDecompress.c
ShellPkg/Dp: Add null pointer check
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / EfiDecompress.c
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 }