]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/CapsuleApp/AppSupport.c
MdeModulePkg CapsuleApp: Add directory support
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / AppSupport.c
1 /** @file
2 A shell application that triggers capsule update process.
3
4 Copyright (c) 2016 - 2017, 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 <Uefi.h>
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Protocol/SimpleFileSystem.h>
22 #include <Protocol/ShellParameters.h>
23 #include <Protocol/Shell.h>
24 #include <Guid/FileInfo.h>
25
26 UINTN Argc;
27 CHAR16 **Argv;
28 EFI_SHELL_PROTOCOL *mShellProtocol = NULL;
29
30 /**
31
32 This function parse application ARG.
33
34 @return Status
35 **/
36 EFI_STATUS
37 GetArg (
38 VOID
39 )
40 {
41 EFI_STATUS Status;
42 EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
43
44 Status = gBS->HandleProtocol (
45 gImageHandle,
46 &gEfiShellParametersProtocolGuid,
47 (VOID**)&ShellParameters
48 );
49 if (EFI_ERROR(Status)) {
50 return Status;
51 }
52
53 Argc = ShellParameters->Argc;
54 Argv = ShellParameters->Argv;
55 return EFI_SUCCESS;
56 }
57
58 /**
59 Get shell protocol.
60
61 @return Pointer to shell protocol.
62 **/
63 EFI_SHELL_PROTOCOL *
64 GetShellProtocol (
65 VOID
66 )
67 {
68 EFI_STATUS Status;
69
70 if (mShellProtocol == NULL) {
71 Status = gBS->LocateProtocol (
72 &gEfiShellProtocolGuid,
73 NULL,
74 (VOID **) &mShellProtocol
75 );
76 if (EFI_ERROR (Status)) {
77 mShellProtocol = NULL;
78 }
79 }
80
81 return mShellProtocol;
82 }
83
84 /**
85 Read a file.
86
87 @param[in] FileName The file to be read.
88 @param[out] BufferSize The file buffer size
89 @param[out] Buffer The file buffer
90
91 @retval EFI_SUCCESS Read file successfully
92 @retval EFI_NOT_FOUND Shell protocol or file not found
93 @retval others Read file failed
94 **/
95 EFI_STATUS
96 ReadFileToBuffer (
97 IN CHAR16 *FileName,
98 OUT UINTN *BufferSize,
99 OUT VOID **Buffer
100 )
101 {
102 EFI_STATUS Status;
103 EFI_SHELL_PROTOCOL *ShellProtocol;
104 SHELL_FILE_HANDLE Handle;
105 UINT64 FileSize;
106 UINTN TempBufferSize;
107 VOID *TempBuffer;
108
109 ShellProtocol = GetShellProtocol();
110 if (ShellProtocol == NULL) {
111 return EFI_NOT_FOUND;
112 }
113
114 //
115 // Open file by FileName.
116 //
117 Status = ShellProtocol->OpenFileByName (
118 FileName,
119 &Handle,
120 EFI_FILE_MODE_READ
121 );
122 if (EFI_ERROR (Status)) {
123 return Status;
124 }
125
126 //
127 // Get the file size.
128 //
129 Status = ShellProtocol->GetFileSize (Handle, &FileSize);
130 if (EFI_ERROR (Status)) {
131 ShellProtocol->CloseFile (Handle);
132 return Status;
133 }
134
135 TempBufferSize = (UINTN) FileSize;
136 TempBuffer = AllocateZeroPool (TempBufferSize);
137 if (TempBuffer == NULL) {
138 ShellProtocol->CloseFile (Handle);
139 return EFI_OUT_OF_RESOURCES;
140 }
141
142 //
143 // Read the file data to the buffer
144 //
145 Status = ShellProtocol->ReadFile (
146 Handle,
147 &TempBufferSize,
148 TempBuffer
149 );
150 if (EFI_ERROR (Status)) {
151 ShellProtocol->CloseFile (Handle);
152 return Status;
153 }
154
155 ShellProtocol->CloseFile (Handle);
156
157 *BufferSize = TempBufferSize;
158 *Buffer = TempBuffer;
159 return EFI_SUCCESS;
160 }
161
162 /**
163 Write a file.
164
165 @param[in] FileName The file to be written.
166 @param[in] BufferSize The file buffer size
167 @param[in] Buffer The file buffer
168
169 @retval EFI_SUCCESS Write file successfully
170 @retval EFI_NOT_FOUND Shell protocol not found
171 @retval others Write file failed
172 **/
173 EFI_STATUS
174 WriteFileFromBuffer (
175 IN CHAR16 *FileName,
176 IN UINTN BufferSize,
177 IN VOID *Buffer
178 )
179 {
180 EFI_STATUS Status;
181 EFI_SHELL_PROTOCOL *ShellProtocol;
182 SHELL_FILE_HANDLE Handle;
183 EFI_FILE_INFO *FileInfo;
184 UINTN TempBufferSize;
185
186 ShellProtocol = GetShellProtocol();
187 if (ShellProtocol == NULL) {
188 return EFI_NOT_FOUND;
189 }
190
191 //
192 // Open file by FileName.
193 //
194 Status = ShellProtocol->OpenFileByName (
195 FileName,
196 &Handle,
197 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE
198 );
199 if (EFI_ERROR (Status)) {
200 return Status;
201 }
202
203 //
204 // Empty the file contents.
205 //
206 FileInfo = ShellProtocol->GetFileInfo (Handle);
207 if (FileInfo == NULL) {
208 ShellProtocol->CloseFile (Handle);
209 return EFI_DEVICE_ERROR;
210 }
211
212 //
213 // If the file size is already 0, then it has been empty.
214 //
215 if (FileInfo->FileSize != 0) {
216 //
217 // Set the file size to 0.
218 //
219 FileInfo->FileSize = 0;
220 Status = ShellProtocol->SetFileInfo (Handle, FileInfo);
221 if (EFI_ERROR (Status)) {
222 FreePool (FileInfo);
223 ShellProtocol->CloseFile (Handle);
224 return Status;
225 }
226 }
227 FreePool (FileInfo);
228
229 //
230 // Write the file data from the buffer
231 //
232 TempBufferSize = BufferSize;
233 Status = ShellProtocol->WriteFile (
234 Handle,
235 &TempBufferSize,
236 Buffer
237 );
238 if (EFI_ERROR (Status)) {
239 ShellProtocol->CloseFile (Handle);
240 return Status;
241 }
242
243 ShellProtocol->CloseFile (Handle);
244
245 return EFI_SUCCESS;
246 }
247