feat(ffi): initial C# bindings (connector only) (#423)

This commit is contained in:
irvingouj @ Devolutions 2024-04-05 11:11:32 -04:00 committed by GitHub
parent ba3796f738
commit 3bcf51306d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
107 changed files with 7058 additions and 2 deletions

8
.gitattribute Normal file
View file

@ -0,0 +1,8 @@
*.rs text eol=lf
*.toml text eol=lf
*.cs text eol=lf
*.js text eol=lf
*.ps1 text eol=lf
*.sln text eol=crlf
ffi/dotnet/Devolutions.IronRdp/Generated/** linguist-generated merge=binary

155
Cargo.lock generated
View file

@ -858,6 +858,39 @@ dependencies = [
"subtle",
]
[[package]]
name = "diplomat"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31672b3ebc3c7866c3c98726f7a9a5ac8f13962e77d3c8225f6be49a7b8c5f2"
dependencies = [
"diplomat_core",
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "diplomat-runtime"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b0f23d549a46540e26e5490cd44c64ced0d762959f1ffdec6ab0399634cf3c"
[[package]]
name = "diplomat_core"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfaa5e13e8b8735d2338f2836c06cd8643902ab87dda1dd07dbb351998ddc127"
dependencies = [
"lazy_static",
"proc-macro2",
"quote",
"serde",
"smallvec",
"strck_ident",
"syn 2.0.48",
]
[[package]]
name = "dispatch"
version = "0.2.0"
@ -1001,6 +1034,20 @@ dependencies = [
"zeroize",
]
[[package]]
name = "embed-resource"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d"
dependencies = [
"cc",
"memchr",
"rustc_version",
"toml",
"vswhom",
"winreg 0.52.0",
]
[[package]]
name = "encoding_rs"
version = "0.8.33"
@ -1073,6 +1120,18 @@ dependencies = [
"subtle",
]
[[package]]
name = "ffi"
version = "0.1.0"
dependencies = [
"diplomat",
"diplomat-runtime",
"embed-resource",
"ironrdp",
"sspi",
"thiserror",
]
[[package]]
name = "fiat-crypto"
version = "0.2.5"
@ -2951,7 +3010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
dependencies = [
"once_cell",
"toml_edit",
"toml_edit 0.19.15",
]
[[package]]
@ -3513,6 +3572,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -3764,6 +3832,22 @@ dependencies = [
"zeroize",
]
[[package]]
name = "strck"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be91090ded9d8f979d9fe921777342d37e769e0b6b7296843a7a38247240e917"
[[package]]
name = "strck_ident"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1c3802b169b3858a44667f221c9a0b3136e6019936ea926fc97fbad8af77202"
dependencies = [
"strck",
"unicode-ident",
]
[[package]]
name = "strict-num"
version = "0.1.1"
@ -4066,11 +4150,26 @@ dependencies = [
"tracing",
]
[[package]]
name = "toml"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.22.9",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
@ -4080,7 +4179,20 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
"winnow 0.5.34",
]
[[package]]
name = "toml_edit"
version = "0.22.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow 0.6.5",
]
[[package]]
@ -4325,6 +4437,26 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vswhom"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
dependencies = [
"libc",
"vswhom-sys",
]
[[package]]
name = "vswhom-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "wait-timeout"
version = "0.2.0"
@ -4879,6 +5011,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.50.0"
@ -4899,6 +5040,16 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "wyz"
version = "0.5.1"

View file

@ -2,6 +2,7 @@
members = [
"crates/*",
"xtask",
"ffi",
]
resolver = "2"

27
ffi/Cargo.toml Normal file
View file

@ -0,0 +1,27 @@
[package]
name = "ffi"
version = "0.1.0"
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
authors.workspace = true
keywords.workspace = true
categories.workspace = true
[lib]
name = "ironrdp"
crate-type = ["staticlib", "cdylib"]
doc = false
test = false
doctest = false
[dependencies]
diplomat = "0.7.0"
diplomat-runtime = "0.7.0"
ironrdp = { workspace = true, features = ["connector", "dvc", "svc","rdpdr","rdpsnd"] }
sspi = { workspace = true, features = ["network_client"] }
thiserror.workspace = true
[target.'cfg(windows)'.build-dependencies]
embed-resource = "2.2.0"

101
ffi/build.rs Normal file
View file

@ -0,0 +1,101 @@
#[cfg(not(target_os = "windows"))]
use other::main_stub;
#[cfg(target_os = "windows")]
use win::main_stub;
fn main() {
main_stub();
}
#[cfg(target_os = "windows")]
mod win {
extern crate embed_resource;
use std::env;
use std::fs::File;
use std::io::Write;
fn generate_version_rc() -> String {
let output_name = "DevolutionsIronRdp";
let filename = format!("{}.dll", output_name);
let company_name = "Devolutions Inc.";
let legal_copyright = format!("Copyright 2019-2024 {}", company_name);
let mut cargo_version = env::var("CARGO_PKG_VERSION").unwrap();
cargo_version.push_str(".0");
let version_number = cargo_version;
let version_commas = version_number.replace('.', ",");
let file_description = output_name;
let file_version = version_number.clone();
let internal_name = filename.clone();
let original_filename = filename;
let product_name = output_name;
let product_version = version_number;
let vs_file_version = version_commas.clone();
let vs_product_version = version_commas;
let version_rc = format!(
r#"#include <winresrc.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION {vs_file_version}
PRODUCTVERSION {vs_product_version}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "{company_name}"
VALUE "FileDescription", "{file_description}"
VALUE "FileVersion", "{file_version}"
VALUE "InternalName", "{internal_name}"
VALUE "LegalCopyright", "{legal_copyright}"
VALUE "OriginalFilename", "{original_filename}"
VALUE "ProductName", "{product_name}"
VALUE "ProductVersion", "{product_version}"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
"#,
vs_file_version = vs_file_version,
vs_product_version = vs_product_version,
company_name = company_name,
file_description = file_description,
file_version = file_version,
internal_name = internal_name,
legal_copyright = legal_copyright,
original_filename = original_filename,
product_name = product_name,
product_version = product_version
);
version_rc
}
pub(crate) fn main_stub() {
let out_dir = env::var("OUT_DIR").unwrap();
let version_rc_file = format!("{}/version.rc", out_dir);
let version_rc_data = generate_version_rc();
let mut file = File::create(&version_rc_file).expect("cannot create version.rc file");
file.write_all(version_rc_data.as_bytes()).unwrap();
embed_resource::compile(&version_rc_file, embed_resource::NONE);
}
}
#[cfg(not(target_os = "windows"))]
mod other {
pub(crate) fn main_stub() {}
}

View file

@ -0,0 +1,10 @@
namespace = "Devolutions.IronRdp"
native_lib = "DevolutionsIronRdp"
[exceptions]
trim_suffix = "Error"
error_message_method = "ToDisplay"
[properties]
setters_prefix = "set_"
getters_prefix = "get_"

View file

@ -0,0 +1,3 @@
obj
bin
.vs

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Devolutions.IronRdp/Devolutions.IronRdp.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,318 @@
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
namespace Devolutions.IronRdp.ConnectExample
{
class Program
{
static async Task Main(string[] args)
{
var arguments = ParseArguments(args);
if (arguments == null)
{
return;
}
var serverName = arguments["--serverName"];
var username = arguments["--username"];
var password = arguments["--password"];
var domain = arguments["--domain"];
try
{
await Connect(serverName, username, password, domain);
}
catch (Exception e)
{
Console.WriteLine($"An error occurred: {e.Message}");
}
}
static Dictionary<string, string> ParseArguments(string[] args)
{
if (args.Length == 0 || Array.Exists(args, arg => arg == "--help"))
{
PrintHelp();
return null;
}
var arguments = new Dictionary<string, string>();
string lastKey = null;
foreach (var arg in args)
{
if (arg.StartsWith("--"))
{
if (lastKey != null)
{
Console.WriteLine($"Error: Missing value for {lastKey}.");
PrintHelp();
return null;
}
if (!IsValidArgument(arg))
{
Console.WriteLine($"Error: Unknown argument {arg}.");
PrintHelp();
return null;
}
lastKey = arg;
}
else
{
if (lastKey == null)
{
Console.WriteLine("Error: Value without a preceding flag.");
PrintHelp();
return null;
}
arguments[lastKey] = arg;
lastKey = null;
}
}
if (lastKey != null)
{
Console.WriteLine($"Error: Missing value for {lastKey}.");
PrintHelp();
return null;
}
return arguments;
}
static bool IsValidArgument(string argument)
{
var validArguments = new List<string> { "--serverName", "--username", "--password", "--domain" };
return validArguments.Contains(argument);
}
static void PrintHelp()
{
Console.WriteLine("Usage: dotnet run -- [OPTIONS]");
Console.WriteLine("Options:");
Console.WriteLine(" --serverName <serverName> The name of the server to connect to.");
Console.WriteLine(" --username <username> The username for connection.");
Console.WriteLine(" --password <password> The password for connection.");
Console.WriteLine(" --domain <domain> The domain of the server.");
Console.WriteLine(" --help Show this message and exit.");
}
static async Task Connect(String servername, String username, String password, String domain)
{
Config config = buildConfig(servername, username, password, domain);
var stream = await CreateTcpConnection(servername, 3389);
var framed = new Framed<NetworkStream>(stream);
ClientConnector connector = ClientConnector.New(config);
var ip = await Dns.GetHostAddressesAsync(servername);
if (ip.Length == 0)
{
throw new Exception("Could not resolve server address");
}
var socketAddrString = ip[0].ToString()+":3389";
connector.WithServerAddr(socketAddrString);
await connectBegin(framed, connector);
var (serverPublicKey, framedSsl) = await securityUpgrade(servername, framed, connector);
await ConnectFinalize(servername, connector, serverPublicKey, framedSsl);
}
private static async Task<(byte[], Framed<SslStream>)> securityUpgrade(string servername, Framed<NetworkStream> framed, ClientConnector connector)
{
byte[] serverPublicKey;
Framed<SslStream> framedSsl;
var (streamRequireUpgrade, _) = framed.GetInner();
var promise = new TaskCompletionSource<byte[]>();
var sslStream = new SslStream(streamRequireUpgrade, false, (sender, certificate, chain, sslPolicyErrors) =>
{
promise.SetResult(certificate!.GetPublicKey());
return true;
});
await sslStream.AuthenticateAsClientAsync(servername);
serverPublicKey = await promise.Task;
framedSsl = new Framed<SslStream>(sslStream);
connector.MarkSecurityUpgradeAsDone();
return (serverPublicKey, framedSsl);
}
private static async Task connectBegin(Framed<NetworkStream> framed, ClientConnector connector)
{
var writeBuf = WriteBuf.New();
while (!connector.ShouldPerformSecurityUpgrade())
{
await SingleConnectStep(connector, writeBuf, framed);
}
}
private static Config buildConfig(string servername, string username, string password, string domain)
{
ConfigBuilder configBuilder = ConfigBuilder.New();
configBuilder.WithUsernameAndPasswrord(username, password);
configBuilder.SetDomain(domain);
configBuilder.SetDesktopSize(800, 600);
configBuilder.SetClientName("IronRdp");
configBuilder.SetClientDir("C:\\");
configBuilder.SetPerformanceFlags(PerformanceFlags.NewDefault());
return configBuilder.Build();
}
private static async Task ConnectFinalize(string servername, ClientConnector connector, byte[] serverpubkey, Framed<SslStream> framedSsl)
{
var writeBuf2 = WriteBuf.New();
if (connector.ShouldPerformCredssp())
{
await PerformCredsspSteps(connector, servername, writeBuf2, framedSsl, serverpubkey);
}
while (!connector.State().IsTerminal())
{
await SingleConnectStep(connector, writeBuf2, framedSsl);
}
}
private static async Task PerformCredsspSteps(ClientConnector connector, string serverName, WriteBuf writeBuf, Framed<SslStream> framedSsl, byte[] serverpubkey)
{
var credsspSequenceInitResult = CredsspSequence.Init(connector, serverName, serverpubkey, null);
var credsspSequence = credsspSequenceInitResult.GetCredsspSequence();
var tsRequest = credsspSequenceInitResult.GetTsRequest();
TcpClient tcpClient = new TcpClient();
while (true)
{
var generator = credsspSequence.ProcessTsRequest(tsRequest);
var clientState = await ResolveGenerator(generator, tcpClient);
writeBuf.Clear();
var written = credsspSequence.HandleProcessResult(clientState, writeBuf);
if (written.GetSize().IsSome())
{
var actualSize = (int)written.GetSize().Get();
var response = new byte[actualSize];
writeBuf.ReadIntoBuf(response);
await framedSsl.Write(response);
}
var pduHint = credsspSequence.NextPduHint()!;
if (pduHint == null)
{
break;
}
var pdu = await framedSsl.ReadByHint(pduHint);
var decoded = credsspSequence.DecodeServerMessage(pdu);
if (null == decoded)
{
break;
}
tsRequest = decoded;
}
}
private static async Task<ClientState> ResolveGenerator(CredsspProcessGenerator generator, TcpClient tcpClient)
{
var state = generator.Start();
NetworkStream stream = null;
while (true)
{
if (state.IsSuspended())
{
var request = state.GetNetworkRequestIfSuspended()!;
var protocol = request.GetProtocol();
var url = request.GetUrl();
var data = request.GetData();
if (null == stream)
{
url = url.Replace("tcp://", "");
var split = url.Split(":");
await tcpClient.ConnectAsync(split[0], int.Parse(split[1]));
stream = tcpClient.GetStream();
}
if (protocol == NetworkRequestProtocol.Tcp)
{
stream.Write(Utils.Vecu8ToByte(data));
var readBuf = new byte[8096];
var readlen = await stream.ReadAsync(readBuf, 0, readBuf.Length);
var actuallyRead = new byte[readlen];
Array.Copy(readBuf, actuallyRead, readlen);
state = generator.Resume(actuallyRead);
}
else
{
throw new Exception("Unimplemented protocol");
}
}
else
{
var client_state = state.GetClientStateIfCompleted();
return client_state;
}
}
}
static async Task SingleConnectStep<T>(ClientConnector connector, WriteBuf buf, Framed<T> framed)
where T : Stream
{
buf.Clear();
var pduHint = connector.NextPduHint();
Written written;
if (pduHint != null)
{
byte[] pdu = await framed.ReadByHint(pduHint);
written = connector.Step(pdu, buf);
}
else
{
written = connector.StepNoInput(buf);
}
if (written.GetWrittenType() == WrittenType.Nothing)
{
return;
}
// will throw if size is not set
var size = written.GetSize().Get();
var response = new byte[size];
buf.ReadIntoBuf(response);
await framed.Write(response);
}
static async Task<NetworkStream> CreateTcpConnection(String servername, int port)
{
IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync(servername);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint ipEndPoint = new(ipAddress, port);
TcpClient client = new TcpClient();
await client.ConnectAsync(ipEndPoint);
NetworkStream stream = client.GetStream();
return stream;
}
}
public static class Utils
{
public static byte[] Vecu8ToByte(VecU8 vecU8)
{
var len = vecU8.GetSize();
byte[] buffer = new byte[len];
vecU8.Fill(buffer);
return buffer;
}
}
}

View file

@ -0,0 +1,2 @@
obj
bin

View file

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,331 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class ClientConnector: IDisposable
{
private unsafe Raw.ClientConnector* _inner;
/// <summary>
/// Creates a managed <c>ClientConnector</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe ClientConnector(Raw.ClientConnector* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>ClientConnector</c> allocated on Rust side.
/// </returns>
public static ClientConnector New(Config config)
{
unsafe
{
Raw.Config* configRaw;
configRaw = config.AsFFI();
if (configRaw == null)
{
throw new ObjectDisposedException("Config");
}
Raw.ClientConnector* retVal = Raw.ClientConnector.New(configRaw);
return new ClientConnector(retVal);
}
}
/// <summary>
/// Must use
/// </summary>
/// <exception cref="IronRdpException"></exception>
public void WithServerAddr(string serverAddr)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
byte[] serverAddrBuf = DiplomatUtils.StringToUtf8(serverAddr);
nuint serverAddrBufLength = (nuint)serverAddrBuf.Length;
fixed (byte* serverAddrBufPtr = serverAddrBuf)
{
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithServerAddr(_inner, serverAddrBufPtr, serverAddrBufLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
}
/// <summary>
/// Must use
/// </summary>
/// <exception cref="IronRdpException"></exception>
public void WithStaticChannelRdpSnd()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithStaticChannelRdpSnd(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
/// <summary>
/// Must use
/// </summary>
/// <exception cref="IronRdpException"></exception>
public void WithStaticChannelRdpdr(string computerName, uint smartCardDeviceId)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
byte[] computerNameBuf = DiplomatUtils.StringToUtf8(computerName);
nuint computerNameBufLength = (nuint)computerNameBuf.Length;
fixed (byte* computerNameBufPtr = computerNameBuf)
{
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithStaticChannelRdpdr(_inner, computerNameBufPtr, computerNameBufLength, smartCardDeviceId);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
}
/// <exception cref="IronRdpException"></exception>
public bool ShouldPerformSecurityUpgrade()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultBoolBoxIronRdpError result = Raw.ClientConnector.ShouldPerformSecurityUpgrade(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
bool retVal = result.Ok;
return retVal;
}
}
/// <exception cref="IronRdpException"></exception>
public void MarkSecurityUpgradeAsDone()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.MarkSecurityUpgradeAsDone(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
/// <exception cref="IronRdpException"></exception>
public bool ShouldPerformCredssp()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultBoolBoxIronRdpError result = Raw.ClientConnector.ShouldPerformCredssp(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
bool retVal = result.Ok;
return retVal;
}
}
/// <exception cref="IronRdpException"></exception>
public void MarkCredsspAsDone()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.MarkCredsspAsDone(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>Written</c> allocated on Rust side.
/// </returns>
public Written Step(byte[] input, WriteBuf writeBuf)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
nuint inputLength = (nuint)input.Length;
Raw.WriteBuf* writeBufRaw;
writeBufRaw = writeBuf.AsFFI();
if (writeBufRaw == null)
{
throw new ObjectDisposedException("WriteBuf");
}
fixed (byte* inputPtr = input)
{
Raw.ConnectorFfiResultBoxWrittenBoxIronRdpError result = Raw.ClientConnector.Step(_inner, inputPtr, inputLength, writeBufRaw);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.Written* retVal = result.Ok;
return new Written(retVal);
}
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>Written</c> allocated on Rust side.
/// </returns>
public Written StepNoInput(WriteBuf writeBuf)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.WriteBuf* writeBufRaw;
writeBufRaw = writeBuf.AsFFI();
if (writeBufRaw == null)
{
throw new ObjectDisposedException("WriteBuf");
}
Raw.ConnectorFfiResultBoxWrittenBoxIronRdpError result = Raw.ClientConnector.StepNoInput(_inner, writeBufRaw);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.Written* retVal = result.Ok;
return new Written(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>PduHint</c> allocated on Rust side.
/// </returns>
public PduHint NextPduHint()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultOptBoxPduHintBoxIronRdpError result = Raw.ClientConnector.NextPduHint(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.PduHint* retVal = result.Ok;
if (retVal == null)
{
return null;
}
return new PduHint(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>State</c> allocated on Rust side.
/// </returns>
public State State()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.ConnectorFfiResultBoxStateBoxIronRdpError result = Raw.ClientConnector.State(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.State* retVal = result.Ok;
return new State(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.ClientConnector* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.ClientConnector.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~ClientConnector()
{
Dispose();
}
}

View file

@ -0,0 +1,63 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class ClientConnectorState: IDisposable
{
private unsafe Raw.ClientConnectorState* _inner;
/// <summary>
/// Creates a managed <c>ClientConnectorState</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe ClientConnectorState(Raw.ClientConnectorState* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.ClientConnectorState* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.ClientConnectorState.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~ClientConnectorState()
{
Dispose();
}
}

View file

@ -0,0 +1,119 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class ClientState: IDisposable
{
private unsafe Raw.ClientState* _inner;
public TsRequest TsRequest
{
get
{
return GetTsRequest();
}
}
/// <summary>
/// Creates a managed <c>ClientState</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe ClientState(Raw.ClientState* handle)
{
_inner = handle;
}
public bool IsReplyNeeded()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientState");
}
bool retVal = Raw.ClientState.IsReplyNeeded(_inner);
return retVal;
}
}
public bool IsFinalMessage()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientState");
}
bool retVal = Raw.ClientState.IsFinalMessage(_inner);
return retVal;
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>TsRequest</c> allocated on Rust side.
/// </returns>
public TsRequest GetTsRequest()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ClientState");
}
Raw.CredsspNetworkFfiResultBoxTsRequestBoxIronRdpError result = Raw.ClientState.GetTsRequest(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.TsRequest* retVal = result.Ok;
return new TsRequest(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.ClientState* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.ClientState.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~ClientState()
{
Dispose();
}
}

View file

@ -0,0 +1,75 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class Config: IDisposable
{
private unsafe Raw.Config* _inner;
/// <summary>
/// Creates a managed <c>Config</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe Config(Raw.Config* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>ConfigBuilder</c> allocated on Rust side.
/// </returns>
public static ConfigBuilder GetBuilder()
{
unsafe
{
Raw.ConfigBuilder* retVal = Raw.Config.GetBuilder();
return new ConfigBuilder(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.Config* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.Config.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~Config()
{
Dispose();
}
}

View file

@ -0,0 +1,464 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class ConfigBuilder: IDisposable
{
private unsafe Raw.ConfigBuilder* _inner;
public bool Autologon
{
set
{
SetAutologon(value);
}
}
public uint ClientBuild
{
set
{
SetClientBuild(value);
}
}
public string ClientDir
{
set
{
SetClientDir(value);
}
}
public string ClientName
{
set
{
SetClientName(value);
}
}
public string DigProductId
{
set
{
SetDigProductId(value);
}
}
public string Domain
{
set
{
SetDomain(value);
}
}
public bool EnableCredssp
{
set
{
SetEnableCredssp(value);
}
}
public bool EnableTls
{
set
{
SetEnableTls(value);
}
}
public string ImeFileName
{
set
{
SetImeFileName(value);
}
}
public uint KeyboardFunctionalKeysCount
{
set
{
SetKeyboardFunctionalKeysCount(value);
}
}
public uint KeyboardSubtype
{
set
{
SetKeyboardSubtype(value);
}
}
public KeyboardType KeyboardType
{
set
{
SetKeyboardType(value);
}
}
public bool NoServerPointer
{
set
{
SetNoServerPointer(value);
}
}
public PerformanceFlags PerformanceFlags
{
set
{
SetPerformanceFlags(value);
}
}
public bool PointerSoftwareRendering
{
set
{
SetPointerSoftwareRendering(value);
}
}
/// <summary>
/// Creates a managed <c>ConfigBuilder</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe ConfigBuilder(Raw.ConfigBuilder* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>ConfigBuilder</c> allocated on Rust side.
/// </returns>
public static ConfigBuilder New()
{
unsafe
{
Raw.ConfigBuilder* retVal = Raw.ConfigBuilder.New();
return new ConfigBuilder(retVal);
}
}
public void WithUsernameAndPasswrord(string username, string password)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] usernameBuf = DiplomatUtils.StringToUtf8(username);
byte[] passwordBuf = DiplomatUtils.StringToUtf8(password);
nuint usernameBufLength = (nuint)usernameBuf.Length;
nuint passwordBufLength = (nuint)passwordBuf.Length;
fixed (byte* usernameBufPtr = usernameBuf)
{
fixed (byte* passwordBufPtr = passwordBuf)
{
Raw.ConfigBuilder.WithUsernameAndPasswrord(_inner, usernameBufPtr, usernameBufLength, passwordBufPtr, passwordBufLength);
}
}
}
}
public void SetDomain(string domain)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] domainBuf = DiplomatUtils.StringToUtf8(domain);
nuint domainBufLength = (nuint)domainBuf.Length;
fixed (byte* domainBufPtr = domainBuf)
{
Raw.ConfigBuilder.SetDomain(_inner, domainBufPtr, domainBufLength);
}
}
}
public void SetEnableTls(bool enableTls)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetEnableTls(_inner, enableTls);
}
}
public void SetEnableCredssp(bool enableCredssp)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetEnableCredssp(_inner, enableCredssp);
}
}
public void SetKeyboardType(KeyboardType keyboardType)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.KeyboardType keyboardTypeRaw;
keyboardTypeRaw = (Raw.KeyboardType)keyboardType;
Raw.ConfigBuilder.SetKeyboardType(_inner, keyboardTypeRaw);
}
}
public void SetKeyboardSubtype(uint keyboardSubtype)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetKeyboardSubtype(_inner, keyboardSubtype);
}
}
public void SetKeyboardFunctionalKeysCount(uint keyboardFunctionalKeysCount)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetKeyboardFunctionalKeysCount(_inner, keyboardFunctionalKeysCount);
}
}
public void SetImeFileName(string imeFileName)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] imeFileNameBuf = DiplomatUtils.StringToUtf8(imeFileName);
nuint imeFileNameBufLength = (nuint)imeFileNameBuf.Length;
fixed (byte* imeFileNameBufPtr = imeFileNameBuf)
{
Raw.ConfigBuilder.SetImeFileName(_inner, imeFileNameBufPtr, imeFileNameBufLength);
}
}
}
public void SetDigProductId(string digProductId)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] digProductIdBuf = DiplomatUtils.StringToUtf8(digProductId);
nuint digProductIdBufLength = (nuint)digProductIdBuf.Length;
fixed (byte* digProductIdBufPtr = digProductIdBuf)
{
Raw.ConfigBuilder.SetDigProductId(_inner, digProductIdBufPtr, digProductIdBufLength);
}
}
}
public void SetDesktopSize(ushort height, ushort width)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetDesktopSize(_inner, height, width);
}
}
public void SetPerformanceFlags(PerformanceFlags performanceFlags)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.PerformanceFlags* performanceFlagsRaw;
performanceFlagsRaw = performanceFlags.AsFFI();
if (performanceFlagsRaw == null)
{
throw new ObjectDisposedException("PerformanceFlags");
}
Raw.ConfigBuilder.SetPerformanceFlags(_inner, performanceFlagsRaw);
}
}
public void SetClientBuild(uint clientBuild)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetClientBuild(_inner, clientBuild);
}
}
public void SetClientName(string clientName)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] clientNameBuf = DiplomatUtils.StringToUtf8(clientName);
nuint clientNameBufLength = (nuint)clientNameBuf.Length;
fixed (byte* clientNameBufPtr = clientNameBuf)
{
Raw.ConfigBuilder.SetClientName(_inner, clientNameBufPtr, clientNameBufLength);
}
}
}
public void SetClientDir(string clientDir)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
byte[] clientDirBuf = DiplomatUtils.StringToUtf8(clientDir);
nuint clientDirBufLength = (nuint)clientDirBuf.Length;
fixed (byte* clientDirBufPtr = clientDirBuf)
{
Raw.ConfigBuilder.SetClientDir(_inner, clientDirBufPtr, clientDirBufLength);
}
}
}
public void SetNoServerPointer(bool noServerPointer)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetNoServerPointer(_inner, noServerPointer);
}
}
public void SetAutologon(bool autologon)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetAutologon(_inner, autologon);
}
}
public void SetPointerSoftwareRendering(bool pointerSoftwareRendering)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConfigBuilder.SetPointerSoftwareRendering(_inner, pointerSoftwareRendering);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>Config</c> allocated on Rust side.
/// </returns>
public Config Build()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConfigBuilder");
}
Raw.ConnectorConfigFfiResultBoxConfigBoxIronRdpError result = Raw.ConfigBuilder.Build(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.Config* retVal = result.Ok;
return new Config(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.ConfigBuilder* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.ConfigBuilder.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~ConfigBuilder()
{
Dispose();
}
}

View file

@ -0,0 +1,195 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class ConnectionResult: IDisposable
{
private unsafe Raw.ConnectionResult* _inner;
public DesktopSize DesktopSize
{
get
{
return GetDesktopSize();
}
}
public ushort IoChannelId
{
get
{
return GetIoChannelId();
}
}
public bool NoServerPointer
{
get
{
return GetNoServerPointer();
}
}
public bool PointerSoftwareRendering
{
get
{
return GetPointerSoftwareRendering();
}
}
public StaticChannelSet StaticChannels
{
get
{
return GetStaticChannels();
}
}
public ushort UserChannelId
{
get
{
return GetUserChannelId();
}
}
/// <summary>
/// Creates a managed <c>ConnectionResult</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe ConnectionResult(Raw.ConnectionResult* handle)
{
_inner = handle;
}
public ushort GetIoChannelId()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
ushort retVal = Raw.ConnectionResult.GetIoChannelId(_inner);
return retVal;
}
}
public ushort GetUserChannelId()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
ushort retVal = Raw.ConnectionResult.GetUserChannelId(_inner);
return retVal;
}
}
/// <returns>
/// A <c>StaticChannelSet</c> allocated on Rust side.
/// </returns>
public StaticChannelSet GetStaticChannels()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
Raw.StaticChannelSet* retVal = Raw.ConnectionResult.GetStaticChannels(_inner);
return new StaticChannelSet(retVal);
}
}
/// <returns>
/// A <c>DesktopSize</c> allocated on Rust side.
/// </returns>
public DesktopSize GetDesktopSize()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
Raw.DesktopSize* retVal = Raw.ConnectionResult.GetDesktopSize(_inner);
return new DesktopSize(retVal);
}
}
public bool GetNoServerPointer()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
bool retVal = Raw.ConnectionResult.GetNoServerPointer(_inner);
return retVal;
}
}
public bool GetPointerSoftwareRendering()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("ConnectionResult");
}
bool retVal = Raw.ConnectionResult.GetPointerSoftwareRendering(_inner);
return retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.ConnectionResult* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.ConnectionResult.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~ConnectionResult()
{
Dispose();
}
}

View file

@ -0,0 +1,111 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class CredsspProcessGenerator: IDisposable
{
private unsafe Raw.CredsspProcessGenerator* _inner;
/// <summary>
/// Creates a managed <c>CredsspProcessGenerator</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe CredsspProcessGenerator(Raw.CredsspProcessGenerator* handle)
{
_inner = handle;
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>GeneratorState</c> allocated on Rust side.
/// </returns>
public GeneratorState Start()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspProcessGenerator");
}
Raw.CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError result = Raw.CredsspProcessGenerator.Start(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.GeneratorState* retVal = result.Ok;
return new GeneratorState(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>GeneratorState</c> allocated on Rust side.
/// </returns>
public GeneratorState Resume(byte[] response)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspProcessGenerator");
}
nuint responseLength = (nuint)response.Length;
fixed (byte* responsePtr = response)
{
Raw.CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError result = Raw.CredsspProcessGenerator.Resume(_inner, responsePtr, responseLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.GeneratorState* retVal = result.Ok;
return new GeneratorState(retVal);
}
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.CredsspProcessGenerator* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.CredsspProcessGenerator.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~CredsspProcessGenerator()
{
Dispose();
}
}

View file

@ -0,0 +1,221 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class CredsspSequence: IDisposable
{
private unsafe Raw.CredsspSequence* _inner;
/// <summary>
/// Creates a managed <c>CredsspSequence</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe CredsspSequence(Raw.CredsspSequence* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>PduHint</c> allocated on Rust side.
/// </returns>
public PduHint? NextPduHint()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequence");
}
Raw.PduHint* retVal = Raw.CredsspSequence.NextPduHint(_inner);
if (retVal == null)
{
return null;
}
return new PduHint(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>CredsspSequenceInitResult</c> allocated on Rust side.
/// </returns>
public static CredsspSequenceInitResult Init(ClientConnector connector, string serverName, byte[] serverPublicKey, KerberosConfig? kerberoConfigs)
{
unsafe
{
byte[] serverNameBuf = DiplomatUtils.StringToUtf8(serverName);
nuint serverPublicKeyLength = (nuint)serverPublicKey.Length;
nuint serverNameBufLength = (nuint)serverNameBuf.Length;
Raw.ClientConnector* connectorRaw;
connectorRaw = connector.AsFFI();
if (connectorRaw == null)
{
throw new ObjectDisposedException("ClientConnector");
}
Raw.KerberosConfig* kerberoConfigsRaw;
if (kerberoConfigs == null)
{
kerberoConfigsRaw = null;
}
else
{
kerberoConfigsRaw = kerberoConfigs.AsFFI();
if (kerberoConfigsRaw == null)
{
throw new ObjectDisposedException("KerberosConfig");
}
}
fixed (byte* serverPublicKeyPtr = serverPublicKey)
{
fixed (byte* serverNameBufPtr = serverNameBuf)
{
Raw.CredsspFfiResultBoxCredsspSequenceInitResultBoxIronRdpError result = Raw.CredsspSequence.Init(connectorRaw, serverNameBufPtr, serverNameBufLength, serverPublicKeyPtr, serverPublicKeyLength, kerberoConfigsRaw);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.CredsspSequenceInitResult* retVal = result.Ok;
return new CredsspSequenceInitResult(retVal);
}
}
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>TsRequest</c> allocated on Rust side.
/// </returns>
public TsRequest DecodeServerMessage(byte[] pdu)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequence");
}
nuint pduLength = (nuint)pdu.Length;
fixed (byte* pduPtr = pdu)
{
Raw.CredsspFfiResultOptBoxTsRequestBoxIronRdpError result = Raw.CredsspSequence.DecodeServerMessage(_inner, pduPtr, pduLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.TsRequest* retVal = result.Ok;
if (retVal == null)
{
return null;
}
return new TsRequest(retVal);
}
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>CredsspProcessGenerator</c> allocated on Rust side.
/// </returns>
public CredsspProcessGenerator ProcessTsRequest(TsRequest tsRequest)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequence");
}
Raw.TsRequest* tsRequestRaw;
tsRequestRaw = tsRequest.AsFFI();
if (tsRequestRaw == null)
{
throw new ObjectDisposedException("TsRequest");
}
Raw.CredsspFfiResultBoxCredsspProcessGeneratorBoxIronRdpError result = Raw.CredsspSequence.ProcessTsRequest(_inner, tsRequestRaw);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.CredsspProcessGenerator* retVal = result.Ok;
return new CredsspProcessGenerator(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>Written</c> allocated on Rust side.
/// </returns>
public Written HandleProcessResult(ClientState clientState, WriteBuf buf)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequence");
}
Raw.ClientState* clientStateRaw;
clientStateRaw = clientState.AsFFI();
if (clientStateRaw == null)
{
throw new ObjectDisposedException("ClientState");
}
Raw.WriteBuf* bufRaw;
bufRaw = buf.AsFFI();
if (bufRaw == null)
{
throw new ObjectDisposedException("WriteBuf");
}
Raw.CredsspFfiResultBoxWrittenBoxIronRdpError result = Raw.CredsspSequence.HandleProcessResult(_inner, clientStateRaw, bufRaw);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.Written* retVal = result.Ok;
return new Written(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.CredsspSequence* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.CredsspSequence.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~CredsspSequence()
{
Dispose();
}
}

View file

@ -0,0 +1,123 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class CredsspSequenceInitResult: IDisposable
{
private unsafe Raw.CredsspSequenceInitResult* _inner;
public CredsspSequence CredsspSequence
{
get
{
return GetCredsspSequence();
}
}
public TsRequest TsRequest
{
get
{
return GetTsRequest();
}
}
/// <summary>
/// Creates a managed <c>CredsspSequenceInitResult</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe CredsspSequenceInitResult(Raw.CredsspSequenceInitResult* handle)
{
_inner = handle;
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>CredsspSequence</c> allocated on Rust side.
/// </returns>
public CredsspSequence GetCredsspSequence()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequenceInitResult");
}
Raw.CredsspFfiResultBoxCredsspSequenceBoxIronRdpError result = Raw.CredsspSequenceInitResult.GetCredsspSequence(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.CredsspSequence* retVal = result.Ok;
return new CredsspSequence(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>TsRequest</c> allocated on Rust side.
/// </returns>
public TsRequest GetTsRequest()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("CredsspSequenceInitResult");
}
Raw.CredsspFfiResultBoxTsRequestBoxIronRdpError result = Raw.CredsspSequenceInitResult.GetTsRequest(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.TsRequest* retVal = result.Ok;
return new TsRequest(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.CredsspSequenceInitResult* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.CredsspSequenceInitResult.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~CredsspSequenceInitResult()
{
Dispose();
}
}

View file

@ -0,0 +1,105 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class DesktopSize: IDisposable
{
private unsafe Raw.DesktopSize* _inner;
public ushort Height
{
get
{
return GetHeight();
}
}
public ushort Width
{
get
{
return GetWidth();
}
}
/// <summary>
/// Creates a managed <c>DesktopSize</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe DesktopSize(Raw.DesktopSize* handle)
{
_inner = handle;
}
public ushort GetWidth()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("DesktopSize");
}
ushort retVal = Raw.DesktopSize.GetWidth(_inner);
return retVal;
}
}
public ushort GetHeight()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("DesktopSize");
}
ushort retVal = Raw.DesktopSize.GetHeight(_inner);
return retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.DesktopSize* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.DesktopSize.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~DesktopSize()
{
Dispose();
}
}

View file

@ -0,0 +1,172 @@
// Automatically generated by Diplomat
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Devolutions.IronRdp.Diplomat;
#nullable enable
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void WriteableFlush(IntPtr self);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
delegate bool WriteableGrow(IntPtr self, nuint capacity);
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct DiplomatWriteable : IDisposable
{
// About the current approach:
// Ideally DiplomatWriteable should wrap the native string type and grows/writes directly into the internal buffer.
// However, there is no native string type backed by UTF-8 in dotnet frameworks.
// Alternative could be to provide Diplomat's own `Utf8String` type, but this is not trivial and mostly useless
// on its own because all other dotnet/C# APIs are expecting the standard UTF-16 encoded string/String type.
// API is expectedto become overall less ergonomic by forcing users to explicitly convert between UTF-16 and UTF-8 anyway in such case.
// It could be useful for copy-free interactions between Diplomat-generated API though.
// Also, there is no way to re-use the unmanaged buffer as-is to get a managed byte[]
// (hence `ToUtf8Bytes` is copying the internal buffer from unmanaged to managed memory).
// It's encouraged to enable memoization when applicable (#129).
IntPtr context;
IntPtr buf;
nuint len;
nuint cap;
readonly IntPtr flush;
readonly IntPtr grow;
public DiplomatWriteable()
{
WriteableFlush flushFunc = Flush;
WriteableGrow growFunc = Grow;
IntPtr flushFuncPtr = Marshal.GetFunctionPointerForDelegate(flushFunc);
IntPtr growFuncPtr = Marshal.GetFunctionPointerForDelegate(growFunc);
// flushFunc and growFunc are managed objects and might be disposed of by the garbage collector.
// To prevent this, we make the context hold the references and protect the context itself
// for automatic disposal by moving it behind a GCHandle.
DiplomatWriteableContext ctx = new DiplomatWriteableContext();
ctx.flushFunc = flushFunc;
ctx.growFunc = growFunc;
GCHandle ctxHandle = GCHandle.Alloc(ctx);
context = GCHandle.ToIntPtr(ctxHandle);
buf = Marshal.AllocHGlobal(64);
len = 0;
cap = 64;
flush = flushFuncPtr;
grow = growFuncPtr;
}
public byte[] ToUtf8Bytes()
{
if (len > int.MaxValue)
{
throw new IndexOutOfRangeException("DiplomatWriteable buffer is too big");
}
byte[] managedArray = new byte[(int)len];
Marshal.Copy(buf, managedArray, 0, (int)len);
return managedArray;
}
public string ToUnicode()
{
#if NET6_0_OR_GREATER
if (len > int.MaxValue)
{
throw new IndexOutOfRangeException("DiplomatWriteable buffer is too big");
}
return Marshal.PtrToStringUTF8(buf, (int) len);
#else
byte[] utf8 = ToUtf8Bytes();
return DiplomatUtils.Utf8ToString(utf8);
#endif
}
public void Dispose()
{
if (buf != IntPtr.Zero)
{
Marshal.FreeHGlobal(buf);
buf = IntPtr.Zero;
}
if (context != IntPtr.Zero)
{
GCHandle.FromIntPtr(context).Free();
context = IntPtr.Zero;
}
}
private static void Flush(IntPtr self)
{
// Nothing to do
}
[return: MarshalAs(UnmanagedType.U1)]
private unsafe static bool Grow(IntPtr writeable, nuint capacity)
{
if (writeable == IntPtr.Zero)
{
return false;
}
DiplomatWriteable* self = (DiplomatWriteable*)writeable;
nuint newCap = capacity;
if (newCap > int.MaxValue)
{
return false;
}
IntPtr newBuf;
try
{
newBuf = Marshal.AllocHGlobal((int)newCap);
}
catch (OutOfMemoryException)
{
return false;
}
Buffer.MemoryCopy((void*)self->buf, (void*)newBuf, newCap, self->cap);
Marshal.FreeHGlobal(self->buf);
self->buf = newBuf;
self->cap = newCap;
return true;
}
}
internal struct DiplomatWriteableContext
{
internal WriteableFlush flushFunc;
internal WriteableGrow growFunc;
}
internal static class DiplomatUtils
{
internal static byte[] StringToUtf8(string s)
{
int size = Encoding.UTF8.GetByteCount(s);
byte[] buf = new byte[size];
Encoding.UTF8.GetBytes(s, 0, s.Length, buf, 0);
return buf;
}
internal static string Utf8ToString(byte[] utf8)
{
char[] chars = new char[utf8.Length];
Encoding.UTF8.GetChars(utf8, 0, utf8.Length, chars, 0);
return new string(chars);
}
}
public class DiplomatOpaqueException : Exception
{
public DiplomatOpaqueException() : base("The FFI function failed with an opaque error") { }
}

View file

@ -0,0 +1,63 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class DrdynvcChannel: IDisposable
{
private unsafe Raw.DrdynvcChannel* _inner;
/// <summary>
/// Creates a managed <c>DrdynvcChannel</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe DrdynvcChannel(Raw.DrdynvcChannel* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.DrdynvcChannel* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.DrdynvcChannel.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~DrdynvcChannel()
{
Dispose();
}
}

View file

@ -0,0 +1,147 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class GeneratorState: IDisposable
{
private unsafe Raw.GeneratorState* _inner;
public ClientState ClientStateIfCompleted
{
get
{
return GetClientStateIfCompleted();
}
}
public NetworkRequest? NetworkRequestIfSuspended
{
get
{
return GetNetworkRequestIfSuspended();
}
}
/// <summary>
/// Creates a managed <c>GeneratorState</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe GeneratorState(Raw.GeneratorState* handle)
{
_inner = handle;
}
public bool IsSuspended()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("GeneratorState");
}
bool retVal = Raw.GeneratorState.IsSuspended(_inner);
return retVal;
}
}
public bool IsCompleted()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("GeneratorState");
}
bool retVal = Raw.GeneratorState.IsCompleted(_inner);
return retVal;
}
}
/// <returns>
/// A <c>NetworkRequest</c> allocated on Rust side.
/// </returns>
public NetworkRequest? GetNetworkRequestIfSuspended()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("GeneratorState");
}
Raw.NetworkRequest* retVal = Raw.GeneratorState.GetNetworkRequestIfSuspended(_inner);
if (retVal == null)
{
return null;
}
return new NetworkRequest(retVal);
}
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>ClientState</c> allocated on Rust side.
/// </returns>
public ClientState GetClientStateIfCompleted()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("GeneratorState");
}
Raw.CredsspNetworkFfiResultBoxClientStateBoxIronRdpError result = Raw.GeneratorState.GetClientStateIfCompleted(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.ClientState* retVal = result.Ok;
return new ClientState(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.GeneratorState* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.GeneratorState.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~GeneratorState()
{
Dispose();
}
}

View file

@ -0,0 +1,127 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
/// <summary>
/// Stringified Picky error along with an error kind.
/// </summary>
public partial class IronRdpError: IDisposable
{
private unsafe Raw.IronRdpError* _inner;
public IronRdpErrorKind Kind
{
get
{
return GetKind();
}
}
/// <summary>
/// Creates a managed <c>IronRdpError</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe IronRdpError(Raw.IronRdpError* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the error as a string.
/// </summary>
public void ToDisplay(DiplomatWriteable writeable)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("IronRdpError");
}
Raw.IronRdpError.ToDisplay(_inner, &writeable);
}
}
/// <summary>
/// Returns the error as a string.
/// </summary>
public string ToDisplay()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("IronRdpError");
}
DiplomatWriteable writeable = new DiplomatWriteable();
Raw.IronRdpError.ToDisplay(_inner, &writeable);
string retVal = writeable.ToUnicode();
writeable.Dispose();
return retVal;
}
}
/// <summary>
/// Returns the error kind.
/// </summary>
/// <returns>
/// A <c>IronRdpErrorKind</c> allocated on C# side.
/// </returns>
public IronRdpErrorKind GetKind()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("IronRdpError");
}
Raw.IronRdpErrorKind retVal = Raw.IronRdpError.GetKind(_inner);
return (IronRdpErrorKind)retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.IronRdpError* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.IronRdpError.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~IronRdpError()
{
Dispose();
}
}

View file

@ -0,0 +1,22 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public enum IronRdpErrorKind
{
Generic = 0,
PduError = 1,
CredsspError = 2,
Consumed = 3,
IO = 4,
AccessDenied = 5,
}

View file

@ -0,0 +1,30 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class IronRdpException : Exception
{
private IronRdpError _inner;
public IronRdpException(IronRdpError inner) : base(inner.ToDisplay())
{
_inner = inner;
}
public IronRdpError Inner
{
get
{
return _inner;
}
}
}

View file

@ -0,0 +1,63 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class KerberosConfig: IDisposable
{
private unsafe Raw.KerberosConfig* _inner;
/// <summary>
/// Creates a managed <c>KerberosConfig</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe KerberosConfig(Raw.KerberosConfig* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.KerberosConfig* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.KerberosConfig.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~KerberosConfig()
{
Dispose();
}
}

View file

@ -0,0 +1,23 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public enum KeyboardType
{
IbmPcXt = 0,
OlivettiIco = 1,
IbmPcAt = 2,
IbmEnhanced = 3,
Nokia1050 = 4,
Nokia9140 = 5,
Japanese = 6,
}

View file

@ -0,0 +1,157 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class NetworkRequest: IDisposable
{
private unsafe Raw.NetworkRequest* _inner;
public VecU8 Data
{
get
{
return GetData();
}
}
public NetworkRequestProtocol Protocol
{
get
{
return GetProtocol();
}
}
public string Url
{
get
{
return GetUrl();
}
}
/// <summary>
/// Creates a managed <c>NetworkRequest</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe NetworkRequest(Raw.NetworkRequest* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>VecU8</c> allocated on Rust side.
/// </returns>
public VecU8 GetData()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("NetworkRequest");
}
Raw.VecU8* retVal = Raw.NetworkRequest.GetData(_inner);
return new VecU8(retVal);
}
}
/// <returns>
/// A <c>NetworkRequestProtocol</c> allocated on C# side.
/// </returns>
public NetworkRequestProtocol GetProtocol()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("NetworkRequest");
}
Raw.NetworkRequestProtocol retVal = Raw.NetworkRequest.GetProtocol(_inner);
return (NetworkRequestProtocol)retVal;
}
}
/// <exception cref="IronRdpException"></exception>
public void GetUrl(DiplomatWriteable writeable)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("NetworkRequest");
}
Raw.CredsspNetworkFfiResultVoidBoxIronRdpError result = Raw.NetworkRequest.GetUrl(_inner, &writeable);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
/// <exception cref="IronRdpException"></exception>
public string GetUrl()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("NetworkRequest");
}
DiplomatWriteable writeable = new DiplomatWriteable();
Raw.CredsspNetworkFfiResultVoidBoxIronRdpError result = Raw.NetworkRequest.GetUrl(_inner, &writeable);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
string retVal = writeable.ToUnicode();
writeable.Dispose();
return retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.NetworkRequest* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.NetworkRequest.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~NetworkRequest()
{
Dispose();
}
}

View file

@ -0,0 +1,20 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public enum NetworkRequestProtocol
{
Tcp = 0,
Udp = 1,
Http = 2,
Https = 3,
}

View file

@ -0,0 +1,95 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class OptionalUsize: IDisposable
{
private unsafe Raw.OptionalUsize* _inner;
/// <summary>
/// Creates a managed <c>OptionalUsize</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe OptionalUsize(Raw.OptionalUsize* handle)
{
_inner = handle;
}
public bool IsSome()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("OptionalUsize");
}
bool retVal = Raw.OptionalUsize.IsSome(_inner);
return retVal;
}
}
/// <exception cref="IronRdpException"></exception>
public nuint Get()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("OptionalUsize");
}
Raw.UtilsFfiResultUsizeBoxIronRdpError result = Raw.OptionalUsize.Get(_inner);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
nuint retVal = result.Ok;
return retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.OptionalUsize* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.OptionalUsize.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~OptionalUsize()
{
Dispose();
}
}

View file

@ -0,0 +1,89 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class PduHint: IDisposable
{
private unsafe Raw.PduHint* _inner;
/// <summary>
/// Creates a managed <c>PduHint</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe PduHint(Raw.PduHint* handle)
{
_inner = handle;
}
/// <exception cref="IronRdpException"></exception>
/// <returns>
/// A <c>OptionalUsize</c> allocated on Rust side.
/// </returns>
public OptionalUsize FindSize(byte[] bytes)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("PduHint");
}
nuint bytesLength = (nuint)bytes.Length;
fixed (byte* bytesPtr = bytes)
{
Raw.ConnectorFfiResultBoxOptionalUsizeBoxIronRdpError result = Raw.PduHint.FindSize(_inner, bytesPtr, bytesLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
Raw.OptionalUsize* retVal = result.Ok;
return new OptionalUsize(retVal);
}
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.PduHint* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.PduHint.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~PduHint()
{
Dispose();
}
}

View file

@ -0,0 +1,101 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class PerformanceFlags: IDisposable
{
private unsafe Raw.PerformanceFlags* _inner;
/// <summary>
/// Creates a managed <c>PerformanceFlags</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe PerformanceFlags(Raw.PerformanceFlags* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>PerformanceFlags</c> allocated on Rust side.
/// </returns>
public static PerformanceFlags NewDefault()
{
unsafe
{
Raw.PerformanceFlags* retVal = Raw.PerformanceFlags.NewDefault();
return new PerformanceFlags(retVal);
}
}
/// <returns>
/// A <c>PerformanceFlags</c> allocated on Rust side.
/// </returns>
public static PerformanceFlags NewEmpty()
{
unsafe
{
Raw.PerformanceFlags* retVal = Raw.PerformanceFlags.NewEmpty();
return new PerformanceFlags(retVal);
}
}
public void AddFlag(PerformanceFlagsType flag)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("PerformanceFlags");
}
Raw.PerformanceFlagsType flagRaw;
flagRaw = (Raw.PerformanceFlagsType)flag;
Raw.PerformanceFlags.AddFlag(_inner, flagRaw);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.PerformanceFlags* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.PerformanceFlags.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~PerformanceFlags()
{
Dispose();
}
}

View file

@ -0,0 +1,26 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public enum PerformanceFlagsType
{
DisableWallpaper = 0,
DisableFullWindowDrag = 1,
DisableMenuAnimations = 2,
DisableTheming = 3,
Reserved1 = 4,
DisableCursorShadow = 5,
DisableCursorSettings = 6,
EnableFontSmoothing = 7,
EnableDesktopComposition = 8,
Reserved2 = 9,
}

View file

@ -0,0 +1,66 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ClientConnector
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_new", ExactSpelling = true)]
public static unsafe extern ClientConnector* New(Config* config);
/// <summary>
/// Must use
/// </summary>
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_with_server_addr", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError WithServerAddr(ClientConnector* self, byte* serverAddr, nuint serverAddrSz);
/// <summary>
/// Must use
/// </summary>
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_with_static_channel_rdp_snd", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError WithStaticChannelRdpSnd(ClientConnector* self);
/// <summary>
/// Must use
/// </summary>
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_with_static_channel_rdpdr", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError WithStaticChannelRdpdr(ClientConnector* self, byte* computerName, nuint computerNameSz, uint smartCardDeviceId);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_should_perform_security_upgrade", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoolBoxIronRdpError ShouldPerformSecurityUpgrade(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_mark_security_upgrade_as_done", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError MarkSecurityUpgradeAsDone(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_should_perform_credssp", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoolBoxIronRdpError ShouldPerformCredssp(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_mark_credssp_as_done", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError MarkCredsspAsDone(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_step", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoxWrittenBoxIronRdpError Step(ClientConnector* self, byte* input, nuint inputSz, WriteBuf* writeBuf);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_step_no_input", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoxWrittenBoxIronRdpError StepNoInput(ClientConnector* self, WriteBuf* writeBuf);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_next_pdu_hint", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultOptBoxPduHintBoxIronRdpError NextPduHint(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_state", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoxStateBoxIronRdpError State(ClientConnector* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(ClientConnector* self);
}

View file

@ -0,0 +1,21 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ClientConnectorState
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(ClientConnectorState* self);
}

View file

@ -0,0 +1,32 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ClientState
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientState_is_reply_needed", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsReplyNeeded(ClientState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientState_is_final_message", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsFinalMessage(ClientState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientState_get_ts_request", ExactSpelling = true)]
public static unsafe extern CredsspNetworkFfiResultBoxTsRequestBoxIronRdpError GetTsRequest(ClientState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientState_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(ClientState* self);
}

View file

@ -0,0 +1,24 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct Config
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Config_get_builder", ExactSpelling = true)]
public static unsafe extern ConfigBuilder* GetBuilder();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Config_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(Config* self);
}

View file

@ -0,0 +1,78 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConfigBuilder
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_new", ExactSpelling = true)]
public static unsafe extern ConfigBuilder* New();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_with_username_and_passwrord", ExactSpelling = true)]
public static unsafe extern void WithUsernameAndPasswrord(ConfigBuilder* self, byte* username, nuint usernameSz, byte* password, nuint passwordSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_domain", ExactSpelling = true)]
public static unsafe extern void SetDomain(ConfigBuilder* self, byte* domain, nuint domainSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_enable_tls", ExactSpelling = true)]
public static unsafe extern void SetEnableTls(ConfigBuilder* self, [MarshalAs(UnmanagedType.U1)] bool enableTls);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_enable_credssp", ExactSpelling = true)]
public static unsafe extern void SetEnableCredssp(ConfigBuilder* self, [MarshalAs(UnmanagedType.U1)] bool enableCredssp);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_keyboard_type", ExactSpelling = true)]
public static unsafe extern void SetKeyboardType(ConfigBuilder* self, KeyboardType keyboardType);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_keyboard_subtype", ExactSpelling = true)]
public static unsafe extern void SetKeyboardSubtype(ConfigBuilder* self, uint keyboardSubtype);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_keyboard_functional_keys_count", ExactSpelling = true)]
public static unsafe extern void SetKeyboardFunctionalKeysCount(ConfigBuilder* self, uint keyboardFunctionalKeysCount);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_ime_file_name", ExactSpelling = true)]
public static unsafe extern void SetImeFileName(ConfigBuilder* self, byte* imeFileName, nuint imeFileNameSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_dig_product_id", ExactSpelling = true)]
public static unsafe extern void SetDigProductId(ConfigBuilder* self, byte* digProductId, nuint digProductIdSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_desktop_size", ExactSpelling = true)]
public static unsafe extern void SetDesktopSize(ConfigBuilder* self, ushort height, ushort width);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_performance_flags", ExactSpelling = true)]
public static unsafe extern void SetPerformanceFlags(ConfigBuilder* self, PerformanceFlags* performanceFlags);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_client_build", ExactSpelling = true)]
public static unsafe extern void SetClientBuild(ConfigBuilder* self, uint clientBuild);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_client_name", ExactSpelling = true)]
public static unsafe extern void SetClientName(ConfigBuilder* self, byte* clientName, nuint clientNameSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_client_dir", ExactSpelling = true)]
public static unsafe extern void SetClientDir(ConfigBuilder* self, byte* clientDir, nuint clientDirSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_no_server_pointer", ExactSpelling = true)]
public static unsafe extern void SetNoServerPointer(ConfigBuilder* self, [MarshalAs(UnmanagedType.U1)] bool noServerPointer);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_autologon", ExactSpelling = true)]
public static unsafe extern void SetAutologon(ConfigBuilder* self, [MarshalAs(UnmanagedType.U1)] bool autologon);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_set_pointer_software_rendering", ExactSpelling = true)]
public static unsafe extern void SetPointerSoftwareRendering(ConfigBuilder* self, [MarshalAs(UnmanagedType.U1)] bool pointerSoftwareRendering);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_build", ExactSpelling = true)]
public static unsafe extern ConnectorConfigFfiResultBoxConfigBoxIronRdpError Build(ConfigBuilder* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConfigBuilder_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(ConfigBuilder* self);
}

View file

@ -0,0 +1,41 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectionResult
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_io_channel_id", ExactSpelling = true)]
public static unsafe extern ushort GetIoChannelId(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_user_channel_id", ExactSpelling = true)]
public static unsafe extern ushort GetUserChannelId(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_static_channels", ExactSpelling = true)]
public static unsafe extern StaticChannelSet* GetStaticChannels(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_desktop_size", ExactSpelling = true)]
public static unsafe extern DesktopSize* GetDesktopSize(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_no_server_pointer", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool GetNoServerPointer(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_pointer_software_rendering", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool GetPointerSoftwareRendering(ConnectionResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(ConnectionResult* self);
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorConfigFfiResultBoxConfigBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal Config* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe Config* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultBoolBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal bool ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe bool Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultBoxOptionalUsizeBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal OptionalUsize* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe OptionalUsize* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultBoxStateBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal State* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe State* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultBoxWrittenBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal Written* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe Written* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultOptBoxPduHintBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal PduHint* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe PduHint* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct ConnectorFfiResultVoidBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultBoxCredsspProcessGeneratorBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal CredsspProcessGenerator* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe CredsspProcessGenerator* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultBoxCredsspSequenceBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal CredsspSequence* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe CredsspSequence* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultBoxCredsspSequenceInitResultBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal CredsspSequenceInitResult* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe CredsspSequenceInitResult* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultBoxTsRequestBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal TsRequest* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe TsRequest* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultBoxWrittenBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal Written* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe Written* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspFfiResultOptBoxTsRequestBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal TsRequest* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe TsRequest* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspNetworkFfiResultBoxClientStateBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal ClientState* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe ClientState* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal GeneratorState* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe GeneratorState* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspNetworkFfiResultBoxTsRequestBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal TsRequest* ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe TsRequest* Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspNetworkFfiResultVoidBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,27 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspProcessGenerator
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspProcessGenerator_start", ExactSpelling = true)]
public static unsafe extern CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError Start(CredsspProcessGenerator* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspProcessGenerator_resume", ExactSpelling = true)]
public static unsafe extern CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError Resume(CredsspProcessGenerator* self, byte* response, nuint responseSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspProcessGenerator_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(CredsspProcessGenerator* self);
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspSequence
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_next_pdu_hint", ExactSpelling = true)]
public static unsafe extern PduHint* NextPduHint(CredsspSequence* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_init", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultBoxCredsspSequenceInitResultBoxIronRdpError Init(ClientConnector* connector, byte* serverName, nuint serverNameSz, byte* serverPublicKey, nuint serverPublicKeySz, KerberosConfig* kerberoConfigs);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_decode_server_message", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultOptBoxTsRequestBoxIronRdpError DecodeServerMessage(CredsspSequence* self, byte* pdu, nuint pduSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_process_ts_request", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultBoxCredsspProcessGeneratorBoxIronRdpError ProcessTsRequest(CredsspSequence* self, TsRequest* tsRequest);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_handle_process_result", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultBoxWrittenBoxIronRdpError HandleProcessResult(CredsspSequence* self, ClientState* clientState, WriteBuf* buf);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequence_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(CredsspSequence* self);
}

View file

@ -0,0 +1,27 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct CredsspSequenceInitResult
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequenceInitResult_get_credssp_sequence", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultBoxCredsspSequenceBoxIronRdpError GetCredsspSequence(CredsspSequenceInitResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequenceInitResult_get_ts_request", ExactSpelling = true)]
public static unsafe extern CredsspFfiResultBoxTsRequestBoxIronRdpError GetTsRequest(CredsspSequenceInitResult* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "CredsspSequenceInitResult_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(CredsspSequenceInitResult* self);
}

View file

@ -0,0 +1,27 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct DesktopSize
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DesktopSize_get_width", ExactSpelling = true)]
public static unsafe extern ushort GetWidth(DesktopSize* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DesktopSize_get_height", ExactSpelling = true)]
public static unsafe extern ushort GetHeight(DesktopSize* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DesktopSize_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(DesktopSize* self);
}

View file

@ -0,0 +1,21 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct DrdynvcChannel
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DrdynvcChannel_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(DrdynvcChannel* self);
}

View file

@ -0,0 +1,35 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct GeneratorState
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GeneratorState_is_suspended", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsSuspended(GeneratorState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GeneratorState_is_completed", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsCompleted(GeneratorState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GeneratorState_get_network_request_if_suspended", ExactSpelling = true)]
public static unsafe extern NetworkRequest* GetNetworkRequestIfSuspended(GeneratorState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GeneratorState_get_client_state_if_completed", ExactSpelling = true)]
public static unsafe extern CredsspNetworkFfiResultBoxClientStateBoxIronRdpError GetClientStateIfCompleted(GeneratorState* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GeneratorState_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(GeneratorState* self);
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
/// <summary>
/// Stringified Picky error along with an error kind.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public partial struct IronRdpError
{
private const string NativeLib = "DevolutionsIronRdp";
/// <summary>
/// Returns the error as a string.
/// </summary>
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpError_to_display", ExactSpelling = true)]
public static unsafe extern void ToDisplay(IronRdpError* self, DiplomatWriteable* writeable);
/// <summary>
/// Returns the error kind.
/// </summary>
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpError_get_kind", ExactSpelling = true)]
public static unsafe extern IronRdpErrorKind GetKind(IronRdpError* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpError_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(IronRdpError* self);
}

View file

@ -0,0 +1,22 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
public enum IronRdpErrorKind
{
Generic = 0,
PduError = 1,
CredsspError = 2,
Consumed = 3,
IO = 4,
AccessDenied = 5,
}

View file

@ -0,0 +1,21 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct KerberosConfig
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "KerberosConfig_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(KerberosConfig* self);
}

View file

@ -0,0 +1,23 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
public enum KeyboardType
{
IbmPcXt = 0,
OlivettiIco = 1,
IbmPcAt = 2,
IbmEnhanced = 3,
Nokia1050 = 4,
Nokia9140 = 5,
Japanese = 6,
}

View file

@ -0,0 +1,30 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct NetworkRequest
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "NetworkRequest_get_data", ExactSpelling = true)]
public static unsafe extern VecU8* GetData(NetworkRequest* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "NetworkRequest_get_protocol", ExactSpelling = true)]
public static unsafe extern NetworkRequestProtocol GetProtocol(NetworkRequest* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "NetworkRequest_get_url", ExactSpelling = true)]
public static unsafe extern CredsspNetworkFfiResultVoidBoxIronRdpError GetUrl(NetworkRequest* self, DiplomatWriteable* writeable);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "NetworkRequest_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(NetworkRequest* self);
}

View file

@ -0,0 +1,20 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
public enum NetworkRequestProtocol
{
Tcp = 0,
Udp = 1,
Http = 2,
Https = 3,
}

View file

@ -0,0 +1,28 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct OptionalUsize
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OptionalUsize_is_some", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsSome(OptionalUsize* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OptionalUsize_get", ExactSpelling = true)]
public static unsafe extern UtilsFfiResultUsizeBoxIronRdpError Get(OptionalUsize* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OptionalUsize_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(OptionalUsize* self);
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct PduFfiResultVoidBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,24 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct PduHint
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduHint_find_size", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultBoxOptionalUsizeBoxIronRdpError FindSize(PduHint* self, byte* bytes, nuint bytesSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduHint_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(PduHint* self);
}

View file

@ -0,0 +1,30 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct PerformanceFlags
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PerformanceFlags_new_default", ExactSpelling = true)]
public static unsafe extern PerformanceFlags* NewDefault();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PerformanceFlags_new_empty", ExactSpelling = true)]
public static unsafe extern PerformanceFlags* NewEmpty();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PerformanceFlags_add_flag", ExactSpelling = true)]
public static unsafe extern void AddFlag(PerformanceFlags* self, PerformanceFlagsType flag);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PerformanceFlags_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(PerformanceFlags* self);
}

View file

@ -0,0 +1,26 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
public enum PerformanceFlagsType
{
DisableWallpaper = 0,
DisableFullWindowDrag = 1,
DisableMenuAnimations = 2,
DisableTheming = 3,
Reserved1 = 4,
DisableCursorShadow = 5,
DisableCursorSettings = 6,
EnableFontSmoothing = 7,
EnableDesktopComposition = 8,
Reserved2 = 9,
}

View file

@ -0,0 +1,28 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct State
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "State_get_name", ExactSpelling = true)]
public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError GetName(State* self, DiplomatWriteable* writeable);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "State_is_terminal", ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)]
public static unsafe extern bool IsTerminal(State* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "State_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(State* self);
}

View file

@ -0,0 +1,21 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct StaticChannelSet
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "StaticChannelSet_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(StaticChannelSet* self);
}

View file

@ -0,0 +1,21 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct TsRequest
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "TsRequest_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(TsRequest* self);
}

View file

@ -0,0 +1,46 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct UtilsFfiResultUsizeBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal nuint ok;
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe nuint Ok
{
get
{
return _inner.ok;
}
}
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,36 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct UtilsFfiResultVoidBoxIronRdpError
{
[StructLayout(LayoutKind.Explicit)]
private unsafe struct InnerUnion
{
[FieldOffset(0)]
internal IronRdpError* err;
}
private InnerUnion _inner;
[MarshalAs(UnmanagedType.U1)]
public bool isOk;
public unsafe IronRdpError* Err
{
get
{
return _inner.err;
}
}
}

View file

@ -0,0 +1,33 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct VecU8
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "VecU8_from_bytes", ExactSpelling = true)]
public static unsafe extern VecU8* FromBytes(byte* bytes, nuint bytesSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "VecU8_get_size", ExactSpelling = true)]
public static unsafe extern nuint GetSize(VecU8* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "VecU8_fill", ExactSpelling = true)]
public static unsafe extern UtilsFfiResultVoidBoxIronRdpError Fill(VecU8* self, byte* buffer, nuint bufferSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "VecU8_new_empty", ExactSpelling = true)]
public static unsafe extern VecU8* NewEmpty();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "VecU8_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(VecU8* self);
}

View file

@ -0,0 +1,30 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct WriteBuf
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "WriteBuf_new", ExactSpelling = true)]
public static unsafe extern WriteBuf* New();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "WriteBuf_clear", ExactSpelling = true)]
public static unsafe extern void Clear(WriteBuf* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "WriteBuf_read_into_buf", ExactSpelling = true)]
public static unsafe extern PduFfiResultVoidBoxIronRdpError ReadIntoBuf(WriteBuf* self, byte* buf, nuint bufSz);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "WriteBuf_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(WriteBuf* self);
}

View file

@ -0,0 +1,27 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
[StructLayout(LayoutKind.Sequential)]
public partial struct Written
{
private const string NativeLib = "DevolutionsIronRdp";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Written_get_written_type", ExactSpelling = true)]
public static unsafe extern WrittenType GetWrittenType(Written* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Written_get_size", ExactSpelling = true)]
public static unsafe extern OptionalUsize* GetSize(Written* self);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Written_destroy", ExactSpelling = true)]
public static unsafe extern void Destroy(Written* self);
}

View file

@ -0,0 +1,18 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp.Raw;
#nullable enable
public enum WrittenType
{
Size = 0,
Nothing = 1,
}

View file

@ -0,0 +1,122 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class State: IDisposable
{
private unsafe Raw.State* _inner;
public string Name
{
get
{
return GetName();
}
}
/// <summary>
/// Creates a managed <c>State</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe State(Raw.State* handle)
{
_inner = handle;
}
/// <exception cref="IronRdpException"></exception>
public void GetName(DiplomatWriteable writeable)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("State");
}
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.State.GetName(_inner, &writeable);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
/// <exception cref="IronRdpException"></exception>
public string GetName()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("State");
}
DiplomatWriteable writeable = new DiplomatWriteable();
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.State.GetName(_inner, &writeable);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
string retVal = writeable.ToUnicode();
writeable.Dispose();
return retVal;
}
}
public bool IsTerminal()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("State");
}
bool retVal = Raw.State.IsTerminal(_inner);
return retVal;
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.State* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.State.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~State()
{
Dispose();
}
}

View file

@ -0,0 +1,63 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class StaticChannelSet: IDisposable
{
private unsafe Raw.StaticChannelSet* _inner;
/// <summary>
/// Creates a managed <c>StaticChannelSet</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe StaticChannelSet(Raw.StaticChannelSet* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.StaticChannelSet* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.StaticChannelSet.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~StaticChannelSet()
{
Dispose();
}
}

View file

@ -0,0 +1,63 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class TsRequest: IDisposable
{
private unsafe Raw.TsRequest* _inner;
/// <summary>
/// Creates a managed <c>TsRequest</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe TsRequest(Raw.TsRequest* handle)
{
_inner = handle;
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.TsRequest* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.TsRequest.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~TsRequest()
{
Dispose();
}
}

View file

@ -0,0 +1,133 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class VecU8: IDisposable
{
private unsafe Raw.VecU8* _inner;
public nuint Size
{
get
{
return GetSize();
}
}
/// <summary>
/// Creates a managed <c>VecU8</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe VecU8(Raw.VecU8* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>VecU8</c> allocated on Rust side.
/// </returns>
public static VecU8 FromBytes(byte[] bytes)
{
unsafe
{
nuint bytesLength = (nuint)bytes.Length;
fixed (byte* bytesPtr = bytes)
{
Raw.VecU8* retVal = Raw.VecU8.FromBytes(bytesPtr, bytesLength);
return new VecU8(retVal);
}
}
}
public nuint GetSize()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("VecU8");
}
nuint retVal = Raw.VecU8.GetSize(_inner);
return retVal;
}
}
/// <exception cref="IronRdpException"></exception>
public void Fill(byte[] buffer)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("VecU8");
}
nuint bufferLength = (nuint)buffer.Length;
fixed (byte* bufferPtr = buffer)
{
Raw.UtilsFfiResultVoidBoxIronRdpError result = Raw.VecU8.Fill(_inner, bufferPtr, bufferLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
}
/// <returns>
/// A <c>VecU8</c> allocated on Rust side.
/// </returns>
public static VecU8 NewEmpty()
{
unsafe
{
Raw.VecU8* retVal = Raw.VecU8.NewEmpty();
return new VecU8(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.VecU8* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.VecU8.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~VecU8()
{
Dispose();
}
}

View file

@ -0,0 +1,108 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class WriteBuf: IDisposable
{
private unsafe Raw.WriteBuf* _inner;
/// <summary>
/// Creates a managed <c>WriteBuf</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe WriteBuf(Raw.WriteBuf* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>WriteBuf</c> allocated on Rust side.
/// </returns>
public static WriteBuf New()
{
unsafe
{
Raw.WriteBuf* retVal = Raw.WriteBuf.New();
return new WriteBuf(retVal);
}
}
public void Clear()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("WriteBuf");
}
Raw.WriteBuf.Clear(_inner);
}
}
/// <exception cref="IronRdpException"></exception>
public void ReadIntoBuf(byte[] buf)
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("WriteBuf");
}
nuint bufLength = (nuint)buf.Length;
fixed (byte* bufPtr = buf)
{
Raw.PduFfiResultVoidBoxIronRdpError result = Raw.WriteBuf.ReadIntoBuf(_inner, bufPtr, bufLength);
if (!result.isOk)
{
throw new IronRdpException(new IronRdpError(result.Err));
}
}
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.WriteBuf* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.WriteBuf.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~WriteBuf()
{
Dispose();
}
}

View file

@ -0,0 +1,111 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public partial class Written: IDisposable
{
private unsafe Raw.Written* _inner;
public OptionalUsize Size
{
get
{
return GetSize();
}
}
public WrittenType WrittenType
{
get
{
return GetWrittenType();
}
}
/// <summary>
/// Creates a managed <c>Written</c> from a raw handle.
/// </summary>
/// <remarks>
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
/// <br/>
/// This constructor assumes the raw struct is allocated on Rust side.
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
/// </remarks>
public unsafe Written(Raw.Written* handle)
{
_inner = handle;
}
/// <returns>
/// A <c>WrittenType</c> allocated on C# side.
/// </returns>
public WrittenType GetWrittenType()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("Written");
}
Raw.WrittenType retVal = Raw.Written.GetWrittenType(_inner);
return (WrittenType)retVal;
}
}
/// <returns>
/// A <c>OptionalUsize</c> allocated on Rust side.
/// </returns>
public OptionalUsize GetSize()
{
unsafe
{
if (_inner == null)
{
throw new ObjectDisposedException("Written");
}
Raw.OptionalUsize* retVal = Raw.Written.GetSize(_inner);
return new OptionalUsize(retVal);
}
}
/// <summary>
/// Returns the underlying raw handle.
/// </summary>
public unsafe Raw.Written* AsFFI()
{
return _inner;
}
/// <summary>
/// Destroys the underlying object immediately.
/// </summary>
public void Dispose()
{
unsafe
{
if (_inner == null)
{
return;
}
Raw.Written.Destroy(_inner);
_inner = null;
GC.SuppressFinalize(this);
}
}
~Written()
{
Dispose();
}
}

View file

@ -0,0 +1,18 @@
// <auto-generated/> by Diplomat
#pragma warning disable 0105
using System;
using System.Runtime.InteropServices;
using Devolutions.IronRdp.Diplomat;
#pragma warning restore 0105
namespace Devolutions.IronRdp;
#nullable enable
public enum WrittenType
{
Size = 0,
Nothing = 1,
}

View file

@ -0,0 +1,95 @@
using System.Runtime.InteropServices;
using Devolutions.IronRdp;
public class Framed<S> where S : Stream
{
private S stream;
private List<byte> buffer;
public Framed(S stream)
{
this.stream = stream;
this.buffer = new List<byte>();
}
public (S, List<byte>) GetInner()
{
return (this.stream, this.buffer);
}
/// <summary>
/// Returns a span that represents a portion of the underlying buffer without modifying it.
/// </summary>
/// <remarks>Memory safety: the Framed instance should not be modified (any read operations) while span is in use.</remarks>
/// <returns>A span that represents a portion of the underlying buffer.</returns>
public Span<byte> Peek()
{
return CollectionsMarshal.AsSpan(this.buffer);
}
/// <summary>
/// Reads from 0 to size bytes from the front of the buffer, and remove them from the buffer keeping the rest.
/// </summary>
/// <param name="size">The number of bytes to read.</param>
/// <returns>An array of bytes containing the read data.</returns>
public async Task<byte[]> ReadExact(nuint size)
{
while (true)
{
if (buffer.Count >= (int)size)
{
var res = this.buffer.Take((int)size).ToArray();
this.buffer = this.buffer.Skip((int)size).ToList();
return res;
}
var len = await this.Read();
if (len == 0)
{
throw new Exception("EOF");
}
}
}
async Task<int> Read()
{
var buffer = new byte[1024];
Memory<byte> memory = buffer;
var size = await this.stream.ReadAsync(memory);
this.buffer.AddRange(buffer.Take(size));
return size;
}
public async Task Write(byte[] data)
{
ReadOnlyMemory<byte> memory = data;
await this.stream.WriteAsync(memory);
}
/// <summary>
/// Reads data from the buffer based on the provided PduHint.
/// </summary>
/// <param name="pduHint">The PduHint object used to determine the size of the data to read.</param>
/// <returns>An asynchronous task that represents the operation. The task result contains the read data as a byte array.</returns>
public async Task<byte[]> ReadByHint(PduHint pduHint)
{
while (true)
{
var size = pduHint.FindSize(this.buffer.ToArray());
if (size.IsSome())
{
return await this.ReadExact(size.Get());
}
else
{
var len = await this.Read();
if (len == 0)
{
throw new Exception("EOF");
}
}
}
}
}

247
ffi/src/connector/config.rs Normal file
View file

@ -0,0 +1,247 @@
use ironrdp::pdu::rdp::client_info::PerformanceFlags;
use self::ffi::PerformanceFlagsType;
#[diplomat::bridge]
pub mod ffi {
use ironrdp::{
connector::{BitmapConfig, Credentials},
pdu::rdp::capability_sets::MajorPlatformType,
};
use crate::error::ffi::IronRdpError;
#[diplomat::opaque]
pub struct Config(pub ironrdp::connector::Config);
impl Config {
pub fn get_builder() -> Box<ConfigBuilder> {
Box::<ConfigBuilder>::default()
}
}
#[derive(Default)]
#[diplomat::opaque]
pub struct ConfigBuilder {
pub credentials: Option<Credentials>,
pub domain: Option<String>,
pub enable_tls: Option<bool>,
pub enable_credssp: Option<bool>,
pub keyboard_type: Option<ironrdp::pdu::gcc::KeyboardType>,
pub keyboard_subtype: Option<u32>,
pub keyboard_functional_keys_count: Option<u32>,
pub ime_file_name: Option<String>,
pub dig_product_id: Option<String>,
pub desktop_size: Option<ironrdp::connector::DesktopSize>,
pub bitmap: Option<BitmapConfig>,
pub client_build: Option<u32>,
pub client_name: Option<String>,
pub client_dir: Option<String>,
pub platform: Option<MajorPlatformType>,
pub no_server_pointer: Option<bool>,
pub autologon: Option<bool>,
pub pointer_software_rendering: Option<bool>,
pub performance_flags: Option<ironrdp::pdu::rdp::client_info::PerformanceFlags>,
}
#[diplomat::enum_convert(ironrdp::pdu::gcc::KeyboardType)]
pub enum KeyboardType {
IbmPcXt,
OlivettiIco,
IbmPcAt,
IbmEnhanced,
Nokia1050,
Nokia9140,
Japanese,
}
#[diplomat::opaque]
pub struct DesktopSize(pub ironrdp::connector::DesktopSize);
impl DesktopSize {
pub fn get_width(&self) -> u16 {
self.0.width
}
pub fn get_height(&self) -> u16 {
self.0.height
}
}
impl ConfigBuilder {
pub fn new() -> Box<Self> {
Box::<ConfigBuilder>::default()
}
pub fn with_username_and_password(&mut self, username: &str, password: &str) {
self.credentials = Some(Credentials::UsernamePassword {
username: username.to_owned(),
password: password.to_owned(),
});
}
pub fn set_domain(&mut self, domain: &str) {
self.domain = Some(domain.to_owned());
}
pub fn set_enable_tls(&mut self, enable_tls: bool) {
self.enable_tls = Some(enable_tls);
}
pub fn set_enable_credssp(&mut self, enable_credssp: bool) {
self.enable_credssp = Some(enable_credssp);
}
pub fn set_keyboard_type(&mut self, keyboard_type: KeyboardType) {
self.keyboard_type = Some(keyboard_type.into());
}
pub fn set_keyboard_subtype(&mut self, keyboard_subtype: u32) {
self.keyboard_subtype = Some(keyboard_subtype);
}
pub fn set_keyboard_functional_keys_count(&mut self, keyboard_functional_keys_count: u32) {
self.keyboard_functional_keys_count = Some(keyboard_functional_keys_count);
}
pub fn set_ime_file_name(&mut self, ime_file_name: &str) {
self.ime_file_name = Some(ime_file_name.to_owned());
}
pub fn set_dig_product_id(&mut self, dig_product_id: &str) {
self.dig_product_id = Some(dig_product_id.to_owned());
}
pub fn set_desktop_size(&mut self, height: u16, width: u16) {
self.desktop_size = Some(ironrdp::connector::DesktopSize { width, height });
}
pub fn set_performance_flags(&mut self, performance_flags: &PerformanceFlags) {
self.performance_flags = Some(performance_flags.0);
}
// TODO: set bitmap
pub fn set_client_build(&mut self, client_build: u32) {
self.client_build = Some(client_build);
}
pub fn set_client_name(&mut self, client_name: &str) {
self.client_name = Some(client_name.to_owned());
}
pub fn set_client_dir(&mut self, client_dir: &str) {
self.client_dir = Some(client_dir.to_owned());
}
pub fn set_no_server_pointer(&mut self, no_server_pointer: bool) {
self.no_server_pointer = Some(no_server_pointer);
}
pub fn set_autologon(&mut self, autologon: bool) {
self.autologon = Some(autologon);
}
pub fn set_pointer_software_rendering(&mut self, pointer_software_rendering: bool) {
self.pointer_software_rendering = Some(pointer_software_rendering);
}
pub fn build(&self) -> Result<Box<Config>, Box<IronRdpError>> {
let inner_config = ironrdp::connector::Config {
credentials: self.credentials.clone().ok_or("Credentials not set")?,
domain: self.domain.clone(),
enable_tls: self.enable_tls.unwrap_or(false),
enable_credssp: self.enable_credssp.unwrap_or(true),
keyboard_type: self
.keyboard_type
.unwrap_or(ironrdp::pdu::gcc::KeyboardType::IbmEnhanced),
keyboard_subtype: self.keyboard_subtype.unwrap_or(0),
keyboard_functional_keys_count: self.keyboard_functional_keys_count.unwrap_or(12),
ime_file_name: self.ime_file_name.clone().unwrap_or_default(),
dig_product_id: self.dig_product_id.clone().unwrap_or_default(),
desktop_size: self.desktop_size.ok_or("Desktop size not set")?,
bitmap: None,
client_build: self.client_build.unwrap_or(0),
client_name: self.client_name.clone().ok_or("Client name not set")?,
client_dir: self.client_dir.clone().ok_or("Client dir not set")?,
#[cfg(windows)]
platform: MajorPlatformType::WINDOWS,
#[cfg(target_os = "macos")]
platform: MajorPlatformType::MACINTOSH,
#[cfg(target_os = "ios")]
platform: MajorPlatformType::IOS,
#[cfg(target_os = "linux")]
platform: MajorPlatformType::UNIX,
#[cfg(target_os = "android")]
platform: MajorPlatformType::ANDROID,
#[cfg(target_os = "freebsd")]
platform: MajorPlatformType::UNIX,
#[cfg(target_os = "dragonfly")]
platform: MajorPlatformType::UNIX,
#[cfg(target_os = "openbsd")]
platform: MajorPlatformType::UNIX,
#[cfg(target_os = "netbsd")]
platform: MajorPlatformType::UNIX,
no_server_pointer: self.no_server_pointer.unwrap_or(false),
autologon: self.autologon.unwrap_or(false),
pointer_software_rendering: self.pointer_software_rendering.unwrap_or(false),
performance_flags: self.performance_flags.ok_or("Performance flag is missing")?,
};
Ok(Box::new(Config(inner_config)))
}
}
#[diplomat::opaque]
#[derive(Default)]
pub struct PerformanceFlags(pub ironrdp::pdu::rdp::client_info::PerformanceFlags);
pub enum PerformanceFlagsType {
DisableWallpaper,
DisableFullWindowDrag,
DisableMenuAnimations,
DisableTheming,
Reserved1,
DisableCursorShadow,
DisableCursorSettings,
EnableFontSmoothing,
EnableDesktopComposition,
Reserved2,
}
impl PerformanceFlags {
pub fn new_default() -> Box<Self> {
Box::<PerformanceFlags>::default()
}
pub fn new_empty() -> Box<Self> {
Box::new(PerformanceFlags(
ironrdp::pdu::rdp::client_info::PerformanceFlags::empty(),
))
}
pub fn add_flag(&mut self, flag: PerformanceFlagsType) {
self.0.insert(flag.into());
}
}
}
impl From<PerformanceFlagsType> for PerformanceFlags {
fn from(val: PerformanceFlagsType) -> Self {
match val {
PerformanceFlagsType::DisableCursorSettings => PerformanceFlags::DISABLE_CURSORSETTINGS,
PerformanceFlagsType::DisableCursorShadow => PerformanceFlags::DISABLE_CURSOR_SHADOW,
PerformanceFlagsType::DisableFullWindowDrag => PerformanceFlags::DISABLE_FULLWINDOWDRAG,
PerformanceFlagsType::DisableMenuAnimations => PerformanceFlags::DISABLE_MENUANIMATIONS,
PerformanceFlagsType::DisableTheming => PerformanceFlags::DISABLE_THEMING,
PerformanceFlagsType::DisableWallpaper => PerformanceFlags::DISABLE_WALLPAPER,
PerformanceFlagsType::EnableDesktopComposition => PerformanceFlags::ENABLE_DESKTOP_COMPOSITION,
PerformanceFlagsType::EnableFontSmoothing => PerformanceFlags::ENABLE_DESKTOP_COMPOSITION,
PerformanceFlagsType::Reserved1 => PerformanceFlags::RESERVED1,
PerformanceFlagsType::Reserved2 => PerformanceFlags::RESERVED2,
}
}
}

164
ffi/src/connector/mod.rs Normal file
View file

@ -0,0 +1,164 @@
pub mod config;
pub mod result;
pub mod state;
#[diplomat::bridge]
pub mod ffi {
use diplomat_runtime::DiplomatWriteable;
use ironrdp::connector::Sequence as _;
use std::fmt::Write;
use crate::{
error::{
ffi::{IronRdpError, IronRdpErrorKind},
ValueConsumedError,
},
pdu::ffi::WriteBuf,
};
use super::{config::ffi::Config, result::ffi::Written};
#[diplomat::opaque] // We must use Option here, as ClientConnector is not Clone and have functions that consume it
pub struct ClientConnector(pub Option<ironrdp::connector::ClientConnector>);
// Basic Impl for ClientConnector
impl ClientConnector {
pub fn new(config: &Config) -> Box<ClientConnector> {
Box::new(ClientConnector(Some(ironrdp::connector::ClientConnector::new(
config.0.clone(),
))))
}
/// Must use
pub fn with_server_addr(&mut self, server_addr: &str) -> Result<(), Box<IronRdpError>> {
let Some(connector) = self.0.take() else {
return Err(IronRdpErrorKind::Consumed.into());
};
let server_addr = server_addr.parse().map_err(|_| IronRdpErrorKind::Generic)?;
self.0 = Some(connector.with_server_addr(server_addr));
Ok(())
}
// FIXME: We need to create opaque for ironrdp::svc::StaticChannelSet
/// Must use
pub fn with_static_channel_rdp_snd(&mut self) -> Result<(), Box<IronRdpError>> {
let Some(connector) = self.0.take() else {
return Err(IronRdpErrorKind::Consumed.into());
};
self.0 = Some(connector.with_static_channel(ironrdp::rdpsnd::Rdpsnd::new()));
Ok(())
}
// FIXME: We need to create opaque for ironrdp::rdpdr::Rdpdr
/// Must use
pub fn with_static_channel_rdpdr(
&mut self,
computer_name: &str,
smart_card_device_id: u32,
) -> Result<(), Box<IronRdpError>> {
let Some(connector) = self.0.take() else {
return Err(ValueConsumedError::for_item("connector").into());
};
self.0 = Some(
connector.with_static_channel(
ironrdp::rdpdr::Rdpdr::new(Box::new(ironrdp::rdpdr::NoopRdpdrBackend {}), computer_name.to_owned())
.with_smartcard(smart_card_device_id),
),
);
Ok(())
}
pub fn should_perform_security_upgrade(&self) -> Result<bool, Box<IronRdpError>> {
let Some(connector) = self.0.as_ref() else {
return Err(ValueConsumedError::for_item("connector").into());
};
Ok(connector.should_perform_security_upgrade())
}
pub fn mark_security_upgrade_as_done(&mut self) -> Result<(), Box<IronRdpError>> {
let Some(connector) = self.0.as_mut() else {
return Err(ValueConsumedError::for_item("connector").into());
};
connector.mark_security_upgrade_as_done();
Ok(())
}
pub fn should_perform_credssp(&self) -> Result<bool, Box<IronRdpError>> {
let Some(connector) = self.0.as_ref() else {
return Err(ValueConsumedError::for_item("connector").into());
};
Ok(connector.should_perform_credssp())
}
pub fn mark_credssp_as_done(&mut self) -> Result<(), Box<IronRdpError>> {
let Some(connector) = self.0.as_mut() else {
return Err(ValueConsumedError::for_item("connector").into());
};
connector.mark_credssp_as_done();
Ok(())
}
pub fn step(&mut self, input: &[u8], write_buf: &mut WriteBuf) -> Result<Box<Written>, Box<IronRdpError>> {
let Some(connector) = self.0.as_mut() else {
return Err(ValueConsumedError::for_item("connector").into());
};
let written = connector.step(input, &mut write_buf.0)?;
Ok(Box::new(Written(written)))
}
pub fn step_no_input(&mut self, write_buf: &mut WriteBuf) -> Result<Box<Written>, Box<IronRdpError>> {
let Some(connector) = self.0.as_mut() else {
return Err(ValueConsumedError::for_item("connector").into());
};
let written = connector.step_no_input(&mut write_buf.0)?;
Ok(Box::new(Written(written)))
}
}
#[diplomat::opaque]
pub struct PduHint<'a>(pub &'a dyn ironrdp::pdu::PduHint);
impl<'a> PduHint<'a> {
pub fn find_size(&'a self, bytes: &[u8]) -> Result<Box<crate::utils::ffi::OptionalUsize>, Box<IronRdpError>> {
let pdu_hint = self.0;
let size = pdu_hint.find_size(bytes)?;
Ok(Box::new(crate::utils::ffi::OptionalUsize(size)))
}
}
#[diplomat::opaque]
pub struct State<'a>(pub &'a dyn ironrdp::connector::State);
impl<'a> State<'a> {
pub fn get_name(&'a self, writeable: &'a mut DiplomatWriteable) -> Result<(), Box<IronRdpError>> {
let name = self.0.name();
write!(writeable, "{}", name)?;
Ok(())
}
pub fn is_terminal(&'a self) -> bool {
self.0.is_terminal()
}
}
impl ClientConnector {
pub fn next_pdu_hint(&self) -> Result<Option<Box<PduHint<'_>>>, Box<IronRdpError>> {
let Some(connector) = self.0.as_ref() else {
return Err(ValueConsumedError::for_item("connector").into());
};
Ok(connector.next_pdu_hint().map(PduHint).map(Box::new))
}
pub fn state(&self) -> Result<Box<State<'_>>, Box<IronRdpError>> {
let Some(connector) = self.0.as_ref() else {
return Err(ValueConsumedError::for_item("connector").into());
};
Ok(Box::new(State(connector.state())))
}
}
}

View file

@ -0,0 +1,57 @@
#[diplomat::bridge]
pub mod ffi {
use crate::{connector::config::ffi::DesktopSize, utils::ffi::OptionalUsize};
#[diplomat::opaque]
pub struct Written(pub ironrdp::connector::Written);
pub enum WrittenType {
Size,
Nothing,
}
impl Written {
pub fn get_written_type(&self) -> WrittenType {
match &self.0 {
ironrdp::connector::Written::Size(_) => WrittenType::Size,
ironrdp::connector::Written::Nothing => WrittenType::Nothing,
}
}
pub fn get_size(&self) -> Box<OptionalUsize> {
match &self.0 {
ironrdp::connector::Written::Size(size) => Box::new(OptionalUsize(Some(size.get()))),
ironrdp::connector::Written::Nothing => Box::new(OptionalUsize(None)),
}
}
}
#[diplomat::opaque]
pub struct ConnectionResult(pub ironrdp::connector::ConnectionResult);
impl ConnectionResult {
pub fn get_io_channel_id(&self) -> u16 {
self.0.io_channel_id
}
pub fn get_user_channel_id(&self) -> u16 {
self.0.user_channel_id
}
pub fn get_static_channels(&self) -> Box<crate::svc::ffi::StaticChannelSet<'_>> {
Box::new(crate::svc::ffi::StaticChannelSet(&self.0.static_channels))
}
pub fn get_desktop_size(&self) -> Box<DesktopSize> {
Box::new(DesktopSize(self.0.desktop_size))
}
pub fn get_no_server_pointer(&self) -> bool {
self.0.no_server_pointer
}
pub fn get_pointer_software_rendering(&self) -> bool {
self.0.pointer_software_rendering
}
}
}

View file

@ -0,0 +1,6 @@
#[diplomat::bridge]
pub mod ffi {
#[diplomat::opaque]
pub struct ClientConnectorState(pub ironrdp::connector::ClientConnectorState);
}

101
ffi/src/credssp/mod.rs Normal file
View file

@ -0,0 +1,101 @@
#![allow(clippy::needless_lifetimes)] // Diplomat requires lifetimes
pub mod network;
#[diplomat::bridge]
pub mod ffi {
use crate::{
connector::{
ffi::{ClientConnector, PduHint},
result::ffi::Written,
},
error::{ffi::IronRdpError, ValueConsumedError},
pdu::ffi::WriteBuf,
};
use super::network::ffi::{ClientState, CredsspProcessGenerator};
#[diplomat::opaque]
pub struct KerberosConfig(pub ironrdp::connector::credssp::KerberosConfig);
#[diplomat::opaque]
pub struct CredsspSequence(pub ironrdp::connector::credssp::CredsspSequence);
#[diplomat::opaque]
pub struct TsRequest(pub sspi::credssp::TsRequest);
#[diplomat::opaque]
pub struct CredsspSequenceInitResult {
pub credssp_sequence: Option<Box<CredsspSequence>>,
pub ts_request: Option<Box<TsRequest>>,
}
impl CredsspSequenceInitResult {
pub fn get_credssp_sequence(&mut self) -> Result<Box<CredsspSequence>, Box<IronRdpError>> {
let Some(credssp_sequence) = self.credssp_sequence.take() else {
return Err(ValueConsumedError::for_item("credssp_sequence").into());
};
Ok(credssp_sequence)
}
pub fn get_ts_request(&mut self) -> Result<Box<TsRequest>, Box<IronRdpError>> {
let Some(ts_request) = self.ts_request.take() else {
return Err(ValueConsumedError::for_item("ts_request").into());
};
Ok(ts_request)
}
}
impl CredsspSequence {
pub fn next_pdu_hint<'a>(&'a self) -> Option<Box<PduHint<'a>>> {
self.0.next_pdu_hint().map(|hint| Box::new(PduHint(hint)))
}
pub fn init(
connector: &ClientConnector,
server_name: &str,
server_public_key: &[u8],
kerbero_configs: Option<&KerberosConfig>,
) -> Result<Box<CredsspSequenceInitResult>, Box<IronRdpError>> {
let Some(connector) = connector.0.as_ref() else {
return Err(ValueConsumedError::for_item("connector").into());
};
let (credssp_sequence, ts_request) = ironrdp::connector::credssp::CredsspSequence::init(
connector,
server_name.into(),
server_public_key.to_owned(),
kerbero_configs.map(|config| config.0.clone()),
)?;
Ok(Box::new(CredsspSequenceInitResult {
credssp_sequence: Some(Box::new(CredsspSequence(credssp_sequence))),
ts_request: Some(Box::new(TsRequest(ts_request))),
}))
}
pub fn decode_server_message(&mut self, pdu: &[u8]) -> Result<Option<Box<TsRequest>>, Box<IronRdpError>> {
let ts_request = self.0.decode_server_message(pdu)?;
Ok(ts_request.map(|ts_request| Box::new(TsRequest(ts_request))))
}
pub fn process_ts_request<'a>(
&'a mut self,
ts_request: &TsRequest,
) -> Result<Box<CredsspProcessGenerator<'a>>, Box<IronRdpError>> {
let ts_request = ts_request.0.clone();
let generator = self.0.process_ts_request(ts_request);
Ok(Box::new(CredsspProcessGenerator(generator)))
}
pub fn handle_process_result(
&mut self,
client_state: &ClientState,
buf: &mut WriteBuf,
) -> Result<Box<Written>, Box<IronRdpError>> {
let client_state = client_state.0.clone();
let written = self.0.handle_process_result(client_state, &mut buf.0)?;
Ok(Box::new(Written(written)))
}
}
}

103
ffi/src/credssp/network.rs Normal file
View file

@ -0,0 +1,103 @@
#![allow(single_use_lifetimes)] // Diplomat requires lifetimes
pub type CredsspGeneratorState =
sspi::generator::GeneratorState<sspi::generator::NetworkRequest, sspi::Result<sspi::credssp::ClientState>>;
#[diplomat::bridge]
pub mod ffi {
use crate::{credssp::ffi::TsRequest, error::ffi::IronRdpError, utils::ffi::VecU8};
use super::CredsspGeneratorState;
#[diplomat::opaque]
pub struct CredsspProcessGenerator<'a>(pub ironrdp::connector::credssp::CredsspProcessGenerator<'a>);
#[diplomat::opaque]
pub struct GeneratorState(pub CredsspGeneratorState);
#[diplomat::opaque]
pub struct NetworkRequest<'a>(pub &'a sspi::generator::NetworkRequest);
#[diplomat::enum_convert(sspi::network_client::NetworkProtocol)]
pub enum NetworkRequestProtocol {
Tcp,
Udp,
Http,
Https,
}
#[diplomat::opaque]
pub struct ClientState(pub sspi::credssp::ClientState);
impl<'a> CredsspProcessGenerator<'a> {
pub fn start(&mut self) -> Result<Box<GeneratorState>, Box<IronRdpError>> {
let state = self.0.start();
Ok(Box::new(GeneratorState(state)))
}
pub fn resume(&mut self, response: &[u8]) -> Result<Box<GeneratorState>, Box<IronRdpError>> {
let state = self.0.resume(Ok(response.to_owned()));
Ok(Box::new(GeneratorState(state)))
}
}
impl GeneratorState {
pub fn is_suspended(&self) -> bool {
matches!(self.0, CredsspGeneratorState::Suspended(_))
}
pub fn is_completed(&self) -> bool {
matches!(self.0, CredsspGeneratorState::Completed(_))
}
pub fn get_network_request_if_suspended<'a>(&'a self) -> Option<Box<NetworkRequest<'a>>> {
match &self.0 {
CredsspGeneratorState::Suspended(request) => Some(Box::new(NetworkRequest(request))),
_ => None,
}
}
pub fn get_client_state_if_completed(&self) -> Result<Box<ClientState>, Box<IronRdpError>> {
match &self.0 {
CredsspGeneratorState::Completed(Ok(res)) => Ok(Box::new(ClientState(res.clone()))),
CredsspGeneratorState::Completed(Err(e)) => Err(e.to_owned().into()),
_ => Err("Generator is not completed".into()),
}
}
}
impl ClientState {
pub fn is_reply_needed(&self) -> bool {
matches!(self.0, sspi::credssp::ClientState::ReplyNeeded(_))
}
pub fn is_final_message(&self) -> bool {
matches!(self.0, sspi::credssp::ClientState::FinalMessage(_))
}
pub fn get_ts_request(&self) -> Result<Box<TsRequest>, Box<IronRdpError>> {
match &self.0 {
sspi::credssp::ClientState::ReplyNeeded(ts_request) => Ok(Box::new(TsRequest(ts_request.clone()))),
sspi::credssp::ClientState::FinalMessage(ts_request) => Ok(Box::new(TsRequest(ts_request.clone()))),
}
}
}
impl<'a> NetworkRequest<'a> {
pub fn get_data(&self) -> Box<VecU8> {
Box::new(VecU8(self.0.data.clone()))
}
pub fn get_protocol(&self) -> NetworkRequestProtocol {
self.0.protocol.into()
}
pub fn get_url(&self, writeable: &mut diplomat_runtime::DiplomatWriteable) -> Result<(), Box<IronRdpError>> {
use std::fmt::Write;
let url: &str = self.0.url.as_ref();
write!(writeable, "{}", url)?;
Ok(())
}
}
}

6
ffi/src/dvc.rs Normal file
View file

@ -0,0 +1,6 @@
#[diplomat::bridge]
pub mod ffi {
#[diplomat::opaque]
pub struct DrdynvcChannel(pub ironrdp::dvc::DrdynvcClient);
}

138
ffi/src/error.rs Normal file
View file

@ -0,0 +1,138 @@
#![allow(clippy::return_self_not_must_use)]
use std::fmt::Display;
use ironrdp::connector::ConnectorError;
use self::ffi::IronRdpErrorKind;
impl From<ConnectorError> for IronRdpErrorKind {
fn from(val: ConnectorError) -> Self {
match val.kind {
ironrdp::connector::ConnectorErrorKind::Pdu(_) => IronRdpErrorKind::PduError,
ironrdp::connector::ConnectorErrorKind::Credssp(_) => IronRdpErrorKind::CredsspError,
ironrdp::connector::ConnectorErrorKind::AccessDenied => IronRdpErrorKind::AccessDenied,
_ => IronRdpErrorKind::Generic,
}
}
}
impl From<&str> for IronRdpErrorKind {
fn from(_val: &str) -> Self {
IronRdpErrorKind::Generic
}
}
impl From<sspi::Error> for IronRdpErrorKind {
fn from(_val: sspi::Error) -> Self {
IronRdpErrorKind::CredsspError
}
}
impl From<ironrdp::pdu::PduError> for IronRdpErrorKind {
fn from(_val: ironrdp::pdu::PduError) -> Self {
IronRdpErrorKind::PduError
}
}
impl From<std::io::Error> for IronRdpErrorKind {
fn from(_: std::io::Error) -> Self {
IronRdpErrorKind::IO
}
}
impl From<std::fmt::Error> for IronRdpErrorKind {
fn from(_val: std::fmt::Error) -> Self {
IronRdpErrorKind::Generic
}
}
impl<T> From<T> for Box<ffi::IronRdpError>
where
T: Into<IronRdpErrorKind> + ToString,
{
fn from(value: T) -> Self {
let repr = value.to_string();
let kind = value.into();
Box::new(ffi::IronRdpError(IronRdpErrorInner { repr, kind }))
}
}
struct IronRdpErrorInner {
repr: String,
kind: IronRdpErrorKind,
}
#[diplomat::bridge]
pub mod ffi {
use diplomat_runtime::DiplomatWriteable;
use std::fmt::Write as _;
#[derive(Debug, Clone, Copy, thiserror::Error)]
pub enum IronRdpErrorKind {
#[error("Generic error")]
Generic,
#[error("PDU error")]
PduError,
#[error("CredSSP error")]
CredsspError,
#[error("Value is consumed")]
Consumed,
#[error("IO error")]
IO,
#[error("Access denied")]
AccessDenied,
}
/// Stringified Picky error along with an error kind.
#[diplomat::opaque]
pub struct IronRdpError(pub(super) super::IronRdpErrorInner);
impl IronRdpError {
/// Returns the error as a string.
pub fn to_display(&self, writeable: &mut DiplomatWriteable) {
let _ = write!(writeable, "{}", self.0.repr);
writeable.flush();
}
/// Returns the error kind.
pub fn get_kind(&self) -> IronRdpErrorKind {
self.0.kind
}
}
}
#[derive(Debug)]
pub struct ValueConsumedError {
item: String,
reason: Option<String>,
}
impl ValueConsumedError {
pub fn for_item(item: &str) -> ValueConsumedError {
ValueConsumedError {
item: item.to_owned(),
reason: None,
}
}
pub fn reason(mut self, reason: &str) -> ValueConsumedError {
self.reason = Some(reason.to_owned());
self
}
}
impl Display for ValueConsumedError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(reason) = &self.reason {
write!(f, "{}: {}", self.item, reason)
} else {
write!(f, "{}: is consumed or never constructed", self.item)
}
}
}
impl From<ValueConsumedError> for IronRdpErrorKind {
fn from(_val: ValueConsumedError) -> Self {
IronRdpErrorKind::Consumed
}
}

Some files were not shown because too many files have changed in this diff Show more