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: EFI_OUT_OF_RESOURCES - Can not allocate the memory for the IFile EFI_SUCCESS - Create the new IFile for the OFile successfully --*/ { 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; }
/** 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; }
EFI_STATUS FatAccessOFile ( IN FAT_OFILE *OFile, IN IO_MODE IoMode, IN UINTN Position, IN OUT UINTN *DataBufferSize, IN OUT UINT8 *UserBuffer, IN FAT_TASK *Task ) /*++ Routine Description: This function reads data from a file or writes data to a file. It uses OFile->PosRem to determine how much data can be accessed in one time. Arguments: OFile - The open file. IoMode - Indicate whether the access mode is reading or writing. Position - The position where data will be accessed. DataBufferSize - Size of Buffer. UserBuffer - Buffer containing data. Returns: EFI_SUCCESS - Access the data successfully. other - An error occurred when operating on the disk. --*/ { FAT_VOLUME *Volume; UINTN Len; EFI_STATUS Status; UINTN BufferSize; BufferSize = *DataBufferSize; Volume = OFile->Volume; ASSERT_VOLUME_LOCKED (Volume); Status = EFI_SUCCESS; while (BufferSize > 0) { // // Seek the OFile to the file position // Status = FatOFilePosition (OFile, Position, BufferSize); if (EFI_ERROR (Status)) { break; } // // Clip length to block run // Len = BufferSize > OFile->PosRem ? OFile->PosRem : BufferSize; // // Write the data // Status = FatDiskIo (Volume, IoMode, OFile->PosDisk, Len, UserBuffer, Task); if (EFI_ERROR (Status)) { break; } // // Data was successfully accessed // Position += Len; UserBuffer += Len; BufferSize -= Len; if (IoMode == WRITE_DATA) { OFile->Dirty = TRUE; OFile->Archive = TRUE; } // // Make sure no outbound occurred // ASSERT (Position <= OFile->FileSize); } // // Update the number of bytes accessed // *DataBufferSize -= BufferSize; return Status; }
/** 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); }