mirror of https://github.com/acidanthera/audk.git
248 lines
6.2 KiB
C
248 lines
6.2 KiB
C
/** @file
|
|
A shell application that triggers capsule update process.
|
|
|
|
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Protocol/SimpleFileSystem.h>
|
|
#include <Protocol/ShellParameters.h>
|
|
#include <Protocol/Shell.h>
|
|
#include <Guid/FileInfo.h>
|
|
|
|
UINTN Argc;
|
|
CHAR16 **Argv;
|
|
EFI_SHELL_PROTOCOL *mShellProtocol = NULL;
|
|
|
|
/**
|
|
|
|
This function parse application ARG.
|
|
|
|
@return Status
|
|
**/
|
|
EFI_STATUS
|
|
GetArg (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
gImageHandle,
|
|
&gEfiShellParametersProtocolGuid,
|
|
(VOID**)&ShellParameters
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Argc = ShellParameters->Argc;
|
|
Argv = ShellParameters->Argv;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get shell protocol.
|
|
|
|
@return Pointer to shell protocol.
|
|
**/
|
|
EFI_SHELL_PROTOCOL *
|
|
GetShellProtocol (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (mShellProtocol == NULL) {
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiShellProtocolGuid,
|
|
NULL,
|
|
(VOID **) &mShellProtocol
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
mShellProtocol = NULL;
|
|
}
|
|
}
|
|
|
|
return mShellProtocol;
|
|
}
|
|
|
|
/**
|
|
Read a file.
|
|
|
|
@param[in] FileName The file to be read.
|
|
@param[out] BufferSize The file buffer size
|
|
@param[out] Buffer The file buffer
|
|
|
|
@retval EFI_SUCCESS Read file successfully
|
|
@retval EFI_NOT_FOUND Shell protocol or file not found
|
|
@retval others Read file failed
|
|
**/
|
|
EFI_STATUS
|
|
ReadFileToBuffer (
|
|
IN CHAR16 *FileName,
|
|
OUT UINTN *BufferSize,
|
|
OUT VOID **Buffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SHELL_PROTOCOL *ShellProtocol;
|
|
SHELL_FILE_HANDLE Handle;
|
|
UINT64 FileSize;
|
|
UINTN TempBufferSize;
|
|
VOID *TempBuffer;
|
|
|
|
ShellProtocol = GetShellProtocol();
|
|
if (ShellProtocol == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Open file by FileName.
|
|
//
|
|
Status = ShellProtocol->OpenFileByName (
|
|
FileName,
|
|
&Handle,
|
|
EFI_FILE_MODE_READ
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get the file size.
|
|
//
|
|
Status = ShellProtocol->GetFileSize (Handle, &FileSize);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellProtocol->CloseFile (Handle);
|
|
return Status;
|
|
}
|
|
|
|
TempBufferSize = (UINTN) FileSize;
|
|
TempBuffer = AllocateZeroPool (TempBufferSize);
|
|
if (TempBuffer == NULL) {
|
|
ShellProtocol->CloseFile (Handle);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Read the file data to the buffer
|
|
//
|
|
Status = ShellProtocol->ReadFile (
|
|
Handle,
|
|
&TempBufferSize,
|
|
TempBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellProtocol->CloseFile (Handle);
|
|
return Status;
|
|
}
|
|
|
|
ShellProtocol->CloseFile (Handle);
|
|
|
|
*BufferSize = TempBufferSize;
|
|
*Buffer = TempBuffer;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Write a file.
|
|
|
|
@param[in] FileName The file to be written.
|
|
@param[in] BufferSize The file buffer size
|
|
@param[in] Buffer The file buffer
|
|
|
|
@retval EFI_SUCCESS Write file successfully
|
|
@retval EFI_NOT_FOUND Shell protocol not found
|
|
@retval others Write file failed
|
|
**/
|
|
EFI_STATUS
|
|
WriteFileFromBuffer (
|
|
IN CHAR16 *FileName,
|
|
IN UINTN BufferSize,
|
|
IN VOID *Buffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SHELL_PROTOCOL *ShellProtocol;
|
|
SHELL_FILE_HANDLE Handle;
|
|
EFI_FILE_INFO *FileInfo;
|
|
UINTN TempBufferSize;
|
|
|
|
ShellProtocol = GetShellProtocol();
|
|
if (ShellProtocol == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Open file by FileName.
|
|
//
|
|
Status = ShellProtocol->OpenFileByName (
|
|
FileName,
|
|
&Handle,
|
|
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Empty the file contents.
|
|
//
|
|
FileInfo = ShellProtocol->GetFileInfo (Handle);
|
|
if (FileInfo == NULL) {
|
|
ShellProtocol->CloseFile (Handle);
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
//
|
|
// If the file size is already 0, then it has been empty.
|
|
//
|
|
if (FileInfo->FileSize != 0) {
|
|
//
|
|
// Set the file size to 0.
|
|
//
|
|
FileInfo->FileSize = 0;
|
|
Status = ShellProtocol->SetFileInfo (Handle, FileInfo);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (FileInfo);
|
|
ShellProtocol->CloseFile (Handle);
|
|
return Status;
|
|
}
|
|
}
|
|
FreePool (FileInfo);
|
|
|
|
//
|
|
// Write the file data from the buffer
|
|
//
|
|
TempBufferSize = BufferSize;
|
|
Status = ShellProtocol->WriteFile (
|
|
Handle,
|
|
&TempBufferSize,
|
|
Buffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellProtocol->CloseFile (Handle);
|
|
return Status;
|
|
}
|
|
|
|
ShellProtocol->CloseFile (Handle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|