2 A shell application that triggers capsule update process.
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
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.
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 <Library/UefiRuntimeServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/PrintLib.h>
24 #include <Protocol/LoadedImage.h>
25 #include <Protocol/SimpleFileSystem.h>
26 #include <Protocol/ShellParameters.h>
27 #include <Guid/FileInfo.h>
30 #define IS_HYPHEN(a) ((a) == L'-')
31 #define IS_NULL(a) ((a) == L'\0')
33 #define MAX_ARG_NUM 11
40 This function parse application ARG.
50 EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
;
52 Status
= gBS
->HandleProtocol (
54 &gEfiShellParametersProtocolGuid
,
55 (VOID
**)&ShellParameters
57 if (EFI_ERROR(Status
)) {
61 Argc
= ShellParameters
->Argc
;
62 Argv
= ShellParameters
->Argv
;
67 Return File System Volume containing this shell application.
69 @return File System Volume containing this shell application.
71 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*
77 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
78 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Vol
;
80 Status
= gBS
->HandleProtocol (
82 &gEfiLoadedImageProtocolGuid
,
85 ASSERT_EFI_ERROR (Status
);
87 Status
= gBS
->HandleProtocol (
88 LoadedImage
->DeviceHandle
,
89 &gEfiSimpleFileSystemProtocolGuid
,
92 if (!EFI_ERROR (Status
)) {
100 Read a file from this volume.
102 @param[in] Vol File System Volume
103 @param[in] FileName The file to be read.
104 @param[out] BufferSize The file buffer size
105 @param[out] Buffer The file buffer
107 @retval EFI_SUCCESS Read file successfully
108 @retval EFI_NOT_FOUND File not found
112 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Vol
,
114 OUT UINTN
*BufferSize
,
119 EFI_FILE_HANDLE RootDir
;
120 EFI_FILE_HANDLE Handle
;
122 EFI_FILE_INFO
*FileInfo
;
123 UINTN TempBufferSize
;
127 // Open the root directory
129 Status
= Vol
->OpenVolume (Vol
, &RootDir
);
130 if (EFI_ERROR (Status
)) {
137 Status
= RootDir
->Open (
144 if (EFI_ERROR (Status
)) {
145 RootDir
->Close (RootDir
);
149 RootDir
->Close (RootDir
);
152 // Get the file information
154 FileInfoSize
= sizeof(EFI_FILE_INFO
) + 1024;
156 FileInfo
= AllocateZeroPool (FileInfoSize
);
157 if (FileInfo
== NULL
) {
158 Handle
->Close (Handle
);
162 Status
= Handle
->GetInfo (
168 if (EFI_ERROR (Status
)) {
169 Handle
->Close (Handle
);
170 gBS
->FreePool (FileInfo
);
175 // Allocate buffer for the file data. The last CHAR16 is for L'\0'
177 TempBufferSize
= (UINTN
) FileInfo
->FileSize
+ sizeof(CHAR16
);
178 TempBuffer
= AllocateZeroPool (TempBufferSize
);
179 if (TempBuffer
== NULL
) {
180 Handle
->Close (Handle
);
181 gBS
->FreePool (FileInfo
);
185 gBS
->FreePool (FileInfo
);
188 // Read the file data to the buffer
190 Status
= Handle
->Read (
195 if (EFI_ERROR (Status
)) {
196 Handle
->Close (Handle
);
197 gBS
->FreePool (TempBuffer
);
201 Handle
->Close (Handle
);
203 *BufferSize
= TempBufferSize
;
204 *Buffer
= TempBuffer
;
210 If ScanFs is FLASE, it will use this Vol as default Fs.
211 If ScanFs is TRUE, it will scan all FS and check the file.
212 If there is only one file match the name, it will be read.
213 If there is more than one file match the name, it will return Error.
215 @param[in,out] ThisVol File System Volume
216 @param[in] FileName The file to be read.
217 @param[out] BufferSize The file buffer size
218 @param[out] Buffer The file buffer
219 @param[in] ScanFs Need Scan all FS
221 @retval EFI_SUCCESS Read file successfully
222 @retval EFI_NOT_FOUND File not found
223 @retval EFI_NO_MAPPING There is duplicated files found
227 IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**ThisVol
,
229 OUT UINTN
*BufferSize
,
235 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Vol
;
236 UINTN TempBufferSize
;
239 EFI_HANDLE
*HandleBuffer
;
245 if ((FileName
== NULL
) || (Buffer
== NULL
) || (ThisVol
== NULL
)) {
246 return EFI_INVALID_PARAMETER
;
253 if (*ThisVol
== NULL
) {
254 *ThisVol
= GetMyVol ();
255 if (*ThisVol
== NULL
) {
256 return EFI_INVALID_PARAMETER
;
260 // Read file directly from Vol
262 return ReadFileFromVol (*ThisVol
, FileName
, BufferSize
, Buffer
);
270 // Get all Vol handle
272 Status
= gBS
->LocateHandleBuffer (
274 &gEfiSimpleFileSystemProtocolGuid
,
279 if (EFI_ERROR (Status
) && (NoHandles
== 0)) {
280 return EFI_NOT_FOUND
;
284 // Walk through each Vol
289 for (Index
= 0; Index
< NoHandles
; Index
++) {
290 Status
= gBS
->HandleProtocol (
292 &gEfiSimpleFileSystemProtocolGuid
,
295 if (EFI_ERROR(Status
)) {
299 Status
= ReadFileFromVol (Vol
, FileName
, &TempBufferSize
, &TempBuffer
);
300 if (!EFI_ERROR (Status
)) {
302 // Read file OK, check duplication
304 if (*ThisVol
!= NULL
) {
306 // Find the duplicated file
308 gBS
->FreePool (TempBuffer
);
309 gBS
->FreePool (*Buffer
);
310 Print (L
"Duplicated FileName found!\n");
311 return EFI_NO_MAPPING
;
317 *BufferSize
= TempBufferSize
;
318 *Buffer
= TempBuffer
;
326 if (*ThisVol
== NULL
) {
327 return EFI_NOT_FOUND
;
339 @param[in] FileName The file to be read.
340 @param[out] BufferSize The file buffer size
341 @param[out] Buffer The file buffer
343 @retval EFI_SUCCESS Read file successfully
344 @retval EFI_NOT_FOUND File not found
349 OUT UINTN
*BufferSize
,
353 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Vol
;
355 return ReadFileToBufferEx(&Vol
, FileName
, BufferSize
, Buffer
, FALSE
);
361 @param[in] FileName The file to be written.
362 @param[in] BufferSize The file buffer size
363 @param[in] Buffer The file buffer
365 @retval EFI_SUCCESS Write file successfully
368 WriteFileFromBuffer (
375 EFI_FILE_HANDLE RootDir
;
376 EFI_FILE_HANDLE Handle
;
377 UINTN TempBufferSize
;
378 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Vol
;
382 return EFI_NOT_FOUND
;
386 // Open the root directory
388 Status
= Vol
->OpenVolume (Vol
, &RootDir
);
389 if (EFI_ERROR (Status
)) {
396 Status
= RootDir
->Open (
400 EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
,
403 if (EFI_ERROR (Status
)) {
404 RootDir
->Close (RootDir
);
411 Status
= Handle
->Delete(Handle
);
412 if (EFI_ERROR(Status
)) {
417 // Open the file again
419 Status
= RootDir
->Open (
423 EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
,
426 if (EFI_ERROR (Status
)) {
427 RootDir
->Close (RootDir
);
431 RootDir
->Close (RootDir
);
434 // Write the file data from the buffer
436 TempBufferSize
= BufferSize
;
437 Status
= Handle
->Write (
442 if (EFI_ERROR (Status
)) {
443 Handle
->Close (Handle
);
447 Handle
->Close (Handle
);