123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*++
- Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
- 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
- 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:
- 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));
- IFile->OFile = OFile;
- InsertTailList (&OFile->Opens, &IFile->Link);
- *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.
- 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;
- 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;
- }
- 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
- EFIAPI
- FatOpen (
- IN EFI_FILE_PROTOCOL *FHand,
- OUT EFI_FILE_PROTOCOL **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.
- Returns:
- 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.
- --*/
- {
- FAT_IFILE *IFile;
- FAT_IFILE *NewIFile;
- FAT_OFILE *OFile;
- EFI_STATUS Status;
- //
- // 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;
- //
- // 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);
- FatReleaseLock ();
- return Status;
- }
|