Skip to content

fix(egfx): preserve AVC_DISABLED during negotiation#1455

Open
digyear wants to merge 1 commit into
Devolutions:masterfrom
digyear:fix/egfx-preserve-avc-disabled
Open

fix(egfx): preserve AVC_DISABLED during negotiation#1455
digyear wants to merge 1 commit into
Devolutions:masterfrom
digyear:fix/egfx-preserve-avc-disabled

Conversation

@digyear

@digyear digyear commented Jul 18, 2026

Copy link
Copy Markdown

Summary

Preserve the client-provided AVC_DISABLED flag when negotiating EGFX capability sets while continuing to intersect normal positive feature flags.

The fix covers every typed capability version that defines AVC_DISABLED:

  • V10 and V10.2
  • V10.3
  • V10.4, V10.5, V10.6, and the V10.6 compatibility variant
  • V10.7

Why

AVC_DISABLED is different from ordinary capability bits: it describes a client-side decoder constraint. A client sets it to state that AVC420/AVC444 decoding is unavailable.

The current negotiation code treats every flag as a mutually supported positive feature and computes:

client_flags & server_flags

A server normally does not advertise that its own AVC decoder is disabled, so this operation removes the client's constraint from CapabilitiesConfirm. The negotiated state can then report AVC support even though the client explicitly disabled it.

This was reproduced with Microsoft Remote Desktop for Android advertising a V10.4 capability set containing AVC_DISABLED | SMALL_CACHE. After the flag was removed during confirmation, the server and client disagreed about the available codec path. Preserving the constraint keeps the negotiated state faithful to the client and allows the server to select a non-AVC path such as Planar.

The relevant capability definitions are documented in MS-RDPEGFX:

Implementation

For capability versions containing AVC_DISABLED, negotiation now computes:

(client_flags & server_flags) | (client_flags & AVC_DISABLED)

This preserves only the negative client constraint. All other flags retain the existing intersection behavior.

Validation

Added unit tests that verify:

  • AVC_DISABLED survives negotiation for every supported capability version that defines it
  • mutually supported positive flags are retained
  • unsupported positive flags are still removed

Commands run:

  • cargo test -p ironrdp-egfx capability_negotiation_tests
  • cargo check -p ironrdp-egfx
  • cargo fmt --all -- --check
  • git diff --check

The V10.4 behavior was also validated downstream with Microsoft Remote Desktop for Android through lamco-rdp-server.

Relationship to Planar support

This fix is independent of, but complementary to, #1454. That PR exposes a Planar frame sender; this PR ensures an AVC-disabled client remains identified as such after capability negotiation.

Treat AVC_DISABLED as a client-side decoder constraint rather than a mutually supported feature. Preserve it in CapsConfirm for every capability version that defines the flag while retaining intersection semantics for positive flags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant