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
|
||||
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
BasePathLib|MdeModulePkg/Library/BasePathLib/BasePathLib.inf
|
||||
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
|
||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||
|
|
|
@ -33,9 +33,11 @@
|
|||
[Packages]
|
||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BasePathLib
|
||||
DevicePathLib
|
||||
MemoryAllocationLib
|
||||
PrintLib
|
||||
|
|
|
@ -91,6 +91,28 @@ BootMonFsCloseFile (
|
|||
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
|
||||
EFI_STATUS
|
||||
BootMonFsOpenFile (
|
||||
|
@ -101,7 +123,23 @@ BootMonFsOpenFile (
|
|||
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
|
||||
EFI_STATUS
|
||||
BootMonFsReadFile (
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*
|
||||
**/
|
||||
|
||||
#include <Library/PathLib.h>
|
||||
#include "BootMonFsInternal.h"
|
||||
|
||||
// Clear a file's image description on storage media:
|
||||
|
@ -445,24 +446,30 @@ 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 NewHandle Double-pointer to the newly created protocol.
|
||||
@param FileName The name of the image/metadata on flash
|
||||
@param OpenMode Read,write,append etc
|
||||
@param Attributes ?
|
||||
@param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
|
||||
the file handle to source location.
|
||||
@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
|
||||
|
||||
@return EFI_STATUS
|
||||
OUT_OF_RESOURCES
|
||||
Run out of space to keep track of the allocated structures
|
||||
DEVICE_ERROR
|
||||
Unable to locate the volume associated with the parent file handle
|
||||
NOT_FOUND
|
||||
Filename wasn't found on flash
|
||||
SUCCESS
|
||||
@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 Boot Monitor 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
|
||||
|
@ -475,29 +482,42 @@ BootMonFsOpenFile (
|
|||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOTMON_FS_FILE *Directory;
|
||||
BOOTMON_FS_FILE *File;
|
||||
BOOTMON_FS_INSTANCE *Instance;
|
||||
CHAR8 *Buf;
|
||||
CHAR16 *Path;
|
||||
CHAR16 *Separator;
|
||||
CHAR8 *AsciiFileName;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((FileName == NULL) || (NewHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
|
||||
if (Directory == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
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) {
|
||||
Status = BootMonFsInitialize (Instance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -505,58 +525,137 @@ BootMonFsOpenFile (
|
|||
}
|
||||
}
|
||||
|
||||
// BootMonFs interface requires ASCII filenames
|
||||
AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
|
||||
if (AsciiFileName == NULL) {
|
||||
//
|
||||
// Copy the file path to be able to work on it. We do not want to
|
||||
// modify the input file name string "FileName".
|
||||
//
|
||||
Buf = AllocateCopyPool (StrSize (FileName), FileName);
|
||||
if (Buf == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
UnicodeStrToAsciiStr (FileName, AsciiFileName);
|
||||
Path = (CHAR16*)Buf;
|
||||
AsciiFileName = NULL;
|
||||
|
||||
if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, "/") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, "") == 0) ||
|
||||
(AsciiStrCmp (AsciiFileName, ".") == 0))
|
||||
{
|
||||
//
|
||||
// Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
|
||||
// Handle single periods, double periods and convert forward slashes '/'
|
||||
// to backward '\' ones. Does not handle a '.' at the beginning of the
|
||||
// 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) {
|
||||
//
|
||||
// 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;
|
||||
Instance->RootFile->Position = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
} 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);
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
// The file doesn't exist.
|
||||
if (OpenMode & EFI_FILE_MODE_CREATE) {
|
||||
// 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
|
||||
if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
//
|
||||
// The file already exists.
|
||||
//
|
||||
File->OpenMode = OpenMode;
|
||||
*NewHandle = &File->File;
|
||||
File->Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Error:
|
||||
|
||||
FreePool (Buf);
|
||||
if (AsciiFileName != NULL) {
|
||||
FreePool (AsciiFileName);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,23 @@
|
|||
|
||||
#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
|
||||
EFI_STATUS
|
||||
BootMonFsReadFile (
|
||||
|
@ -51,9 +68,14 @@ BootMonFsReadFile (
|
|||
FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
|
||||
|
||||
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;
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue