Ejemplo n.º 1
0
EFI_STATUS
VolumeOpen (
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
  OUT EFI_FILE                        **Root
  )
{
  SEMIHOST_FCB *RootFcb = NULL;
  
  if (Root == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  RootFcb = AllocateFCB ();
  if (RootFcb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  RootFcb->IsRoot = TRUE;

  InsertTailList (&gFileList, &RootFcb->Link);

  *Root = &RootFcb->File;

  return EFI_SUCCESS;
}
Ejemplo n.º 2
0
EFI_STATUS
FileOpen (
  IN  EFI_FILE    *File,
  OUT EFI_FILE    **NewHandle,
  IN  CHAR16      *FileName,
  IN  UINT64      OpenMode,
  IN  UINT64      Attributes
  )
{
  SEMIHOST_FCB  *FileFcb = NULL;
  EFI_STATUS    Status   = EFI_SUCCESS;
  UINTN         SemihostHandle;
  CHAR8         *AsciiFileName;
  UINT32        SemihostMode;
  BOOLEAN       IsRoot;

  if ((FileName == NULL) || (NewHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  // Semihost interface requires ASCII filenames
  AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
  if (AsciiFileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  UnicodeStrToAsciiStr (FileName, AsciiFileName);

  if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
      (AsciiStrCmp (AsciiFileName, "/")  == 0) ||
      (AsciiStrCmp (AsciiFileName, "")   == 0) ||
      (AsciiStrCmp (AsciiFileName, ".")  == 0)) {
    // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
    IsRoot = TRUE;

    // Root directory node doesn't have a name.
    FreePool (AsciiFileName);
    AsciiFileName = NULL;
  } else {
    // Translate EFI_FILE_MODE into Semihosting mode
    if (OpenMode & EFI_FILE_MODE_WRITE) {
      SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY;
    } else if (OpenMode & EFI_FILE_MODE_READ) {
      SemihostMode = SEMIHOST_FILE_MODE_READ  | SEMIHOST_FILE_MODE_BINARY;
    } else {
      return EFI_UNSUPPORTED;
    }

    // Add the creation flag if necessary
    if (OpenMode & EFI_FILE_MODE_CREATE) {
      SemihostMode |= SEMIHOST_FILE_MODE_CREATE;
    }

    // Call the semihosting interface to open the file.
    Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
    if (EFI_ERROR(Status)) {
      return Status;
    }
    
    IsRoot = FALSE;
  }

  // Allocate a control block and fill it
  FileFcb = AllocateFCB ();
  if (FileFcb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  FileFcb->FileName       = AsciiFileName;
  FileFcb->SemihostHandle = SemihostHandle;
  FileFcb->Position       = 0;
  FileFcb->IsRoot         = IsRoot;

  InsertTailList (&gFileList, &FileFcb->Link);

  *NewHandle = &FileFcb->File;

  return Status;
}
Ejemplo n.º 3
0
/**
  Open a file on the host system by means of the semihosting interface.

  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is
                           the file handle to source location.
  @param[out]  NewHandle   A pointer to the location to return the opened
                           handle for the new file.
  @param[in]   FileName    The Null-terminated string of the name of the file
                           to be opened.
  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or
                           Read/Write/Create
  @param[in]   Attributes  Only valid for EFI_FILE_MODE_CREATE, in which case these
                           are the attribute bits for the newly created file. The
                           mnemonics of the attribute bits are : EFI_FILE_READ_ONLY,
                           EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED,
                           EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE.

  @retval  EFI_SUCCESS            The file was open.
  @retval  EFI_NOT_FOUND          The specified file could not be found.
  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.
  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible
                                  with the semi-hosting interface.
  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.
  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

**/
EFI_STATUS
FileOpen (
  IN  EFI_FILE  *This,
  OUT EFI_FILE  **NewHandle,
  IN  CHAR16    *FileName,
  IN  UINT64    OpenMode,
  IN  UINT64    Attributes
  )
{
  SEMIHOST_FCB   *FileFcb;
  RETURN_STATUS  Return;
  EFI_STATUS     Status;
  UINTN          SemihostHandle;
  CHAR8          *AsciiFileName;
  UINT32         SemihostMode;
  UINTN          Length;

  if ((FileName == NULL) || (NewHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ( (OpenMode != EFI_FILE_MODE_READ) &&
       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
    return EFI_INVALID_PARAMETER;
  }

  if ((OpenMode & EFI_FILE_MODE_CREATE) &&
      (Attributes & EFI_FILE_DIRECTORY)    ) {
    return EFI_WRITE_PROTECTED;
  }

  AsciiFileName = AllocatePool (StrLen (FileName) + 1);
  if (AsciiFileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  UnicodeStrToAsciiStr (FileName, AsciiFileName);

  // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
  if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
      (AsciiStrCmp (AsciiFileName, "/")  == 0) ||
      (AsciiStrCmp (AsciiFileName, "")   == 0) ||
      (AsciiStrCmp (AsciiFileName, ".")  == 0)    ) {
    FreePool (AsciiFileName);
    return (VolumeOpen (&gSemihostFs, NewHandle));
  }

  //
  // No control is done here concerning the file path. It is passed
  // as it is to the host operating system through the semi-hosting
  // interface. We first try to open the file in the read or update
  // mode even if the file creation has been asked for. That way, if
  // the file already exists, it is not truncated to zero length. In
  // write mode (bit SEMIHOST_FILE_MODE_WRITE up), if the file already
  // exists, it is reset to an empty file.
  //
  if (OpenMode == EFI_FILE_MODE_READ) {
    SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;
  } else {
    SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
  }
  Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);

  if (RETURN_ERROR (Return)) {
    if (OpenMode & EFI_FILE_MODE_CREATE) {
      //
      // In the create if does not exist case, if the opening in update
      // mode failed, create it and open it in update mode. The update
      // mode allows for both read and write from and to the file.
      //
      Return = SemihostFileOpen (
                 AsciiFileName,
                 SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE,
                 &SemihostHandle
                 );
      if (RETURN_ERROR (Return)) {
        Status = EFI_DEVICE_ERROR;
        goto Error;
      }
    } else {
      Status = EFI_NOT_FOUND;
      goto Error;
    }
  }

  // Allocate a control block and fill it
  FileFcb = AllocateFCB ();
  if (FileFcb == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  FileFcb->FileName       = AsciiFileName;
  FileFcb->SemihostHandle = SemihostHandle;
  FileFcb->Position       = 0;
  FileFcb->IsRoot         = 0;
  FileFcb->OpenMode       = OpenMode;

  Return = SemihostFileLength (SemihostHandle, &Length);
  if (RETURN_ERROR (Return)) {
    Status = EFI_DEVICE_ERROR;
    FreeFCB (FileFcb);
    goto Error;
  }

  FileFcb->Info.FileSize     = Length;
  FileFcb->Info.PhysicalSize = Length;
  FileFcb->Info.Attribute    = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;

  InsertTailList (&gFileList, &FileFcb->Link);

  *NewHandle = &FileFcb->File;

  return EFI_SUCCESS;

Error:

  FreePool (AsciiFileName);

  return Status;
}