这里介绍一个能够获得文件基本信息的函数: 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
参考:
1.本文的例子参考 \ShellPkg\Library\UefiShellLevel3CommandsLib\Touch.c