static EFI_STATUS fsw_efi_ReMount(IN FSW_VOLUME_DATA *pVolume, IN EFI_HANDLE ControllerHandle, EFI_DISK_IO *pDiskIo, EFI_BLOCK_IO *pBlockIo) { EFI_STATUS Status; VBoxLogFlowFuncEnter(); pVolume->Signature = FSW_VOLUME_DATA_SIGNATURE; pVolume->Handle = ControllerHandle; pVolume->DiskIo = pDiskIo; pVolume->MediaId = pBlockIo->Media->MediaId; pVolume->LastIOStatus = EFI_SUCCESS; // mount the filesystem Status = fsw_efi_map_status(fsw_mount(pVolume, &fsw_efi_host_table, &FSW_FSTYPE_TABLE_NAME(FSTYPE), &pVolume->vol), pVolume); VBoxLogFlowFuncMarkRC(Status); if (!EFI_ERROR(Status)) { // register the SimpleFileSystem protocol pVolume->FileSystem.Revision = EFI_FILE_IO_INTERFACE_REVISION; pVolume->FileSystem.OpenVolume = fsw_efi_FileSystem_OpenVolume; Status = BS->InstallMultipleProtocolInterfaces(&ControllerHandle, &PROTO_NAME(SimpleFileSystemProtocol), &pVolume->FileSystem, NULL); if (EFI_ERROR(Status)) Print(L"Fsw ERROR: InstallMultipleProtocolInterfaces returned %x\n", Status); } VBoxLogFlowFuncLeaveRC(Status); return Status; }
struct fsw_posix_volume * fsw_posix_mount(const char *path, struct fsw_fstype_table *fstype_table) { fsw_status_t status; struct fsw_posix_volume *pvol; // allocate volume structure status = fsw_alloc_zero(sizeof(struct fsw_posix_volume), (void **)&pvol); if (status) return NULL; pvol->fd = -1; // open underlying file/device pvol->fd = open(path, O_RDONLY, 0); if (pvol->fd < 0) { fprintf(stderr, "fsw_posix_mount: %s: %s\n", path, strerror(errno)); fsw_free(pvol); return NULL; } // mount the filesystem if (fstype_table == NULL) fstype_table = &FSW_FSTYPE_TABLE_NAME(FSTYPE); status = fsw_mount(pvol, &fsw_posix_host_table, fstype_table, &pvol->vol); if (status) { fprintf(stderr, "fsw_posix_mount: fsw_mount returned %d\n", status); fsw_free(pvol); return NULL; } return pvol; }
EFI_STATUS fsw_efi_AttachVolume(IN EFI_HANDLE ControllerHandle, IN EFI_DISK_IO_PROTOCOL *pDiskIo, IN EFI_BLOCK_IO_PROTOCOL *pBlockIo) { EFI_STATUS Status; FSW_VOLUME_DATA *pVolume; pVolume = AllocateZeroPool(sizeof(FSW_VOLUME_DATA)); if (pVolume == NULL) { return EFI_OUT_OF_RESOURCES; } pVolume->Signature = FSW_VOLUME_DATA_SIGNATURE; pVolume->Handle = ControllerHandle; pVolume->DiskIo = pDiskIo; pVolume->MediaId = pBlockIo->Media->MediaId; pVolume->FileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; pVolume->FileSystem.OpenVolume = fsw_efi_FileSystem_OpenVolume; pVolume->LastIOStatus = EFI_SUCCESS; Status = fsw_efi_map_status(fsw_mount(pVolume, &fsw_efi_host_table, &FSW_FSTYPE_TABLE_NAME(FSTYPE), &pVolume->vol), pVolume); if (EFI_ERROR(Status)) { goto Done; } Status = BS->InstallMultipleProtocolInterfaces( &pVolume->Handle, &PROTO_NAME(SimpleFileSystemProtocol), &pVolume->FileSystem, NULL); if (EFI_ERROR(Status)) { goto Done; } DEBUG((EFI_D_INIT, "fsw_efi: Installed volume on %p\n", ControllerHandle)); Done: if (EFI_ERROR(Status)) { fsw_efi_DetachVolume(pVolume); } 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; }