예제 #1
0
/**
  Worker function that extends the size of an open file.

  The extension is filled with zeros.

  @param[in]  Fcb   Internal description of the opened file
  @param[in]  Size  The number of bytes, the file has to be extended.

  @retval  EFI_SUCCESS       The file was extended.
  @retval  EFI_DEVICE_ERROR  The last issued semi-hosting operation failed.

**/
STATIC
EFI_STATUS
ExtendFile (
  IN  SEMIHOST_FCB  *Fcb,
  IN  UINTN         Size
  )
{
  RETURN_STATUS  Return;
  UINTN          Remaining;
  CHAR8          WriteBuffer[128];
  UINTN          WriteNb;
  UINTN          WriteSize;

  Return = SemihostFileSeek (Fcb->SemihostHandle, Fcb->Info.FileSize);
  if (RETURN_ERROR (Return)) {
    return EFI_DEVICE_ERROR;
  }

  Remaining = Size;
  SetMem (WriteBuffer, 0, sizeof(WriteBuffer));
  while (Remaining > 0) {
    WriteNb = MIN (Remaining, sizeof(WriteBuffer));
    WriteSize = WriteNb;
    Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
    if (RETURN_ERROR (Return)) {
      return EFI_DEVICE_ERROR;
    }
    Remaining -= WriteNb;
  }

  return EFI_SUCCESS;
}
예제 #2
0
/**
  Write data to an open file.

  @param[in]      This        A pointer to the EFI_FILE_PROTOCOL instance that
                              is the file handle to write data to.
  @param[in out]  BufferSize  On input, the size of the Buffer. On output, the
                              size of the data actually written. In both cases,
                              the size is measured in bytes.
  @param[in]      Buffer      The buffer of data to write.

  @retval  EFI_SUCCESS            The data was written.
  @retval  EFI_ACCESS_DENIED      Attempt to write into a read only file or
                                  in a file opened in read only mode.
  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.
  @retval  EFI_INVALID_PARAMETER  At least one of the three input pointers is NULL.

**/
EFI_STATUS
FileWrite (
  IN     EFI_FILE *This,
  IN OUT UINTN    *BufferSize,
  IN     VOID     *Buffer
  )
{
  SEMIHOST_FCB   *Fcb;
  EFI_STATUS     Status;
  UINTN          WriteSize;
  RETURN_STATUS  Return;
  UINTN          Length;

  if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Fcb = SEMIHOST_FCB_FROM_THIS (This);

  // We cannot write a read-only file
  if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
      || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
    return EFI_ACCESS_DENIED;
  }

  //
  // If the position has been set past the end of the file, first grow the
  // file from its current size "Fcb->Info.FileSize" to "Fcb->Position"
  // size, filling the gap with zeros.
  //
  if (Fcb->Position > Fcb->Info.FileSize) {
    Status = ExtendFile (Fcb, Fcb->Position - Fcb->Info.FileSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Fcb->Info.FileSize = Fcb->Position;
  }

  WriteSize = *BufferSize;
  Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
  if (RETURN_ERROR (Return)) {
    return EFI_DEVICE_ERROR;
  }

  Fcb->Position += *BufferSize;
  if (Fcb->Position > Fcb->Info.FileSize) {
    Fcb->Info.FileSize = Fcb->Position;
  }

  Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
  if (RETURN_ERROR (Return)) {
    return EFI_DEVICE_ERROR;
  }
  Fcb->Info.PhysicalSize = Length;

  return EFI_SUCCESS;
}
예제 #3
0
파일: SemihostFs.c 프로젝트: Cutty/edk2
EFI_STATUS
FileWrite (
  IN     EFI_FILE *File,
  IN OUT UINTN    *BufferSize,
  IN     VOID     *Buffer
  )
{
  SEMIHOST_FCB *Fcb    = NULL;
  EFI_STATUS   Status;
  UINTN        WriteSize = *BufferSize;

  Fcb = SEMIHOST_FCB_FROM_THIS(File);

  Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);

  if (!EFI_ERROR(Status)) {
    // Semihost write return the number of bytes *NOT* written.
    *BufferSize -= WriteSize;
    Fcb->Position += *BufferSize;
  }
  
  return Status;
}
예제 #4
0
/**
  Worker function that truncate a file specified by its name to a given size.

  @param[in]  FileName  The Null-terminated string of the name of the file to be opened.
  @param[in]  Size      The target size for the file.

  @retval  EFI_SUCCESS       The file was truncated.
  @retval  EFI_DEVICE_ERROR  The last issued semi-hosting operation failed.

**/
STATIC
EFI_STATUS
TruncateFile (
  IN CHAR8  *FileName,
  IN UINTN   Size
  )
{
  EFI_STATUS     Status;
  RETURN_STATUS  Return;
  UINTN          FileHandle;
  UINT8          *Buffer;
  UINTN          Remaining;
  UINTN          Read;
  UINTN          ToRead;

  Status     = EFI_DEVICE_ERROR;
  FileHandle = 0;
  Buffer     = NULL;

  Return = SemihostFileOpen (
             FileName,
             SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,
             &FileHandle
             );
  if (RETURN_ERROR (Return)) {
    goto Error;
  }

  Buffer = AllocatePool (Size);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  Read = 0;
  Remaining = Size;
  while (Remaining > 0) {
    ToRead = Remaining;
    Return = SemihostFileRead (FileHandle, &ToRead, Buffer + Read);
    if (RETURN_ERROR (Return)) {
      goto Error;
    }
    Remaining -= ToRead;
    Read      += ToRead;
  }

  Return = SemihostFileClose (FileHandle);
  FileHandle = 0;
  if (RETURN_ERROR (Return)) {
    goto Error;
  }

  Return = SemihostFileOpen (
             FileName,
             SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY,
             &FileHandle
             );
  if (RETURN_ERROR (Return)) {
    goto Error;
  }

  if (Size > 0) {
    Return = SemihostFileWrite (FileHandle, &Size, Buffer);
    if (RETURN_ERROR (Return)) {
      goto Error;
    }
  }

  Status = EFI_SUCCESS;

Error:

  if (FileHandle != 0) {
    SemihostFileClose (FileHandle);
  }
  if (Buffer != NULL) {
    FreePool (Buffer);
  }

  return (Status);

}