Switch 2 Pro USB Windows owned-composite transport¶
Status: production-selected by Switch2ProUsbProductionCoordinator and
offline-tested. ControlService now constructs this adapter for an admitted
057E:2069/bcdDevice 0x0201 exact composite. No controller I/O was performed
while making or validating the current revision.
Evidence boundary¶
The transport was reconciled against these pinned reference revisions:
| Reference | Pin | Use |
|---|---|---|
| Switch2Connect | 4487322a306f04efa27682e3f3a508635a84fd98 |
USB interface/pipe and request-order corroboration |
| SDL current | c71abd08605b8bb7078372307a93274725c99fe0 |
independent USB startup/output corroboration |
| SDL hifihedgehog fork | d98c5804a9d20b0d96e993741797878c86b8f1e1 |
independent fork comparison |
The implementation is original DS4Windows GPL code. The references establish
the exact admitted topology already frozen by the repository: MI_00 HID input
and 64-byte output, plus MI_01 WinUSB bulk OUT 0x02 and bulk IN 0x82. They do
not by themselves establish a causally valid response tuple for the two USB
feature requests. A separate authorized hardware capture established the exact
step-specific 00/F8 responses now enforced by
Switch2UsbCommandCodec.TryValidateFeatureResponse. The concrete command lease
therefore performs an exact write/read/validate pair for both feature steps and
for the capture-backed Player-1 LED request; it still rejects SDL's unchecked
read as proof and does not borrow Bluetooth response semantics.
One physical owner¶
Switch2ProUsbWindowsOwnedCompositeAdapter reserves the opaque physical
container before opening anything. Before a lease can escape it:
- discovers one exact admitted MI_00/MI_01 pair;
- opens one overlapped MI_00
SafeFileHandlewith read/write access; - opens one overlapped MI_01 file and adopts one exact WinUSB lifetime;
- re-enumerates and matches the complete private Windows identity while both handles remain retained; and
- transfers the reservation and both handles into one lease object.
That revalidation is the final discovery for the lifetime. After escape, input, HID output, command output, command input, cancellation, and disposal operate only on retained handles. There is no path rediscovery and no second HID or WinUSB handle.
The existing public Switch2ProUsbWindowsAdapter remains the legacy read-only
discovery/open path. Production Switch 2 Pro USB registration uses the
full-duplex adapter through Switch2ProUsbProductionCoordinator.
Cleanup ambiguity is ownership, not an ordinary failed open. After a container reservation exists, its exact registry entry strongly roots every file, WinUSB, preparsed-data, device-information-set, or composite cleanup owner whose release was not proved. If discovery fails before a container can be attributed, the process registry strongly roots an unattributed quarantine owner and rejects all later discovery and reservation attempts. Neither path depends on a local stack frame, a finalizer, or garbage-collection reachability to preserve the native lifetime.
Before either a successful legacy read-only lease or owned full-duplex lease escapes, that same entry also adopts and strongly roots the exact lease object. The root remains for the entire reservation lifetime, not only after an error, and therefore transitively retains every live or ambiguous MI_00/MI_01 handle, operation, buffer, and release capability if a caller drops its last reference. Final registry removal authenticates that reference-identical lifetime owner and removes the root only in the terminal-fence publication which releases the container. A failed facet cleanup, release hook, reentrant callback, or retryable native release leaves both the root and the exact retry capability intact.
Independent submission lanes¶
The MI_00 owner has one retained, preallocated read operation and one separate retained, preallocated write operation on the same bound handle. The two lanes have independent submission state and fixed pinned buffers, so one input read and one output write can coexist without allocating a replacement operation.
MI_01 has one preallocated operation for bulk OUT and another for bulk IN.
Startup admits only one command transaction at a time, and at most one operation
can exist on either exact pipe. WinUsb_AbortPipe is therefore exact within
this unescaped command lifetime: it cannot cancel a second owner's operation or
a second operation on the selected pipe.
A start result distinguishes a rejected new read from a prior busy submission. Neither the legacy nor owned wrapper releases on a generic false start. A completed-but-unretired prior input operation remains owned until its exact claim retires it.
One atomic terminal fence is shared by input, HID output, and command facets. Every native start admission, native begin call, and exact-operation publication is serialized by that fence. Every input/output/command ambiguity latches it. An operation admitted before a concurrent latch must recheck the same fence and retain/quarantine its exact capability before any success escapes; an operation admitted after the latch performs no native I/O. The lock order is terminal fence, then facet gate. The input IOCP callback follows that order and never acquires the terminal fence while holding the input gate.
A thrown native begin is not converted to a clean rejected start. The exact
pin, OVERLAPPED, operation object, handle, and reservation remain retained and
the shared fence latches. A late input completion may cross the callback only to
establish native/managed drain; it is suppressed before the canonical input
consumer and cannot publish controller state after quarantine. Failure to free
storage for an otherwise rejected read is treated the same way, not as an
ordinary false start.
Deadline, uncertainty, and retirement¶
The historical Bounded method/property names denote a maximum cumulative
managed native-quiescence wait budget, not a hard wall-clock limit for the
whole call. Accounting begins before native begin/cancel and elapsed synchronous
phase time is deducted before every wait. Win32/WinUSB begin, CancelIoEx,
WinUsb_AbortPipe, FreeNativeOverlapped, WinUsb_Free, and CloseHandle are
synchronous APIs without a nonblocking deadline contract. The production owner
deliberately adopts this managed-wait contract and retains/quarantines any
ambiguous native lifetime; hardware lifecycle evidence remains required before
a release claim.
When an output wait budget expires, the result carries the exact retained operation claim. The buffer, native storage, MI_00 handle, command lifetime, and container reservation remain owned; no replacement write is admitted. The claim authorizes bounded retryable cancel/drain. A false cancel followed by a non-quiescent wait remains eligible to reissue exact cancellation; a false cancel followed by a completion race drains once without a duplicate cancel.
Startup has the analogous fence. Every TimedOut or PossiblyConsumed result,
including malformed/noncausal response and start contradiction, blocks another
Execute until exact transaction retirement. Command and retirement claims
authenticate the exact lease object, exact full lifetime, registration, and
both generations; matching numeric generations from another lifetime cannot
operate or dispose this lease.
IOCP and cleanup proof¶
Completion callbacks contain every exception. They authenticate the exact native-overlapped pointer, bound transferred bytes to the submitted buffer, publish terminal failure on a callback-path fault when possible, and never let a stale/duplicate/mismatched callback signal another submission.
Quiescence is signalled only after:
- the exact completion transitioned the current submission;
FreeNativeOverlappedsucceeded; and- for input, the managed consumer callback returned.
For callback-only output/command operations, signalling is the final owned resource access; after it returns the IOCP frame only unwinds. A failed native storage release never signals and permanently fences the lease rather than publishing false quiescence.
OS cleanup is observable instead of relying on SafeHandle.Dispose()'s void
surface. Nonzero contradictory WinUSB and HID preparsed-data results are adopted
and released. WinUsb_Free, CloseHandle, HidD_FreePreparsedData, and
SetupDiDestroyDeviceInfoList failures propagate as cleanup ambiguity. Exact
WinUSB/file owners retain the same handle for retry where a retry capability is
still owned. A native false release can retry the same exact capability; a
thrown release has no consumed/not-consumed fact and is permanently fenced
without reissuing a potentially double free/close. On thrown CloseHandle, the
file owner publishes ambiguity before immediately marking its
SafeFileHandle invalid and disposing the managed wrapper. This suppresses the
SafeHandle native finalizer mechanically, so it cannot later close a recycled
numeric handle; the registry's exact lifetime root retains the ambiguity record
for terminal attention. Any unproven acquisition, revalidation, or terminal
cleanup keeps the process container reservation fenced.
If two cleanup operations fail while one acquisition frame unwinds, their
retained owners are composed; a later finally failure cannot overwrite and
drop the earlier native capability.
Terminal order is:
- drain and release exact command OUT/IN operations;
- release WinUSB, then the MI_01 file;
- prove output and input quiescence;
- release MI_00 operation storage, bound handle, then file; and
- publish the container reservation release.
Reservation publication itself is retry-safe: a throwing release hook retains
the exact reservation capability and its registry-rooted lease; it cannot
strand an ownerless registry entry or leave live SafeHandles reachable only by
GC.
Terminal publication is a two-phase protocol shared by the full-duplex and
legacy read-only leases. It first fences new submissions, then runs the injected
release hook without holding the terminal gate so a same-thread reentrant or
concurrent stale callback can latch quarantine. Registry removal is finally
committed while holding that terminal gate. If the callback wins, removal is
rejected and the same reservation capability remains retained; if removal wins,
later native admission is permanently sealed. This couples the final callback
fact and reservation removal instead of relying on Monitor ownership, which
is same-thread reentrant.
Deliberate limits¶
- no feature-response semantic guess;
- Bluetooth/Joy-Con association remains a separate BLE production owner;
- no cadence/500 Hz claim;
- no claim that synchronous native calls obey a hard deadline;
- no controller, LED, or haptic hardware run in this revision.
The production composition now activates the canonical feedback pump and requires an exact terminal-neutral operation before whole-composite disposal. It does not add a second mapping or physical-output writer.
Hardware validation must occur only after the offline composition blockers are closed and under the repository's authorized verifier protocol. The separate hardware verifier must never open these interfaces alongside a live owner.
Offline verification¶
The focused Windows suites cover exact pair acquisition, pre-escape-only discovery, ambiguity/quarantine, partial-open cleanup, output/input concurrency, retained timeout and late completion, cancellation retry/race behavior, foreign claims and private-fence/current-operation provenance, exact feature and player-LED response validation, whole-lease disposal order, observable handle release retries and no-repeat thrown-close finalization, attributed/pre-attribution acquisition ownership, registry-rooted terminal lifetimes across caller-drop/forced-GC, reservation publication retry, same-thread and cross-thread callback races at the release hook, symmetric cross-facet terminal races, deadline arithmetic, IOCP publication gates, and legacy read-owner regression cases.
Representative commands:
dotnet test DS4WindowsTests/DS4WindowsTests.csproj -c Release -p:Platform=x64 --no-restore --filter "FullyQualifiedName~Switch2ProUsbWindowsOwnedCompositeAdapterTests|FullyQualifiedName~Switch2ProUsbWindowsAdapterTests"
dotnet build DS4WindowsWPF.sln -c Release -p:Platform=x64 --no-restore