mirror of https://github.com/stascorp/rdpwrap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
4.2 KiB
80 lines
4.2 KiB
# RdpCoexist
|
|
|
|
A small, portable **governance/ops shell** that lets **AnyDesk and RDP run side by
|
|
side** (concurrent RDP sessions + local console) on modern Windows — **without
|
|
modifying `System32\termsrv.dll` on disk**.
|
|
|
|
It does *not* reimplement the wrapper. It drives
|
|
[`sergiye/rdpWrapper`](https://github.com/sergiye/rdpWrapper) (a portable, .NET
|
|
Framework 4.7.2, single-file rewrite of RDP Wrapper that redirects the
|
|
`TermService` `ServiceDll` to a non-destructive proxy — `TermWrap` — with a
|
|
built-in offset engine) and wraps it with the operational pieces it lacks.
|
|
|
|
> Approach: stop RDP service → point `TermService` `ServiceDll` at a wrapper in a
|
|
> portable folder → set `fDenyTSConnections=0`, `fSingleSessionPerUser=0`,
|
|
> `EnableConcurrentSessions=1` → start service. The original `termsrv.dll` is
|
|
> **never touched**, so SFC / WRP / Windows Update leave it alone.
|
|
|
|
## Why a shell (the 5 gaps this closes)
|
|
|
|
| # | Gap in the bare engine | What this shell adds |
|
|
|---|------------------------|----------------------|
|
|
| 1 | No license grant → cannot repackage/redistribute the engine binary | Engine is **fetched from its official release** and **SHA256-pinned**; nothing is bundled here (`.gitignore` blocks `*.exe`/`*.dll`) |
|
|
| 2 | No self-heal after Windows Update replaces `termsrv.dll` | `-Heal` + a **SYSTEM startup scheduled task**: verify, and only re-install if the listener dropped |
|
|
| 3 | Verification is GUI-only | `-Verify` returns a **machine-checkable verdict** (`COEXIST-OK` requires a real listener **and** ≥2 active sessions, not just registry values) |
|
|
| 4 | Engine phones home for updates → version drift | Engine is **always** invoked with `-offline`; version is pinned in `config.psd1` |
|
|
| 5 | Engine DLL is commonly flagged `HackTool:Win32/RDPWrap` | Idempotent **Defender exclusion** for the engine folder (skipped gracefully if exclusions are policy-locked) |
|
|
|
|
## Layout
|
|
|
|
```
|
|
RdpCoexist/
|
|
├─ RdpCoexist.cmd self-elevating launcher (UAC)
|
|
├─ RdpCoexist.ps1 -Apply | -Revert | -Verify | -Heal | -Status
|
|
├─ config.psd1 version pin, SHA256 pin, paths, options
|
|
└─ modules/
|
|
├─ Common.psm1 logging, admin check, GPO-override warning
|
|
├─ Engine.psm1 download + hash-verify + drive the engine
|
|
├─ Defender.psm1 idempotent exclusion add/remove
|
|
├─ Verify.psm1 listener + active-session verdict
|
|
├─ Heal.psm1 scheduled-task register/unregister
|
|
└─ LocalUser.psm1 optional dedicated RDP account
|
|
```
|
|
Engine binary, logs, and state live under `%ProgramData%\RdpCoexist\` — never in this repo.
|
|
|
|
## Usage
|
|
|
|
1. Edit `config.psd1`. At minimum set **`EngineSha256`** to the hash of the engine
|
|
release you vetted (or run the first `-Apply` with `-TrustOnFirstUse`, which
|
|
prints the observed hash for you to paste back and lock).
|
|
2. Run:
|
|
|
|
```
|
|
RdpCoexist.cmd -Apply :: fetch+verify engine, install, register heal task, verify
|
|
RdpCoexist.cmd -Verify :: print current verdict
|
|
RdpCoexist.cmd -Revert :: uninstall engine, remove task + exclusion
|
|
```
|
|
|
|
`COEXIST-OK` only appears once **two** sessions are actually active (e.g. console +
|
|
one RDP), because a listener alone does not prove coexistence.
|
|
|
|
## Requirements & caveats
|
|
|
|
- **Admin** required (the launcher elevates).
|
|
- **.NET Framework 4.7.2** — built into supported Windows 10/11; no install needed.
|
|
- **Domain GPO**: if `fSingleSessionPerUser` / `fDenyTSConnections` are enforced by
|
|
policy, they revert on GP refresh. The shell warns; resolve with IT.
|
|
- **Same-user dual session** trips license locks in OneDrive/Outlook/Office. Prefer
|
|
the optional dedicated RDP account (`CreateRdpUser`), keeping the console user for AnyDesk.
|
|
- **Portability vs. resilience**: the engine is copied under `%ProgramData%` by
|
|
default. Pointing `ServiceDll` at removable media means RDP dies if the media is
|
|
pulled — don't.
|
|
- Concurrent-session enablement changes the effective RDP session limit; confirm your
|
|
own licensing position before use.
|
|
|
|
## Configuration keys
|
|
|
|
See `config.psd1` for the annotated list. Values shipped here are **neutral
|
|
placeholders** — set the version pin, hash pin, and (if used) the RDP user name to
|
|
your own before running.
|