/** @file
ExtLib APIs
Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include "Ext2Fs.h"
/**
Initialize the EXT2/3 FileSystem API structure.
@param SwPart The partition number of EXT2/3 FileSystem located
@param PartHandle The Partition handle
@param FsHandle The EXT2/3 FILE system handle
@retval EFI_INVALID_PARAMETER The Partition handle is not for EXT2/3, or
partition number exceeds the maxium number in Partition handle
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resource
**/
EFI_STATUS
EFIAPI
ExtInitFileSystem (
IN UINT32 SwPart,
IN EFI_HANDLE PartHandle,
OUT EFI_HANDLE *FsHandle
)
{
PEI_EXT_PRIVATE_DATA *PrivateData;
PART_BLOCK_DEVICE *PartBlockDev;
EFI_STATUS Status;
// Valid parameters
PartBlockDev = (PART_BLOCK_DEVICE *)PartHandle;
if ((FsHandle == NULL) || (PartBlockDev == NULL) || \
(PartBlockDev->Signature != PART_INFO_SIGNATURE)) {
return EFI_INVALID_PARAMETER;
}
if (SwPart >= PartBlockDev->BlockDeviceCount) {
return EFI_INVALID_PARAMETER;
}
PrivateData = (PEI_EXT_PRIVATE_DATA *)AllocateZeroPool (sizeof (PEI_EXT_PRIVATE_DATA));
if (PrivateData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
PrivateData->Signature = FS_EXT_SIGNATURE;
PrivateData->PhysicalDevNo = (UINT8)PartBlockDev->HarewareDevice;
PrivateData->StartBlock = PartBlockDev->BlockDevice[SwPart].StartBlock;
PrivateData->LastBlock = PartBlockDev->BlockDevice[SwPart].LastBlock;
PrivateData->BlockSize = PartBlockDev->BlockInfo.BlockSize;
// validate Ext2 superblock
Status = Ext2SbValidate ((EFI_HANDLE)PrivateData, NULL, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_VERBOSE, "No valid EXT superblock on StartBlock %d Part %d\n", PrivateData->StartBlock, SwPart));
goto Error;
}
DEBUG ((DEBUG_INFO, "Detected EXT on StartBlock %d Part %d\n", PrivateData->StartBlock, SwPart));
*FsHandle = (EFI_HANDLE)PrivateData;
return EFI_SUCCESS;
Error:
if (PrivateData != NULL) {
FreePool (PrivateData);
}
return Status;
}
/**
Clean-up allocated memory/etc. for EXT file system
@param[in] FsHandle EXT file system handle.
@retval none
**/
VOID
EFIAPI
ExtCloseFileSystem (
IN EFI_HANDLE FsHandle
)
{
PEI_EXT_PRIVATE_DATA *PrivateData;
PrivateData = NULL;
if (FsHandle != NULL) {
PrivateData = (PEI_EXT_PRIVATE_DATA *)FsHandle;
ASSERT (PrivateData->Signature == FS_EXT_SIGNATURE);
}
if (PrivateData != NULL && PrivateData->Signature == FS_EXT_SIGNATURE) {
FreePool (PrivateData);
}
}
/**
Open a file by its name and return its file handle.
@param[in] FsHandle file system handle.
@param[in] FileName The file name to get.
@param[out] FileHandle file handle
@retval EFI_SUCCESS The file opened correctly.
@retval EFI_INVALID_PARAMETER Parameter is not valid.
@retval EFI_DEVICE_ERROR A device error occurred.
@retval EFI_NOT_FOUND A requested file cannot be found.
@retval EFI_OUT_OF_RESOURCES Insufficant memory resource pool.
**/
EFI_STATUS
EFIAPI
ExtFsOpenFile (
IN EFI_HANDLE FsHandle,
IN CHAR16 *FileName,
OUT EFI_HANDLE *FileHandle
)
{
EFI_STATUS Status;
PEI_EXT_PRIVATE_DATA *PrivateData;
OPEN_FILE *OpenFile;
CHAR8 *NameBuffer;
UINTN NameSize;
PrivateData = (PEI_EXT_PRIVATE_DATA *)FsHandle;
if (PrivateData == NULL || PrivateData->Signature != FS_EXT_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
NameSize = StrSize (FileName);
NameBuffer = AllocatePool (NameSize);
Status = UnicodeStrToAsciiStrS (FileName, NameBuffer, NameSize);
if (EFI_ERROR(Status)) {
FreePool (NameBuffer);
return Status;
}
OpenFile = (OPEN_FILE *)AllocateZeroPool (sizeof (OPEN_FILE));
if (OpenFile == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Error;
}
OpenFile->FileDevData = PrivateData;
Status = Ext2fsOpen (NameBuffer, OpenFile);
if (EFI_ERROR (Status)) {
goto Error;
}
FreePool (NameBuffer);
*FileHandle = (EFI_HANDLE)OpenFile;
return EFI_SUCCESS;
Error:
if (NameBuffer != NULL) {
FreePool (NameBuffer);
}
if (OpenFile != NULL) {
FreePool (OpenFile);
}
return Status;
}
/**
Get file size by opened file handle.
@param[in] FileHandle file handle
@param[out] FileSize Pointer to file buffer size.
@retval EFI_SUCCESS The file was loaded correctly.
@retval EFI_INVALID_PARAMETER Parameter is not valid.
**/
EFI_STATUS
EFIAPI
ExtFsGetFileSize (
IN EFI_HANDLE FileHandle,
OUT UINTN *FileSize
)
{
OPEN_FILE *OpenFile;
OpenFile = (OPEN_FILE *)FileHandle;
ASSERT (OpenFile != NULL);
if (OpenFile == NULL) {
return EFI_INVALID_PARAMETER;
}
*FileSize = Ext2fsFileSize (OpenFile);
return EFI_SUCCESS;
}
/**
Read file into memory by opened file handle.
@param[in] FileHandle file handle
@param[out] FileBufferPtr Allocated file buffer pointer.
@param[out] FileSize Pointer to file buffer size.
@retval EFI_SUCCESS The file was loaded correctly.
@retval EFI_INVALID_PARAMETER Parameter is not valid.
@retval EFI_DEVICE_ERROR A device error occurred.
@retval EFI_NOT_FOUND A requested file cannot be found.
@retval EFI_OUT_OF_RESOURCES Insufficant memory resource pool.
@retval EFI_BUFFER_TOO_SMALL Buffer size is too small.
**/
EFI_STATUS
EFIAPI
ExtFsReadFile (
IN EFI_HANDLE FsHandle,
IN EFI_HANDLE FileHandle,
OUT VOID *FileBufferPtr,
OUT UINTN *FileSizePtr
)
{
OPEN_FILE *OpenFile;
VOID *FileBuffer;
UINT32 FileSize;
UINT32 Residual;
EFI_STATUS Status;
OpenFile = (OPEN_FILE *)FileHandle;
ASSERT (OpenFile != NULL);
if (OpenFile == NULL) {
return EFI_INVALID_PARAMETER;
}
FileSize = Ext2fsFileSize (OpenFile);
if (FileSize == 0) {
return EFI_SUCCESS;
}
ASSERT (FileBufferPtr != NULL);
if (FileBufferPtr == NULL) {
return EFI_INVALID_PARAMETER;
}
FileBuffer = FileBufferPtr;
Residual = 0;
Status = Ext2fsRead (OpenFile, FileBuffer, FileSize, &Residual);
if (EFI_ERROR (Status) || (Residual != 0)) {
return EFI_LOAD_ERROR;
} else {
*FileSizePtr = FileSize;
}
return EFI_SUCCESS;
}
/**
Close a file by opened file handle
@param[in] FileHandle file handle
@retval none
**/
VOID
EFIAPI
ExtFsCloseFile (
IN EFI_HANDLE FileHandle
)
{
OPEN_FILE *OpenFile;
OpenFile = (OPEN_FILE *)FileHandle;
if (OpenFile == NULL) {
return;
}
Ext2fsClose (OpenFile);
FreePool (OpenFile);
}
/**
List directories or files
@param[in] FsHandle file system handle.
@param[in] DirFilePath directory or file path
@param[in] ConsoleOutFunc redirect output message to a console
@retval EFI_SUCCESS list directories of files successfully
@retval EFI_UNSUPPORTED this api is not supported
@retval Others an error occurs
**/
EFI_STATUS
EFIAPI
ExtFsListDir (
IN EFI_HANDLE FsHandle,
IN CHAR16 *DirFilePath
)
{
EFI_STATUS Status;
EFI_HANDLE FileHandle;
Status = EFI_UNSUPPORTED;
DEBUG_CODE_BEGIN ();
FileHandle = NULL;
Status = ExtFsOpenFile (FsHandle, DirFilePath, &FileHandle);
if (!EFI_ERROR (Status)) {
Status = Ext2fsLs ((OPEN_FILE *)FileHandle, NULL);
}
if (FileHandle != NULL) {
ExtFsCloseFile (FileHandle);
}
DEBUG_CODE_END ();
return Status;
}