Exemple #1
0
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;
}
Exemple #2
0
/**

  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;
}
Exemple #3
0
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;
}
Exemple #4
0
/**

  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);
}
Exemple #5
0
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);
}