mirror of https://github.com/acidanthera/audk.git
ArmPlatformPkg/BootMonFs: Fix error codes returned by Open() and Read()
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ronald Cron <Ronald.Cron@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16510 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
a40ff4578d
commit
fb08c45511
|
@ -23,6 +23,7 @@
|
||||||
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||||
|
|
||||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||||
|
BasePathLib|MdeModulePkg/Library/BasePathLib/BasePathLib.inf
|
||||||
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
|
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
|
||||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||||
|
|
|
@ -33,9 +33,11 @@
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
|
BasePathLib
|
||||||
DevicePathLib
|
DevicePathLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
PrintLib
|
PrintLib
|
||||||
|
|
|
@ -91,6 +91,28 @@ BootMonFsCloseFile (
|
||||||
IN EFI_FILE_PROTOCOL *This
|
IN EFI_FILE_PROTOCOL *This
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Open a file on the boot monitor file system.
|
||||||
|
|
||||||
|
@param[in] This The EFI_FILE_PROTOCOL parent handle.
|
||||||
|
@param[out] NewHandle A pointer to the location to return the opened
|
||||||
|
handle for the new file.
|
||||||
|
@param[in] FileName The Null-terminated string of the name of the file
|
||||||
|
to be opened.
|
||||||
|
@param[in] OpenMode The mode to open the file : Read or Read/Write or
|
||||||
|
Read/Write/Create
|
||||||
|
@param[in] Attributes Attributes of the file in case of a file creation
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The file was open.
|
||||||
|
@retval EFI_NOT_FOUND The specified file could not be found or the specified
|
||||||
|
directory in which to create a file could not be found.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error.
|
||||||
|
@retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
|
||||||
|
with the BootMon file system.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
|
||||||
|
@retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BootMonFsOpenFile (
|
BootMonFsOpenFile (
|
||||||
|
@ -101,7 +123,23 @@ BootMonFsOpenFile (
|
||||||
IN UINT64 Attributes
|
IN UINT64 Attributes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read data from an open file.
|
||||||
|
|
||||||
|
@param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
|
||||||
|
is the file handle to read data from.
|
||||||
|
@param[in out] BufferSize On input, the size of the Buffer. On output, the
|
||||||
|
amount of data returned in Buffer. In both cases,
|
||||||
|
the size is measured in bytes.
|
||||||
|
@param[out] Buffer The buffer into which the data is read.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read.
|
||||||
|
@retval EFI_DEVICE_ERROR On entry, the current file position is
|
||||||
|
beyond the end of the file, or the device
|
||||||
|
reported an error while performing the read
|
||||||
|
operation.
|
||||||
|
@retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
|
||||||
|
**/
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BootMonFsReadFile (
|
BootMonFsReadFile (
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <Library/PathLib.h>
|
||||||
#include "BootMonFsInternal.h"
|
#include "BootMonFsInternal.h"
|
||||||
|
|
||||||
// Clear a file's image description on storage media:
|
// Clear a file's image description on storage media:
|
||||||
|
@ -445,59 +446,78 @@ CreateNewFile (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Opens a file on the Nor Flash FS volume
|
Open a file on the boot monitor file system.
|
||||||
|
|
||||||
Calls BootMonFsGetFileFromAsciiFilename to search the list of tracked files.
|
The boot monitor file system does not allow for sub-directories. There is only
|
||||||
|
one directory, the root one. On any attempt to create a directory, the function
|
||||||
|
returns in error with the EFI_WRITE_PROTECTED error code.
|
||||||
|
|
||||||
@param This The EFI_FILE_PROTOCOL parent handle.
|
@param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
|
||||||
@param NewHandle Double-pointer to the newly created protocol.
|
the file handle to source location.
|
||||||
@param FileName The name of the image/metadata on flash
|
@param[out] NewHandle A pointer to the location to return the opened
|
||||||
@param OpenMode Read,write,append etc
|
handle for the new file.
|
||||||
@param Attributes ?
|
@param[in] FileName The Null-terminated string of the name of the file
|
||||||
|
to be opened.
|
||||||
|
@param[in] OpenMode The mode to open the file : Read or Read/Write or
|
||||||
|
Read/Write/Create
|
||||||
|
@param[in] Attributes Attributes of the file in case of a file creation
|
||||||
|
|
||||||
@return EFI_STATUS
|
@retval EFI_SUCCESS The file was open.
|
||||||
OUT_OF_RESOURCES
|
@retval EFI_NOT_FOUND The specified file could not be found or the specified
|
||||||
Run out of space to keep track of the allocated structures
|
directory in which to create a file could not be found.
|
||||||
DEVICE_ERROR
|
@retval EFI_DEVICE_ERROR The device reported an error.
|
||||||
Unable to locate the volume associated with the parent file handle
|
@retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
|
||||||
NOT_FOUND
|
with the Boot Monitor file system.
|
||||||
Filename wasn't found on flash
|
@retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
|
||||||
SUCCESS
|
@retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BootMonFsOpenFile (
|
BootMonFsOpenFile (
|
||||||
IN EFI_FILE_PROTOCOL *This,
|
IN EFI_FILE_PROTOCOL *This,
|
||||||
OUT EFI_FILE_PROTOCOL **NewHandle,
|
OUT EFI_FILE_PROTOCOL **NewHandle,
|
||||||
IN CHAR16 *FileName,
|
IN CHAR16 *FileName,
|
||||||
IN UINT64 OpenMode,
|
IN UINT64 OpenMode,
|
||||||
IN UINT64 Attributes
|
IN UINT64 Attributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BOOTMON_FS_FILE *Directory;
|
|
||||||
BOOTMON_FS_FILE *File;
|
|
||||||
BOOTMON_FS_INSTANCE *Instance;
|
|
||||||
CHAR8* AsciiFileName;
|
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
BOOTMON_FS_FILE *Directory;
|
||||||
|
BOOTMON_FS_FILE *File;
|
||||||
|
BOOTMON_FS_INSTANCE *Instance;
|
||||||
|
CHAR8 *Buf;
|
||||||
|
CHAR16 *Path;
|
||||||
|
CHAR16 *Separator;
|
||||||
|
CHAR8 *AsciiFileName;
|
||||||
|
|
||||||
|
if (This == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
if ((FileName == NULL) || (NewHandle == NULL)) {
|
if ((FileName == NULL) || (NewHandle == NULL)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// The only valid modes are read, read/write, and read/write/create
|
// The only valid modes are read, read/write, and read/write/create
|
||||||
if (!(OpenMode & EFI_FILE_MODE_READ) || ((OpenMode & EFI_FILE_MODE_CREATE) && !(OpenMode & EFI_FILE_MODE_WRITE))) {
|
//
|
||||||
|
if ( (OpenMode != EFI_FILE_MODE_READ) &&
|
||||||
|
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
|
||||||
|
(OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
|
Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
|
||||||
if (Directory == NULL) {
|
if (Directory == NULL) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance = Directory->Instance;
|
Instance = Directory->Instance;
|
||||||
|
|
||||||
// If the instance has not been initialized it yet then do it ...
|
//
|
||||||
|
// If the instance has not been initialized yet then do it ...
|
||||||
|
//
|
||||||
if (!Instance->Initialized) {
|
if (!Instance->Initialized) {
|
||||||
Status = BootMonFsInitialize (Instance);
|
Status = BootMonFsInitialize (Instance);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -505,58 +525,137 @@ BootMonFsOpenFile (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BootMonFs interface requires ASCII filenames
|
//
|
||||||
AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
|
// Copy the file path to be able to work on it. We do not want to
|
||||||
if (AsciiFileName == NULL) {
|
// modify the input file name string "FileName".
|
||||||
|
//
|
||||||
|
Buf = AllocateCopyPool (StrSize (FileName), FileName);
|
||||||
|
if (Buf == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
UnicodeStrToAsciiStr (FileName, AsciiFileName);
|
Path = (CHAR16*)Buf;
|
||||||
|
AsciiFileName = NULL;
|
||||||
|
|
||||||
if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
|
//
|
||||||
(AsciiStrCmp (AsciiFileName, "/") == 0) ||
|
// Handle single periods, double periods and convert forward slashes '/'
|
||||||
(AsciiStrCmp (AsciiFileName, "") == 0) ||
|
// to backward '\' ones. Does not handle a '.' at the beginning of the
|
||||||
(AsciiStrCmp (AsciiFileName, ".") == 0))
|
// path for the time being.
|
||||||
{
|
//
|
||||||
|
if (PathCleanUpDirectories (Path) == NULL) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect if the first component of the path refers to a directory.
|
||||||
|
// This is done to return the correct error code when trying to
|
||||||
|
// access or create a directory other than the root directory.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Search for the '\\' sequence and if found return in error
|
||||||
|
// with the EFI_INVALID_PARAMETER error code. ere in the path.
|
||||||
|
//
|
||||||
|
if (StrStr (Path, L"\\\\") != NULL) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get rid of the leading '\' if any.
|
||||||
|
//
|
||||||
|
Path += (Path[0] == L'\\');
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for a '\' in the file path. If one is found then
|
||||||
|
// the first component of the path refers to a directory
|
||||||
|
// that is not the root directory.
|
||||||
|
//
|
||||||
|
Separator = StrStr (Path, L"\\");
|
||||||
|
if (Separator != NULL) {
|
||||||
//
|
//
|
||||||
// Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
|
// In the case '<dir name>\' and a creation, return
|
||||||
|
// EFI_WRITE_PROTECTED if this is for a directory
|
||||||
|
// creation, EFI_INVALID_PARAMETER otherwise.
|
||||||
|
//
|
||||||
|
if ((*(Separator + 1) == '\0') && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
|
||||||
|
if (Attributes & EFI_FILE_DIRECTORY) {
|
||||||
|
Status = EFI_WRITE_PROTECTED;
|
||||||
|
} else {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Attempt to open a file or a directory that is not in the
|
||||||
|
// root directory or to open without creation a directory
|
||||||
|
// located in the root directory, returns EFI_NOT_FOUND.
|
||||||
|
//
|
||||||
|
Status = EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// BootMonFs interface requires ASCII filenames
|
||||||
|
//
|
||||||
|
AsciiFileName = AllocatePool (StrLen (Path) + 1);
|
||||||
|
if (AsciiFileName == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
UnicodeStrToAsciiStr (Path, AsciiFileName);
|
||||||
|
if (AsciiStrSize (AsciiFileName) > MAX_NAME_LENGTH) {
|
||||||
|
AsciiFileName[MAX_NAME_LENGTH - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((AsciiFileName[0] == '\0') ||
|
||||||
|
(AsciiFileName[0] == '.' ) ) {
|
||||||
|
//
|
||||||
|
// Opening the root directory
|
||||||
//
|
//
|
||||||
|
|
||||||
*NewHandle = &Instance->RootFile->File;
|
*NewHandle = &Instance->RootFile->File;
|
||||||
Instance->RootFile->Position = 0;
|
Instance->RootFile->Position = 0;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if ((OpenMode & EFI_FILE_MODE_CREATE) &&
|
||||||
|
(Attributes & EFI_FILE_DIRECTORY) ) {
|
||||||
|
Status = EFI_WRITE_PROTECTED;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open or Create a regular file
|
// Open or create a file in the root directory.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Check if the file already exists
|
|
||||||
Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
|
Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
|
||||||
if (Status == EFI_NOT_FOUND) {
|
if (Status == EFI_NOT_FOUND) {
|
||||||
// The file doesn't exist.
|
if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
|
||||||
if (OpenMode & EFI_FILE_MODE_CREATE) {
|
goto Error;
|
||||||
// If the file does not exist but is required then create it.
|
|
||||||
if (Attributes & EFI_FILE_DIRECTORY) {
|
|
||||||
// BootMonFS doesn't support subdirectories
|
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
} else {
|
|
||||||
// Create a new file
|
|
||||||
Status = CreateNewFile (Instance, AsciiFileName, &File);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
File->OpenMode = OpenMode;
|
|
||||||
*NewHandle = &File->File;
|
|
||||||
File->Position = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (Status == EFI_SUCCESS) {
|
|
||||||
// The file exists
|
Status = CreateNewFile (Instance, AsciiFileName, &File);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
File->OpenMode = OpenMode;
|
||||||
|
*NewHandle = &File->File;
|
||||||
|
File->Position = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// The file already exists.
|
||||||
|
//
|
||||||
File->OpenMode = OpenMode;
|
File->OpenMode = OpenMode;
|
||||||
*NewHandle = &File->File;
|
*NewHandle = &File->File;
|
||||||
File->Position = 0;
|
File->Position = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FreePool (AsciiFileName);
|
Error:
|
||||||
|
|
||||||
|
FreePool (Buf);
|
||||||
|
if (AsciiFileName != NULL) {
|
||||||
|
FreePool (AsciiFileName);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,23 @@
|
||||||
|
|
||||||
#include "BootMonFsInternal.h"
|
#include "BootMonFsInternal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read data from an open file.
|
||||||
|
|
||||||
|
@param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
|
||||||
|
is the file handle to read data from.
|
||||||
|
@param[in out] BufferSize On input, the size of the Buffer. On output, the
|
||||||
|
amount of data returned in Buffer. In both cases,
|
||||||
|
the size is measured in bytes.
|
||||||
|
@param[out] Buffer The buffer into which the data is read.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read.
|
||||||
|
@retval EFI_DEVICE_ERROR On entry, the current file position is
|
||||||
|
beyond the end of the file, or the device
|
||||||
|
reported an error while performing the read
|
||||||
|
operation.
|
||||||
|
@retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
|
||||||
|
**/
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BootMonFsReadFile (
|
BootMonFsReadFile (
|
||||||
|
@ -51,9 +68,14 @@ BootMonFsReadFile (
|
||||||
FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
|
FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
|
||||||
|
|
||||||
if (File->Position >= File->HwDescription.Region[0].Size) {
|
if (File->Position >= File->HwDescription.Region[0].Size) {
|
||||||
// The entire file has been read
|
// The entire file has been read or the position has been
|
||||||
|
// set past the end of the file.
|
||||||
*BufferSize = 0;
|
*BufferSize = 0;
|
||||||
return EFI_DEVICE_ERROR;
|
if (File->Position > File->HwDescription.Region[0].Size) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This driver assumes that the entire file is in region 0.
|
// This driver assumes that the entire file is in region 0.
|
||||||
|
|
Loading…
Reference in New Issue