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

This commit is contained in:
irvingouj @ Devolutions
2024-04-05 15:11:32 +00:00
committed by GitHub
parent ba3796f738
commit 3bcf51306d
107 changed files with 7058 additions and 2 deletions
+8
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
Generated
+153 -2
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"
+1
View File
@@ -2,6 +2,7 @@
members = [
"crates/*",
"xtask",
"ffi",
]
resolver = "2"
+27
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
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() {}
}
+10
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_"
@@ -0,0 +1,3 @@
obj
bin
.vs
@@ -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>
@@ -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;
}
}
}
@@ -0,0 +1,2 @@
obj
bin
@@ -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>
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
}

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