mirror of
https://github.com/fstat13/PSCapture.git
synced 2026-10-17 18:02:05 +02:00
- custom-chrome dark window: painted title bar (minimize/close), rounded region, owner-drawn buttons, status pill with state dot, dark console pane - installer: verified writes (write -> check -> report), in-process LoadLibrary + DllRegisterServer with real HRESULT reporting; no more cryptic rundll32 'module not found' - driver check verifies the registered dll still exists on disk - feeder reports 'IN ATTESA DELLA PS5' when the console is unreachable - log file next to the exe with %TEMP% fallback - docs: installer + engineering log (B6, B7, lesson 8)
102 lines
4.4 KiB
Markdown
102 lines
4.4 KiB
Markdown
# How the PSCapture installer works
|
||
|
||
There is no separate installer: **`PSCapture.exe` installs itself**. Everything
|
||
happens on the first launch, in four steps, from one window.
|
||
|
||
```
|
||
launch ─► self-elevate (UAC) ─► driver check ─► install (once) ─► deploy payload ─► stream
|
||
```
|
||
|
||
---
|
||
|
||
## Step 0 — Self-elevation (no manifest tricks)
|
||
|
||
On startup the app calls `CheckTokenMembership` against the *Administrators*
|
||
group. If it is not elevated it re-launches itself through
|
||
`ShellExecuteEx(…, "runas", …)` — the standard UAC prompt — and the elevated
|
||
instance takes over. No manifest is embedded, so the executable stays a plain
|
||
single file.
|
||
|
||
## Step 1 — Is the driver installed?
|
||
|
||
Checked by a single registry probe:
|
||
|
||
```
|
||
HKEY_CLASSES_ROOT\CLSID\{50533543-414d-4def-9b0e-192080102030}\InprocServer32
|
||
```
|
||
|
||
That CLSID is the virtual capture card's DirectShow filter. If the key exists,
|
||
the driver is considered installed and this step is skipped.
|
||
|
||
## Step 2 — Installing the driver (first run only)
|
||
|
||
1. Creates `%ProgramFiles%\PSCapture`.
|
||
2. **Extracts `pscapture.dll` from its own resources** (the driver travels
|
||
embedded inside the executable, resource `RCDATA` n.3) and writes it
|
||
there. It also copies itself, so the installed folder is self-contained
|
||
— the distributed installer is literally **one file**.
|
||
3. Registers the filter by loading the dll into the app itself and calling
|
||
`DllRegisterServer` directly. *(Earlier builds shelled out to `rundll32`,
|
||
which turned a missing dll into a cryptic "the specified module could not
|
||
be found" dialog; the in-process call returns real error codes.)* Every
|
||
step is checked: if the dll could not be written (not elevated, no
|
||
rights), the app says so instead of attempting a doomed registration.
|
||
|
||
DllRegisterServer writes the COM registration for the filter CLSID,
|
||
including the **DevicePath** entry that modern capture consumers
|
||
(Chromium/Discord media engine among them) use to pick the device.
|
||
DllUnregisterServer removes it - that is the uninstall path today
|
||
(delete the folder + call it).
|
||
|
||
## Step 3 — Deploying the console payload
|
||
|
||
The payload (`pscapture.elf`) ships **inside the executable** as a Windows
|
||
`RCDATA` resource — no loose files to lose. Two paths are used, in order:
|
||
|
||
1. **Autoloader** (persistence): over anonymous FTP (port 2121) the app
|
||
creates `/data/pldmgr/payloads/pscapture/` on the console and uploads
|
||
`pscapture.elf` there, so the jailbreak's autoloader starts it on every
|
||
boot.
|
||
2. **Immediate start** (this session): the same bytes are pushed to the
|
||
payload loader on TCP port **9021**; the app reads back the console log
|
||
and prints it in the window. The console shows the system notification
|
||
**“PSCapture is streaming on:PORT”**.
|
||
|
||
## Step 4 — Streaming (the feeder)
|
||
|
||
The feeder lives inside the app (a worker thread), no background services:
|
||
|
||
1. reads the stream port from `/data/pscapture.port` (FTP),
|
||
2. connects to the console over TCP and receives **NV12 1920×1080** frames,
|
||
3. applies the live **gain** and **shift px** settings from
|
||
`pscapture.ini` (re-read every ~30 frames — changes are instant),
|
||
4. publishes each frame into the shared memory ring `Local\Ps5CamShm`,
|
||
where the driver picks it up for any consumer (Discord, OBS, ffmpeg…).
|
||
|
||
Closing the app stops the feeder; the camera freezes on the last frame and
|
||
reconnects automatically the next time you press **Start**.
|
||
|
||
---
|
||
|
||
## Files and locations touched
|
||
|
||
| Where | What |
|
||
|---|---|
|
||
| `%ProgramFiles%\PSCapture\` | `pscapture.exe` (self-contained) + the `pscapture.dll` it extracts |
|
||
| Registry `HKCR\CLSID\{50533543-…-192080102030}` | the capture-card filter registration |
|
||
| Console `/data/pldmgr/payloads/pscapture/pscapture.elf` | payload (autoloader) |
|
||
| Console `/data/pscapture.port` | stream port announced by the payload |
|
||
| Console `/data/pscapture.log` | payload log (FTP-readable) |
|
||
| Next to the exe: `pscapture.ini` | `IP`, `GAIN`, `SHIFT` settings |
|
||
|
||
## Notes
|
||
|
||
- No Windows service, no scheduled task, no kernel driver: the capture card
|
||
is a user-space DirectShow filter, the feeder dies with the app.
|
||
- The console side never needs configuration through the PS5 menus: the
|
||
payload and the app handle everything.
|
||
- Uninstall = stop the app, run
|
||
`rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer`,
|
||
delete the folder (and optionally `/data/pldmgr/payloads/pscapture/` on the
|
||
console). A one-click uninstaller is on the roadmap.
|