mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-29 12:35:53 +01:00
133 lines
3.6 KiB
C
133 lines
3.6 KiB
C
/** @file
|
|
Driver entry point
|
|
|
|
Copyright (c) 2021 Pedro Falcato All rights reserved.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
|
|
#include "Ext4Dxe.h"
|
|
|
|
/**
|
|
Opens an ext4 partition and installs the Simple File System protocol.
|
|
|
|
@param[in] DeviceHandle Handle to the block device.
|
|
@param[in] DiskIo Pointer to an EFI_DISK_IO_PROTOCOL.
|
|
@param[in opt] DiskIo2 Pointer to an EFI_DISK_IO2_PROTOCOL, if supported.
|
|
@param[in] BlockIo Pointer to an EFI_BLOCK_IO_PROTOCOL.
|
|
|
|
@retval EFI_SUCCESS The opening was successful.
|
|
!EFI_SUCCESS Opening failed.
|
|
**/
|
|
EFI_STATUS
|
|
Ext4OpenPartition (
|
|
IN EFI_HANDLE DeviceHandle,
|
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
|
IN OPTIONAL EFI_DISK_IO2_PROTOCOL *DiskIo2,
|
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo
|
|
)
|
|
{
|
|
EXT4_PARTITION *Part;
|
|
EFI_STATUS Status;
|
|
|
|
Part = AllocateZeroPool (sizeof (*Part));
|
|
|
|
if (Part == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
InitializeListHead (&Part->OpenFiles);
|
|
|
|
Part->BlockIo = BlockIo;
|
|
Part->DiskIo = DiskIo;
|
|
Part->DiskIo2 = DiskIo2;
|
|
|
|
Status = Ext4OpenSuperblock (Part);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (Part);
|
|
return Status;
|
|
}
|
|
|
|
Part->Interface.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
|
|
Part->Interface.OpenVolume = Ext4OpenVolume;
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&DeviceHandle,
|
|
&gEfiSimpleFileSystemProtocolGuid,
|
|
&Part->Interface,
|
|
NULL
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (Part);
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Sets up the protocol and metadata of a file that is being opened.
|
|
|
|
@param[in out] File Pointer to the file.
|
|
@param[in] Partition Pointer to the opened partition.
|
|
**/
|
|
VOID
|
|
Ext4SetupFile (
|
|
IN OUT EXT4_FILE *File,
|
|
IN EXT4_PARTITION *Partition
|
|
)
|
|
{
|
|
// Note: We don't yet support revision 2 of the file protocol
|
|
// (needs DISK_IO2 + asynchronous IO)
|
|
File->Protocol.Revision = EFI_FILE_PROTOCOL_REVISION;
|
|
File->Protocol.Open = Ext4Open;
|
|
File->Protocol.Close = Ext4Close;
|
|
File->Protocol.Delete = Ext4Delete;
|
|
File->Protocol.Read = Ext4ReadFile;
|
|
File->Protocol.Write = Ext4WriteFile;
|
|
File->Protocol.SetPosition = Ext4SetPosition;
|
|
File->Protocol.GetPosition = Ext4GetPosition;
|
|
File->Protocol.GetInfo = Ext4GetInfo;
|
|
File->Protocol.SetInfo = Ext4SetInfo;
|
|
|
|
File->Partition = Partition;
|
|
}
|
|
|
|
/**
|
|
Unmounts and frees an ext4 partition.
|
|
|
|
@param[in] Partition Pointer to the opened partition.
|
|
|
|
@retval Status of the unmount.
|
|
**/
|
|
EFI_STATUS
|
|
Ext4UnmountAndFreePartition (
|
|
IN EXT4_PARTITION *Partition
|
|
)
|
|
{
|
|
LIST_ENTRY *Entry;
|
|
LIST_ENTRY *NextEntry;
|
|
EXT4_FILE *File;
|
|
BOOLEAN DeletedRootDentry;
|
|
|
|
Partition->Unmounting = TRUE;
|
|
Ext4CloseInternal (Partition->Root);
|
|
|
|
BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Partition->OpenFiles) {
|
|
File = EXT4_FILE_FROM_OPEN_FILES_NODE (Entry);
|
|
|
|
Ext4CloseInternal (File);
|
|
}
|
|
|
|
DeletedRootDentry = Ext4UnrefDentry (Partition->RootDentry);
|
|
|
|
if (!DeletedRootDentry) {
|
|
DEBUG ((DEBUG_ERROR, "[ext4] Failed to delete root dentry - resource leak present.\n"));
|
|
}
|
|
|
|
FreePool (Partition->BlockGroups);
|
|
FreePool (Partition);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|