feat(windows-drivers): STEP 3 on-glass — driver LOADS + runs full IddCx init chain
apple / swift (push) Failing after 2s
apple / screenshots (push) Has been skipped
windows-drivers / probe-and-proto (push) Successful in 19s
windows-drivers / driver-build (push) Successful in 1m7s
windows-host / package (push) Successful in 5m27s
android / android (push) Successful in 4m5s
ci / web (push) Successful in 47s
ci / rust (push) Successful in 4m41s
ci / docs-site (push) Successful in 57s
deb / build-publish (push) Successful in 2m26s
decky / build-publish (push) Successful in 13s
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 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 5s
ci / bench (push) Successful in 5m1s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 9m21s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 9m23s
docker / deploy-docs (push) Successful in 6s

Major on-glass progress on the RTX box. The all-Rust wdk-sys IddCx driver now LOADS
under Secure Boot and runs the ENTIRE init chain: DriverEntry -> WdfDriverCreate ->
driver_add -> IddCxDeviceInitConfig(0x0) -> WdfDeviceCreate -> CreateDeviceInterface
-> IddCxDeviceInitialize -> D0Entry -> init_adapter. Findings:
- Signing was a RED HERRING (the driver loads); std works in WUDFHost (DualSense uses
  it too).
- THE unblock: link the iddcx **1.10** IddCxStub (build.rs now picks the highest
  version-aware), not 1.0 — the 1.0 stub lacks the version-table symbols AND its
  dispatch table mismatched the 1.10 framework, which made IddCxDeviceInitConfig
  return INVALID_PARAMETER. With 1.10 the whole chain runs.
- Added a file/OutputDebugString logger (log.rs, matches the DualSense driver) — the
  driver was silent; this is how the chain was traced.
- size.rs: framework_struct_size() reads the frameworks authoritative struct sizes
  from IddStructures[] (the config keeps size_of=208, validated working).
- adapter.rs: version ptrs + ObjectAttributes(InheritFromParent) + FP16 + framework
  caps/diag/version sizes — matches the oracle.

KNOWN WIP: IddCxAdapterInitAsync still returns INVALID_PARAMETER though caps match
the framework size table (88/56/24) + the oracle exactly — likely a subtle wdk-sys
bindgen field-layout detail in IDDCX_ADAPTER_CAPS/IDDCX_ENDPOINT_DIAGNOSTIC_INFO.
CI gate (compile+link) stays green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 17:46:58 +00:00
parent ad27174027
commit 3d3dd3627c
7 changed files with 175 additions and 31 deletions
@@ -1,7 +1,7 @@
//! DriverEntry + driver_add — the IddCx device bring-up (STEP 2 skeleton). wdk-build links the UMDF
//! DriverEntry + driver_add — the IddCx device bring-up (STEP 2/3). wdk-build links the UMDF
//! `WdfDriverStubUm` whose `FxDriverEntryUm` forwards to the exported `DriverEntry`. Adapter creation is
//! deferred to the first `EvtDeviceD0Entry` (STEP 3); monitors are created on demand by the control
//! plane (STEP 4).
//! plane (STEP 4). Instrumented with `dbglog!` for on-glass bring-up.
use wdk_iddcx::nt_success;
use wdk_sys::{
@@ -17,12 +17,13 @@ pub unsafe extern "system" fn driver_entry(
driver: PDRIVER_OBJECT,
registry_path: PCUNICODE_STRING,
) -> NTSTATUS {
dbglog!("[pf-vd] DriverEntry");
// 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(driver_add);
// SAFETY: driver + registry_path are loader-provided; config is valid for the call.
unsafe {
let st = unsafe {
call_unsafe_wdf_function_binding!(
WdfDriverCreate,
driver,
@@ -31,10 +32,13 @@ pub unsafe extern "system" fn driver_entry(
&mut config,
WDF_NO_HANDLE.cast::<WDFDRIVER>()
)
}
};
dbglog!("[pf-vd] WdfDriverCreate -> {st:#x}");
st
}
extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTATUS {
dbglog!("[pf-vd] driver_add");
// Defer adapter creation to the first D0 entry.
let mut pnp: WDF_PNPPOWER_EVENT_CALLBACKS = unsafe { core::mem::zeroed() };
pnp.Size = core::mem::size_of::<WDF_PNPPOWER_EVENT_CALLBACKS>() as ULONG;
@@ -46,6 +50,7 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA
// Build + size the IddCx client config (versioned size) and wire the 14 callbacks.
let Some(cfg_size) = size::idd_cx_client_config_size() else {
dbglog!("[pf-vd] config size unavailable");
return STATUS_NOT_FOUND;
};
let mut cfg: iddcx::IDD_CX_CLIENT_CONFIG = unsafe { core::mem::zeroed() };
@@ -67,6 +72,7 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA
// SAFETY: init is the framework device-init; cfg is fully populated + sized. (Links IddCxStub.)
let status = unsafe { wdk_iddcx::IddCxDeviceInitConfig(init, &cfg) };
dbglog!("[pf-vd] IddCxDeviceInitConfig -> {status:#x}");
if !nt_success(status) {
return status;
}
@@ -81,6 +87,7 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA
&mut device
)
};
dbglog!("[pf-vd] WdfDeviceCreate -> {status:#x}");
if !nt_success(status) {
return status;
}
@@ -103,10 +110,13 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA
core::ptr::null()
)
};
dbglog!("[pf-vd] WdfDeviceCreateDeviceInterface -> {status:#x}");
if !nt_success(status) {
return status;
}
// SAFETY: device is the just-created WDFDEVICE.
unsafe { wdk_iddcx::IddCxDeviceInitialize(device) }
let status = unsafe { wdk_iddcx::IddCxDeviceInitialize(device) };
dbglog!("[pf-vd] IddCxDeviceInitialize -> {status:#x}");
status
}