mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
624 lines
18 KiB
C
624 lines
18 KiB
C
/** @file
|
|
Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#ifndef OC_FILE_LIB_H
|
|
#define OC_FILE_LIB_H
|
|
|
|
// Include the abstracted protocol for its definitions
|
|
|
|
#include <Guid/FileInfo.h>
|
|
|
|
#include <Protocol/SimpleFileSystem.h>
|
|
#include <Protocol/DevicePath.h>
|
|
#include <Protocol/BlockIo.h>
|
|
#include <Protocol/BlockIo2.h>
|
|
|
|
/**
|
|
Maximum safe volume label size.
|
|
**/
|
|
#define OC_MAX_VOLUME_LABEL_SIZE 64
|
|
|
|
/**
|
|
Maximum safe content flavour size.
|
|
**/
|
|
#define OC_MAX_CONTENT_FLAVOUR_SIZE 64
|
|
|
|
typedef struct {
|
|
UINT32 PreviousTime;
|
|
UINTN PreviousIndex;
|
|
} DIRECTORY_SEARCH_CONTEXT;
|
|
|
|
/**
|
|
Locate file system from Device handle or path.
|
|
|
|
@param[in] DeviceHandle Device handle.
|
|
@param[in] FilePath Device path.
|
|
|
|
@retval simple file system protocol or NULL.
|
|
**/
|
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *
|
|
OcLocateFileSystem (
|
|
IN EFI_HANDLE DeviceHandle OPTIONAL,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Locate root volume from Device handle or path.
|
|
|
|
@param[in] DeviceHandle Device handle.
|
|
@param[in] FilePath Device path.
|
|
|
|
@retval opened file protocol or NULL.
|
|
**/
|
|
EFI_FILE_PROTOCOL *
|
|
OcLocateRootVolume (
|
|
IN EFI_HANDLE DeviceHandle OPTIONAL,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Locate file system from GUID.
|
|
|
|
@param[in] Guid GUID of the volume to locate.
|
|
|
|
@retval simple file system protocol or NULL.
|
|
**/
|
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *
|
|
OcLocateFileSystemByGuid (
|
|
IN CONST GUID *Guid
|
|
);
|
|
|
|
/**
|
|
Retrieves volume label.
|
|
|
|
@param[in] FileSystem A pointer to the file system protocol of the volume.
|
|
|
|
@retval A pointer to the NULL terminated unicode volume label.
|
|
**/
|
|
CHAR16 *
|
|
OcGetVolumeLabel (
|
|
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem
|
|
);
|
|
|
|
/**
|
|
Opens a new file relative to the source file's location.
|
|
This function is equivalent to EFI_FILE_OPEN but has additional restrictions
|
|
to provide board compatibility. Currently the only restriction is
|
|
no trailing slash in the filename due to issues in FAT drivers.
|
|
|
|
- Multiple boards, namely ASUS P8H61-M and P8H61-M LX2 will not
|
|
open directories with trailing slash. It is irrelevant whether
|
|
front slash is present for them.
|
|
For example, it means that L"EFI\\OC\\" or L"\\EFI\\OC\\" will both
|
|
fail to open, while L"EFI\\OC" and L"\\EFI\\OC" will open fine.
|
|
- Most newer boards on APTIO IV do handle directories with trailing
|
|
slash, however, their driver will modify passed string by removing
|
|
the slash by \0.
|
|
|
|
@param Directory File protocol instance of parent directory.
|
|
@param NewHandle Pointer for returned handle.
|
|
@param FileName Null-terminated file name or relative path.
|
|
@param OpenMode File open mode.
|
|
@param Attributes Attributes for the newly created file.
|
|
|
|
@retval EFI_SUCCESS for successfully opened file.
|
|
**/
|
|
EFI_STATUS
|
|
OcSafeFileOpen (
|
|
IN CONST EFI_FILE_PROTOCOL *Directory,
|
|
OUT EFI_FILE_PROTOCOL **NewHandle,
|
|
IN CONST CHAR16 *FileName,
|
|
IN CONST UINT64 OpenMode,
|
|
IN CONST UINT64 Attributes
|
|
);
|
|
|
|
/**
|
|
Report existence of file relative to source file's location.
|
|
|
|
@param Directory File protocol instance of parent directory.
|
|
@param FileName Null-terminated file name or relative path.
|
|
|
|
@retval TRUE when file exists.
|
|
**/
|
|
BOOLEAN
|
|
OcFileExists (
|
|
IN CONST EFI_FILE_PROTOCOL *Directory,
|
|
IN CONST CHAR16 *FileName
|
|
);
|
|
|
|
/**
|
|
Delete child file relative to source file's location.
|
|
|
|
@param Directory File protocol instance of parent directory.
|
|
@param FileName Null-terminated file name or relative path.
|
|
|
|
@retval EFI_SUCCESS File successfully deleted.
|
|
@retval EFI_NOT_FOUND File was not present.
|
|
@retval other Other error opening or deleting file.
|
|
**/
|
|
EFI_STATUS
|
|
OcDeleteFile (
|
|
IN EFI_FILE_PROTOCOL *Directory,
|
|
IN CONST CHAR16 *FileName
|
|
);
|
|
|
|
/**
|
|
Read file from file system with implicit double (2 byte) null termination.
|
|
Null termination does not affect the returned file size.
|
|
Depending on the implementation 0 byte files may return null.
|
|
|
|
@param[in] FileSystem A pointer to the file system protocol of the volume.
|
|
@param[in] FilePath The full path to the file on the device.
|
|
@param[out] FileSize The size of the file read (optional).
|
|
@param[in] MaxFileSize Upper file size bound (optional).
|
|
|
|
@retval A pointer to a buffer containing file read or NULL.
|
|
**/
|
|
VOID *
|
|
OcReadFile (
|
|
IN CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
|
|
IN CONST CHAR16 *FilePath,
|
|
OUT UINT32 *FileSize OPTIONAL,
|
|
IN CONST UINT32 MaxFileSize OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Read file from file protocol with implicit double (2 byte) null termination.
|
|
Null termination does not affect the returned file size.
|
|
Depending on the implementation 0 byte files may return null.
|
|
|
|
@param[in] RootDirectory A pointer to the file protocol of the directory.
|
|
@param[in] FilePath The full path to the file on the device.
|
|
@param[out] FileSize The size of the file read (optional).
|
|
@param[in] MaxFileSize Upper file size bound (optional).
|
|
|
|
@retval A pointer to a buffer containing file read or NULL.
|
|
**/
|
|
VOID *
|
|
OcReadFileFromDirectory (
|
|
IN CONST EFI_FILE_PROTOCOL *RootDirectory,
|
|
IN CONST CHAR16 *FilePath,
|
|
OUT UINT32 *FileSize OPTIONAL,
|
|
IN UINT32 MaxFileSize OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Determine file size if it is less than 4 GB.
|
|
|
|
@param[in] FileSystem A pointer to the file system protocol of the volume.
|
|
@param[in] FilePath The full path to the file on the device.
|
|
@param[out] Size 32-bit file size.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcReadFileSize (
|
|
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
|
|
IN CONST CHAR16 *FilePath,
|
|
OUT UINT32 *Size
|
|
);
|
|
|
|
/**
|
|
Read exact amount of bytes from EFI_FILE_PROTOCOL at specified position.
|
|
|
|
@param[in] File A pointer to the file protocol.
|
|
@param[in] Position Position to read data from.
|
|
@param[in] Size The size of the data read.
|
|
@param[out] Buffer A pointer to previously allocated buffer to read data to.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcGetFileData (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
IN UINT32 Position,
|
|
IN UINT32 Size,
|
|
OUT UINT8 *Buffer
|
|
);
|
|
|
|
/**
|
|
Write exact amount of bytes to a newly created file in EFI_FILE_PROTOCOL.
|
|
Please note, that several filesystems (or drivers) may limit file name length.
|
|
|
|
@param[in] WritableFs A pointer to the file protocol, any will be tried if NULL.
|
|
@param[in] FileName File name (possibly with path) to write.
|
|
@param[in] Buffer A pointer with the data to be written.
|
|
@param[in] Size Amount of data to be written.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcSetFileData (
|
|
IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL,
|
|
IN CONST CHAR16 *FileName,
|
|
IN CONST VOID *Buffer,
|
|
IN UINT32 Size
|
|
);
|
|
|
|
/**
|
|
Read all bytes from EFI_FILE_PROTOCOL and return a buffer.
|
|
|
|
@param[in] File A pointer to the file protocol.
|
|
@param[out] Buffer A pointer for the returned buffer.
|
|
@param[out] BufferSize A pointer for the size of the returned buffer.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcAllocateCopyFileData (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
OUT UINT8 **Buffer,
|
|
OUT UINT32 *BufferSize
|
|
);
|
|
|
|
/**
|
|
Initialize DIRECTORY_SEARCH_CONTEXT.
|
|
|
|
@param[in,out] Context A pointer to the DIRECTORY_SEARCH_CONTEXT.
|
|
**/
|
|
VOID
|
|
OcDirectorySeachContextInit (
|
|
IN OUT DIRECTORY_SEARCH_CONTEXT *Context
|
|
);
|
|
|
|
/**
|
|
Gets the next newest file from the specified directory.
|
|
|
|
@param[in,out] Context Context.
|
|
@param[in] Directory The directory EFI_FILE_PROTOCOL instance.
|
|
@param[in] FileNameStartsWith Skip files starting with this value.
|
|
@param[out] FileInfo EFI_FILE_INFO allocated from pool memory.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcGetNewestFileFromDirectory (
|
|
IN OUT DIRECTORY_SEARCH_CONTEXT *Context,
|
|
IN EFI_FILE_PROTOCOL *Directory,
|
|
IN CHAR16 *FileNameStartsWith OPTIONAL,
|
|
OUT EFI_FILE_INFO **FileInfo
|
|
);
|
|
|
|
/**
|
|
Ensure specified file is directory or file as specified by IsDirectory.
|
|
|
|
@param[in] File The file to check.
|
|
@param[in] IsDirectory Require that file is directory.
|
|
|
|
@retval EFI_SUCCESS File is directory/file as specified.
|
|
@retval EFI_INVALID_PARAMETER File is not directory/file as specified.
|
|
**/
|
|
EFI_STATUS
|
|
OcEnsureDirectoryFile (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
IN BOOLEAN IsDirectory
|
|
);
|
|
|
|
/**
|
|
Process directory item.
|
|
|
|
NB Successful processing must return EFI_SUCCESS or EFI_NOT_FOUND, or further
|
|
processing will be aborted.
|
|
|
|
Return EFI_NOT_FOUND to continue processing but act if no file found.
|
|
|
|
@param[in] Directory Parent directory file handle.
|
|
@param[in] FileInfo EFI_FILE_INFO allocated from pool memory,
|
|
will be freed after this call,
|
|
data to preserve must be copied.
|
|
@param[in] FileInfoSize FileInfoSize.
|
|
@param[in,out] Context Optional application-specific context.
|
|
|
|
@retval EFI_SUCCESS File found and successfully processed.
|
|
@retval EFI_NOT_FOUND (Act as if) no matching file was found.
|
|
@retval other Error processing file (aborts directory scan).
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(*OC_PROCESS_DIRECTORY_ENTRY) (
|
|
EFI_FILE_HANDLE Directory,
|
|
EFI_FILE_INFO *FileInfo,
|
|
UINTN FileInfoSize,
|
|
VOID *Context OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Scan directory, calling specified procedure for each directory entry.
|
|
|
|
@param[in] Directory The directory to scan.
|
|
@param[in] ProcessEntry Process entry, called for each directory entry matching filter.
|
|
@param[in,out] Context Optional application-specific context.
|
|
|
|
@retval EFI_NOT_FOUND Successful processing, no entries matching filter were found.
|
|
@retval EFI_SUCCESS Successful processing, at least one entry matching filter was found.
|
|
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
|
@retval other Other error returned by file system or ProcessEntry during processing
|
|
**/
|
|
EFI_STATUS
|
|
OcScanDirectory (
|
|
IN EFI_FILE_HANDLE Directory,
|
|
IN OC_PROCESS_DIRECTORY_ENTRY ProcessEntry,
|
|
IN OUT VOID *Context OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Get file information of specified type.
|
|
|
|
@param[in] File A pointer to file handle.
|
|
@param[in] InformationType A pointer to file info GUID.
|
|
@param[in] MinFileInfoSize Minimal size of the info provided.
|
|
@param[out] RealFileInfoSize Actual info size read (optional).
|
|
|
|
@retval read file info or NULL.
|
|
**/
|
|
VOID *
|
|
OcGetFileInfo (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
IN EFI_GUID *InformationType,
|
|
IN UINTN MinFileInfoSize,
|
|
OUT UINTN *RealFileInfoSize OPTIONAL
|
|
);
|
|
|
|
/**
|
|
Determine file size if it is less than 4 GB.
|
|
|
|
@param[in] File A pointer to the file protocol.
|
|
@param[out] Size 32-bit file size.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcGetFileSize (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
OUT UINT32 *Size
|
|
);
|
|
|
|
/**
|
|
Determine file modification time.
|
|
|
|
@param[in] File A pointer to the file protocol.
|
|
@param[out] Time Modification time.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcGetFileModificationTime (
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
OUT EFI_TIME *Time
|
|
);
|
|
|
|
/**
|
|
Check if filesystem is writable.
|
|
|
|
@param[in] Fs File system to check.
|
|
|
|
@retval TRUE on success.
|
|
**/
|
|
BOOLEAN
|
|
OcIsWritableFileSystem (
|
|
IN EFI_FILE_PROTOCOL *Fs
|
|
);
|
|
|
|
/**
|
|
Find writable filesystem.
|
|
|
|
@param[in,out] WritableFs First found writeable file system.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcFindWritableFileSystem (
|
|
IN OUT EFI_FILE_PROTOCOL **WritableFs
|
|
);
|
|
|
|
/**
|
|
Find writable filesystem from Bootstrap.
|
|
|
|
@param[out] FileSystem Pointer to first found writeable file system.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcFindWritableOcFileSystem (
|
|
OUT EFI_FILE_PROTOCOL **FileSystem
|
|
);
|
|
|
|
/**
|
|
Open a file or directory by file system handle and path.
|
|
See OcOpenFileByDevicePath() for more details.
|
|
|
|
@param[in] FileSystemHandle File System handle.
|
|
@param[in] RemainingDevicePath The remaining Device Path (must be all file
|
|
path nodes).
|
|
@param[out] File Resulting file protocol.
|
|
@param[in] OpenMode File open mode.
|
|
@param[in] Attributes File attributes.
|
|
|
|
@retval EFI_SUCCESS on succesful open.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OcOpenFileByRemainingDevicePath (
|
|
IN EFI_HANDLE FileSystemHandle,
|
|
IN CONST EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
|
|
OUT EFI_FILE_PROTOCOL **File,
|
|
IN UINT64 OpenMode,
|
|
IN UINT64 Attributes
|
|
);
|
|
|
|
/**
|
|
Open a file or directory by device path. This is a modified
|
|
version of EfiOpenFileByDevicePath function, which handles paths
|
|
with trailing slashes, that cause Open failure on old firmware.
|
|
EfiOpenFileByDevicePath is additionally not available in UDK.
|
|
|
|
See more details at:
|
|
https://github.com/tianocore/edk2/commit/768b611136d0f2b99a99e446c089d1a30c3fa5d5
|
|
|
|
@param[in,out] FilePath Device path protocol.
|
|
@param[out] File Resulting file protocol.
|
|
@param[in] OpenMode File open mode.
|
|
@param[in] Attributes File attributes.
|
|
|
|
@retval EFI_SUCCESS on succesful open.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OcOpenFileByDevicePath (
|
|
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
|
|
OUT EFI_FILE_PROTOCOL **File,
|
|
IN UINT64 OpenMode,
|
|
IN UINT64 Attributes
|
|
);
|
|
|
|
/**
|
|
Retrieve the disk's device handle from a partition's Device Path.
|
|
|
|
@param[in] HdDevicePath The Device Path of the partition.
|
|
|
|
@retval device handle or NULL
|
|
**/
|
|
EFI_HANDLE
|
|
OcPartitionGetDiskHandle (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *HdDevicePath
|
|
);
|
|
|
|
/**
|
|
Locate the disk's EFI System Partition.
|
|
|
|
@param[in] DiskDevicePath The Device Path of the disk to scan.
|
|
@param[out] EspDevicePathSize The size of the returned Device Path.
|
|
@param[out] EspDeviceHandle Device handle of the returned partition.
|
|
|
|
@return The device path protocol from the discovered handle or NULL.
|
|
**/
|
|
EFI_DEVICE_PATH_PROTOCOL *
|
|
OcDiskFindSystemPartitionPath (
|
|
IN CONST EFI_DEVICE_PATH_PROTOCOL *DiskDevicePath,
|
|
OUT UINTN *EspDevicePathSize,
|
|
OUT EFI_HANDLE *EspDeviceHandle
|
|
);
|
|
|
|
/**
|
|
Disk I/O context.
|
|
**/
|
|
typedef struct {
|
|
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
|
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
|
|
UINT32 MediaId;
|
|
UINT32 BlockSize;
|
|
} OC_DISK_CONTEXT;
|
|
|
|
/**
|
|
Initialize disk I/O context.
|
|
|
|
@param[out] Context Disk I/O context to intialize.
|
|
@param[in] DiskHandle Disk handle with protocols.
|
|
@param[in] UseBlockIo2 Try to use BlockIo2 protocol if available.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcDiskInitializeContext (
|
|
OUT OC_DISK_CONTEXT *Context,
|
|
IN EFI_HANDLE DiskHandle,
|
|
IN BOOLEAN UseBlockIo2
|
|
);
|
|
|
|
/**
|
|
Read information from disk.
|
|
|
|
@param[in] Context Disk I/O context.
|
|
@param[in] Lba LBA number to read from.
|
|
@param[in] BufferSize Buffer size allocated in Buffer.
|
|
@param[out] Buffer Buffer to store data in.
|
|
|
|
@retval EFI_SUCCESS on success.
|
|
**/
|
|
EFI_STATUS
|
|
OcDiskRead (
|
|
IN OC_DISK_CONTEXT *Context,
|
|
IN UINT64 Lba,
|
|
IN UINTN BufferSize,
|
|
OUT VOID *Buffer
|
|
);
|
|
|
|
/**
|
|
OC partition list.
|
|
**/
|
|
typedef struct {
|
|
UINT32 NumPartitions;
|
|
UINT32 PartitionEntrySize;
|
|
EFI_PARTITION_ENTRY FirstEntry[];
|
|
} OC_PARTITION_ENTRIES;
|
|
|
|
/**
|
|
Retrieve the disk GPT partitions, if applicable.
|
|
|
|
@param[in] DiskHandle Disk device handle to retrive partition table from.
|
|
@param[in] UseBlockIo2 Use 2nd revision of Block I/O if available.
|
|
|
|
@retval partition entry list or NULL.
|
|
**/
|
|
CONST OC_PARTITION_ENTRIES *
|
|
OcGetDiskPartitions (
|
|
IN EFI_HANDLE DiskHandle,
|
|
IN BOOLEAN UseBlockIo2
|
|
);
|
|
|
|
/**
|
|
Retrieve the partition's GPT information, if applicable.
|
|
Calls to this function undergo internal lazy caching.
|
|
|
|
@param[in] FsHandle The device handle of the partition to retrieve info of.
|
|
|
|
@retval partition entry or NULL
|
|
**/
|
|
CONST EFI_PARTITION_ENTRY *
|
|
OcGetGptPartitionEntry (
|
|
IN EFI_HANDLE FsHandle
|
|
);
|
|
|
|
/**
|
|
Creates a device path for a firmware file.
|
|
|
|
@param[in] FileGuid Firmware file GUID.
|
|
|
|
@retval device path allocated from pool on success.
|
|
@retval NULL on failure (e.g. when a file is not present).
|
|
**/
|
|
EFI_DEVICE_PATH_PROTOCOL *
|
|
OcCreateFvFileDevicePath (
|
|
IN EFI_GUID *FileGuid
|
|
);
|
|
|
|
/**
|
|
Reads firmware file section to pool-allocated buffer.
|
|
|
|
@param[in] FileGuid Firmware file GUID.
|
|
@param[in] SectionType Section type to read.
|
|
@param[out] FileSize Size of the section read.
|
|
|
|
@return file contents allocated from pool.
|
|
@retval NULL on failure (e.g. when a file is not present).
|
|
**/
|
|
VOID *
|
|
OcReadFvFileSection (
|
|
IN EFI_GUID *FileGuid,
|
|
IN UINT8 SectionType,
|
|
OUT UINT32 *FileSize
|
|
);
|
|
|
|
#endif // OC_FILE_LIB_H
|