Files
punktfunk/packaging/windows/drivers/pf-vdisplay/build.rs
T
enricobuehler 55899bf73f
apple / swift (push) Failing after 0s
apple / screenshots (push) Has been skipped
windows-drivers / probe-and-proto (push) Successful in 33s
windows-drivers / driver-build (push) Successful in 1m10s
windows-host / package (push) Successful in 6m13s
android / android (push) Successful in 4m7s
ci / rust (push) Successful in 4m24s
ci / web (push) Successful in 42s
ci / docs-site (push) Successful in 53s
deb / build-publish (push) Successful in 2m15s
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 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 3s
ci / bench (push) Successful in 4m45s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m27s
docker / deploy-docs (push) Successful in 6s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m14s
test(windows-drivers): adapter-init isolated to wdk-sys IddCx binding (Rust IddCx PROVEN to work on-box)
DECISIVE: installed the pre-built UPSTREAM virtual-display-rs (Rust wdf-umdf IddCx)
driver on the SAME box -> Status=OK. So a Rust IddCx driver inits an adapter here,
self-signed, right now. My wdk-sys driver still fails ONLY at IddCxAdapterInitAsync
(0xc000000d) despite matching virtual-display-rs on EVERY inspectable dimension:
- same iddcx 1.10 headers+stub
- IDDCX_ADAPTER_CAPS + IDD_CX_CLIENT_CONFIG byte-perfect (offsets match C header)
- runtime pointers all valid/non-null (names .rdata, version stack, dev handle)
- identical IddFunctions[idx]+IddDriverGlobals dispatch; indices 0/1/2
- matched the minimal link (tested vendored wdk-build WITHOUT OneCoreUAP/
  NODEFAULTLIB/OPT/INTEGRITYCHECK -> still fails; export pollution ruled out)
- device context, no device interface (control via EvtIddCxDeviceIoControl), init order

The IddCx ClassExtension ETW provider emits no decodable reason (WPP/kernel-debugger
only). The remaining difference is the wdk-sys IddCx binding itself, invisible to
inspection. This commit keeps the upstream-matching structure (device context, no
interface) + the on-glass instrumentation; vendored wdk-build reverted to pristine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 19:40:26 +00:00

59 lines
2.9 KiB
Rust

//! WDK link flags for the cdylib (wdk-build) + `IddCxStub` (the driver calls IddCx DDIs via wdk-iddcx,
//! and exports `IddMinimumVersionRequired`). `/INTEGRITYCHECK` (set by wdk-build) is cleared by the CI
//! packaging step. Glob recipe matches wdk-probe/build.rs.
fn main() -> Result<(), wdk_build::ConfigError> {
wdk_build::configure_wdk_binary_build()?;
link_iddcx_stub();
// wdk-build emits `/OPT:REF,ICF`. ICF (Identical COMDAT Folding) merges functions with identical
// bodies into ONE address — our many identical stub IddCx callbacks (`return STATUS_SUCCESS`) collapse
// to the same pointer (and even CRT EH handlers fold, hence the dumpbin `__CxxFrameHandler4 = DllMain`
// alias). The working virtual-display-rs links with NO `/OPT`, and IddCxAdapterInitAsync rejects a
// config whose distinct callbacks alias each other. Disable ICF (REF stays on); last `/OPT` wins.
println!("cargo::rustc-cdylib-link-arg=/OPT:NOICF");
Ok(())
}
/// Link `IddCxStub.lib`. It ships under `Lib\<sdkver>\um\<arch>\iddcx\<iddcxver>\`, and the iddcx
/// versions are NOT equivalent: the `1.0`/`1.2` stubs lack the versioned-struct-size table symbols
/// (`IddStructures`/`IddStructureCount`/`IddClientVersionHigherThanFramework`) that `size.rs` needs —
/// `1.3`+ and `1.10` have them. So pick the HIGHEST `iddcx\<X.Y>` dir that has the lib (version-aware,
/// since "1.10" < "1.2" lexically). x64 only.
fn link_iddcx_stub() {
const ARCH: &str = "x64";
const ROOTS: [&str; 2] = [
r"C:\Program Files (x86)\Windows Kits\10\Lib",
r"C:\Program Files\Windows Kits\10\Lib",
];
let mut best: Option<((u32, u32), std::path::PathBuf)> = None;
for root in ROOTS {
let Ok(versions) = std::fs::read_dir(root) else {
continue;
};
for ver in versions.flatten() {
let iddcx = ver.path().join("um").join(ARCH).join("iddcx");
let Ok(subdirs) = std::fs::read_dir(&iddcx) else {
continue;
};
for sub in subdirs.flatten() {
if !sub.path().join("IddCxStub.lib").is_file() {
continue;
}
let name = sub.file_name().to_string_lossy().into_owned();
let mut parts = name.split('.');
let v = (
parts.next().and_then(|x| x.parse().ok()).unwrap_or(0u32),
parts.next().and_then(|x| x.parse().ok()).unwrap_or(0u32),
);
if best.as_ref().is_none_or(|(bv, _)| v > *bv) {
best = Some((v, sub.path()));
}
}
}
}
let Some((_, dir)) = best else {
panic!("IddCxStub.lib not found under any Windows Kits Lib\\<ver>\\um\\{ARCH}\\iddcx\\<iddcxver>\\");
};
println!("cargo:rustc-link-search={}", dir.display());
println!("cargo:rustc-link-lib=static=IddCxStub");
}