Exemple #1
0
/**
  Set the name of a file.

  This is a helper function for SetFileInfo().

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  FileName  A pointer to the new name of the file.

  @retval  EFI_SUCCESS        The name was set.
  @retval  EFI_ACCESS_DENIED  An attempt is made to change the name of a file
                              to a file that is already present.

**/
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_INSTANCE  *Instance,
  IN  BOOTMON_FS_FILE      *File,
  IN  CONST CHAR16         *FileName
  )
{
  CHAR8            AsciiFileName[MAX_NAME_LENGTH];
  BOOTMON_FS_FILE  *SameFile;

  // If the file path start with a \ strip it. The EFI Shell may
  // insert a \ in front of the file name.
  if (FileName[0] == L'\\') {
    FileName++;
  }

  UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH);

  if (BootMonGetFileFromAsciiFileName (
        File->Instance,
        AsciiFileName,
        &SameFile
        ) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    return EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName,
      (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16));
    return EFI_SUCCESS;
  }
}
Exemple #2
0
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_FILE *File,
  IN  CHAR16          *FileNameUnicode
  )
{
  CHAR8                 *FileNameAscii;
  UINT16                 SavedChar;
  UINTN                  FileNameSize;
  BOOTMON_FS_FILE       *SameFile;
  EFI_STATUS             Status;

  // EFI Shell inserts '\' in front of the filename that must be stripped
  if (FileNameUnicode[0] == L'\\') {
    FileNameUnicode++;
  }
  //
  // Convert Unicode into Ascii
  //
  SavedChar = L'\0';
  FileNameSize = StrLen (FileNameUnicode) + 1;
  FileNameAscii = AllocatePool (FileNameSize * sizeof (CHAR8));
  if (FileNameAscii == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  // If Unicode string is too long then truncate it.
  if (FileNameSize > MAX_NAME_LENGTH) {
    SavedChar = FileNameUnicode[MAX_NAME_LENGTH - 1];
    FileNameUnicode[MAX_NAME_LENGTH - 1] = L'\0';
  }
  UnicodeStrToAsciiStr (FileNameUnicode, FileNameAscii);
  // If the unicode string was truncated then restore its original content.
  if (SavedChar != L'\0') {
    FileNameUnicode[MAX_NAME_LENGTH - 1] = SavedChar;
  }

  // If we're changing the file name
  if (AsciiStrCmp (FileNameAscii, File->HwDescription.Footer.Filename) == 0) {
    // No change to filename.
    Status = EFI_SUCCESS;
  } else if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
    // You can only change the filename if you open the file for write.
    Status = EFI_ACCESS_DENIED;
  } else if (BootMonGetFileFromAsciiFileName (
                File->Instance,
                File->HwDescription.Footer.Filename,
                &SameFile) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    Status = EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrCpy (FileNameAscii, File->HwDescription.Footer.Filename);
    Status = EFI_SUCCESS;
  }

  FreePool (FileNameAscii);
  return Status;
}
/**
  Opens a file on the Nor Flash FS volume

  Calls BootMonFsGetFileFromAsciiFilename to search the list of tracked files.

  @param  This  The EFI_FILE_PROTOCOL parent handle.
  @param  NewHandle Double-pointer to the newly created protocol.
  @param  FileName The name of the image/metadata on flash
  @param  OpenMode Read,write,append etc
  @param  Attributes ?

  @return EFI_STATUS
  OUT_OF_RESOURCES
    Run out of space to keep track of the allocated structures
  DEVICE_ERROR
    Unable to locate the volume associated with the parent file handle
  NOT_FOUND
    Filename wasn't found on flash
  SUCCESS

**/
EFIAPI
EFI_STATUS
BootMonFsOpenFile (
  IN EFI_FILE_PROTOCOL  *This,
  OUT EFI_FILE_PROTOCOL **NewHandle,
  IN CHAR16             *FileName,
  IN UINT64             OpenMode,
  IN UINT64             Attributes
  )
{
  BOOTMON_FS_FILE     *Directory;
  BOOTMON_FS_FILE     *File;
  BOOTMON_FS_INSTANCE *Instance;
  CHAR8*               AsciiFileName;
  EFI_STATUS           Status;

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

  // The only valid modes are read, read/write, and read/write/create
  if (!(OpenMode & EFI_FILE_MODE_READ) || ((OpenMode & EFI_FILE_MODE_CREATE)  && !(OpenMode & EFI_FILE_MODE_WRITE))) {
    return EFI_INVALID_PARAMETER;
  }

  Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (Directory == NULL) {
    return EFI_DEVICE_ERROR;
  }

  Instance = Directory->Instance;

  // If the instance has not been initialized it yet then do it ...
  if (!Instance->Initialized) {
    Status = BootMonFsInitialize (Instance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  // BootMonFs 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
    //

    *NewHandle = &Instance->RootFile->File;
    Instance->RootFile->Position = 0;
    Status = EFI_SUCCESS;
  } else {
    //
    // Open or Create a regular file
    //

    // Check if the file already exists
    Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
    if (Status == EFI_NOT_FOUND) {
      // The file doesn't exist.
      if (OpenMode & EFI_FILE_MODE_CREATE) {
        // If the file does not exist but is required then create it.
        if (Attributes & EFI_FILE_DIRECTORY) {
          // BootMonFS doesn't support subdirectories
          Status = EFI_UNSUPPORTED;
        } else {
          // Create a new file
          Status = CreateNewFile (Instance, AsciiFileName, &File);
          if (!EFI_ERROR (Status)) {
            File->OpenMode = OpenMode;
            *NewHandle = &File->File;
            File->Position = 0;
          }
        }
      }
    } else if (Status == EFI_SUCCESS) {
      // The file exists
      File->OpenMode = OpenMode;
      *NewHandle = &File->File;
      File->Position = 0;
    }
  }

  FreePool (AsciiFileName);

  return Status;
}