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