d39da4bc06
P1 done: a pure-Rust UMDF2 IddCx driver, drop-in compatible with the host's
existing vdisplay/sudovda.rs control plane (the {e5bcc234} interface + the
SudoVDA IOCTL ABI), so the host drives it unchanged. Validated streaming on
glass at 5120x1440@240 — steady 240 fps, ~2.4 ms encode, clean teardown, full
parity with SudoVDA.
- Vendored wdf-umdf-sys / wdf-umdf bindgen crates (MIT, from virtual-display-rs)
+ the SDK-version build.rs fix that resolves the IddCxStub lib path by the WDK
version actually containing um\x64\iddcx, not the max base SDK.
- pf-vdisplay crate: entry/callbacks/context/control/monitor/edid/
swap_chain_processor. Our OWN 128-byte EDID (manufacturer PNK, product
punktfunk — no SudoVDA bytes), a real swap-chain drain (faithful vdd port,
required so DWM keeps compositing), the SudoVDA-compatible IOCTL control plane
(ADD/REMOVE/PING/GET_WATCHDOG/GET_VERSION/SET_RENDER_ADAPTER) + a watchdog that
tears down orphaned monitors when the host stops pinging.
- deploy-dev.ps1: stage + sign + stampinf (date.time DriverVer) + Inf2Cat +
install, codifying the "bump DriverVer or pnputil keeps the old binary" gotcha.
- docs/windows-virtual-display-rust-port.md: investigation, the on-glass
validation, and the two traps that cost time (Session-0 measurement +
accumulated device-state needing a reboot).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
3.7 KiB
PowerShell
78 lines
3.7 KiB
PowerShell
#requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Stage, sign, and (optionally) install the pf-vdisplay UMDF IddCx driver for local dev/test.
|
|
|
|
.DESCRIPTION
|
|
Copies the freshly built pf_vdisplay.dll into the stage dir, signs it with the self-signed test cert,
|
|
stamps a STRICTLY INCREASING DriverVer (date.time) into the INF, then generates and signs the catalog.
|
|
With -Install it also pnputil /add-driver's the package and creates the Root\pf_vdisplay devnode.
|
|
|
|
Why the DriverVer bump matters: `pnputil /add-driver /install` only replaces an already-installed
|
|
driver binary when the INF DriverVer is higher than the installed one. Re-deploying without a bump
|
|
silently keeps the OLD binary loaded — a trap that masks code changes during iteration.
|
|
|
|
Build first: from pf-vdisplay/, in an MSVC dev shell with LIBCLANG_PATH set, run `cargo build`.
|
|
|
|
NOTE: pf-vdisplay and SudoVDA register the SAME control-interface GUID, so only one may be active at a
|
|
time. On the dev box, disable/remove the SudoVDA devnode before installing pf-vdisplay (and restore it
|
|
after). This script does not touch SudoVDA.
|
|
|
|
.PARAMETER Install
|
|
Also add the driver package to the store and create the root devnode.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$Stage = 'C:\Users\Public\pfvd-stage',
|
|
[string]$Thumbprint = '6A52984E54376C45A1C236B1A2C8A746C5AB6131',
|
|
[string]$Nefconc = 'C:\Users\Public\virtual-display-rs\installer\files\nefconc.exe',
|
|
[switch]$Install
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$root = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$dll = Join-Path $root 'target\x86_64-pc-windows-msvc\debug\pf_vdisplay.dll'
|
|
$inx = Join-Path $root 'pf-vdisplay\pf_vdisplay.inx'
|
|
if (-not (Test-Path $dll)) { throw "driver not built: $dll (run cargo build in pf-vdisplay/ first)" }
|
|
|
|
$kits = 'C:\Program Files (x86)\Windows Kits\10\bin'
|
|
function Find-Tool([string]$name, [string]$arch) {
|
|
(Get-ChildItem "$kits\*\$arch\$name" -EA SilentlyContinue | Sort-Object FullName | Select-Object -Last 1).FullName
|
|
}
|
|
$signtool = Find-Tool 'signtool.exe' 'x64'
|
|
$stampinf = Find-Tool 'stampinf.exe' 'x64'
|
|
$inf2cat = Find-Tool 'Inf2Cat.exe' 'x86'
|
|
if (-not $signtool) { throw 'signtool.exe not found in the WDK' }
|
|
if (-not $stampinf) { throw 'stampinf.exe not found in the WDK' }
|
|
if (-not $inf2cat) { throw 'Inf2Cat.exe not found in the WDK' }
|
|
|
|
New-Item -ItemType Directory -Force -Path $Stage | Out-Null
|
|
$stagedDll = Join-Path $Stage 'pf_vdisplay.dll'
|
|
$stagedInf = Join-Path $Stage 'pf_vdisplay.inf'
|
|
$stagedCat = Join-Path $Stage 'pf_vdisplay.cat'
|
|
Copy-Item $dll $stagedDll -Force
|
|
Copy-Item $inx $stagedInf -Force # stampinf rewrites this copy in place
|
|
|
|
# DriverVer date+time — must strictly increase each deploy or pnputil keeps the old binary.
|
|
$now = Get-Date
|
|
$ver = '1.0.{0}.{1}' -f $now.ToString('MMdd'), $now.ToString('HHmm')
|
|
|
|
& $signtool sign /fd SHA256 /sha1 $Thumbprint $stagedDll | Out-Null
|
|
& $stampinf -f $stagedInf -d '*' -a 'amd64' -u '2.15.0' -v $ver | Out-Null
|
|
& $inf2cat /driver:$Stage /os:10_X64 /uselocaltime | Out-Null
|
|
& $signtool sign /fd SHA256 /sha1 $Thumbprint $stagedCat | Out-Null
|
|
Write-Host "staged + signed pf-vdisplay DriverVer=$ver"
|
|
|
|
if ($Install) {
|
|
& pnputil /add-driver $stagedInf /install | Out-Null
|
|
$present = Get-PnpDevice -EA SilentlyContinue |
|
|
Where-Object { $_.InstanceId -match 'PF_VDISPLAY' -or $_.FriendlyName -match 'punktfunk Virtual Display' }
|
|
if (-not $present) {
|
|
if (-not (Test-Path $Nefconc)) { throw "nefconc not found: $Nefconc" }
|
|
& $Nefconc --create-device-node --hardware-id 'root\pf_vdisplay' --class-name Display --class-guid '{4d36e968-e325-11ce-bfc1-08002be10318}' | Out-Null
|
|
Start-Sleep 2
|
|
& pnputil /add-driver $stagedInf /install | Out-Null
|
|
}
|
|
Write-Host 'installed pf-vdisplay (root\pf_vdisplay devnode)'
|
|
}
|