Step to UEFI (32) —– GetFileInfo

这里介绍一个能够获得文件基本信息的函数: GetFileInfo

可以在 \ShellPkg\Include\Library\ShellLib.h 看到定义

/**
  This function will retrieve the information about the file for the handle
  specified and store it in allocated pool memory.

  This function allocates a buffer to store the file's information. It is the
  caller's responsibility to free the buffer.

  @param[in] FileHandle         The file handle of the file for which information is
                                being requested.

  @retval NULL                  Information could not be retrieved.

  @return                       The information about the file.
**/
EFI_FILE_INFO*
EFIAPI
ShellGetFileInfo (
  IN SHELL_FILE_HANDLE          FileHandle
  );

 

需要FileHandle作为输入函数,输出结果是 EFI_FILE_INFO 结构体。 这个结构体可以在
\MdePkg\Include\Guid\FileInfo.h 这个文件中看到(同时在 \EdkCompatibilityPkg\Foundation\Efi\Protocol\FileInfo\FileInfo.h 里面也有一个定义,只是这个定义未参加编译)。需要注意,调用的函数负责给结果分配一块内存,你自己的程序要负责释放这块内存的。

typedef struct {
  ///
  /// The size of the EFI_FILE_INFO structure, including the Null-terminated FileName string.
  ///
  UINT64    Size;
  ///
  /// The size of the file in bytes.
  ///
  UINT64    FileSize;
  ///
  /// PhysicalSize The amount of physical space the file consumes on the file system volume.
  ///
  UINT64    PhysicalSize;
  ///
  /// The time the file was created.
  ///
  EFI_TIME  CreateTime;
  ///
  /// The time when the file was last accessed.
  ///
  EFI_TIME  LastAccessTime;
  ///
  /// The time when the file's contents were last modified.
  ///
  EFI_TIME  ModificationTime;
  ///
  /// The attribute bits for the file.
  ///
  UINT64    Attribute;
  ///
  /// The Null-terminated name of the file.
  ///
  CHAR16    FileName[1];
} EFI_FILE_INFO;

 

看这个结构体可以得知,我们能够获得文件的大小,创建时间,修改时间属性文件名等等。

对于时间的定义 EFI_TIME 可以在 \BaseTools\Source\C\Include\Common\UefiBaseTypes.h 看到。相比之前我们看过的 time_t ,这个结构体是很单纯的定义,不需要换算:

// EFI Time Abstraction:
//  Year:       2000 - 20XX
//  Month:      1 - 12
//  Day:        1 - 31
//  Hour:       0 - 23
//  Minute:     0 - 59
//  Second:     0 - 59
//  Nanosecond: 0 - 999,999,999
//  TimeZone:   -1440 to 1440 or 2047
//
typedef struct {
  UINT16  Year;
  UINT8   Month;
  UINT8   Day;
  UINT8   Hour;
  UINT8   Minute;
  UINT8   Second;
  UINT8   Pad1;
  UINT32  Nanosecond;
  INT16   TimeZone;
  UINT8   Daylight;
  UINT8   Pad2;
} EFI_TIME;

 

对于 Attribute 的定义,在 \MdePkg\Include\Protocol\SimpleFileSystem.h

//
// File attributes
//
#define EFI_FILE_READ_ONLY  0x0000000000000001ULL
#define EFI_FILE_HIDDEN     0x0000000000000002ULL
#define EFI_FILE_SYSTEM     0x0000000000000004ULL
#define EFI_FILE_RESERVED   0x0000000000000008ULL
#define EFI_FILE_DIRECTORY  0x0000000000000010ULL
#define EFI_FILE_ARCHIVE    0x0000000000000020ULL
#define EFI_FILE_VALID_ATTR 0x0000000000000037ULL

 

最后,写一个程序验证一下

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

#include  <stdio.h>
#include  <stdlib.h>
#include  <wchar.h>

#include <Protocol/EfiShell.h>
#include <Library/ShellLib.h>

extern EFI_BOOT_SERVICES         *gBS;
extern EFI_SYSTEM_TABLE			 *gST;
extern EFI_RUNTIME_SERVICES 	 *gRT;

extern EFI_SHELL_PROTOCOL        *gEfiShellProtocol;

int
EFIAPI
main (
  IN int Argc,
  IN char **Argv
  )
{
  EFI_FILE_HANDLE   FileHandle;
  RETURN_STATUS     Status;
  EFI_FILE_INFO     *FileInfo = NULL;
  
  Status = ShellOpenFileByName(L"fsnt0:", (SHELL_FILE_HANDLE *)&FileHandle,
                               EFI_FILE_MODE_READ , 0);

  if(Status != RETURN_SUCCESS) {
        Print(L"OpenFile failed!\n");
		return EFI_SUCCESS;
      }							   

  FileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)FileHandle);	

  Print(L"Filesize [%ld] bytes\n",FileInfo-> FileSize);
  Print(L"PhysicalSize [%ld] bytes\n",FileInfo-> PhysicalSize);  

  Print(L"File Create date [%d-%d-%d %d-%d-%d]\n",
		FileInfo-> CreateTime.Year,
		FileInfo-> CreateTime.Month,
		FileInfo-> CreateTime.Day,
		FileInfo-> CreateTime.Hour,
		FileInfo-> CreateTime.Minute,
		FileInfo-> CreateTime.Second);    
		
  Print(L"File last accessed date [%d-%d-%d %d-%d-%d]\n",
		FileInfo-> LastAccessTime.Year,
		FileInfo-> LastAccessTime.Month,
		FileInfo-> LastAccessTime.Day,
		FileInfo-> LastAccessTime.Hour,
		FileInfo-> LastAccessTime.Minute,
		FileInfo-> LastAccessTime.Second);   		
		
  Print(L"File last modification date [%d-%d-%d %d-%d-%d]\n",
		FileInfo-> ModificationTime.Year,
		FileInfo-> ModificationTime.Month,
		FileInfo-> ModificationTime.Day,
		FileInfo-> ModificationTime.Hour,
		FileInfo-> ModificationTime.Minute,
		FileInfo-> ModificationTime.Second);   		

  Print(L"File Name [%s]\n",&FileInfo->FileName[0]);  
		
  free(FileInfo);  // Free up the buffer from ShellGetFileInfo()  
  
  return EFI_SUCCESS;
}

 

getfileinfo

代码下载:
GetFileInfo

参考:

1.本文的例子参考 \ShellPkg\Library\UefiShellLevel3CommandsLib\Touch.c

发表评论

电子邮件地址不会被公开。 必填项已用*标注