Skip to main content

ironrdp_dvc_com_plugin/
lib.rs

1//! DVC COM client plugin loader for IronRDP (Windows-only).
2//!
3//! This crate enables loading native Windows DVC (Dynamic Virtual Channel) client plugin DLLs
4//! such as `webauthn.dll` into IronRDP's DVC channel infrastructure.
5//!
6//! The plugin DLL is loaded via `LoadLibraryW`, its `VirtualChannelGetInstance` export is called
7//! to obtain `IWTSPlugin` COM objects, and a Rust implementation of `IWTSVirtualChannelManager`
8//! bridges data bidirectionally between the plugin's COM callbacks and IronRDP's DVC system.
9//!
10//! # Architecture
11//!
12//! A dedicated COM worker thread owns all COM objects (which are `!Send`). The [`DvcComChannel`]
13//! structs (which implement `DvcProcessor + Send`) are registered as DVC channels in IronRDP's
14//! `DrdynvcClient` and communicate with the COM thread via `std::sync::mpsc` channels.
15//!
16//! Outbound data from the plugin (`IWTSVirtualChannel::Write`) is injected into the active
17//! session loop via the `on_write_dvc` callback, following the same pattern as
18//! `ironrdp-dvc-pipe-proxy`.
19//!
20//! # References
21//!
22//! - [Writing a Client DVC Component](https://learn.microsoft.com/en-us/windows/win32/termserv/writing-a-client-dvc-component)
23//! - [tsvirtualchannels.h](https://learn.microsoft.com/en-us/windows/win32/api/tsvirtualchannels/)
24
25#![cfg(windows)]
26// The `windows` crate's `#[implement]` macro generates code that triggers these lints.
27// We must allow them crate-wide since the generated code is not under our control.
28#![allow(clippy::inline_always)]
29#![allow(clippy::as_pointer_underscore)]
30#![allow(clippy::multiple_unsafe_ops_per_block)]
31#![allow(clippy::undocumented_unsafe_blocks)]
32#![allow(clippy::unnecessary_safety_comment)]
33
34mod channel;
35mod com;
36mod worker;
37
38pub use channel::{DvcComChannel, load_dvc_plugin};