static EFI_STATUS EFIAPI FSBindingStop(EFI_DRIVER_BINDING_PROTOCOL *This, EFI_HANDLE ControllerHandle, UINTN NumberOfChildren, EFI_HANDLE *ChildHandleBuffer) { EFI_STATUS Status; EFI_FS *Instance; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileIoInterface; PrintDebug(L"FSBindingStop\n"); /* Get a pointer back to our FS instance through its installed protocol */ Status = BS->OpenProtocol(ControllerHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &FileIoInterface, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not locate our instance"); return Status; } Instance = _CR(FileIoInterface, EFI_FS, FileIoInterface); FSUninstall(Instance, ControllerHandle); Status = GrubDeviceExit(Instance); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not destroy grub device"); } BS->CloseProtocol(ControllerHandle, &gEfiDiskIo2ProtocolGuid, This->DriverBindingHandle, ControllerHandle); BS->CloseProtocol(ControllerHandle, &gEfiDiskIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); FreeFsInstance(Instance); return EFI_SUCCESS; }
static EFI_STATUS EFIAPI FSBindingStart(EFI_DRIVER_BINDING_PROTOCOL *This, EFI_HANDLE ControllerHandle, EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath) { EFI_STATUS Status; EFI_FS *Instance; EFI_DEVICE_PATH *DevicePath; PrintDebug(L"FSBindingStart\n"); /* Allocate a new instance of a filesystem */ Instance = AllocateZeroPool(sizeof(EFI_FS)); if (Instance == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate a new file system instance"); return Status; } Instance->FileIoInterface.Revision = EFI_FILE_IO_INTERFACE_REVISION; Instance->FileIoInterface.OpenVolume = FileOpenVolume, /* Fill the device path for our instance */ DevicePath = DevicePathFromHandle(ControllerHandle); if (DevicePath == NULL) { Status = EFI_NO_MAPPING; PrintStatusError(Status, L"Could not get Device Path"); goto error; } Instance->DevicePathString = DevicePathToStr(DevicePath); if (Instance->DevicePathString == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate Device Path string"); goto error; } /* Get access to the Block IO protocol for this controller */ Status = BS->OpenProtocol(ControllerHandle, &BlockIoProtocol, (VOID **) &Instance->BlockIo, This->DriverBindingHandle, ControllerHandle, /* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29 * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely * because the disk driver has that protocol already open. So we use * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it) */ EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access BlockIO protocol"); goto error; } /* Get exclusive access to the Disk IO protocol */ Status = BS->OpenProtocol(ControllerHandle, &DiskIoProtocol, (VOID**) &Instance->DiskIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access the DiskIo protocol"); goto error; } /* Go through GRUB target init */ Status = GrubDeviceInit(Instance); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not init grub device"); goto error; } Status = FSInstall(Instance, ControllerHandle); /* Unless we close the DiskIO protocol in case of error, no other * FS driver will be able to access this partition. */ if (EFI_ERROR(Status)) { GrubDeviceExit(Instance); BS->CloseProtocol(ControllerHandle, &DiskIoProtocol, This->DriverBindingHandle, ControllerHandle); } error: if (EFI_ERROR(Status)) FreeFsInstance(Instance); return Status; }