X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=FatPkg%2FEnhancedFatDxe%2FOpen.c;h=f3fd6566ea3f791456ea64cc340ea9767634d2ba;hb=HEAD;hp=b6369cf0b3af10d19cada1b4d8a8658b64a51832;hpb=b9ec93308b33bcb0bb37d6213a76c3fed0b5bc0b;p=mirror_edk2.git diff --git a/FatPkg/EnhancedFatDxe/Open.c b/FatPkg/EnhancedFatDxe/Open.c index b6369cf0b3..f3fd6566ea 100644 --- a/FatPkg/EnhancedFatDxe/Open.c +++ b/FatPkg/EnhancedFatDxe/Open.c @@ -1,54 +1,32 @@ -/*++ +/** @file + Routines dealing with file open. -Copyright (c) 2005 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php +Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - open.c - -Abstract: - - Routines dealing with file open - -Revision History - ---*/ +**/ #include "Fat.h" -EFI_STATUS -FatAllocateIFile ( - IN FAT_OFILE *OFile, - OUT FAT_IFILE **PtrIFile - ) -/*++ - -Routine Description: +/** Create an Open instance for the existing OFile. The IFile of the newly opened file is passed out. -Arguments: - - OFile - The file that serves as a starting reference point. - PtrIFile - The newly generated IFile instance. - -Returns: + @param OFile - The file that serves as a starting reference point. + @param PtrIFile - The newly generated IFile instance. - EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile - EFI_SUCCESS - Create the new IFile for the OFile successfully + @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; + FAT_IFILE *IFile; ASSERT_VOLUME_LOCKED (OFile->Volume); @@ -62,50 +40,55 @@ Returns: IFile->Signature = FAT_IFILE_SIGNATURE; - CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE)); + 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; } -EFI_STATUS -FatOFileOpen ( - IN FAT_OFILE *OFile, - OUT FAT_IFILE **NewIFile, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT8 Attributes - ) -/*++ - -Routine Description: +/** Open a file for a file name relative to an existing OFile. The IFile of the newly opened file is passed out. -Arguments: - - OFile - The file that serves as a starting reference point. - NewIFile - The newly generated IFile instance. - FileName - The file name relative to the OFile. - OpenMode - Open mode. - Attributes - Attributes to set if the file is created. + @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. -Returns: - EFI_SUCCESS - Open the file successfully. - EFI_INVALID_PARAMETER - The open mode is conflict with the attributes + @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. - EFI_NOT_FOUND - Conficts between dir intention and attribute. - EFI_WRITE_PROTECTED - Can't open for write if the volume is read only. - EFI_ACCESS_DENIED - If the file's attribute is read only, and the + @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. - EFI_OUT_OF_RESOURCES - Can not allocate the memory. + @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; @@ -114,12 +97,14 @@ Returns: UINT8 FileAttributes; BOOLEAN WriteMode; + DirEnt = NULL; Volume = OFile->Volume; ASSERT_VOLUME_LOCKED (Volume); - WriteMode = (BOOLEAN) (OpenMode & EFI_FILE_MODE_WRITE); + 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 // @@ -127,6 +112,7 @@ Returns: if (EFI_ERROR (Status)) { return Status; } + // // Get new OFile for the file // @@ -149,6 +135,7 @@ Returns: return Status; } + ASSERT (DirEnt != NULL); Status = FatOpenDirEnt (OFile, DirEnt); if (EFI_ERROR (Status)) { return Status; @@ -165,14 +152,16 @@ Returns: } } } + // // 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) { + if (((FileAttributes & EFI_FILE_READ_ONLY) != 0) && ((FileAttributes & FAT_ATTRIBUTE_DIRECTORY) == 0) && WriteMode) { return EFI_ACCESS_DENIED; } + // // Create an open instance of the OFile // @@ -181,49 +170,47 @@ Returns: return Status; } - (*NewIFile)->ReadOnly = (BOOLEAN)!WriteMode; + (*NewIFile)->ReadOnly = (BOOLEAN) !WriteMode; - DEBUG ((EFI_D_INFO, "FSOpen: Open '%S' %r\n", FileName, Status)); + DEBUG ((DEBUG_INFO, "FSOpen: Open '%S' %r\n", FileName, Status)); return FatOFileFlush (OFile); } -EFI_STATUS -EFIAPI -FatOpen ( - IN EFI_FILE *FHand, - OUT EFI_FILE **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -/*++ -Routine Description: +/** - Implements Open() of Simple File System Protocol. - -Arguments: - - FHand - File handle of the file serves as a starting reference point. - NewHandle - Handle of the file that is newly opened. - FileName - File name relative to FHand. - OpenMode - Open mode. - Attributes - Attributes to set if the file is created. + Implements OpenEx() of Simple File System Protocol. -Returns: + @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.: - EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty. + @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. - EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string. - EFI_SUCCESS - Open the file successfully. - Others - The status of open file. + @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 @@ -231,33 +218,47 @@ Returns: 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; + 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 - // - if (Attributes & (~EFI_FILE_VALID_ATTR)) { - return EFI_INVALID_PARAMETER; + default: + return EFI_INVALID_PARAMETER; } + // - // Can't open for create and apply the read only attribute + // Check for valid Attributes for file creation case. // - if ((OpenMode & EFI_FILE_MODE_CREATE) && (Attributes & EFI_FILE_READ_ONLY)) { + 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 @@ -267,7 +268,7 @@ Returns: // // Open the file // - Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes); + Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8)Attributes); // // If the file was opened, return the handle to the caller @@ -275,11 +276,52 @@ Returns: if (!EFI_ERROR (Status)) { *NewHandle = &NewIFile->Handle; } + // // Unlock // - Status = FatCleanupVolume (OFile->Volume, NULL, Status); + 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); +}