diff --git a/.gitea/workflows/windows-drivers.yml b/.gitea/workflows/windows-drivers.yml index 677a867..a77c025 100644 --- a/.gitea/workflows/windows-drivers.yml +++ b/.gitea/workflows/windows-drivers.yml @@ -76,7 +76,7 @@ jobs: head "EWDK" Write-Host ("EWDKROOT = " + ($env:EWDKROOT ?? '')) - head "LLVM / clang (README pins 21.1.2 for wdk-sys bindgen)" + head "LLVM / clang (bindgen 0.72 builds on the runner default clang)" Write-Host ("LIBCLANG_PATH = " + ($env:LIBCLANG_PATH ?? '')) $clang = Get-Command clang -ErrorAction SilentlyContinue if ($clang) { & clang --version } else { Write-Host "clang: NOT on PATH" } @@ -119,12 +119,12 @@ jobs: env: # wdk-build otherwise picks 10.0.28000.0 (no km/crt) and bindgen fails — pin the WDK SDK version. Version_Number: '10.0.26100.0' - # wdk-sys bindgen layout tests overflow (E0080) on the runner's default LLVM (ToT/22-dev); point at - # the pinned LLVM 21.1.2 that windows-drivers-rs builds clean against (provisioned to C:\llvm-21). - LIBCLANG_PATH: 'C:\llvm-21\bin' + # No LIBCLANG_PATH pin: the vendored bindgen 0.72 builds clean on the runner's default clang 22 + # (the shipping pack proves it). A 0.71-era layout-test overflow once needed LLVM 21; the 0.72 bump + # retired that — see design/windows-build-and-packaging.md. steps: - uses: actions/checkout@v4 - - name: Ensure WDK + cargo-wdk + LLVM 21.1.2 (idempotent self-provision) + - name: Ensure WDK + cargo-wdk (idempotent self-provision) # Run the provisioning script here too so driver-build is self-sufficient and never races a # separate provision run on the single runner. Path is relative to the job working-directory # (packaging/windows/drivers). Near-noop once the toolchain is present. diff --git a/packaging/windows/build-gamepad-drivers.ps1 b/packaging/windows/build-gamepad-drivers.ps1 index 5317cba..a7e0020 100644 --- a/packaging/windows/build-gamepad-drivers.ps1 +++ b/packaging/windows/build-gamepad-drivers.ps1 @@ -10,8 +10,8 @@ `cargo build --release` builds the whole workspace (this shares wdk-sys/wdk-build + the bindgen pin with pf-vdisplay). Then, per driver: CLEAR the FORCE_INTEGRITY PE bit, sign the .dll, stampinf a DriverVer into the INF; then Inf2Cat both catalogs and sign them. Both drivers share ONE self-signed cert (or a - supplied DRIVER_CERT secret) + ONE exported .cer, matching the vendored gamepad-drivers/ layout that - install-gamepad-drivers.ps1 expects. + supplied DRIVER_CERT secret) + ONE exported .cer - the layout install-gamepad-drivers.ps1 consumes + (per-driver .inf/.cat/.dll + one shared punktfunk-driver.cer). Output (-Out): pf_dualsense.{dll,inf,cat} + pf_xusb.{dll,inf,cat} + punktfunk-driver.cer. diff --git a/packaging/windows/drivers/deploy-dev.ps1 b/packaging/windows/drivers/deploy-dev.ps1 index 385fc98..7957d29 100644 --- a/packaging/windows/drivers/deploy-dev.ps1 +++ b/packaging/windows/drivers/deploy-dev.ps1 @@ -15,8 +15,8 @@ Version_Number=10.0.26100.0, run `cargo build`. Re-deploying needs a HIGHER DriverVer than the installed one or pnputil silently keeps the old binary — - hence the 9.9.MMdd.HHmm scheme (the vendored build is 9.5.*). If the host service is running it holds the - driver: `punktfunk-host service stop`, deploy, then start it, for a clean test. + hence the 9.9.MMdd.HHmm scheme (also what the installer build uses; a later-minute dev redeploy wins). + If the host service is running it holds the driver: `punktfunk-host service stop`, deploy, then start it. .PARAMETER Install Also add the driver package to the store + (if absent) create the Root\pf_vdisplay devnode via nefconc. Needs an ELEVATED shell. @@ -25,7 +25,7 @@ param( [string]$Stage = 'C:\Users\Public\pfvd-stage-deploy', [string]$Thumbprint = '6A52984E54376C45A1C236B1A2C8A746C5AB6131', - [string]$Nefconc = 'C:\Users\Public\virtual-display-rs\installer\files\nefconc.exe', + [string]$Nefconc = 'C:\Users\Public\nefcon\x64\nefconc.exe', # pinned nefcon (stage-pf-vdisplay.ps1 fetches it) [switch]$Install ) $ErrorActionPreference = 'Stop' @@ -56,7 +56,7 @@ Copy-Item $inx $stagedInf -Force # stampinf rewrites this copy in place # Clear FORCE_INTEGRITY BEFORE signing (the clear edits the PE, which invalidates any signature). & $clear -Path $stagedDll | Out-Null -# DriverVer must strictly increase. Installed is 9.5.* — 9.9.MMdd.HHmm always wins on the same day. +# DriverVer must strictly increase past whatever is installed; 9.9.MMdd.HHmm bumps every minute. $now = Get-Date $ver = '9.9.{0}.{1}' -f $now.ToString('MMdd'), $now.ToString('HHmm') diff --git a/packaging/windows/drivers/pf-dualsense/README.md b/packaging/windows/drivers/pf-dualsense/README.md index 89bb73d..2e727d9 100644 --- a/packaging/windows/drivers/pf-dualsense/README.md +++ b/packaging/windows/drivers/pf-dualsense/README.md @@ -24,8 +24,9 @@ version control / portability of the spike. ## Build / sign / install recipe (the one that actually loads) -Prereqs on the Windows box: **WDK 26100**, **LLVM 21.1.2** (pinned — newer bindgen breaks), -`cargo-make`, Rust MSVC. A self-signed CodeSigning cert in `CurrentUser\My` + `LocalMachine\Root` + +Prereqs on the Windows box: **WDK 26100**, **LLVM** (the current default; bindgen 0.72 builds on clang +22), Rust MSVC. Built as a member of the `packaging/windows/drivers/` workspace (plain `cargo build`, no +cargo-make). A self-signed CodeSigning cert in `CurrentUser\My` + `LocalMachine\Root` + `TrustedPublisher`. Every build needs: diff --git a/packaging/windows/drivers/pf-xusb/README.md b/packaging/windows/drivers/pf-xusb/README.md index cda75b3..62516ea 100644 --- a/packaging/windows/drivers/pf-xusb/README.md +++ b/packaging/windows/drivers/pf-xusb/README.md @@ -66,8 +66,8 @@ there); these repo files are the canonical copies — keep them in sync. `crates/punktfunk-host/src/inject/gamepad_windows.rs` is the Windows `GamepadManager` (used by `PadBackend::Xbox360`): it SwDeviceCreate's the `pf_xusb` companion, maps `pfxusb-shm-`, writes the XInput state from the client's gamepad frame (already XInput-convention) and forwards rumble. There -is **no ViGEmBus dependency** anymore. The driver is vendored + pnputil-installed by the Inno Setup -installer (`packaging/windows/gamepad-drivers/` + `install-gamepad-drivers.ps1`). +is **no ViGEmBus dependency** anymore. The driver is built from source (`packaging/windows/drivers/pf-xusb`), +signed, and pnputil-installed by the Inno Setup installer (via `install-gamepad-drivers.ps1`). ## Multi-pad diff --git a/packaging/windows/gamepad-drivers/pf_dualsense.cat b/packaging/windows/gamepad-drivers/pf_dualsense.cat deleted file mode 100644 index cf3e613..0000000 Binary files a/packaging/windows/gamepad-drivers/pf_dualsense.cat and /dev/null differ diff --git a/packaging/windows/gamepad-drivers/pf_dualsense.dll b/packaging/windows/gamepad-drivers/pf_dualsense.dll deleted file mode 100644 index 674bac0..0000000 Binary files a/packaging/windows/gamepad-drivers/pf_dualsense.dll and /dev/null differ diff --git a/packaging/windows/gamepad-drivers/pf_dualsense.inf b/packaging/windows/gamepad-drivers/pf_dualsense.inf deleted file mode 100644 index eb06379..0000000 --- a/packaging/windows/gamepad-drivers/pf_dualsense.inf +++ /dev/null @@ -1,82 +0,0 @@ -;/*++ -; punktfunk virtual DualSense — UMDF2 HID minidriver INF (M0 spike). -; Adapted from the WDK vhidmini2 UMDF2 sample (VhidminiUm.inx). -; Depends on MsHidUmdf.inf (build >= 22000). -; Install: devgen /add /hardwareid "root\pf_dualsense" (after pnputil /add-driver /install) -;--*/ -[Version] -Signature="$WINDOWS NT$" -Class=HIDClass -ClassGuid={745a17a0-74d3-11d0-b6fe-00a0c90f57da} -Provider=%ProviderString% -CatalogFile = pf_dualsense.cat -PnpLockdown=1 -DriverVer = 06/22/2026,16.23.43.887 - -[DestinationDirs] -DefaultDestDir = 13 - -[SourceDisksNames] -1=%Disk_Description%,,, - -[SourceDisksFiles] -pf_dualsense.dll=1 - -[Manufacturer] -%ManufacturerString%=pf, NTamd64.10.0...22000 - -[pf.NTamd64.10.0...22000] -; Hardware ids: `root\pf_dualsense` for a root-enumerated devnode (devgen/devcon tests); `pf_dualsense` -; for the host's SwDeviceCreate'd DualSense (the `root\` prefix is reserved for root enumeration, so -; SwDeviceCreate rejects it with E_INVALIDARG); `pf_dualshock4` for the host's virtual DualShock 4 — the -; same driver binds both and serves the DualSense or DS4 identity per the device_type byte the host -; stamps into shared memory. -%DeviceDesc%=pfDualSense, root\pf_dualsense, pf_dualsense, pf_dualshock4 - -[pfDualSense.NT] -CopyFiles=UMDriverCopy -Include=MsHidUmdf.inf -Needs=MsHidUmdf.NT -Include=WUDFRD.inf -Needs=WUDFRD_LowerFilter.NT - -[pfDualSense.NT.hw] -Include=MsHidUmdf.inf -Needs=MsHidUmdf.NT.hw -Include=WUDFRD.inf -Needs=WUDFRD_LowerFilter.NT.hw - -[pfDualSense.NT.Services] -Include=MsHidUmdf.inf -Needs=MsHidUmdf.NT.Services -Include=WUDFRD.inf -Needs=WUDFRD_LowerFilter.NT.Services - -[pfDualSense.NT.Filters] -Include=WUDFRD.inf -Needs=WUDFRD_LowerFilter.NT.Filters - -[pfDualSense.NT.Wdf] -UmdfService="pf_dualsense", pf_dualsense_Install -UmdfServiceOrder=pf_dualsense -UmdfKernelModeClientPolicy=AllowKernelModeClients -UmdfFileObjectPolicy=AllowNullAndUnknownFileObjects -UmdfMethodNeitherAction=Copy -UmdfFsContextUsePolicy=CanUseFsContext2 -; Each pad gets its OWN WUDFHost so the driver's per-pad statics (incl. the shm index) don't collide -; across multiple simultaneous controllers (multi-pad). -UmdfHostProcessSharing=ProcessSharingDisabled - -[pf_dualsense_Install] -UmdfLibraryVersion=2.31.0 -ServiceBinary="%13%\pf_dualsense.dll" - -[UMDriverCopy] -pf_dualsense.dll - -[Strings] -ProviderString ="punktfunk" -ManufacturerString ="punktfunk" -ClassName ="HID device" -Disk_Description ="punktfunk DualSense Installation Disk" -DeviceDesc ="punktfunk Virtual DualSense" diff --git a/packaging/windows/gamepad-drivers/pf_xusb.cat b/packaging/windows/gamepad-drivers/pf_xusb.cat deleted file mode 100644 index ec19e3b..0000000 Binary files a/packaging/windows/gamepad-drivers/pf_xusb.cat and /dev/null differ diff --git a/packaging/windows/gamepad-drivers/pf_xusb.dll b/packaging/windows/gamepad-drivers/pf_xusb.dll deleted file mode 100644 index c94c3b4..0000000 Binary files a/packaging/windows/gamepad-drivers/pf_xusb.dll and /dev/null differ diff --git a/packaging/windows/gamepad-drivers/pf_xusb.inf b/packaging/windows/gamepad-drivers/pf_xusb.inf deleted file mode 100644 index fc10984..0000000 --- a/packaging/windows/gamepad-drivers/pf_xusb.inf +++ /dev/null @@ -1,66 +0,0 @@ -;/*++ -; punktfunk virtual Xbox 360 XUSB companion — a non-HID UMDF2 driver that registers the XUSB -; device-interface GUID {EC87F1E3-...} and answers the buffered XInput IOCTLs, so classic -; XInputGetState() reads the pad without a kernel bus driver (the HIDMaestro approach). System class, -; hosted by the in-box WUDFRd reflector. Created per-session by the host via SwDeviceCreate -; (hardware id `pf_xusb`); `root\pf_xusb` is the devgen/devcon test id. -;--*/ -[Version] -Signature = "$WINDOWS NT$" -Class = System -ClassGuid = {4D36E97D-E325-11CE-BFC1-08002BE10318} -Provider = %ProviderString% -CatalogFile = pf_xusb.cat -PnpLockdown = 1 -DriverVer = 06/22/2026,16.17.56.696 - -[DestinationDirs] -DefaultDestDir = 13 - -[SourceDisksNames] -1 = %DiskId1%,,,"" - -[SourceDisksFiles] -pf_xusb.dll = 1,, - -[Manufacturer] -%StdMfg%=Standard, NTamd64.10.0...22000 - -[Standard.NTamd64.10.0...22000] -%DeviceDesc%=pfXusb, root\pf_xusb, pf_xusb - -[pfXusb.NT] -CopyFiles=Drivers_Dir -Include=WUDFRD.inf -Needs=WUDFRD.NT - -[Drivers_Dir] -pf_xusb.dll - -[pfXusb.NT.HW] -Include=WUDFRD.inf -Needs=WUDFRD.NT.HW - -[pfXusb.NT.Services] -Include=WUDFRD.inf -Needs=WUDFRD.NT.Services - -[pfXusb.NT.Wdf] -UmdfService=pf_xusb, pfXusb_Install -UmdfServiceOrder=pf_xusb -UmdfKernelModeClientPolicy=AllowKernelModeClients -UmdfFileObjectPolicy=AllowNullAndUnknownFileObjects -UmdfMethodNeitherAction=Copy -UmdfFsContextUsePolicy=CanUseFsContext2 -UmdfHostProcessSharing=ProcessSharingDisabled - -[pfXusb_Install] -UmdfLibraryVersion=2.31.0 -ServiceBinary=%13%\pf_xusb.dll - -[Strings] -ProviderString = "punktfunk" -StdMfg = "(Standard system devices)" -DiskId1 = "punktfunk XUSB Installation Disk" -DeviceDesc = "punktfunk Virtual Xbox 360 (XUSB)" - diff --git a/packaging/windows/gamepad-drivers/punktfunk-driver.cer b/packaging/windows/gamepad-drivers/punktfunk-driver.cer deleted file mode 100644 index 603933e..0000000 Binary files a/packaging/windows/gamepad-drivers/punktfunk-driver.cer and /dev/null differ diff --git a/packaging/windows/pack-host-installer.ps1 b/packaging/windows/pack-host-installer.ps1 index c3e809a..07b99fb 100644 --- a/packaging/windows/pack-host-installer.ps1 +++ b/packaging/windows/pack-host-installer.ps1 @@ -164,7 +164,9 @@ else { Write-Host "-NoDriver: building installer WITHOUT the bundled pf-vdisplay # gamepad-drivers.ps1 adds each to the store (the host SwDeviceCreate's the per-session devnodes). if (-not $NoDriver) { $gpBuilt = Join-Path $OutDir 'gamepad-built' - & (Join-Path $here 'build-gamepad-drivers.ps1') -Out $gpBuilt + # -SkipBuild: build-pf-vdisplay.ps1 above already `cargo build`s the WHOLE drivers workspace (incl. + # the gamepad cdylibs), so just sign+stage them here - no redundant second full build. + & (Join-Path $here 'build-gamepad-drivers.ps1') -Out $gpBuilt -SkipBuild $gpStage = Join-Path $OutDir 'gamepad' if (Test-Path $gpStage) { Remove-Item -Recurse -Force $gpStage } New-Item -ItemType Directory -Force -Path $gpStage | Out-Null diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.cat b/packaging/windows/pf-vdisplay/pf_vdisplay.cat deleted file mode 100644 index f4b2a96..0000000 Binary files a/packaging/windows/pf-vdisplay/pf_vdisplay.cat and /dev/null differ diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.dll b/packaging/windows/pf-vdisplay/pf_vdisplay.dll deleted file mode 100644 index 07ca706..0000000 Binary files a/packaging/windows/pf-vdisplay/pf_vdisplay.dll and /dev/null differ diff --git a/packaging/windows/pf-vdisplay/pf_vdisplay.inf b/packaging/windows/pf-vdisplay/pf_vdisplay.inf deleted file mode 100644 index 3111821..0000000 --- a/packaging/windows/pf-vdisplay/pf_vdisplay.inf +++ /dev/null @@ -1,85 +0,0 @@ -;/*++ -; pf-vdisplay - punktfunk virtual display, UMDF2 IddCx driver INF (template; stampinf -> .inf). -; -; For the all-Rust wdk-sys / windows-drivers-rs driver in THIS tree -; (packaging/windows/drivers/pf-vdisplay/). The driver registers the OWNED pf_driver_proto -; control-interface GUID in CODE (WdfDeviceCreateDeviceInterface), so this INF is GUID-agnostic and -; is byte-identical to the superseded oracle's (packaging/windows/vdisplay-driver/.../pf_vdisplay.inx, -; itself adapted from MolotovCherry/virtual-display-rs (MIT) + SudoVDA's control-device security DACL). -; HWID Root\pf_vdisplay + IddCx0102 + the DACL match the host backend (crates/punktfunk-host/src/ -; vdisplay/pf_vdisplay.rs) and install-pf-vdisplay.ps1's Test-PfVdisplayPresent / nefconc node-create. -;--*/ -[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/25/2026,9.5.0625.1614 - -[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 deleted file mode 100644 index 603933e..0000000 Binary files a/packaging/windows/pf-vdisplay/punktfunk-driver.cer and /dev/null differ diff --git a/packaging/windows/punktfunk-host.iss b/packaging/windows/punktfunk-host.iss index b03269c..0ec3161 100644 --- a/packaging/windows/punktfunk-host.iss +++ b/packaging/windows/punktfunk-host.iss @@ -40,7 +40,7 @@ #ifdef StageDir #define WithDriver #endif -; GamepadStageDir (the vendored UMDF gamepad drivers + install-gamepad-drivers.ps1) is optional. +; GamepadStageDir (the built-from-source UMDF gamepad drivers + install-gamepad-drivers.ps1) is optional. #ifdef GamepadStageDir #define WithGamepad #endif @@ -126,7 +126,7 @@ Source: "{#WebSetup}"; DestDir: "{tmp}"; DestName: "web-setup.ps1"; Flags: delet 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. +; The built-from-source UMDF gamepad drivers + install-gamepad-drivers.ps1, extracted to {tmp}, removed after. Source: "{#GamepadStageDir}\*"; DestDir: "{tmp}\gamepad"; Flags: deleteafterinstall recursesubdirs createallsubdirs; Tasks: installgamepad #endif #ifdef WithVkLayer diff --git a/packaging/windows/stage-pf-vdisplay.ps1 b/packaging/windows/stage-pf-vdisplay.ps1 index 5b976fb..587ef62 100644 --- a/packaging/windows/stage-pf-vdisplay.ps1 +++ b/packaging/windows/stage-pf-vdisplay.ps1 @@ -1,20 +1,20 @@ <# .SYNOPSIS - Stage the pf-vdisplay driver bundle the installer ships into -OutDir: the VENDORED signed pf-vdisplay - driver + the fetched nefcon device tool. + Stage the pf-vdisplay driver bundle the installer ships into -OutDir: the freshly-built signed + pf-vdisplay driver (from -VendorDir) + the fetched nefcon device tool. .DESCRIPTION - pf-vdisplay (our all-Rust IddCx virtual display) is built from packaging/windows/drivers/, 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/drivers/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 + + pf-vdisplay (our all-Rust IddCx virtual display) is BUILT FROM SOURCE per release by + build-pf-vdisplay.ps1 (packaging/windows/drivers/), which emits the signed pf_vdisplay.{dll,inf,cat} + + punktfunk-driver.cer into a build-output dir. pack-host-installer.ps1 passes that dir here as + -VendorDir; we copy it + add the nefcon tool. (The old checked-in binaries under + packaging/windows/pf-vdisplay/ were retired - building from source keeps the .dll/.inf/.cat in + lockstep; see design/windows-build-and-packaging.md.) 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 pf_vdisplay.inf/.cat/.dll + punktfunk-driver.cer - and nefconc.exe (x64). pack-host-installer.ps1 also drops install-pf-vdisplay.ps1 in. + and nefconc.exe (x64). .EXAMPLE pwsh -File stage-pf-vdisplay.ps1 -OutDir C:\t\out\stage @@ -22,7 +22,7 @@ [CmdletBinding()] param( [Parameter(Mandatory = $true)][string]$OutDir, - [string]$VendorDir = (Join-Path $PSScriptRoot 'pf-vdisplay'), + [Parameter(Mandatory = $true)][string]$VendorDir, # the build-pf-vdisplay.ps1 output dir # 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' @@ -34,11 +34,11 @@ $PSNativeCommandUseErrorActionPreference = $false if (Test-Path $OutDir) { Remove-Item -Recurse -Force $OutDir } New-Item -ItemType Directory -Force -Path $OutDir | Out-Null -# --- vendored pf-vdisplay driver -------------------------------------------------------------- +# --- built 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 drivers/deploy-dev.ps1" } +if (-not $inf) { throw "no pf_vdisplay.inf under $VendorDir - did build-pf-vdisplay.ps1 run?" } Copy-Item (Join-Path $VendorDir '*') $OutDir -Force -Write-Host "==> vendored pf-vdisplay staged from $VendorDir" +Write-Host "==> pf-vdisplay staged from $VendorDir" # --- nefcon (fetched + verified) -------------------------------------------------------------- $work = Join-Path ([IO.Path]::GetTempPath()) ('nefcon-' + [IO.Path]::GetRandomFileName()) diff --git a/scripts/ci/provision-windows-wdk.ps1 b/scripts/ci/provision-windows-wdk.ps1 index 7077d04..713dd53 100644 --- a/scripts/ci/provision-windows-wdk.ps1 +++ b/scripts/ci/provision-windows-wdk.ps1 @@ -52,31 +52,10 @@ if ($haveCargoWdk) { if ($LASTEXITCODE -ne 0) { throw "cargo install cargo-wdk failed ($LASTEXITCODE)" } } -# ---- 2b. LLVM 21.1.2 (libclang for wdk-sys bindgen) ---- -# wdk-sys's bindgen layout tests overflow (E0080 on threadlocaleinfostruct etc.) with LLVM ToT / dev -# (22+) builds — the runner's default C:\Program Files\LLVM. The windows-drivers-rs maintainers confirm -# the RELEASED LLVM 21.1.2 builds clean (discussion #591). Install it to a dedicated path so the client -# builds' LLVM is untouched; the driver-build CI job points LIBCLANG_PATH here. -$llvmDir = 'C:\llvm-21' -$libclang = Join-Path $llvmDir 'bin\libclang.dll' -if (Test-Path $libclang) { - info "LLVM 21.1.2 already present ($libclang) — skipping." -} else { - # Use the portable .tar.xz, NOT the NSIS .exe: the .exe /S silent install HANGS in the headless SYSTEM - # CI session (observed stuck >15 min after download, blocking the runner). Win11's bundled tar - # (bsdtar/libarchive) extracts .tar.xz; the tarball has one top-level dir, so --strip-components=1 - # lands bin/ at $llvmDir\bin. We only need libclang.dll + the clang resource dir for bindgen. - $url = 'https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.2/clang+llvm-21.1.2-x86_64-pc-windows-msvc.tar.xz' - $tmp = Join-Path $env:TEMP 'llvm-21.1.2-msvc.tar.xz' - info "Downloading LLVM 21.1.2 portable archive (~898 MB) -> $tmp" - & curl.exe -L --fail --retry 3 -o $tmp $url - if ($LASTEXITCODE -ne 0) { throw "LLVM archive download failed ($LASTEXITCODE)" } - info ("downloaded {0:N0} MB; extracting to $llvmDir (tar, strip 1)..." -f ((Get-Item $tmp).Length / 1MB)) - New-Item -ItemType Directory -Force -Path $llvmDir | Out-Null - & tar -xf $tmp -C $llvmDir --strip-components=1 - if ($LASTEXITCODE -ne 0) { throw "tar extract of LLVM failed ($LASTEXITCODE) — runner tar may lack .xz support" } - if (-not (Test-Path $libclang)) { throw "LLVM extract did not produce $libclang" } -} +# ---- 2b. (LLVM is NOT pinned) ---- +# The runner's default clang (C:\Program Files\LLVM) builds the driver workspace clean now that the +# vendored bindgen is 0.72 (the shipping pack proves it). LLVM 21.1.2 was briefly installed here to dodge +# a bindgen-0.71 layout-test overflow on clang 22; the 0.72 bump retired that pin. No LLVM install needed. # ---- 3. Verify (enumerate the REAL layout; fail only on build-essential absences) ---- Write-Host "" @@ -99,10 +78,11 @@ foreach ($t in 'inf2cat.exe','stampinf.exe','signtool.exe','makecat.exe','InfVer } try { $cw = (& cargo wdk --version 2>&1) -join ' ' } catch { $cw = '' } found 'cargo-wdk' $cw -found 'LLVM 21.1.2 libclang' ($(if (Test-Path $libclang) { $libclang } else { 'MISSING' })) +$defClang = 'C:\Program Files\LLVM\bin\libclang.dll' +found 'default libclang' ($(if (Test-Path $defClang) { $defClang } else { 'MISSING (clang not on the runner?)' })) -# Block only on the genuinely build-essential pieces (headers + iddcx + cargo-wdk + the pinned libclang). +# Block only on the genuinely build-essential pieces (headers + iddcx + cargo-wdk). # inf2cat arch quirks are non-fatal — cargo-wdk locates the WDK tools itself. -$essential = ($null -ne $umdfHdr) -and (Test-Path $kmDir) -and ($iddcxVers -ne '') -and ($cw -match 'wdk') -and (Test-Path $libclang) -if (-not $essential) { throw "provisioning incomplete: need wdf.h + km headers + iddcx + cargo-wdk + LLVM 21.1.2 (see above)" } -info "WDK + cargo-wdk + LLVM 21.1.2 provisioned OK. Driver builds pin Version_Number=$SdkVersion + LIBCLANG_PATH=$llvmDir\bin." +$essential = ($null -ne $umdfHdr) -and (Test-Path $kmDir) -and ($iddcxVers -ne '') -and ($cw -match 'wdk') +if (-not $essential) { throw "provisioning incomplete: need wdf.h + km headers + iddcx + cargo-wdk (see above)" } +info "WDK + cargo-wdk provisioned OK. Driver builds use Version_Number=$SdkVersion + the runner-default clang (bindgen 0.72)." diff --git a/scripts/windows/README.md b/scripts/windows/README.md index c75eab8..9d25044 100644 --- a/scripts/windows/README.md +++ b/scripts/windows/README.md @@ -50,9 +50,9 @@ and log in with the password the installer shows on its final page. To change it powershell -ExecutionPolicy Bypass -File scripts\windows\build-web.ps1 ``` -`bun install && bun run build`, installs the externalized server deps into `.output/server` -(with the `@unom` `.npmrc`), then restarts the `PunktfunkWeb` task and checks `:3000/login`. Use -this to iterate on the console against an installed host — `web-setup.ps1` (or a fresh install) is +`bun install && bun run build` (Nitro `noExternals` -> a self-contained `.output`, no +`node_modules`/`.npmrc`), then restarts the `PunktfunkWeb` task and checks `:3000/login`. Use +this to iterate on the console against an installed host - `web-setup.ps1` (or a fresh install) is what creates the task in the first place. ## Typical flow after pulling new code diff --git a/scripts/windows/build-web.ps1 b/scripts/windows/build-web.ps1 index 70ebba5..b06dc9d 100644 --- a/scripts/windows/build-web.ps1 +++ b/scripts/windows/build-web.ps1 @@ -23,7 +23,7 @@ if ($LASTEXITCODE -ne 0) { throw "web build failed (exit $LASTEXITCODE)" } Write-Host "restarting $task ..." & schtasks /end /tn $task 2>$null | Out-Null -Get-CimInstance Win32_Process -Filter "Name='bun.exe'" -ErrorAction SilentlyContinue | +Get-CimInstance Win32_Process -Filter "Name='bun.exe' OR Name='node.exe'" -ErrorAction SilentlyContinue | Where-Object { $_.CommandLine -match 'index\.mjs' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } Start-Sleep 2 diff --git a/web/vite.config.ts b/web/vite.config.ts index a2b4376..a6a31ca 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -48,9 +48,9 @@ export default defineConfig({ preset: "node-server", // BUNDLE every dependency into the server output (no externalized node_modules). Three wins: // (1) the .output tree drops from ~47k files / 730 MB (the whole untree-shaken @unom/ui dep - // tree — payload, lexical, date-fns…) to a handful of tree-shaken chunks; (2) it makes the - // output a self-contained graph `bun build --compile` can fold into ONE native binary (the - // Windows installer ships that instead of node + a node_modules forest); (3) it removes the + // tree — payload, lexical, date-fns…) to a handful of tree-shaken chunks; (2) the output is a + // self-contained ~75-file `.output` the bundled `bun` runs directly (the Windows installer + // ships bun + that `.output`, not node + a node_modules forest); (3) it removes the // bare external imports (`srvx`, `seroval`…) bun couldn't resolve at runtime — the reason we // used to need node. node still runs the same self-contained output for the Linux .deb. noExternals: true,