123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /** @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 - Conficts 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);
- }
|