feat(windows): the brand reads Punktfunk on every device Windows shows
deb / build-publish-client-arm64 (push) Failing after 4s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 13s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 11s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 11s
ci / web (push) Successful in 1m53s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 13s
ci / docs-site (push) Successful in 2m3s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 15s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 30s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m24s
windows-drivers / driver-build (push) Successful in 2m30s
docker / builders-arm64cross (push) Successful in 6s
docker / deploy-docs (push) Successful in 29s
android / android (push) Successful in 5m7s
apple / swift (push) Canceled after 4m50s
apple / screenshots (push) Canceled after 0s
deb / build-publish (push) Successful in 4m42s
arch / build-publish (push) Canceled after 5m25s
ci / rust (push) Canceled after 5m26s
ci / rust-arm64 (push) Canceled after 5m31s
deb / build-publish-host (push) Canceled after 5m19s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 3m30s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 3m26s
windows-host / package (push) Canceled after 2m29s
windows-host / winget-source (push) Canceled after 0s
windows-drivers / probe-and-proto (push) Successful in 37s
deb / build-publish-client-arm64 (push) Failing after 4s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 13s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 11s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 11s
ci / web (push) Successful in 1m53s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 13s
ci / docs-site (push) Successful in 2m3s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 15s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 30s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m24s
windows-drivers / driver-build (push) Successful in 2m30s
docker / builders-arm64cross (push) Successful in 6s
docker / deploy-docs (push) Successful in 29s
android / android (push) Successful in 5m7s
apple / swift (push) Canceled after 4m50s
apple / screenshots (push) Canceled after 0s
deb / build-publish (push) Successful in 4m42s
arch / build-publish (push) Canceled after 5m25s
ci / rust (push) Canceled after 5m26s
ci / rust-arm64 (push) Canceled after 5m31s
deb / build-publish-host (push) Canceled after 5m19s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 3m30s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 3m26s
windows-host / package (push) Canceled after 2m29s
windows-host / winget-source (push) Canceled after 0s
windows-drivers / probe-and-proto (push) Successful in 37s
Device Manager, the firewall list and the monitor name all said "punktfunk". The brand
is Punktfunk.
Renamed: the [Strings] blocks of all four driver INFs (device descriptions, install
disks, provider, manufacturer), the `description` on every SwDeviceProfile the host
creates, pf-mouse's HID manufacturer + product strings, pf-vdisplay's IddCx endpoint
friendly + manufacturer names, the EDID 0xFC display-name descriptor — so Windows now
shows `Generic Monitor (Punktfunk)` — and the netsh firewall rule names.
The EDID edit is a single byte (0x70 -> 0x50) and needs no hand-patched checksum:
Edid::generate_with already recomputes both block checksums after patching the serial.
Deliberately left lowercase, because these are IDENTITIES rather than display names and
renaming them would orphan installed state:
* the SwDeviceCreate enumerator `w!("punktfunk")` — it IS the SWD\PUNKTFUNK\... path
every pad instance id is built from
* pf-paths' `join("punktfunk")` — C:\ProgramData\punktfunk
* the CN=punktfunk-driver cert subject, which purge_driver_certs and both driver build
scripts match by string
* install.rs' `lo.contains("punktfunk virtual display")` probes, whose haystack is
to_ascii_lowercase()d, so they already match the capitalised name
Nothing is orphaned by the renames that DID happen either: netsh rule names,
Get-NetFirewallRule -DisplayName and PowerShell's -match are all case-insensitive, so
the firewall delete paths and reset-pf-vdisplay.ps1's -AdapterName / -GhostMatch
defaults still reap what every release up to 0.22.1 created.
Cosmetic, with two consequences worth knowing: it takes a driver rebuild + re-sign to
appear at all, and an existing devnode keeps its cached FriendlyName until it is
recreated.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -393,7 +393,7 @@ impl WinDsIdentity {
|
||||
// child, no channel proof, and a pad no game ever saw. `hwid_matches_inf` pins it now.
|
||||
hwid: "pf_dualsense",
|
||||
usb_vid_pid: "VID_054C&PID_0CE6",
|
||||
description: "punktfunk Virtual DualSense",
|
||||
description: "Punktfunk Virtual DualSense",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ impl WinDsIdentity {
|
||||
instance_prefix: "pf_edge",
|
||||
hwid: "pf_dualsenseedge",
|
||||
usb_vid_pid: "VID_054C&PID_0DF2",
|
||||
description: "punktfunk Virtual DualSense Edge",
|
||||
description: "Punktfunk Virtual DualSense Edge",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -644,7 +644,7 @@ pub fn deck_spike_hold(index: u8, secs: u64) -> Result<()> {
|
||||
// The Deck's controller interface — the promotion gate the first spike run hit
|
||||
// (hidapi parses MI_ from the child hwids; absent = interface 0, Steam wants 2).
|
||||
usb_mi: Some(2),
|
||||
description: "punktfunk Virtual Steam Deck (spike)",
|
||||
description: "Punktfunk Virtual Steam Deck (spike)",
|
||||
})?;
|
||||
// The spike drives a real pad channel, so it takes the same devnode-proved delivery a session
|
||||
// pad does — no special case, and no reason for a bring-up tool to run on the old trust.
|
||||
|
||||
@@ -73,7 +73,7 @@ impl Ds4WinPad {
|
||||
hwid: DS4_HWID,
|
||||
usb_vid_pid: "VID_054C&PID_09CC",
|
||||
usb_mi: None,
|
||||
description: "punktfunk Virtual DualShock 4",
|
||||
description: "Punktfunk Virtual DualShock 4",
|
||||
})?; // Propagate, do NOT swallow — see below.
|
||||
let (hsw, instance_id) = (Some(hsw), instance_id);
|
||||
// Swallowing a create failure here (the previous behaviour) latched the pad slot to
|
||||
|
||||
@@ -56,7 +56,7 @@ fn create_swdevice(index: u8) -> Result<(HSWDEVICE, Option<String>)> {
|
||||
.encode_utf16()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
let desc: Vec<u16> = "punktfunk Virtual Xbox 360 (XUSB)"
|
||||
let desc: Vec<u16> = "Punktfunk Virtual Xbox 360 (XUSB)"
|
||||
.encode_utf16()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
@@ -66,7 +66,7 @@ impl VirtualMouse {
|
||||
// a mouse (nothing fingerprints them); reusing the shared profile keeps one code path.
|
||||
usb_vid_pid: "VID_5046&PID_4D4F",
|
||||
usb_mi: None,
|
||||
description: "punktfunk Virtual Mouse",
|
||||
description: "Punktfunk Virtual Mouse",
|
||||
}) {
|
||||
Ok((h, i)) => (Some(h), i),
|
||||
Err(e) => {
|
||||
@@ -386,7 +386,7 @@ pub fn channel_proof_probe() -> Result<()> {
|
||||
hwid: "pf_mouse",
|
||||
usb_vid_pid: "VID_5046&PID_4D4F",
|
||||
usb_mi: None,
|
||||
description: "punktfunk Virtual Mouse (channel-proof probe)",
|
||||
description: "Punktfunk Virtual Mouse (channel-proof probe)",
|
||||
})?;
|
||||
let _sw = super::gamepad_raii::SwDevice::new(hsw);
|
||||
let Some(instance_id) = instance_id else {
|
||||
|
||||
@@ -80,7 +80,7 @@ impl DeckWinPad {
|
||||
// token, hidapi reports interface 0, and Steam never claims the pad (the N4
|
||||
// spike's run-1 failure).
|
||||
usb_mi: Some(2),
|
||||
description: "punktfunk Virtual Steam Deck",
|
||||
description: "Punktfunk Virtual Steam Deck",
|
||||
})?; // Propagate — swallowing latched the slot to a pad with no devnode (see the DS4 twin).
|
||||
let (hsw, instance_id) = (Some(hsw), instance_id);
|
||||
// The DATA section goes to whoever THIS devnode says is serving it — not to whatever pid
|
||||
|
||||
@@ -92,7 +92,7 @@ unsafe fn ioctl(h: HANDLE, code: u32, input: &[u8], output: &mut [u8]) -> Result
|
||||
}
|
||||
|
||||
/// Reap the ghost (NOT-present) "punktfunk" virtual-monitor device nodes that `IddCxMonitorDeparture`
|
||||
/// leaves behind. Each departed monitor leaves a not-present "Generic Monitor (punktfunk)" PDO that keeps
|
||||
/// leaves behind. Each departed monitor leaves a not-present "Generic Monitor (Punktfunk)" PDO that keeps
|
||||
/// pinning an OS VidPN target against the IddCx adapter's fixed monitor-slot budget; once ~16 accumulate,
|
||||
/// `IOCTL_ADD` wedges at 0x80070490 (`ERROR_NOT_FOUND`) and every session black-screens until a manual
|
||||
/// reset/reboot. Removing the not-present PDOs frees the slots — the in-process equivalent of
|
||||
@@ -532,7 +532,7 @@ impl VdisplayDriver for PfVdisplayDriver {
|
||||
tracing::warn!("pf-vdisplay IOCTL_CLEAR_ALL failed on startup (continuing)");
|
||||
}
|
||||
// CLEAR_ALL only departs the driver's own (in-process) monitor list; it can NOT remove the
|
||||
// OS-side not-present "Generic Monitor (punktfunk)" PDOs that a previous host-run's monitor
|
||||
// OS-side not-present "Generic Monitor (Punktfunk)" PDOs that a previous host-run's monitor
|
||||
// departures left behind. Reap those here so a fresh host start begins with a clean IddCx
|
||||
// monitor-slot budget — prevents the 0x80070490 slot-exhaustion wedge from carrying across
|
||||
// restarts (the reason a restart's CLEAR_ALL alone never recovered it before).
|
||||
|
||||
@@ -471,7 +471,7 @@ fn web_setup(args: &[String]) -> Result<()> {
|
||||
"firewall",
|
||||
"delete",
|
||||
"rule",
|
||||
"name=punktfunk web console (TCP 47992)",
|
||||
"name=Punktfunk web console (TCP 47992)",
|
||||
],
|
||||
);
|
||||
if !run_quiet(
|
||||
@@ -481,7 +481,7 @@ fn web_setup(args: &[String]) -> Result<()> {
|
||||
"firewall",
|
||||
"add",
|
||||
"rule",
|
||||
"name=punktfunk web console (TCP 47992)",
|
||||
"name=Punktfunk web console (TCP 47992)",
|
||||
"dir=in",
|
||||
"action=allow",
|
||||
"protocol=TCP",
|
||||
|
||||
@@ -995,7 +995,7 @@ fn add_firewall_rules(allow_public: bool) {
|
||||
("UDP", "UDP", "47998-48010,9777,5353"),
|
||||
];
|
||||
for (suffix, proto, ports) in rules {
|
||||
let name = format!("punktfunk {suffix}");
|
||||
let name = format!("Punktfunk {suffix}");
|
||||
let ok = run_quiet(
|
||||
"netsh",
|
||||
&[
|
||||
@@ -1028,7 +1028,9 @@ fn add_firewall_rules(allow_public: bool) {
|
||||
|
||||
fn remove_firewall_rules() {
|
||||
for suffix in ["TCP", "UDP"] {
|
||||
let name = format!("punktfunk {suffix}");
|
||||
// Capital P is the brand; netsh matches a rule name case-INSENSITIVELY, so this still
|
||||
// reaps the lowercase rules every release up to 0.22.1 created — no orphans on upgrade.
|
||||
let name = format!("Punktfunk {suffix}");
|
||||
let _ = run_quiet(
|
||||
"netsh",
|
||||
&[
|
||||
|
||||
@@ -90,13 +90,13 @@ ServiceBinary="%13%\pf_gamepad.dll"
|
||||
pf_gamepad.dll
|
||||
|
||||
[Strings]
|
||||
ProviderString ="punktfunk"
|
||||
ManufacturerString ="punktfunk"
|
||||
ProviderString ="Punktfunk"
|
||||
ManufacturerString ="Punktfunk"
|
||||
ClassName ="HID device"
|
||||
Disk_Description ="punktfunk Gamepad Installation Disk"
|
||||
Disk_Description ="Punktfunk Gamepad Installation Disk"
|
||||
; One per hardware id — these are what Device Manager shows. Keep them aligned with the product
|
||||
; strings the driver serves per device_type (src/lib.rs `on_get_string`).
|
||||
DeviceDesc ="punktfunk Virtual DualSense"
|
||||
DeviceDescDS4 ="punktfunk Virtual DualShock 4"
|
||||
DeviceDescEdge ="punktfunk Virtual DualSense Edge"
|
||||
DeviceDescDeck ="punktfunk Virtual Steam Deck Controller"
|
||||
DeviceDesc ="Punktfunk Virtual DualSense"
|
||||
DeviceDescDS4 ="Punktfunk Virtual DualShock 4"
|
||||
DeviceDescEdge ="Punktfunk Virtual DualSense Edge"
|
||||
DeviceDescDeck ="Punktfunk Virtual Steam Deck Controller"
|
||||
|
||||
@@ -72,8 +72,8 @@ ServiceBinary="%13%\pf_mouse.dll"
|
||||
pf_mouse.dll
|
||||
|
||||
[Strings]
|
||||
ProviderString ="punktfunk"
|
||||
ManufacturerString ="punktfunk"
|
||||
ProviderString ="Punktfunk"
|
||||
ManufacturerString ="Punktfunk"
|
||||
ClassName ="HID device"
|
||||
Disk_Description ="punktfunk Mouse Installation Disk"
|
||||
DeviceDesc ="punktfunk Virtual Mouse"
|
||||
Disk_Description ="Punktfunk Mouse Installation Disk"
|
||||
DeviceDesc ="Punktfunk Virtual Mouse"
|
||||
|
||||
@@ -428,14 +428,14 @@ fn on_get_string(request: &Request) -> NTSTATUS {
|
||||
};
|
||||
let string_id = id_val & 0xFFFF;
|
||||
let s: String = match string_id {
|
||||
0 | 0x000E => "punktfunk".into(),
|
||||
0 | 0x000E => "Punktfunk".into(),
|
||||
// (2) The SERIAL carries the channel proof — the one transport measured to reach a UMDF HID
|
||||
// minidriver from user mode (`HidD_GetSerialNumberString`, zero-access handle, verified on
|
||||
// .173). Safe HERE and only here: nothing reads the virtual mouse's serial, whereas the pads'
|
||||
// serials are what SDL and Steam dedup controllers on. The old value was the inert
|
||||
// "PFMOUSE00"; the proof text is just as inert and does the security work.
|
||||
2 | 0x0010 => ChannelProof::new(CHANNEL.index(), std::process::id()).to_hid_string(),
|
||||
_ => "punktfunk Virtual Mouse".into(),
|
||||
_ => "Punktfunk Virtual Mouse".into(),
|
||||
};
|
||||
let mut wide: Vec<u8> = Vec::with_capacity(s.len() * 2 + 2);
|
||||
for u in s.encode_utf16() {
|
||||
|
||||
@@ -75,10 +75,10 @@ UMDriverCopy=12,UMDF
|
||||
pf_vdisplay.dll
|
||||
|
||||
[Strings]
|
||||
ManufacturerName="punktfunk"
|
||||
DiskName="punktfunk Virtual Display Installation Disk"
|
||||
ManufacturerName="Punktfunk"
|
||||
DiskName="Punktfunk Virtual Display Installation Disk"
|
||||
WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector"
|
||||
DeviceName="punktfunk Virtual Display"
|
||||
DeviceName="Punktfunk Virtual Display"
|
||||
|
||||
REG_MULTI_SZ=0x00010000
|
||||
REG_SZ=0x00000000
|
||||
|
||||
@@ -82,8 +82,8 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS {
|
||||
diag.Size = core::mem::size_of::<iddcx::IDDCX_ENDPOINT_DIAGNOSTIC_INFO>() as u32;
|
||||
diag.GammaSupport = iddcx::IDDCX_FEATURE_IMPLEMENTATION::IDDCX_FEATURE_IMPLEMENTATION_NONE;
|
||||
diag.TransmissionType = iddcx::IDDCX_TRANSMISSION_TYPE::IDDCX_TRANSMISSION_TYPE_WIRED_OTHER;
|
||||
diag.pEndPointFriendlyName = wstr!("punktfunk Virtual Display Adapter");
|
||||
diag.pEndPointManufacturerName = wstr!("punktfunk");
|
||||
diag.pEndPointFriendlyName = wstr!("Punktfunk Virtual Display Adapter");
|
||||
diag.pEndPointManufacturerName = wstr!("Punktfunk");
|
||||
diag.pEndPointModelName = wstr!("Virtual Display");
|
||||
// SAFETY: `version` is a stack local that outlives this `init_adapter` call; IddCxAdapterInitAsync
|
||||
// (below) reads through these pointers SYNCHRONOUSLY, before `version` drops — the pointer never escapes.
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
//! made "Use HDR" never appear for the virtual display). The base block declares EDID 1.4 + 10-bit
|
||||
//! digital so the panel's bit depth is unambiguous.
|
||||
//!
|
||||
//! Identity: manufacturer "PNK" (bytes 8-9), product name "punktfunk" (the 0xFC display descriptor). The
|
||||
//! Identity: manufacturer "PNK" (bytes 8-9), product name "Punktfunk" (the 0xFC display descriptor —
|
||||
//! this is what Windows shows as `Generic Monitor (Punktfunk)`; byte 127's checksum is recomputed in
|
||||
//! [`Edid::generate_with`], so editing the name here needs no hand-patched checksum). The
|
||||
//! serial-number field (base offset 0x0C, little-endian) encodes the per-monitor index so
|
||||
//! `parse_monitor_description` can map an EDID the OS hands back to its monitor; [`Edid::generate_with`]
|
||||
//! patches that serial and recomputes BOTH block checksums (base byte 127 + extension byte 255). The
|
||||
@@ -34,7 +36,7 @@ const BASE: [u8; 128] = [
|
||||
0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E,
|
||||
0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 0xF0, 0x0F, // display range-limits descriptor
|
||||
0xFF, 0x0F, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x70, // name descriptor "punktfunk"
|
||||
0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x50, // name descriptor "Punktfunk"
|
||||
0x75, 0x6E, 0x6B, 0x74, 0x66, 0x75, 0x6E, 0x6B,
|
||||
0x0A, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, // empty 4th descriptor...
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
@@ -58,7 +58,7 @@ UmdfLibraryVersion=$UMDFVERSION$
|
||||
ServiceBinary=%13%\pf_xusb.dll
|
||||
|
||||
[Strings]
|
||||
ProviderString = "punktfunk"
|
||||
ProviderString = "Punktfunk"
|
||||
StdMfg = "(Standard system devices)"
|
||||
DiskId1 = "punktfunk XUSB Installation Disk"
|
||||
DeviceDesc = "punktfunk Virtual Xbox 360 (XUSB)"
|
||||
DiskId1 = "Punktfunk XUSB Installation Disk"
|
||||
DeviceDesc = "Punktfunk Virtual Xbox 360 (XUSB)"
|
||||
|
||||
@@ -351,7 +351,7 @@ Filename: "{app}\punktfunk-host.exe"; Parameters: "driver uninstall --gamepad";
|
||||
; Stop + remove the PunktfunkWeb task and its firewall rule (leaves %ProgramData%\punktfunk config,
|
||||
; like the host uninstall does).
|
||||
Filename: "powershell.exe"; \
|
||||
Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Stop-ScheduledTask -TaskName PunktfunkWeb -ErrorAction SilentlyContinue; Get-NetTCPConnection -LocalPort 47992,3000 -State Listen -ErrorAction SilentlyContinue | ForEach-Object {{ Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }; Unregister-ScheduledTask -TaskName PunktfunkWeb -Confirm:$false -ErrorAction SilentlyContinue; Get-NetFirewallRule -DisplayName 'punktfunk web console (*' -ErrorAction SilentlyContinue | Remove-NetFirewallRule"""; \
|
||||
Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Stop-ScheduledTask -TaskName PunktfunkWeb -ErrorAction SilentlyContinue; Get-NetTCPConnection -LocalPort 47992,3000 -State Listen -ErrorAction SilentlyContinue | ForEach-Object {{ Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }; Unregister-ScheduledTask -TaskName PunktfunkWeb -Confirm:$false -ErrorAction SilentlyContinue; Get-NetFirewallRule -DisplayName 'Punktfunk web console (*' -ErrorAction SilentlyContinue | Remove-NetFirewallRule"""; \
|
||||
Flags: runhidden waituntilterminated; RunOnceId: "PunktfunkWebCleanup"
|
||||
#endif
|
||||
#ifdef WithScripting
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
.DESCRIPTION
|
||||
Sustained connect/disconnect churn (e.g. a client reconnect loop x the host's 8 pipeline-build
|
||||
retries - ~100 ADD/REMOVE cycles) exhausts the driver's IddCx monitor slots: the per-monitor
|
||||
target_ids climb, ghost "Generic Monitor (punktfunk)" device nodes pile up, and eventually
|
||||
target_ids climb, ghost "Generic Monitor (Punktfunk)" device nodes pile up, and eventually
|
||||
IOCTL_ADD returns 0x80070490 ERROR_NOT_FOUND ("Element nicht gefunden"). Every session then fails
|
||||
to create a virtual output -> the client gets a hard blackscreen. A host-service restart's
|
||||
IOCTL_CLEAR_ALL does NOT recover it; the driver instance itself must be reloaded.
|
||||
@@ -16,16 +16,16 @@
|
||||
1. Stop the host service (it holds the driver's control device).
|
||||
2. pnputil /remove-device the GHOST (Status != OK = not-present) punktfunk virtual-monitor nodes
|
||||
that accumulated - the root of the slot exhaustion.
|
||||
3. Disable + Enable the pf-vdisplay adapter (ROOT\DISPLAY\*, "punktfunk Virtual Display") to
|
||||
3. Disable + Enable the pf-vdisplay adapter (ROOT\DISPLAY\*, "Punktfunk Virtual Display") to
|
||||
reload the IddCx driver instance and reset its monitor list. (Restart-PnpDevice does NOT exist
|
||||
on this box's PowerShell, so we disable+enable explicitly.)
|
||||
4. Restart the host service.
|
||||
Avoids a reboot on purpose (this box boots to Proxmox).
|
||||
|
||||
.PARAMETER Service Host service name. Default PunktfunkHost.
|
||||
.PARAMETER AdapterName FriendlyName substring of the IddCx adapter to cycle. Default "punktfunk
|
||||
.PARAMETER AdapterName FriendlyName substring of the IddCx adapter to cycle. Default "Punktfunk
|
||||
Virtual Display" (NOT SudoVDA's "SudoMaker Virtual Display Adapter").
|
||||
.PARAMETER GhostMatch FriendlyName substring of the virtual monitors to reap. Default "punktfunk".
|
||||
.PARAMETER GhostMatch FriendlyName substring of the virtual monitors to reap. Default "Punktfunk".
|
||||
.PARAMETER KeepGhosts Skip the ghost-node cleanup; only cycle the adapter.
|
||||
.PARAMETER NoHost Don't stop/start the host service (just reset the driver) - used by
|
||||
redeploy-pf-vdisplay.ps1, which manages the service itself.
|
||||
@@ -41,8 +41,8 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Service = 'PunktfunkHost',
|
||||
[string]$AdapterName = 'punktfunk Virtual Display',
|
||||
[string]$GhostMatch = 'punktfunk',
|
||||
[string]$AdapterName = 'Punktfunk Virtual Display',
|
||||
[string]$GhostMatch = 'Punktfunk',
|
||||
[switch]$KeepGhosts,
|
||||
[switch]$NoHost,
|
||||
[switch]$Verify,
|
||||
|
||||
Reference in New Issue
Block a user