feat(windows-drivers): pf-vdisplay STEP 2 — IddCx device skeleton
apple / swift (push) Failing after 2s
apple / screenshots (push) Has been skipped
windows-drivers / probe-and-proto (push) Successful in 21s
windows-drivers / driver-build (push) Successful in 1m5s
windows-host / package (push) Successful in 5m16s
android / android (push) Successful in 3m40s
ci / web (push) Successful in 59s
ci / docs-site (push) Successful in 1m2s
ci / rust (push) Successful in 4m32s
deb / build-publish (push) Successful in 2m14s
decky / build-publish (push) Successful in 12s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 6s
ci / bench (push) Successful in 4m44s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m31s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m22s
docker / deploy-docs (push) Successful in 18s

DriverEntry -> driver_add builds the full IDD_CX_CLIENT_CONFIG (14 IddCx callbacks +
PnP EvtDeviceD0Entry, all stubs with correct PFN signatures) sized via the ported
IDD_STRUCTURE_SIZE! (size.rs), runs IddCxDeviceInitConfig -> WdfDeviceCreate ->
WdfDeviceCreateDeviceInterface(the owned pf-vdisplay GUID, not SudoVDA) ->
IddCxDeviceInitialize. callbacks.rs has all 14 + device_d0_entry; query_target_info
implements HIGH_COLOR_SPACE. edid.rs salvaged verbatim from the oracle. proto gains
interface_guid_fields() (u128 -> Windows GUID fields). Links IddCxStub (the CI gate);
adapter/monitor/swapchain/IDD-push fill the stubs in STEP 3-6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 16:12:20 +00:00
parent 788e4acbb5
commit 4f10f3439d
7 changed files with 480 additions and 65 deletions
@@ -1,70 +1,29 @@
//! pf-vdisplay — the all-Rust UMDF IddCx virtual-display driver (M1 step-2 rewrite, on wdk-sys + the
//! owned pf-vdisplay-proto ABI). See docs/windows-host-rewrite.md §14 for the full port plan.
//!
//! STEP 0 (this commit): the workspace scaffold + the std-under-UMDF LINK GATE. DriverEntry →
//! WdfDriverCreate → (EvtDeviceAdd) WdfDeviceCreate, plus a `#[used]` probe that forces `std::thread`
//! + `OwnedHandle` to link — the SwapChainProcessor (STEP 5) depends on both, and the wdk-build UMDF
//! link settings `/NODEFAULTLIB:kernel32.lib`, so std must resolve via OneCoreUAP. If this fails to
//! link, the worker-thread/handle design needs a CreateThread shim BEFORE any callback work (port-plan
//! critique gap #9). The adapter/monitor/swapchain/IDD-push logic lands in STEP 2-6.
//! STEP 2: the IddCx driver SKELETON — DriverEntry → driver_add builds the full `IDD_CX_CLIENT_CONFIG`
//! (14 IddCx callbacks + the PnP `EvtDeviceD0Entry`, all stubs) sized via the versioned
//! [`size::idd_cx_client_config_size`], runs `IddCxDeviceInitConfig` → `WdfDeviceCreate` →
//! `WdfDeviceCreateDeviceInterface`(the owned pf-vdisplay GUID) → `IddCxDeviceInitialize`, and exports
//! `IddMinimumVersionRequired`. This links `IddCxStub` (the CI gate). The real adapter init (STEP 3),
//! control plane + monitor/modes (STEP 4), and swap-chain/IDD-push (STEP 5-6) fill the stubs in.
#![allow(non_snake_case, clippy::missing_safety_doc)]
use wdk_sys::{
call_unsafe_wdf_function_binding, NTSTATUS, PCUNICODE_STRING, PDRIVER_OBJECT, PWDFDEVICE_INIT,
ULONG, WDFDEVICE, WDFDRIVER, WDF_DRIVER_CONFIG, WDF_NO_HANDLE, WDF_NO_OBJECT_ATTRIBUTES,
};
mod callbacks;
mod edid;
mod entry;
mod size;
const STATUS_SUCCESS: NTSTATUS = 0;
use wdk_sys::NTSTATUS;
/// STEP-0 link gate (port-plan critique #9). Forces `std::thread` + `std::os::windows::io::OwnedHandle`
/// to be linked into the UMDF cdylib so STEP 0's `cargo build` actually proves the std surface resolves
/// under the wdk-build link settings (kernel32 is `/NODEFAULTLIB`'d → std must come via OneCoreUAP).
/// Never called; `#[used]` keeps the symbol so the linker pulls std. Also touches `wdk-iddcx` to prove
/// the pf-vdisplay → wdk-iddcx → wdk-sys/iddcx dependency graph resolves.
fn _std_link_gate() {
use std::os::windows::io::OwnedHandle;
let t = std::thread::spawn(|| 0u32);
let _ = t.join();
let _drop_owned: fn(OwnedHandle) = core::mem::drop;
// touch the iddcx surface via wdk-iddcx (forces the feature-enabled dep graph)
let _adapter: Option<wdk_iddcx::iddcx::IDDCX_ADAPTER> = None;
}
#[used]
static _STD_LINK_GATE: fn() = _std_link_gate;
// 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_FOUND: NTSTATUS = 0xC000_0225u32 as NTSTATUS;
#[unsafe(export_name = "DriverEntry")]
pub unsafe extern "system" fn driver_entry(
driver: PDRIVER_OBJECT,
registry_path: PCUNICODE_STRING,
) -> NTSTATUS {
// SAFETY: zeroed then Size + the device-add callback set, per the WDF_DRIVER_CONFIG contract.
let mut config: WDF_DRIVER_CONFIG = unsafe { core::mem::zeroed() };
config.Size = core::mem::size_of::<WDF_DRIVER_CONFIG>() as ULONG;
config.EvtDriverDeviceAdd = Some(evt_device_add);
// SAFETY: driver + registry_path are loader-provided; config is valid for the call.
unsafe {
call_unsafe_wdf_function_binding!(
WdfDriverCreate,
driver,
registry_path,
WDF_NO_OBJECT_ATTRIBUTES,
&mut config,
WDF_NO_HANDLE.cast::<WDFDRIVER>()
)
}
}
extern "C" fn evt_device_add(_driver: WDFDRIVER, mut device_init: PWDFDEVICE_INIT) -> NTSTATUS {
let mut device: WDFDEVICE = core::ptr::null_mut();
// SAFETY: device_init is the framework-provided init; attributes null; device receives the handle.
let _ = unsafe {
call_unsafe_wdf_function_binding!(
WdfDeviceCreate,
&mut device_init,
WDF_NO_OBJECT_ATTRIBUTES,
&mut device
)
};
STATUS_SUCCESS
}
/// IddCx (stub mode) requires the driver to export the minimum IddCx framework version it needs — the
/// `#ifndef IDD_STUB` branch of `IddCxFuncEnum.h` that normally emits it is compiled out under
/// `IDD_STUB`. `4` matches the proven `wdf-umdf` oracle.
#[unsafe(no_mangle)]
pub static IddMinimumVersionRequired: wdk_sys::ULONG = 4;