diff --git a/.gitea/workflows/windows-host.yml b/.gitea/workflows/windows-host.yml index e3ffa19..f6c1af6 100644 --- a/.gitea/workflows/windows-host.yml +++ b/.gitea/workflows/windows-host.yml @@ -1,6 +1,6 @@ # Build the punktfunk Windows HOST as a signed Inno Setup installer and publish it to Gitea's generic # package registry, so a Windows GPU box can install the streaming host (SYSTEM service + bundled -# SudoVDA virtual-display driver + the web management console, run by a scheduled task on a bundled +# pf-vdisplay virtual-display driver + the web management console, run by a scheduled task on a bundled # bun) from one signed setup.exe. Runs on the self-hosted Windows runner # (host mode; scripts/ci/setup-windows-runner.ps1) — same MSVC/Windows-SDK/LLVM env as windows.yml. # diff --git a/packaging/windows/README.md b/packaging/windows/README.md index 8a5123b..6f9e52d 100644 --- a/packaging/windows/README.md +++ b/packaging/windows/README.md @@ -6,16 +6,16 @@ generic package registry (`punktfunk-host-windows`) by `.gitea/workflows/windows ## x64 only (no ARM64) Unlike the client (which ships x64 + ARM64 MSIX), the host is **x64-only by design**. It is coupled to -an NVIDIA GPU (NVENC, via `nvEncodeAPI64.dll` from the driver) and the **SudoVDA** virtual-display -driver — neither exists on Windows ARM64 (no ARM64 NVIDIA driver; the vendored SudoVDA is x64-only). An +an NVIDIA GPU (NVENC, via `nvEncodeAPI64.dll` from the driver) and the **pf-vdisplay** virtual-display +driver — neither exists on Windows ARM64 (no ARM64 NVIDIA driver; the driver builds x64-only). An ARM64 host would install but couldn't encode or create a virtual display, so we don't build one. -Revisit if NVIDIA-ARM Windows PCs + an ARM64 SudoVDA ever ship. +Revisit if NVIDIA-ARM Windows PCs ever ship. ## Why not MSIX (like the client) The host installs a **`LocalSystem` SCM service** that `CreateProcessAsUserW`'s from Session 0 into the interactive session for secure-desktop (UAC / lock screen) capture, adds firewall rules, and depends -on the **SudoVDA** kernel/IDD virtual-display driver. MSIX's sandbox can install **neither** a SYSTEM +on the **pf-vdisplay** UMDF/IDD virtual-display driver. MSIX's sandbox can install **neither** a SYSTEM service of this kind **nor** a driver. So the host ships as a classic elevated installer. The installer is deliberately thin: the real install logic — SCM registration, firewall rules, the @@ -26,9 +26,10 @@ exe into `C:\Program Files\punktfunk\` and calls that subcommand, elevated. ## What the installer does - Installs `punktfunk-host.exe` (+ `host.env.example`, this README) to `{app}` (`C:\Program Files\punktfunk`). -- **Optional task** *Install the SudoVDA virtual display driver* — imports the driver's self-signed - cert (machine `Root` + `TrustedPublisher`), creates the `root\sudomaker\sudovda` device node (only - if absent — `install-sudovda.ps1`), and stages the driver with `pnputil /add-driver /install`. +- **Optional task** *Install the pf-vdisplay virtual display driver* — imports the driver's self-signed + cert (machine `Root` + `TrustedPublisher`), creates the `root\pf_vdisplay` device node (only + if absent, via nefconc — never devgen — `install-pf-vdisplay.ps1`), and stages the driver with + `pnputil /add-driver /install`. Best-effort: a driver failure warns but never aborts the install (the host degrades to a physical display without it). - Runs `punktfunk-host service install` (idempotent; writes a default `host.env` only if absent, so @@ -45,7 +46,7 @@ exe into `C:\Program Files\punktfunk\` and calls that subcommand, elevated. (otherwise the locked exe / respawning supervisor would block the copy), then re-points the service; the existing console password is kept (the wizard page is skipped). - **Uninstall** (Add/Remove Programs): runs `service uninstall` (stop + delete service + remove - firewall rules) and removes the `PunktfunkWeb` task + its firewall rule. The SudoVDA driver and the + firewall rules) and removes the `PunktfunkWeb` task + its firewall rule. The pf-vdisplay driver and the `%ProgramData%\punktfunk` config (incl. `web-password`) are intentionally left in place. Silent install: `punktfunk-host-setup-.exe /VERYSILENT` (omit the driver with @@ -65,21 +66,24 @@ read it from `%ProgramData%\punktfunk\web-password`. |------|------| | `punktfunk-host.iss` | Inno Setup script (the installer definition). | | `pack-host-installer.ps1` | Orchestrator: cert + sign, stage the driver + FFmpeg + **web console** (`.output` + bun) bundles, run ISCC, sign setup.exe, emit registry paths. | -| `stage-sudovda.ps1` | Stage the **vendored** SudoVDA driver + fetch/verify the **pinned** nefcon release into the bundle. | -| `install-sudovda.ps1` | Runs at install time (elevated): trust cert → gated device-node create → `pnputil` install. | +| `stage-pf-vdisplay.ps1` | Stage the **vendored** pf-vdisplay driver + fetch/verify the **pinned** nefcon release into the bundle. | +| `install-pf-vdisplay.ps1` | Runs at install time (elevated): trust cert → gated device-node create (nefconc) → `pnputil` install. | | `../../scripts/windows/web-run.cmd` | The `PunktfunkWeb` task action: loads the mgmt token + login password env, runs the bundled `bun` on the Nitro server (`:3000`). | | `../../scripts/windows/web-setup.ps1` | Install-time (elevated): write the ACL'd console password, register the `PunktfunkWeb` task + firewall rule, start it. | -| `sudovda/` | **Vendored** prebuilt SudoVDA driver: `SudoVDA.inf` / `sudovda.cat` / `SudoVDA.dll` / `sudovda.cer`. | +| `pf-vdisplay/` | **Vendored** signed pf-vdisplay driver: `pf_vdisplay.inf` / `pf_vdisplay.cat` / `pf_vdisplay.dll` / `punktfunk-driver.cer`. Built from `vdisplay-driver/`. | +| `vdisplay-driver/` | The all-Rust IddCx **driver source** (`pf-vdisplay` crate + vendored `wdf-umdf*` bindings) + `deploy-dev.ps1` (build/sign/install for dev). | | `nvenc/nvenc.def`, `nvenc/gen-nvenc-importlib.ps1` | Synthesise `nvencodeapi.lib` for the `--features nvenc` link (llvm-dlltool / lib.exe). | -> **Vendored driver:** SudoVDA has no upstream release (its repo is a source-only VS solution; Apollo -> embeds the driver in its own installer), so the prebuilt **signed** driver is checked in under -> `sudovda/` (MIT/CC0; v1.10.9.289, signer `CN=sudovda@su.mk`, Class=Display, HWID -> `Root\SudoMaker\SudoVDA`). To refresh it, copy the four files out of a box's driver store -> (`C:\Windows\System32\DriverStore\FileRepository\sudovda.inf_amd64_*`) and re-derive `sudovda.cer` -> from the `.cat` signer (`(Get-AuthenticodeSignature sudovda.cat).SignerCertificate | Export-Certificate`). -> nefcon (the device-node tool) **is** fetched + SHA-256-verified from its pinned release in -> `stage-sudovda.ps1`. +> **Vendored driver:** pf-vdisplay is our **all-Rust IddCx** virtual display (UMDF2), built from +> `packaging/windows/vdisplay-driver/`. It replaced the vendored SudoVDA C++ driver — full story in +> [`docs/windows-virtual-display-rust-port.md`](../../docs/windows-virtual-display-rust-port.md). The +> **signed** output (`pf_vdisplay.dll`/`.inf`/`.cat` + `punktfunk-driver.cer`; signer +> `punktfunk-ds-test` — the same cert the gamepad drivers ship, Class=Display, HWID `root\pf_vdisplay`) +> is checked in under `pf-vdisplay/`. To refresh it after a driver-source change, rebuild + re-sign with +> `vdisplay-driver/deploy-dev.ps1` and copy the staged `pf_vdisplay.{dll,inf,cat}` over the vendored +> copies. nefcon (the device-node tool — the install creates the node with it, **never** `devgen`, which +> leaves persistent phantom devices) **is** fetched + SHA-256-verified from its pinned release in +> `stage-pf-vdisplay.ps1`. ## Build locally (Windows, MSVC + Windows SDK + Inno Setup) @@ -91,7 +95,7 @@ $env:PUNKTFUNK_NVENC_LIB_DIR = 'C:\t\nvenc' # 2. build the host cargo build --release -p punktfunk-host --features nvenc -# 3. pack (self-signed unless MSIX_CERT_PFX_B64/MSIX_CERT_PASSWORD are set; -NoDriver to skip SudoVDA) +# 3. pack (self-signed unless MSIX_CERT_PFX_B64/MSIX_CERT_PASSWORD are set; -NoDriver to skip pf-vdisplay) pwsh -File packaging\windows\pack-host-installer.ps1 -Version 0.0.0-dev -TargetDir C:\t\release -OutDir C:\t\out ``` diff --git a/packaging/windows/install-sudovda.ps1 b/packaging/windows/install-pf-vdisplay.ps1 similarity index 62% rename from packaging/windows/install-sudovda.ps1 rename to packaging/windows/install-pf-vdisplay.ps1 index d8c0a2c..5a8faae 100644 --- a/packaging/windows/install-sudovda.ps1 +++ b/packaging/windows/install-pf-vdisplay.ps1 @@ -1,32 +1,35 @@ <# .SYNOPSIS - Install the bundled SudoVDA virtual-display driver. Runs ELEVATED at setup time (invoked from the - installer's [Run] section). Best-effort: warns and exits 0 on any failure — the host degrades to a - physical display without SudoVDA, so a driver hiccup must never abort the whole install. + Install the bundled pf-vdisplay (punktfunk) virtual-display driver — our all-Rust IddCx replacement + for SudoVDA. Runs ELEVATED at setup time (invoked from the installer's [Run] section). Best-effort: + warns and exits 0 on any failure — the host degrades to a physical display without a virtual display, + so a driver hiccup must never abort the whole install. .DESCRIPTION - -Dir holds the staged payload from fetch-sudovda.ps1 (the .inf/.cat/.dll + signing .cer + nefconc.exe). - Steps: - 1. Trust the self-signed driver cert (machine Root + TrustedPublisher) so PnP installs it silently. - 2. Create the root device node IF ABSENT (gated — a blind re-create spawns a phantom duplicate, and + -Dir holds the staged payload (pf_vdisplay.inf/.cat/.dll + signing .cer + nefconc.exe). Steps: + 1. Trust the self-signed driver cert (machine Root + TrustedPublisher) so PnP installs it silently + (the same punktfunk-ds-test cert the gamepad drivers ship). + 2. Create the ROOT device node IF ABSENT (gated — a blind re-create spawns a phantom duplicate, and the host's open_device() binds interface index 0; crates/punktfunk-host/src/vdisplay/sudovda.rs). + ALWAYS via nefconc (a clean ROOT\DISPLAY node) — NEVER devgen, which makes persistent SWD\DEVGEN + software devices that survive reboot + registry deletion and resurrect on every driver install. 3. Stage + bind the driver (pnputil /add-driver /install — modern, in-box, idempotent). Class/ClassGuid are read from the .inf so they always match the shipped driver. .EXAMPLE - powershell -ExecutionPolicy Bypass -File install-sudovda.ps1 -Dir C:\path\to\sudovda + powershell -ExecutionPolicy Bypass -File install-pf-vdisplay.ps1 -Dir C:\path\to\pf-vdisplay #> [CmdletBinding()] param( [string]$Dir = $PSScriptRoot, - [string]$HardwareId = 'root\sudomaker\sudovda' # verified live (docs/windows-host.md) + [string]$HardwareId = 'root\pf_vdisplay' # matches pf_vdisplay.inf [Standard.NTamd64] ) # Never abort the installer on a driver failure. $ErrorActionPreference = 'Continue' -trap { Write-Warning "SudoVDA install error: $_"; exit 0 } +trap { Write-Warning "pf-vdisplay install error: $_"; exit 0 } -function Test-SudoVdaPresent { +function Test-PfVdisplayPresent { $devs = Get-PnpDevice -Class Display -PresentOnly -ErrorAction SilentlyContinue foreach ($d in $devs) { $hw = (Get-PnpDeviceProperty -InstanceId $d.InstanceId -KeyName 'DEVPKEY_Device_HardwareIds' ` @@ -36,14 +39,14 @@ function Test-SudoVdaPresent { return $false } -$inf = Get-ChildItem -Path $Dir -Filter *.inf -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 +$inf = Get-ChildItem -Path $Dir -Filter pf_vdisplay.inf -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 $cer = Get-ChildItem -Path $Dir -Filter *.cer -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 $nef = Get-ChildItem -Path $Dir -Filter 'nefconc.exe' -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -if (-not $inf) { Write-Warning "no SudoVDA .inf in $Dir; skipping driver install."; exit 0 } -Write-Host "SudoVDA inf: $($inf.FullName)" +if (-not $inf) { Write-Warning "no pf_vdisplay.inf in $Dir; skipping driver install."; exit 0 } +Write-Host "pf-vdisplay inf: $($inf.FullName)" -# 1) Trust the self-signed driver cert (a self-signed driver needs the cert in BOTH the machine -# Root store, so the chain validates, and TrustedPublisher, so PnP installs without a prompt). +# 1) Trust the self-signed driver cert (a self-signed driver needs the cert in BOTH the machine Root +# store, so the chain validates, and TrustedPublisher, so PnP installs without a prompt). if ($cer) { Write-Host "==> importing $($cer.Name) to Root + TrustedPublisher" certutil.exe -addstore -f Root "$($cer.FullName)" | Out-Null @@ -51,9 +54,9 @@ if ($cer) { } else { Write-Warning "no .cer in $Dir — driver may not install silently (untrusted publisher)" } -# 2) Create the root device node only if it isn't already there. -if (Test-SudoVdaPresent) { - Write-Host "SudoVDA device node already present — leaving it as-is." +# 2) Create the root device node only if it isn't already there. nefconc, NEVER devgen. +if (Test-PfVdisplayPresent) { + Write-Host "pf-vdisplay device node already present — leaving it as-is." } elseif ($nef) { $infText = Get-Content -Raw $inf.FullName @@ -66,7 +69,7 @@ elseif ($nef) { Write-Warning "nefconc --create-device-node returned $LASTEXITCODE" } } -else { Write-Warning "nefconc.exe not found in $Dir — cannot create the SudoVDA device node." } +else { Write-Warning "nefconc.exe not found in $Dir — cannot create the pf-vdisplay device node." } # 3) Stage + bind the driver (idempotent; re-staging the same .inf is harmless). Write-Host "==> pnputil /add-driver $($inf.Name) /install" diff --git a/packaging/windows/pack-host-installer.ps1 b/packaging/windows/pack-host-installer.ps1 index 0d34703..cafdb9d 100644 --- a/packaging/windows/pack-host-installer.ps1 +++ b/packaging/windows/pack-host-installer.ps1 @@ -7,7 +7,7 @@ 1. resolves a code-signing cert (supplied stable .pfx from CI secrets OR an ephemeral self-signed CN=unom — same scheme as the client's pack-msix.ps1) and exports the public .cer, 2. signs the inner punktfunk-host.exe, - 3. fetches + stages the SudoVDA driver bundle (unless -NoDriver), + 3. stages the pf-vdisplay virtual-display driver bundle (unless -NoDriver), 4. runs ISCC to build punktfunk-host-setup-.exe, 5. signs the setup.exe (timestamp best-effort), 6. emits HOST_SETUP_PATH / HOST_CER_PATH to GITHUB_ENV for the publish step. @@ -28,7 +28,7 @@ param( [string]$FfmpegDir = $env:FFMPEG_DIR, # bundle its bin\*.dll (amf-qsv build) [string]$WebDir = $env:WEB_OUTPUT_DIR, # built web .output tree -> bundle the mgmt console [string]$BunExe = $env:BUN_EXE, # portable bun.exe runtime for the console - [switch]$NoDriver, # build without the bundled SudoVDA driver + [switch]$NoDriver, # build without the bundled pf-vdisplay driver [switch]$NoSign # skip signing (local debug) ) $ErrorActionPreference = 'Stop' @@ -140,17 +140,19 @@ $defines = @( "/DReadme=$readme" ) -# --- stage the SudoVDA driver bundle ---------------------------------------------------------- +# --- stage the pf-vdisplay virtual-display driver bundle -------------------------------------- +# pf-vdisplay is our all-Rust IddCx driver (packaging/windows/vdisplay-driver/), vendored signed under +# packaging/windows/pf-vdisplay/. It replaced the vendored SudoVDA C++ driver. if (-not $NoDriver) { $stage = Join-Path $OutDir 'stage' - & (Join-Path $here 'stage-sudovda.ps1') -OutDir $stage - Copy-Item (Join-Path $here 'install-sudovda.ps1') (Join-Path $stage 'install-sudovda.ps1') -Force + & (Join-Path $here 'stage-pf-vdisplay.ps1') -OutDir $stage + Copy-Item (Join-Path $here 'install-pf-vdisplay.ps1') (Join-Path $stage 'install-pf-vdisplay.ps1') -Force $defines += "/DStageDir=$stage" } -else { Write-Host "-NoDriver: building installer WITHOUT the bundled SudoVDA driver" } +else { Write-Host "-NoDriver: building installer WITHOUT the bundled pf-vdisplay driver" } # --- stage the punktfunk virtual-gamepad UMDF drivers (DualSense/DS4 + Xbox 360 XUSB) ---------- -# Vendored, pre-signed under packaging/windows/gamepad-drivers/ (like SudoVDA). Rebuild + re-vendor +# Vendored, pre-signed under packaging/windows/gamepad-drivers/ (like pf-vdisplay). Rebuild + re-vendor # from packaging/windows/{dualsense,xusb}-driver/ when the driver source changes (see their READMEs). if (-not $NoDriver) { $gpVendor = Join-Path $here 'gamepad-drivers' diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.cat b/packaging/windows/pf-vdisplay/pf_vdisplay.cat new file mode 100644 index 0000000..8238ded Binary files /dev/null and b/packaging/windows/pf-vdisplay/pf_vdisplay.cat differ diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.dll b/packaging/windows/pf-vdisplay/pf_vdisplay.dll new file mode 100644 index 0000000..2f511b1 Binary files /dev/null and b/packaging/windows/pf-vdisplay/pf_vdisplay.dll differ diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.inf b/packaging/windows/pf-vdisplay/pf_vdisplay.inf new file mode 100644 index 0000000..18d4d8f --- /dev/null +++ b/packaging/windows/pf-vdisplay/pf_vdisplay.inf @@ -0,0 +1,78 @@ +;/*++ +; pf-vdisplay - punktfunk virtual display, UMDF2 IddCx driver INF (template; stampinf -> .inf). +; Adapted from MolotovCherry/virtual-display-rs (MIT) + SudoVDA's control-device security DACL. +;--*/ +[Version] +PnpLockdown=1 +Signature="$Windows NT$" +ClassGUID={4D36E968-E325-11CE-BFC1-08002BE10318} +Class=Display +ClassVer=2.0 +Provider=%ManufacturerName% +CatalogFile=pf_vdisplay.cat +DriverVer = 06/22/2026,1.0.0622.2210 + +[Manufacturer] +%ManufacturerName%=Standard,NTamd64 + +[Standard.NTamd64] +%DeviceName%=pf_vdisplay_Install, Root\pf_vdisplay + +[SourceDisksFiles] +pf_vdisplay.dll=1 + +[SourceDisksNames] +1=%DiskName% + +; =================== UMDF IddCx device ==================== + +[pf_vdisplay_Install.NT] +CopyFiles=UMDriverCopy + +[pf_vdisplay_Install.NT.hw] +AddReg=pf_vdisplay_HardwareDeviceSettings + +[pf_vdisplay_HardwareDeviceSettings] +HKR, , "UpperFilters", %REG_MULTI_SZ%, "IndirectKmd" +HKR, "WUDF", "DeviceGroupId", %REG_SZ%, "pfVDisplayGroup" +; Let the host (LocalSystem service) + admins open the control device for the ADD/REMOVE/PING IOCTLs. +HKR, , "Security", , "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;WD)" + +[pf_vdisplay_Install.NT.Services] +AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall + +[pf_vdisplay_Install.NT.Wdf] +UmdfService=pf_vdisplay, pf_vdisplay_Install +UmdfServiceOrder=pf_vdisplay +UmdfKernelModeClientPolicy=AllowKernelModeClients +UmdfHostProcessSharing=ProcessSharingDisabled + +[pf_vdisplay_Install] +UmdfLibraryVersion=2.15.0 +ServiceBinary=%12%\UMDF\pf_vdisplay.dll +UmdfExtensions=IddCx0102 + +[WUDFRD_ServiceInstall] +DisplayName=%WudfRdDisplayName% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\WUDFRd.sys + +[DestinationDirs] +UMDriverCopy=12,UMDF + +[UMDriverCopy] +pf_vdisplay.dll + +[Strings] +ManufacturerName="punktfunk" +DiskName="punktfunk Virtual Display Installation Disk" +WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector" +DeviceName="punktfunk Virtual Display" + +REG_MULTI_SZ=0x00010000 +REG_SZ=0x00000000 +REG_EXPAND_SZ=0x00020000 +REG_DWORD=0x00010001 + diff --git a/packaging/windows/pf-vdisplay/punktfunk-driver.cer b/packaging/windows/pf-vdisplay/punktfunk-driver.cer new file mode 100644 index 0000000..603933e Binary files /dev/null and b/packaging/windows/pf-vdisplay/punktfunk-driver.cer differ diff --git a/packaging/windows/punktfunk-host.iss b/packaging/windows/punktfunk-host.iss index 227b230..1b7edc2 100644 --- a/packaging/windows/punktfunk-host.iss +++ b/packaging/windows/punktfunk-host.iss @@ -1,7 +1,7 @@ ; punktfunk host installer (Inno Setup 6). ; ; Produces a signed setup.exe that lays the host into Program Files, optionally installs the bundled -; SudoVDA virtual-display driver, and DELEGATES service registration to `punktfunk-host service +; pf-vdisplay virtual-display driver, and DELEGATES service registration to `punktfunk-host service ; install`. The real, idempotent install logic (SCM registration, firewall rules, default host.env, ; the SYSTEM->interactive-session CreateProcessAsUserW supervisor for secure-desktop capture) lives in ; crates/punktfunk-host/src/service.rs - this script does NOT duplicate it. That SYSTEM service model @@ -36,7 +36,7 @@ #ifndef WebSetup #define WebSetup "..\..\scripts\windows\web-setup.ps1" #endif -; StageDir (the staged SudoVDA payload + nefconc.exe + install-sudovda.ps1) is optional. +; StageDir (the staged pf-vdisplay payload + nefconc.exe + install-pf-vdisplay.ps1) is optional. #ifdef StageDir #define WithDriver #endif @@ -84,7 +84,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] #ifdef WithDriver -Name: "installdriver"; Description: "Install the SudoVDA virtual display driver (required for native-resolution streaming)" +Name: "installdriver"; Description: "Install the pf-vdisplay virtual display driver (required for native-resolution streaming)" #endif #ifdef WithGamepad Name: "installgamepad"; Description: "Install the virtual gamepad drivers (DualSense / DualShock 4 / Xbox 360 — no ViGEmBus needed)" @@ -112,8 +112,8 @@ Source: "{#WebRunCmd}"; DestDir: "{app}\web"; DestName: "web-run.cmd"; Flags: ig Source: "{#WebSetup}"; DestDir: "{tmp}"; DestName: "web-setup.ps1"; Flags: deleteafterinstall #endif #ifdef WithDriver -; The driver payload + nefconc.exe + install-sudovda.ps1, extracted to {tmp} and removed after install. -Source: "{#StageDir}\*"; DestDir: "{tmp}\sudovda"; Flags: deleteafterinstall recursesubdirs createallsubdirs; Tasks: installdriver +; The driver payload + nefconc.exe + install-pf-vdisplay.ps1, extracted to {tmp} and removed after install. +Source: "{#StageDir}\*"; DestDir: "{tmp}\pfvdisplay"; Flags: deleteafterinstall recursesubdirs createallsubdirs; Tasks: installdriver #endif #ifdef WithGamepad ; The vendored UMDF gamepad drivers + install-gamepad-drivers.ps1, extracted to {tmp}, removed after. @@ -123,8 +123,8 @@ Source: "{#GamepadStageDir}\*"; DestDir: "{tmp}\gamepad"; Flags: deleteafterinst [Run] #ifdef WithDriver Filename: "powershell.exe"; \ - Parameters: "-NoProfile -ExecutionPolicy Bypass -File ""{tmp}\sudovda\install-sudovda.ps1"" -Dir ""{tmp}\sudovda"""; \ - StatusMsg: "Installing the SudoVDA virtual display driver..."; \ + Parameters: "-NoProfile -ExecutionPolicy Bypass -File ""{tmp}\pfvdisplay\install-pf-vdisplay.ps1"" -Dir ""{tmp}\pfvdisplay"""; \ + StatusMsg: "Installing the pf-vdisplay virtual display driver..."; \ Flags: runhidden waituntilterminated; Tasks: installdriver #endif #ifdef WithGamepad diff --git a/packaging/windows/stage-sudovda.ps1 b/packaging/windows/stage-pf-vdisplay.ps1 similarity index 58% rename from packaging/windows/stage-sudovda.ps1 rename to packaging/windows/stage-pf-vdisplay.ps1 index c4013cd..ecd4d1f 100644 --- a/packaging/windows/stage-sudovda.ps1 +++ b/packaging/windows/stage-pf-vdisplay.ps1 @@ -1,25 +1,28 @@ <# .SYNOPSIS - Stage the driver bundle the installer ships into -OutDir: the VENDORED SudoVDA driver + the - fetched nefcon device tool. + Stage the pf-vdisplay driver bundle the installer ships into -OutDir: the VENDORED signed pf-vdisplay + driver + the fetched nefcon device tool. .DESCRIPTION - SudoVDA has no upstream release (its repo is a source-only VS solution; Apollo embeds the driver in - its single installer), so the prebuilt, signed driver is VENDORED in this repo under - packaging/windows/sudovda/ (MIT/CC0; SudoVDA v1.10.9.289, signer CN=sudovda@su.mk, Class=Display, - HWID Root\SudoMaker\SudoVDA). nefcon DOES publish a pinned release, so we fetch + SHA-256-verify it - (it provides nefconc.exe, used to create the root-enumerated device node — pnputil can't). + pf-vdisplay (our all-Rust IddCx virtual display) is built from packaging/windows/vdisplay-driver/, and + the SIGNED output (pf_vdisplay.dll/.inf/.cat + punktfunk-driver.cer) is VENDORED under + packaging/windows/pf-vdisplay/ (signer punktfunk-ds-test — shared with the gamepad drivers — Class= + Display, HWID root\pf_vdisplay). Rebuild + re-vendor with + packaging/windows/vdisplay-driver/deploy-dev.ps1 when the driver source changes, then copy the staged + pf_vdisplay.{dll,inf,cat} over the vendored copies. nefcon publishes a pinned release, so we fetch + + SHA-256-verify it (it provides nefconc.exe, used to create the root-enumerated device node — pnputil + can't). - Output (consumed by punktfunk-host.iss): -OutDir gets SudoVDA.inf/.cat/.dll + sudovda.cer and - nefconc.exe (x64). pack-host-installer.ps1 also drops install-sudovda.ps1 in. + Output (consumed by punktfunk-host.iss): -OutDir gets pf_vdisplay.inf/.cat/.dll + punktfunk-driver.cer + and nefconc.exe (x64). pack-host-installer.ps1 also drops install-pf-vdisplay.ps1 in. .EXAMPLE - pwsh -File stage-sudovda.ps1 -OutDir C:\t\out\stage + pwsh -File stage-pf-vdisplay.ps1 -OutDir C:\t\out\stage #> [CmdletBinding()] param( [Parameter(Mandatory = $true)][string]$OutDir, - [string]$VendorDir = (Join-Path $PSScriptRoot 'sudovda'), + [string]$VendorDir = (Join-Path $PSScriptRoot 'pf-vdisplay'), # PINNED nefcon release (https://github.com/nefarius/nefcon/releases). MIT-licensed. [string]$NefconUrl = 'https://github.com/nefarius/nefcon/releases/download/v1.17.40/nefcon_v1.17.40.zip', [string]$NefconSha256 = '812bae7ed7dfb7d6d2284bc7de2f8ccebc92ed2a0b1ae893c53b337096e50c1a' @@ -31,11 +34,11 @@ $PSNativeCommandUseErrorActionPreference = $false if (Test-Path $OutDir) { Remove-Item -Recurse -Force $OutDir } New-Item -ItemType Directory -Force -Path $OutDir | Out-Null -# --- vendored SudoVDA driver ------------------------------------------------------------------ -$inf = Get-ChildItem -Path $VendorDir -Filter *.inf -ErrorAction SilentlyContinue | Select-Object -First 1 -if (-not $inf) { throw "no vendored SudoVDA .inf under $VendorDir — see packaging/windows/README.md" } +# --- vendored pf-vdisplay driver -------------------------------------------------------------- +$inf = Get-ChildItem -Path $VendorDir -Filter pf_vdisplay.inf -ErrorAction SilentlyContinue | Select-Object -First 1 +if (-not $inf) { throw "no vendored pf_vdisplay.inf under $VendorDir — re-vendor via vdisplay-driver/deploy-dev.ps1" } Copy-Item (Join-Path $VendorDir '*') $OutDir -Force -Write-Host "==> vendored SudoVDA staged from $VendorDir" +Write-Host "==> vendored pf-vdisplay staged from $VendorDir" # --- nefcon (fetched + verified) -------------------------------------------------------------- $work = Join-Path ([IO.Path]::GetTempPath()) ('nefcon-' + [IO.Path]::GetRandomFileName()) @@ -51,7 +54,7 @@ try { } Write-Host " sha256 ok ($got)" } - else { Write-Warning "no pinned nefcon SHA-256 — computed $got (PIN THIS in stage-sudovda.ps1)" } + else { Write-Warning "no pinned nefcon SHA-256 — computed $got (PIN THIS in stage-pf-vdisplay.ps1)" } Expand-Archive -Path $zip -DestinationPath $work -Force $nefc = Get-ChildItem -Path $work -Recurse -Filter 'nefconc.exe' | Where-Object { $_.FullName -match '(?i)\\x64\\' } | Select-Object -First 1 diff --git a/packaging/windows/sudovda/SudoVDA.dll b/packaging/windows/sudovda/SudoVDA.dll deleted file mode 100644 index dfdff70..0000000 Binary files a/packaging/windows/sudovda/SudoVDA.dll and /dev/null differ diff --git a/packaging/windows/sudovda/SudoVDA.inf b/packaging/windows/sudovda/SudoVDA.inf deleted file mode 100644 index f1958d5..0000000 Binary files a/packaging/windows/sudovda/SudoVDA.inf and /dev/null differ diff --git a/packaging/windows/sudovda/sudovda.cat b/packaging/windows/sudovda/sudovda.cat deleted file mode 100644 index beb350b..0000000 Binary files a/packaging/windows/sudovda/sudovda.cat and /dev/null differ diff --git a/packaging/windows/sudovda/sudovda.cer b/packaging/windows/sudovda/sudovda.cer deleted file mode 100644 index 6cdc2ae..0000000 Binary files a/packaging/windows/sudovda/sudovda.cer and /dev/null differ