-/*++\r
+/** @file\r
+ Routines dealing with file open.\r
\r
-Copyright (c) 2005 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- open.c\r
-\r
-Abstract:\r
-\r
- Routines dealing with file open\r
-\r
-Revision History\r
-\r
---*/\r
+**/\r
\r
#include "Fat.h"\r
\r
-EFI_STATUS\r
-FatAllocateIFile (\r
- IN FAT_OFILE *OFile,\r
- OUT FAT_IFILE **PtrIFile\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Create an Open instance for the existing OFile.\r
The IFile of the newly opened file is passed out.\r
\r
-Arguments:\r
-\r
- OFile - The file that serves as a starting reference point.\r
- PtrIFile - The newly generated IFile instance.\r
-\r
-Returns:\r
+ @param OFile - The file that serves as a starting reference point.\r
+ @param PtrIFile - The newly generated IFile instance.\r
\r
- EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile\r
- EFI_SUCCESS - Create the new IFile for the OFile successfully\r
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile\r
+ @retval EFI_SUCCESS - Create the new IFile for the OFile successfully\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatAllocateIFile (\r
+ IN FAT_OFILE *OFile,\r
+ OUT FAT_IFILE **PtrIFile\r
+ )\r
{\r
- FAT_IFILE *IFile;\r
+ FAT_IFILE *IFile;\r
\r
ASSERT_VOLUME_LOCKED (OFile->Volume);\r
\r
\r
IFile->Signature = FAT_IFILE_SIGNATURE;\r
\r
- CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE));\r
+ CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));\r
+\r
+ //\r
+ // Report the correct revision number based on the DiskIo2 availability\r
+ //\r
+ if (OFile->Volume->DiskIo2 != NULL) {\r
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;\r
+ } else {\r
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;\r
+ }\r
\r
IFile->OFile = OFile;\r
InsertTailList (&OFile->Opens, &IFile->Link);\r
+ InitializeListHead (&IFile->Tasks);\r
\r
*PtrIFile = IFile;\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-FatOFileOpen (\r
- IN FAT_OFILE *OFile,\r
- OUT FAT_IFILE **NewIFile,\r
- IN CHAR16 *FileName,\r
- IN UINT64 OpenMode,\r
- IN UINT8 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Open a file for a file name relative to an existing OFile.\r
The IFile of the newly opened file is passed out.\r
\r
-Arguments:\r
-\r
- OFile - The file that serves as a starting reference point.\r
- NewIFile - The newly generated IFile instance.\r
- FileName - The file name relative to the OFile.\r
- OpenMode - Open mode.\r
- Attributes - Attributes to set if the file is created.\r
+ @param OFile - The file that serves as a starting reference point.\r
+ @param NewIFile - The newly generated IFile instance.\r
+ @param FileName - The file name relative to the OFile.\r
+ @param OpenMode - Open mode.\r
+ @param Attributes - Attributes to set if the file is created.\r
\r
-Returns:\r
\r
- EFI_SUCCESS - Open the file successfully.\r
- EFI_INVALID_PARAMETER - The open mode is conflict with the attributes\r
+ @retval EFI_SUCCESS - Open the file successfully.\r
+ @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes\r
or the file name is not valid.\r
- EFI_NOT_FOUND - Conficts between dir intention and attribute.\r
- EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.\r
- EFI_ACCESS_DENIED - If the file's attribute is read only, and the\r
+ @retval EFI_NOT_FOUND - Conflicts between dir intention and attribute.\r
+ @retval EFI_WRITE_PROTECTED - Can't open for write if the volume is read only.\r
+ @retval EFI_ACCESS_DENIED - If the file's attribute is read only, and the\r
open is for read-write fail it.\r
- EFI_OUT_OF_RESOURCES - Can not allocate the memory.\r
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatOFileOpen (\r
+ IN FAT_OFILE *OFile,\r
+ OUT FAT_IFILE **NewIFile,\r
+ IN CHAR16 *FileName,\r
+ IN UINT64 OpenMode,\r
+ IN UINT8 Attributes\r
+ )\r
{\r
FAT_VOLUME *Volume;\r
EFI_STATUS Status;\r
UINT8 FileAttributes;\r
BOOLEAN WriteMode;\r
\r
+ DirEnt = NULL;\r
Volume = OFile->Volume;\r
ASSERT_VOLUME_LOCKED (Volume);\r
- WriteMode = (BOOLEAN) (OpenMode & EFI_FILE_MODE_WRITE);\r
+ WriteMode = (BOOLEAN)(OpenMode & EFI_FILE_MODE_WRITE);\r
if (Volume->ReadOnly && WriteMode) {\r
return EFI_WRITE_PROTECTED;\r
}\r
+\r
//\r
// Verify the source file handle isn't in an error state\r
//\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// Get new OFile for the file\r
//\r
return Status;\r
}\r
\r
+ ASSERT (DirEnt != NULL);\r
Status = FatOpenDirEnt (OFile, DirEnt);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
}\r
}\r
+\r
//\r
// If the file's attribute is read only, and the open is for\r
// read-write, then the access is denied.\r
//\r
FileAttributes = OFile->DirEnt->Entry.Attributes;\r
- if ((FileAttributes & EFI_FILE_READ_ONLY) != 0 && (FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0 && WriteMode) {\r
+ if (((FileAttributes & EFI_FILE_READ_ONLY) != 0) && ((FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0) && WriteMode) {\r
return EFI_ACCESS_DENIED;\r
}\r
+\r
//\r
// Create an open instance of the OFile\r
//\r
return Status;\r
}\r
\r
- (*NewIFile)->ReadOnly = (BOOLEAN)!WriteMode;\r
+ (*NewIFile)->ReadOnly = (BOOLEAN) !WriteMode;\r
\r
- DEBUG ((EFI_D_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));\r
+ DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status));\r
return FatOFileFlush (OFile);\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-FatOpen (\r
- IN EFI_FILE *FHand,\r
- OUT EFI_FILE **NewHandle,\r
- IN CHAR16 *FileName,\r
- IN UINT64 OpenMode,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-Routine Description:\r
+/**\r
\r
- Implements Open() of Simple File System Protocol.\r
-\r
-Arguments:\r
-\r
- FHand - File handle of the file serves as a starting reference point.\r
- NewHandle - Handle of the file that is newly opened.\r
- FileName - File name relative to FHand.\r
- OpenMode - Open mode.\r
- Attributes - Attributes to set if the file is created.\r
+ Implements OpenEx() of Simple File System Protocol.\r
\r
-Returns:\r
+ @param FHand - File handle of the file serves as a starting reference point.\r
+ @param NewHandle - Handle of the file that is newly opened.\r
+ @param FileName - File name relative to FHand.\r
+ @param OpenMode - Open mode.\r
+ @param Attributes - Attributes to set if the file is created.\r
+ @param Token - A pointer to the token associated with the transaction.:\r
\r
- EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
+ @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
The OpenMode is not supported.\r
The Attributes is not the valid attributes.\r
- EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
- EFI_SUCCESS - Open the file successfully.\r
- Others - The status of open file.\r
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
+ @retval EFI_SUCCESS - Open the file successfully.\r
+ @return Others - The status of open file.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FatOpenEx (\r
+ IN EFI_FILE_PROTOCOL *FHand,\r
+ OUT EFI_FILE_PROTOCOL **NewHandle,\r
+ IN CHAR16 *FileName,\r
+ IN UINT64 OpenMode,\r
+ IN UINT64 Attributes,\r
+ IN OUT EFI_FILE_IO_TOKEN *Token\r
+ )\r
{\r
FAT_IFILE *IFile;\r
FAT_IFILE *NewIFile;\r
FAT_OFILE *OFile;\r
EFI_STATUS Status;\r
+ FAT_TASK *Task;\r
\r
//\r
// Perform some parameter checking\r
if (FileName == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
// Check for a valid mode\r
//\r
switch (OpenMode) {\r
- case EFI_FILE_MODE_READ:\r
- case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
- case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
- break;\r
+ case EFI_FILE_MODE_READ:\r
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r
+ break;\r
\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Check for valid attributes\r
- //\r
- if (Attributes & (~EFI_FILE_VALID_ATTR)) {\r
- return EFI_INVALID_PARAMETER;\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
- // Can't open for create and apply the read only attribute\r
+ // Check for valid Attributes for file creation case.\r
//\r
- if ((OpenMode & EFI_FILE_MODE_CREATE) && (Attributes & EFI_FILE_READ_ONLY)) {\r
+ if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && ((Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
IFile = IFILE_FROM_FHAND (FHand);\r
OFile = IFile->OFile;\r
+ Task = NULL;\r
+\r
+ if (Token == NULL) {\r
+ FatWaitNonblockingTask (IFile);\r
+ } else {\r
+ //\r
+ // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.\r
+ // But if it calls, the below check can avoid crash.\r
+ //\r
+ if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Task = FatCreateTask (IFile, Token);\r
+ if (Task == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
\r
//\r
// Lock\r
//\r
// Open the file\r
//\r
- Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);\r
+ Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8)Attributes);\r
\r
//\r
// If the file was opened, return the handle to the caller\r
if (!EFI_ERROR (Status)) {\r
*NewHandle = &NewIFile->Handle;\r
}\r
+\r
//\r
// Unlock\r
//\r
- Status = FatCleanupVolume (OFile->Volume, NULL, Status);\r
+ Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);\r
FatReleaseLock ();\r
\r
+ if (Token != NULL) {\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = FatQueueTask (IFile, Task);\r
+ } else {\r
+ FatDestroyTask (Task);\r
+ }\r
+ }\r
+\r
return Status;\r
}\r
+\r
+/**\r
+\r
+ Implements Open() of Simple File System Protocol.\r
+\r
+\r
+ @param FHand - File handle of the file serves as a starting reference point.\r
+ @param NewHandle - Handle of the file that is newly opened.\r
+ @param FileName - File name relative to FHand.\r
+ @param OpenMode - Open mode.\r
+ @param Attributes - Attributes to set if the file is created.\r
+\r
+ @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.\r
+ The OpenMode is not supported.\r
+ The Attributes is not the valid attributes.\r
+ @retval EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.\r
+ @retval EFI_SUCCESS - Open the file successfully.\r
+ @return Others - The status of open file.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FatOpen (\r
+ IN EFI_FILE_PROTOCOL *FHand,\r
+ OUT EFI_FILE_PROTOCOL **NewHandle,\r
+ IN CHAR16 *FileName,\r
+ IN UINT64 OpenMode,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);\r
+}\r