NTSTATUS VioCryptDeviceD0Entry(IN WDFDEVICE Device, IN WDF_POWER_DEVICE_STATE PreviousState) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_CONTEXT context = GetDeviceContext(Device); VIRTIO_WDF_QUEUE_PARAM param; struct virtqueue *queues[1]; u64 u64HostFeatures, u64GuestFeatures = 0; Trace(TRACE_LEVEL_VERBOSE, "[%s] from D%d", __FUNCTION__, PreviousState - WdfPowerDeviceD0); PAGED_CODE(); u64HostFeatures = VirtIOWdfGetDeviceFeatures(&context->VDevice); if (virtio_is_feature_enabled(u64HostFeatures, VIRTIO_F_VERSION_1)) { virtio_feature_enable(u64GuestFeatures, VIRTIO_F_VERSION_1); } if (virtio_is_feature_enabled(u64HostFeatures, VIRTIO_F_ANY_LAYOUT)) { virtio_feature_enable(u64GuestFeatures, VIRTIO_F_ANY_LAYOUT); } status = VirtIOWdfSetDriverFeatures(&context->VDevice, u64GuestFeatures); if (NT_SUCCESS(status)) { param.Interrupt = context->WdfInterrupt; status = VirtIOWdfInitQueues(&context->VDevice, 1, queues, ¶m); } if (NT_SUCCESS(status)) { context->ControlQueue = queues[0]; VirtIOWdfSetDriverOK(&context->VDevice); } else { VirtIOWdfSetDriverFailed(&context->VDevice); Trace(TRACE_LEVEL_ERROR, "[%s] VirtIOWdfInitQueues failed with %x\n", __FUNCTION__, status); } return status; }
NTSTATUS virtio_set_features(VirtIODevice *vdev, u64 features) { unsigned char dev_status; NTSTATUS status = vdev->device->set_features(vdev, features); if (!NT_SUCCESS(status)) { return status; } if (!virtio_is_feature_enabled(features, VIRTIO_F_VERSION_1)) { return status; } virtio_add_status(vdev, VIRTIO_CONFIG_S_FEATURES_OK); dev_status = vdev->device->get_status(vdev); if (!(dev_status & VIRTIO_CONFIG_S_FEATURES_OK)) { DPrintf(0, ("virtio: device refuses features: %x\n", dev_status)); status = STATUS_INVALID_PARAMETER; } return status; }