summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonald Cron <ronald.cron@arm.com>2014-09-04 15:48:05 +0100
committerRyan Harkin <ryan.harkin@linaro.org>2014-10-22 16:22:40 +0100
commitadf60a548ad968db01443d4bc245d95e9db2af02 (patch)
treec420552f4f39b7bdf6bf7c073812b50f242ae01f
parent91d8c6098a78b414a78124774362d891a2bc2bd6 (diff)
BootMonFs: Fix error codes returned by Open() and Read()
Change-Id: I245a4d219d4cfed0138ba52b4250e23e4903ae7e
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc1
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf2
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h38
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c217
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c26
5 files changed, 223 insertions, 61 deletions
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 7d7f23279..817cebbef 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -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
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
index 94e8916e1..c76946218 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
@@ -33,9 +33,11 @@
[Packages]
ArmPlatformPkg/ArmPlatformPkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
+ BasePathLib
DevicePathLib
MemoryAllocationLib
PrintLib
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
index 9c1daa523..affc51093 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
@@ -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 (
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
index 6616b4f69..45ac89026 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
@@ -12,6 +12,7 @@
*
**/
+#include <Library/PathLib.h>
#include "BootMonFsInternal.h"
// Clear a file's image description on storage media:
@@ -445,59 +446,78 @@ CreateNewFile (
}
/**
- Opens a file on the Nor Flash FS volume
-
- Calls BootMonFsGetFileFromAsciiFilename to search the list of tracked files.
-
- @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 ?
-
- @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
+ Open a file on the boot monitor file system.
+
+ 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[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
+
+ @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
EFI_STATUS
BootMonFsOpenFile (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
)
{
- BOOTMON_FS_FILE *Directory;
- BOOTMON_FS_FILE *File;
- BOOTMON_FS_INSTANCE *Instance;
- CHAR8* AsciiFileName;
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)) {
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 (
}
}
+ //
+ // 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;
+ }
+ Path = (CHAR16*)Buf;
+ AsciiFileName = NULL;
+
+ //
+ // 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 (FileName) + 1) * sizeof (CHAR8));
+ //
+ AsciiFileName = AllocatePool (StrLen (Path) + 1);
if (AsciiFileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ UnicodeStrToAsciiStr (Path, AsciiFileName);
+ if (AsciiStrSize (AsciiFileName) > MAX_NAME_LENGTH) {
+ AsciiFileName[MAX_NAME_LENGTH - 1] = '\0';
}
- UnicodeStrToAsciiStr (FileName, AsciiFileName);
- if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
- (AsciiStrCmp (AsciiFileName, "/") == 0) ||
- (AsciiStrCmp (AsciiFileName, "") == 0) ||
- (AsciiStrCmp (AsciiFileName, ".") == 0))
- {
+ if ((AsciiFileName[0] == '\0') ||
+ (AsciiFileName[0] == '.' ) ) {
//
- // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
+ // 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
- Status = CreateNewFile (Instance, AsciiFileName, &File);
- if (!EFI_ERROR (Status)) {
- File->OpenMode = OpenMode;
- *NewHandle = &File->File;
- File->Position = 0;
- }
- }
+ if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
+ goto Error;
}
- } 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;
*NewHandle = &File->File;
File->Position = 0;
}
}
- FreePool (AsciiFileName);
+Error:
+
+ FreePool (Buf);
+ if (AsciiFileName != NULL) {
+ FreePool (AsciiFileName);
+ }
return Status;
}
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
index 653b2c507..358332d65 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
@@ -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;
- 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.