aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/FatPkg/EnhancedFatDxe/Open.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/FatPkg/EnhancedFatDxe/Open.c')
-rw-r--r--roms/edk2/FatPkg/EnhancedFatDxe/Open.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/roms/edk2/FatPkg/EnhancedFatDxe/Open.c b/roms/edk2/FatPkg/EnhancedFatDxe/Open.c
new file mode 100644
index 000000000..1b716e0cd
--- /dev/null
+++ b/roms/edk2/FatPkg/EnhancedFatDxe/Open.c
@@ -0,0 +1,320 @@
+/** @file
+ Routines dealing with file open.
+
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Fat.h"
+
+/**
+
+ Create an Open instance for the existing OFile.
+ The IFile of the newly opened file is passed out.
+
+ @param OFile - The file that serves as a starting reference point.
+ @param PtrIFile - The newly generated IFile instance.
+
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile
+ @retval EFI_SUCCESS - Create the new IFile for the OFile successfully
+
+**/
+EFI_STATUS
+FatAllocateIFile (
+ IN FAT_OFILE *OFile,
+ OUT FAT_IFILE **PtrIFile
+ )
+{
+ FAT_IFILE *IFile;
+
+ ASSERT_VOLUME_LOCKED (OFile->Volume);
+
+ //
+ // Allocate a new open instance
+ //
+ IFile = AllocateZeroPool (sizeof (FAT_IFILE));
+ if (IFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IFile->Signature = FAT_IFILE_SIGNATURE;
+
+ CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));
+
+ //
+ // Report the correct revision number based on the DiskIo2 availability
+ //
+ if (OFile->Volume->DiskIo2 != NULL) {
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;
+ } else {
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;
+ }
+
+ IFile->OFile = OFile;
+ InsertTailList (&OFile->Opens, &IFile->Link);
+ InitializeListHead (&IFile->Tasks);
+
+ *PtrIFile = IFile;
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Open a file for a file name relative to an existing OFile.
+ The IFile of the newly opened file is passed out.
+
+ @param OFile - The file that serves as a starting reference point.
+ @param NewIFile - The newly generated IFile instance.
+ @param FileName - The file name relative to the OFile.
+ @param OpenMode - Open mode.
+ @param Attributes - Attributes to set if the file is created.
+
+
+ @retval EFI_SUCCESS - Open the file successfully.
+ @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes
+ or the file name is not valid.
+ @retval EFI_NOT_FOUND - Conflicts between dir intention and attribute.
+ @retval EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.
+ @retval EFI_ACCESS_DENIED - If the file's attribute is read only, and the
+ open is for read-write fail it.
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.
+
+**/
+EFI_STATUS
+FatOFileOpen (
+ IN FAT_OFILE *OFile,
+ OUT FAT_IFILE **NewIFile,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT8 Attributes
+ )
+{
+ FAT_VOLUME *Volume;
+ EFI_STATUS Status;
+ CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];
+ FAT_DIRENT *DirEnt;
+ UINT8 FileAttributes;
+ BOOLEAN WriteMode;
+
+ DirEnt = NULL;
+ Volume = OFile->Volume;
+ ASSERT_VOLUME_LOCKED (Volume);
+ WriteMode = (BOOLEAN) (OpenMode & EFI_FILE_MODE_WRITE);
+ if (Volume->ReadOnly && WriteMode) {
+ return EFI_WRITE_PROTECTED;
+ }
+ //
+ // Verify the source file handle isn't in an error state
+ //
+ Status = OFile->Error;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Get new OFile for the file
+ //
+ Status = FatLocateOFile (&OFile, FileName, Attributes, NewFileName);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (*NewFileName != 0) {
+ //
+ // If there's a remaining part of the name, then we had
+ // better be creating the file in the directory
+ //
+ if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = FatCreateDirEnt (OFile, NewFileName, Attributes, &DirEnt);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (DirEnt != NULL);
+ Status = FatOpenDirEnt (OFile, DirEnt);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OFile = DirEnt->OFile;
+ if (OFile->ODir != NULL) {
+ //
+ // If we just created a directory, we need to create "." and ".."
+ //
+ Status = FatCreateDotDirEnts (OFile);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+ //
+ // If the file's attribute is read only, and the open is for
+ // read-write, then the access is denied.
+ //
+ FileAttributes = OFile->DirEnt->Entry.Attributes;
+ if ((FileAttributes & EFI_FILE_READ_ONLY) != 0 && (FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0 && WriteMode) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Create an open instance of the OFile
+ //
+ Status = FatAllocateIFile (OFile, NewIFile);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ (*NewIFile)->ReadOnly = (BOOLEAN)!WriteMode;
+
+ DEBUG ((EFI_D_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));
+ return FatOFileFlush (OFile);
+}
+
+/**
+
+ Implements OpenEx() of Simple File System Protocol.
+
+ @param FHand - File handle of the file serves as a starting reference point.
+ @param NewHandle - Handle of the file that is newly opened.
+ @param FileName - File name relative to FHand.
+ @param OpenMode - Open mode.
+ @param Attributes - Attributes to set if the file is created.
+ @param Token - A pointer to the token associated with the transaction.:
+
+ @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
+ The OpenMode is not supported.
+ The Attributes is not the valid attributes.
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
+ @retval EFI_SUCCESS - Open the file successfully.
+ @return Others - The status of open file.
+
+**/
+EFI_STATUS
+EFIAPI
+FatOpenEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+{
+ FAT_IFILE *IFile;
+ FAT_IFILE *NewIFile;
+ FAT_OFILE *OFile;
+ EFI_STATUS Status;
+ FAT_TASK *Task;
+
+ //
+ // Perform some parameter checking
+ //
+ if (FileName == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Check for a valid mode
+ //
+ switch (OpenMode) {
+ case EFI_FILE_MODE_READ:
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for valid Attributes for file creation case.
+ //
+ if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && (Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IFile = IFILE_FROM_FHAND (FHand);
+ OFile = IFile->OFile;
+ Task = NULL;
+
+ if (Token == NULL) {
+ FatWaitNonblockingTask (IFile);
+ } else {
+ //
+ // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
+ // But if it calls, the below check can avoid crash.
+ //
+ if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
+ return EFI_UNSUPPORTED;
+ }
+ Task = FatCreateTask (IFile, Token);
+ if (Task == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ //
+ // Lock
+ //
+ FatAcquireLock ();
+
+ //
+ // Open the file
+ //
+ Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);
+
+ //
+ // If the file was opened, return the handle to the caller
+ //
+ if (!EFI_ERROR (Status)) {
+ *NewHandle = &NewIFile->Handle;
+ }
+ //
+ // Unlock
+ //
+ Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);
+ FatReleaseLock ();
+
+ if (Token != NULL) {
+ if (!EFI_ERROR (Status)) {
+ Status = FatQueueTask (IFile, Task);
+ } else {
+ FatDestroyTask (Task);
+ }
+ }
+
+ return Status;
+}
+
+/**
+
+ Implements Open() of Simple File System Protocol.
+
+
+ @param FHand - File handle of the file serves as a starting reference point.
+ @param NewHandle - Handle of the file that is newly opened.
+ @param FileName - File name relative to FHand.
+ @param OpenMode - Open mode.
+ @param Attributes - Attributes to set if the file is created.
+
+ @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
+ The OpenMode is not supported.
+ The Attributes is not the valid attributes.
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
+ @retval EFI_SUCCESS - Open the file successfully.
+ @return Others - The status of open file.
+
+**/
+EFI_STATUS
+EFIAPI
+FatOpen (
+ IN EFI_FILE_PROTOCOL *FHand,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
+}