コード例 #1
0
ファイル: FvSimpleFileSystem.c プロジェクト: Rafog/edk2
/**
  Opens a new file relative to the source file's location.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to the source location. This would typically be an open
                     handle to a directory.
  @param  NewHandle  A pointer to the location to return the opened handle for the new
                     file.
  @param  FileName   The Null-terminated string of the name of the file to be opened.
                     The file name may contain the following path modifiers: "\", ".",
                     and "..".
  @param  OpenMode   The mode to open the file. The only valid combinations that the
                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
                     attribute bits for the newly created file.

  @retval EFI_SUCCESS          The file was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
                               when the media is write-protected.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemOpen (
    IN     EFI_FILE_PROTOCOL    *This,
    OUT EFI_FILE_PROTOCOL    **NewHandle,
    IN     CHAR16               *FileName,
    IN     UINT64               OpenMode,
    IN     UINT64               Attributes
)
{
    FV_FILESYSTEM_INSTANCE      *Instance;
    FV_FILESYSTEM_FILE          *File;
    FV_FILESYSTEM_FILE          *NewFile;
    FV_FILESYSTEM_FILE_INFO     *FvFileInfo;
    LIST_ENTRY                  *FvFileInfoLink;

    //
    // Check for a valid mode
    //
    switch (OpenMode) {
    case EFI_FILE_MODE_READ:
        break;

    default:
        return EFI_WRITE_PROTECTED;
    }

    File = FVFS_FILE_FROM_FILE_THIS (This);
    Instance = File->Instance;

    FileName = TrimFilePathToAbsolutePath (FileName);
    if (FileName == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    if (FileName[0] == L'\\') {
        FileName++;
    }

    //
    // Check for opening root
    //
    if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {
        NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
        if (NewFile == NULL) {
            return EFI_OUT_OF_RESOURCES;
        }
        NewFile->Signature = FVFS_FILE_SIGNATURE;
        NewFile->Instance  = Instance;
        NewFile->FvFileInfo = File->FvFileInfo;
        CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
        InitializeListHead (&NewFile->Link);
        InsertHeadList (&Instance->FileHead, &NewFile->Link);

        NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);

        *NewHandle = &NewFile->FileProtocol;
        return EFI_SUCCESS;
    }

    //
    // Do a linear search for a file in the FV with a matching filename
    //
    for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
            !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
            FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
        FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
        if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
            NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
            if (NewFile == NULL) {
                return EFI_OUT_OF_RESOURCES;
            }

            NewFile->Signature = FVFS_FILE_SIGNATURE;
            NewFile->Instance  = Instance;
            NewFile->FvFileInfo = FvFileInfo;
            CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
            InitializeListHead (&NewFile->Link);
            InsertHeadList (&Instance->FileHead, &NewFile->Link);

            *NewHandle = &NewFile->FileProtocol;
            return EFI_SUCCESS;
        }
    }

    return EFI_NOT_FOUND;
}
コード例 #2
0
ファイル: FvSimpleFileSystem.c プロジェクト: MattDevo/edk2
/**
  Opens a new file relative to the source file's location.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to the source location. This would typically be an open
                     handle to a directory.
  @param  NewHandle  A pointer to the location to return the opened handle for the new
                     file.
  @param  FileName   The Null-terminated string of the name of the file to be opened.
                     The file name may contain the following path modifiers: "\", ".",
                     and "..".
  @param  OpenMode   The mode to open the file. The only valid combinations that the
                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
                     attribute bits for the newly created file.

  @retval EFI_SUCCESS          The file was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
                               when the media is write-protected.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemOpen (
  IN     EFI_FILE_PROTOCOL    *This,
     OUT EFI_FILE_PROTOCOL    **NewHandle,
  IN     CHAR16               *FileName,
  IN     UINT64               OpenMode,
  IN     UINT64               Attributes
  )
{
  FV_FILESYSTEM_INSTANCE      *Instance;
  FV_FILESYSTEM_FILE          *File;
  FV_FILESYSTEM_FILE          *NewFile;
  FV_FILESYSTEM_FILE_INFO     *FvFileInfo;
  LIST_ENTRY                  *FvFileInfoLink;
  EFI_STATUS                  Status;
  UINTN                       FileNameLength;
  UINTN                       NewFileNameLength;
  CHAR16                      *FileNameWithExtension;

  //
  // Check for a valid mode
  //
  switch (OpenMode) {
  case EFI_FILE_MODE_READ:
    break;

  default:
    return EFI_WRITE_PROTECTED;
  }

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  FileName = TrimFilePathToAbsolutePath (FileName);
  if (FileName == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (FileName[0] == L'\\') {
    FileName++;
  }

  //
  // Check for opening root
  //
  if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = File->FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    NewFile->DirReadNext = NULL;
    if (!IsListEmpty (&Instance->FileInfoHead)) {
      NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
    }

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  //
  // Do a linear search for a file in the FV with a matching filename
  //
  Status     = EFI_NOT_FOUND;
  FvFileInfo = NULL;
  for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
      !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
       FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
    FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
    if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
      Status = EFI_SUCCESS;
      break;
    }
  }

  // If the file has not been found check if the filename exists with an extension
  // in case there was no extension present.
  // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers
  // present in the Firmware Volume
  if (Status == EFI_NOT_FOUND) {
    FileNameLength = StrLen (FileName);

    // Does the filename already contain the '.EFI' extension?
    if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) {
      // No, there was no extension. So add one and search again for the file
      // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character)
      NewFileNameLength = FileNameLength + 1 + 4;
      FileNameWithExtension = AllocatePool (NewFileNameLength * 2);
      StrCpyS (FileNameWithExtension, NewFileNameLength, FileName);
      StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI");

      for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
          !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
           FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
        FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
        if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) {
          Status = EFI_SUCCESS;
          break;
        }
      }
    }
  }

  if (!EFI_ERROR (Status)) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}