diff --git a/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs b/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs index 54b8ca8e..6b0476ec 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs @@ -375,3 +375,30 @@ pub unsafe extern "C" fn device_io_control( // SAFETY: `request` is the framework-provided WDFREQUEST; `control::dispatch` completes it exactly once. unsafe { crate::control::dispatch(request, ioctl_code) }; } + +/// DDC/CI transmit toward the virtual monitor — refuse INSTANTLY (stall-immunity: DDC fail-fast). +/// +/// In exclusive topology the virtual display is the ONLY monitor on the desktop, so +/// monitor-control software (the Twinkle Tray / PowerToys PowerDisplay / Monitorian class) aims +/// its entire DDC traffic — brightness polls, capabilities-string requests — at THIS monitor. +/// There is no bus and no sink here; the only wrong answer is a slow one (a timeout-shaped +/// failure occupies win32k's physical-monitor path, serialized per monitor, for its full +/// duration). Registering the pair pins every probe's cost to one immediate +/// `STATUS_NOT_SUPPORTED`. EDID needs no equivalent: the OS serves descriptor queries from the +/// blob supplied at monitor creation without calling the driver. +pub unsafe extern "C" fn monitor_i2c_transmit( + _monitor: iddcx::IDDCX_MONITOR, + _p_in: *const iddcx::IDARG_IN_I2C_TRANSMIT, +) -> NTSTATUS { + crate::STATUS_NOT_SUPPORTED +} + +/// DDC/CI receive from the virtual monitor — same contract as [`monitor_i2c_transmit`]. (The +/// receive DDI has no out-arg at the callback — data would flow back through an async completion; +/// a synchronous failure return refuses the whole transaction, which is exactly the point.) +pub unsafe extern "C" fn monitor_i2c_receive( + _monitor: iddcx::IDDCX_MONITOR, + _p_in: *const iddcx::IDARG_IN_I2C_RECEIVE, +) -> NTSTATUS { + crate::STATUS_NOT_SUPPORTED +} diff --git a/packaging/windows/drivers/pf-vdisplay/src/entry.rs b/packaging/windows/drivers/pf-vdisplay/src/entry.rs index 846c8a93..dd1e51e3 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/entry.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/entry.rs @@ -89,6 +89,11 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA cfg.EvtIddCxMonitorSetGammaRamp = Some(callbacks::set_gamma_ramp); cfg.EvtIddCxMonitorAssignSwapChain = Some(callbacks::assign_swap_chain); cfg.EvtIddCxMonitorUnassignSwapChain = Some(callbacks::unassign_swap_chain); + // DDC fail-fast (stall-immunity): monitor-control software polls the virtual monitor's DDC — + // in exclusive topology it is the ONLY monitor. These answer every probe with an immediate + // STATUS_NOT_SUPPORTED instead of whatever slow path an unregistered interface takes. + cfg.EvtIddCxMonitorI2CTransmit = Some(callbacks::monitor_i2c_transmit); + cfg.EvtIddCxMonitorI2CReceive = Some(callbacks::monitor_i2c_receive); cfg.EvtIddCxDeviceIoControl = Some(callbacks::device_io_control); // SAFETY: init is the framework device-init; cfg is fully populated + sized. (Links IddCxStub.) diff --git a/packaging/windows/drivers/pf-vdisplay/src/lib.rs b/packaging/windows/drivers/pf-vdisplay/src/lib.rs index 38f2aefe..b92fead1 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/lib.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/lib.rs @@ -35,6 +35,7 @@ use wdk_sys::NTSTATUS; // NTSTATUS codes the driver returns (wdk-sys doesn't surface all of these as constants). pub(crate) const STATUS_SUCCESS: NTSTATUS = 0; pub(crate) const STATUS_NOT_IMPLEMENTED: NTSTATUS = 0xC000_0002u32 as NTSTATUS; +pub(crate) const STATUS_NOT_SUPPORTED: NTSTATUS = 0xC000_00BBu32 as NTSTATUS; pub(crate) const STATUS_NOT_FOUND: NTSTATUS = 0xC000_0225u32 as NTSTATUS; pub(crate) const STATUS_INVALID_PARAMETER: NTSTATUS = 0xC000_000Du32 as NTSTATUS; pub(crate) const STATUS_BUFFER_TOO_SMALL: NTSTATUS = 0xC000_0023u32 as NTSTATUS;