]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/CapsuleApp/AppSupport.c
MdeModulePkg DxeCore: Fix issue to print GUID value %g without pointer
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / AppSupport.c
CommitLineData
592bad04
JY
1/** @file\r
2 A shell application that triggers capsule update process.\r
3\r
787f6744 4 Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
592bad04
JY
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/UefiRuntimeServicesTableLib.h>\r
22#include <Library/UefiLib.h>\r
23#include <Library/PrintLib.h>\r
24#include <Protocol/LoadedImage.h>\r
25#include <Protocol/SimpleFileSystem.h>\r
26#include <Protocol/ShellParameters.h>\r
27#include <Guid/FileInfo.h>\r
28#include <Guid/Gpt.h>\r
29\r
1e09ec09
JY
30#define IS_HYPHEN(a) ((a) == L'-')\r
31#define IS_NULL(a) ((a) == L'\0')\r
32\r
592bad04
JY
33#define MAX_ARG_NUM 11\r
34\r
35UINTN Argc;\r
36CHAR16 **Argv;\r
37\r
38/**\r
39\r
40 This function parse application ARG.\r
41\r
42 @return Status\r
43**/\r
44EFI_STATUS\r
45GetArg (\r
46 VOID\r
47 )\r
48{\r
49 EFI_STATUS Status;\r
50 EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;\r
51\r
52 Status = gBS->HandleProtocol (\r
53 gImageHandle,\r
54 &gEfiShellParametersProtocolGuid,\r
55 (VOID**)&ShellParameters\r
56 );\r
57 if (EFI_ERROR(Status)) {\r
58 return Status;\r
59 }\r
60\r
61 Argc = ShellParameters->Argc;\r
62 Argv = ShellParameters->Argv;\r
63 return EFI_SUCCESS;\r
64}\r
65\r
66/**\r
67 Return File System Volume containing this shell application.\r
68\r
69 @return File System Volume containing this shell application.\r
70**/\r
71EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *\r
72GetMyVol (\r
73 VOID\r
74 )\r
75{\r
76 EFI_STATUS Status;\r
77 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
78 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
79\r
80 Status = gBS->HandleProtocol (\r
81 gImageHandle,\r
82 &gEfiLoadedImageProtocolGuid,\r
83 (VOID **)&LoadedImage\r
84 );\r
85 ASSERT_EFI_ERROR (Status);\r
86\r
87 Status = gBS->HandleProtocol (\r
88 LoadedImage->DeviceHandle,\r
89 &gEfiSimpleFileSystemProtocolGuid,\r
90 (VOID **)&Vol\r
91 );\r
92 if (!EFI_ERROR (Status)) {\r
93 return Vol;\r
94 }\r
95\r
96 return NULL;\r
97}\r
98\r
99/**\r
100 Read a file from this volume.\r
101\r
102 @param[in] Vol File System Volume\r
103 @param[in] FileName The file to be read.\r
104 @param[out] BufferSize The file buffer size\r
105 @param[out] Buffer The file buffer\r
106\r
107 @retval EFI_SUCCESS Read file successfully\r
108 @retval EFI_NOT_FOUND File not found\r
109**/\r
110EFI_STATUS\r
111ReadFileFromVol (\r
112 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol,\r
113 IN CHAR16 *FileName,\r
114 OUT UINTN *BufferSize,\r
115 OUT VOID **Buffer\r
116 )\r
117{\r
118 EFI_STATUS Status;\r
119 EFI_FILE_HANDLE RootDir;\r
120 EFI_FILE_HANDLE Handle;\r
121 UINTN FileInfoSize;\r
122 EFI_FILE_INFO *FileInfo;\r
123 UINTN TempBufferSize;\r
124 VOID *TempBuffer;\r
125\r
126 //\r
127 // Open the root directory\r
128 //\r
129 Status = Vol->OpenVolume (Vol, &RootDir);\r
130 if (EFI_ERROR (Status)) {\r
131 return Status;\r
132 }\r
133\r
134 //\r
135 // Open the file\r
136 //\r
137 Status = RootDir->Open (\r
138 RootDir,\r
139 &Handle,\r
140 FileName,\r
141 EFI_FILE_MODE_READ,\r
142 0\r
143 );\r
144 if (EFI_ERROR (Status)) {\r
145 RootDir->Close (RootDir);\r
146 return Status;\r
147 }\r
148\r
149 RootDir->Close (RootDir);\r
150\r
151 //\r
152 // Get the file information\r
153 //\r
154 FileInfoSize = sizeof(EFI_FILE_INFO) + 1024;\r
155\r
156 FileInfo = AllocateZeroPool (FileInfoSize);\r
157 if (FileInfo == NULL) {\r
158 Handle->Close (Handle);\r
159 return Status;\r
160 }\r
161\r
162 Status = Handle->GetInfo (\r
163 Handle,\r
164 &gEfiFileInfoGuid,\r
165 &FileInfoSize,\r
166 FileInfo\r
167 );\r
168 if (EFI_ERROR (Status)) {\r
169 Handle->Close (Handle);\r
170 gBS->FreePool (FileInfo);\r
171 return Status;\r
172 }\r
173\r
174 //\r
175 // Allocate buffer for the file data. The last CHAR16 is for L'\0'\r
176 //\r
177 TempBufferSize = (UINTN) FileInfo->FileSize + sizeof(CHAR16);\r
178 TempBuffer = AllocateZeroPool (TempBufferSize);\r
179 if (TempBuffer == NULL) {\r
180 Handle->Close (Handle);\r
181 gBS->FreePool (FileInfo);\r
182 return Status;\r
183 }\r
184\r
185 gBS->FreePool (FileInfo);\r
186\r
187 //\r
188 // Read the file data to the buffer\r
189 //\r
190 Status = Handle->Read (\r
191 Handle,\r
192 &TempBufferSize,\r
193 TempBuffer\r
194 );\r
195 if (EFI_ERROR (Status)) {\r
196 Handle->Close (Handle);\r
197 gBS->FreePool (TempBuffer);\r
198 return Status;\r
199 }\r
200\r
201 Handle->Close (Handle);\r
202\r
203 *BufferSize = TempBufferSize;\r
204 *Buffer = TempBuffer;\r
205 return EFI_SUCCESS;\r
206}\r
207\r
208/**\r
209 Read a file.\r
210 If ScanFs is FLASE, it will use this Vol as default Fs.\r
211 If ScanFs is TRUE, it will scan all FS and check the file.\r
212 If there is only one file match the name, it will be read.\r
213 If there is more than one file match the name, it will return Error.\r
214\r
11ee1bc9
DB
215 @param[in,out] ThisVol File System Volume\r
216 @param[in] FileName The file to be read.\r
217 @param[out] BufferSize The file buffer size\r
218 @param[out] Buffer The file buffer\r
219 @param[in] ScanFs Need Scan all FS\r
592bad04
JY
220\r
221 @retval EFI_SUCCESS Read file successfully\r
222 @retval EFI_NOT_FOUND File not found\r
223 @retval EFI_NO_MAPPING There is duplicated files found\r
224**/\r
225EFI_STATUS\r
226ReadFileToBufferEx (\r
227 IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **ThisVol,\r
228 IN CHAR16 *FileName,\r
229 OUT UINTN *BufferSize,\r
230 OUT VOID **Buffer,\r
231 IN BOOLEAN ScanFs\r
232 )\r
233{\r
234 EFI_STATUS Status;\r
235 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
236 UINTN TempBufferSize;\r
237 VOID *TempBuffer;\r
238 UINTN NoHandles;\r
239 EFI_HANDLE *HandleBuffer;\r
240 UINTN Index;\r
241\r
242 //\r
243 // Check parameters\r
244 //\r
245 if ((FileName == NULL) || (Buffer == NULL) || (ThisVol == NULL)) {\r
246 return EFI_INVALID_PARAMETER;\r
247 }\r
248\r
249 //\r
250 // not scan fs\r
251 //\r
252 if (!ScanFs) {\r
253 if (*ThisVol == NULL) {\r
254 *ThisVol = GetMyVol ();\r
255 if (*ThisVol == NULL) {\r
256 return EFI_INVALID_PARAMETER;\r
257 }\r
258 }\r
259 //\r
260 // Read file directly from Vol\r
261 //\r
262 return ReadFileFromVol (*ThisVol, FileName, BufferSize, Buffer);\r
263 }\r
264\r
265 //\r
266 // need scan fs\r
267 //\r
268\r
269 //\r
270 // Get all Vol handle\r
271 //\r
272 Status = gBS->LocateHandleBuffer (\r
273 ByProtocol,\r
274 &gEfiSimpleFileSystemProtocolGuid,\r
275 NULL,\r
276 &NoHandles,\r
277 &HandleBuffer\r
278 );\r
279 if (EFI_ERROR (Status) && (NoHandles == 0)) {\r
280 return EFI_NOT_FOUND;\r
281 }\r
282\r
283 //\r
284 // Walk through each Vol\r
285 //\r
286 *ThisVol = NULL;\r
287 *BufferSize = 0;\r
288 *Buffer = NULL;\r
289 for (Index = 0; Index < NoHandles; Index++) {\r
290 Status = gBS->HandleProtocol (\r
291 HandleBuffer[Index],\r
292 &gEfiSimpleFileSystemProtocolGuid,\r
293 (VOID **)&Vol\r
294 );\r
295 if (EFI_ERROR(Status)) {\r
296 continue;\r
297 }\r
298\r
299 Status = ReadFileFromVol (Vol, FileName, &TempBufferSize, &TempBuffer);\r
300 if (!EFI_ERROR (Status)) {\r
301 //\r
302 // Read file OK, check duplication\r
303 //\r
304 if (*ThisVol != NULL) {\r
305 //\r
306 // Find the duplicated file\r
307 //\r
308 gBS->FreePool (TempBuffer);\r
309 gBS->FreePool (*Buffer);\r
310 Print (L"Duplicated FileName found!\n");\r
311 return EFI_NO_MAPPING;\r
312 } else {\r
313 //\r
314 // Record value\r
315 //\r
316 *ThisVol = Vol;\r
317 *BufferSize = TempBufferSize;\r
318 *Buffer = TempBuffer;\r
319 }\r
320 }\r
321 }\r
322\r
323 //\r
324 // Scan Fs done\r
325 //\r
326 if (*ThisVol == NULL) {\r
327 return EFI_NOT_FOUND;\r
328 }\r
329\r
330 //\r
331 // Done\r
332 //\r
333 return EFI_SUCCESS;\r
334}\r
335\r
336/**\r
337 Read a file.\r
338\r
339 @param[in] FileName The file to be read.\r
340 @param[out] BufferSize The file buffer size\r
341 @param[out] Buffer The file buffer\r
342\r
343 @retval EFI_SUCCESS Read file successfully\r
344 @retval EFI_NOT_FOUND File not found\r
345**/\r
346EFI_STATUS\r
347ReadFileToBuffer (\r
348 IN CHAR16 *FileName,\r
349 OUT UINTN *BufferSize,\r
350 OUT VOID **Buffer\r
351 )\r
352{\r
353 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
354 Vol = NULL;\r
355 return ReadFileToBufferEx(&Vol, FileName, BufferSize, Buffer, FALSE);\r
356}\r
357\r
358/**\r
359 Write a file.\r
360\r
361 @param[in] FileName The file to be written.\r
362 @param[in] BufferSize The file buffer size\r
363 @param[in] Buffer The file buffer\r
364\r
365 @retval EFI_SUCCESS Write file successfully\r
366**/\r
367EFI_STATUS\r
368WriteFileFromBuffer (\r
369 IN CHAR16 *FileName,\r
370 IN UINTN BufferSize,\r
371 IN VOID *Buffer\r
372 )\r
373{\r
374 EFI_STATUS Status;\r
375 EFI_FILE_HANDLE RootDir;\r
376 EFI_FILE_HANDLE Handle;\r
377 UINTN TempBufferSize;\r
378 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol;\r
379\r
380 Vol = GetMyVol();\r
381 if (Vol == NULL) {\r
382 return EFI_NOT_FOUND;\r
383 }\r
384\r
385 //\r
386 // Open the root directory\r
387 //\r
388 Status = Vol->OpenVolume (Vol, &RootDir);\r
389 if (EFI_ERROR (Status)) {\r
390 return Status;\r
391 }\r
392\r
393 //\r
394 // Open the file\r
395 //\r
396 Status = RootDir->Open (\r
397 RootDir,\r
398 &Handle,\r
399 FileName,\r
400 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
401 0\r
402 );\r
403 if (EFI_ERROR (Status)) {\r
404 RootDir->Close (RootDir);\r
405 return Status;\r
406 }\r
407\r
408 //\r
409 // Delete file\r
410 //\r
411 Status = Handle->Delete(Handle);\r
412 if (EFI_ERROR(Status)) {\r
413 return Status;\r
414 }\r
415\r
416 //\r
417 // Open the file again\r
418 //\r
419 Status = RootDir->Open (\r
420 RootDir,\r
421 &Handle,\r
422 FileName,\r
423 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,\r
424 0\r
425 );\r
426 if (EFI_ERROR (Status)) {\r
427 RootDir->Close (RootDir);\r
428 return Status;\r
429 }\r
430\r
431 RootDir->Close (RootDir);\r
432\r
433 //\r
434 // Write the file data from the buffer\r
435 //\r
436 TempBufferSize = BufferSize;\r
437 Status = Handle->Write (\r
438 Handle,\r
439 &TempBufferSize,\r
440 Buffer\r
441 );\r
442 if (EFI_ERROR (Status)) {\r
443 Handle->Close (Handle);\r
444 return Status;\r
445 }\r
446\r
447 Handle->Close (Handle);\r
448\r
449 return EFI_SUCCESS;\r
450}\r
451\r