| /** @file | |
| UDF/ECMA-167 file system driver. | |
| Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "Udf.h" | |
| // | |
| // UDF filesystem driver's Global Variables. | |
| // | |
| EFI_DRIVER_BINDING_PROTOCOL gUdfDriverBinding = { | |
| UdfDriverBindingSupported, | |
| UdfDriverBindingStart, | |
| UdfDriverBindingStop, | |
| 0x10, | |
| NULL, | |
| NULL | |
| }; | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gUdfSimpleFsTemplate = { | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, | |
| UdfOpenVolume | |
| }; | |
| /** | |
| Test to see if this driver supports ControllerHandle. Any ControllerHandle | |
| than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be | |
| supported. | |
| @param[in] This Protocol instance pointer. | |
| @param[in] ControllerHandle Handle of device to test. | |
| @param[in] RemainingDevicePath Optional parameter use to pick a specific | |
| child device to start. | |
| @retval EFI_SUCCESS This driver supports this device. | |
| @retval EFI_ALREADY_STARTED This driver is already running on this device. | |
| @retval other This driver does not support this device. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| UdfDriverBindingSupported ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_DISK_IO_PROTOCOL *DiskIo; | |
| // | |
| // Open DiskIo protocol on ControllerHandle | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiDiskIoProtocolGuid, | |
| (VOID **)&DiskIo, | |
| This->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_BY_DRIVER | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Close DiskIo protocol on ControllerHandle | |
| // | |
| gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiDiskIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| ControllerHandle | |
| ); | |
| // | |
| // Test whether ControllerHandle supports BlockIo protocol | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiBlockIoProtocolGuid, | |
| NULL, | |
| This->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_TEST_PROTOCOL | |
| ); | |
| return Status; | |
| } | |
| /** | |
| Start this driver on ControllerHandle by opening a Block IO or a Block IO2 | |
| or both, and Disk IO protocol, reading Device Path, and creating a child | |
| handle with a Disk IO and device path protocol. | |
| @param[in] This Protocol instance pointer. | |
| @param[in] ControllerHandle Handle of device to bind driver to | |
| @param[in] RemainingDevicePath Optional parameter use to pick a specific | |
| child device to start. | |
| @retval EFI_SUCCESS This driver is added to ControllerHandle. | |
| @retval EFI_ALREADY_STARTED This driver is already running on | |
| ControllerHandle. | |
| @retval other This driver does not support this device. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| UdfDriverBindingStart ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
| ) | |
| { | |
| EFI_TPL OldTpl; | |
| EFI_STATUS Status; | |
| EFI_BLOCK_IO_PROTOCOL *BlockIo; | |
| EFI_DISK_IO_PROTOCOL *DiskIo; | |
| PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; | |
| OldTpl = gBS->RaiseTPL (TPL_CALLBACK); | |
| // | |
| // Open BlockIo protocol on ControllerHandle | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiBlockIoProtocolGuid, | |
| (VOID **)&BlockIo, | |
| This->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Open DiskIo protocol on ControllerHandle | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiDiskIoProtocolGuid, | |
| (VOID **)&DiskIo, | |
| This->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_BY_DRIVER | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Check if ControllerHandle supports an UDF file system | |
| // | |
| Status = SupportUdfFileSystem (This, ControllerHandle); | |
| if (EFI_ERROR (Status)) { | |
| goto Exit; | |
| } | |
| // | |
| // Initialize private file system structure | |
| // | |
| PrivFsData = | |
| (PRIVATE_UDF_SIMPLE_FS_DATA *) | |
| AllocateZeroPool (sizeof (PRIVATE_UDF_SIMPLE_FS_DATA)); | |
| if (PrivFsData == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto Exit; | |
| } | |
| // | |
| // Create new child handle | |
| // | |
| PrivFsData->Signature = PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE; | |
| PrivFsData->BlockIo = BlockIo; | |
| PrivFsData->DiskIo = DiskIo; | |
| PrivFsData->Handle = ControllerHandle; | |
| // | |
| // Set up SimpleFs protocol | |
| // | |
| CopyMem ( | |
| (VOID *)&PrivFsData->SimpleFs, | |
| (VOID *)&gUdfSimpleFsTemplate, | |
| sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL) | |
| ); | |
| // | |
| // Install child handle | |
| // | |
| Status = gBS->InstallMultipleProtocolInterfaces ( | |
| &PrivFsData->Handle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| &PrivFsData->SimpleFs, | |
| NULL | |
| ); | |
| Exit: | |
| if (EFI_ERROR (Status)) { | |
| // | |
| // Close DiskIo protocol on ControllerHandle | |
| // | |
| gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiDiskIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| ControllerHandle | |
| ); | |
| // | |
| // Close BlockIo protocol on ControllerHandle | |
| // | |
| gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiBlockIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| ControllerHandle | |
| ); | |
| } | |
| gBS->RestoreTPL (OldTpl); | |
| return Status; | |
| } | |
| /** | |
| Stop this driver on ControllerHandle. Support stopping any child handles | |
| created by this driver. | |
| @param This Protocol instance pointer. | |
| @param ControllerHandle Handle of device to stop driver on | |
| @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of | |
| children is zero stop the entire bus driver. | |
| @param ChildHandleBuffer List of Child Handles to Stop. | |
| @retval EFI_SUCCESS This driver is removed ControllerHandle | |
| @retval other This driver was not removed from this device | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| UdfDriverBindingStop ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN UINTN NumberOfChildren, | |
| IN EFI_HANDLE *ChildHandleBuffer | |
| ) | |
| { | |
| PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; | |
| EFI_STATUS Status; | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs; | |
| // | |
| // Open SimpleFs protocol on ControllerHandle | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| (VOID **)&SimpleFs, | |
| This->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (SimpleFs); | |
| // | |
| // Uninstall child handle | |
| // | |
| Status = gBS->UninstallMultipleProtocolInterfaces ( | |
| PrivFsData->Handle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| &PrivFsData->SimpleFs, | |
| NULL | |
| ); | |
| FreePool ((VOID *)PrivFsData); | |
| } | |
| if (!EFI_ERROR (Status)) { | |
| // | |
| // Close DiskIo protocol on ControllerHandle | |
| // | |
| gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiDiskIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| ControllerHandle | |
| ); | |
| // | |
| // Close BlockIo protocol on ControllerHandle | |
| // | |
| gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiBlockIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| ControllerHandle | |
| ); | |
| } | |
| return Status; | |
| } | |
| /** | |
| The user Entry Point for UDF file system driver. The user code starts with | |
| this function. | |
| @param[in] ImageHandle The firmware allocated handle for the EFI image. | |
| @param[in] SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The entry point is executed successfully. | |
| @retval other Some error occurs when executing this entry point. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| InitializeUdf ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = EfiLibInstallDriverBindingComponentName2 ( | |
| ImageHandle, | |
| SystemTable, | |
| &gUdfDriverBinding, | |
| ImageHandle, | |
| &gUdfComponentName, | |
| &gUdfComponentName2 | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| return Status; | |
| } |