int fsw_posix_unmount(struct fsw_posix_volume *pvol) { if (pvol->vol != NULL) fsw_unmount(pvol->vol); fsw_free(pvol); return 0; }
EFI_STATUS EFIAPI fsw_efi_DriverBinding_Start(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath) { EFI_STATUS Status; EFI_BLOCK_IO *BlockIo; EFI_DISK_IO *DiskIo; FSW_VOLUME_DATA *Volume; VBoxLogFlowFuncEnter(); // open consumed protocols Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(BlockIoProtocol), (VOID **) &BlockIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); // NOTE: we only want to look at the MediaId if (EFI_ERROR(Status)) { VBoxLogFlowFuncLeaveRC(Status); return Status; } Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(DiskIoProtocol), (VOID **) &DiskIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { VBoxLogFlowFuncLeaveRC(Status); return Status; } // allocate volume structure Volume = AllocateZeroPool(sizeof(FSW_VOLUME_DATA)); Status = fsw_efi_ReMount(Volume, ControllerHandle, DiskIo, BlockIo); // on errors, close the opened protocols if (EFI_ERROR(Status)) { if (Volume->vol != NULL) fsw_unmount(Volume->vol); FreePool(Volume); #if 0 if (Status == EFI_MEDIA_CHANGED) Status = fsw_efi_ReMount(Volume, ControllerHandle, DiskIo, BlockIo); else #endif BS->CloseProtocol(ControllerHandle, &PROTO_NAME(DiskIoProtocol), This->DriverBindingHandle, ControllerHandle); } VBoxLogFlowFuncLeaveRC(Status); return Status; }
EFI_STATUS EFIAPI fsw_efi_DriverBinding_Stop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer) { EFI_STATUS Status; EFI_FILE_IO_INTERFACE *FileSystem; FSW_VOLUME_DATA *Volume; #if DEBUG_LEVEL // Print(L"fsw_efi_DriverBinding_Stop\n"); #endif // get the installed SimpleFileSystem interface Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(SimpleFileSystemProtocol), (VOID **) &FileSystem, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) return EFI_UNSUPPORTED; // get private data structure Volume = FSW_VOLUME_FROM_FILE_SYSTEM(FileSystem); // uninstall Simple File System protocol Status = BS->UninstallMultipleProtocolInterfaces(ControllerHandle, &PROTO_NAME(SimpleFileSystemProtocol), &Volume->FileSystem, NULL); if (EFI_ERROR(Status)) { // Print(L"Fsw ERROR: UninstallMultipleProtocolInterfaces returned %x\n", Status); return Status; } #if DEBUG_LEVEL // Print(L"fsw_efi_DriverBinding_Stop: protocol uninstalled successfully\n"); #endif // release private data structure if (Volume->vol != NULL) fsw_unmount(Volume->vol); FreePool(Volume); Status = BS->CloseProtocol(ControllerHandle, &PROTO_NAME(DiskIo2Protocol), This->DriverBindingHandle, ControllerHandle); // close the consumed protocols Status = BS->CloseProtocol(ControllerHandle, &PROTO_NAME(DiskIoProtocol), This->DriverBindingHandle, ControllerHandle); return Status; }
VOID fsw_efi_DetachVolume(IN FSW_VOLUME_DATA *pVolume) { // uninstall Simple File System protocol BS->UninstallMultipleProtocolInterfaces(pVolume->Handle, &PROTO_NAME(SimpleFileSystemProtocol), &pVolume->FileSystem, NULL); // release private data structure if (pVolume->vol != NULL) fsw_unmount(pVolume->vol); FreePool(pVolume); }
fsw_status_t fsw_mount(void *host_data, struct fsw_host_table *host_table, struct fsw_fstype_table *fstype_table, struct fsw_volume **vol_out) { fsw_status_t status; struct fsw_volume *vol; // allocate memory for the structure status = fsw_alloc_zero(fstype_table->volume_struct_size, (void **)&vol); if (status) return status; // initialize fields vol->phys_blocksize = 512; vol->log_blocksize = 512; vol->label.type = FSW_STRING_TYPE_EMPTY; vol->host_data = host_data; vol->host_table = host_table; vol->fstype_table = fstype_table; vol->host_string_type = host_table->native_string_type; // let the fs driver mount the file system status = vol->fstype_table->volume_mount(vol); if (status) goto errorexit; /// @todo anything else? *vol_out = vol; return FSW_SUCCESS; errorexit: fsw_unmount(vol); return status; }
EFI_STATUS EFIAPI fsw_efi_DriverBinding_Start(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath) { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_BLOCK_IO2_PROTOCOL *BlockIo2; EFI_DISK_IO_PROTOCOL *DiskIo; EFI_DISK_IO2_PROTOCOL *DiskIo2; FSW_VOLUME_DATA *Volume; #if DEBUG_LEVEL // Print(L"fsw_efi_DriverBinding_Start\n"); #endif // open consumed protocols Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(BlockIo2Protocol), (VOID **) &BlockIo2, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { BlockIo2 = NULL; } Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(BlockIoProtocol), (VOID **) &BlockIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); // NOTE: we only want to look at the MediaId if ((BlockIo2 == NULL) && EFI_ERROR(Status)) { // Print(L"Fsw ERROR: OpenProtocol(BlockIo) returned %x\n", Status); return Status; } Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(DiskIo2Protocol), (VOID **) &DiskIo2, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { DiskIo2 = NULL; } Status = BS->OpenProtocol(ControllerHandle, &PROTO_NAME(DiskIoProtocol), (VOID **) &DiskIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if ((DiskIo2 == NULL) && EFI_ERROR(Status)) { // DBG("Fsw ERROR: OpenProtocol(DiskIo) returned %r\n", Status); return Status; } // allocate volume structure Volume = AllocateZeroPool(sizeof(FSW_VOLUME_DATA)); Volume->Signature = FSW_VOLUME_DATA_SIGNATURE; Volume->Handle = ControllerHandle; Volume->DiskIo = DiskIo; Volume->DiskIo2 = DiskIo2; Volume->LastIOStatus = EFI_SUCCESS; if (BlockIo2 != NULL) { Volume->MediaId = BlockIo2->Media->MediaId; } else { Volume->MediaId = BlockIo->Media->MediaId; } // mount the filesystem Status = fsw_efi_map_status(fsw_mount(Volume, &fsw_efi_host_table, &FSW_FSTYPE_TABLE_NAME(FSTYPE), &Volume->vol), Volume); if (!EFI_ERROR(Status)) { // register the SimpleFileSystem protocol Volume->FileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; Volume->FileSystem.OpenVolume = fsw_efi_FileSystem_OpenVolume; Status = BS->InstallMultipleProtocolInterfaces( &ControllerHandle, &PROTO_NAME(SimpleFileSystemProtocol), &Volume->FileSystem, NULL); if (EFI_ERROR(Status)) { // Print(L"Fsw ERROR: InstallMultipleProtocolInterfaces returned %x\n", Status); } } // on errors, close the opened protocols if (EFI_ERROR(Status)) { if (Volume->vol != NULL) fsw_unmount(Volume->vol); FreePool(Volume); BS->CloseProtocol(ControllerHandle, &PROTO_NAME(DiskIo2Protocol), This->DriverBindingHandle, ControllerHandle); BS->CloseProtocol(ControllerHandle, &PROTO_NAME(DiskIoProtocol), This->DriverBindingHandle, ControllerHandle); } return Status; }
static void free_dummy_volume(struct fsw_volume *vol) { fsw_free(vol->host_data); fsw_unmount(vol); }