diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..35049cbc --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44a3e3af..8436d9ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: if ($LastExitCode -eq 1) { throw "Bad formatting, please run 'cargo +stable fmt --all'" } - + lints: name: Lints runs-on: ubuntu-20.04 @@ -47,7 +47,8 @@ jobs: key: ${{ runner.os }}-lints-${{ hashFiles('Cargo.lock') }} - name: Check clippy - run: cargo clippy --workspace -- -D warnings + # FIXME: run: cargo clippy --workspace -- -D warnings + run: cargo clippy -- -D warnings wasm: name: WASM target @@ -63,15 +64,14 @@ jobs: path: | ~/.cargo/registry/ ~/.cargo/git/ - ./ffi/wasm/target/ + ./target/ key: ${{ runner.os }}-wasm-${{ hashFiles('ffi/wasm/Cargo.lock') }} - name: Prepare runner run: sudo apt install wabt - name: Check - shell: pwsh - run: ./ffi/wasm/check.ps1 + run: cargo xtask check wasm tests: name: Tests [${{ matrix.os }}] @@ -100,7 +100,8 @@ jobs: key: ${{ runner.os }}-tests-${{ hashFiles('Cargo.lock') }} - name: Test [${{ matrix.os }}] - run: cargo test --workspace + # FIXME: run: cargo test --workspace + run: cargo test fuzz: name: Fuzzing diff --git a/.gitignore b/.gitignore index 0f32155f..05146457 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ +# Build artifacts /target + +# Log files *.log +# Coverage +/docs + # Editor/IDE files *~ /tags diff --git a/Cargo.lock b/Cargo.lock index db7a7691..646a6b38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,8 +114,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "synstructure", ] @@ -126,8 +126,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -440,8 +440,8 @@ checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -504,6 +504,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + [[package]] name = "const-oid" version = "0.7.1" @@ -690,7 +710,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.104", ] @@ -721,8 +741,8 @@ dependencies = [ "cc", "codespan-reporting", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "scratch", "syn 1.0.104", ] @@ -739,8 +759,8 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -762,8 +782,8 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "strsim", "syn 1.0.104", ] @@ -775,7 +795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.104", ] @@ -839,8 +859,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ef71ddb5b3a1f53dee24817c8f70dfa1cb29e804c18d88c228d4bc9c86ee3b9" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -850,8 +870,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -911,8 +931,8 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -1068,8 +1088,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -1139,9 +1159,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" dependencies = [ "futures-core", "futures-sink", @@ -1149,9 +1169,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" [[package]] name = "futures-executor" @@ -1166,32 +1186,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" [[package]] name = "futures-timer" @@ -1201,9 +1221,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" dependencies = [ "futures-channel", "futures-core", @@ -1264,8 +1284,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1279,6 +1301,39 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "gloo-net" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-utils" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "glow" version = "0.11.2" @@ -1623,11 +1678,11 @@ checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" [[package]] name = "ironrdp" -version = "0.4.2" +version = "0.5.0" dependencies = [ - "ironrdp-core", "ironrdp-graphics", "ironrdp-input", + "ironrdp-pdu", "ironrdp-session", ] @@ -1645,6 +1700,7 @@ dependencies = [ "inquire", "ironrdp", "ironrdp-input", + "ironrdp-session", "log", "smallvec", "softbuffer", @@ -1660,7 +1716,73 @@ dependencies = [ ] [[package]] -name = "ironrdp-core" +name = "ironrdp-client-glutin" +version = "0.4.2" +dependencies = [ + "async-native-tls", + "chrono", + "clap", + "exitcode", + "fern", + "futures-util", + "glutin", + "ironrdp", + "ironrdp-glutin-renderer", + "ironrdp-session", + "log", + "sspi", + "tokio", + "tokio-rustls", + "tokio-util", + "x509-parser 0.14.0", +] + +[[package]] +name = "ironrdp-glutin-renderer" +version = "0.1.0" +dependencies = [ + "glow", + "glutin", + "ironrdp", + "log", + "openh264", + "thiserror", +] + +[[package]] +name = "ironrdp-graphics" +version = "0.1.0" +dependencies = [ + "bit_field", + "bitflags", + "bitvec", + "byteorder", + "bytes", + "hex-literal", + "ironrdp-pdu", + "lazy_static", + "num-derive 0.3.3", + "num-traits", + "proptest", + "rdp-rs", + "rstest 0.16.0", + "thiserror", +] + +[[package]] +name = "ironrdp-input" +version = "0.1.0" +dependencies = [ + "anyhow", + "bitvec", + "ironrdp-pdu", + "proptest", + "rstest 0.16.0", + "smallvec", +] + +[[package]] +name = "ironrdp-pdu" version = "0.1.0" dependencies = [ "bit_field", @@ -1680,56 +1802,11 @@ dependencies = [ ] [[package]] -name = "ironrdp-graphics" -version = "0.1.0" +name = "ironrdp-pdu-generators" +version = "0.0.0" dependencies = [ - "bit_field", - "bitflags", - "bitvec", - "byteorder", - "bytes", - "hex-literal", - "ironrdp-core", - "lazy_static", - "num-derive 0.3.3", - "num-traits", + "ironrdp-pdu", "proptest", - "rdp-rs", - "rstest 0.16.0", - "thiserror", -] - -[[package]] -name = "ironrdp-gui-client" -version = "0.4.2" -dependencies = [ - "async-native-tls", - "chrono", - "clap", - "exitcode", - "fern", - "futures-util", - "glutin", - "ironrdp", - "ironrdp-renderer", - "log", - "sspi", - "tokio", - "tokio-rustls", - "tokio-util", - "x509-parser 0.14.0", -] - -[[package]] -name = "ironrdp-input" -version = "0.1.0" -dependencies = [ - "anyhow", - "bitvec", - "ironrdp-core", - "proptest", - "rstest 0.16.0", - "smallvec", ] [[package]] @@ -1743,18 +1820,6 @@ dependencies = [ "rstest 0.15.0", ] -[[package]] -name = "ironrdp-renderer" -version = "0.1.0" -dependencies = [ - "glow", - "glutin", - "ironrdp", - "log", - "openh264", - "thiserror", -] - [[package]] name = "ironrdp-replay-client" version = "0.4.2" @@ -1762,7 +1827,7 @@ dependencies = [ "clap", "glutin", "ironrdp", - "ironrdp-renderer", + "ironrdp-glutin-renderer", "log", "simplelog", ] @@ -1777,8 +1842,8 @@ dependencies = [ "byteorder", "bytes", "futures-util", - "ironrdp-core", "ironrdp-graphics", + "ironrdp-pdu", "ironrdp-rdcleanpath", "lazy_static", "log", @@ -1801,15 +1866,48 @@ dependencies = [ "byteorder", "bytes", "futures-util", - "ironrdp-core", - "ironrdp-graphics", + "ironrdp-pdu", + "ironrdp-session", "num-traits", + "tokio", + "tokio-util", +] + +[[package]] +name = "ironrdp-session-generators" +version = "0.0.0" +dependencies = [ + "ironrdp-pdu-generators", + "ironrdp-session", + "proptest", ] [[package]] name = "ironrdp-tls" version = "0.1.0" +[[package]] +name = "ironrdp-web" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "console_error_panic_hook", + "console_log", + "futures-channel", + "futures-util", + "getrandom 0.2.8", + "gloo-net", + "ironrdp", + "ironrdp-session", + "js-sys", + "log", + "smallvec", + "sspi", + "wasm-bindgen", + "wasm-bindgen-futures", +] + [[package]] name = "is-terminal" version = "0.4.0" @@ -1891,9 +1989,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libloading" @@ -2151,8 +2249,8 @@ checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" dependencies = [ "darling", "proc-macro-crate 1.2.1", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -2301,8 +2399,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -2373,8 +2471,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" dependencies = [ "proc-macro-crate 0.1.5", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -2385,8 +2483,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ "proc-macro-crate 1.2.1", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -2511,8 +2609,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -2736,6 +2834,32 @@ dependencies = [ "uuid", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 1.0.104", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2842,8 +2966,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "version_check", ] @@ -2854,8 +2978,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "version_check", ] @@ -2870,9 +2994,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] @@ -2930,11 +3054,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ - "proc-macro2 1.0.47", + "proc-macro2 1.0.54", ] [[package]] @@ -3217,8 +3341,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5015e68a0685a95ade3eee617ff7101ab6a3fc689203101ca16ebc16f2b89c66" dependencies = [ "cfg-if 1.0.0", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "rustc_version", "syn 1.0.104", ] @@ -3230,8 +3354,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7" dependencies = [ "cfg-if 1.0.0", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "rustc_version", "syn 1.0.104", "unicode-ident", @@ -3463,8 +3587,8 @@ version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -3673,9 +3797,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -3825,8 +3949,19 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40" +dependencies = [ + "proc-macro2 1.0.54", + "quote 1.0.26", "unicode-ident", ] @@ -3836,8 +3971,8 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "unicode-xid 0.2.4", ] @@ -3886,8 +4021,8 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -4008,14 +4143,13 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", @@ -4023,18 +4157,18 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.45.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.104", + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 2.0.11", ] [[package]] @@ -4050,9 +4184,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", @@ -4096,8 +4230,8 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", ] @@ -4327,8 +4461,8 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "wasm-bindgen-shared", ] @@ -4351,7 +4485,7 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ - "quote 1.0.21", + "quote 1.0.26", "wasm-bindgen-macro-support", ] @@ -4361,8 +4495,8 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -4468,8 +4602,8 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "xml-rs", ] @@ -4479,9 +4613,9 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4834c14b3edf1d9986c83ca79b1e7e3afbe9874c7c144702f6467063259ce45d" dependencies = [ - "proc-macro2 1.0.47", + "proc-macro2 1.0.54", "quick-xml", - "quote 1.0.21", + "quote 1.0.26", ] [[package]] @@ -4950,6 +5084,30 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +[[package]] +name = "xshell" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962c039b3a7b16cf4e9a4248397c6585c07547412e7d6a6e035389a802dcfe90" +dependencies = [ + "xshell-macros", +] + +[[package]] +name = "xshell-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbabb1cbd15a1d6d12d9ed6b35cc6777d4af87ab3ba155ea37215f20beab80c" + +[[package]] +name = "xtask" +version = "0.0.0" +dependencies = [ + "anyhow", + "pico-args", + "xshell", +] + [[package]] name = "yansi" version = "0.5.1" @@ -4977,8 +5135,8 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.54", + "quote 1.0.26", "syn 1.0.104", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index acdcc011..19a5cdd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,43 @@ +[package] +name = "ironrdp" +version = "0.5.0" +edition = "2021" +readme = "README.md" +license = "MIT/Apache-2.0" +homepage = "https://github.com/Devolutions/IronRDP" +repository = "https://github.com/Devolutions/IronRDP" +authors = ["Devolutions Inc. "] +description = "A Rust implementation of the Microsoft Remote Desktop Protocol (RDP)" +keywords = ["rdp", "remote", "desktop", "protocol"] + [workspace] members = [ - "ironrdp", - "ironrdp-core", - "ironrdp-graphics", - "ironrdp-input", - "ironrdp-session", - "ironrdp-session-async", - "ironrdp-tls", - "ironrdp-rdcleanpath", - "ironrdp-renderer", - "ironrdp-client", - "ironrdp-client-glutin", - "ironrdp-replay-client", + "crates/*", + "xtask", ] +default-members = [ + "crates/pdu", + "crates/session", + "crates/graphics", + "crates/input", + "crates/session-async", + "crates/client", +] + +[profile.production] +inherits = "release" +lto = true + +[profile.production-wasm] +inherits = "release" +opt-level = "s" +lto = true + +[features] +default = [] + +[dependencies] +ironrdp-pdu = { path = "crates/pdu" } +ironrdp-session = { path = "crates/session" } +ironrdp-graphics = { path = "crates/graphics" } +ironrdp-input = { path = "crates/input" } diff --git a/README.md b/README.md index 6c498097..22dd5231 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,10 @@ # IronRDP -A Rust implementation of the Microsoft Remote Desktop Protocol, with a focus on security. +A collection of Rust crates providing an implementation of the Microsoft Remote Desktop Protocol, with a focus on security. -## Architecture (Work In Progress…) +## Demonstration -- `ironrdp`: meta crate re-exporting important crates -- `ironrdp-core`: core, RDP protocol packets encoding and decoding. -- `ironrdp-graphics`: image processing primitives and algorithms (ZGFX, DWT…). -- `ironrdp-input`: helpers to build FastPathInput packets. -- `ironrdp-session`: abstract state machine on top of `ironrdp-graphics`. -- `ironrdp-session-async`: `Future`s built on top of `ironrdp-session`. -- `ironrdp-tls`: TLS boilerplate common with most IronRDP clients. -- `ironrdp-devolutions-gateway`: Devolutions Gateway extensions. -- `ironrdp-renderer`: `glutin` primitives for OpenGL rendering. -- `ironrdp-client`: Portable RDP client without GPU acceleration using softbuffer and winit for windowing. -- `ironrdp-client-glutin`: GPU-accelerated RDP client using glutin. -- `ironrdp-replay-client`: utility tool to replay RDP graphics pipeline for debugging purposes. -- `iron-remote-gui`: core frontend ui used by both, iron-svelte-client and iron-tauri-client. -- `iron-svelte-client`: web-based frontend using `Svelte` and `Material` frameworks). -- `iron-tauri-client`: a native client built with Tauri. Frontend is using the `iron-web-client`/`iron-svelte-client` component. -- `ffi/wasm`: WebAssembly high-level bindings targeting web browsers. +https://user-images.githubusercontent.com/3809077/202049929-76f42471-aeb0-41da-9118-0dc6ea491bd2.mp4 ## Video Codec Support @@ -50,7 +35,39 @@ Alternatively, you may change a few group policies using `gpedit.msc`: 5. Reboot. -## Demonstration +## Architecture (Work In Progress…) -https://user-images.githubusercontent.com/3809077/202049929-76f42471-aeb0-41da-9118-0dc6ea491bd2.mp4 +- `ironrdp` (root package): meta crate re-exporting important crates, +- `ironrdp-pdu` (`crates/pdu`): PDU encoding and decoding (no I/O, trivial to fuzz), +- `ironrdp-graphics` (`crates/graphics`): image processing primitives (no I/O, trivial to fuzz), +- `ironrdp-session` (`crates/session`): state machine to drive a complete VNC session (no I/O, not _too_ hard to fuzz), +- `ironrdp-input` (`crates/input`): utilities to manage and build input packets (no I/O), +- `ironrdp-session-async` (`crates/session-async`): provides `Future`s wrapping the session state machine conveniently, +- `ironrdp-tls` (`crates/tls`): TLS boilerplate common with most IronRDP clients, +- `ironrdp-rdcleanpath` (`crates/rdcleanpath`): RDCleanPath PDU structure used by IronRDP web client and Devolutions Gateway, +- `ironrdp-client` (`crates/client`): Portable RDP client without GPU acceleration using softbuffer and winit for windowing, +- `ironrdp-web` (`crates/web`): WebAssembly high-level bindings targeting web browsers, +- `ironrdp-glutin-renderer` (`crates/glutin-renderer`): `glutin` primitives for OpenGL rendering, +- `ironrdp-client-glutin` (`crates/client-glutin`): GPU-accelerated RDP client using glutin, +- `ironrdp-replay-client` (`crates/replay-client`): utility tool to replay RDP graphics pipeline for debugging purposes, +- `ironrdp-pdu-generators` (`crates/pdu-generators`): `proptest` generators for `ironrdp-pdu` types, +- `ironrdp-session-generators` (`crates/session-generators`): `proptest` generators for `ironrdp-session` types, +- `iron-remote-gui` (`web-client/iron-remote-gui`): core frontend UI used by `iron-svelte-client` as a Web Component, +- `iron-svelte-client` (`web-client/iron-svelte-client`): web-based frontend using `Svelte` and `Material` frameworks, +- and finally, `ironrdp-fuzz` (`fuzz`): fuzz targets for core crates. +## General design + +- Avoid I/O wherever possible +- Dependency injection when runtime information is necessary in core crates (no system call such as `gethostname`) +- Keep non-portable code out of core crates +- Make crate `no_std`-compatible wherever possible +- Facilitate fuzzing +- In libraries, provide concrete error types either hand-crafted or using `thiserror` crate +- In binaries, use the convenient catch-all error type `anyhow::Error` +- Free-form automation a-la `make` following [`cargo xtask`](https://github.com/matklad/cargo-xtask) specification + +## Continuous integration + +We use GitHub action and our workflows simply run `cargo xtask`. +The expectation is that, if `cargo xtask ci` passes locally, the CI will be green as well. diff --git a/ironrdp-client-glutin/Cargo.toml b/crates/client-glutin/Cargo.toml similarity index 77% rename from ironrdp-client-glutin/Cargo.toml rename to crates/client-glutin/Cargo.toml index 54854a8e..2c197b44 100644 --- a/ironrdp-client-glutin/Cargo.toml +++ b/crates/client-glutin/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironrdp-gui-client" +name = "ironrdp-client-glutin" version = "0.4.2" edition = "2021" readme = "README.md" @@ -11,13 +11,14 @@ keywords = ["rdp", "client", "remote", "desktop", "protocol", "gfx", "rfx"] [features] default = ["rustls"] -rustls = ["dep:tokio-rustls", "ironrdp/rustls"] -native-tls = ["dep:async-native-tls", "ironrdp/native-tls"] +rustls = ["dep:tokio-rustls", "ironrdp-session/rustls"] +native-tls = ["dep:async-native-tls", "ironrdp-session/native-tls"] [dependencies] -# Protocol -ironrdp = { path = "../ironrdp" } +# Protocols +ironrdp = { path = "../.." } +ironrdp-session = { path = "../session" } sspi = { version = "0.8", features = ["network_client"] } # CLI @@ -43,4 +44,4 @@ chrono = "0.4.23" # GUI glutin = "0.29" -ironrdp-renderer = { path = "../ironrdp-renderer"} \ No newline at end of file +ironrdp-glutin-renderer = { path = "../glutin-renderer"} \ No newline at end of file diff --git a/ironrdp-client-glutin/README.md b/crates/client-glutin/README.md similarity index 100% rename from ironrdp-client-glutin/README.md rename to crates/client-glutin/README.md diff --git a/ironrdp-client-glutin/src/config.rs b/crates/client-glutin/src/config.rs similarity index 83% rename from ironrdp-client-glutin/src/config.rs rename to crates/client-glutin/src/config.rs index f879ac25..64e58723 100644 --- a/ironrdp-client-glutin/src/config.rs +++ b/crates/client-glutin/src/config.rs @@ -26,11 +26,11 @@ enum SecurityProtocol { } impl SecurityProtocol { - fn parse(security_protocol: SecurityProtocol) -> ironrdp::core::SecurityProtocol { + fn parse(security_protocol: SecurityProtocol) -> ironrdp::pdu::SecurityProtocol { match security_protocol { - SecurityProtocol::Ssl => ironrdp::core::SecurityProtocol::SSL, - SecurityProtocol::Hybrid => ironrdp::core::SecurityProtocol::HYBRID, - SecurityProtocol::HybridEx => ironrdp::core::SecurityProtocol::HYBRID_EX, + SecurityProtocol::Ssl => ironrdp::pdu::SecurityProtocol::SSL, + SecurityProtocol::Hybrid => ironrdp::pdu::SecurityProtocol::HYBRID, + SecurityProtocol::HybridEx => ironrdp::pdu::SecurityProtocol::HYBRID_EX, } } } @@ -47,15 +47,15 @@ enum KeyboardType { } impl KeyboardType { - fn parse(keyboard_type: KeyboardType) -> ironrdp::gcc::KeyboardType { + fn parse(keyboard_type: KeyboardType) -> ironrdp::pdu::gcc::KeyboardType { match keyboard_type { - KeyboardType::IbmEnhanced => ironrdp::gcc::KeyboardType::IbmEnhanced, - KeyboardType::IbmPcAt => ironrdp::gcc::KeyboardType::IbmPcAt, - KeyboardType::IbmPcXt => ironrdp::gcc::KeyboardType::IbmPcXt, - KeyboardType::OlivettiIco => ironrdp::gcc::KeyboardType::OlivettiIco, - KeyboardType::Nokia1050 => ironrdp::gcc::KeyboardType::Nokia1050, - KeyboardType::Nokia9140 => ironrdp::gcc::KeyboardType::Nokia9140, - KeyboardType::Japanese => ironrdp::gcc::KeyboardType::Japanese, + KeyboardType::IbmEnhanced => ironrdp::pdu::gcc::KeyboardType::IbmEnhanced, + KeyboardType::IbmPcAt => ironrdp::pdu::gcc::KeyboardType::IbmPcAt, + KeyboardType::IbmPcXt => ironrdp::pdu::gcc::KeyboardType::IbmPcXt, + KeyboardType::OlivettiIco => ironrdp::pdu::gcc::KeyboardType::OlivettiIco, + KeyboardType::Nokia1050 => ironrdp::pdu::gcc::KeyboardType::Nokia1050, + KeyboardType::Nokia9140 => ironrdp::pdu::gcc::KeyboardType::Nokia9140, + KeyboardType::Japanese => ironrdp::pdu::gcc::KeyboardType::Japanese, } } } diff --git a/ironrdp-client-glutin/src/gui.rs b/crates/client-glutin/src/gui.rs similarity index 97% rename from ironrdp-client-glutin/src/gui.rs rename to crates/client-glutin/src/gui.rs index 66b8799c..44197320 100644 --- a/ironrdp-client-glutin/src/gui.rs +++ b/crates/client-glutin/src/gui.rs @@ -6,9 +6,9 @@ use std::sync::{self, Arc}; use glutin::dpi::PhysicalPosition; use glutin::event::{Event, WindowEvent}; use glutin::event_loop::ControlFlow; -use ironrdp::dvc::gfx::ServerPdu; +use ironrdp::pdu::dvc::gfx::ServerPdu; use ironrdp::session::{ErasedWriter, GfxHandler}; -use ironrdp_renderer::renderer::Renderer; +use ironrdp_glutin_renderer::renderer::Renderer; use tokio::sync::Mutex; use self::input::{handle_input_events, translate_input_event}; @@ -28,7 +28,7 @@ impl MessagePassingGfxHandler { } impl GfxHandler for MessagePassingGfxHandler { - fn on_message(&self, message: ServerPdu) -> Result, RdpError> { + fn on_message(&self, message: ServerPdu) -> Result, RdpError> { self.channel.send(message).map_err(|e| RdpError::Send(e.to_string()))?; Ok(None) } diff --git a/ironrdp-client-glutin/src/gui/input.rs b/crates/client-glutin/src/gui/input.rs similarity index 94% rename from ironrdp-client-glutin/src/gui/input.rs rename to crates/client-glutin/src/gui/input.rs index 42b930c1..baaea0aa 100644 --- a/ironrdp-client-glutin/src/gui/input.rs +++ b/crates/client-glutin/src/gui/input.rs @@ -4,10 +4,10 @@ use std::sync::Arc; use futures_util::AsyncWriteExt; use glutin::dpi::PhysicalPosition; use glutin::event::{ElementState, Event, WindowEvent}; -use ironrdp::core::input::fast_path::{FastPathInput, FastPathInputEvent, KeyboardFlags}; -use ironrdp::core::input::mouse::PointerFlags; -use ironrdp::core::input::MousePdu; -use ironrdp::core::PduParsing; +use ironrdp::pdu::input::fast_path::{FastPathInput, FastPathInputEvent, KeyboardFlags}; +use ironrdp::pdu::input::mouse::PointerFlags; +use ironrdp::pdu::input::MousePdu; +use ironrdp::pdu::PduParsing; use ironrdp::session::ErasedWriter; use tokio::sync::Mutex; diff --git a/ironrdp-client-glutin/src/main.rs b/crates/client-glutin/src/main.rs similarity index 99% rename from ironrdp-client-glutin/src/main.rs rename to crates/client-glutin/src/main.rs index 7639e974..d1fc53fb 100644 --- a/ironrdp-client-glutin/src/main.rs +++ b/crates/client-glutin/src/main.rs @@ -9,8 +9,8 @@ use std::{io, process}; use futures_util::io::AsyncWriteExt as _; use gui::MessagePassingGfxHandler; -use ironrdp::dvc::gfx::ServerPdu; use ironrdp::graphics::image_processing::PixelFormat; +use ironrdp::pdu::dvc::gfx::ServerPdu; use ironrdp::session::connection_sequence::{process_connection_sequence, UpgradedStream}; use ironrdp::session::image::DecodedImage; use ironrdp::session::{ActiveStageOutput, ActiveStageProcessor, ErasedWriter, RdpError}; diff --git a/ironrdp-client/Cargo.toml b/crates/client/Cargo.toml similarity index 74% rename from ironrdp-client/Cargo.toml rename to crates/client/Cargo.toml index 6a130e92..67186cdf 100644 --- a/ironrdp-client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -11,15 +11,16 @@ keywords = ["rdp", "client", "remote", "desktop", "protocol", "gfx", "rfx"] [features] default = ["rustls"] -rustls = ["dep:tokio-rustls", "ironrdp/rustls"] -native-tls = ["dep:async-native-tls", "ironrdp/native-tls"] +rustls = ["dep:tokio-rustls", "ironrdp-session/rustls"] +native-tls = ["dep:async-native-tls", "ironrdp-session/native-tls"] [dependencies] -# Protocol -ironrdp = { path = "../ironrdp" } -ironrdp-input = { path = "../ironrdp-input" } -sspi = { version = "0.8.0", features = ["network_client"] } # TODO: enable dns_resolver at some point +# Protocols +ironrdp = { path = "../.." } +ironrdp-input = { path = "../input" } +ironrdp-session = { path = "../session" } +sspi = { version = "0.8", features = ["network_client"] } # TODO: enable dns_resolver at some point # GUI softbuffer = "0.2.0" @@ -30,16 +31,18 @@ clap = { version = "4.0", features = ["derive", "cargo"] } exitcode = "1.1.2" inquire = "0.5.3" -# logging +# Logging log = "0.4" fern = "0.6" +tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } +tracing = "0.1.37" # SSL x509-parser = "0.14" async-native-tls = { version = "0.4", default-features = false, features = [ "runtime-tokio" ], optional = true } tokio-rustls = { version = "0.23", features = ["dangerous_configuration"], optional = true } -# async, futures +# Async, futures tokio = { version = "1", features = ["full"]} tokio-util = { version = "0.7.4", features = ["compat"] } futures-util = "0.3" @@ -49,5 +52,3 @@ chrono = "0.4.23" whoami = "1.2.3" anyhow = "1.0.68" smallvec = "1.10.0" -tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } -tracing = "0.1.37" diff --git a/ironrdp-client/README.md b/crates/client/README.md similarity index 100% rename from ironrdp-client/README.md rename to crates/client/README.md diff --git a/ironrdp-client/src/config.rs b/crates/client/src/config.rs similarity index 84% rename from ironrdp-client/src/config.rs rename to crates/client/src/config.rs index 7815ffb5..34b6b3df 100644 --- a/ironrdp-client/src/config.rs +++ b/crates/client/src/config.rs @@ -26,11 +26,11 @@ enum SecurityProtocol { } impl SecurityProtocol { - fn parse(security_protocol: SecurityProtocol) -> ironrdp::core::SecurityProtocol { + fn parse(security_protocol: SecurityProtocol) -> ironrdp::pdu::SecurityProtocol { match security_protocol { - SecurityProtocol::Ssl => ironrdp::core::SecurityProtocol::SSL, - SecurityProtocol::Hybrid => ironrdp::core::SecurityProtocol::HYBRID, - SecurityProtocol::HybridEx => ironrdp::core::SecurityProtocol::HYBRID_EX, + SecurityProtocol::Ssl => ironrdp::pdu::SecurityProtocol::SSL, + SecurityProtocol::Hybrid => ironrdp::pdu::SecurityProtocol::HYBRID, + SecurityProtocol::HybridEx => ironrdp::pdu::SecurityProtocol::HYBRID_EX, } } } @@ -47,15 +47,15 @@ enum KeyboardType { } impl KeyboardType { - fn parse(keyboard_type: KeyboardType) -> ironrdp::gcc::KeyboardType { + fn parse(keyboard_type: KeyboardType) -> ironrdp::pdu::gcc::KeyboardType { match keyboard_type { - KeyboardType::IbmEnhanced => ironrdp::gcc::KeyboardType::IbmEnhanced, - KeyboardType::IbmPcAt => ironrdp::gcc::KeyboardType::IbmPcAt, - KeyboardType::IbmPcXt => ironrdp::gcc::KeyboardType::IbmPcXt, - KeyboardType::OlivettiIco => ironrdp::gcc::KeyboardType::OlivettiIco, - KeyboardType::Nokia1050 => ironrdp::gcc::KeyboardType::Nokia1050, - KeyboardType::Nokia9140 => ironrdp::gcc::KeyboardType::Nokia9140, - KeyboardType::Japanese => ironrdp::gcc::KeyboardType::Japanese, + KeyboardType::IbmEnhanced => ironrdp::pdu::gcc::KeyboardType::IbmEnhanced, + KeyboardType::IbmPcAt => ironrdp::pdu::gcc::KeyboardType::IbmPcAt, + KeyboardType::IbmPcXt => ironrdp::pdu::gcc::KeyboardType::IbmPcXt, + KeyboardType::OlivettiIco => ironrdp::pdu::gcc::KeyboardType::OlivettiIco, + KeyboardType::Nokia1050 => ironrdp::pdu::gcc::KeyboardType::Nokia1050, + KeyboardType::Nokia9140 => ironrdp::pdu::gcc::KeyboardType::Nokia9140, + KeyboardType::Japanese => ironrdp::pdu::gcc::KeyboardType::Japanese, } } } diff --git a/ironrdp-client/src/gui.rs b/crates/client/src/gui.rs similarity index 99% rename from ironrdp-client/src/gui.rs rename to crates/client/src/gui.rs index b4eca3de..e7563573 100644 --- a/ironrdp-client/src/gui.rs +++ b/crates/client/src/gui.rs @@ -261,7 +261,7 @@ impl GuiContext { fn send_fast_path_events( input_event_sender: &mpsc::UnboundedSender, - input_events: smallvec::SmallVec<[ironrdp::core::input::fast_path::FastPathInputEvent; 2]>, + input_events: smallvec::SmallVec<[ironrdp::pdu::input::fast_path::FastPathInputEvent; 2]>, ) { if !input_events.is_empty() { let _ = input_event_sender.send(RdpInputEvent::FastPath(input_events)); diff --git a/ironrdp-client/src/lib.rs b/crates/client/src/lib.rs similarity index 100% rename from ironrdp-client/src/lib.rs rename to crates/client/src/lib.rs diff --git a/ironrdp-client/src/main.rs b/crates/client/src/main.rs similarity index 95% rename from ironrdp-client/src/main.rs rename to crates/client/src/main.rs index 135011e0..adfed714 100644 --- a/ironrdp-client/src/main.rs +++ b/crates/client/src/main.rs @@ -1,15 +1,11 @@ #[macro_use] extern crate log; -use std::fs::OpenOptions; - use anyhow::Context as _; use ironrdp_client::config::Config; use ironrdp_client::gui::GuiContext; use ironrdp_client::rdp::{RdpClient, RdpInputEvent}; use tokio::runtime; -use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; -use tracing_subscriber::EnvFilter; fn main() -> anyhow::Result<()> { let mut config = Config::parse_args().context("CLI arguments parsing")?; @@ -63,6 +59,11 @@ fn setup_logging(log_file: &str) -> Result<(), fern::InitError> { // sspi-rs logging if let Ok(path) = std::env::var("SSPI_LOG_FILE") { + use std::fs::OpenOptions; + + use tracing_subscriber::prelude::*; + use tracing_subscriber::EnvFilter; + let file = match OpenOptions::new().read(true).append(true).open(path) { Ok(file) => file, Err(e) => { diff --git a/ironrdp-client/src/rdp.rs b/crates/client/src/rdp.rs similarity index 95% rename from ironrdp-client/src/rdp.rs rename to crates/client/src/rdp.rs index 450a8c66..f92303a0 100644 --- a/ironrdp-client/src/rdp.rs +++ b/crates/client/src/rdp.rs @@ -1,6 +1,6 @@ use futures_util::io::AsyncWriteExt as _; -use ironrdp::core::input::fast_path::FastPathInputEvent; use ironrdp::graphics::image_processing::PixelFormat; +use ironrdp::pdu::input::fast_path::FastPathInputEvent; use ironrdp::session::connection_sequence::{process_connection_sequence, Address}; use ironrdp::session::image::DecodedImage; use ironrdp::session::{ActiveStageOutput, ActiveStageProcessor, RdpError}; @@ -143,8 +143,8 @@ async fn run_impl( return Ok(RdpControlFlow::ReconnectWithNewSize { width, height }) }, RdpInputEvent::FastPath(events) => { - use ironrdp::core::input::fast_path::FastPathInput; - use ironrdp::core::PduParsing as _; + use ironrdp::pdu::input::fast_path::FastPathInput; + use ironrdp::pdu::PduParsing as _; trace!("Inputs: {events:?}"); @@ -159,7 +159,7 @@ async fn run_impl( writer.write_all(&frame).await?; } RdpInputEvent::Close => { - // TODO: should we send a connection close to server? + // TODO: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/27915739-8f77-487e-9927-55008af7fd68 break 'outer; } } diff --git a/ironrdp-client/src/tls.rs b/crates/client/src/tls.rs similarity index 100% rename from ironrdp-client/src/tls.rs rename to crates/client/src/tls.rs diff --git a/ironrdp-renderer/Cargo.toml b/crates/glutin-renderer/Cargo.toml similarity index 81% rename from ironrdp-renderer/Cargo.toml rename to crates/glutin-renderer/Cargo.toml index ad945aac..e2efe3f0 100644 --- a/ironrdp-renderer/Cargo.toml +++ b/crates/glutin-renderer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironrdp-renderer" +name = "ironrdp-glutin-renderer" version = "0.1.0" edition = "2021" readme = "README.md" @@ -8,13 +8,10 @@ homepage = "https://github.com/Devolutions/IronRDP" repository = "https://github.com/Devolutions/IronRDP" authors = ["Devolutions Inc. "] -[lib] -path = "src/lib.rs" - [dependencies] +ironrdp = { path = "../.." } glow = "0.11" log = "0.4" thiserror = "1.0.38" -ironrdp = { path = "../ironrdp" } glutin = { version = "0.29" } openh264 = { version = "0.3" } diff --git a/ironrdp-renderer/shaders/avc.vert b/crates/glutin-renderer/shaders/avc.vert similarity index 95% rename from ironrdp-renderer/shaders/avc.vert rename to crates/glutin-renderer/shaders/avc.vert index 12aa17d5..2477588c 100644 --- a/ironrdp-renderer/shaders/avc.vert +++ b/crates/glutin-renderer/shaders/avc.vert @@ -1,8 +1,8 @@ -precision mediump float; - -uniform mat4 u_projection; -attribute vec2 a_position; - -void main(){ - gl_Position = u_projection * vec4(a_position, 0.0, 1.0); +precision mediump float; + +uniform mat4 u_projection; +attribute vec2 a_position; + +void main(){ + gl_Position = u_projection * vec4(a_position, 0.0, 1.0); } \ No newline at end of file diff --git a/ironrdp-renderer/shaders/avc420.frag b/crates/glutin-renderer/shaders/avc420.frag similarity index 97% rename from ironrdp-renderer/shaders/avc420.frag rename to crates/glutin-renderer/shaders/avc420.frag index 1e68d41a..639873c2 100644 --- a/ironrdp-renderer/shaders/avc420.frag +++ b/crates/glutin-renderer/shaders/avc420.frag @@ -1,35 +1,35 @@ -precision lowp float; - -uniform vec2 screen_size; -uniform vec2 stride_scale; -uniform sampler2D main_y_texture; -uniform sampler2D main_u_texture; -uniform sampler2D main_v_texture; - -uniform sampler2D aux_y_texture; -uniform sampler2D aux_u_texture; -uniform sampler2D aux_v_texture; - -// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js -const mat4 conversion = mat4( - 1.16438, 0.00000, 1.79274, -0.97295, - 1.16438, -0.21325, -0.53291, 0.30148, - 1.16438, 2.11240, 0.00000, -1.13340, - 0, 0, 0, 1 -); - -void main(void) { - // Inverted image - vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y); - - // Scale from [0..width, 0..height] to [0..1.0, 0..1.0] range and - // then scale to eliminate the stride padding - vec2 tex_coord = ((coordinates) / screen_size) * stride_scale; - - float main_y_channel = texture2D(main_y_texture, tex_coord).x; - float main_u_channel = texture2D(main_u_texture, tex_coord).x; - float main_v_channel = texture2D(main_v_texture, tex_coord).x; - - vec4 channels = vec4(main_y_channel, main_u_channel, main_v_channel, 1.0); - gl_FragColor = channels * conversion; +precision lowp float; + +uniform vec2 screen_size; +uniform vec2 stride_scale; +uniform sampler2D main_y_texture; +uniform sampler2D main_u_texture; +uniform sampler2D main_v_texture; + +uniform sampler2D aux_y_texture; +uniform sampler2D aux_u_texture; +uniform sampler2D aux_v_texture; + +// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js +const mat4 conversion = mat4( + 1.16438, 0.00000, 1.79274, -0.97295, + 1.16438, -0.21325, -0.53291, 0.30148, + 1.16438, 2.11240, 0.00000, -1.13340, + 0, 0, 0, 1 +); + +void main(void) { + // Inverted image + vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y); + + // Scale from [0..width, 0..height] to [0..1.0, 0..1.0] range and + // then scale to eliminate the stride padding + vec2 tex_coord = ((coordinates) / screen_size) * stride_scale; + + float main_y_channel = texture2D(main_y_texture, tex_coord).x; + float main_u_channel = texture2D(main_u_texture, tex_coord).x; + float main_v_channel = texture2D(main_v_texture, tex_coord).x; + + vec4 channels = vec4(main_y_channel, main_u_channel, main_v_channel, 1.0); + gl_FragColor = channels * conversion; } \ No newline at end of file diff --git a/ironrdp-renderer/shaders/avc444.frag b/crates/glutin-renderer/shaders/avc444.frag similarity index 97% rename from ironrdp-renderer/shaders/avc444.frag rename to crates/glutin-renderer/shaders/avc444.frag index 1b55e93b..9851b8b2 100644 --- a/ironrdp-renderer/shaders/avc444.frag +++ b/crates/glutin-renderer/shaders/avc444.frag @@ -1,77 +1,77 @@ -precision lowp float; - -uniform vec2 screen_size; -uniform vec2 stride_scale; -uniform sampler2D main_y_texture; -uniform sampler2D main_u_texture; -uniform sampler2D main_v_texture; - -uniform sampler2D aux_y_texture; -uniform sampler2D aux_u_texture; -uniform sampler2D aux_v_texture; - -const vec2 CUTOFF = vec2(30.0/255.0, 30.0/255.0); - -// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js -const mat4 conversion = mat4( - 1.16438, 0.00000, 1.79274, -0.97295, - 1.16438, -0.21325, -0.53291, 0.30148, - 1.16438, 2.11240, 0.00000, -1.13340, - 0, 0, 0, 1 -); - -const vec2 half_offset = vec2(0.5, 0.5); - -void main(void) { - vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y) ; - vec2 main_tex_coord = (coordinates / screen_size) * stride_scale; - // Query the main view - float main_y_channel = texture2D(main_y_texture, main_tex_coord).x; - float main_u_channel = texture2D(main_u_texture, main_tex_coord).x; - float main_v_channel = texture2D(main_v_texture, main_tex_coord).x; - - coordinates = coordinates - half_offset; - - float offset = floor(mod(coordinates.y, 16.0) * 0.5); - float start_y = offset + floor(coordinates.y / 16.0) * 16.0; - // Auxiliary view - vec2 aux_tex_coord = vec2(coordinates.x, start_y) + half_offset; - vec2 aux_tex_coord_next = aux_tex_coord + vec2(1.0, 0.0); - - vec2 top_half = aux_tex_coord/screen_size * stride_scale; - vec2 top_half_next = aux_tex_coord_next/screen_size * stride_scale; - vec2 bottom_half = (aux_tex_coord + vec2(0.0, 8.0))/screen_size * stride_scale; - vec2 bottom_half_next = (aux_tex_coord_next + vec2(0.0, 8.0))/screen_size * stride_scale; - - float aux_b4 = texture2D(aux_y_texture, top_half).x; - float aux_b5 = texture2D(aux_y_texture, bottom_half).x; - float next_u = texture2D(aux_y_texture, top_half_next).x; - float next_v = texture2D(aux_y_texture, bottom_half_next).x; - vec2 aux_uv_additional = vec2(next_u, next_v); - - float aux_b6 = texture2D(aux_u_texture, main_tex_coord).x; - float aux_b7 = texture2D(aux_v_texture, main_tex_coord).x; - - float is_x_odd = mod(coordinates.x, 2.0); - float is_y_odd = mod(coordinates.y, 2.0); - float is_xy_even = (1.0 - is_x_odd) * (1.0 - is_y_odd); - - vec2 aux_uv_main = vec2(aux_b4, aux_b5); - vec2 aux_uv_secondary = vec2(aux_b6, aux_b7); - - vec2 uv_channels = is_y_odd * aux_uv_main + (1.0 - is_y_odd) * is_x_odd * aux_uv_secondary; - - // Apply the reverse filter when both (x, y) are even based on [MS-RDPEGFX] rule - vec2 main_uv=vec2(main_u_channel, main_v_channel); - vec2 uv_augmented = clamp(main_uv * 4.0 - aux_uv_main - aux_uv_secondary - aux_uv_additional, vec2(0.0, 0.0), vec2(1.0, 1.0)); - vec2 uv_diff = abs(uv_augmented - main_uv); - bvec2 uv_is_greater = greaterThan(uv_diff, CUTOFF); - vec2 uv_is_greater_vec = vec2(uv_is_greater.x, uv_is_greater.y); - vec2 uv_touse = uv_augmented * uv_is_greater_vec + main_uv * (vec2(1.0, 1.0) - uv_is_greater_vec); - - vec2 final_uv_channels = is_xy_even * uv_touse + (1.0 - is_xy_even) * uv_channels; - - vec4 channels = vec4(main_y_channel, final_uv_channels.x, final_uv_channels.y, 1.0); - vec3 rgb = (channels * conversion).xyz; - gl_FragColor = vec4(rgb, 1.0); +precision lowp float; + +uniform vec2 screen_size; +uniform vec2 stride_scale; +uniform sampler2D main_y_texture; +uniform sampler2D main_u_texture; +uniform sampler2D main_v_texture; + +uniform sampler2D aux_y_texture; +uniform sampler2D aux_u_texture; +uniform sampler2D aux_v_texture; + +const vec2 CUTOFF = vec2(30.0/255.0, 30.0/255.0); + +// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js +const mat4 conversion = mat4( + 1.16438, 0.00000, 1.79274, -0.97295, + 1.16438, -0.21325, -0.53291, 0.30148, + 1.16438, 2.11240, 0.00000, -1.13340, + 0, 0, 0, 1 +); + +const vec2 half_offset = vec2(0.5, 0.5); + +void main(void) { + vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y) ; + vec2 main_tex_coord = (coordinates / screen_size) * stride_scale; + // Query the main view + float main_y_channel = texture2D(main_y_texture, main_tex_coord).x; + float main_u_channel = texture2D(main_u_texture, main_tex_coord).x; + float main_v_channel = texture2D(main_v_texture, main_tex_coord).x; + + coordinates = coordinates - half_offset; + + float offset = floor(mod(coordinates.y, 16.0) * 0.5); + float start_y = offset + floor(coordinates.y / 16.0) * 16.0; + // Auxiliary view + vec2 aux_tex_coord = vec2(coordinates.x, start_y) + half_offset; + vec2 aux_tex_coord_next = aux_tex_coord + vec2(1.0, 0.0); + + vec2 top_half = aux_tex_coord/screen_size * stride_scale; + vec2 top_half_next = aux_tex_coord_next/screen_size * stride_scale; + vec2 bottom_half = (aux_tex_coord + vec2(0.0, 8.0))/screen_size * stride_scale; + vec2 bottom_half_next = (aux_tex_coord_next + vec2(0.0, 8.0))/screen_size * stride_scale; + + float aux_b4 = texture2D(aux_y_texture, top_half).x; + float aux_b5 = texture2D(aux_y_texture, bottom_half).x; + float next_u = texture2D(aux_y_texture, top_half_next).x; + float next_v = texture2D(aux_y_texture, bottom_half_next).x; + vec2 aux_uv_additional = vec2(next_u, next_v); + + float aux_b6 = texture2D(aux_u_texture, main_tex_coord).x; + float aux_b7 = texture2D(aux_v_texture, main_tex_coord).x; + + float is_x_odd = mod(coordinates.x, 2.0); + float is_y_odd = mod(coordinates.y, 2.0); + float is_xy_even = (1.0 - is_x_odd) * (1.0 - is_y_odd); + + vec2 aux_uv_main = vec2(aux_b4, aux_b5); + vec2 aux_uv_secondary = vec2(aux_b6, aux_b7); + + vec2 uv_channels = is_y_odd * aux_uv_main + (1.0 - is_y_odd) * is_x_odd * aux_uv_secondary; + + // Apply the reverse filter when both (x, y) are even based on [MS-RDPEGFX] rule + vec2 main_uv=vec2(main_u_channel, main_v_channel); + vec2 uv_augmented = clamp(main_uv * 4.0 - aux_uv_main - aux_uv_secondary - aux_uv_additional, vec2(0.0, 0.0), vec2(1.0, 1.0)); + vec2 uv_diff = abs(uv_augmented - main_uv); + bvec2 uv_is_greater = greaterThan(uv_diff, CUTOFF); + vec2 uv_is_greater_vec = vec2(uv_is_greater.x, uv_is_greater.y); + vec2 uv_touse = uv_augmented * uv_is_greater_vec + main_uv * (vec2(1.0, 1.0) - uv_is_greater_vec); + + vec2 final_uv_channels = is_xy_even * uv_touse + (1.0 - is_xy_even) * uv_channels; + + vec4 channels = vec4(main_y_channel, final_uv_channels.x, final_uv_channels.y, 1.0); + vec3 rgb = (channels * conversion).xyz; + gl_FragColor = vec4(rgb, 1.0); } \ No newline at end of file diff --git a/ironrdp-renderer/shaders/avc444v2.frag b/crates/glutin-renderer/shaders/avc444v2.frag similarity index 97% rename from ironrdp-renderer/shaders/avc444v2.frag rename to crates/glutin-renderer/shaders/avc444v2.frag index 6e72bfcc..872e206d 100644 --- a/ironrdp-renderer/shaders/avc444v2.frag +++ b/crates/glutin-renderer/shaders/avc444v2.frag @@ -1,79 +1,79 @@ -precision lowp float; - -uniform vec2 screen_size; -uniform vec2 stride_scale; -uniform sampler2D main_y_texture; -uniform sampler2D main_u_texture; -uniform sampler2D main_v_texture; - -uniform sampler2D aux_y_texture; -uniform sampler2D aux_u_texture; -uniform sampler2D aux_v_texture; - -const vec2 CUTOFF = vec2(30.0/255.0, 30.0/255.0); - -// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js -const mat4 conversion = mat4( - 1.16438, 0.00000, 1.79274, -0.97295, - 1.16438, -0.21325, -0.53291, 0.30148, - 1.16438, 2.11240, 0.00000, -1.13340, - 0, 0, 0, 1 -); - -const vec2 half_offset = vec2(0.5, 0.5); - -void main(void) { - - vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y); - - // Query the main view - vec2 main_tex_coord = (coordinates / screen_size) * stride_scale; - float main_y_channel = texture2D(main_y_texture, main_tex_coord).x; - float main_u_channel = texture2D(main_u_texture, main_tex_coord).x; - float main_v_channel = texture2D(main_v_texture, main_tex_coord).x; - - coordinates = coordinates - half_offset; - float left_x = coordinates.x * 0.5; - float right_x = (screen_size.x + coordinates.x) * 0.5; - - // Auxiliary view - // Left - vec2 left_half = (vec2(left_x, coordinates.y) + half_offset)/screen_size * stride_scale; - float aux_ub4 = texture2D(aux_y_texture, left_half).x; - float aux_ub6 = texture2D(aux_u_texture, left_half).x; - float aux_ub8 = texture2D(aux_v_texture, left_half).x; - - // Right - vec2 right_half = (vec2(right_x, coordinates.y) + half_offset)/screen_size * stride_scale; - float aux_vb5 = texture2D(aux_y_texture, right_half).x; - float aux_vb7 = texture2D(aux_u_texture, right_half).x; - float aux_vb9 = texture2D(aux_v_texture, right_half).x; - - // Create aux view - vec2 aux_uv_main = vec2(aux_ub4, aux_vb5); - vec2 aux_uv_left = vec2(aux_ub6, aux_vb7); - vec2 aux_uv_right = vec2(aux_ub8, aux_vb9); - - float is_x_odd = mod(coordinates.x, 2.0); - float is_y_odd = mod(coordinates.y, 2.0); - float is_xy_even = (1.0 - is_x_odd) * (1.0 - is_y_odd); - float is_x_mod_4 = float(mod(coordinates.x, 4.0) < 1.0); - - // If x is odd then b4,b5 have data - // else if y is odd then b6,b7 have data when x is divisible by 4 - // else b8,b9 have data - vec2 uv_channels = is_x_odd * aux_uv_main + (1.0 - is_x_odd) * is_y_odd * (is_x_mod_4 * aux_uv_left + (1.0 - is_x_mod_4) * aux_uv_right); - - // Apply the reverse filter when both (x, y) are even based on [MS-RDPEGFX] rule - vec2 main_uv=vec2(main_u_channel, main_v_channel); - vec2 uv_augmented = clamp(main_uv * 4.0 - aux_uv_main - aux_uv_left - aux_uv_right, vec2(0.0, 0.0), vec2(1.0, 1.0)); - vec2 uv_diff = abs(uv_augmented - main_uv); - bvec2 uv_is_greater = greaterThan(uv_diff, CUTOFF); - vec2 uv_is_greater_vec = vec2(uv_is_greater.x, uv_is_greater.y); - vec2 uv_touse = uv_augmented * uv_is_greater_vec + main_uv * (vec2(1.0, 1.0) - uv_is_greater_vec); - - vec2 final_uv_channels = is_xy_even * uv_touse + (1.0 - is_xy_even) * uv_channels; - vec4 channels = vec4(main_y_channel, final_uv_channels.x, final_uv_channels.y, 1.0); - vec3 rgb = (channels * conversion).xyz; - gl_FragColor = vec4(rgb, 1.0); +precision lowp float; + +uniform vec2 screen_size; +uniform vec2 stride_scale; +uniform sampler2D main_y_texture; +uniform sampler2D main_u_texture; +uniform sampler2D main_v_texture; + +uniform sampler2D aux_y_texture; +uniform sampler2D aux_u_texture; +uniform sampler2D aux_v_texture; + +const vec2 CUTOFF = vec2(30.0/255.0, 30.0/255.0); + +// YUV to RGB conversion matrix from https://github.com/mbebenita/Broadway/blob/master/Player/YUVCanvas.js +const mat4 conversion = mat4( + 1.16438, 0.00000, 1.79274, -0.97295, + 1.16438, -0.21325, -0.53291, 0.30148, + 1.16438, 2.11240, 0.00000, -1.13340, + 0, 0, 0, 1 +); + +const vec2 half_offset = vec2(0.5, 0.5); + +void main(void) { + + vec2 coordinates = vec2(gl_FragCoord.x, screen_size.y - gl_FragCoord.y); + + // Query the main view + vec2 main_tex_coord = (coordinates / screen_size) * stride_scale; + float main_y_channel = texture2D(main_y_texture, main_tex_coord).x; + float main_u_channel = texture2D(main_u_texture, main_tex_coord).x; + float main_v_channel = texture2D(main_v_texture, main_tex_coord).x; + + coordinates = coordinates - half_offset; + float left_x = coordinates.x * 0.5; + float right_x = (screen_size.x + coordinates.x) * 0.5; + + // Auxiliary view + // Left + vec2 left_half = (vec2(left_x, coordinates.y) + half_offset)/screen_size * stride_scale; + float aux_ub4 = texture2D(aux_y_texture, left_half).x; + float aux_ub6 = texture2D(aux_u_texture, left_half).x; + float aux_ub8 = texture2D(aux_v_texture, left_half).x; + + // Right + vec2 right_half = (vec2(right_x, coordinates.y) + half_offset)/screen_size * stride_scale; + float aux_vb5 = texture2D(aux_y_texture, right_half).x; + float aux_vb7 = texture2D(aux_u_texture, right_half).x; + float aux_vb9 = texture2D(aux_v_texture, right_half).x; + + // Create aux view + vec2 aux_uv_main = vec2(aux_ub4, aux_vb5); + vec2 aux_uv_left = vec2(aux_ub6, aux_vb7); + vec2 aux_uv_right = vec2(aux_ub8, aux_vb9); + + float is_x_odd = mod(coordinates.x, 2.0); + float is_y_odd = mod(coordinates.y, 2.0); + float is_xy_even = (1.0 - is_x_odd) * (1.0 - is_y_odd); + float is_x_mod_4 = float(mod(coordinates.x, 4.0) < 1.0); + + // If x is odd then b4,b5 have data + // else if y is odd then b6,b7 have data when x is divisible by 4 + // else b8,b9 have data + vec2 uv_channels = is_x_odd * aux_uv_main + (1.0 - is_x_odd) * is_y_odd * (is_x_mod_4 * aux_uv_left + (1.0 - is_x_mod_4) * aux_uv_right); + + // Apply the reverse filter when both (x, y) are even based on [MS-RDPEGFX] rule + vec2 main_uv=vec2(main_u_channel, main_v_channel); + vec2 uv_augmented = clamp(main_uv * 4.0 - aux_uv_main - aux_uv_left - aux_uv_right, vec2(0.0, 0.0), vec2(1.0, 1.0)); + vec2 uv_diff = abs(uv_augmented - main_uv); + bvec2 uv_is_greater = greaterThan(uv_diff, CUTOFF); + vec2 uv_is_greater_vec = vec2(uv_is_greater.x, uv_is_greater.y); + vec2 uv_touse = uv_augmented * uv_is_greater_vec + main_uv * (vec2(1.0, 1.0) - uv_is_greater_vec); + + vec2 final_uv_channels = is_xy_even * uv_touse + (1.0 - is_xy_even) * uv_channels; + vec4 channels = vec4(main_y_channel, final_uv_channels.x, final_uv_channels.y, 1.0); + vec3 rgb = (channels * conversion).xyz; + gl_FragColor = vec4(rgb, 1.0); } \ No newline at end of file diff --git a/ironrdp-renderer/shaders/texture_shader.frag b/crates/glutin-renderer/shaders/texture_shader.frag similarity index 95% rename from ironrdp-renderer/shaders/texture_shader.frag rename to crates/glutin-renderer/shaders/texture_shader.frag index bbbb22d2..bf62522f 100644 --- a/ironrdp-renderer/shaders/texture_shader.frag +++ b/crates/glutin-renderer/shaders/texture_shader.frag @@ -1,9 +1,9 @@ -precision lowp float; - -varying vec2 v_texCoord; -uniform sampler2D screen_texture; - -void main(void) { - vec4 color = texture2D(screen_texture, v_texCoord); - gl_FragColor = color; +precision lowp float; + +varying vec2 v_texCoord; +uniform sampler2D screen_texture; + +void main(void) { + vec4 color = texture2D(screen_texture, v_texCoord); + gl_FragColor = color; } \ No newline at end of file diff --git a/ironrdp-renderer/shaders/texture_shader.vert b/crates/glutin-renderer/shaders/texture_shader.vert similarity index 95% rename from ironrdp-renderer/shaders/texture_shader.vert rename to crates/glutin-renderer/shaders/texture_shader.vert index f9acb74e..cfcf6a18 100644 --- a/ironrdp-renderer/shaders/texture_shader.vert +++ b/crates/glutin-renderer/shaders/texture_shader.vert @@ -1,10 +1,10 @@ -precision mediump float; - -attribute vec2 a_position; -attribute vec2 a_tex_coord; -varying vec2 v_texCoord; - -void main(){ - v_texCoord = a_tex_coord; - gl_Position = vec4(a_position, 0.0, 1.0); +precision mediump float; + +attribute vec2 a_position; +attribute vec2 a_tex_coord; +varying vec2 v_texCoord; + +void main(){ + v_texCoord = a_tex_coord; + gl_Position = vec4(a_position, 0.0, 1.0); } \ No newline at end of file diff --git a/ironrdp-renderer/src/draw.rs b/crates/glutin-renderer/src/draw.rs similarity index 99% rename from ironrdp-renderer/src/draw.rs rename to crates/glutin-renderer/src/draw.rs index c7dceae4..17da9c08 100644 --- a/ironrdp-renderer/src/draw.rs +++ b/crates/glutin-renderer/src/draw.rs @@ -4,7 +4,7 @@ use std::slice::from_raw_parts; use std::sync::Arc; use glow::*; -use ironrdp::geometry::Rectangle; +use ironrdp::pdu::geometry::Rectangle; fn cast_as_bytes(input: &[T]) -> &[u8] { unsafe { from_raw_parts(input.as_ptr() as *const u8, input.len() * size_of::()) } diff --git a/ironrdp-renderer/src/lib.rs b/crates/glutin-renderer/src/lib.rs similarity index 100% rename from ironrdp-renderer/src/lib.rs rename to crates/glutin-renderer/src/lib.rs diff --git a/ironrdp-renderer/src/renderer.rs b/crates/glutin-renderer/src/renderer.rs similarity index 97% rename from ironrdp-renderer/src/renderer.rs rename to crates/glutin-renderer/src/renderer.rs index dc70c557..532d8310 100644 --- a/ironrdp-renderer/src/renderer.rs +++ b/crates/glutin-renderer/src/renderer.rs @@ -7,10 +7,10 @@ use std::thread; use std::thread::JoinHandle; use glutin::dpi::PhysicalSize; -use ironrdp::dvc::gfx; -use ironrdp::dvc::gfx::{Codec1Type, ServerPdu}; -use ironrdp::geometry::Rectangle; -use ironrdp::PduParsing; +use ironrdp::pdu::dvc::gfx; +use ironrdp::pdu::dvc::gfx::{Codec1Type, ServerPdu}; +use ironrdp::pdu::geometry::Rectangle; +use ironrdp::pdu::PduParsing; use log::info; use thiserror::Error; diff --git a/ironrdp-renderer/src/surface.rs b/crates/glutin-renderer/src/surface.rs similarity index 96% rename from ironrdp-renderer/src/surface.rs rename to crates/glutin-renderer/src/surface.rs index df5c6fb9..9eee6ded 100644 --- a/ironrdp-renderer/src/surface.rs +++ b/crates/glutin-renderer/src/surface.rs @@ -3,12 +3,12 @@ use std::fmt::Debug; use std::sync::Arc; use glow::Context; -use ironrdp::core::dvc::gfx::{ +use ironrdp::pdu::dvc::gfx::{ Avc420BitmapStream, Avc444BitmapStream, Codec1Type, CreateSurfacePdu, Encoding, GraphicsPipelineError, PixelFormat, WireToSurface1Pdu, }; -use ironrdp::core::PduBufferParsing; -use ironrdp::geometry::Rectangle; +use ironrdp::pdu::geometry::Rectangle; +use ironrdp::pdu::PduBufferParsing; use log::error; use openh264::decoder::{DecodedYUV, Decoder}; @@ -58,7 +58,7 @@ impl SurfaceDecoders { .get_mut(&pdu.surface_id) .ok_or(RendererError::InvalidSurfaceId(pdu.surface_id))?; match pdu.codec_id { - ironrdp::dvc::gfx::Codec1Type::Avc420 => { + ironrdp::pdu::dvc::gfx::Codec1Type::Avc420 => { let packet = Avc420BitmapStream::from_buffer_consume(&mut pdu.bitmap_data.as_slice()) .map_err(GraphicsPipelineError::from)?; let yuv = decoder.decode(packet.data)?.ok_or(RendererError::DecodeError)?; @@ -77,7 +77,7 @@ impl SurfaceDecoders { dimensions, }) } - ironrdp::dvc::gfx::Codec1Type::Avc444 | ironrdp::dvc::gfx::Codec1Type::Avc444v2 => { + ironrdp::pdu::dvc::gfx::Codec1Type::Avc444 | ironrdp::pdu::dvc::gfx::Codec1Type::Avc444v2 => { let packet = Avc444BitmapStream::from_buffer_consume(&mut pdu.bitmap_data.as_slice()) .map_err(GraphicsPipelineError::from)?; let yuv = decoder.decode(packet.stream1.data)?.ok_or(RendererError::DecodeError)?; @@ -304,7 +304,7 @@ impl Surfaces { pub(crate) fn map_surface_to_scaled_output( &mut self, - pdu: ironrdp::dvc::gfx::MapSurfaceToScaledOutputPdu, + pdu: ironrdp::pdu::dvc::gfx::MapSurfaceToScaledOutputPdu, ) -> Result<()> { let surface = self.get_surface(pdu.surface_id)?; surface.set_location(Rectangle { diff --git a/ironrdp-graphics/Cargo.toml b/crates/graphics/Cargo.toml similarity index 93% rename from ironrdp-graphics/Cargo.toml rename to crates/graphics/Cargo.toml index ce281bd2..214717e0 100644 --- a/ironrdp-graphics/Cargo.toml +++ b/crates/graphics/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/Devolutions/IronRDP" authors = ["Devolutions Inc. "] [dependencies] -ironrdp-core = { path = "../ironrdp-core" } +ironrdp-pdu = { path = "../pdu" } num-traits = "0.2.15" num-derive = "0.3.3" byteorder = "1.4.3" diff --git a/ironrdp-graphics/README.md b/crates/graphics/README.md similarity index 100% rename from ironrdp-graphics/README.md rename to crates/graphics/README.md diff --git a/ironrdp-graphics/src/color_conversion.rs b/crates/graphics/src/color_conversion.rs similarity index 100% rename from ironrdp-graphics/src/color_conversion.rs rename to crates/graphics/src/color_conversion.rs diff --git a/ironrdp-graphics/src/dwt.rs b/crates/graphics/src/dwt.rs similarity index 98% rename from ironrdp-graphics/src/dwt.rs rename to crates/graphics/src/dwt.rs index 44d87843..bc8d988c 100644 --- a/ironrdp-graphics/src/dwt.rs +++ b/crates/graphics/src/dwt.rs @@ -1,4 +1,4 @@ -use ironrdp_core::utils::SplitTo as _; +use ironrdp_pdu::utils::SplitTo as _; pub fn decode(buffer: &mut [i16], temp_buffer: &mut [i16]) { decode_block(&mut buffer[3840..], temp_buffer, 8); diff --git a/ironrdp-graphics/src/image_processing.rs b/crates/graphics/src/image_processing.rs similarity index 99% rename from ironrdp-graphics/src/image_processing.rs rename to crates/graphics/src/image_processing.rs index d047ba4a..1e6b2b50 100644 --- a/ironrdp-graphics/src/image_processing.rs +++ b/crates/graphics/src/image_processing.rs @@ -1,7 +1,7 @@ use std::io; use byteorder::WriteBytesExt; -use ironrdp_core::geometry::Rectangle; +use ironrdp_pdu::geometry::Rectangle; use num_derive::ToPrimitive; use num_traits::ToPrimitive as _; diff --git a/ironrdp-graphics/src/lib.rs b/crates/graphics/src/lib.rs similarity index 100% rename from ironrdp-graphics/src/lib.rs rename to crates/graphics/src/lib.rs diff --git a/ironrdp-graphics/src/quantization.rs b/crates/graphics/src/quantization.rs similarity index 99% rename from ironrdp-graphics/src/quantization.rs rename to crates/graphics/src/quantization.rs index 3e512ad0..cfb353ea 100644 --- a/ironrdp-graphics/src/quantization.rs +++ b/crates/graphics/src/quantization.rs @@ -1,4 +1,4 @@ -use ironrdp_core::codecs::rfx::Quant; +use ironrdp_pdu::codecs::rfx::Quant; const FIRST_LEVEL_SIZE: usize = 1024; const SECOND_LEVEL_SIZE: usize = 256; diff --git a/ironrdp-graphics/src/rectangle_processing.rs b/crates/graphics/src/rectangle_processing.rs similarity index 99% rename from ironrdp-graphics/src/rectangle_processing.rs rename to crates/graphics/src/rectangle_processing.rs index 8829585f..24ff1e14 100644 --- a/ironrdp-graphics/src/rectangle_processing.rs +++ b/crates/graphics/src/rectangle_processing.rs @@ -1,6 +1,6 @@ use std::cmp::{max, min}; -use ironrdp_core::geometry::Rectangle; +use ironrdp_pdu::geometry::Rectangle; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Region { diff --git a/ironrdp-graphics/src/rle.rs b/crates/graphics/src/rle.rs similarity index 100% rename from ironrdp-graphics/src/rle.rs rename to crates/graphics/src/rle.rs diff --git a/ironrdp-graphics/src/rlgr.rs b/crates/graphics/src/rlgr.rs similarity index 99% rename from ironrdp-graphics/src/rlgr.rs rename to crates/graphics/src/rlgr.rs index 596ec0e4..5e41a023 100644 --- a/ironrdp-graphics/src/rlgr.rs +++ b/crates/graphics/src/rlgr.rs @@ -4,7 +4,7 @@ use std::io; use bitvec::field::BitField as _; use bitvec::order::Msb0; use bitvec::slice::BitSlice; -use ironrdp_core::codecs::rfx::EntropyAlgorithm; +use ironrdp_pdu::codecs::rfx::EntropyAlgorithm; use thiserror::Error; use crate::utils::Bits; diff --git a/ironrdp-graphics/src/subband_reconstruction.rs b/crates/graphics/src/subband_reconstruction.rs similarity index 100% rename from ironrdp-graphics/src/subband_reconstruction.rs rename to crates/graphics/src/subband_reconstruction.rs diff --git a/ironrdp-graphics/src/utils.rs b/crates/graphics/src/utils.rs similarity index 100% rename from ironrdp-graphics/src/utils.rs rename to crates/graphics/src/utils.rs diff --git a/ironrdp-graphics/src/zgfx/circular_buffer.rs b/crates/graphics/src/zgfx/circular_buffer.rs similarity index 100% rename from ironrdp-graphics/src/zgfx/circular_buffer.rs rename to crates/graphics/src/zgfx/circular_buffer.rs diff --git a/ironrdp-graphics/src/zgfx/control_messages.rs b/crates/graphics/src/zgfx/control_messages.rs similarity index 100% rename from ironrdp-graphics/src/zgfx/control_messages.rs rename to crates/graphics/src/zgfx/control_messages.rs diff --git a/ironrdp-graphics/src/zgfx/mod.rs b/crates/graphics/src/zgfx/mod.rs similarity index 100% rename from ironrdp-graphics/src/zgfx/mod.rs rename to crates/graphics/src/zgfx/mod.rs diff --git a/ironrdp-graphics/tests/color_conversion.rs b/crates/graphics/tests/color_conversion.rs similarity index 100% rename from ironrdp-graphics/tests/color_conversion.rs rename to crates/graphics/tests/color_conversion.rs diff --git a/ironrdp-graphics/tests/dwt.rs b/crates/graphics/tests/dwt.rs similarity index 100% rename from ironrdp-graphics/tests/dwt.rs rename to crates/graphics/tests/dwt.rs diff --git a/ironrdp-graphics/tests/image_processing.rs b/crates/graphics/tests/image_processing.rs similarity index 99% rename from ironrdp-graphics/tests/image_processing.rs rename to crates/graphics/tests/image_processing.rs index 24c42fb4..a7ef141f 100644 --- a/ironrdp-graphics/tests/image_processing.rs +++ b/crates/graphics/tests/image_processing.rs @@ -1,7 +1,7 @@ use std::io; -use ironrdp_core::geometry::Rectangle; use ironrdp_graphics::image_processing::*; +use ironrdp_pdu::geometry::Rectangle; use proptest::prelude::*; fn bgra_to_rgba(input: &[u8], mut output: &mut [u8]) -> io::Result<()> { diff --git a/ironrdp-graphics/tests/rle.rs b/crates/graphics/tests/rle.rs similarity index 100% rename from ironrdp-graphics/tests/rle.rs rename to crates/graphics/tests/rle.rs diff --git a/ironrdp-graphics/tests/rlgr.rs b/crates/graphics/tests/rlgr.rs similarity index 99% rename from ironrdp-graphics/tests/rlgr.rs rename to crates/graphics/tests/rlgr.rs index 1a71019e..87a07c7f 100644 --- a/ironrdp-graphics/tests/rlgr.rs +++ b/crates/graphics/tests/rlgr.rs @@ -1,5 +1,5 @@ -use ironrdp_core::codecs::rfx::EntropyAlgorithm; use ironrdp_graphics::rlgr::*; +use ironrdp_pdu::codecs::rfx::EntropyAlgorithm; #[test] fn decode_works_with_rlgr3() { diff --git a/ironrdp-input/Cargo.toml b/crates/input/Cargo.toml similarity index 90% rename from ironrdp-input/Cargo.toml rename to crates/input/Cargo.toml index b31a8562..67cfe05a 100644 --- a/ironrdp-input/Cargo.toml +++ b/crates/input/Cargo.toml @@ -9,8 +9,8 @@ repository = "https://github.com/Devolutions/IronRDP" authors = ["Devolutions Inc. "] [dependencies] +ironrdp-pdu = { path = "../pdu" } bitvec = "1.0.1" -ironrdp-core = { path = "../ironrdp-core" } smallvec = "1.10.0" [dev-dependencies] diff --git a/ironrdp-input/README.md b/crates/input/README.md similarity index 100% rename from ironrdp-input/README.md rename to crates/input/README.md diff --git a/ironrdp-input/src/lib.rs b/crates/input/src/lib.rs similarity index 97% rename from ironrdp-input/src/lib.rs rename to crates/input/src/lib.rs index 74423bc7..dda534ac 100644 --- a/ironrdp-input/src/lib.rs +++ b/crates/input/src/lib.rs @@ -1,9 +1,9 @@ use bitvec::array::BitArray; use bitvec::BitArr; -use ironrdp_core::input::fast_path::{FastPathInputEvent, KeyboardFlags}; -use ironrdp_core::input::mouse::PointerFlags; -use ironrdp_core::input::mouse_x::PointerXFlags; -use ironrdp_core::input::{MousePdu, MouseXPdu}; +use ironrdp_pdu::input::fast_path::{FastPathInputEvent, KeyboardFlags}; +use ironrdp_pdu::input::mouse::PointerFlags; +use ironrdp_pdu::input::mouse_x::PointerXFlags; +use ironrdp_pdu::input::{MousePdu, MouseXPdu}; use smallvec::SmallVec; // TODO: unicode keyboard event support @@ -345,7 +345,7 @@ impl Database { /// Returns the RDP input event to send in order to synchronize lock keys. pub fn synchronize_event(scroll_lock: bool, num_lock: bool, caps_lock: bool, kana_lock: bool) -> FastPathInputEvent { - use ironrdp_core::input::fast_path::SynchronizeFlags; + use ironrdp_pdu::input::fast_path::SynchronizeFlags; let mut flags = SynchronizeFlags::empty(); diff --git a/ironrdp-input/tests/fastpath_packets.rs b/crates/input/tests/fastpath_packets.rs similarity index 98% rename from ironrdp-input/tests/fastpath_packets.rs rename to crates/input/tests/fastpath_packets.rs index 7f247d65..98984c2a 100644 --- a/ironrdp-input/tests/fastpath_packets.rs +++ b/crates/input/tests/fastpath_packets.rs @@ -1,8 +1,8 @@ -use ironrdp_core::input::fast_path::{FastPathInputEvent, KeyboardFlags, SynchronizeFlags}; -use ironrdp_core::input::mouse::PointerFlags; -use ironrdp_core::input::mouse_x::PointerXFlags; -use ironrdp_core::input::{MousePdu, MouseXPdu}; use ironrdp_input::*; +use ironrdp_pdu::input::fast_path::{FastPathInputEvent, KeyboardFlags, SynchronizeFlags}; +use ironrdp_pdu::input::mouse::PointerFlags; +use ironrdp_pdu::input::mouse_x::PointerXFlags; +use ironrdp_pdu::input::{MousePdu, MouseXPdu}; use rstest::rstest; enum MouseFlags { diff --git a/ironrdp-input/tests/smoke.rs b/crates/input/tests/smoke.rs similarity index 98% rename from ironrdp-input/tests/smoke.rs rename to crates/input/tests/smoke.rs index 4c9625be..8dfef14e 100644 --- a/ironrdp-input/tests/smoke.rs +++ b/crates/input/tests/smoke.rs @@ -1,6 +1,6 @@ use anyhow::{bail, ensure}; -use ironrdp_core::input::fast_path::{FastPathInputEvent, KeyboardFlags}; use ironrdp_input::*; +use ironrdp_pdu::input::fast_path::{FastPathInputEvent, KeyboardFlags}; use proptest::collection::vec; use proptest::prelude::*; diff --git a/crates/pdu-generators/Cargo.toml b/crates/pdu-generators/Cargo.toml new file mode 100644 index 00000000..524882c5 --- /dev/null +++ b/crates/pdu-generators/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ironrdp-pdu-generators" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +ironrdp-pdu = { path = "../pdu" } +proptest = "1.1.0" diff --git a/crates/pdu-generators/src/lib.rs b/crates/pdu-generators/src/lib.rs new file mode 100644 index 00000000..7d12d9af --- /dev/null +++ b/crates/pdu-generators/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/ironrdp-core/Cargo.toml b/crates/pdu/Cargo.toml similarity index 96% rename from ironrdp-core/Cargo.toml rename to crates/pdu/Cargo.toml index b39b2934..bbd4fd50 100644 --- a/ironrdp-core/Cargo.toml +++ b/crates/pdu/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironrdp-core" +name = "ironrdp-pdu" version = "0.1.0" edition = "2021" readme = "README.md" diff --git a/ironrdp-core/README.md b/crates/pdu/README.md similarity index 100% rename from ironrdp-core/README.md rename to crates/pdu/README.md diff --git a/ironrdp-core/src/basic_output.rs b/crates/pdu/src/basic_output.rs similarity index 100% rename from ironrdp-core/src/basic_output.rs rename to crates/pdu/src/basic_output.rs diff --git a/ironrdp-core/src/basic_output/bitmap.rs b/crates/pdu/src/basic_output/bitmap.rs similarity index 100% rename from ironrdp-core/src/basic_output/bitmap.rs rename to crates/pdu/src/basic_output/bitmap.rs diff --git a/ironrdp-core/src/basic_output/bitmap/tests.rs b/crates/pdu/src/basic_output/bitmap/tests.rs similarity index 100% rename from ironrdp-core/src/basic_output/bitmap/tests.rs rename to crates/pdu/src/basic_output/bitmap/tests.rs diff --git a/ironrdp-core/src/basic_output/fast_path.rs b/crates/pdu/src/basic_output/fast_path.rs similarity index 100% rename from ironrdp-core/src/basic_output/fast_path.rs rename to crates/pdu/src/basic_output/fast_path.rs diff --git a/ironrdp-core/src/basic_output/fast_path/test.rs b/crates/pdu/src/basic_output/fast_path/test.rs similarity index 100% rename from ironrdp-core/src/basic_output/fast_path/test.rs rename to crates/pdu/src/basic_output/fast_path/test.rs diff --git a/ironrdp-core/src/basic_output/surface_commands.rs b/crates/pdu/src/basic_output/surface_commands.rs similarity index 100% rename from ironrdp-core/src/basic_output/surface_commands.rs rename to crates/pdu/src/basic_output/surface_commands.rs diff --git a/ironrdp-core/src/basic_output/surface_commands/tests.rs b/crates/pdu/src/basic_output/surface_commands/tests.rs similarity index 100% rename from ironrdp-core/src/basic_output/surface_commands/tests.rs rename to crates/pdu/src/basic_output/surface_commands/tests.rs diff --git a/ironrdp-core/src/ber.rs b/crates/pdu/src/ber.rs similarity index 100% rename from ironrdp-core/src/ber.rs rename to crates/pdu/src/ber.rs diff --git a/ironrdp-core/src/ber/tests.rs b/crates/pdu/src/ber/tests.rs similarity index 100% rename from ironrdp-core/src/ber/tests.rs rename to crates/pdu/src/ber/tests.rs diff --git a/ironrdp-core/src/codecs.rs b/crates/pdu/src/codecs.rs similarity index 100% rename from ironrdp-core/src/codecs.rs rename to crates/pdu/src/codecs.rs diff --git a/ironrdp-core/src/codecs/rfx.rs b/crates/pdu/src/codecs/rfx.rs similarity index 100% rename from ironrdp-core/src/codecs/rfx.rs rename to crates/pdu/src/codecs/rfx.rs diff --git a/ironrdp-core/src/codecs/rfx/data_messages.rs b/crates/pdu/src/codecs/rfx/data_messages.rs similarity index 100% rename from ironrdp-core/src/codecs/rfx/data_messages.rs rename to crates/pdu/src/codecs/rfx/data_messages.rs diff --git a/ironrdp-core/src/codecs/rfx/header_messages.rs b/crates/pdu/src/codecs/rfx/header_messages.rs similarity index 100% rename from ironrdp-core/src/codecs/rfx/header_messages.rs rename to crates/pdu/src/codecs/rfx/header_messages.rs diff --git a/ironrdp-core/src/codecs/rfx/tests.rs b/crates/pdu/src/codecs/rfx/tests.rs similarity index 100% rename from ironrdp-core/src/codecs/rfx/tests.rs rename to crates/pdu/src/codecs/rfx/tests.rs diff --git a/ironrdp-core/src/connection_initiation.rs b/crates/pdu/src/connection_initiation.rs similarity index 100% rename from ironrdp-core/src/connection_initiation.rs rename to crates/pdu/src/connection_initiation.rs diff --git a/ironrdp-core/src/crypto.rs b/crates/pdu/src/crypto.rs similarity index 100% rename from ironrdp-core/src/crypto.rs rename to crates/pdu/src/crypto.rs diff --git a/ironrdp-core/src/crypto/rc4.rs b/crates/pdu/src/crypto/rc4.rs similarity index 100% rename from ironrdp-core/src/crypto/rc4.rs rename to crates/pdu/src/crypto/rc4.rs diff --git a/ironrdp-core/src/crypto/rsa.rs b/crates/pdu/src/crypto/rsa.rs similarity index 100% rename from ironrdp-core/src/crypto/rsa.rs rename to crates/pdu/src/crypto/rsa.rs diff --git a/ironrdp-core/src/gcc.rs b/crates/pdu/src/gcc.rs similarity index 100% rename from ironrdp-core/src/gcc.rs rename to crates/pdu/src/gcc.rs diff --git a/ironrdp-core/src/gcc/cluster_data.rs b/crates/pdu/src/gcc/cluster_data.rs similarity index 100% rename from ironrdp-core/src/gcc/cluster_data.rs rename to crates/pdu/src/gcc/cluster_data.rs diff --git a/ironrdp-core/src/gcc/cluster_data/test.rs b/crates/pdu/src/gcc/cluster_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/cluster_data/test.rs rename to crates/pdu/src/gcc/cluster_data/test.rs diff --git a/ironrdp-core/src/gcc/conference_create.rs b/crates/pdu/src/gcc/conference_create.rs similarity index 100% rename from ironrdp-core/src/gcc/conference_create.rs rename to crates/pdu/src/gcc/conference_create.rs diff --git a/ironrdp-core/src/gcc/conference_create/test.rs b/crates/pdu/src/gcc/conference_create/test.rs similarity index 100% rename from ironrdp-core/src/gcc/conference_create/test.rs rename to crates/pdu/src/gcc/conference_create/test.rs diff --git a/ironrdp-core/src/gcc/core_data.rs b/crates/pdu/src/gcc/core_data.rs similarity index 100% rename from ironrdp-core/src/gcc/core_data.rs rename to crates/pdu/src/gcc/core_data.rs diff --git a/ironrdp-core/src/gcc/core_data/client.rs b/crates/pdu/src/gcc/core_data/client.rs similarity index 100% rename from ironrdp-core/src/gcc/core_data/client.rs rename to crates/pdu/src/gcc/core_data/client.rs diff --git a/ironrdp-core/src/gcc/core_data/client/test.rs b/crates/pdu/src/gcc/core_data/client/test.rs similarity index 100% rename from ironrdp-core/src/gcc/core_data/client/test.rs rename to crates/pdu/src/gcc/core_data/client/test.rs diff --git a/ironrdp-core/src/gcc/core_data/server.rs b/crates/pdu/src/gcc/core_data/server.rs similarity index 100% rename from ironrdp-core/src/gcc/core_data/server.rs rename to crates/pdu/src/gcc/core_data/server.rs diff --git a/ironrdp-core/src/gcc/core_data/server/test.rs b/crates/pdu/src/gcc/core_data/server/test.rs similarity index 100% rename from ironrdp-core/src/gcc/core_data/server/test.rs rename to crates/pdu/src/gcc/core_data/server/test.rs diff --git a/ironrdp-core/src/gcc/message_channel_data.rs b/crates/pdu/src/gcc/message_channel_data.rs similarity index 100% rename from ironrdp-core/src/gcc/message_channel_data.rs rename to crates/pdu/src/gcc/message_channel_data.rs diff --git a/ironrdp-core/src/gcc/message_channel_data/test.rs b/crates/pdu/src/gcc/message_channel_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/message_channel_data/test.rs rename to crates/pdu/src/gcc/message_channel_data/test.rs diff --git a/ironrdp-core/src/gcc/monitor_data.rs b/crates/pdu/src/gcc/monitor_data.rs similarity index 100% rename from ironrdp-core/src/gcc/monitor_data.rs rename to crates/pdu/src/gcc/monitor_data.rs diff --git a/ironrdp-core/src/gcc/monitor_data/test.rs b/crates/pdu/src/gcc/monitor_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/monitor_data/test.rs rename to crates/pdu/src/gcc/monitor_data/test.rs diff --git a/ironrdp-core/src/gcc/monitor_extended_data.rs b/crates/pdu/src/gcc/monitor_extended_data.rs similarity index 100% rename from ironrdp-core/src/gcc/monitor_extended_data.rs rename to crates/pdu/src/gcc/monitor_extended_data.rs diff --git a/ironrdp-core/src/gcc/monitor_extended_data/test.rs b/crates/pdu/src/gcc/monitor_extended_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/monitor_extended_data/test.rs rename to crates/pdu/src/gcc/monitor_extended_data/test.rs diff --git a/ironrdp-core/src/gcc/multi_transport_channel_data.rs b/crates/pdu/src/gcc/multi_transport_channel_data.rs similarity index 100% rename from ironrdp-core/src/gcc/multi_transport_channel_data.rs rename to crates/pdu/src/gcc/multi_transport_channel_data.rs diff --git a/ironrdp-core/src/gcc/multi_transport_channel_data/test.rs b/crates/pdu/src/gcc/multi_transport_channel_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/multi_transport_channel_data/test.rs rename to crates/pdu/src/gcc/multi_transport_channel_data/test.rs diff --git a/ironrdp-core/src/gcc/network_data.rs b/crates/pdu/src/gcc/network_data.rs similarity index 100% rename from ironrdp-core/src/gcc/network_data.rs rename to crates/pdu/src/gcc/network_data.rs diff --git a/ironrdp-core/src/gcc/network_data/test.rs b/crates/pdu/src/gcc/network_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/network_data/test.rs rename to crates/pdu/src/gcc/network_data/test.rs diff --git a/ironrdp-core/src/gcc/security_data.rs b/crates/pdu/src/gcc/security_data.rs similarity index 100% rename from ironrdp-core/src/gcc/security_data.rs rename to crates/pdu/src/gcc/security_data.rs diff --git a/ironrdp-core/src/gcc/security_data/test.rs b/crates/pdu/src/gcc/security_data/test.rs similarity index 100% rename from ironrdp-core/src/gcc/security_data/test.rs rename to crates/pdu/src/gcc/security_data/test.rs diff --git a/ironrdp-core/src/gcc/tests.rs b/crates/pdu/src/gcc/tests.rs similarity index 100% rename from ironrdp-core/src/gcc/tests.rs rename to crates/pdu/src/gcc/tests.rs diff --git a/ironrdp-core/src/geometry.rs b/crates/pdu/src/geometry.rs similarity index 100% rename from ironrdp-core/src/geometry.rs rename to crates/pdu/src/geometry.rs diff --git a/ironrdp-core/src/input.rs b/crates/pdu/src/input.rs similarity index 100% rename from ironrdp-core/src/input.rs rename to crates/pdu/src/input.rs diff --git a/ironrdp-core/src/input/fast_path.rs b/crates/pdu/src/input/fast_path.rs similarity index 100% rename from ironrdp-core/src/input/fast_path.rs rename to crates/pdu/src/input/fast_path.rs diff --git a/ironrdp-core/src/input/mouse.rs b/crates/pdu/src/input/mouse.rs similarity index 100% rename from ironrdp-core/src/input/mouse.rs rename to crates/pdu/src/input/mouse.rs diff --git a/ironrdp-core/src/input/mouse_x.rs b/crates/pdu/src/input/mouse_x.rs similarity index 100% rename from ironrdp-core/src/input/mouse_x.rs rename to crates/pdu/src/input/mouse_x.rs diff --git a/ironrdp-core/src/input/scan_code.rs b/crates/pdu/src/input/scan_code.rs similarity index 100% rename from ironrdp-core/src/input/scan_code.rs rename to crates/pdu/src/input/scan_code.rs diff --git a/ironrdp-core/src/input/sync.rs b/crates/pdu/src/input/sync.rs similarity index 100% rename from ironrdp-core/src/input/sync.rs rename to crates/pdu/src/input/sync.rs diff --git a/ironrdp-core/src/input/tests.rs b/crates/pdu/src/input/tests.rs similarity index 100% rename from ironrdp-core/src/input/tests.rs rename to crates/pdu/src/input/tests.rs diff --git a/ironrdp-core/src/input/unicode.rs b/crates/pdu/src/input/unicode.rs similarity index 100% rename from ironrdp-core/src/input/unicode.rs rename to crates/pdu/src/input/unicode.rs diff --git a/ironrdp-core/src/input/unused.rs b/crates/pdu/src/input/unused.rs similarity index 100% rename from ironrdp-core/src/input/unused.rs rename to crates/pdu/src/input/unused.rs diff --git a/ironrdp-core/src/lib.rs b/crates/pdu/src/lib.rs similarity index 100% rename from ironrdp-core/src/lib.rs rename to crates/pdu/src/lib.rs diff --git a/ironrdp-core/src/macros.rs b/crates/pdu/src/macros.rs similarity index 100% rename from ironrdp-core/src/macros.rs rename to crates/pdu/src/macros.rs diff --git a/ironrdp-core/src/mcs.rs b/crates/pdu/src/mcs.rs similarity index 100% rename from ironrdp-core/src/mcs.rs rename to crates/pdu/src/mcs.rs diff --git a/ironrdp-core/src/mcs/connect_initial.rs b/crates/pdu/src/mcs/connect_initial.rs similarity index 100% rename from ironrdp-core/src/mcs/connect_initial.rs rename to crates/pdu/src/mcs/connect_initial.rs diff --git a/ironrdp-core/src/mcs/connect_initial/test.rs b/crates/pdu/src/mcs/connect_initial/test.rs similarity index 100% rename from ironrdp-core/src/mcs/connect_initial/test.rs rename to crates/pdu/src/mcs/connect_initial/test.rs diff --git a/ironrdp-core/src/mcs/tests.rs b/crates/pdu/src/mcs/tests.rs similarity index 100% rename from ironrdp-core/src/mcs/tests.rs rename to crates/pdu/src/mcs/tests.rs diff --git a/ironrdp-core/src/per.rs b/crates/pdu/src/per.rs similarity index 100% rename from ironrdp-core/src/per.rs rename to crates/pdu/src/per.rs diff --git a/ironrdp-core/src/per/test.rs b/crates/pdu/src/per/test.rs similarity index 100% rename from ironrdp-core/src/per/test.rs rename to crates/pdu/src/per/test.rs diff --git a/ironrdp-core/src/preconnection.rs b/crates/pdu/src/preconnection.rs similarity index 100% rename from ironrdp-core/src/preconnection.rs rename to crates/pdu/src/preconnection.rs diff --git a/ironrdp-core/src/rdp.rs b/crates/pdu/src/rdp.rs similarity index 100% rename from ironrdp-core/src/rdp.rs rename to crates/pdu/src/rdp.rs diff --git a/ironrdp-core/src/rdp/capability_sets.rs b/crates/pdu/src/rdp/capability_sets.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets.rs rename to crates/pdu/src/rdp/capability_sets.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap.rs b/crates/pdu/src/rdp/capability_sets/bitmap.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap.rs rename to crates/pdu/src/rdp/capability_sets/bitmap.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap/test.rs b/crates/pdu/src/rdp/capability_sets/bitmap/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap/test.rs rename to crates/pdu/src/rdp/capability_sets/bitmap/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap_cache.rs b/crates/pdu/src/rdp/capability_sets/bitmap_cache.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap_cache.rs rename to crates/pdu/src/rdp/capability_sets/bitmap_cache.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap_cache/test.rs b/crates/pdu/src/rdp/capability_sets/bitmap_cache/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap_cache/test.rs rename to crates/pdu/src/rdp/capability_sets/bitmap_cache/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap_codecs.rs b/crates/pdu/src/rdp/capability_sets/bitmap_codecs.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap_codecs.rs rename to crates/pdu/src/rdp/capability_sets/bitmap_codecs.rs diff --git a/ironrdp-core/src/rdp/capability_sets/bitmap_codecs/test.rs b/crates/pdu/src/rdp/capability_sets/bitmap_codecs/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/bitmap_codecs/test.rs rename to crates/pdu/src/rdp/capability_sets/bitmap_codecs/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/brush.rs b/crates/pdu/src/rdp/capability_sets/brush.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/brush.rs rename to crates/pdu/src/rdp/capability_sets/brush.rs diff --git a/ironrdp-core/src/rdp/capability_sets/brush/test.rs b/crates/pdu/src/rdp/capability_sets/brush/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/brush/test.rs rename to crates/pdu/src/rdp/capability_sets/brush/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/frame_acknowledge.rs b/crates/pdu/src/rdp/capability_sets/frame_acknowledge.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/frame_acknowledge.rs rename to crates/pdu/src/rdp/capability_sets/frame_acknowledge.rs diff --git a/ironrdp-core/src/rdp/capability_sets/general.rs b/crates/pdu/src/rdp/capability_sets/general.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/general.rs rename to crates/pdu/src/rdp/capability_sets/general.rs diff --git a/ironrdp-core/src/rdp/capability_sets/general/test.rs b/crates/pdu/src/rdp/capability_sets/general/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/general/test.rs rename to crates/pdu/src/rdp/capability_sets/general/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/glyph_cache.rs b/crates/pdu/src/rdp/capability_sets/glyph_cache.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/glyph_cache.rs rename to crates/pdu/src/rdp/capability_sets/glyph_cache.rs diff --git a/ironrdp-core/src/rdp/capability_sets/glyph_cache/test.rs b/crates/pdu/src/rdp/capability_sets/glyph_cache/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/glyph_cache/test.rs rename to crates/pdu/src/rdp/capability_sets/glyph_cache/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/input.rs b/crates/pdu/src/rdp/capability_sets/input.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/input.rs rename to crates/pdu/src/rdp/capability_sets/input.rs diff --git a/ironrdp-core/src/rdp/capability_sets/input/test.rs b/crates/pdu/src/rdp/capability_sets/input/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/input/test.rs rename to crates/pdu/src/rdp/capability_sets/input/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/large_pointer.rs b/crates/pdu/src/rdp/capability_sets/large_pointer.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/large_pointer.rs rename to crates/pdu/src/rdp/capability_sets/large_pointer.rs diff --git a/ironrdp-core/src/rdp/capability_sets/multifragment_update.rs b/crates/pdu/src/rdp/capability_sets/multifragment_update.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/multifragment_update.rs rename to crates/pdu/src/rdp/capability_sets/multifragment_update.rs diff --git a/ironrdp-core/src/rdp/capability_sets/offscreen_bitmap_cache.rs b/crates/pdu/src/rdp/capability_sets/offscreen_bitmap_cache.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/offscreen_bitmap_cache.rs rename to crates/pdu/src/rdp/capability_sets/offscreen_bitmap_cache.rs diff --git a/ironrdp-core/src/rdp/capability_sets/offscreen_bitmap_cache/test.rs b/crates/pdu/src/rdp/capability_sets/offscreen_bitmap_cache/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/offscreen_bitmap_cache/test.rs rename to crates/pdu/src/rdp/capability_sets/offscreen_bitmap_cache/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/order.rs b/crates/pdu/src/rdp/capability_sets/order.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/order.rs rename to crates/pdu/src/rdp/capability_sets/order.rs diff --git a/ironrdp-core/src/rdp/capability_sets/order/test.rs b/crates/pdu/src/rdp/capability_sets/order/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/order/test.rs rename to crates/pdu/src/rdp/capability_sets/order/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/pointer.rs b/crates/pdu/src/rdp/capability_sets/pointer.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/pointer.rs rename to crates/pdu/src/rdp/capability_sets/pointer.rs diff --git a/ironrdp-core/src/rdp/capability_sets/pointer/test.rs b/crates/pdu/src/rdp/capability_sets/pointer/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/pointer/test.rs rename to crates/pdu/src/rdp/capability_sets/pointer/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/sound.rs b/crates/pdu/src/rdp/capability_sets/sound.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/sound.rs rename to crates/pdu/src/rdp/capability_sets/sound.rs diff --git a/ironrdp-core/src/rdp/capability_sets/sound/test.rs b/crates/pdu/src/rdp/capability_sets/sound/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/sound/test.rs rename to crates/pdu/src/rdp/capability_sets/sound/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/surface_commands.rs b/crates/pdu/src/rdp/capability_sets/surface_commands.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/surface_commands.rs rename to crates/pdu/src/rdp/capability_sets/surface_commands.rs diff --git a/ironrdp-core/src/rdp/capability_sets/surface_commands/test.rs b/crates/pdu/src/rdp/capability_sets/surface_commands/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/surface_commands/test.rs rename to crates/pdu/src/rdp/capability_sets/surface_commands/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/test.rs b/crates/pdu/src/rdp/capability_sets/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/test.rs rename to crates/pdu/src/rdp/capability_sets/test.rs diff --git a/ironrdp-core/src/rdp/capability_sets/virtual_channel.rs b/crates/pdu/src/rdp/capability_sets/virtual_channel.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/virtual_channel.rs rename to crates/pdu/src/rdp/capability_sets/virtual_channel.rs diff --git a/ironrdp-core/src/rdp/capability_sets/virtual_channel/test.rs b/crates/pdu/src/rdp/capability_sets/virtual_channel/test.rs similarity index 100% rename from ironrdp-core/src/rdp/capability_sets/virtual_channel/test.rs rename to crates/pdu/src/rdp/capability_sets/virtual_channel/test.rs diff --git a/ironrdp-core/src/rdp/client_info.rs b/crates/pdu/src/rdp/client_info.rs similarity index 100% rename from ironrdp-core/src/rdp/client_info.rs rename to crates/pdu/src/rdp/client_info.rs diff --git a/ironrdp-core/src/rdp/client_info/test.rs b/crates/pdu/src/rdp/client_info/test.rs similarity index 100% rename from ironrdp-core/src/rdp/client_info/test.rs rename to crates/pdu/src/rdp/client_info/test.rs diff --git a/ironrdp-core/src/rdp/finalization_messages.rs b/crates/pdu/src/rdp/finalization_messages.rs similarity index 100% rename from ironrdp-core/src/rdp/finalization_messages.rs rename to crates/pdu/src/rdp/finalization_messages.rs diff --git a/ironrdp-core/src/rdp/headers.rs b/crates/pdu/src/rdp/headers.rs similarity index 100% rename from ironrdp-core/src/rdp/headers.rs rename to crates/pdu/src/rdp/headers.rs diff --git a/ironrdp-core/src/rdp/server_error_info.rs b/crates/pdu/src/rdp/server_error_info.rs similarity index 100% rename from ironrdp-core/src/rdp/server_error_info.rs rename to crates/pdu/src/rdp/server_error_info.rs diff --git a/ironrdp-core/src/rdp/server_license.rs b/crates/pdu/src/rdp/server_license.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license.rs rename to crates/pdu/src/rdp/server_license.rs diff --git a/ironrdp-core/src/rdp/server_license/client_new_license_request.rs b/crates/pdu/src/rdp/server_license/client_new_license_request.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/client_new_license_request.rs rename to crates/pdu/src/rdp/server_license/client_new_license_request.rs diff --git a/ironrdp-core/src/rdp/server_license/client_new_license_request/test.rs b/crates/pdu/src/rdp/server_license/client_new_license_request/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/client_new_license_request/test.rs rename to crates/pdu/src/rdp/server_license/client_new_license_request/test.rs diff --git a/ironrdp-core/src/rdp/server_license/client_platform_challenge_response.rs b/crates/pdu/src/rdp/server_license/client_platform_challenge_response.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/client_platform_challenge_response.rs rename to crates/pdu/src/rdp/server_license/client_platform_challenge_response.rs diff --git a/ironrdp-core/src/rdp/server_license/client_platform_challenge_response/test.rs b/crates/pdu/src/rdp/server_license/client_platform_challenge_response/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/client_platform_challenge_response/test.rs rename to crates/pdu/src/rdp/server_license/client_platform_challenge_response/test.rs diff --git a/ironrdp-core/src/rdp/server_license/licensing_error_message.rs b/crates/pdu/src/rdp/server_license/licensing_error_message.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/licensing_error_message.rs rename to crates/pdu/src/rdp/server_license/licensing_error_message.rs diff --git a/ironrdp-core/src/rdp/server_license/licensing_error_message/test.rs b/crates/pdu/src/rdp/server_license/licensing_error_message/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/licensing_error_message/test.rs rename to crates/pdu/src/rdp/server_license/licensing_error_message/test.rs diff --git a/ironrdp-core/src/rdp/server_license/server_license_request.rs b/crates/pdu/src/rdp/server_license/server_license_request.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_license_request.rs rename to crates/pdu/src/rdp/server_license/server_license_request.rs diff --git a/ironrdp-core/src/rdp/server_license/server_license_request/cert.rs b/crates/pdu/src/rdp/server_license/server_license_request/cert.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_license_request/cert.rs rename to crates/pdu/src/rdp/server_license/server_license_request/cert.rs diff --git a/ironrdp-core/src/rdp/server_license/server_license_request/test.rs b/crates/pdu/src/rdp/server_license/server_license_request/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_license_request/test.rs rename to crates/pdu/src/rdp/server_license/server_license_request/test.rs diff --git a/ironrdp-core/src/rdp/server_license/server_platform_challenge.rs b/crates/pdu/src/rdp/server_license/server_platform_challenge.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_platform_challenge.rs rename to crates/pdu/src/rdp/server_license/server_platform_challenge.rs diff --git a/ironrdp-core/src/rdp/server_license/server_platform_challenge/test.rs b/crates/pdu/src/rdp/server_license/server_platform_challenge/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_platform_challenge/test.rs rename to crates/pdu/src/rdp/server_license/server_platform_challenge/test.rs diff --git a/ironrdp-core/src/rdp/server_license/server_upgrade_license.rs b/crates/pdu/src/rdp/server_license/server_upgrade_license.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_upgrade_license.rs rename to crates/pdu/src/rdp/server_license/server_upgrade_license.rs diff --git a/ironrdp-core/src/rdp/server_license/server_upgrade_license/test.rs b/crates/pdu/src/rdp/server_license/server_upgrade_license/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/server_upgrade_license/test.rs rename to crates/pdu/src/rdp/server_license/server_upgrade_license/test.rs diff --git a/ironrdp-core/src/rdp/server_license/test.rs b/crates/pdu/src/rdp/server_license/test.rs similarity index 100% rename from ironrdp-core/src/rdp/server_license/test.rs rename to crates/pdu/src/rdp/server_license/test.rs diff --git a/ironrdp-core/src/rdp/session_info.rs b/crates/pdu/src/rdp/session_info.rs similarity index 100% rename from ironrdp-core/src/rdp/session_info.rs rename to crates/pdu/src/rdp/session_info.rs diff --git a/ironrdp-core/src/rdp/session_info/logon_extended.rs b/crates/pdu/src/rdp/session_info/logon_extended.rs similarity index 100% rename from ironrdp-core/src/rdp/session_info/logon_extended.rs rename to crates/pdu/src/rdp/session_info/logon_extended.rs diff --git a/ironrdp-core/src/rdp/session_info/logon_info.rs b/crates/pdu/src/rdp/session_info/logon_info.rs similarity index 100% rename from ironrdp-core/src/rdp/session_info/logon_info.rs rename to crates/pdu/src/rdp/session_info/logon_info.rs diff --git a/ironrdp-core/src/rdp/session_info/tests.rs b/crates/pdu/src/rdp/session_info/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/session_info/tests.rs rename to crates/pdu/src/rdp/session_info/tests.rs diff --git a/ironrdp-core/src/rdp/test.rs b/crates/pdu/src/rdp/test.rs similarity index 100% rename from ironrdp-core/src/rdp/test.rs rename to crates/pdu/src/rdp/test.rs diff --git a/ironrdp-core/src/rdp/vc.rs b/crates/pdu/src/rdp/vc.rs similarity index 100% rename from ironrdp-core/src/rdp/vc.rs rename to crates/pdu/src/rdp/vc.rs diff --git a/ironrdp-core/src/rdp/vc/dvc.rs b/crates/pdu/src/rdp/vc/dvc.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc.rs rename to crates/pdu/src/rdp/vc/dvc.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/capabilities.rs b/crates/pdu/src/rdp/vc/dvc/capabilities.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/capabilities.rs rename to crates/pdu/src/rdp/vc/dvc/capabilities.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/capabilities/tests.rs b/crates/pdu/src/rdp/vc/dvc/capabilities/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/capabilities/tests.rs rename to crates/pdu/src/rdp/vc/dvc/capabilities/tests.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/close.rs b/crates/pdu/src/rdp/vc/dvc/close.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/close.rs rename to crates/pdu/src/rdp/vc/dvc/close.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/close/tests.rs b/crates/pdu/src/rdp/vc/dvc/close/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/close/tests.rs rename to crates/pdu/src/rdp/vc/dvc/close/tests.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/create.rs b/crates/pdu/src/rdp/vc/dvc/create.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/create.rs rename to crates/pdu/src/rdp/vc/dvc/create.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/create/tests.rs b/crates/pdu/src/rdp/vc/dvc/create/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/create/tests.rs rename to crates/pdu/src/rdp/vc/dvc/create/tests.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/data.rs b/crates/pdu/src/rdp/vc/dvc/data.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/data.rs rename to crates/pdu/src/rdp/vc/dvc/data.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/data/tests.rs b/crates/pdu/src/rdp/vc/dvc/data/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/data/tests.rs rename to crates/pdu/src/rdp/vc/dvc/data/tests.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/data_first.rs b/crates/pdu/src/rdp/vc/dvc/data_first.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/data_first.rs rename to crates/pdu/src/rdp/vc/dvc/data_first.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/data_first/tests.rs b/crates/pdu/src/rdp/vc/dvc/data_first/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/data_first/tests.rs rename to crates/pdu/src/rdp/vc/dvc/data_first/tests.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/display.rs b/crates/pdu/src/rdp/vc/dvc/display.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/display.rs rename to crates/pdu/src/rdp/vc/dvc/display.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx.rs b/crates/pdu/src/rdp/vc/dvc/gfx.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx.rs rename to crates/pdu/src/rdp/vc/dvc/gfx.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages.rs b/crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/avc_messages.rs b/crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/avc_messages.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/avc_messages.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/avc_messages.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/client.rs b/crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/client.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/client.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/client.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/server.rs b/crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/server.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/server.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/server.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/test.rs b/crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/test.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/graphics_messages/test.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/graphics_messages/test.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/gfx/test.rs b/crates/pdu/src/rdp/vc/dvc/gfx/test.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/gfx/test.rs rename to crates/pdu/src/rdp/vc/dvc/gfx/test.rs diff --git a/ironrdp-core/src/rdp/vc/dvc/tests.rs b/crates/pdu/src/rdp/vc/dvc/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/dvc/tests.rs rename to crates/pdu/src/rdp/vc/dvc/tests.rs diff --git a/ironrdp-core/src/rdp/vc/tests.rs b/crates/pdu/src/rdp/vc/tests.rs similarity index 100% rename from ironrdp-core/src/rdp/vc/tests.rs rename to crates/pdu/src/rdp/vc/tests.rs diff --git a/ironrdp-core/src/utils.rs b/crates/pdu/src/utils.rs similarity index 100% rename from ironrdp-core/src/utils.rs rename to crates/pdu/src/utils.rs diff --git a/ironrdp-core/src/x224.rs b/crates/pdu/src/x224.rs similarity index 100% rename from ironrdp-core/src/x224.rs rename to crates/pdu/src/x224.rs diff --git a/ironrdp-core/src/x224/tests.rs b/crates/pdu/src/x224/tests.rs similarity index 100% rename from ironrdp-core/src/x224/tests.rs rename to crates/pdu/src/x224/tests.rs diff --git a/ironrdp-rdcleanpath/Cargo.toml b/crates/rdcleanpath/Cargo.toml similarity index 100% rename from ironrdp-rdcleanpath/Cargo.toml rename to crates/rdcleanpath/Cargo.toml diff --git a/ironrdp-rdcleanpath/README.md b/crates/rdcleanpath/README.md similarity index 100% rename from ironrdp-rdcleanpath/README.md rename to crates/rdcleanpath/README.md diff --git a/ironrdp-rdcleanpath/src/lib.rs b/crates/rdcleanpath/src/lib.rs similarity index 99% rename from ironrdp-rdcleanpath/src/lib.rs rename to crates/rdcleanpath/src/lib.rs index 8b8c2cdb..13f26894 100644 --- a/ironrdp-rdcleanpath/src/lib.rs +++ b/crates/rdcleanpath/src/lib.rs @@ -309,7 +309,7 @@ impl TryFrom for RDCleanPath { .x224_connection_pdu .ok_or(MissingRDCleanPathField("x224_connection_pdu"))?, } - } else if let Some(server_addr) = pdu.server_auth { + } else if let Some(server_addr) = pdu.server_addr { Self::Response { x224_connection_response: pdu .x224_connection_pdu diff --git a/ironrdp-replay-client/Cargo.toml b/crates/replay-client/Cargo.toml similarity index 83% rename from ironrdp-replay-client/Cargo.toml rename to crates/replay-client/Cargo.toml index 811ee7ad..889d4b5c 100644 --- a/ironrdp-replay-client/Cargo.toml +++ b/crates/replay-client/Cargo.toml @@ -9,9 +9,9 @@ repository = "https://github.com/Devolutions/IronRDP" keywords = ["rdp", "client", "remote", "desktop", "protocol", "gfx", "rfx"] [dependencies] -ironrdp = { path = "../ironrdp" } +ironrdp = { path = "../.." } +ironrdp-glutin-renderer = { path = "../glutin-renderer" } clap = { version = "4.0", features = ["derive", "cargo"] } glutin = { version = "0.29" } -ironrdp-renderer = { path = "../ironrdp-renderer" } simplelog = "0.12" log = "0.4" \ No newline at end of file diff --git a/ironrdp-replay-client/README.md b/crates/replay-client/README.md similarity index 100% rename from ironrdp-replay-client/README.md rename to crates/replay-client/README.md diff --git a/ironrdp-replay-client/scripts/runtests.ps1 b/crates/replay-client/scripts/runtests.ps1 similarity index 99% rename from ironrdp-replay-client/scripts/runtests.ps1 rename to crates/replay-client/scripts/runtests.ps1 index 4221d431..cc4503a0 100644 --- a/ironrdp-replay-client/scripts/runtests.ps1 +++ b/crates/replay-client/scripts/runtests.ps1 @@ -1,4 +1,4 @@ -cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample1_avc444.data && ` -cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample2_avc444.data && ` -cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample1_avc444v2.data && ` +cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample1_avc444.data && ` +cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample2_avc444.data && ` +cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample1_avc444v2.data && ` cargo run --bin ironrdp-replay-client -- --close --frame-rate=30 --data-file $PSScriptRoot/../test_data/sample2_avc444v2.data \ No newline at end of file diff --git a/ironrdp-replay-client/src/main.rs b/crates/replay-client/src/main.rs similarity index 96% rename from ironrdp-replay-client/src/main.rs rename to crates/replay-client/src/main.rs index efd37705..d411e99d 100644 --- a/ironrdp-replay-client/src/main.rs +++ b/crates/replay-client/src/main.rs @@ -10,9 +10,9 @@ use clap::Parser; use glutin::dpi::PhysicalSize; use glutin::event::{Event, WindowEvent}; use glutin::event_loop::ControlFlow; -use ironrdp::dvc::gfx::{GraphicsPipelineError, ServerPdu}; -use ironrdp::PduParsing; -use ironrdp_renderer::renderer::Renderer; +use ironrdp::pdu::dvc::gfx::{GraphicsPipelineError, ServerPdu}; +use ironrdp::pdu::PduParsing; +use ironrdp_glutin_renderer::renderer::Renderer; use log::LevelFilter; use simplelog::{Config, SimpleLogger}; diff --git a/ironrdp-replay-client/test_data/README.md b/crates/replay-client/test_data/README.md similarity index 99% rename from ironrdp-replay-client/test_data/README.md rename to crates/replay-client/test_data/README.md index 492535d6..13bb571c 100644 --- a/ironrdp-replay-client/test_data/README.md +++ b/crates/replay-client/test_data/README.md @@ -1,3 +1,3 @@ -Data generated using a custom parser and data file from [Here](https://github.com/microsoft/WindowsProtocolTestSuites/tree/main/TestSuites/RDP/Client/src/TestSuite/RDPEGFX/H264TestData) - +Data generated using a custom parser and data file from [Here](https://github.com/microsoft/WindowsProtocolTestSuites/tree/main/TestSuites/RDP/Client/src/TestSuite/RDPEGFX/H264TestData) + Some data generated using custom code in FreeRDP GFX pipeline to dump stream to file. \ No newline at end of file diff --git a/ironrdp-replay-client/test_data/sample1_avc444.data b/crates/replay-client/test_data/sample1_avc444.data similarity index 100% rename from ironrdp-replay-client/test_data/sample1_avc444.data rename to crates/replay-client/test_data/sample1_avc444.data diff --git a/ironrdp-replay-client/test_data/sample1_avc444v2.data b/crates/replay-client/test_data/sample1_avc444v2.data similarity index 100% rename from ironrdp-replay-client/test_data/sample1_avc444v2.data rename to crates/replay-client/test_data/sample1_avc444v2.data diff --git a/ironrdp-replay-client/test_data/sample2_avc444.data b/crates/replay-client/test_data/sample2_avc444.data similarity index 100% rename from ironrdp-replay-client/test_data/sample2_avc444.data rename to crates/replay-client/test_data/sample2_avc444.data diff --git a/ironrdp-replay-client/test_data/sample2_avc444v2.data b/crates/replay-client/test_data/sample2_avc444v2.data similarity index 100% rename from ironrdp-replay-client/test_data/sample2_avc444v2.data rename to crates/replay-client/test_data/sample2_avc444v2.data diff --git a/crates/session-async/Cargo.toml b/crates/session-async/Cargo.toml new file mode 100644 index 00000000..6d36bc55 --- /dev/null +++ b/crates/session-async/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "ironrdp-session-async" +version = "0.1.0" +edition = "2021" +readme = "README.md" +license = "MIT/Apache-2.0" +homepage = "https://github.com/Devolutions/IronRDP" +repository = "https://github.com/Devolutions/IronRDP" +authors = ["Devolutions Inc. "] + +[features] +default = ["tokio"] +tokio = ["dep:tokio", "dep:tokio-util"] +futures = ["dep:futures-util"] + +[dependencies] +ironrdp-pdu = { path = "../pdu" } +ironrdp-session = { path = "../session" } +bytes = "1" +num-traits = "0.2.15" +bit_field = "0.10.1" +byteorder = "1.4.3" +tokio = { version = "1.25.0", features = ["io-util"], optional = true } +tokio-util = { version = "0.7.7", features = ["codec"], optional = true } +futures-util = { version = "0.3.26", features = ["io"], optional = true } diff --git a/ironrdp-session-async/README.md b/crates/session-async/README.md similarity index 100% rename from ironrdp-session-async/README.md rename to crates/session-async/README.md diff --git a/crates/session-async/src/lib.rs b/crates/session-async/src/lib.rs new file mode 100644 index 00000000..4304f273 --- /dev/null +++ b/crates/session-async/src/lib.rs @@ -0,0 +1,4 @@ +// pub mod framed; + +#[cfg(all(feature = "tokio", feature = "futures"))] +compile_error!("Only \"tokio\" or \"futures\" should be enabled at a time."); diff --git a/crates/session-generators/Cargo.toml b/crates/session-generators/Cargo.toml new file mode 100644 index 00000000..e5c7eeda --- /dev/null +++ b/crates/session-generators/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ironrdp-session-generators" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +ironrdp-session = { path = "../session" } +ironrdp-pdu-generators = { path = "../pdu-generators" } +proptest = "1.1.0" diff --git a/crates/session-generators/src/lib.rs b/crates/session-generators/src/lib.rs new file mode 100644 index 00000000..7d12d9af --- /dev/null +++ b/crates/session-generators/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/ironrdp-session/Cargo.toml b/crates/session/Cargo.toml similarity index 79% rename from ironrdp-session/Cargo.toml rename to crates/session/Cargo.toml index 018df07d..d0747cbe 100644 --- a/ironrdp-session/Cargo.toml +++ b/crates/session/Cargo.toml @@ -15,9 +15,9 @@ native-tls = ["dep:async-native-tls"] dgw_ext = [] [dependencies] -ironrdp-core = { path = "../ironrdp-core" } -ironrdp-graphics = { path = "../ironrdp-graphics" } -ironrdp-rdcleanpath = { path = "../ironrdp-rdcleanpath" } # FIXME: Quick and dirty approach, this should not be here +ironrdp-pdu = { path = "../pdu" } +ironrdp-graphics = { path = "../graphics" } +ironrdp-rdcleanpath = { path = "../rdcleanpath" } # FIXME: Quick and dirty approach, this should not be here sspi = "0.8" bytes = "1" log = "0.4" @@ -29,7 +29,7 @@ lazy_static = "1.4" bitflags = "1" bit_field = "0.10.1" # TODO: will be unused once the framed module is moved byteorder = "1.4.3" -futures-util = "0.3" +futures-util = { version = "0.3", features = ["sink", "io"] } thiserror = "1.0.37" rand_core = "0.6.4" x509-cert = "0.1.0" # TODO: consider removing dependency on this one in `ironrdp-session` diff --git a/ironrdp-session/README.md b/crates/session/README.md similarity index 100% rename from ironrdp-session/README.md rename to crates/session/README.md diff --git a/ironrdp-session/src/active_session.rs b/crates/session/src/active_session.rs similarity index 93% rename from ironrdp-session/src/active_session.rs rename to crates/session/src/active_session.rs index 61d57e2c..14a234d6 100644 --- a/ironrdp-session/src/active_session.rs +++ b/crates/session/src/active_session.rs @@ -3,9 +3,9 @@ mod fast_path; mod x224; use bytes::{BufMut as _, Bytes, BytesMut}; -use ironrdp_core::fast_path::FastPathError; -use ironrdp_core::geometry::Rectangle; -use ironrdp_core::{PduHeader, PduParsing as _}; +use ironrdp_pdu::fast_path::FastPathError; +use ironrdp_pdu::geometry::Rectangle; +use ironrdp_pdu::{PduHeader, PduParsing as _}; pub use self::x224::GfxHandler; use crate::connection_sequence::ConnectionSequenceResult; @@ -56,11 +56,7 @@ impl ActiveStageProcessor { // TODO: async version? /// Send a pdu on the static global channel. Typically used to send input events - pub fn send_static( - &self, - stream: impl std::io::Write, - message: ironrdp_core::ShareDataPdu, - ) -> Result<(), RdpError> { + pub fn send_static(&self, stream: impl std::io::Write, message: ironrdp_pdu::ShareDataPdu) -> Result<(), RdpError> { self.x224_processor.send_static(stream, message) } diff --git a/ironrdp-session/src/active_session/codecs.rs b/crates/session/src/active_session/codecs.rs similarity index 100% rename from ironrdp-session/src/active_session/codecs.rs rename to crates/session/src/active_session/codecs.rs diff --git a/ironrdp-session/src/active_session/codecs/rfx.rs b/crates/session/src/active_session/codecs/rfx.rs similarity index 97% rename from ironrdp-session/src/active_session/codecs/rfx.rs rename to crates/session/src/active_session/codecs/rfx.rs index a6cdd46f..8545049d 100644 --- a/ironrdp-session/src/active_session/codecs/rfx.rs +++ b/crates/session/src/active_session/codecs/rfx.rs @@ -3,13 +3,13 @@ mod tests; use std::cmp::min; -use ironrdp_core::codecs::rfx::{self, EntropyAlgorithm, Headers, Quant, RfxRectangle, Tile}; -use ironrdp_core::geometry::Rectangle; -use ironrdp_core::PduBufferParsing; use ironrdp_graphics::color_conversion::{self, YCbCrBuffer}; use ironrdp_graphics::image_processing::PixelFormat; use ironrdp_graphics::rectangle_processing::Region; use ironrdp_graphics::{dwt, quantization, rlgr, subband_reconstruction}; +use ironrdp_pdu::codecs::rfx::{self, EntropyAlgorithm, Headers, Quant, RfxRectangle, Tile}; +use ironrdp_pdu::geometry::Rectangle; +use ironrdp_pdu::PduBufferParsing; use lazy_static::lazy_static; use log::debug; diff --git a/ironrdp-session/src/active_session/codecs/rfx/tests.rs b/crates/session/src/active_session/codecs/rfx/tests.rs similarity index 100% rename from ironrdp-session/src/active_session/codecs/rfx/tests.rs rename to crates/session/src/active_session/codecs/rfx/tests.rs diff --git a/ironrdp-session/src/active_session/fast_path.rs b/crates/session/src/active_session/fast_path.rs similarity index 96% rename from ironrdp-session/src/active_session/fast_path.rs rename to crates/session/src/active_session/fast_path.rs index 01576cf2..1ce76e87 100644 --- a/ironrdp-session/src/active_session/fast_path.rs +++ b/crates/session/src/active_session/fast_path.rs @@ -1,14 +1,14 @@ use std::io; use bytes::BytesMut; -use ironrdp_core::codecs::rfx::FrameAcknowledgePdu; -use ironrdp_core::fast_path::{ +use ironrdp_graphics::rle::RlePixelFormat; +use ironrdp_pdu::codecs::rfx::FrameAcknowledgePdu; +use ironrdp_pdu::fast_path::{ FastPathError, FastPathHeader, FastPathUpdate, FastPathUpdatePdu, Fragmentation, UpdateCode, }; -use ironrdp_core::geometry::Rectangle; -use ironrdp_core::surface_commands::{FrameAction, FrameMarkerPdu, SurfaceCommand}; -use ironrdp_core::{PduBufferParsing, ShareDataPdu}; -use ironrdp_graphics::rle::RlePixelFormat; +use ironrdp_pdu::geometry::Rectangle; +use ironrdp_pdu::surface_commands::{FrameAction, FrameMarkerPdu, SurfaceCommand}; +use ironrdp_pdu::{PduBufferParsing, ShareDataPdu}; use num_traits::FromPrimitive; use super::codecs::rfx; @@ -69,7 +69,7 @@ impl Processor { // flags field. if update .compression_flags - .contains(ironrdp_core::bitmap::Compression::BITMAP_COMPRESSION) + .contains(ironrdp_pdu::bitmap::Compression::BITMAP_COMPRESSION) { if update.bits_per_pixel == 32 { // Compressed bitmaps at a color depth of 32 bpp are compressed using RDP 6.0 diff --git a/ironrdp-session/src/active_session/x224.rs b/crates/session/src/active_session/x224.rs similarity index 98% rename from ironrdp-session/src/active_session/x224.rs rename to crates/session/src/active_session/x224.rs index d9fcc12c..04027bd6 100644 --- a/ironrdp-session/src/active_session/x224.rs +++ b/crates/session/src/active_session/x224.rs @@ -5,10 +5,10 @@ use std::collections::HashMap; use std::{cmp, io}; use bytes::{BufMut as _, Bytes, BytesMut}; -use ironrdp_core::dvc::FieldType; -use ironrdp_core::rdp::vc::{self, dvc}; -use ironrdp_core::rdp::{ErrorInfo, ProtocolIndependentCode, ServerSetErrorInfoPdu}; -use ironrdp_core::ShareDataPdu; +use ironrdp_pdu::dvc::FieldType; +use ironrdp_pdu::rdp::vc::{self, dvc}; +use ironrdp_pdu::rdp::{ErrorInfo, ProtocolIndependentCode, ServerSetErrorInfoPdu}; +use ironrdp_pdu::ShareDataPdu; pub use self::gfx::GfxHandler; use crate::frame::{ diff --git a/ironrdp-session/src/active_session/x224/display.rs b/crates/session/src/active_session/x224/display.rs similarity index 86% rename from ironrdp-session/src/active_session/x224/display.rs rename to crates/session/src/active_session/x224/display.rs index 1218cbb1..ca7a869b 100644 --- a/ironrdp-session/src/active_session/x224/display.rs +++ b/crates/session/src/active_session/x224/display.rs @@ -1,5 +1,5 @@ -use ironrdp_core::dvc::display::ServerPdu; -use ironrdp_core::PduParsing; +use ironrdp_pdu::dvc::display::ServerPdu; +use ironrdp_pdu::PduParsing; use super::DynamicChannelDataHandler; use crate::RdpError; diff --git a/ironrdp-session/src/active_session/x224/gfx.rs b/crates/session/src/active_session/x224/gfx.rs similarity index 99% rename from ironrdp-session/src/active_session/x224/gfx.rs rename to crates/session/src/active_session/x224/gfx.rs index 29be978a..175d5f94 100644 --- a/ironrdp-session/src/active_session/x224/gfx.rs +++ b/crates/session/src/active_session/x224/gfx.rs @@ -1,11 +1,11 @@ use bitflags::bitflags; -use ironrdp_core::dvc::gfx::{ +use ironrdp_graphics::zgfx; +use ironrdp_pdu::dvc::gfx::{ CapabilitiesAdvertisePdu, CapabilitiesV103Flags, CapabilitiesV104Flags, CapabilitiesV107Flags, CapabilitiesV10Flags, CapabilitiesV81Flags, CapabilitiesV8Flags, CapabilitySet, ClientPdu, FrameAcknowledgePdu, QueueDepth, ServerPdu, }; -use ironrdp_core::PduParsing; -use ironrdp_graphics::zgfx; +use ironrdp_pdu::PduParsing; use log::debug; use super::DynamicChannelDataHandler; diff --git a/ironrdp-session/src/connection_sequence.rs b/crates/session/src/connection_sequence.rs similarity index 91% rename from ironrdp-session/src/connection_sequence.rs rename to crates/session/src/connection_sequence.rs index 5f5de6ff..5e8d4144 100644 --- a/ironrdp-session/src/connection_sequence.rs +++ b/crates/session/src/connection_sequence.rs @@ -6,13 +6,13 @@ use std::{io, iter}; use bytes::{BufMut as _, Bytes, BytesMut}; use futures_util::{AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _}; -use ironrdp_core::rdp::capability_sets::CapabilitySet; -use ironrdp_core::rdp::server_license::{ +use ironrdp_pdu::rdp::capability_sets::CapabilitySet; +use ironrdp_pdu::rdp::server_license::{ ClientNewLicenseRequest, ClientPlatformChallengeResponse, InitialMessageType, InitialServerLicenseMessage, ServerPlatformChallenge, ServerUpgradeLicense, PREMASTER_SECRET_SIZE, RANDOM_NUMBER_SIZE, }; -use ironrdp_core::rdp::{ErrorInfo, ProtocolIndependentCode, ServerSetErrorInfoPdu, SERVER_CHANNEL_ID}; -use ironrdp_core::{rdp, PduParsing}; +use ironrdp_pdu::rdp::{ErrorInfo, ProtocolIndependentCode, ServerSetErrorInfoPdu, SERVER_CHANNEL_ID}; +use ironrdp_pdu::{rdp, PduParsing}; use rand_core::{OsRng, RngCore}; use sspi::network_client::NetworkClientFactory; use sspi::{credssp, NegotiateConfig}; @@ -107,8 +107,8 @@ where server_public_key, } = upgrade_stream(stream).await?; - if selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID) - || selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID_EX) + if selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID) + || selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID_EX) { process_cred_ssp( &mut stream, @@ -119,7 +119,7 @@ where ) .await?; - if selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID_EX) { + if selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID_EX) { let data = read_early_user_auth_result(&mut stream).await?; if let credssp::EarlyUserAuthResult::AccessDenied = data { return Err(RdpError::AccessDenied); @@ -157,7 +157,7 @@ where // When using standard RDP security (RC4), a Security Exchange PDU is sent at this point. // NOTE: IronRDP is only supporting extended security (TLS…). - if selected_protocol == ironrdp_core::SecurityProtocol::RDP { + if selected_protocol == ironrdp_pdu::SecurityProtocol::RDP { return Err(RdpError::Connection(io::Error::new( io::ErrorKind::Other, "Standard RDP Security (RC4 encryption) is not supported", @@ -245,8 +245,8 @@ where let mut stream = reader.reunite(writer).unwrap(); - if selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID) - || selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID_EX) + if selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID) + || selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID_EX) { process_cred_ssp( &mut stream, @@ -257,7 +257,7 @@ where ) .await?; - if selected_protocol.contains(ironrdp_core::SecurityProtocol::HYBRID_EX) { + if selected_protocol.contains(ironrdp_pdu::SecurityProtocol::HYBRID_EX) { let data = read_early_user_auth_result(&mut stream).await?; if let credssp::EarlyUserAuthResult::AccessDenied = data { return Err(RdpError::AccessDenied); @@ -295,7 +295,7 @@ where // When using standard RDP security (RC4), a Security Exchange PDU is sent at this point. // NOTE: IronRDP is only supporting extended security (TLS…). - if selected_protocol == ironrdp_core::SecurityProtocol::RDP { + if selected_protocol == ironrdp_pdu::SecurityProtocol::RDP { return Err(RdpError::Connection(io::Error::new( io::ErrorKind::Other, "Standard RDP Security (RC4 encryption) is not supported", @@ -406,19 +406,19 @@ pub async fn basic_settings_exchange( reader: &mut FramedReader, writer: &mut ErasedWriter, config: &InputConfig, - selected_protocol: ironrdp_core::SecurityProtocol, + selected_protocol: ironrdp_pdu::SecurityProtocol, ) -> Result { let connect_initial = - ironrdp_core::ConnectInitial::with_gcc_blocks(user_info::create_gcc_blocks(config, selected_protocol)?); + ironrdp_pdu::ConnectInitial::with_gcc_blocks(user_info::create_gcc_blocks(config, selected_protocol)?); debug!("Send MCS Connect Initial PDU: {:?}", connect_initial); encode_next_frame(writer, X224Frame(&connect_initial)).await?; - let connect_response: ironrdp_core::ConnectResponse = reader.decode_next_frame::>().await?.0; + let connect_response: ironrdp_pdu::ConnectResponse = reader.decode_next_frame::>().await?.0; debug!("Got MCS Connect Response PDU: {:?}", connect_response); let gcc_blocks = connect_response.conference_create_response.gcc_blocks; if connect_initial.conference_create_request.gcc_blocks.security - == ironrdp_core::gcc::ClientSecurityData::no_security() - && gcc_blocks.security != ironrdp_core::gcc::ServerSecurityData::no_security() + == ironrdp_pdu::gcc::ClientSecurityData::no_security() + && gcc_blocks.security != ironrdp_pdu::gcc::ServerSecurityData::no_security() { return Err(RdpError::InvalidResponse(String::from( "The server demands a security, while the client requested 'no security'", @@ -452,7 +452,7 @@ pub async fn channel_connection( mut static_channels: StaticChannels, config: &InputConfig, ) -> Result { - let erect_domain_request = ironrdp_core::mcs::ErectDomainPdu { + let erect_domain_request = ironrdp_pdu::mcs::ErectDomainPdu { sub_height: 0, sub_interval: 0, }; @@ -460,15 +460,15 @@ pub async fn channel_connection( debug!("Send MCS Erect Domain Request PDU: {:?}", erect_domain_request); encode_next_frame( writer, - X224Frame(ironrdp_core::McsPdu::ErectDomainRequest(erect_domain_request)), + X224Frame(ironrdp_pdu::McsPdu::ErectDomainRequest(erect_domain_request)), ) .await?; debug!("Send MCS Attach User Request PDU"); - encode_next_frame(writer, X224Frame(ironrdp_core::McsPdu::AttachUserRequest)).await?; + encode_next_frame(writer, X224Frame(ironrdp_pdu::McsPdu::AttachUserRequest)).await?; let mcs_pdu = stream.decode_next_frame::>().await?.0; - let initiator_id = if let ironrdp_core::McsPdu::AttachUserConfirm(attach_user_confirm) = mcs_pdu { + let initiator_id = if let ironrdp_pdu::McsPdu::AttachUserConfirm(attach_user_confirm) = mcs_pdu { debug!("Got MCS Attach User Confirm PDU: {:?}", attach_user_confirm); static_channels.insert(config.user_channel_name.clone(), attach_user_confirm.initiator_id); @@ -482,19 +482,19 @@ pub async fn channel_connection( }; for (_, id) in static_channels.iter() { - let channel_join_request = ironrdp_core::mcs::ChannelJoinRequestPdu { + let channel_join_request = ironrdp_pdu::mcs::ChannelJoinRequestPdu { initiator_id, channel_id: *id, }; debug!("Send MCS Channel Join Request PDU: {:?}", channel_join_request); encode_next_frame( writer, - X224Frame(ironrdp_core::McsPdu::ChannelJoinRequest(channel_join_request)), + X224Frame(ironrdp_pdu::McsPdu::ChannelJoinRequest(channel_join_request)), ) .await?; let mcs_pdu = stream.decode_next_frame::>().await?.0; - if let ironrdp_core::McsPdu::ChannelJoinConfirm(channel_join_confirm) = mcs_pdu { + if let ironrdp_pdu::McsPdu::ChannelJoinConfirm(channel_join_confirm) = mcs_pdu { debug!("Got MCS Channel Join Confirm PDU: {:?}", channel_join_confirm); if channel_join_confirm.initiator_id != initiator_id @@ -683,7 +683,7 @@ pub async fn capabilities_exchange( } let capability_sets = - if let ironrdp_core::ShareControlPdu::ServerDemandActive(server_demand_active) = share_control_frame.pdu { + if let ironrdp_pdu::ShareControlPdu::ServerDemandActive(server_demand_active) = share_control_frame.pdu { debug!("Got Server Demand Active PDU: {:?}", server_demand_active.pdu); server_demand_active.pdu.capability_sets } else { @@ -708,7 +708,7 @@ pub async fn capabilities_exchange( height: config.height, }); - let client_confirm_active = ironrdp_core::ShareControlPdu::ClientConfirmActive( + let client_confirm_active = ironrdp_pdu::ShareControlPdu::ClientConfirmActive( user_info::create_client_confirm_active(config, capability_sets)?, ); debug!("Send Client Confirm Active PDU: {:?}", client_confirm_active); @@ -731,7 +731,7 @@ pub async fn connection_finalization( writer: &mut ErasedWriter, global_channel_ids: ChannelIdentificators, ) -> Result<(), RdpError> { - use ironrdp_core::rdp::{ControlAction, ControlPdu, FontPdu, SequenceFlags, ShareDataPdu, SynchronizePdu}; + use ironrdp_pdu::rdp::{ControlAction, ControlPdu, FontPdu, SequenceFlags, ShareDataPdu, SynchronizePdu}; #[derive(Copy, Clone, PartialEq, Debug)] enum FinalizationOrder { @@ -787,7 +787,7 @@ pub async fn connection_finalization( ( FinalizationOrder::ControlCooperate, ShareDataPdu::Control(ControlPdu { - action: ironrdp_core::ControlAction::Cooperate, + action: ironrdp_pdu::ControlAction::Cooperate, grant_id: 0, control_id: 0, }), @@ -795,7 +795,7 @@ pub async fn connection_finalization( ( FinalizationOrder::RequestControl, ShareDataPdu::Control(ControlPdu { - action: ironrdp_core::ControlAction::GrantedControl, + action: ironrdp_pdu::ControlAction::GrantedControl, grant_id, control_id, }), @@ -885,9 +885,9 @@ pub async fn read_early_user_auth_result( pub async fn connection_initiation( reader: &mut FramedReader, mut writer: W, - security_protocol: ironrdp_core::SecurityProtocol, + security_protocol: ironrdp_pdu::SecurityProtocol, username: String, -) -> Result { +) -> Result { let connection_request = build_connection_request_with_username(security_protocol, username); let mut buffer = Vec::new(); connection_request.to_buffer(&mut buffer)?; @@ -896,8 +896,8 @@ pub async fn connection_initiation( writer.flush().await?; let frame = reader.read_frame().await?.ok_or(RdpError::AccessDenied)?; - let connection_response = ironrdp_core::Response::from_buffer(frame.as_ref())?; - if let Some(ironrdp_core::ResponseData::Confirm { + let connection_response = ironrdp_pdu::Response::from_buffer(frame.as_ref())?; + if let Some(ironrdp_pdu::ResponseData::Confirm { flags, protocol: selected_protocol, }) = connection_response.response @@ -930,10 +930,10 @@ pub async fn connection_initiation( reader: &mut FramedReader, mut writer: W, proxy_auth_token: String, - security_protocol: ironrdp_core::SecurityProtocol, + security_protocol: ironrdp_pdu::SecurityProtocol, username: String, hostname: String, -) -> Result<(ironrdp_core::SecurityProtocol, Vec, std::net::SocketAddr), RdpError> { +) -> Result<(ironrdp_pdu::SecurityProtocol, Vec, std::net::SocketAddr), RdpError> { use ironrdp_rdcleanpath::{RDCleanPath, RDCleanPathPdu}; use x509_cert::der::Decode as _; @@ -995,9 +995,9 @@ pub async fn connection_initiation( } }; - let connection_response = ironrdp_core::Response::from_buffer(x224_connection_response.as_bytes())?; + let connection_response = ironrdp_pdu::Response::from_buffer(x224_connection_response.as_bytes())?; - if let Some(ironrdp_core::ResponseData::Confirm { + if let Some(ironrdp_pdu::ResponseData::Confirm { flags, protocol: selected_protocol, }) = connection_response.response @@ -1046,12 +1046,12 @@ pub async fn connection_initiation( } fn build_connection_request_with_username( - security_protocol: ironrdp_core::SecurityProtocol, + security_protocol: ironrdp_pdu::SecurityProtocol, username: String, -) -> ironrdp_core::Request { - ironrdp_core::Request { - nego_data: Some(ironrdp_core::NegoData::Cookie(username)), - flags: ironrdp_core::RequestFlags::empty(), +) -> ironrdp_pdu::Request { + ironrdp_pdu::Request { + nego_data: Some(ironrdp_pdu::NegoData::Cookie(username)), + flags: ironrdp_pdu::RequestFlags::empty(), protocol: security_protocol, src_ref: 0, } diff --git a/ironrdp-session/src/connection_sequence/user_info.rs b/crates/session/src/connection_sequence/user_info.rs similarity index 98% rename from ironrdp-session/src/connection_sequence/user_info.rs rename to crates/session/src/connection_sequence/user_info.rs index 24109dc8..c5091bb5 100644 --- a/ironrdp-session/src/connection_sequence/user_info.rs +++ b/crates/session/src/connection_sequence/user_info.rs @@ -1,12 +1,12 @@ use std::str::FromStr; use std::{env, net}; -use ironrdp_core::gcc::{ +use ironrdp_pdu::gcc::{ Channel, ChannelOptions, ClientCoreData, ClientCoreOptionalData, ClientEarlyCapabilityFlags, ClientGccBlocks, ClientNetworkData, ClientSecurityData, ColorDepth, ConnectionType, HighColorDepth, RdpVersion, SecureAccessSequence, SupportedColorDepths, }; -use ironrdp_core::rdp::capability_sets::{ +use ironrdp_pdu::rdp::capability_sets::{ Bitmap, BitmapCache, BitmapCodecs, BitmapDrawingFlags, Brush, CacheDefinition, CacheEntry, CaptureFlags, CmdFlags, Codec, CodecProperty, EntropyBits, FrameAcknowledge, General, GeneralExtraFlags, GlyphCache, GlyphSupportLevel, Input, InputFlags, LargePointer, LargePointerSupportFlags, MajorPlatformType, MinorPlatformType, @@ -14,11 +14,11 @@ use ironrdp_core::rdp::capability_sets::{ RfxCaps, RfxCapset, RfxClientCapsContainer, RfxICap, RfxICapFlags, Sound, SoundFlags, SupportLevel, SurfaceCommands, VirtualChannel, VirtualChannelFlags, BITMAP_CACHE_ENTRIES_NUM, GLYPH_CACHE_NUM, }; -use ironrdp_core::rdp::{ +use ironrdp_pdu::rdp::{ AddressFamily, BasicSecurityHeader, BasicSecurityHeaderFlags, ClientInfo, ClientInfoFlags, ClientInfoPdu, CompressionType, Credentials, ExtendedClientInfo, ExtendedClientOptionalInfo, SERVER_CHANNEL_ID, }; -use ironrdp_core::{CapabilitySet, ClientConfirmActive, SecurityProtocol}; +use ironrdp_pdu::{CapabilitySet, ClientConfirmActive, SecurityProtocol}; use num_traits::ToPrimitive; use crate::utils::CodecId; @@ -117,7 +117,7 @@ pub fn create_client_confirm_active( Ok(ClientConfirmActive { originator_id: SERVER_CHANNEL_ID, - pdu: ironrdp_core::DemandActive { + pdu: ironrdp_pdu::DemandActive { source_descriptor: SOURCE_DESCRIPTOR.to_string(), capability_sets: server_capability_sets, }, diff --git a/ironrdp-session/src/errors.rs b/crates/session/src/errors.rs similarity index 93% rename from ironrdp-session/src/errors.rs rename to crates/session/src/errors.rs index b5475186..59875b20 100644 --- a/ironrdp-session/src/errors.rs +++ b/crates/session/src/errors.rs @@ -2,11 +2,11 @@ use std::io; use std::sync::mpsc::{RecvError, SendError}; use std::sync::PoisonError; -use ironrdp_core::dvc::{display, gfx}; -use ironrdp_core::fast_path::FastPathError; -use ironrdp_core::rdp::server_license::ServerLicenseError; -use ironrdp_core::{codecs, rdp, McsError}; use ironrdp_graphics::{rlgr, zgfx}; +use ironrdp_pdu::dvc::{display, gfx}; +use ironrdp_pdu::fast_path::FastPathError; +use ironrdp_pdu::rdp::server_license::ServerLicenseError; +use ironrdp_pdu::{codecs, rdp, McsError}; use thiserror::Error; #[derive(Debug, Error)] @@ -18,7 +18,7 @@ pub enum RdpError { #[error("X.224 error")] X224(#[source] io::Error), #[error("negotiation error")] - Negotiation(#[from] ironrdp_core::NegotiationError), + Negotiation(#[from] ironrdp_pdu::NegotiationError), #[error("unexpected PDU: {0}")] UnexpectedPdu(String), #[error("Unexpected disconnection: {0}")] @@ -72,7 +72,7 @@ pub enum RdpError { #[error("Fast-Path error")] FastPath(#[from] FastPathError), #[error("RDP error")] - Rdp(#[from] ironrdp_core::RdpError), + Rdp(#[from] ironrdp_pdu::RdpError), #[error("access to the non-existing channel: {0}")] AccessToNonExistingChannel(u32), #[error("access to the non-existing channel name: {0}")] @@ -90,7 +90,7 @@ pub enum RdpError { #[error("absence of RFX channels")] NoRfxChannelsAnnounced, #[error("the server that started working using the inconsistent protocol: {0:?}")] - UnexpectedFastPathUpdate(ironrdp_core::fast_path::UpdateCode), + UnexpectedFastPathUpdate(ironrdp_pdu::fast_path::UpdateCode), #[error("server error: {0}")] Server(String), #[error("Missing peer certificate")] diff --git a/ironrdp-session/src/frame.rs b/crates/session/src/frame.rs similarity index 85% rename from ironrdp-session/src/frame.rs rename to crates/session/src/frame.rs index 84013b43..4a4bb69d 100644 --- a/ironrdp-session/src/frame.rs +++ b/crates/session/src/frame.rs @@ -1,8 +1,8 @@ use std::io; use bytes::{Buf as _, BufMut as _, Bytes, BytesMut}; -use ironrdp_core::rdp::{vc, SERVER_CHANNEL_ID}; -use ironrdp_core::PduParsing; +use ironrdp_pdu::rdp::{vc, SERVER_CHANNEL_ID}; +use ironrdp_pdu::PduParsing; use crate::{ChannelIdentificators, RdpError}; @@ -24,9 +24,9 @@ where RdpError: From<::Error>, { fn encode(self, mut stream: impl io::Write) -> Result<(), RdpError> { - ironrdp_core::DataHeader::new(self.0.buffer_length()) + ironrdp_pdu::DataHeader::new(self.0.buffer_length()) .to_buffer(&mut stream) - .map_err(ironrdp_core::RdpError::X224Error)?; + .map_err(ironrdp_pdu::RdpError::X224Error)?; self.0.to_buffer(&mut stream)?; stream.flush()?; Ok(()) @@ -34,7 +34,7 @@ where fn decode(mut stream: impl io::Read) -> Result { let data_header = - ironrdp_core::DataHeader::from_buffer(&mut stream).map_err(ironrdp_core::RdpError::X224Error)?; + ironrdp_pdu::DataHeader::from_buffer(&mut stream).map_err(ironrdp_pdu::RdpError::X224Error)?; let length = data_header.data_length; let item = T::from_buffer(&mut stream)?; let remaining = length - item.buffer_length(); @@ -48,13 +48,13 @@ where #[derive(Clone, Debug)] pub struct McsFrame { - pub pdu: ironrdp_core::McsPdu, + pub pdu: ironrdp_pdu::McsPdu, pub data: Bytes, } impl Frame for McsFrame { fn encode(self, mut stream: impl io::Write) -> Result<(), RdpError> { - let data_header = ironrdp_core::DataHeader::new(self.pdu.buffer_length() + self.data.len()); + let data_header = ironrdp_pdu::DataHeader::new(self.pdu.buffer_length() + self.data.len()); data_header.to_buffer(&mut stream)?; self.pdu.to_buffer(&mut stream)?; @@ -66,9 +66,9 @@ impl Frame for McsFrame { } fn decode(mut stream: impl io::Read) -> Result { - let data_header = ironrdp_core::DataHeader::from_buffer(&mut stream)?; + let data_header = ironrdp_pdu::DataHeader::from_buffer(&mut stream)?; - let mcs_pdu = ironrdp_core::McsPdu::from_buffer(&mut stream)?; + let mcs_pdu = ironrdp_pdu::McsPdu::from_buffer(&mut stream)?; let remaining = data_header.data_length - mcs_pdu.buffer_length(); let mut data = BytesMut::zeroed(remaining); @@ -104,14 +104,14 @@ impl SendDataInfoFrame { impl Frame for SendDataInfoFrame { fn encode(self, stream: impl io::Write) -> Result<(), RdpError> { - let send_data_context = ironrdp_core::mcs::SendDataContext { + let send_data_context = ironrdp_pdu::mcs::SendDataContext { channel_id: self.channel_ids.channel_id, initiator_id: self.channel_ids.initiator_id, pdu_length: self.data.len(), }; McsFrame { - pdu: ironrdp_core::McsPdu::SendDataRequest(send_data_context), + pdu: ironrdp_pdu::McsPdu::SendDataRequest(send_data_context), data: self.data, } .encode(stream) @@ -121,14 +121,14 @@ impl Frame for SendDataInfoFrame { let mcs_frame = McsFrame::decode(stream)?; match mcs_frame.pdu { - ironrdp_core::McsPdu::SendDataIndication(send_data_context) => Ok(Self { + ironrdp_pdu::McsPdu::SendDataIndication(send_data_context) => Ok(Self { channel_ids: ChannelIdentificators { initiator_id: send_data_context.initiator_id, channel_id: send_data_context.channel_id, }, data: mcs_frame.data, }), - ironrdp_core::McsPdu::DisconnectProviderUltimatum(disconnect_reason) => Err( + ironrdp_pdu::McsPdu::DisconnectProviderUltimatum(disconnect_reason) => Err( RdpError::UnexpectedDisconnection(format!("Server disconnection reason - {disconnect_reason:?}")), ), _ => Err(RdpError::UnexpectedPdu(format!( @@ -143,13 +143,13 @@ pub struct ShareControlFrame { pub channel_ids: ChannelIdentificators, pub share_id: u32, pub pdu_source: u16, // NOTE: looks like this is always equal to channel_ids.initiatior_id - pub pdu: ironrdp_core::ShareControlPdu, + pub pdu: ironrdp_pdu::ShareControlPdu, pub data: Bytes, } impl Frame for ShareControlFrame { fn encode(self, stream: impl io::Write) -> Result<(), RdpError> { - let share_control_header = ironrdp_core::ShareControlHeader { + let share_control_header = ironrdp_pdu::ShareControlHeader { share_control_pdu: self.pdu, pdu_source: self.pdu_source, share_id: self.share_id, @@ -175,7 +175,7 @@ impl Frame for ShareControlFrame { let channel_ids = info_frame.channel_ids; let mut remaining_reader = info_frame.data.reader(); - let share_control_header = ironrdp_core::ShareControlHeader::from_buffer(&mut remaining_reader) + let share_control_header = ironrdp_pdu::ShareControlHeader::from_buffer(&mut remaining_reader) .map_err(RdpError::ShareControlHeader)?; let pdu = share_control_header.share_control_pdu; let pdu_source = share_control_header.pdu_source; @@ -204,23 +204,23 @@ pub struct ShareDataFrame { pub channel_ids: ChannelIdentificators, pub share_id: u32, pub pdu_source: u16, // NOTE: looks like this is always equal to channel_ids.initiatior_id - pub pdu: ironrdp_core::ShareDataPdu, + pub pdu: ironrdp_pdu::ShareDataPdu, } impl Frame for ShareDataFrame { fn encode(self, stream: impl io::Write) -> Result<(), RdpError> { - let share_data_header = ironrdp_core::ShareDataHeader { + let share_data_header = ironrdp_pdu::ShareDataHeader { share_data_pdu: self.pdu, - stream_priority: ironrdp_core::rdp::StreamPriority::Medium, - compression_flags: ironrdp_core::rdp::CompressionFlags::empty(), - compression_type: ironrdp_core::rdp::CompressionType::K8, // ignored if CompressionFlags::empty() + stream_priority: ironrdp_pdu::rdp::StreamPriority::Medium, + compression_flags: ironrdp_pdu::rdp::CompressionFlags::empty(), + compression_type: ironrdp_pdu::rdp::CompressionType::K8, // ignored if CompressionFlags::empty() }; ShareControlFrame { channel_ids: self.channel_ids, share_id: self.share_id, pdu_source: self.pdu_source, - pdu: ironrdp_core::ShareControlPdu::Data(share_data_header), + pdu: ironrdp_pdu::ShareControlPdu::Data(share_data_header), data: Bytes::new(), } .encode(stream) @@ -229,7 +229,7 @@ impl Frame for ShareDataFrame { fn decode(stream: impl io::Read) -> Result { let frame = ShareControlFrame::decode(stream)?; - if let ironrdp_core::ShareControlPdu::Data(share_data_header) = frame.pdu { + if let ironrdp_pdu::ShareControlPdu::Data(share_data_header) = frame.pdu { Ok(Self { channel_ids: frame.channel_ids, share_id: frame.share_id, @@ -260,7 +260,7 @@ where RdpError: From<::Error>, { fn encode(self, stream: impl io::Write) -> Result<(), RdpError> { - let send_data_context = ironrdp_core::mcs::SendDataContext { + let send_data_context = ironrdp_pdu::mcs::SendDataContext { channel_id: self.channel_ids.channel_id, initiator_id: self.channel_ids.initiator_id, pdu_length: self.pdu.buffer_length(), @@ -271,7 +271,7 @@ where let buf = buf_writer.into_inner(); McsFrame { - pdu: ironrdp_core::McsPdu::SendDataRequest(send_data_context), + pdu: ironrdp_pdu::McsPdu::SendDataRequest(send_data_context), data: buf.freeze(), } .encode(stream) @@ -281,11 +281,11 @@ where let mcs_frame = McsFrame::decode(stream)?; let channel_ids = match mcs_frame.pdu { - ironrdp_core::McsPdu::SendDataIndication(send_data_context) => ChannelIdentificators { + ironrdp_pdu::McsPdu::SendDataIndication(send_data_context) => ChannelIdentificators { initiator_id: send_data_context.initiator_id, channel_id: send_data_context.channel_id, }, - ironrdp_core::McsPdu::DisconnectProviderUltimatum(disconnect_reason) => { + ironrdp_pdu::McsPdu::DisconnectProviderUltimatum(disconnect_reason) => { return Err(RdpError::UnexpectedDisconnection(format!( "Server disconnection reason - {disconnect_reason:?}" ))) diff --git a/ironrdp-session/src/framed.rs b/crates/session/src/framed.rs similarity index 95% rename from ironrdp-session/src/framed.rs rename to crates/session/src/framed.rs index d6a3510e..8105920b 100644 --- a/ironrdp-session/src/framed.rs +++ b/crates/session/src/framed.rs @@ -5,7 +5,7 @@ use bit_field::BitField; use byteorder::{BigEndian, ReadBytesExt}; use bytes::{BufMut, BytesMut}; use futures_util::{AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _}; -use ironrdp_core::Action; +use ironrdp_pdu::Action; use num_traits::FromPrimitive; use crate::frame::Frame; @@ -76,7 +76,7 @@ where (&mut self.reader, &mut self.buf) } - pub async fn read_frame(&mut self) -> Result, ironrdp_core::RdpError> + pub async fn read_frame(&mut self) -> Result, ironrdp_pdu::RdpError> where R: Unpin, { @@ -129,7 +129,7 @@ where } /// Function to call when there are no more bytes available to be read from the underlying I/O. -fn decode_frame_eof(buf: &mut BytesMut) -> Result, ironrdp_core::RdpError> { +fn decode_frame_eof(buf: &mut BytesMut) -> Result, ironrdp_pdu::RdpError> { match decode_frame(buf)? { Some(frame) => Ok(Some(frame)), None => { @@ -144,14 +144,14 @@ fn decode_frame_eof(buf: &mut BytesMut) -> Result, ironrdp_core /// Attempts to decode a frame from the provided buffer of bytes. // TODO: try `&mut Bytes` -fn decode_frame(buf: &mut BytesMut) -> Result, ironrdp_core::RdpError> { +fn decode_frame(buf: &mut BytesMut) -> Result, ironrdp_pdu::RdpError> { let mut stream = buf.as_ref(); if stream.is_empty() { return Ok(None); } let header = stream.read_u8()?; let action = header.get_bits(0..2); - let action = Action::from_u8(action).ok_or(ironrdp_core::RdpError::InvalidActionCode(action))?; + let action = Action::from_u8(action).ok_or(ironrdp_pdu::RdpError::InvalidActionCode(action))?; let length = match action { Action::X224 if stream.len() >= 3 => { diff --git a/ironrdp-session/src/image.rs b/crates/session/src/image.rs similarity index 99% rename from ironrdp-session/src/image.rs rename to crates/session/src/image.rs index 290e6529..0231e21b 100644 --- a/ironrdp-session/src/image.rs +++ b/crates/session/src/image.rs @@ -1,6 +1,6 @@ -use ironrdp_core::geometry::Rectangle; use ironrdp_graphics::image_processing::{ImageRegion, ImageRegionMut, PixelFormat}; use ironrdp_graphics::rectangle_processing::Region; +use ironrdp_pdu::geometry::Rectangle; use crate::RdpError; diff --git a/ironrdp-session/src/lib.rs b/crates/session/src/lib.rs similarity index 93% rename from ironrdp-session/src/lib.rs rename to crates/session/src/lib.rs index 6f4ab383..2bedad19 100644 --- a/ironrdp-session/src/lib.rs +++ b/crates/session/src/lib.rs @@ -10,7 +10,7 @@ pub mod utils; mod errors; mod framed; -use ironrdp_core::gcc; +use ironrdp_pdu::gcc; pub use crate::active_session::{ActiveStageOutput, ActiveStageProcessor, GfxHandler}; pub use crate::errors::RdpError; @@ -28,7 +28,7 @@ pub struct GraphicsConfig { #[derive(Debug, Clone)] pub struct InputConfig { pub credentials: sspi::AuthIdentity, - pub security_protocol: ironrdp_core::SecurityProtocol, + pub security_protocol: ironrdp_pdu::SecurityProtocol, pub keyboard_type: gcc::KeyboardType, pub keyboard_subtype: u32, pub keyboard_functional_keys_count: u32, diff --git a/ironrdp-session/src/utils.rs b/crates/session/src/utils.rs similarity index 100% rename from ironrdp-session/src/utils.rs rename to crates/session/src/utils.rs diff --git a/ironrdp-tls/Cargo.toml b/crates/tls/Cargo.toml similarity index 100% rename from ironrdp-tls/Cargo.toml rename to crates/tls/Cargo.toml diff --git a/ironrdp-tls/README.md b/crates/tls/README.md similarity index 100% rename from ironrdp-tls/README.md rename to crates/tls/README.md diff --git a/ironrdp-tls/src/lib.rs b/crates/tls/src/lib.rs similarity index 100% rename from ironrdp-tls/src/lib.rs rename to crates/tls/src/lib.rs diff --git a/ffi/wasm/.gitignore b/crates/web/.gitignore similarity index 100% rename from ffi/wasm/.gitignore rename to crates/web/.gitignore diff --git a/ffi/wasm/Cargo.lock b/crates/web/Cargo.lock similarity index 100% rename from ffi/wasm/Cargo.lock rename to crates/web/Cargo.lock diff --git a/ffi/wasm/Cargo.toml b/crates/web/Cargo.toml similarity index 70% rename from ffi/wasm/Cargo.toml rename to crates/web/Cargo.toml index ce74f669..affabe5a 100644 --- a/ffi/wasm/Cargo.toml +++ b/crates/web/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ironrdp" +name = "ironrdp-web" version = "0.1.0" edition = "2021" readme = "README.md" @@ -7,30 +7,23 @@ license = "MIT/Apache-2.0" homepage = "https://github.com/Devolutions/IronRDP" repository = "https://github.com/Devolutions/IronRDP" authors = ["Devolutions Inc. "] +publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "rlib"] [features] default = ["panic_hook"] panic_hook = ["dep:console_error_panic_hook"] -[workspace] -members = ["."] - -[profile.release] -# Tell `rustc` to optimize for small code size. -opt-level = "s" - [dependencies] -# RDP protocol -ironrdp = { path = "../../ironrdp" } -ironrdp-session = { path = "../../ironrdp-session", features = ["dgw_ext"] } # FIXME: secret feature until session state machine is done -ironrdp-input = { path = "../../ironrdp-input" } +# Protocols +ironrdp = { path = "../.." } +ironrdp-session = { path = "../session", features = ["dgw_ext"] } # FIXME: secret feature until session state machine is done sspi = "0.8" -# Wasm +# WASM wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" js-sys = "0.3.60" @@ -38,7 +31,7 @@ gloo-net = "0.2.4" # Enable WebAssembly support for a few crates getrandom = { version = "*", features = ["js"] } -chrono = { version = "0.4", features = ["wasmbind"] } +chrono = { version = "*", features = ["wasmbind"] } # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires diff --git a/crates/web/README.md b/crates/web/README.md new file mode 100644 index 00000000..a0516f0b --- /dev/null +++ b/crates/web/README.md @@ -0,0 +1,7 @@ +# WASM bindings for web + +## 🛠️ Build with `wasm-pack build` + +``` +wasm-pack build +``` diff --git a/ffi/wasm/rust-toolchain.toml b/crates/web/rust-toolchain.toml similarity index 100% rename from ffi/wasm/rust-toolchain.toml rename to crates/web/rust-toolchain.toml diff --git a/ffi/wasm/src/error.rs b/crates/web/src/error.rs similarity index 99% rename from ffi/wasm/src/error.rs rename to crates/web/src/error.rs index 9bf20f05..2408235a 100644 --- a/ffi/wasm/src/error.rs +++ b/crates/web/src/error.rs @@ -18,7 +18,7 @@ impl IronRdpError { pub fn backtrace(&self) -> String { format!("{:?}", self.source) } - + pub fn kind(&self) -> IronRdpErrorKind { self.kind } diff --git a/ffi/wasm/src/image.rs b/crates/web/src/image.rs similarity index 98% rename from ffi/wasm/src/image.rs rename to crates/web/src/image.rs index 9990276e..32ca552b 100644 --- a/ffi/wasm/src/image.rs +++ b/crates/web/src/image.rs @@ -1,4 +1,4 @@ -use ironrdp::geometry::Rectangle; +use ironrdp::pdu::geometry::Rectangle; use ironrdp::session::image::DecodedImage; use wasm_bindgen::prelude::*; diff --git a/ffi/wasm/src/input.rs b/crates/web/src/input.rs similarity index 95% rename from ffi/wasm/src/input.rs rename to crates/web/src/input.rs index 719e6d95..361e3cdd 100644 --- a/ffi/wasm/src/input.rs +++ b/crates/web/src/input.rs @@ -1,4 +1,4 @@ -use ironrdp_input::{MouseButton, MousePosition, Operation, Scancode, WheelRotations}; +use ironrdp::input::{MouseButton, MousePosition, Operation, Scancode, WheelRotations}; use smallvec::SmallVec; use wasm_bindgen::prelude::*; diff --git a/ffi/wasm/src/lib.rs b/crates/web/src/lib.rs similarity index 100% rename from ffi/wasm/src/lib.rs rename to crates/web/src/lib.rs diff --git a/ffi/wasm/src/network_client.rs b/crates/web/src/network_client.rs similarity index 100% rename from ffi/wasm/src/network_client.rs rename to crates/web/src/network_client.rs diff --git a/ffi/wasm/src/session.rs b/crates/web/src/session.rs similarity index 91% rename from ffi/wasm/src/session.rs rename to crates/web/src/session.rs index bf014c21..4e2858c1 100644 --- a/ffi/wasm/src/session.rs +++ b/crates/web/src/session.rs @@ -5,8 +5,8 @@ use anyhow::Context as _; use futures_channel::mpsc; use futures_util::{AsyncWriteExt as _, StreamExt as _}; use gloo_net::websocket::futures::WebSocket; -use ironrdp::geometry::Rectangle; use ironrdp::graphics::image_processing::PixelFormat; +use ironrdp::pdu::geometry::Rectangle; use ironrdp::session::connection_sequence::{process_connection_sequence, ConnectionSequenceResult}; use ironrdp::session::image::DecodedImage; use ironrdp::session::{ActiveStageOutput, ActiveStageProcessor, ErasedWriter, FramedReader, InputConfig, RdpError}; @@ -14,9 +14,8 @@ use sspi::AuthIdentity; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::spawn_local; -use crate::image::extract_partial_image; use crate::error::IronRdpError; -use crate::image::RectInfo; +use crate::image::{extract_partial_image, RectInfo}; use crate::input::InputTransaction; use crate::network_client::PlaceholderNetworkClientFactory; use crate::websocket::WebSocketCompat; @@ -55,11 +54,7 @@ impl SessionBuilder { } pub fn domain(&self, domain: String) -> SessionBuilder { - self.0.borrow_mut().domain = if domain.is_empty() { - None - } else { - Some(domain) - }; + self.0.borrow_mut().domain = if domain.is_empty() { None } else { Some(domain) }; self.clone() } @@ -89,7 +84,16 @@ impl SessionBuilder { } pub async fn connect(&self) -> Result { - let (username, hostname, domain, password, gateway_address, auth_token, update_callback, update_callback_context); + let ( + username, + hostname, + domain, + password, + gateway_address, + auth_token, + update_callback, + update_callback_context, + ); { let inner = self.0.borrow(); @@ -129,7 +133,7 @@ impl SessionBuilder { connection_sequence_result, update_callback, update_callback_context, - input_database: RefCell::new(ironrdp_input::Database::new()), + input_database: RefCell::new(ironrdp::input::Database::new()), rdp_reader: RefCell::new(Some(rdp_reader)), writer_tx, }) @@ -142,7 +146,7 @@ pub struct Session { connection_sequence_result: ConnectionSequenceResult, update_callback: js_sys::Function, update_callback_context: JsValue, - input_database: RefCell, + input_database: RefCell, rdp_reader: RefCell>, writer_tx: mpsc::UnboundedSender>, } @@ -236,10 +240,10 @@ impl Session { fn h_send_inputs( &self, - inputs: smallvec::SmallVec<[ironrdp::core::input::fast_path::FastPathInputEvent; 2]>, + inputs: smallvec::SmallVec<[ironrdp::pdu::input::fast_path::FastPathInputEvent; 2]>, ) -> Result<(), IronRdpError> { - use ironrdp::core::input::fast_path::FastPathInput; - use ironrdp::core::PduParsing as _; + use ironrdp::pdu::input::fast_path::FastPathInput; + use ironrdp::pdu::PduParsing as _; trace!("Inputs: {inputs:?}"); @@ -265,10 +269,10 @@ impl Session { caps_lock: bool, kana_lock: bool, ) -> Result<(), IronRdpError> { - use ironrdp::core::input::fast_path::FastPathInput; - use ironrdp::core::PduParsing as _; + use ironrdp::pdu::input::fast_path::FastPathInput; + use ironrdp::pdu::PduParsing as _; - let event = ironrdp_input::synchronize_event(scroll_lock, num_lock, caps_lock, kana_lock); + let event = ironrdp::input::synchronize_event(scroll_lock, num_lock, caps_lock, kana_lock); let fastpath_input = FastPathInput(vec![event]); let mut frame = Vec::new(); @@ -294,8 +298,8 @@ fn build_input_config(username: String, password: String, domain: Option password: password.into(), domain, }, - security_protocol: ironrdp::SecurityProtocol::HYBRID_EX, - keyboard_type: ironrdp::gcc::KeyboardType::IbmEnhanced, + security_protocol: ironrdp::pdu::SecurityProtocol::HYBRID_EX, + keyboard_type: ironrdp::pdu::gcc::KeyboardType::IbmEnhanced, keyboard_subtype: 0, keyboard_functional_keys_count: 12, ime_file_name: String::new(), diff --git a/ffi/wasm/src/utils.rs b/crates/web/src/utils.rs similarity index 100% rename from ffi/wasm/src/utils.rs rename to crates/web/src/utils.rs diff --git a/ffi/wasm/src/websocket.rs b/crates/web/src/websocket.rs similarity index 100% rename from ffi/wasm/src/websocket.rs rename to crates/web/src/websocket.rs diff --git a/ffi/wasm/.cargo/config.toml b/ffi/wasm/.cargo/config.toml deleted file mode 100644 index f4e8c002..00000000 --- a/ffi/wasm/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" diff --git a/ffi/wasm/README.md b/ffi/wasm/README.md deleted file mode 100644 index f7dedbba..00000000 --- a/ffi/wasm/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# WASM bindings - -## 🛠️ Build with `wasm-pack build` - -``` -wasm-pack build -``` - -## 🔬 Test in Headless Browsers with `wasm-pack test` - -``` -wasm-pack test --headless --firefox -``` - -## 🎁 Publish to NPM with `wasm-pack publish` - -``` -wasm-pack publish -``` diff --git a/ffi/wasm/check.ps1 b/ffi/wasm/check.ps1 deleted file mode 100755 index 2d563428..00000000 --- a/ffi/wasm/check.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/env pwsh - -$ErrorActionPreference = "Stop" - -Push-Location -Path $PSScriptRoot - -try { - cargo build - - if ($LastExitCode -ne 0) { - throw "Compilation failed" - } - - $undefinedSymbols = wasm2wat ./target/wasm32-unknown-unknown/debug/ironrdp.wasm | Select-String -Pattern 'import "env"' - - if (-Not [string]::IsNullOrEmpty($undefinedSymbols)) { - throw "Found undefined symbols in generated wasm file: $undefinedSymbols" - } - - Write-Host "Looks WASM-compatible to me!" -} finally { - Pop-Location -} diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 204dfc98..84784bcb 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -209,35 +209,14 @@ dependencies = [ "version_check", ] -[[package]] -name = "ironrdp-core" -version = "0.1.0" -dependencies = [ - "bit_field", - "bitflags", - "byteorder", - "der-parser", - "lazy_static", - "log", - "md-5", - "num-bigint", - "num-derive", - "num-integer", - "num-traits", - "sha1", - "tap", - "thiserror", - "x509-parser", -] - [[package]] name = "ironrdp-fuzz" version = "0.0.0" dependencies = [ "arbitrary", "bytes", - "ironrdp-core", "ironrdp-graphics", + "ironrdp-pdu", "libfuzzer-sys", ] @@ -250,13 +229,33 @@ dependencies = [ "bitvec", "byteorder", "bytes", - "ironrdp-core", + "ironrdp-pdu", "lazy_static", "num-derive", "num-traits", "thiserror", ] +[[package]] +name = "ironrdp-pdu" +version = "0.1.0" +dependencies = [ + "bit_field", + "bitflags", + "byteorder", + "der-parser", + "lazy_static", + "md-5", + "num-bigint", + "num-derive", + "num-integer", + "num-traits", + "sha1", + "tap", + "thiserror", + "x509-parser", +] + [[package]] name = "itoa" version = "1.0.6" @@ -295,15 +294,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - [[package]] name = "md-5" version = "0.10.5" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index d90b76a1..506830eb 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [package.metadata] cargo-fuzz = true +# Prevent this from interfering with workspaces [workspace] members = ["."] @@ -14,16 +15,20 @@ members = ["."] debug = 1 [dependencies] -ironrdp-core = { path = "../ironrdp-core" } -ironrdp-graphics = { path = "../ironrdp-graphics" } +ironrdp-pdu = { path = "../crates/pdu" } +ironrdp-graphics = { path = "../crates/graphics" } +bytes = "1.4.0" libfuzzer-sys = "0.4" arbitrary = { version = "1", features = ["derive"] } -bytes = "1.4.0" [[bin]] name = "pdu_decoding" path = "fuzz_targets/pdu_decoding.rs" +test = false +doc = false [[bin]] name = "rle_decompression" path = "fuzz_targets/rle_decompression.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/pdu_decoding.rs b/fuzz/fuzz_targets/pdu_decoding.rs index f61245d6..411163ad 100644 --- a/fuzz/fuzz_targets/pdu_decoding.rs +++ b/fuzz/fuzz_targets/pdu_decoding.rs @@ -1,7 +1,7 @@ #![no_main] -use ironrdp_core::rdp::*; -use ironrdp_core::*; +use ironrdp_pdu::rdp::*; +use ironrdp_pdu::*; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/iron-tauri-client/.gitignore b/iron-tauri-client/.gitignore deleted file mode 100644 index 7094b042..00000000 --- a/iron-tauri-client/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules \ No newline at end of file diff --git a/iron-tauri-client/README.md b/iron-tauri-client/README.md deleted file mode 100644 index 08dcf510..00000000 --- a/iron-tauri-client/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Tauri GUI Client - -## How to build - -> Gui client is still in early stage development and everything can change (mostly the framework use on web side) - -### Prerequisites - -- Node.js (npm): https://nodejs.org/en/ -- wasm-pack: https://rustwasm.github.io/wasm-pack/installer/ -- rust... : https://www.rust-lang.org/tools/install - -### Steps - -#### Dev - -- run `wasm-pack build` in `./ffi/wasm` folder -- run `npm install` in `./iron-svelte-client` folder -- run `npm run build-tauri` in `./iron-svelte-client` folder -- run `npm install` in `./iron-tauri-client` folder -- finally, run `npm run tauri dev` in `./iron-tauri-client` folder - -#### Build executable - -To build the executable, run the step detailed in Dev section then, instead the last one, -- run `npm run tauri build`. -- You can execute the application directly from `./iron-tauri-client/src-tauri/target/release` or you can install it on your computer by executing the msi file from `./iron-tauri-client/src-tauri/target/release/bundle/msi` \ No newline at end of file diff --git a/iron-tauri-client/app-icon.png b/iron-tauri-client/app-icon.png deleted file mode 100644 index 986a8b16..00000000 Binary files a/iron-tauri-client/app-icon.png and /dev/null differ diff --git a/iron-tauri-client/package-lock.json b/iron-tauri-client/package-lock.json deleted file mode 100644 index 39fe4f01..00000000 --- a/iron-tauri-client/package-lock.json +++ /dev/null @@ -1,265 +0,0 @@ -{ - "name": "iron-tauri-client", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "@tauri-apps/cli": "^1.2.0" - } - }, - "node_modules/@tauri-apps/cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.2.0.tgz", - "integrity": "sha512-DgUnk4p/atWHq2HUx9Vt+/LuRsx4iFlkzdZIUxtFWvpcZih2k0TzmHJbrhM1evh1/7a+SqiwDawmyf3Hz1HxXA==", - "dev": true, - "bin": { - "tauri": "tauri.js" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" - }, - "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "1.2.0", - "@tauri-apps/cli-darwin-x64": "1.2.0", - "@tauri-apps/cli-linux-arm-gnueabihf": "1.2.0", - "@tauri-apps/cli-linux-arm64-gnu": "1.2.0", - "@tauri-apps/cli-linux-arm64-musl": "1.2.0", - "@tauri-apps/cli-linux-x64-gnu": "1.2.0", - "@tauri-apps/cli-linux-x64-musl": "1.2.0", - "@tauri-apps/cli-win32-ia32-msvc": "1.2.0", - "@tauri-apps/cli-win32-x64-msvc": "1.2.0" - } - }, - "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.2.0.tgz", - "integrity": "sha512-f3LR2RvTU2ulxYdK9Nc3vKaSpDChu52pz0BMWNrSs3dxs4WTVioie98Ufz+GorifkUp3sYXcJte3HzX6wH/QxQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.2.0.tgz", - "integrity": "sha512-m07QZaAZCtyobrjddfz/Rxf9GGutnBOpRMbNqVqCk0qKRJzHG1fIsLqkgZh6+qPv0zHpu7xi/FPcqTec72Cp8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.2.0.tgz", - "integrity": "sha512-Id9eF1JtthZRFVtXAAVtSlI3uMT8cJ7LYmCSIl3mAXEUeaPBxnUs1i9X6/J+2Ho3yLEuuOxJ7PaJd+4v8wnEeg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.2.0.tgz", - "integrity": "sha512-NtfPkkpeMPl+i/tB/Fc8ST2rKO2vV8int/RkOvNGLCkhWcl4sbzKBol7tc4q8c8h0X7FXDcF1l/EOuGsZUAA5Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.2.0.tgz", - "integrity": "sha512-tz+mOOVsy/TMdq2WJVIJl/iwW3OCWCyD5Fls3fhyJ4XpLfjn4G+C+oU0awXD/0se0ko81aq4D+r8eDx6oBRi0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.2.0.tgz", - "integrity": "sha512-FH/wU+OWZjRQvrq/oequScr72I84XgOuRuMEpt/GqGD341cBJ8ithpoyzuiKsvjS6K0qMyRFzy3eyhQ7gwX+4Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.2.0.tgz", - "integrity": "sha512-nLg30aBT9fI83sjIqaGPN7twbtE5LJy2DbKzxIlw59F+GT8HBdiM/2mZdTLB3AQb52yVHuGB1TVtWDsl0JHqCA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.2.0.tgz", - "integrity": "sha512-eXtgIgY0fawgcOuUjH8Y6PxwPxbK87Zl9XmA7Q0m58T7pIz+gcbgvtH8Bb+liYHoRYItIhQxVm+ui7Y59rI7Cg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.2.0.tgz", - "integrity": "sha512-egyM66R05AIbkaUDptpHurFTIYp3VM4H5OrRd3O2b0oXf8SoiXiyrHbQsHVHHDYyytKmwkdNqjdy+Vev/Vq25Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - } - }, - "dependencies": { - "@tauri-apps/cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.2.0.tgz", - "integrity": "sha512-DgUnk4p/atWHq2HUx9Vt+/LuRsx4iFlkzdZIUxtFWvpcZih2k0TzmHJbrhM1evh1/7a+SqiwDawmyf3Hz1HxXA==", - "dev": true, - "requires": { - "@tauri-apps/cli-darwin-arm64": "1.2.0", - "@tauri-apps/cli-darwin-x64": "1.2.0", - "@tauri-apps/cli-linux-arm-gnueabihf": "1.2.0", - "@tauri-apps/cli-linux-arm64-gnu": "1.2.0", - "@tauri-apps/cli-linux-arm64-musl": "1.2.0", - "@tauri-apps/cli-linux-x64-gnu": "1.2.0", - "@tauri-apps/cli-linux-x64-musl": "1.2.0", - "@tauri-apps/cli-win32-ia32-msvc": "1.2.0", - "@tauri-apps/cli-win32-x64-msvc": "1.2.0" - } - }, - "@tauri-apps/cli-darwin-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.2.0.tgz", - "integrity": "sha512-f3LR2RvTU2ulxYdK9Nc3vKaSpDChu52pz0BMWNrSs3dxs4WTVioie98Ufz+GorifkUp3sYXcJte3HzX6wH/QxQ==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-darwin-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.2.0.tgz", - "integrity": "sha512-m07QZaAZCtyobrjddfz/Rxf9GGutnBOpRMbNqVqCk0qKRJzHG1fIsLqkgZh6+qPv0zHpu7xi/FPcqTec72Cp8w==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.2.0.tgz", - "integrity": "sha512-Id9eF1JtthZRFVtXAAVtSlI3uMT8cJ7LYmCSIl3mAXEUeaPBxnUs1i9X6/J+2Ho3yLEuuOxJ7PaJd+4v8wnEeg==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-linux-arm64-gnu": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.2.0.tgz", - "integrity": "sha512-NtfPkkpeMPl+i/tB/Fc8ST2rKO2vV8int/RkOvNGLCkhWcl4sbzKBol7tc4q8c8h0X7FXDcF1l/EOuGsZUAA5Q==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-linux-arm64-musl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.2.0.tgz", - "integrity": "sha512-tz+mOOVsy/TMdq2WJVIJl/iwW3OCWCyD5Fls3fhyJ4XpLfjn4G+C+oU0awXD/0se0ko81aq4D+r8eDx6oBRi0A==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-linux-x64-gnu": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.2.0.tgz", - "integrity": "sha512-FH/wU+OWZjRQvrq/oequScr72I84XgOuRuMEpt/GqGD341cBJ8ithpoyzuiKsvjS6K0qMyRFzy3eyhQ7gwX+4Q==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-linux-x64-musl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.2.0.tgz", - "integrity": "sha512-nLg30aBT9fI83sjIqaGPN7twbtE5LJy2DbKzxIlw59F+GT8HBdiM/2mZdTLB3AQb52yVHuGB1TVtWDsl0JHqCA==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-win32-ia32-msvc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.2.0.tgz", - "integrity": "sha512-eXtgIgY0fawgcOuUjH8Y6PxwPxbK87Zl9XmA7Q0m58T7pIz+gcbgvtH8Bb+liYHoRYItIhQxVm+ui7Y59rI7Cg==", - "dev": true, - "optional": true - }, - "@tauri-apps/cli-win32-x64-msvc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.2.0.tgz", - "integrity": "sha512-egyM66R05AIbkaUDptpHurFTIYp3VM4H5OrRd3O2b0oXf8SoiXiyrHbQsHVHHDYyytKmwkdNqjdy+Vev/Vq25Q==", - "dev": true, - "optional": true - } - } -} diff --git a/iron-tauri-client/package.json b/iron-tauri-client/package.json deleted file mode 100644 index b316c98c..00000000 --- a/iron-tauri-client/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "scripts": { - "tauri": "tauri" - }, - - "devDependencies": { - "@tauri-apps/cli": "^1.2.0" - } -} diff --git a/iron-tauri-client/src-tauri/.gitignore b/iron-tauri-client/src-tauri/.gitignore deleted file mode 100644 index cdf41c85..00000000 --- a/iron-tauri-client/src-tauri/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ -/Cargo.lock diff --git a/iron-tauri-client/src-tauri/Cargo.toml b/iron-tauri-client/src-tauri/Cargo.toml deleted file mode 100644 index 2c047e94..00000000 --- a/iron-tauri-client/src-tauri/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "app" -version = "0.1.0" -description = "A Tauri App" -authors = ["you"] -license = "" -repository = "" -default-run = "app" -edition = "2021" -rust-version = "1.59" - -[features] -# by default Tauri runs in production mode -# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL -default = [ "custom-protocol" ] -# this feature is used for production builds where `devPath` points to the filesystem -# DO NOT remove this -custom-protocol = [ "tauri/custom-protocol" ] - -[dependencies] - -# Protocol -ironrdp = { path = "../../ironrdp" } -sspi = { version = "0.8", features = ["network_client"] } -serde = { version = "1.0", features = ["derive"] } - -# SSL -x509-parser = "0.14" -rustls = { version = "0.20", features = ["dangerous_configuration"] } - -# async, futures -tokio = { version = "1", features = ["full"] } -tokio-rustls = "0.23" -tokio-util = { version = "0.7.4", features = ["compat"] } -tokio-tungstenite = "0.17.2" -futures-util = "0.3.25" - -# utils -anyhow = "1" -bytes = "1" - -# tauri stuff -tauri = { version = "1.2.0", features = [] } - -[workspace] -members = ["."] - -[build-dependencies] -tauri-build = { version = "1.2.0", features = [] } - diff --git a/iron-tauri-client/src-tauri/build.rs b/iron-tauri-client/src-tauri/build.rs deleted file mode 100644 index d860e1e6..00000000 --- a/iron-tauri-client/src-tauri/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - tauri_build::build() -} diff --git a/iron-tauri-client/src-tauri/icons/128x128.png b/iron-tauri-client/src-tauri/icons/128x128.png deleted file mode 100644 index 3ef9026b..00000000 Binary files a/iron-tauri-client/src-tauri/icons/128x128.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/128x128@2x.png b/iron-tauri-client/src-tauri/icons/128x128@2x.png deleted file mode 100644 index be89dd04..00000000 Binary files a/iron-tauri-client/src-tauri/icons/128x128@2x.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/32x32.png b/iron-tauri-client/src-tauri/icons/32x32.png deleted file mode 100644 index b0adbce9..00000000 Binary files a/iron-tauri-client/src-tauri/icons/32x32.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square107x107Logo.png b/iron-tauri-client/src-tauri/icons/Square107x107Logo.png deleted file mode 100644 index 6399af9b..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square107x107Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square142x142Logo.png b/iron-tauri-client/src-tauri/icons/Square142x142Logo.png deleted file mode 100644 index 28d41928..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square142x142Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square150x150Logo.png b/iron-tauri-client/src-tauri/icons/Square150x150Logo.png deleted file mode 100644 index 47ce4a35..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square150x150Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square284x284Logo.png b/iron-tauri-client/src-tauri/icons/Square284x284Logo.png deleted file mode 100644 index 7dcad9c2..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square284x284Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square30x30Logo.png b/iron-tauri-client/src-tauri/icons/Square30x30Logo.png deleted file mode 100644 index 34ea920c..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square30x30Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square310x310Logo.png b/iron-tauri-client/src-tauri/icons/Square310x310Logo.png deleted file mode 100644 index c8d279cf..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square310x310Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square44x44Logo.png b/iron-tauri-client/src-tauri/icons/Square44x44Logo.png deleted file mode 100644 index 7d43e08d..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square44x44Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square71x71Logo.png b/iron-tauri-client/src-tauri/icons/Square71x71Logo.png deleted file mode 100644 index 4b5f506b..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square71x71Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/Square89x89Logo.png b/iron-tauri-client/src-tauri/icons/Square89x89Logo.png deleted file mode 100644 index d8857dbf..00000000 Binary files a/iron-tauri-client/src-tauri/icons/Square89x89Logo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/StoreLogo.png b/iron-tauri-client/src-tauri/icons/StoreLogo.png deleted file mode 100644 index 00d9ce7c..00000000 Binary files a/iron-tauri-client/src-tauri/icons/StoreLogo.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/icon.icns b/iron-tauri-client/src-tauri/icons/icon.icns deleted file mode 100644 index 67b95e19..00000000 Binary files a/iron-tauri-client/src-tauri/icons/icon.icns and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/icon.ico b/iron-tauri-client/src-tauri/icons/icon.ico deleted file mode 100644 index 2c58ba7d..00000000 Binary files a/iron-tauri-client/src-tauri/icons/icon.ico and /dev/null differ diff --git a/iron-tauri-client/src-tauri/icons/icon.png b/iron-tauri-client/src-tauri/icons/icon.png deleted file mode 100644 index fb1e8bd5..00000000 Binary files a/iron-tauri-client/src-tauri/icons/icon.png and /dev/null differ diff --git a/iron-tauri-client/src-tauri/src/main.rs b/iron-tauri-client/src-tauri/src/main.rs deleted file mode 100644 index 37ce323d..00000000 --- a/iron-tauri-client/src-tauri/src/main.rs +++ /dev/null @@ -1,560 +0,0 @@ -#![cfg_attr(all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows")] - -use core::future::Future; -use std::collections::HashMap; -use std::io; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Mutex; - -use anyhow::Context as _; -use bytes::BytesMut; -use ironrdp::core::input::fast_path::FastPathInput; -use ironrdp::geometry::Rectangle; -use ironrdp::graphics::image_processing::PixelFormat; -use ironrdp::session::connection_sequence::{process_connection_sequence, ConnectionSequenceResult, UpgradedStream}; -use ironrdp::session::image::DecodedImage; -use ironrdp::session::{ActiveStageOutput, ActiveStageProcessor, ErasedWriter, FramedReader, InputConfig, RdpError}; -use serde::Serialize; -use sspi::network_client::reqwest_network_client::RequestClientFactory; -use sspi::AuthIdentity; -use tauri::{Manager as _, State}; -use tokio::io::AsyncWriteExt as _; -use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::mpsc; -use tokio_util::compat::TokioAsyncReadCompatExt as _; -use x509_parser::prelude::{FromDer as _, X509Certificate}; - -const DEFAULT_WIDTH: u16 = 1280; -const DEFAULT_HEIGHT: u16 = 720; -const GLOBAL_CHANNEL_NAME: &str = "GLOBAL"; -const USER_CHANNEL_NAME: &str = "USER"; - -type TlsStream = tokio_util::compat::Compat>; - -fn main() { - tauri::Builder::default() - .invoke_handler(tauri::generate_handler![ - close_splashscreen, - init, - connect, - update_mouse - ]) - .setup(|app| { - if let Some(splashscreen) = app.get_window("splashscreen") { - splashscreen.set_always_on_top(false).unwrap(); - } - app.manage(SessionManager::new()); - Ok(()) - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} - -#[derive(Clone, Serialize)] -struct DesktopSize { - width: u16, - height: u16, -} - -#[derive(Clone, Serialize)] -struct ResizeEvent { - session_id: usize, - desktop_size: DesktopSize, -} - -#[derive(Clone, Serialize)] -struct NewSessionInfo { - session_id: usize, - websocket_port: u16, - initial_desktop_size: DesktopSize, -} - -struct SessionManager { - next_session_id: AtomicUsize, - sessions: Mutex>, -} - -enum ButtonState { - Unchanged, - Pressed, - Released, -} - -impl SessionManager { - fn new() -> Self { - Self { - next_session_id: AtomicUsize::new(0), - sessions: Mutex::new(HashMap::new()), - } - } - - fn send_message(&self, session_id: usize, msg: SessionMessage) -> anyhow::Result<()> { - let sessions = self.sessions.lock().unwrap(); - let session = sessions.get(&session_id).context("session not found")?; - session.msg_tx.send(msg).ok().context("couldn’t send session message")?; - Ok(()) - } - - /// Returns previous state - fn toggle_down(&self, session_id: usize, currently_down: bool) -> anyhow::Result { - let mut sessions = self.sessions.lock().unwrap(); - let mut session = sessions.get_mut(&session_id).context("session not found")?; - - match (currently_down, session.was_down) { - (true, false) => { - session.was_down = true; - Ok(ButtonState::Pressed) - } - (false, true) => { - session.was_down = false; - Ok(ButtonState::Released) - } - _ => Ok(ButtonState::Unchanged), - } - } - - fn register_session(&self, session: Session) -> usize { - let session_id = self.next_session_id.fetch_add(1, Ordering::SeqCst); - self.sessions.lock().unwrap().insert(session_id, session); - session_id - } -} - -type MessageSender = mpsc::UnboundedSender; - -type MessageReceiver = mpsc::UnboundedReceiver; - -struct Session { - msg_tx: MessageSender, - was_down: bool, -} - -impl Session { - fn new() -> (Self, MessageReceiver) { - let (tx, rx) = mpsc::unbounded_channel(); - let session = Self { - msg_tx: tx, - was_down: false, - }; - (session, rx) - } -} - -enum SessionMessage { - Inputs(FastPathInput), - ResponseFrame(BytesMut), -} - -#[tauri::command] -fn init() { - // do nothing for now -} - -#[tauri::command] -async fn close_splashscreen(window: tauri::Window) { - if let Some(splashscreen) = window.get_window("splashscreen") { - splashscreen.close().unwrap(); - window.get_window("main").unwrap().show().unwrap(); - } -} - -#[tauri::command] -#[allow(non_snake_case)] -async fn update_mouse( - sessionId: usize, - mouseX: u16, - mouseY: u16, - leftClick: bool, - session_manager: State<'_, SessionManager>, -) -> Result<(), String> { - use ironrdp::core::input::fast_path::FastPathInputEvent; - use ironrdp::core::input::mouse::{ButtonEvents, MovementEvents, WheelEvents}; - use ironrdp::core::input::MousePdu; - - let session_id = sessionId; - let mouse_x = mouseX; - let mouse_y = mouseY; - let left_click = leftClick; - - let mut inputs = vec![]; - - inputs.push(FastPathInputEvent::MouseEvent(MousePdu { - wheel_events: WheelEvents::empty(), - movement_events: MovementEvents::MOVE, - button_events: ButtonEvents::empty(), - number_of_wheel_rotations: 0, - x_position: mouse_x, - y_position: mouse_y, - })); - - let button_state = session_manager - .toggle_down(session_id, left_click) - .map_err(|e| e.to_string())?; - - match button_state { - ButtonState::Pressed => { - inputs.push(FastPathInputEvent::MouseEvent(MousePdu { - wheel_events: WheelEvents::empty(), - movement_events: MovementEvents::empty(), - button_events: ButtonEvents::DOWN | ButtonEvents::LEFT_BUTTON, - number_of_wheel_rotations: 0, - x_position: mouse_x, - y_position: mouse_y, - })); - } - ButtonState::Released => { - inputs.push(FastPathInputEvent::MouseEvent(MousePdu { - wheel_events: WheelEvents::empty(), - movement_events: MovementEvents::empty(), - button_events: ButtonEvents::LEFT_BUTTON, - number_of_wheel_rotations: 0, - x_position: mouse_x, - y_position: mouse_y, - })); - } - ButtonState::Unchanged => {} - } - - let fastpath_input = FastPathInput(inputs); - - session_manager - .send_message(session_id, SessionMessage::Inputs(fastpath_input)) - .unwrap(); - - Ok(()) -} - -#[tauri::command] -async fn connect( - username: String, - password: String, - address: String, - session_manager: State<'_, SessionManager>, -) -> Result { - let input_config = build_input_config(username, password, None); - - let addr = ironrdp::session::connection_sequence::Address::lookup_addr(address).map_err(|e| e.to_string())?; - - println!("Connect to RDP host"); - - let tcp_stream = TcpStream::connect(addr.sock) - .await - .map_err(RdpError::Connection) - .map_err(|e| e.to_string())?; - - let (connection_sequence_result, rdp_reader, rdp_writer) = process_connection_sequence( - tcp_stream.compat(), - &addr, - &input_config, - establish_tls, - Box::new(RequestClientFactory), - ) - .await - .map_err(|e| e.to_string())?; - - let desktop_width = connection_sequence_result.desktop_size.width; - let desktop_height = connection_sequence_result.desktop_size.height; - - let listener = TcpListener::bind("127.0.0.1:0").await.map_err(|e| e.to_string())?; - let websocket_port = listener.local_addr().unwrap().port(); - - let initial_desktop_size = DesktopSize { - width: desktop_width, - height: desktop_height, - }; - - let (session, msg_rx) = Session::new(); - let msg_tx = session.msg_tx.clone(); - let session_id = session_manager.register_session(session); - let new_session_info = NewSessionInfo { - session_id, - websocket_port, - initial_desktop_size, - }; - - start_rdp_session( - msg_tx, - msg_rx, - listener, - rdp_reader, - rdp_writer, - input_config, - connection_sequence_result, - ); - - Ok(new_session_info) -} - -fn build_input_config(username: String, password: String, domain: Option) -> InputConfig { - InputConfig { - credentials: AuthIdentity { - username, - password: password.into(), - domain, - }, - security_protocol: ironrdp::SecurityProtocol::HYBRID_EX, - keyboard_type: ironrdp::gcc::KeyboardType::IbmEnhanced, - keyboard_subtype: 0, - keyboard_functional_keys_count: 12, - ime_file_name: String::new(), - dig_product_id: String::new(), - width: DEFAULT_WIDTH, - height: DEFAULT_HEIGHT, - global_channel_name: GLOBAL_CHANNEL_NAME.to_owned(), - user_channel_name: USER_CHANNEL_NAME.to_owned(), - graphics_config: None, - } -} - -fn start_rdp_session( - msg_tx: MessageSender, - msg_rx: MessageReceiver, - listener: TcpListener, - rdp_reader: FramedReader, - rdp_writer: ErasedWriter, - input_config: InputConfig, - connection_sequence_result: ConnectionSequenceResult, -) { - spawn_task(rdp_session_task( - msg_tx, - listener, - rdp_reader, - input_config, - connection_sequence_result, - )); - spawn_task(message_writer_task(msg_rx, rdp_writer)); -} - -async fn message_writer_task(mut msg_rx: MessageReceiver, mut rdp_writer: ErasedWriter) -> anyhow::Result<()> { - use futures_util::AsyncWriteExt as _; - use ironrdp::PduParsing; - - while let Some(message) = msg_rx.recv().await { - match message { - SessionMessage::ResponseFrame(frame) => { - rdp_writer.write_all(&frame).await?; - rdp_writer.flush().await?; - } - SessionMessage::Inputs(inputs) => { - let mut frame = Vec::new(); - inputs.to_buffer(&mut frame).unwrap(); - rdp_writer.write_all(&frame).await?; - rdp_writer.flush().await?; - } - } - } - - Ok(()) -} - -async fn rdp_session_task( - msg_tx: MessageSender, - listener: TcpListener, - mut rdp_reader: FramedReader, - input_config: InputConfig, - connection_sequence_result: ConnectionSequenceResult, -) -> anyhow::Result<()> { - println!("RDP session task started"); - - // Waiting for frontend to connect via WebSocket - let (tcp_stream, _) = listener.accept().await?; - let mut ws_stream = tokio_tungstenite::accept_async(tcp_stream).await?; - - let mut image = DecodedImage::new( - PixelFormat::RgbA32, - u32::from(connection_sequence_result.desktop_size.width), - u32::from(connection_sequence_result.desktop_size.height), - ); - - let mut active_stage = ActiveStageProcessor::new(input_config, None, connection_sequence_result); - let mut frame_id = 0; - - 'outer: loop { - // FIXME: remove unwraps - let frame = rdp_reader - .read_frame() - .await - .unwrap() - .ok_or(RdpError::AccessDenied) - .unwrap() - .freeze(); - let outputs = active_stage.process(&mut image, frame).unwrap(); - - for out in outputs { - match out { - ActiveStageOutput::ResponseFrame(frame) => { - if msg_tx.send(SessionMessage::ResponseFrame(frame)).is_err() { - println!("writer task is terminated"); - break 'outer; - }; - } - ActiveStageOutput::GraphicsUpdate(updated_region) => { - let partial_image = extract_partial_image(&image, &updated_region); - - send_update_rectangle(&mut ws_stream, frame_id, updated_region, partial_image) - .await - .context("Failed to send update rectangle")?; - - frame_id += 1; - } - ActiveStageOutput::Terminate => break 'outer, - } - } - } - - println!("RPD session terminated"); - - Ok(()) -} - -fn extract_partial_image(image: &DecodedImage, region: &Rectangle) -> Vec { - let pixel_size = usize::from(image.pixel_format().bytes_per_pixel()); - - let image_width = usize::try_from(image.width()).unwrap(); - - let region_top = usize::from(region.top); - let region_left = usize::from(region.left); - let region_width = usize::from(region.width()); - let region_height = usize::from(region.height()); - - let dst_buf_size = region_width * region_height * pixel_size; - let mut dst = vec![0; dst_buf_size]; - - let src = image.data(); - - let image_stride = image_width * pixel_size; - let region_stride = region_width * pixel_size; - - for row in 0..region_height { - let src_begin = image_stride * (region_top + row) + region_left * pixel_size; - let src_end = src_begin + region_stride; - let src_slice = &src[src_begin..src_end]; - - let target_begin = region_stride * row; - let target_end = target_begin + region_stride; - let target_slice = &mut dst[target_begin..target_end]; - - target_slice.copy_from_slice(src_slice); - } - - dst -} - -async fn send_update_rectangle( - stream: &mut tokio_tungstenite::WebSocketStream, - frame_id: usize, - region: Rectangle, - buffer: Vec, -) -> anyhow::Result<()> { - use futures_util::SinkExt as _; - use tokio_tungstenite::tungstenite::Message; - - let top = region.top; - let left = region.left; - let right = region.right; - let bottom = region.bottom; - let width = region.width(); - let height = region.height(); - let msg_len = buffer.len(); - - stream.feed(Message::Text(format!( - r#"{{"top": {top}, "left": {left}, "right": {right}, "bottom": {bottom}, "width": {width}, "height": {height}, "frame_id": {frame_id}, "msg_len": {msg_len}}}"# - ))).await.unwrap(); - - stream.feed(Message::Binary(buffer)).await?; - - Ok(()) -} - -// TODO: this can be refactored in a separate `ironrdp-tls` crate (all native clients will do the same TLS dance) -async fn establish_tls(stream: tokio_util::compat::Compat) -> Result, RdpError> { - let stream = stream.into_inner(); - - let mut tls_stream = { - let mut client_config = rustls::client::ClientConfig::builder() - .with_safe_defaults() - .with_custom_certificate_verifier(std::sync::Arc::new(danger::NoCertificateVerification)) - .with_no_client_auth(); - // This adds support for the SSLKEYLOGFILE env variable (https://wiki.wireshark.org/TLS#using-the-pre-master-secret) - client_config.key_log = std::sync::Arc::new(rustls::KeyLogFile::new()); - let rc_config = std::sync::Arc::new(client_config); - let example_com = "stub_string".try_into().unwrap(); - let connector = tokio_rustls::TlsConnector::from(rc_config); - connector.connect(example_com, stream).await? - }; - - tls_stream.flush().await?; - - let server_public_key = { - let cert = tls_stream - .get_ref() - .1 - .peer_certificates() - .ok_or(RdpError::MissingPeerCertificate)?[0] - .as_ref(); - get_tls_peer_pubkey(cert.to_vec())? - }; - - Ok(UpgradedStream { - stream: tls_stream.compat(), - server_public_key, - }) -} - -pub fn get_tls_peer_pubkey(cert: Vec) -> io::Result> { - let res = X509Certificate::from_der(&cert[..]) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid der certificate."))?; - let public_key = res.1.tbs_certificate.subject_pki.subject_public_key; - - Ok(public_key.data.to_vec()) -} - -mod danger { - use std::time::SystemTime; - - use rustls::client::ServerCertVerified; - use rustls::{Certificate, Error, ServerName}; - - pub struct NoCertificateVerification; - - impl rustls::client::ServerCertVerifier for NoCertificateVerification { - fn verify_server_cert( - &self, - _end_entity: &Certificate, - _intermediates: &[Certificate], - _server_name: &ServerName, - _scts: &mut dyn Iterator, - _ocsp_response: &[u8], - _now: SystemTime, - ) -> Result { - Ok(rustls::client::ServerCertVerified::assertion()) - } - } -} - -fn spawn_task(task: F) -where - F: Future> + Send + 'static, - F::Output: Send + 'static, - T: 'static, -{ - tauri::async_runtime::spawn(async move { - match task.await { - Ok(_) => {} - Err(e) => println!("Task failed: {e:?}"), - } - }); -} - -// TODO: resize event -#[allow(dead_code)] -fn send_resize_event(app: &tauri::AppHandle, session_id: usize, desktop_size: DesktopSize) -> anyhow::Result<()> { - app.emit_all( - "resize", - ResizeEvent { - session_id, - desktop_size, - }, - )?; - Ok(()) -} diff --git a/iron-tauri-client/src-tauri/tauri.conf.json b/iron-tauri-client/src-tauri/tauri.conf.json deleted file mode 100644 index 973af2e4..00000000 --- a/iron-tauri-client/src-tauri/tauri.conf.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "$schema": "../node_modules/@tauri-apps/cli/schema.json", - "build": { - "beforeBuildCommand": "npm --prefix ../iron-svelte-client run build-tauri", - "beforeDevCommand": "npm --prefix ../iron-svelte-client run dev-tauri", - "devPath": "http://localhost:5173", - "distDir": "../../iron-svelte-client/build/tauri" - }, - "package": { - "productName": "iron-gui", - "version": "0.1.0" - }, - "tauri": { - "allowlist": { - "all": false - }, - "bundle": { - "active": true, - "category": "DeveloperTool", - "copyright": "", - "deb": { - "depends": [] - }, - "externalBin": [], - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ], - "identifier": "com.devolutions.dev", - "longDescription": "", - "macOS": { - "entitlements": null, - "exceptionDomain": "", - "frameworks": [], - "providerShortName": null, - "signingIdentity": null - }, - "resources": [], - "shortDescription": "", - "targets": "all", - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": "sha256", - "timestampUrl": "" - } - }, - "security": { - "csp": null - }, - "updater": { - "active": false - }, - "windows": [ - { - "fullscreen": false, - "height": 800, - "resizable": true, - "title": "IronRDP GUI", - "url": "/session", - "label": "main", - "width": 1400 - } - ] - } -} diff --git a/ironrdp-session-async/Cargo.toml b/ironrdp-session-async/Cargo.toml deleted file mode 100644 index a48c0447..00000000 --- a/ironrdp-session-async/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "ironrdp-session-async" -version = "0.1.0" -edition = "2021" -readme = "README.md" -license = "MIT/Apache-2.0" -homepage = "https://github.com/Devolutions/IronRDP" -repository = "https://github.com/Devolutions/IronRDP" -authors = ["Devolutions Inc. "] - -[dependencies] -ironrdp-core = { path = "../ironrdp-core" } -ironrdp-graphics = { path = "../ironrdp-graphics" } -bytes = "1" -num-traits = "0.2.15" -bit_field = "0.10.1" -byteorder = "1.4.3" -futures-util = "0.3" diff --git a/ironrdp-session-async/src/lib.rs b/ironrdp-session-async/src/lib.rs deleted file mode 100644 index c68850e5..00000000 --- a/ironrdp-session-async/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -// pub mod framed; diff --git a/ironrdp/Cargo.toml b/ironrdp/Cargo.toml deleted file mode 100644 index 206575d5..00000000 --- a/ironrdp/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "ironrdp" -version = "0.4.2" -edition = "2021" -readme = "../README.md" -license = "MIT/Apache-2.0" -homepage = "https://github.com/Devolutions/IronRDP" -repository = "https://github.com/Devolutions/IronRDP" -authors = ["Devolutions Inc. "] -description = "A Rust implementation of the Microsoft Remote Desktop Protocol" -keywords = ["rdp", "remote", "desktop", "protocol"] - -[features] -default = [] -rustls = ["ironrdp-session/rustls"] -native-tls = ["ironrdp-session/native-tls"] - -[dependencies] -ironrdp-core = { path = "../ironrdp-core" } -ironrdp-session = { path = "../ironrdp-session" } -ironrdp-graphics = { path = "../ironrdp-graphics" } -ironrdp-input = { path = "../ironrdp-input" } diff --git a/ironrdp/README.md b/ironrdp/README.md deleted file mode 100644 index 57a29cb6..00000000 --- a/ironrdp/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# IronRDP - -Meta crate re-exporting other important crates for convenience. diff --git a/ironrdp/src/lib.rs b/ironrdp/src/lib.rs deleted file mode 100644 index 75deb26c..00000000 --- a/ironrdp/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -// TODO: remove glob reexport at some point -pub use ironrdp_core::*; -pub use {ironrdp_core as core, ironrdp_graphics as graphics, ironrdp_input as input, ironrdp_session as session}; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b2cf8c5f..434cca45 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.68.0" +channel = "1.68.2" components = ["rustfmt", "clippy"] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..ab0345c6 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,6 @@ +//! Rust implementation of the Remote Desktop Protocol (RDP). +//! +//! This is a meta crate re-exporting ironrdp-pdu, ironrdp-session, ironrdp-graphics +//! and ironrdp-input crates for convenience. + +pub use {ironrdp_graphics as graphics, ironrdp_input as input, ironrdp_pdu as pdu, ironrdp_session as session}; diff --git a/iron-remote-gui/.gitignore b/web-client/iron-remote-gui/.gitignore similarity index 100% rename from iron-remote-gui/.gitignore rename to web-client/iron-remote-gui/.gitignore diff --git a/iron-remote-gui/.vscode/extensions.json b/web-client/iron-remote-gui/.vscode/extensions.json similarity index 100% rename from iron-remote-gui/.vscode/extensions.json rename to web-client/iron-remote-gui/.vscode/extensions.json diff --git a/iron-remote-gui/README.md b/web-client/iron-remote-gui/README.md similarity index 96% rename from iron-remote-gui/README.md rename to web-client/iron-remote-gui/README.md index 14e61b31..92594bc5 100644 --- a/iron-remote-gui/README.md +++ b/web-client/iron-remote-gui/README.md @@ -74,5 +74,5 @@ You can add some parameters for default initialization on the component ` `setScale(scale: ScreenScale)` > > Sets the scale behavior of the canvas. -> See the [ScreenScale](src/services/user-interaction-service.ts) enum for possible values. +> See the [ScreenScale](./src/services/user-interaction-service.ts) enum for possible values. diff --git a/iron-remote-gui/index.html b/web-client/iron-remote-gui/index.html similarity index 100% rename from iron-remote-gui/index.html rename to web-client/iron-remote-gui/index.html diff --git a/iron-remote-gui/package-lock.json b/web-client/iron-remote-gui/package-lock.json similarity index 99% rename from iron-remote-gui/package-lock.json rename to web-client/iron-remote-gui/package-lock.json index 90f49582..3aed4206 100644 --- a/iron-remote-gui/package-lock.json +++ b/web-client/iron-remote-gui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devolutions/iron-remote-gui", - "version": "0.1.0", + "version": "0.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@devolutions/iron-remote-gui", - "version": "0.1.0", + "version": "0.5.0", "dependencies": { "@types/ua-parser-js": "^0.7.36", "ua-parser-js": "^1.0.33" diff --git a/iron-remote-gui/package.json b/web-client/iron-remote-gui/package.json similarity index 100% rename from iron-remote-gui/package.json rename to web-client/iron-remote-gui/package.json diff --git a/iron-remote-gui/pre-build.js b/web-client/iron-remote-gui/pre-build.js similarity index 83% rename from iron-remote-gui/pre-build.js rename to web-client/iron-remote-gui/pre-build.js index 46bd2b66..65f0eba6 100644 --- a/iron-remote-gui/pre-build.js +++ b/web-client/iron-remote-gui/pre-build.js @@ -1,4 +1,4 @@ -import {spawn} from "child_process"; +import {spawn} from "child_process"; let run = async function (command, cwd) { return new Promise(resolve => { @@ -19,4 +19,4 @@ let run = async function (command, cwd) { }) } -await run('wasm-pack build --target web', '../ffi/wasm'); +await run('wasm-pack build --target web', '../../crates/web'); diff --git a/iron-remote-gui/public/package.json b/web-client/iron-remote-gui/public/package.json similarity index 100% rename from iron-remote-gui/public/package.json rename to web-client/iron-remote-gui/public/package.json diff --git a/iron-remote-gui/public/test.html b/web-client/iron-remote-gui/public/test.html similarity index 100% rename from iron-remote-gui/public/test.html rename to web-client/iron-remote-gui/public/test.html diff --git a/iron-remote-gui/src/enums/LockKey.ts b/web-client/iron-remote-gui/src/enums/LockKey.ts similarity index 100% rename from iron-remote-gui/src/enums/LockKey.ts rename to web-client/iron-remote-gui/src/enums/LockKey.ts diff --git a/iron-remote-gui/src/enums/LogType.ts b/web-client/iron-remote-gui/src/enums/LogType.ts similarity index 100% rename from iron-remote-gui/src/enums/LogType.ts rename to web-client/iron-remote-gui/src/enums/LogType.ts diff --git a/iron-remote-gui/src/enums/ModifierKey.ts b/web-client/iron-remote-gui/src/enums/ModifierKey.ts similarity index 100% rename from iron-remote-gui/src/enums/ModifierKey.ts rename to web-client/iron-remote-gui/src/enums/ModifierKey.ts diff --git a/iron-remote-gui/src/enums/OS.ts b/web-client/iron-remote-gui/src/enums/OS.ts similarity index 100% rename from iron-remote-gui/src/enums/OS.ts rename to web-client/iron-remote-gui/src/enums/OS.ts diff --git a/iron-remote-gui/src/enums/SessionEventType.ts b/web-client/iron-remote-gui/src/enums/SessionEventType.ts similarity index 100% rename from iron-remote-gui/src/enums/SessionEventType.ts rename to web-client/iron-remote-gui/src/enums/SessionEventType.ts diff --git a/iron-remote-gui/src/interfaces/session-event.model.ts b/web-client/iron-remote-gui/src/interfaces/session-event.model.ts similarity index 100% rename from iron-remote-gui/src/interfaces/session-event.model.ts rename to web-client/iron-remote-gui/src/interfaces/session-event.model.ts diff --git a/iron-remote-gui/src/iron-remote-gui.svelte b/web-client/iron-remote-gui/src/iron-remote-gui.svelte similarity index 100% rename from iron-remote-gui/src/iron-remote-gui.svelte rename to web-client/iron-remote-gui/src/iron-remote-gui.svelte diff --git a/iron-remote-gui/src/lib/scancodes.ts b/web-client/iron-remote-gui/src/lib/scancodes.ts similarity index 100% rename from iron-remote-gui/src/lib/scancodes.ts rename to web-client/iron-remote-gui/src/lib/scancodes.ts diff --git a/iron-remote-gui/src/main.ts b/web-client/iron-remote-gui/src/main.ts similarity index 100% rename from iron-remote-gui/src/main.ts rename to web-client/iron-remote-gui/src/main.ts diff --git a/iron-remote-gui/src/services/logging.service.ts b/web-client/iron-remote-gui/src/services/logging.service.ts similarity index 100% rename from iron-remote-gui/src/services/logging.service.ts rename to web-client/iron-remote-gui/src/services/logging.service.ts diff --git a/iron-remote-gui/src/services/server-bridge.service.ts b/web-client/iron-remote-gui/src/services/server-bridge.service.ts similarity index 100% rename from iron-remote-gui/src/services/server-bridge.service.ts rename to web-client/iron-remote-gui/src/services/server-bridge.service.ts diff --git a/iron-remote-gui/src/services/services-injector.ts b/web-client/iron-remote-gui/src/services/services-injector.ts similarity index 100% rename from iron-remote-gui/src/services/services-injector.ts rename to web-client/iron-remote-gui/src/services/services-injector.ts diff --git a/iron-remote-gui/src/services/tauri-bridge.service.ts b/web-client/iron-remote-gui/src/services/tauri-bridge.service.ts similarity index 100% rename from iron-remote-gui/src/services/tauri-bridge.service.ts rename to web-client/iron-remote-gui/src/services/tauri-bridge.service.ts diff --git a/iron-remote-gui/src/services/user-interaction-service.ts b/web-client/iron-remote-gui/src/services/user-interaction-service.ts similarity index 100% rename from iron-remote-gui/src/services/user-interaction-service.ts rename to web-client/iron-remote-gui/src/services/user-interaction-service.ts diff --git a/iron-remote-gui/src/services/wasm-bridge.service.ts b/web-client/iron-remote-gui/src/services/wasm-bridge.service.ts similarity index 99% rename from iron-remote-gui/src/services/wasm-bridge.service.ts rename to web-client/iron-remote-gui/src/services/wasm-bridge.service.ts index 4a64fe09..b1f41042 100644 --- a/iron-remote-gui/src/services/wasm-bridge.service.ts +++ b/web-client/iron-remote-gui/src/services/wasm-bridge.service.ts @@ -1,7 +1,7 @@ import type {NewSessionInfo, ResizeEvent, ServerBridgeService} from './server-bridge.service'; import {MouseButton, MouseButtonState, SpecialCombination} from './server-bridge.service'; import {from, Observable, of, Subject} from 'rxjs'; -import init, {DeviceEvent, InputTransaction, ironrdp_init, IronRdpError, IronRdpErrorKind, Session, SessionBuilder} from "../../../ffi/wasm/pkg/ironrdp"; +import init, {DeviceEvent, InputTransaction, ironrdp_init, IronRdpError, IronRdpErrorKind, Session, SessionBuilder} from "../../../../crates/web/pkg/ironrdp_web"; import {loggingService} from "./logging.service"; import {catchError, filter, finalize, map} from "rxjs/operators"; import {userInteractionService} from "./user-interaction-service"; diff --git a/iron-remote-gui/src/vite-env.d.ts b/web-client/iron-remote-gui/src/vite-env.d.ts similarity index 100% rename from iron-remote-gui/src/vite-env.d.ts rename to web-client/iron-remote-gui/src/vite-env.d.ts diff --git a/iron-remote-gui/svelte.config.js b/web-client/iron-remote-gui/svelte.config.js similarity index 100% rename from iron-remote-gui/svelte.config.js rename to web-client/iron-remote-gui/svelte.config.js diff --git a/iron-remote-gui/tsconfig.json b/web-client/iron-remote-gui/tsconfig.json similarity index 100% rename from iron-remote-gui/tsconfig.json rename to web-client/iron-remote-gui/tsconfig.json diff --git a/iron-remote-gui/tsconfig.node.json b/web-client/iron-remote-gui/tsconfig.node.json similarity index 100% rename from iron-remote-gui/tsconfig.node.json rename to web-client/iron-remote-gui/tsconfig.node.json diff --git a/iron-remote-gui/vite.config.ts b/web-client/iron-remote-gui/vite.config.ts similarity index 100% rename from iron-remote-gui/vite.config.ts rename to web-client/iron-remote-gui/vite.config.ts diff --git a/iron-svelte-client/.eslintignore b/web-client/iron-svelte-client/.eslintignore similarity index 100% rename from iron-svelte-client/.eslintignore rename to web-client/iron-svelte-client/.eslintignore diff --git a/iron-svelte-client/.eslintrc.cjs b/web-client/iron-svelte-client/.eslintrc.cjs similarity index 100% rename from iron-svelte-client/.eslintrc.cjs rename to web-client/iron-svelte-client/.eslintrc.cjs diff --git a/iron-svelte-client/.gitignore b/web-client/iron-svelte-client/.gitignore similarity index 100% rename from iron-svelte-client/.gitignore rename to web-client/iron-svelte-client/.gitignore diff --git a/iron-svelte-client/.npmrc b/web-client/iron-svelte-client/.npmrc similarity index 100% rename from iron-svelte-client/.npmrc rename to web-client/iron-svelte-client/.npmrc diff --git a/iron-svelte-client/.prettierignore b/web-client/iron-svelte-client/.prettierignore similarity index 100% rename from iron-svelte-client/.prettierignore rename to web-client/iron-svelte-client/.prettierignore diff --git a/iron-svelte-client/.prettierrc b/web-client/iron-svelte-client/.prettierrc similarity index 100% rename from iron-svelte-client/.prettierrc rename to web-client/iron-svelte-client/.prettierrc diff --git a/iron-svelte-client/README.md b/web-client/iron-svelte-client/README.md similarity index 85% rename from iron-svelte-client/README.md rename to web-client/iron-svelte-client/README.md index cdb343e4..996fe503 100644 --- a/iron-svelte-client/README.md +++ b/web-client/iron-svelte-client/README.md @@ -1,24 +1,15 @@ # SvelteKit UI for IronRDP -The UI is used both for Tauri Desktop App and Browser App. +Web-based frontend using [`SvelteKit`](https://kit.svelte.dev/) and [`Material`](https://material.io) frameworks. +This is a simple wrapper around the `iron-remote-gui` Web Component demonstrating how to use the API. -## Tauri +## Requirements -Please read the [README](../iron-tauri-client/) from `iron-tauri-client` - -## Web client - -Web client is built on top of [SvelteKit](https://kit.svelte.dev/). -It's a simple wrapper around `iron-remote-gui` demonstrating how to use the API. -The core of the web client is to be found in `iron-remote-gui` folder provided as a Web Component. - -### Requirements - -- A remote machine ready to receive RDP connections using RemoteFX (see top-level [README](../README.md) on that matter). +- A remote machine ready to receive RDP connections using RemoteFX (see top-level [README](../../README.md) on that matter). - A Devolutions Gateway with network access to this machine up and running - A token signed using the provisioner key the Devolutions Gateway is expecting -#### Devolutions Gateway setup +### Devolutions Gateway setup Web client is using a special extension to RDP protocol. This extension is available starting Devolutions Gateway v2023.1.1. @@ -87,7 +78,7 @@ $ ./DevolutionsGateway # Linux / macOS $ ./DevolutionsGateway.exe # Windows ``` -#### Token generation +### Token generation The most straightforward way of generating a token if you don’t have a Rust toolchain installed is the PowerShell package. @@ -102,7 +93,7 @@ You can then run the following: $ New-DGatewayToken -Type ASSOCIATION -PrivateKeyFile -DestinationHost -ApplicationProtocol rdp ``` -### Run in dev mode +## Run in dev mode First, run `npm install` in the [iron-remote-gui](../iron-remote-gui/) folder, and then `npm install` in [iron-svelte-client](./) folder. diff --git a/iron-svelte-client/env.development b/web-client/iron-svelte-client/env.development similarity index 100% rename from iron-svelte-client/env.development rename to web-client/iron-svelte-client/env.development diff --git a/iron-svelte-client/env.tauri b/web-client/iron-svelte-client/env.tauri similarity index 100% rename from iron-svelte-client/env.tauri rename to web-client/iron-svelte-client/env.tauri diff --git a/iron-svelte-client/package-lock.json b/web-client/iron-svelte-client/package-lock.json similarity index 100% rename from iron-svelte-client/package-lock.json rename to web-client/iron-svelte-client/package-lock.json diff --git a/iron-svelte-client/package.json b/web-client/iron-svelte-client/package.json similarity index 100% rename from iron-svelte-client/package.json rename to web-client/iron-svelte-client/package.json diff --git a/iron-svelte-client/pre-build.js b/web-client/iron-svelte-client/pre-build.js similarity index 100% rename from iron-svelte-client/pre-build.js rename to web-client/iron-svelte-client/pre-build.js diff --git a/iron-svelte-client/src/app.d.ts b/web-client/iron-svelte-client/src/app.d.ts similarity index 100% rename from iron-svelte-client/src/app.d.ts rename to web-client/iron-svelte-client/src/app.d.ts diff --git a/iron-svelte-client/src/app.html b/web-client/iron-svelte-client/src/app.html similarity index 100% rename from iron-svelte-client/src/app.html rename to web-client/iron-svelte-client/src/app.html diff --git a/iron-svelte-client/src/lib/login/login-store.ts b/web-client/iron-svelte-client/src/lib/login/login-store.ts similarity index 100% rename from iron-svelte-client/src/lib/login/login-store.ts rename to web-client/iron-svelte-client/src/lib/login/login-store.ts diff --git a/iron-svelte-client/src/lib/login/login.css b/web-client/iron-svelte-client/src/lib/login/login.css similarity index 100% rename from iron-svelte-client/src/lib/login/login.css rename to web-client/iron-svelte-client/src/lib/login/login.css diff --git a/iron-svelte-client/src/lib/login/login.svelte b/web-client/iron-svelte-client/src/lib/login/login.svelte similarity index 100% rename from iron-svelte-client/src/lib/login/login.svelte rename to web-client/iron-svelte-client/src/lib/login/login.svelte diff --git a/iron-svelte-client/src/lib/messages/message-store.ts b/web-client/iron-svelte-client/src/lib/messages/message-store.ts similarity index 100% rename from iron-svelte-client/src/lib/messages/message-store.ts rename to web-client/iron-svelte-client/src/lib/messages/message-store.ts diff --git a/iron-svelte-client/src/lib/messages/message.svelte b/web-client/iron-svelte-client/src/lib/messages/message.svelte similarity index 100% rename from iron-svelte-client/src/lib/messages/message.svelte rename to web-client/iron-svelte-client/src/lib/messages/message.svelte diff --git a/iron-svelte-client/src/lib/remote-screen/remote-screen.svelte b/web-client/iron-svelte-client/src/lib/remote-screen/remote-screen.svelte similarity index 100% rename from iron-svelte-client/src/lib/remote-screen/remote-screen.svelte rename to web-client/iron-svelte-client/src/lib/remote-screen/remote-screen.svelte diff --git a/iron-svelte-client/src/models/desktop-size.ts b/web-client/iron-svelte-client/src/models/desktop-size.ts similarity index 100% rename from iron-svelte-client/src/models/desktop-size.ts rename to web-client/iron-svelte-client/src/models/desktop-size.ts diff --git a/iron-svelte-client/src/models/rect.ts b/web-client/iron-svelte-client/src/models/rect.ts similarity index 100% rename from iron-svelte-client/src/models/rect.ts rename to web-client/iron-svelte-client/src/models/rect.ts diff --git a/iron-svelte-client/src/models/session.ts b/web-client/iron-svelte-client/src/models/session.ts similarity index 100% rename from iron-svelte-client/src/models/session.ts rename to web-client/iron-svelte-client/src/models/session.ts diff --git a/iron-svelte-client/src/routes/+layout.ts b/web-client/iron-svelte-client/src/routes/+layout.ts similarity index 100% rename from iron-svelte-client/src/routes/+layout.ts rename to web-client/iron-svelte-client/src/routes/+layout.ts diff --git a/iron-svelte-client/src/routes/+page.svelte b/web-client/iron-svelte-client/src/routes/+page.svelte similarity index 100% rename from iron-svelte-client/src/routes/+page.svelte rename to web-client/iron-svelte-client/src/routes/+page.svelte diff --git a/iron-svelte-client/src/routes/session/+page.svelte b/web-client/iron-svelte-client/src/routes/session/+page.svelte similarity index 100% rename from iron-svelte-client/src/routes/session/+page.svelte rename to web-client/iron-svelte-client/src/routes/session/+page.svelte diff --git a/iron-svelte-client/src/services/server-bridge.service.ts b/web-client/iron-svelte-client/src/services/server-bridge.service.ts similarity index 100% rename from iron-svelte-client/src/services/server-bridge.service.ts rename to web-client/iron-svelte-client/src/services/server-bridge.service.ts diff --git a/iron-svelte-client/src/services/services-injector.ts b/web-client/iron-svelte-client/src/services/services-injector.ts similarity index 100% rename from iron-svelte-client/src/services/services-injector.ts rename to web-client/iron-svelte-client/src/services/services-injector.ts diff --git a/iron-svelte-client/src/services/session.service.ts b/web-client/iron-svelte-client/src/services/session.service.ts similarity index 100% rename from iron-svelte-client/src/services/session.service.ts rename to web-client/iron-svelte-client/src/services/session.service.ts diff --git a/iron-svelte-client/src/services/tauri-bridge.service.ts b/web-client/iron-svelte-client/src/services/tauri-bridge.service.ts similarity index 100% rename from iron-svelte-client/src/services/tauri-bridge.service.ts rename to web-client/iron-svelte-client/src/services/tauri-bridge.service.ts diff --git a/iron-svelte-client/src/services/user-interaction-service.ts b/web-client/iron-svelte-client/src/services/user-interaction-service.ts similarity index 100% rename from iron-svelte-client/src/services/user-interaction-service.ts rename to web-client/iron-svelte-client/src/services/user-interaction-service.ts diff --git a/iron-svelte-client/src/services/wasm-bridge.service.ts b/web-client/iron-svelte-client/src/services/wasm-bridge.service.ts similarity index 93% rename from iron-svelte-client/src/services/wasm-bridge.service.ts rename to web-client/iron-svelte-client/src/services/wasm-bridge.service.ts index 3a2deec0..9e262433 100644 --- a/iron-svelte-client/src/services/wasm-bridge.service.ts +++ b/web-client/iron-svelte-client/src/services/wasm-bridge.service.ts @@ -1,5 +1,5 @@ import type { NewSessionInfo, ServerBridgeService } from './server-bridge.service'; -import * as IronWasm from '../../../ffi/wasm/pkg/ironrdp'; +import * as IronWasm from '../../../ffi/wasm/pkg/ironrdp_web'; import { Observable, of, Subject } from 'rxjs'; export class WasmBridgeService implements ServerBridgeService { diff --git a/iron-svelte-client/static/beercss/beer.min.css b/web-client/iron-svelte-client/static/beercss/beer.min.css similarity index 100% rename from iron-svelte-client/static/beercss/beer.min.css rename to web-client/iron-svelte-client/static/beercss/beer.min.css diff --git a/iron-svelte-client/static/beercss/beer.min.js b/web-client/iron-svelte-client/static/beercss/beer.min.js similarity index 100% rename from iron-svelte-client/static/beercss/beer.min.js rename to web-client/iron-svelte-client/static/beercss/beer.min.js diff --git a/iron-svelte-client/static/favicon.png b/web-client/iron-svelte-client/static/favicon.png similarity index 100% rename from iron-svelte-client/static/favicon.png rename to web-client/iron-svelte-client/static/favicon.png diff --git a/iron-svelte-client/static/material-icons/LICENSE b/web-client/iron-svelte-client/static/material-icons/LICENSE similarity index 100% rename from iron-svelte-client/static/material-icons/LICENSE rename to web-client/iron-svelte-client/static/material-icons/LICENSE diff --git a/iron-svelte-client/static/material-icons/filled.css b/web-client/iron-svelte-client/static/material-icons/filled.css similarity index 100% rename from iron-svelte-client/static/material-icons/filled.css rename to web-client/iron-svelte-client/static/material-icons/filled.css diff --git a/iron-svelte-client/static/material-icons/index.css b/web-client/iron-svelte-client/static/material-icons/index.css similarity index 100% rename from iron-svelte-client/static/material-icons/index.css rename to web-client/iron-svelte-client/static/material-icons/index.css diff --git a/iron-svelte-client/static/material-icons/material-icons-outlined.woff2 b/web-client/iron-svelte-client/static/material-icons/material-icons-outlined.woff2 similarity index 100% rename from iron-svelte-client/static/material-icons/material-icons-outlined.woff2 rename to web-client/iron-svelte-client/static/material-icons/material-icons-outlined.woff2 diff --git a/iron-svelte-client/static/material-icons/material-icons-round.woff2 b/web-client/iron-svelte-client/static/material-icons/material-icons-round.woff2 similarity index 100% rename from iron-svelte-client/static/material-icons/material-icons-round.woff2 rename to web-client/iron-svelte-client/static/material-icons/material-icons-round.woff2 diff --git a/iron-svelte-client/static/material-icons/material-icons-sharp.woff2 b/web-client/iron-svelte-client/static/material-icons/material-icons-sharp.woff2 similarity index 100% rename from iron-svelte-client/static/material-icons/material-icons-sharp.woff2 rename to web-client/iron-svelte-client/static/material-icons/material-icons-sharp.woff2 diff --git a/iron-svelte-client/static/material-icons/material-icons-two-tone.woff2 b/web-client/iron-svelte-client/static/material-icons/material-icons-two-tone.woff2 similarity index 100% rename from iron-svelte-client/static/material-icons/material-icons-two-tone.woff2 rename to web-client/iron-svelte-client/static/material-icons/material-icons-two-tone.woff2 diff --git a/iron-svelte-client/static/material-icons/material-icons.woff2 b/web-client/iron-svelte-client/static/material-icons/material-icons.woff2 similarity index 100% rename from iron-svelte-client/static/material-icons/material-icons.woff2 rename to web-client/iron-svelte-client/static/material-icons/material-icons.woff2 diff --git a/iron-svelte-client/static/material-icons/outlined.css b/web-client/iron-svelte-client/static/material-icons/outlined.css similarity index 100% rename from iron-svelte-client/static/material-icons/outlined.css rename to web-client/iron-svelte-client/static/material-icons/outlined.css diff --git a/iron-svelte-client/static/material-icons/round.css b/web-client/iron-svelte-client/static/material-icons/round.css similarity index 100% rename from iron-svelte-client/static/material-icons/round.css rename to web-client/iron-svelte-client/static/material-icons/round.css diff --git a/iron-svelte-client/static/material-icons/sharp.css b/web-client/iron-svelte-client/static/material-icons/sharp.css similarity index 100% rename from iron-svelte-client/static/material-icons/sharp.css rename to web-client/iron-svelte-client/static/material-icons/sharp.css diff --git a/iron-svelte-client/static/material-icons/two-tone.css b/web-client/iron-svelte-client/static/material-icons/two-tone.css similarity index 100% rename from iron-svelte-client/static/material-icons/two-tone.css rename to web-client/iron-svelte-client/static/material-icons/two-tone.css diff --git a/iron-svelte-client/static/theme.css b/web-client/iron-svelte-client/static/theme.css similarity index 100% rename from iron-svelte-client/static/theme.css rename to web-client/iron-svelte-client/static/theme.css diff --git a/iron-svelte-client/svelte.config.js b/web-client/iron-svelte-client/svelte.config.js similarity index 100% rename from iron-svelte-client/svelte.config.js rename to web-client/iron-svelte-client/svelte.config.js diff --git a/iron-svelte-client/tsconfig.json b/web-client/iron-svelte-client/tsconfig.json similarity index 100% rename from iron-svelte-client/tsconfig.json rename to web-client/iron-svelte-client/tsconfig.json diff --git a/iron-svelte-client/vite.config.ts b/web-client/iron-svelte-client/vite.config.ts similarity index 100% rename from iron-svelte-client/vite.config.ts rename to web-client/iron-svelte-client/vite.config.ts diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 00000000..4ce561f9 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "xtask" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +anyhow = "1.0.68" +pico-args = "0.5.0" +xshell = "0.2.3" diff --git a/xtask/README.md b/xtask/README.md new file mode 100644 index 00000000..7e8c35a7 --- /dev/null +++ b/xtask/README.md @@ -0,0 +1,3 @@ +# IronRDP project automation + +Free-form automation following [`cargo xtask`](https://github.com/matklad/cargo-xtask) specification. diff --git a/xtask/src/cli.rs b/xtask/src/cli.rs new file mode 100644 index 00000000..110619ca --- /dev/null +++ b/xtask/src/cli.rs @@ -0,0 +1,77 @@ +const HELP: &str = "\ +cargo xtask + +USAGE: + cargo xtask [OPTIONS] [TASK] + +FLAGS: + -h, --help Prints help information + +TASKS: + ci Runs all checks required on CI + check [all] Runs all checks + check fmt Checks formatting + check tests Runs tests + check lints Checks lints + check wasm Ensures wasm module is compatible for the web + fuzz run Fuzz all targets for a few seconds + fuzz corpus-min Minify fuzzing corpus + fuzz corpus-fetch Minify fuzzing corpus + fuzz corpus-push Minify fuzzing corpus + svelte-run Runs SvelteKit-based standalone Web Client + coverage Generate code-coverage data using tests and fuzz targets + clean Clean workspace +"; + +pub fn print_help() { + println!("{HELP}"); +} + +pub enum Action { + ShowHelp, + CheckAll, + CheckFmt, + CheckTests, + CheckLints, + CheckWasm, + FuzzRun, + FuzzCorpusMin, + FuzzCorpusFetch, + FuzzCorpusPush, + SvelteRun, + Coverage, + Clean, +} + +pub fn parse_args() -> anyhow::Result { + let mut args = pico_args::Arguments::from_env(); + + let action = if args.contains(["-h", "--help"]) { + Action::ShowHelp + } else { + match args.subcommand()?.as_deref() { + Some("ci") => Action::CheckAll, + Some("check") => match args.subcommand()?.as_deref() { + Some("fmt") => Action::CheckFmt, + Some("tests") => Action::CheckTests, + Some("lints") => Action::CheckLints, + Some("wasm") => Action::CheckWasm, + Some("all") | None => Action::CheckAll, + Some(_) => anyhow::bail!("Unknown check action"), + }, + Some("fuzz") => match args.subcommand()?.as_deref() { + Some("run") | None => Action::FuzzRun, + Some("corpus-min") => Action::FuzzCorpusMin, + Some("corpus-fetch") => Action::FuzzCorpusFetch, + Some("corpus-push") => Action::FuzzCorpusPush, + Some(_) => anyhow::bail!("Unknown fuzz action"), + }, + Some("clean") => Action::Clean, + Some("svelte-run") => Action::SvelteRun, + Some("coverage") => Action::Coverage, + None | Some(_) => Action::ShowHelp, + } + }; + + Ok(action) +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 00000000..61283808 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,55 @@ +mod cli; +mod section; +mod tasks; + +use std::path::{Path, PathBuf}; + +use xshell::Shell; + +use crate::cli::Action; + +fn main() -> anyhow::Result<()> { + let action = match cli::parse_args() { + Ok(action) => action, + Err(e) => { + cli::print_help(); + return Err(e); + } + }; + + let sh = Shell::new()?; + + sh.change_dir(project_root()); + + match action { + Action::ShowHelp => cli::print_help(), + Action::CheckAll => { + tasks::check_formatting(&sh)?; + tasks::run_tests(&sh)?; + tasks::check_lints(&sh)?; + tasks::check_wasm(&sh)?; + tasks::fuzz_run(&sh)?; + } + Action::CheckFmt => tasks::check_formatting(&sh)?, + Action::CheckTests => tasks::run_tests(&sh)?, + Action::CheckLints => tasks::check_lints(&sh)?, + Action::CheckWasm => tasks::check_wasm(&sh)?, + Action::FuzzRun => tasks::fuzz_run(&sh)?, + Action::FuzzCorpusMin => tasks::fuzz_corpus_minify(&sh)?, + Action::FuzzCorpusFetch => tasks::fuzz_corpus_fetch(&sh)?, + Action::FuzzCorpusPush => tasks::fuzz_corpus_push(&sh)?, + Action::SvelteRun => tasks::svelte_run(&sh)?, + Action::Coverage => tasks::report_code_coverage(&sh)?, + Action::Clean => tasks::clean_workspace(&sh)?, + } + + Ok(()) +} + +fn project_root() -> PathBuf { + Path::new(&env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(1) + .unwrap() + .to_path_buf() +} diff --git a/xtask/src/section.rs b/xtask/src/section.rs new file mode 100644 index 00000000..347f9ca5 --- /dev/null +++ b/xtask/src/section.rs @@ -0,0 +1,30 @@ +use std::time::Instant; + +pub struct Section { + name: &'static str, + start: Instant, +} + +impl Section { + pub fn new(name: &'static str) -> Section { + flush_all(); + eprintln!("::group::{name}"); + let start = Instant::now(); + Section { name, start } + } +} + +impl Drop for Section { + fn drop(&mut self) { + flush_all(); + eprintln!("{}: {:.2?}", self.name, self.start.elapsed()); + eprintln!("::endgroup::"); + } +} + +fn flush_all() { + use std::io::{self, Write as _}; + + let _ = io::stdout().flush(); + let _ = io::stderr().flush(); +} diff --git a/xtask/src/tasks.rs b/xtask/src/tasks.rs new file mode 100644 index 00000000..db108001 --- /dev/null +++ b/xtask/src/tasks.rs @@ -0,0 +1,233 @@ +use anyhow::Context as _; +use xshell::{cmd, Shell}; + +use crate::section::Section; + +const CARGO: &str = env!("CARGO"); +const WASM_PACKAGES: &[&str] = &["ironrdp-web"]; +const FUZZ_TARGETS: &[&str] = &["pdu_decoding", "rle_decompression"]; + +pub fn check_formatting(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("FORMATTING"); + + let output = cmd!(sh, "{CARGO} fmt --all -- --check").ignore_status().output()?; + + if !output.status.success() { + anyhow::bail!("Bad formatting, please run 'cargo +stable fmt --all'"); + } + + println!("All good!"); + + Ok(()) +} + +pub fn run_tests(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("TESTS"); + cmd!(sh, "{CARGO} test --workspace --locked").run()?; + println!("All good!"); + Ok(()) +} + +pub fn check_lints(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("LINTS"); + cmd!(sh, "{CARGO} clippy --workspace --locked -- -D warnings").run()?; + println!("All good!"); + Ok(()) +} + +pub fn check_wasm(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("WASM-CHECK"); + + cmd!(sh, "rustup target add wasm32-unknown-unknown").run()?; + + for package in WASM_PACKAGES { + println!("Check {package}"); + + cmd!( + sh, + "{CARGO} rustc --locked --target wasm32-unknown-unknown --package {package} --lib --crate-type cdylib" + ) + .run()?; + + // When building a library, `-` in the artifact name are replaced by `_` + let artifact_name = format!("{}.wasm", package.replace('-', "_")); + + let output = cmd!(sh, "wasm2wat ./target/wasm32-unknown-unknown/debug/{artifact_name}").output()?; + let stdout = std::str::from_utf8(&output.stdout).context("wasm2wat output is not valid UTF-8")?; + + if stdout.contains("import \"env\"") { + anyhow::bail!("Found undefined symbols in generated wasm file"); + } + } + + println!("All good!"); + + Ok(()) +} + +pub fn fuzz_run(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("FUZZ-RUN"); + + let _guard = sh.push_dir("./fuzz"); + + for target in FUZZ_TARGETS { + cmd!(sh, "rustup run nightly cargo fuzz run {target} -- -max_total_time=5s").run()?; + } + + println!("All good!"); + + Ok(()) +} + +pub fn fuzz_corpus_minify(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("FUZZ-CORPUS-MINIFY"); + + let _guard = sh.push_dir("./fuzz"); + + for target in FUZZ_TARGETS { + cmd!(sh, "rustup run nightly cargo fuzz cmin {target}").run()?; + } + + Ok(()) +} + +pub fn fuzz_corpus_fetch(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("FUZZ-CORPUS-FETCH"); + + cmd!( + sh, + "az storage blob download-batch --account-name fuzzingcorpus --source ironrdp --destination fuzz --output none" + ) + .run()?; + + Ok(()) +} + +pub fn fuzz_corpus_push(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("FUZZ-CORPUS-PUSH"); + + cmd!( + sh, + "az storage blob sync --account-name fuzzingcorpus --container ironrdp --source fuzz/corpus --destination corpus --delete-destination true --output none" + ) + .run()?; + + cmd!( + sh, + "az storage blob sync --account-name fuzzingcorpus --container ironrdp --source fuzz/artifacts --destination artifacts --delete-destination true --output none" + ) + .run()?; + + Ok(()) +} + +pub fn svelte_run(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("SVELTE-RUN"); + + { + let _guard = sh.push_dir("./web-client/iron-remote-gui"); + cmd!(sh, "npm install").run()?; + } + + { + let _guard = sh.push_dir("./web-client/iron-svelte-client"); + cmd!(sh, "npm install").run()?; + cmd!(sh, "npm run dev-all").run()?; + } + + Ok(()) +} + +pub fn report_code_coverage(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("COVERAGE"); + + println!("Remove leftovers"); + sh.remove_path("./fuzz/coverage/")?; + sh.remove_path("./coverage/")?; + + sh.create_dir("./coverage/binaries")?; + + { + // Fuzz coverage + + let _guard = sh.push_dir("./fuzz"); + + cmd!(sh, "{CARGO} clean").run()?; + + for target in FUZZ_TARGETS { + cmd!(sh, "rustup run nightly cargo fuzz coverage {target}").run()?; + } + + cmd!(sh, "cp -r ./target ../coverage/binaries/").run()?; + } + + { + // Test coverage + + cmd!(sh, "{CARGO} clean").run()?; + + cmd!(sh, "rustup run nightly cargo test --workspace") + .env("CARGO_INCREMENTAL", "0") + .env("RUSTFLAGS", "-C instrument-coverage") + .env("LLVM_PROFILE_FILE", "./coverage/default-%m-%p.profraw") + .run()?; + + cmd!(sh, "cp -r ./target/debug ./coverage/binaries/").run()?; + } + + sh.create_dir("./docs")?; + + cmd!( + sh, + "grcov . ./fuzz + --source-dir . + --binary-path ./coverage/binaries/ + --output-type html + --branch + --ignore-not-existing + --ignore xtask/* + --ignore src/* + --ignore **/tests/* + --ignore crates/*-generators/* + --ignore crates/web/* + --ignore crates/client/* + --ignore crates/glutin-renderer/* + --ignore crates/glutin-client/* + --ignore crates/replay-client/* + --ignore crates/tls/* + --ignore fuzz/fuzz_targets/* + --ignore target/* + --ignore fuzz/target/* + --excl-start begin-no-coverage + --excl-stop end-no-coverage + -o ./docs/coverage" + ) + .run()?; + + println!("Code coverage report available in `./docs/coverage` folder"); + + println!("Clean up"); + + sh.remove_path("./coverage/")?; + sh.remove_path("./fuzz/coverage/")?; + sh.remove_path("./xtask/coverage/")?; + + sh.read_dir("./crates")? + .into_iter() + .try_for_each(|crate_path| -> xshell::Result<()> { + for path in sh.read_dir(crate_path)? { + if path.ends_with("coverage") { + sh.remove_path(path)?; + } + } + Ok(()) + })?; + + Ok(()) +} + +pub fn clean_workspace(sh: &Shell) -> anyhow::Result<()> { + let _s = Section::new("CLEAN"); + cmd!(sh, "{CARGO} clean").run()?; + Ok(()) +}