/** 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); }
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. Returns: EFI_SUCCESS - Open the file successfully. 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 open is for read-write fail it. EFI_OUT_OF_RESOURCES - Can not allocate the memory. --*/ { 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); }