diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index a38846d2b..26d5ae8a0 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -19,7 +19,7 @@ doctest = false [dependencies] diplomat = "0.7.0" diplomat-runtime = "0.7.0" -ironrdp = { workspace = true, features = ["connector", "dvc", "svc","rdpdr","rdpsnd"] } +ironrdp = { workspace = true, features = ["connector", "dvc", "svc","rdpdr","rdpsnd","graphics","input"] } sspi = { workspace = true, features = ["network_client"] } thiserror.workspace = true diff --git a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/.gitignore b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/.gitignore index 501bb1289..12100f6a1 100644 --- a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/.gitignore +++ b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/.gitignore @@ -1,3 +1,4 @@ obj bin -.vs \ No newline at end of file +.vs +output.bmp \ No newline at end of file diff --git a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Devolutions.IronRdp.ConnectExample.csproj b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Devolutions.IronRdp.ConnectExample.csproj index 2e1eeb1b9..166fc7428 100644 --- a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Devolutions.IronRdp.ConnectExample.csproj +++ b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Devolutions.IronRdp.ConnectExample.csproj @@ -10,5 +10,9 @@ - + + + + + diff --git a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Program.cs b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Program.cs index d09ee3625..7e9a7f855 100644 --- a/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Program.cs +++ b/ffi/dotnet/Devolutions.IronRdp.ConnectExample/Program.cs @@ -1,6 +1,5 @@ -using System.Net; -using System.Net.Security; -using System.Net.Sockets; +using System.Drawing; +using System.Drawing.Imaging; namespace Devolutions.IronRdp.ConnectExample { @@ -10,9 +9,9 @@ static async Task Main(string[] args) { var arguments = ParseArguments(args); - if (arguments == null) + if (arguments == null) { - return; + return; } var serverName = arguments["--serverName"]; @@ -21,15 +20,95 @@ static async Task Main(string[] args) var domain = arguments["--domain"]; try { - await Connect(serverName, username, password, domain); + var (res, framed) = await Connection.Connect(buildConfig(serverName, username, password, domain, 1980, 1080), serverName); + var decodedImage = DecodedImage.New(PixelFormat.RgbA32, res.GetDesktopSize().GetWidth(), res.GetDesktopSize().GetHeight()); + var activeState = ActiveStage.New(res); + var keepLooping = true; + while (keepLooping) + { + var readPduTask = framed.ReadPdu(); + Action? action = null; + byte[]? payload = null; + if (readPduTask == await Task.WhenAny(readPduTask, Task.Delay(1000))) + { + var pduReadTask = await readPduTask; + action = pduReadTask.Item1; + payload = pduReadTask.Item2; + Console.WriteLine($"Action: {action}"); + } + else + { + Console.WriteLine("Timeout"); + break; + } + var outputIterator = activeState.Process(decodedImage, action, payload); + + while (!outputIterator.IsEmpty()) + { + var output = outputIterator.Next()!; // outputIterator.Next() is not null since outputIterator.IsEmpty() is false + Console.WriteLine($"Output type: {output.GetType()}"); + if (output.GetType() == ActiveStageOutputType.Terminate) + { + Console.WriteLine("Connection terminated."); + keepLooping = false; + } + + if (output.GetType() == ActiveStageOutputType.ResponseFrame) + { + var responseFrame = output.GetResponseFrame()!; + byte[] responseFrameBytes = new byte[responseFrame.GetSize()]; + responseFrame.Fill(responseFrameBytes); + await framed.Write(responseFrameBytes); + } + } + } + + saveImage(decodedImage, "output.png"); + } - catch (Exception e) + catch (Exception e) { Console.WriteLine($"An error occurred: {e.Message}"); } } - static Dictionary ParseArguments(string[] args) + private static void saveImage(DecodedImage decodedImage, string v) + { + int width = decodedImage.GetWidth(); + int height = decodedImage.GetHeight(); + var data = decodedImage.GetData(); + + var bytes = new byte[data.GetSize()]; + data.Fill(bytes); + for (int i = 0; i < bytes.Length; i += 4) + { + byte temp = bytes[i]; // Store the original Blue value + bytes[i] = bytes[i + 2]; // Move Red to Blue's position + bytes[i + 2] = temp; // Move original Blue to Red's position + // Green (bytes[i+1]) and Alpha (bytes[i+3]) remain unchanged + } + #if WINDOWS // Bitmap is only available on Windows + using (var bmp = new Bitmap(width, height)) + { + // Lock the bits of the bitmap. + var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), + ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + // Get the address of the first line. + IntPtr ptr = bmpData.Scan0; + // Copy the RGBA values back to the bitmap + System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, bytes.Length); + // Unlock the bits. + bmp.UnlockBits(bmpData); + + // Save the bitmap to the specified output path + bmp.Save("./output.bmp", ImageFormat.Bmp); + } + #endif + + } + + static Dictionary? ParseArguments(string[] args) { if (args.Length == 0 || Array.Exists(args, arg => arg == "--help")) { @@ -38,7 +117,7 @@ static Dictionary ParseArguments(string[] args) } var arguments = new Dictionary(); - string lastKey = null; + string? lastKey = null; foreach (var arg in args) { if (arg.StartsWith("--")) @@ -97,64 +176,15 @@ static void PrintHelp() 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(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)> securityUpgrade(string servername, Framed framed, ClientConnector connector) - { - byte[] serverPublicKey; - Framed framedSsl; - var (streamRequireUpgrade, _) = framed.GetInner(); - var promise = new TaskCompletionSource(); - 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); - connector.MarkSecurityUpgradeAsDone(); - - return (serverPublicKey, framedSsl); - } - - private static async Task connectBegin(Framed 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) + private static Config buildConfig(string servername, string username, string password, string domain, int width, int height) { ConfigBuilder configBuilder = ConfigBuilder.New(); - configBuilder.WithUsernameAndPasswrord(username, password); + configBuilder.WithUsernameAndPassword(username, password); configBuilder.SetDomain(domain); - configBuilder.SetDesktopSize(800, 600); + configBuilder.SetDesktopSize((ushort)height, (ushort)width); configBuilder.SetClientName("IronRdp"); configBuilder.SetClientDir("C:\\"); configBuilder.SetPerformanceFlags(PerformanceFlags.NewDefault()); @@ -162,157 +192,5 @@ private static Config buildConfig(string servername, string username, string pas return configBuilder.Build(); } - private static async Task ConnectFinalize(string servername, ClientConnector connector, byte[] serverpubkey, Framed 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 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 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(ClientConnector connector, WriteBuf buf, Framed 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 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; - } - } -} - - +} \ No newline at end of file diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/Action.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/Action.cs new file mode 100644 index 000000000..d83abd39e --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/Action.cs @@ -0,0 +1,63 @@ +// 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 Action: IDisposable +{ + private unsafe Raw.Action* _inner; + + /// + /// Creates a managed Action from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe Action(Raw.Action* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.Action* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.Action.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~Action() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStage.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStage.cs new file mode 100644 index 000000000..ed32efa1c --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStage.cs @@ -0,0 +1,125 @@ +// 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 ActiveStage: IDisposable +{ + private unsafe Raw.ActiveStage* _inner; + + /// + /// Creates a managed ActiveStage from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ActiveStage(Raw.ActiveStage* handle) + { + _inner = handle; + } + + /// + /// + /// A ActiveStage allocated on Rust side. + /// + public static ActiveStage New(ConnectionResult connectionResult) + { + unsafe + { + Raw.ConnectionResult* connectionResultRaw; + connectionResultRaw = connectionResult.AsFFI(); + if (connectionResultRaw == null) + { + throw new ObjectDisposedException("ConnectionResult"); + } + Raw.SessionFfiResultBoxActiveStageBoxIronRdpError result = Raw.ActiveStage.New(connectionResultRaw); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ActiveStage* retVal = result.Ok; + return new ActiveStage(retVal); + } + } + + /// + /// + /// A ActiveStageOutputIterator allocated on Rust side. + /// + public ActiveStageOutputIterator Process(DecodedImage image, Action action, byte[] payload) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStage"); + } + nuint payloadLength = (nuint)payload.Length; + Raw.DecodedImage* imageRaw; + imageRaw = image.AsFFI(); + if (imageRaw == null) + { + throw new ObjectDisposedException("DecodedImage"); + } + Raw.Action* actionRaw; + actionRaw = action.AsFFI(); + if (actionRaw == null) + { + throw new ObjectDisposedException("Action"); + } + fixed (byte* payloadPtr = payload) + { + Raw.SessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError result = Raw.ActiveStage.Process(_inner, imageRaw, actionRaw, payloadPtr, payloadLength); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ActiveStageOutputIterator* retVal = result.Ok; + return new ActiveStageOutputIterator(retVal); + } + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ActiveStage* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ActiveStage.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ActiveStage() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutput.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutput.cs new file mode 100644 index 000000000..4bc7022b3 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutput.cs @@ -0,0 +1,267 @@ +// 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 ActiveStageOutput: IDisposable +{ + private unsafe Raw.ActiveStageOutput* _inner; + + public ConnectionActivationSequence DeactivateAll + { + get + { + return GetDeactivateAll(); + } + } + + public InclusiveRectangle GraphicsUpdate + { + get + { + return GetGraphicsUpdate(); + } + } + + public DecodedPointer PointerBitmap + { + get + { + return GetPointerBitmap(); + } + } + + public Position PointerPosition + { + get + { + return GetPointerPosition(); + } + } + + public BytesSlice ResponseFrame + { + get + { + return GetResponseFrame(); + } + } + + public GracefulDisconnectReason Terminate + { + get + { + return GetTerminate(); + } + } + + public ActiveStageOutputType Type + { + get + { + return GetType(); + } + } + + /// + /// Creates a managed ActiveStageOutput from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ActiveStageOutput(Raw.ActiveStageOutput* handle) + { + _inner = handle; + } + + /// + /// A ActiveStageOutputType allocated on C# side. + /// + public ActiveStageOutputType GetType() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.ActiveStageOutputType retVal = Raw.ActiveStageOutput.GetType(_inner); + return (ActiveStageOutputType)retVal; + } + } + + /// + /// + /// A BytesSlice allocated on Rust side. + /// + public BytesSlice GetResponseFrame() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultBoxBytesSliceBoxIronRdpError result = Raw.ActiveStageOutput.GetResponseFrame(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.BytesSlice* retVal = result.Ok; + return new BytesSlice(retVal); + } + } + + /// + /// + /// A InclusiveRectangle allocated on Rust side. + /// + public InclusiveRectangle GetGraphicsUpdate() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultBoxInclusiveRectangleBoxIronRdpError result = Raw.ActiveStageOutput.GetGraphicsUpdate(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.InclusiveRectangle* retVal = result.Ok; + return new InclusiveRectangle(retVal); + } + } + + /// + /// + /// A Position allocated on C# side. + /// + public Position GetPointerPosition() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultPositionBoxIronRdpError result = Raw.ActiveStageOutput.GetPointerPosition(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.Position retVal = result.Ok; + return new Position(retVal); + } + } + + /// + /// + /// A DecodedPointer allocated on Rust side. + /// + public DecodedPointer GetPointerBitmap() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultBoxDecodedPointerBoxIronRdpError result = Raw.ActiveStageOutput.GetPointerBitmap(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.DecodedPointer* retVal = result.Ok; + return new DecodedPointer(retVal); + } + } + + /// + /// + /// A GracefulDisconnectReason allocated on Rust side. + /// + public GracefulDisconnectReason GetTerminate() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError result = Raw.ActiveStageOutput.GetTerminate(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.GracefulDisconnectReason* retVal = result.Ok; + return new GracefulDisconnectReason(retVal); + } + } + + /// + /// + /// A ConnectionActivationSequence allocated on Rust side. + /// + public ConnectionActivationSequence GetDeactivateAll() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutput"); + } + Raw.SessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError result = Raw.ActiveStageOutput.GetDeactivateAll(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ConnectionActivationSequence* retVal = result.Ok; + return new ConnectionActivationSequence(retVal); + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ActiveStageOutput* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ActiveStageOutput.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ActiveStageOutput() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputIterator.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputIterator.cs new file mode 100644 index 000000000..b36097c6e --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputIterator.cs @@ -0,0 +1,109 @@ +// 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 ActiveStageOutputIterator: IDisposable +{ + private unsafe Raw.ActiveStageOutputIterator* _inner; + + /// + /// Creates a managed ActiveStageOutputIterator from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ActiveStageOutputIterator(Raw.ActiveStageOutputIterator* handle) + { + _inner = handle; + } + + public nuint Len() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutputIterator"); + } + nuint retVal = Raw.ActiveStageOutputIterator.Len(_inner); + return retVal; + } + } + + public bool IsEmpty() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutputIterator"); + } + bool retVal = Raw.ActiveStageOutputIterator.IsEmpty(_inner); + return retVal; + } + } + + /// + /// A ActiveStageOutput allocated on Rust side. + /// + public ActiveStageOutput? Next() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ActiveStageOutputIterator"); + } + Raw.ActiveStageOutput* retVal = Raw.ActiveStageOutputIterator.Next(_inner); + if (retVal == null) + { + return null; + } + return new ActiveStageOutput(retVal); + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ActiveStageOutputIterator* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ActiveStageOutputIterator.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ActiveStageOutputIterator() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputType.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputType.cs new file mode 100644 index 000000000..e4763bd9e --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ActiveStageOutputType.cs @@ -0,0 +1,24 @@ +// 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 ActiveStageOutputType +{ + ResponseFrame = 0, + GraphicsUpdate = 1, + PointerDefault = 2, + PointerHidden = 3, + PointerPosition = 4, + PointerBitmap = 5, + Terminate = 6, + DeactivateAll = 7, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/BytesSlice.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/BytesSlice.cs new file mode 100644 index 000000000..a3f27f5af --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/BytesSlice.cs @@ -0,0 +1,105 @@ +// 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 BytesSlice: IDisposable +{ + private unsafe Raw.BytesSlice* _inner; + + public nuint Size + { + get + { + return GetSize(); + } + } + + /// + /// Creates a managed BytesSlice from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe BytesSlice(Raw.BytesSlice* handle) + { + _inner = handle; + } + + public nuint GetSize() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("BytesSlice"); + } + nuint retVal = Raw.BytesSlice.GetSize(_inner); + return retVal; + } + } + + /// + public void Fill(byte[] buffer) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("BytesSlice"); + } + nuint bufferLength = (nuint)buffer.Length; + fixed (byte* bufferPtr = buffer) + { + Raw.UtilsFfiResultVoidBoxIronRdpError result = Raw.BytesSlice.Fill(_inner, bufferPtr, bufferLength); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + } + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.BytesSlice* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.BytesSlice.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~BytesSlice() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ChannelConnectionSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ChannelConnectionSequence.cs new file mode 100644 index 000000000..19231a2c1 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ChannelConnectionSequence.cs @@ -0,0 +1,63 @@ +// 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 ChannelConnectionSequence: IDisposable +{ + private unsafe Raw.ChannelConnectionSequence* _inner; + + /// + /// Creates a managed ChannelConnectionSequence from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ChannelConnectionSequence(Raw.ChannelConnectionSequence* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ChannelConnectionSequence* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ChannelConnectionSequence.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ChannelConnectionSequence() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnector.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnector.cs index b87c0fce1..bcb08f4c0 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnector.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnector.cs @@ -15,6 +15,14 @@ public partial class ClientConnector: IDisposable { private unsafe Raw.ClientConnector* _inner; + public DynState DynState + { + get + { + return GetDynState(); + } + } + /// /// Creates a managed ClientConnector from a raw handle. /// @@ -277,9 +285,31 @@ public PduHint NextPduHint() /// /// - /// A State allocated on Rust side. + /// A DynState allocated on Rust side. + /// + public DynState GetDynState() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnector"); + } + Raw.ConnectorFfiResultBoxDynStateBoxIronRdpError result = Raw.ClientConnector.GetDynState(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.DynState* retVal = result.Ok; + return new DynState(retVal); + } + } + + /// + /// + /// A ClientConnectorState allocated on Rust side. /// - public State State() + public ClientConnectorState ConsumeAndCastToClientConnectorState() { unsafe { @@ -287,13 +317,13 @@ public State State() { throw new ObjectDisposedException("ClientConnector"); } - Raw.ConnectorFfiResultBoxStateBoxIronRdpError result = Raw.ClientConnector.State(_inner); + Raw.ConnectorFfiResultBoxClientConnectorStateBoxIronRdpError result = Raw.ClientConnector.ConsumeAndCastToClientConnectorState(_inner); if (!result.isOk) { throw new IronRdpException(new IronRdpError(result.Err)); } - Raw.State* retVal = result.Ok; - return new State(retVal); + Raw.ClientConnectorState* retVal = result.Ok; + return new ClientConnectorState(retVal); } } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorState.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorState.cs index 127bc83cb..1b4b692df 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorState.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorState.cs @@ -15,6 +15,62 @@ public partial class ClientConnectorState: IDisposable { private unsafe Raw.ClientConnectorState* _inner; + public SecurityProtocol BasicSettingsExchangeSendInitialSelectedProtocol + { + get + { + return GetBasicSettingsExchangeSendInitialSelectedProtocol(); + } + } + + public ConnectInitial BasicSettingsExchangeWaitResponseConnectInitial + { + get + { + return GetBasicSettingsExchangeWaitResponseConnectInitial(); + } + } + + public ConnectionResult ConnectedResult + { + get + { + return GetConnectedResult(); + } + } + + public SecurityProtocol ConnectionInitiationWaitConfirmRequestedProtocol + { + get + { + return GetConnectionInitiationWaitConfirmRequestedProtocol(); + } + } + + public SecurityProtocol CredsspSelectedProtocol + { + get + { + return GetCredsspSelectedProtocol(); + } + } + + public SecurityProtocol EnhancedSecurityUpgradeSelectedProtocol + { + get + { + return GetEnhancedSecurityUpgradeSelectedProtocol(); + } + } + + public ClientConnectorStateType Type + { + get + { + return GetType(); + } + } + /// /// Creates a managed ClientConnectorState from a raw handle. /// @@ -29,6 +85,160 @@ public unsafe ClientConnectorState(Raw.ClientConnectorState* handle) _inner = handle; } + /// + /// + /// A ClientConnectorStateType allocated on C# side. + /// + public ClientConnectorStateType GetType() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError result = Raw.ClientConnectorState.GetType(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ClientConnectorStateType retVal = result.Ok; + return (ClientConnectorStateType)retVal; + } + } + + /// + /// + /// A SecurityProtocol allocated on Rust side. + /// + public SecurityProtocol GetConnectionInitiationWaitConfirmRequestedProtocol() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError result = Raw.ClientConnectorState.GetConnectionInitiationWaitConfirmRequestedProtocol(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.SecurityProtocol* retVal = result.Ok; + return new SecurityProtocol(retVal); + } + } + + /// + /// + /// A SecurityProtocol allocated on Rust side. + /// + public SecurityProtocol GetEnhancedSecurityUpgradeSelectedProtocol() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError result = Raw.ClientConnectorState.GetEnhancedSecurityUpgradeSelectedProtocol(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.SecurityProtocol* retVal = result.Ok; + return new SecurityProtocol(retVal); + } + } + + /// + /// + /// A SecurityProtocol allocated on Rust side. + /// + public SecurityProtocol GetCredsspSelectedProtocol() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError result = Raw.ClientConnectorState.GetCredsspSelectedProtocol(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.SecurityProtocol* retVal = result.Ok; + return new SecurityProtocol(retVal); + } + } + + /// + /// + /// A SecurityProtocol allocated on Rust side. + /// + public SecurityProtocol GetBasicSettingsExchangeSendInitialSelectedProtocol() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError result = Raw.ClientConnectorState.GetBasicSettingsExchangeSendInitialSelectedProtocol(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.SecurityProtocol* retVal = result.Ok; + return new SecurityProtocol(retVal); + } + } + + /// + /// + /// A ConnectInitial allocated on Rust side. + /// + public ConnectInitial GetBasicSettingsExchangeWaitResponseConnectInitial() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxConnectInitialBoxIronRdpError result = Raw.ClientConnectorState.GetBasicSettingsExchangeWaitResponseConnectInitial(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ConnectInitial* retVal = result.Ok; + return new ConnectInitial(retVal); + } + } + + /// + /// + /// A ConnectionResult allocated on Rust side. + /// + public ConnectionResult GetConnectedResult() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("ClientConnectorState"); + } + Raw.ConnectorStateFfiResultBoxConnectionResultBoxIronRdpError result = Raw.ClientConnectorState.GetConnectedResult(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.ConnectionResult* retVal = result.Ok; + return new ConnectionResult(retVal); + } + } + /// /// Returns the underlying raw handle. /// diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorStateType.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorStateType.cs new file mode 100644 index 000000000..27a5199e8 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ClientConnectorStateType.cs @@ -0,0 +1,31 @@ +// 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 ClientConnectorStateType +{ + Consumed = 0, + ConnectionInitiationSendRequest = 1, + ConnectionInitiationWaitConfirm = 2, + EnhancedSecurityUpgrade = 3, + Credssp = 4, + BasicSettingsExchangeSendInitial = 5, + BasicSettingsExchangeWaitResponse = 6, + ChannelConnection = 7, + SecureSettingsExchange = 8, + ConnectTimeAutoDetection = 9, + LicensingExchange = 10, + MultitransportBootstrapping = 11, + CapabilitiesExchange = 12, + ConnectionFinalization = 13, + Connected = 14, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ConfigBuilder.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ConfigBuilder.cs index b3f46e34f..f821ebfb3 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/ConfigBuilder.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ConfigBuilder.cs @@ -161,7 +161,7 @@ public static ConfigBuilder New() } } - public void WithUsernameAndPasswrord(string username, string password) + public void WithUsernameAndPassword(string username, string password) { unsafe { @@ -177,7 +177,7 @@ public void WithUsernameAndPasswrord(string username, string password) { fixed (byte* passwordBufPtr = passwordBuf) { - Raw.ConfigBuilder.WithUsernameAndPasswrord(_inner, usernameBufPtr, usernameBufLength, passwordBufPtr, passwordBufLength); + Raw.ConfigBuilder.WithUsernameAndPassword(_inner, usernameBufPtr, usernameBufLength, passwordBufPtr, passwordBufLength); } } } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectInitial.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectInitial.cs new file mode 100644 index 000000000..8a8f676b6 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectInitial.cs @@ -0,0 +1,63 @@ +// 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 ConnectInitial: IDisposable +{ + private unsafe Raw.ConnectInitial* _inner; + + /// + /// Creates a managed ConnectInitial from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ConnectInitial(Raw.ConnectInitial* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ConnectInitial* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ConnectInitial.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ConnectInitial() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionActivationSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionActivationSequence.cs new file mode 100644 index 000000000..5c6e57fe9 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionActivationSequence.cs @@ -0,0 +1,63 @@ +// 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 ConnectionActivationSequence: IDisposable +{ + private unsafe Raw.ConnectionActivationSequence* _inner; + + /// + /// Creates a managed ConnectionActivationSequence from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe ConnectionActivationSequence(Raw.ConnectionActivationSequence* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.ConnectionActivationSequence* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.ConnectionActivationSequence.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~ConnectionActivationSequence() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionResult.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionResult.cs index d1d84d4b8..ce5ea459b 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionResult.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/ConnectionResult.cs @@ -47,14 +47,6 @@ public bool PointerSoftwareRendering } } - public StaticChannelSet StaticChannels - { - get - { - return GetStaticChannels(); - } - } - public ushort UserChannelId { get @@ -77,6 +69,7 @@ public unsafe ConnectionResult(Raw.ConnectionResult* handle) _inner = handle; } + /// public ushort GetIoChannelId() { unsafe @@ -85,11 +78,17 @@ public ushort GetIoChannelId() { throw new ObjectDisposedException("ConnectionResult"); } - ushort retVal = Raw.ConnectionResult.GetIoChannelId(_inner); + Raw.ConnectorResultFfiResultU16BoxIronRdpError result = Raw.ConnectionResult.GetIoChannelId(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + ushort retVal = result.Ok; return retVal; } } + /// public ushort GetUserChannelId() { unsafe @@ -98,27 +97,17 @@ public ushort GetUserChannelId() { throw new ObjectDisposedException("ConnectionResult"); } - ushort retVal = Raw.ConnectionResult.GetUserChannelId(_inner); - return retVal; - } - } - - /// - /// A StaticChannelSet allocated on Rust side. - /// - public StaticChannelSet GetStaticChannels() - { - unsafe - { - if (_inner == null) + Raw.ConnectorResultFfiResultU16BoxIronRdpError result = Raw.ConnectionResult.GetUserChannelId(_inner); + if (!result.isOk) { - throw new ObjectDisposedException("ConnectionResult"); + throw new IronRdpException(new IronRdpError(result.Err)); } - Raw.StaticChannelSet* retVal = Raw.ConnectionResult.GetStaticChannels(_inner); - return new StaticChannelSet(retVal); + ushort retVal = result.Ok; + return retVal; } } + /// /// /// A DesktopSize allocated on Rust side. /// @@ -130,11 +119,17 @@ public DesktopSize GetDesktopSize() { throw new ObjectDisposedException("ConnectionResult"); } - Raw.DesktopSize* retVal = Raw.ConnectionResult.GetDesktopSize(_inner); + Raw.ConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError result = Raw.ConnectionResult.GetDesktopSize(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.DesktopSize* retVal = result.Ok; return new DesktopSize(retVal); } } + /// public bool GetNoServerPointer() { unsafe @@ -143,11 +138,17 @@ public bool GetNoServerPointer() { throw new ObjectDisposedException("ConnectionResult"); } - bool retVal = Raw.ConnectionResult.GetNoServerPointer(_inner); + Raw.ConnectorResultFfiResultBoolBoxIronRdpError result = Raw.ConnectionResult.GetNoServerPointer(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + bool retVal = result.Ok; return retVal; } } + /// public bool GetPointerSoftwareRendering() { unsafe @@ -156,7 +157,12 @@ public bool GetPointerSoftwareRendering() { throw new ObjectDisposedException("ConnectionResult"); } - bool retVal = Raw.ConnectionResult.GetPointerSoftwareRendering(_inner); + Raw.ConnectorResultFfiResultBoolBoxIronRdpError result = Raw.ConnectionResult.GetPointerSoftwareRendering(_inner); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + bool retVal = result.Ok; return retVal; } } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedImage.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedImage.cs new file mode 100644 index 000000000..737e62674 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedImage.cs @@ -0,0 +1,143 @@ +// 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 DecodedImage: IDisposable +{ + private unsafe Raw.DecodedImage* _inner; + + public BytesSlice Data + { + get + { + return GetData(); + } + } + + public ushort Height + { + get + { + return GetHeight(); + } + } + + public ushort Width + { + get + { + return GetWidth(); + } + } + + /// + /// Creates a managed DecodedImage from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe DecodedImage(Raw.DecodedImage* handle) + { + _inner = handle; + } + + /// + /// A DecodedImage allocated on Rust side. + /// + public static DecodedImage New(PixelFormat pixelFormat, ushort width, ushort height) + { + unsafe + { + Raw.PixelFormat pixelFormatRaw; + pixelFormatRaw = (Raw.PixelFormat)pixelFormat; + Raw.DecodedImage* retVal = Raw.DecodedImage.New(pixelFormatRaw, width, height); + return new DecodedImage(retVal); + } + } + + /// + /// A BytesSlice allocated on Rust side. + /// + public BytesSlice GetData() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedImage"); + } + Raw.BytesSlice* retVal = Raw.DecodedImage.GetData(_inner); + return new BytesSlice(retVal); + } + } + + public ushort GetWidth() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedImage"); + } + ushort retVal = Raw.DecodedImage.GetWidth(_inner); + return retVal; + } + } + + public ushort GetHeight() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedImage"); + } + ushort retVal = Raw.DecodedImage.GetHeight(_inner); + return retVal; + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.DecodedImage* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.DecodedImage.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~DecodedImage() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedPointer.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedPointer.cs new file mode 100644 index 000000000..a967b6060 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/DecodedPointer.cs @@ -0,0 +1,171 @@ +// 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 DecodedPointer: IDisposable +{ + private unsafe Raw.DecodedPointer* _inner; + + public BytesSlice Data + { + get + { + return GetData(); + } + } + + public ushort Height + { + get + { + return GetHeight(); + } + } + + public ushort HotspotX + { + get + { + return GetHotspotX(); + } + } + + public ushort HotspotY + { + get + { + return GetHotspotY(); + } + } + + public ushort Width + { + get + { + return GetWidth(); + } + } + + /// + /// Creates a managed DecodedPointer from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe DecodedPointer(Raw.DecodedPointer* handle) + { + _inner = handle; + } + + public ushort GetWidth() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedPointer"); + } + ushort retVal = Raw.DecodedPointer.GetWidth(_inner); + return retVal; + } + } + + public ushort GetHeight() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedPointer"); + } + ushort retVal = Raw.DecodedPointer.GetHeight(_inner); + return retVal; + } + } + + public ushort GetHotspotX() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedPointer"); + } + ushort retVal = Raw.DecodedPointer.GetHotspotX(_inner); + return retVal; + } + } + + public ushort GetHotspotY() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedPointer"); + } + ushort retVal = Raw.DecodedPointer.GetHotspotY(_inner); + return retVal; + } + } + + /// + /// A BytesSlice allocated on Rust side. + /// + public BytesSlice GetData() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("DecodedPointer"); + } + Raw.BytesSlice* retVal = Raw.DecodedPointer.GetData(_inner); + return new BytesSlice(retVal); + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.DecodedPointer* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.DecodedPointer.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~DecodedPointer() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/State.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/DynState.cs similarity index 79% rename from ffi/dotnet/Devolutions.IronRdp/Generated/State.cs rename to ffi/dotnet/Devolutions.IronRdp/Generated/DynState.cs index 7d9875390..ac9c42fd7 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/State.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/DynState.cs @@ -11,9 +11,9 @@ namespace Devolutions.IronRdp; #nullable enable -public partial class State: IDisposable +public partial class DynState: IDisposable { - private unsafe Raw.State* _inner; + private unsafe Raw.DynState* _inner; public string Name { @@ -24,7 +24,7 @@ public string Name } /// - /// Creates a managed State from a raw handle. + /// Creates a managed DynState from a raw handle. /// /// /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). @@ -32,7 +32,7 @@ public string Name /// This constructor assumes the raw struct is allocated on Rust side. /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. /// - public unsafe State(Raw.State* handle) + public unsafe DynState(Raw.DynState* handle) { _inner = handle; } @@ -44,9 +44,9 @@ public void GetName(DiplomatWriteable writeable) { if (_inner == null) { - throw new ObjectDisposedException("State"); + throw new ObjectDisposedException("DynState"); } - Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.State.GetName(_inner, &writeable); + Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.DynState.GetName(_inner, &writeable); if (!result.isOk) { throw new IronRdpException(new IronRdpError(result.Err)); @@ -61,10 +61,10 @@ public string GetName() { if (_inner == null) { - throw new ObjectDisposedException("State"); + throw new ObjectDisposedException("DynState"); } DiplomatWriteable writeable = new DiplomatWriteable(); - Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.State.GetName(_inner, &writeable); + Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.DynState.GetName(_inner, &writeable); if (!result.isOk) { throw new IronRdpException(new IronRdpError(result.Err)); @@ -81,9 +81,9 @@ public bool IsTerminal() { if (_inner == null) { - throw new ObjectDisposedException("State"); + throw new ObjectDisposedException("DynState"); } - bool retVal = Raw.State.IsTerminal(_inner); + bool retVal = Raw.DynState.IsTerminal(_inner); return retVal; } } @@ -91,7 +91,7 @@ public bool IsTerminal() /// /// Returns the underlying raw handle. /// - public unsafe Raw.State* AsFFI() + public unsafe Raw.DynState* AsFFI() { return _inner; } @@ -108,14 +108,14 @@ public void Dispose() return; } - Raw.State.Destroy(_inner); + Raw.DynState.Destroy(_inner); _inner = null; GC.SuppressFinalize(this); } } - ~State() + ~DynState() { Dispose(); } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/GracefulDisconnectReason.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/GracefulDisconnectReason.cs new file mode 100644 index 000000000..8e8c22a5d --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/GracefulDisconnectReason.cs @@ -0,0 +1,63 @@ +// 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 GracefulDisconnectReason: IDisposable +{ + private unsafe Raw.GracefulDisconnectReason* _inner; + + /// + /// Creates a managed GracefulDisconnectReason from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe GracefulDisconnectReason(Raw.GracefulDisconnectReason* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.GracefulDisconnectReason* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.GracefulDisconnectReason.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~GracefulDisconnectReason() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/InclusiveRectangle.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/InclusiveRectangle.cs new file mode 100644 index 000000000..3ffb403c8 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/InclusiveRectangle.cs @@ -0,0 +1,63 @@ +// 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 InclusiveRectangle: IDisposable +{ + private unsafe Raw.InclusiveRectangle* _inner; + + /// + /// Creates a managed InclusiveRectangle from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe InclusiveRectangle(Raw.InclusiveRectangle* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.InclusiveRectangle* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.InclusiveRectangle.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~InclusiveRectangle() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/InputDatabase.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/InputDatabase.cs new file mode 100644 index 000000000..fc59c3da7 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/InputDatabase.cs @@ -0,0 +1,75 @@ +// 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 InputDatabase: IDisposable +{ + private unsafe Raw.InputDatabase* _inner; + + /// + /// Creates a managed InputDatabase from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe InputDatabase(Raw.InputDatabase* handle) + { + _inner = handle; + } + + /// + /// A InputDatabase allocated on Rust side. + /// + public static InputDatabase New() + { + unsafe + { + Raw.InputDatabase* retVal = Raw.InputDatabase.New(); + return new InputDatabase(retVal); + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.InputDatabase* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.InputDatabase.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~InputDatabase() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpErrorKind.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpErrorKind.cs index 029758eac..2b20bdacc 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpErrorKind.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpErrorKind.cs @@ -19,4 +19,5 @@ public enum IronRdpErrorKind Consumed = 3, IO = 4, AccessDenied = 5, + IncorrectEnumType = 6, } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpPdu.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpPdu.cs new file mode 100644 index 000000000..2bebeedeb --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/IronRdpPdu.cs @@ -0,0 +1,105 @@ +// 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 IronRdpPdu: IDisposable +{ + private unsafe Raw.IronRdpPdu* _inner; + + /// + /// Creates a managed IronRdpPdu from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe IronRdpPdu(Raw.IronRdpPdu* handle) + { + _inner = handle; + } + + /// + /// A IronRdpPdu allocated on Rust side. + /// + public static IronRdpPdu New() + { + unsafe + { + Raw.IronRdpPdu* retVal = Raw.IronRdpPdu.New(); + return new IronRdpPdu(retVal); + } + } + + /// + /// + /// A PduInfo allocated on Rust side. + /// + public PduInfo FindSize(byte[] bytes) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("IronRdpPdu"); + } + nuint bytesLength = (nuint)bytes.Length; + fixed (byte* bytesPtr = bytes) + { + Raw.PduFfiResultOptBoxPduInfoBoxIronRdpError result = Raw.IronRdpPdu.FindSize(_inner, bytesPtr, bytesLength); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + Raw.PduInfo* retVal = result.Ok; + if (retVal == null) + { + return null; + } + return new PduInfo(retVal); + } + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.IronRdpPdu* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.IronRdpPdu.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~IronRdpPdu() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/LicenseExchangeSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/LicenseExchangeSequence.cs new file mode 100644 index 000000000..b80e82607 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/LicenseExchangeSequence.cs @@ -0,0 +1,63 @@ +// 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 LicenseExchangeSequence: IDisposable +{ + private unsafe Raw.LicenseExchangeSequence* _inner; + + /// + /// Creates a managed LicenseExchangeSequence from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe LicenseExchangeSequence(Raw.LicenseExchangeSequence* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.LicenseExchangeSequence* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.LicenseExchangeSequence.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~LicenseExchangeSequence() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/PduInfo.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/PduInfo.cs new file mode 100644 index 000000000..94ce1093b --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/PduInfo.cs @@ -0,0 +1,108 @@ +// 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 PduInfo: IDisposable +{ + private unsafe Raw.PduInfo* _inner; + + public Action Action + { + get + { + return GetAction(); + } + } + + public nuint Length + { + get + { + return GetLength(); + } + } + + /// + /// Creates a managed PduInfo from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe PduInfo(Raw.PduInfo* handle) + { + _inner = handle; + } + + /// + /// A Action allocated on Rust side. + /// + public Action GetAction() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("PduInfo"); + } + Raw.Action* retVal = Raw.PduInfo.GetAction(_inner); + return new Action(retVal); + } + } + + public nuint GetLength() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("PduInfo"); + } + nuint retVal = Raw.PduInfo.GetLength(_inner); + return retVal; + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.PduInfo* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.PduInfo.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~PduInfo() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/PixelFormat.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/PixelFormat.cs new file mode 100644 index 000000000..f952c6910 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/PixelFormat.cs @@ -0,0 +1,24 @@ +// 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 PixelFormat +{ + ARgb32 = 0, + XRgb32 = 1, + ABgr32 = 2, + XBgr32 = 3, + BgrA32 = 4, + BgrX32 = 5, + RgbA32 = 6, + RgbX32 = 7, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/Position.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/Position.cs new file mode 100644 index 000000000..e7bc1a896 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/Position.cs @@ -0,0 +1,69 @@ +// 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 Position +{ + private Raw.Position _inner; + + public ushort X + { + get + { + unsafe + { + return _inner.x; + } + } + set + { + unsafe + { + _inner.x = value; + } + } + } + + public ushort Y + { + get + { + unsafe + { + return _inner.y; + } + } + set + { + unsafe + { + _inner.y = value; + } + } + } + + /// + /// Creates a managed Position from the raw representation. + /// + public unsafe Position(Raw.Position data) + { + _inner = data; + } + + /// + /// Returns a copy of the underlying raw representation. + /// + public Raw.Position AsFFI() + { + return _inner; + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawAction.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawAction.cs new file mode 100644 index 000000000..87c5a1e26 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawAction.cs @@ -0,0 +1,21 @@ +// 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 Action +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "Action_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(Action* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStage.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStage.cs new file mode 100644 index 000000000..a0f3d27ee --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStage.cs @@ -0,0 +1,27 @@ +// 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 ActiveStage +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_new", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxActiveStageBoxIronRdpError New(ConnectionResult* connectionResult); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_process", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError Process(ActiveStage* self, DecodedImage* image, Action* action, byte* payload, nuint payloadSz); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ActiveStage* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutput.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutput.cs new file mode 100644 index 000000000..5aa25a44a --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutput.cs @@ -0,0 +1,42 @@ +// 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 ActiveStageOutput +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_type", ExactSpelling = true)] + public static unsafe extern ActiveStageOutputType GetType(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_response_frame", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxBytesSliceBoxIronRdpError GetResponseFrame(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_graphics_update", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxInclusiveRectangleBoxIronRdpError GetGraphicsUpdate(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_pointer_position", ExactSpelling = true)] + public static unsafe extern SessionFfiResultPositionBoxIronRdpError GetPointerPosition(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_pointer_bitmap", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxDecodedPointerBoxIronRdpError GetPointerBitmap(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_terminate", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError GetTerminate(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_get_deactivate_all", ExactSpelling = true)] + public static unsafe extern SessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError GetDeactivateAll(ActiveStageOutput* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutput_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ActiveStageOutput* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputIterator.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputIterator.cs new file mode 100644 index 000000000..1d7b4b20a --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputIterator.cs @@ -0,0 +1,31 @@ +// 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 ActiveStageOutputIterator +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutputIterator_len", ExactSpelling = true)] + public static unsafe extern nuint Len(ActiveStageOutputIterator* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutputIterator_is_empty", ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static unsafe extern bool IsEmpty(ActiveStageOutputIterator* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutputIterator_next", ExactSpelling = true)] + public static unsafe extern ActiveStageOutput* Next(ActiveStageOutputIterator* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStageOutputIterator_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ActiveStageOutputIterator* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputType.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputType.cs new file mode 100644 index 000000000..5f05f2f44 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawActiveStageOutputType.cs @@ -0,0 +1,24 @@ +// 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 ActiveStageOutputType +{ + ResponseFrame = 0, + GraphicsUpdate = 1, + PointerDefault = 2, + PointerHidden = 3, + PointerPosition = 4, + PointerBitmap = 5, + Terminate = 6, + DeactivateAll = 7, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawBytesSlice.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawBytesSlice.cs new file mode 100644 index 000000000..3d7e6f8ca --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawBytesSlice.cs @@ -0,0 +1,27 @@ +// 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 BytesSlice +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "BytesSlice_get_size", ExactSpelling = true)] + public static unsafe extern nuint GetSize(BytesSlice* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "BytesSlice_fill", ExactSpelling = true)] + public static unsafe extern UtilsFfiResultVoidBoxIronRdpError Fill(BytesSlice* self, byte* buffer, nuint bufferSz); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "BytesSlice_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(BytesSlice* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawChannelConnectionSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawChannelConnectionSequence.cs new file mode 100644 index 000000000..74f3c82ca --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawChannelConnectionSequence.cs @@ -0,0 +1,21 @@ +// 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 ChannelConnectionSequence +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ChannelConnectionSequence_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ChannelConnectionSequence* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnector.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnector.cs index ce46a8ddc..ee4a24452 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnector.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnector.cs @@ -58,8 +58,11 @@ public partial struct ClientConnector [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_get_dyn_state", ExactSpelling = true)] + public static unsafe extern ConnectorFfiResultBoxDynStateBoxIronRdpError GetDynState(ClientConnector* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_consume_and_cast_to_client_connector_state", ExactSpelling = true)] + public static unsafe extern ConnectorFfiResultBoxClientConnectorStateBoxIronRdpError ConsumeAndCastToClientConnectorState(ClientConnector* self); [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnector_destroy", ExactSpelling = true)] public static unsafe extern void Destroy(ClientConnector* self); diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorState.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorState.cs index 669ae9c03..06e1dd417 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorState.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorState.cs @@ -16,6 +16,27 @@ public partial struct ClientConnectorState { private const string NativeLib = "DevolutionsIronRdp"; + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_type", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError GetType(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_connection_initiation_wait_confirm_requested_protocol", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError GetConnectionInitiationWaitConfirmRequestedProtocol(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_enhanced_security_upgrade_selected_protocol", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError GetEnhancedSecurityUpgradeSelectedProtocol(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_credssp_selected_protocol", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError GetCredsspSelectedProtocol(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_basic_settings_exchange_send_initial_selected_protocol", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError GetBasicSettingsExchangeSendInitialSelectedProtocol(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_basic_settings_exchange_wait_response_connect_initial", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxConnectInitialBoxIronRdpError GetBasicSettingsExchangeWaitResponseConnectInitial(ClientConnectorState* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_get_connected_result", ExactSpelling = true)] + public static unsafe extern ConnectorStateFfiResultBoxConnectionResultBoxIronRdpError GetConnectedResult(ClientConnectorState* self); + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ClientConnectorState_destroy", ExactSpelling = true)] public static unsafe extern void Destroy(ClientConnectorState* self); } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorStateType.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorStateType.cs new file mode 100644 index 000000000..32b51771d --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawClientConnectorStateType.cs @@ -0,0 +1,31 @@ +// 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 ClientConnectorStateType +{ + Consumed = 0, + ConnectionInitiationSendRequest = 1, + ConnectionInitiationWaitConfirm = 2, + EnhancedSecurityUpgrade = 3, + Credssp = 4, + BasicSettingsExchangeSendInitial = 5, + BasicSettingsExchangeWaitResponse = 6, + ChannelConnection = 7, + SecureSettingsExchange = 8, + ConnectTimeAutoDetection = 9, + LicensingExchange = 10, + MultitransportBootstrapping = 11, + CapabilitiesExchange = 12, + ConnectionFinalization = 13, + Connected = 14, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConfigBuilder.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConfigBuilder.cs index ac96aefb7..08a19c4ef 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConfigBuilder.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConfigBuilder.cs @@ -19,8 +19,8 @@ public partial struct ConfigBuilder [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_with_username_and_password", ExactSpelling = true)] + public static unsafe extern void WithUsernameAndPassword(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); diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectInitial.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectInitial.cs new file mode 100644 index 000000000..12e18464f --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectInitial.cs @@ -0,0 +1,21 @@ +// 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 ConnectInitial +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectInitial_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ConnectInitial* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionActivationSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionActivationSequence.cs new file mode 100644 index 000000000..846de2205 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionActivationSequence.cs @@ -0,0 +1,21 @@ +// 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 ConnectionActivationSequence +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionActivationSequence_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(ConnectionActivationSequence* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionResult.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionResult.cs index c8f51e3d1..80c5b25ff 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionResult.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectionResult.cs @@ -17,24 +17,19 @@ 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); + public static unsafe extern ConnectorResultFfiResultU16BoxIronRdpError 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); + public static unsafe extern ConnectorResultFfiResultU16BoxIronRdpError GetUserChannelId(ConnectionResult* self); [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_get_desktop_size", ExactSpelling = true)] - public static unsafe extern DesktopSize* GetDesktopSize(ConnectionResult* self); + public static unsafe extern ConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError 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); + public static unsafe extern ConnectorResultFfiResultBoolBoxIronRdpError 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); + public static unsafe extern ConnectorResultFfiResultBoolBoxIronRdpError GetPointerSoftwareRendering(ConnectionResult* self); [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ConnectionResult_destroy", ExactSpelling = true)] public static unsafe extern void Destroy(ConnectionResult* self); diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxClientConnectorStateBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxClientConnectorStateBoxIronRdpError.cs new file mode 100644 index 000000000..4a9bf3275 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxClientConnectorStateBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorFfiResultBoxClientConnectorStateBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ClientConnectorState* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ClientConnectorState* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxDynStateBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxDynStateBoxIronRdpError.cs new file mode 100644 index 000000000..68b410941 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxDynStateBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorFfiResultBoxDynStateBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal DynState* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe DynState* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxStateBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoolBoxIronRdpError.cs similarity index 85% rename from ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxStateBoxIronRdpError.cs rename to ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoolBoxIronRdpError.cs index 52c4cae5f..43f6e35f6 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorFfiResultBoxStateBoxIronRdpError.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoolBoxIronRdpError.cs @@ -12,13 +12,13 @@ namespace Devolutions.IronRdp.Raw; #nullable enable [StructLayout(LayoutKind.Sequential)] -public partial struct ConnectorFfiResultBoxStateBoxIronRdpError +public partial struct ConnectorResultFfiResultBoolBoxIronRdpError { [StructLayout(LayoutKind.Explicit)] private unsafe struct InnerUnion { [FieldOffset(0)] - internal State* ok; + internal bool ok; [FieldOffset(0)] internal IronRdpError* err; } @@ -28,7 +28,7 @@ private unsafe struct InnerUnion [MarshalAs(UnmanagedType.U1)] public bool isOk; - public unsafe State* Ok + public unsafe bool Ok { get { diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError.cs new file mode 100644 index 000000000..21b72d2b2 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorResultFfiResultBoxDesktopSizeBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal DesktopSize* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe DesktopSize* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultU16BoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultU16BoxIronRdpError.cs new file mode 100644 index 000000000..6d2c9298f --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorResultFfiResultU16BoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorResultFfiResultU16BoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ushort ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ushort Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectInitialBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectInitialBoxIronRdpError.cs new file mode 100644 index 000000000..57848c690 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectInitialBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorStateFfiResultBoxConnectInitialBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ConnectInitial* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ConnectInitial* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectionResultBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectionResultBoxIronRdpError.cs new file mode 100644 index 000000000..e1b2b186e --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxConnectionResultBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorStateFfiResultBoxConnectionResultBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ConnectionResult* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ConnectionResult* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError.cs new file mode 100644 index 000000000..e4e098e1a --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorStateFfiResultBoxSecurityProtocolBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal SecurityProtocol* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe SecurityProtocol* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError.cs new file mode 100644 index 000000000..05c250ce4 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 ConnectorStateFfiResultClientConnectorStateTypeBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ClientConnectorStateType ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ClientConnectorStateType Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedImage.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedImage.cs new file mode 100644 index 000000000..078af3845 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedImage.cs @@ -0,0 +1,33 @@ +// 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 DecodedImage +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedImage_new", ExactSpelling = true)] + public static unsafe extern DecodedImage* New(PixelFormat pixelFormat, ushort width, ushort height); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedImage_get_data", ExactSpelling = true)] + public static unsafe extern BytesSlice* GetData(DecodedImage* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedImage_get_width", ExactSpelling = true)] + public static unsafe extern ushort GetWidth(DecodedImage* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedImage_get_height", ExactSpelling = true)] + public static unsafe extern ushort GetHeight(DecodedImage* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedImage_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(DecodedImage* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedPointer.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedPointer.cs new file mode 100644 index 000000000..ba4de8bad --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDecodedPointer.cs @@ -0,0 +1,36 @@ +// 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 DecodedPointer +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_get_width", ExactSpelling = true)] + public static unsafe extern ushort GetWidth(DecodedPointer* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_get_height", ExactSpelling = true)] + public static unsafe extern ushort GetHeight(DecodedPointer* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_get_hotspot_x", ExactSpelling = true)] + public static unsafe extern ushort GetHotspotX(DecodedPointer* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_get_hotspot_y", ExactSpelling = true)] + public static unsafe extern ushort GetHotspotY(DecodedPointer* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_get_data", ExactSpelling = true)] + public static unsafe extern BytesSlice* GetData(DecodedPointer* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DecodedPointer_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(DecodedPointer* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawState.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDynState.cs similarity index 60% rename from ffi/dotnet/Devolutions.IronRdp/Generated/RawState.cs rename to ffi/dotnet/Devolutions.IronRdp/Generated/RawDynState.cs index 99ea3e78f..9c1147ef2 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawState.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawDynState.cs @@ -12,17 +12,17 @@ namespace Devolutions.IronRdp.Raw; #nullable enable [StructLayout(LayoutKind.Sequential)] -public partial struct State +public partial struct DynState { 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 = "DynState_get_name", ExactSpelling = true)] + public static unsafe extern ConnectorFfiResultVoidBoxIronRdpError GetName(DynState* self, DiplomatWriteable* writeable); - [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "State_is_terminal", ExactSpelling = true)] + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DynState_is_terminal", ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static unsafe extern bool IsTerminal(State* self); + public static unsafe extern bool IsTerminal(DynState* self); - [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "State_destroy", ExactSpelling = true)] - public static unsafe extern void Destroy(State* self); + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "DynState_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(DynState* self); } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawGracefulDisconnectReason.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawGracefulDisconnectReason.cs new file mode 100644 index 000000000..8539b037d --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawGracefulDisconnectReason.cs @@ -0,0 +1,21 @@ +// 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 GracefulDisconnectReason +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "GracefulDisconnectReason_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(GracefulDisconnectReason* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawInclusiveRectangle.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawInclusiveRectangle.cs new file mode 100644 index 000000000..6215e5924 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawInclusiveRectangle.cs @@ -0,0 +1,21 @@ +// 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 InclusiveRectangle +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "InclusiveRectangle_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(InclusiveRectangle* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawInputDatabase.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawInputDatabase.cs new file mode 100644 index 000000000..b1699ddec --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawInputDatabase.cs @@ -0,0 +1,24 @@ +// 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 InputDatabase +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "InputDatabase_new", ExactSpelling = true)] + public static unsafe extern InputDatabase* New(); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "InputDatabase_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(InputDatabase* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpErrorKind.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpErrorKind.cs index 83c1d0e1b..045a9aedf 100644 --- a/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpErrorKind.cs +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpErrorKind.cs @@ -19,4 +19,5 @@ public enum IronRdpErrorKind Consumed = 3, IO = 4, AccessDenied = 5, + IncorrectEnumType = 6, } diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpPdu.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpPdu.cs new file mode 100644 index 000000000..4e1ea99a2 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawIronRdpPdu.cs @@ -0,0 +1,27 @@ +// 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 IronRdpPdu +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpPdu_new", ExactSpelling = true)] + public static unsafe extern IronRdpPdu* New(); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpPdu_find_size", ExactSpelling = true)] + public static unsafe extern PduFfiResultOptBoxPduInfoBoxIronRdpError FindSize(IronRdpPdu* self, byte* bytes, nuint bytesSz); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "IronRdpPdu_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(IronRdpPdu* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawLicenseExchangeSequence.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawLicenseExchangeSequence.cs new file mode 100644 index 000000000..a0d756681 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawLicenseExchangeSequence.cs @@ -0,0 +1,21 @@ +// 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 LicenseExchangeSequence +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "LicenseExchangeSequence_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(LicenseExchangeSequence* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduFfiResultOptBoxPduInfoBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduFfiResultOptBoxPduInfoBoxIronRdpError.cs new file mode 100644 index 000000000..4e6f63cd7 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduFfiResultOptBoxPduInfoBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 PduFfiResultOptBoxPduInfoBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal PduInfo* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe PduInfo* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduInfo.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduInfo.cs new file mode 100644 index 000000000..04488e485 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPduInfo.cs @@ -0,0 +1,27 @@ +// 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 PduInfo +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduInfo_get_action", ExactSpelling = true)] + public static unsafe extern Action* GetAction(PduInfo* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduInfo_get_length", ExactSpelling = true)] + public static unsafe extern nuint GetLength(PduInfo* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduInfo_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(PduInfo* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawPixelFormat.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPixelFormat.cs new file mode 100644 index 000000000..0cc53eaad --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPixelFormat.cs @@ -0,0 +1,24 @@ +// 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 PixelFormat +{ + ARgb32 = 0, + XRgb32 = 1, + ABgr32 = 2, + XBgr32 = 3, + BgrA32 = 4, + BgrX32 = 5, + RgbA32 = 6, + RgbX32 = 7, +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawPosition.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPosition.cs new file mode 100644 index 000000000..3c55209cf --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawPosition.cs @@ -0,0 +1,22 @@ +// 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 Position +{ + private const string NativeLib = "DevolutionsIronRdp"; + + public ushort x; + + public ushort y; +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSecurityProtocol.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSecurityProtocol.cs new file mode 100644 index 000000000..d3832a261 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSecurityProtocol.cs @@ -0,0 +1,21 @@ +// 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 SecurityProtocol +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SecurityProtocol_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(SecurityProtocol* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageBoxIronRdpError.cs new file mode 100644 index 000000000..998d2eb08 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxActiveStageBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ActiveStage* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ActiveStage* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError.cs new file mode 100644 index 000000000..d31234405 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ActiveStageOutputIterator* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ActiveStageOutputIterator* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxBytesSliceBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxBytesSliceBoxIronRdpError.cs new file mode 100644 index 000000000..24821d13b --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxBytesSliceBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxBytesSliceBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal BytesSlice* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe BytesSlice* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError.cs new file mode 100644 index 000000000..0095580e4 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxConnectionActivationSequenceBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal ConnectionActivationSequence* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe ConnectionActivationSequence* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxDecodedPointerBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxDecodedPointerBoxIronRdpError.cs new file mode 100644 index 000000000..dc819759c --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxDecodedPointerBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxDecodedPointerBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal DecodedPointer* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe DecodedPointer* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError.cs new file mode 100644 index 000000000..23d2076c0 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxGracefulDisconnectReasonBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal GracefulDisconnectReason* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe GracefulDisconnectReason* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxInclusiveRectangleBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxInclusiveRectangleBoxIronRdpError.cs new file mode 100644 index 000000000..7b9a9b0d5 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultBoxInclusiveRectangleBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultBoxInclusiveRectangleBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal InclusiveRectangle* ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe InclusiveRectangle* Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultPositionBoxIronRdpError.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultPositionBoxIronRdpError.cs new file mode 100644 index 000000000..ac73edc65 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawSessionFfiResultPositionBoxIronRdpError.cs @@ -0,0 +1,46 @@ +// 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 SessionFfiResultPositionBoxIronRdpError +{ + [StructLayout(LayoutKind.Explicit)] + private unsafe struct InnerUnion + { + [FieldOffset(0)] + internal Position ok; + [FieldOffset(0)] + internal IronRdpError* err; + } + + private InnerUnion _inner; + + [MarshalAs(UnmanagedType.U1)] + public bool isOk; + + public unsafe Position Ok + { + get + { + return _inner.ok; + } + } + + public unsafe IronRdpError* Err + { + get + { + return _inner.err; + } + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/RawU32Slice.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/RawU32Slice.cs new file mode 100644 index 000000000..bdf2dca80 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/RawU32Slice.cs @@ -0,0 +1,27 @@ +// 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 U32Slice +{ + private const string NativeLib = "DevolutionsIronRdp"; + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "U32Slice_get_size", ExactSpelling = true)] + public static unsafe extern nuint GetSize(U32Slice* self); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "U32Slice_fill", ExactSpelling = true)] + public static unsafe extern UtilsFfiResultVoidBoxIronRdpError Fill(U32Slice* self, uint* buffer, nuint bufferSz); + + [DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "U32Slice_destroy", ExactSpelling = true)] + public static unsafe extern void Destroy(U32Slice* self); +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/SecurityProtocol.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/SecurityProtocol.cs new file mode 100644 index 000000000..92dec8315 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/SecurityProtocol.cs @@ -0,0 +1,63 @@ +// 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 SecurityProtocol: IDisposable +{ + private unsafe Raw.SecurityProtocol* _inner; + + /// + /// Creates a managed SecurityProtocol from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe SecurityProtocol(Raw.SecurityProtocol* handle) + { + _inner = handle; + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.SecurityProtocol* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.SecurityProtocol.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~SecurityProtocol() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/Generated/U32Slice.cs b/ffi/dotnet/Devolutions.IronRdp/Generated/U32Slice.cs new file mode 100644 index 000000000..e552913cf --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/Generated/U32Slice.cs @@ -0,0 +1,105 @@ +// 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 U32Slice: IDisposable +{ + private unsafe Raw.U32Slice* _inner; + + public nuint Size + { + get + { + return GetSize(); + } + } + + /// + /// Creates a managed U32Slice from a raw handle. + /// + /// + /// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free). + ///
+ /// This constructor assumes the raw struct is allocated on Rust side. + /// If implemented, the custom Drop implementation on Rust side WILL run on destruction. + ///
+ public unsafe U32Slice(Raw.U32Slice* handle) + { + _inner = handle; + } + + public nuint GetSize() + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("U32Slice"); + } + nuint retVal = Raw.U32Slice.GetSize(_inner); + return retVal; + } + } + + /// + public void Fill(uint[] buffer) + { + unsafe + { + if (_inner == null) + { + throw new ObjectDisposedException("U32Slice"); + } + nuint bufferLength = (nuint)buffer.Length; + fixed (uint* bufferPtr = buffer) + { + Raw.UtilsFfiResultVoidBoxIronRdpError result = Raw.U32Slice.Fill(_inner, bufferPtr, bufferLength); + if (!result.isOk) + { + throw new IronRdpException(new IronRdpError(result.Err)); + } + } + } + } + + /// + /// Returns the underlying raw handle. + /// + public unsafe Raw.U32Slice* AsFFI() + { + return _inner; + } + + /// + /// Destroys the underlying object immediately. + /// + public void Dispose() + { + unsafe + { + if (_inner == null) + { + return; + } + + Raw.U32Slice.Destroy(_inner); + _inner = null; + + GC.SuppressFinalize(this); + } + } + + ~U32Slice() + { + Dispose(); + } +} diff --git a/ffi/dotnet/Devolutions.IronRdp/src/Connection.cs b/ffi/dotnet/Devolutions.IronRdp/src/Connection.cs new file mode 100644 index 000000000..48086ee47 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/src/Connection.cs @@ -0,0 +1,223 @@ + +using System.Net; +using System.Net.Security; +using System.Net.Sockets; +using Devolutions.IronRdp; + +public class Connection +{ + + public static async Task<(ConnectionResult,Framed)> Connect(Config config,string servername) + { + + var stream = await CreateTcpConnection(servername, 3389); + var framed = new Framed(stream); + + ClientConnector connector = ClientConnector.New(config); + + var ip = await Dns.GetHostAddressesAsync(servername); + if (ip.Length == 0) + { + throw new IronRdpLibException(IronRdpLibExceptionType.CannotResolveDns, "Cannot resolve DNS to " + servername); + } + + var socketAddrString = ip[0].ToString() + ":3389"; + connector.WithServerAddr(socketAddrString); + + await connectBegin(framed, connector); + var (serverPublicKey, framedSsl) = await securityUpgrade(servername, framed, connector); + var result = await ConnectFinalize(servername, connector, serverPublicKey, framedSsl); + return (result, framedSsl); + } + + private static async Task<(byte[], Framed)> securityUpgrade(string servername, Framed framed, ClientConnector connector) + { + byte[] serverPublicKey; + Framed framedSsl; + var (streamRequireUpgrade, _) = framed.GetInner(); + var promise = new TaskCompletionSource(); + 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); + connector.MarkSecurityUpgradeAsDone(); + + return (serverPublicKey, framedSsl); + } + + private static async Task connectBegin(Framed framed, ClientConnector connector) + { + var writeBuf = WriteBuf.New(); + while (!connector.ShouldPerformSecurityUpgrade()) + { + await SingleConnectStep(connector, writeBuf, framed); + } + } + + + private static async Task ConnectFinalize(string servername, ClientConnector connector, byte[] serverpubkey, Framed framedSsl) + { + var writeBuf2 = WriteBuf.New(); + if (connector.ShouldPerformCredssp()) + { + await PerformCredsspSteps(connector, servername, writeBuf2, framedSsl, serverpubkey); + } + while (!connector.GetDynState().IsTerminal()) + { + await SingleConnectStep(connector, writeBuf2, framedSsl); + } + + ClientConnectorState state = connector.ConsumeAndCastToClientConnectorState(); + + if (state.GetType() == ClientConnectorStateType.Connected) + { + return state.GetConnectedResult(); + } + else + { + throw new IronRdpLibException(IronRdpLibExceptionType.ConnectionFailed, "Connection failed"); + } + } + + private static async Task PerformCredsspSteps(ClientConnector connector, string serverName, WriteBuf writeBuf, Framed 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 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(ClientConnector connector, WriteBuf buf, Framed 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 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; + } +} \ No newline at end of file diff --git a/ffi/dotnet/Devolutions.IronRdp/src/Exceptions.cs b/ffi/dotnet/Devolutions.IronRdp/src/Exceptions.cs new file mode 100644 index 000000000..b03ba7338 --- /dev/null +++ b/ffi/dotnet/Devolutions.IronRdp/src/Exceptions.cs @@ -0,0 +1,18 @@ +[Serializable] +public class IronRdpLibException : Exception +{ + public IronRdpLibExceptionType type { get; private set; } + + public IronRdpLibException(IronRdpLibExceptionType type, string message): base(message) + { + this.type = type; + } + +} + +public enum IronRdpLibExceptionType +{ + CannotResolveDns, + ConnectionFailed, + EndOfFile, +} \ No newline at end of file diff --git a/ffi/dotnet/Devolutions.IronRdp/src/Framed.cs b/ffi/dotnet/Devolutions.IronRdp/src/Framed.cs index 715b05407..c31763df3 100644 --- a/ffi/dotnet/Devolutions.IronRdp/src/Framed.cs +++ b/ffi/dotnet/Devolutions.IronRdp/src/Framed.cs @@ -1,3 +1,4 @@ +using System.Linq.Expressions; using System.Runtime.InteropServices; using Devolutions.IronRdp; @@ -17,6 +18,24 @@ public Framed(S stream) return (this.stream, this.buffer); } + public async Task<(Devolutions.IronRdp.Action,byte[])> ReadPdu() { + + while(true) { + var pduInfo = IronRdpPdu.New().FindSize(this.buffer.ToArray()); + if (null != pduInfo) { + var frame = await this.ReadExact(pduInfo.GetLength()); + var action = pduInfo.GetAction(); + return (action,frame); + }else { + var len = await this.Read(); + + if (len == 0) { + throw new IronRdpLibException(IronRdpLibExceptionType.EndOfFile,"EOF on ReadPdu"); + } + } + } + } + /// /// Returns a span that represents a portion of the underlying buffer without modifying it. /// diff --git a/ffi/src/connector/config.rs b/ffi/src/connector/config.rs index e70f30066..d150cdfea 100644 --- a/ffi/src/connector/config.rs +++ b/ffi/src/connector/config.rs @@ -148,7 +148,7 @@ pub mod ffi { pub fn build(&self) -> Result, Box> { let inner_config = ironrdp::connector::Config { - credentials: self.credentials.clone().ok_or("Credentials not set")?, + 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), @@ -160,11 +160,11 @@ pub mod ffi { 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")?, + 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")?, + 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, @@ -188,7 +188,7 @@ pub mod ffi { 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")?, + performance_flags: self.performance_flags.ok_or("performance flag is missing")?, }; Ok(Box::new(Config(inner_config))) diff --git a/ffi/src/connector/mod.rs b/ffi/src/connector/mod.rs index 18b869487..6b764133b 100644 --- a/ffi/src/connector/mod.rs +++ b/ffi/src/connector/mod.rs @@ -16,7 +16,7 @@ pub mod ffi { pdu::ffi::WriteBuf, }; - use super::{config::ffi::Config, result::ffi::Written}; + use super::{config::ffi::Config, result::ffi::Written, state::ffi::ClientConnectorState}; #[diplomat::opaque] // We must use Option here, as ClientConnector is not Clone and have functions that consume it pub struct ClientConnector(pub Option); @@ -132,9 +132,9 @@ pub mod ffi { } #[diplomat::opaque] - pub struct State<'a>(pub &'a dyn ironrdp::connector::State); + pub struct DynState<'a>(pub &'a dyn ironrdp::connector::State); - impl<'a> State<'a> { + impl<'a> DynState<'a> { pub fn get_name(&'a self, writeable: &'a mut DiplomatWriteable) -> Result<(), Box> { let name = self.0.name(); write!(writeable, "{}", name)?; @@ -154,11 +154,31 @@ pub mod ffi { Ok(connector.next_pdu_hint().map(PduHint).map(Box::new)) } - pub fn state(&self) -> Result>, Box> { + pub fn get_dyn_state(&self) -> Result>, Box> { let Some(connector) = self.0.as_ref() else { return Err(ValueConsumedError::for_item("connector").into()); }; - Ok(Box::new(State(connector.state()))) + Ok(Box::new(DynState(connector.state()))) + } + + pub fn consume_and_cast_to_client_connector_state( + &mut self, + ) -> Result, Box> { + let Some(connector) = self.0.take() else { + return Err(ValueConsumedError::for_item("connector").into()); + }; + Ok(Box::new(ClientConnectorState(Some(connector.state)))) } } + + #[diplomat::opaque] + pub struct ChannelConnectionSequence(pub ironrdp::connector::ChannelConnectionSequence); + + #[diplomat::opaque] + pub struct LicenseExchangeSequence(pub ironrdp::connector::LicenseExchangeSequence); + + #[diplomat::opaque] + pub struct ConnectionActivationSequence( + pub Box, + ); } diff --git a/ffi/src/connector/result.rs b/ffi/src/connector/result.rs index cffea1a7b..54211cc34 100644 --- a/ffi/src/connector/result.rs +++ b/ffi/src/connector/result.rs @@ -1,6 +1,10 @@ #[diplomat::bridge] pub mod ffi { - use crate::{connector::config::ffi::DesktopSize, utils::ffi::OptionalUsize}; + use crate::{ + connector::config::ffi::DesktopSize, + error::{ffi::IronRdpError, ValueConsumedError}, + utils::ffi::OptionalUsize, + }; #[diplomat::opaque] pub struct Written(pub ironrdp::connector::Written); @@ -27,31 +31,48 @@ pub mod ffi { } #[diplomat::opaque] - pub struct ConnectionResult(pub ironrdp::connector::ConnectionResult); + pub struct ConnectionResult(pub Option); impl ConnectionResult { - pub fn get_io_channel_id(&self) -> u16 { - self.0.io_channel_id + pub fn get_io_channel_id(&self) -> Result> { + Ok(self + .0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ConnectionResult"))? + .io_channel_id) } - pub fn get_user_channel_id(&self) -> u16 { - self.0.user_channel_id + pub fn get_user_channel_id(&self) -> Result> { + Ok(self + .0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ConnectionResult"))? + .user_channel_id) } - pub fn get_static_channels(&self) -> Box> { - Box::new(crate::svc::ffi::StaticChannelSet(&self.0.static_channels)) + pub fn get_desktop_size(&self) -> Result, Box> { + Ok(Box::new(DesktopSize( + self.0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ConnectionResult"))? + .desktop_size, + ))) } - pub fn get_desktop_size(&self) -> Box { - Box::new(DesktopSize(self.0.desktop_size)) + pub fn get_no_server_pointer(&self) -> Result> { + Ok(self + .0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ConnectionResult"))? + .no_server_pointer) } - 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 + pub fn get_pointer_software_rendering(&self) -> Result> { + Ok(self + .0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ConnectionResult"))? + .pointer_software_rendering) } } } diff --git a/ffi/src/connector/state.rs b/ffi/src/connector/state.rs index de892368c..2a9519ae2 100644 --- a/ffi/src/connector/state.rs +++ b/ffi/src/connector/state.rs @@ -1,6 +1,188 @@ #[diplomat::bridge] pub mod ffi { + use crate::{ + error::{ffi::IronRdpError, IncorrectEnumTypeError, ValueConsumedError}, + pdu::ffi::SecurityProtocol, + }; #[diplomat::opaque] - pub struct ClientConnectorState(pub ironrdp::connector::ClientConnectorState); + pub struct ClientConnectorState(pub Option); + + pub enum ClientConnectorStateType { + Consumed, + ConnectionInitiationSendRequest, + ConnectionInitiationWaitConfirm, + EnhancedSecurityUpgrade, + Credssp, + BasicSettingsExchangeSendInitial, + BasicSettingsExchangeWaitResponse, + ChannelConnection, + SecureSettingsExchange, + ConnectTimeAutoDetection, + LicensingExchange, + MultitransportBootstrapping, + CapabilitiesExchange, + ConnectionFinalization, + Connected, + } + + impl ClientConnectorState { + pub fn get_type(&self) -> Result> { + let res = match &self + .0 + .as_ref() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::Consumed => ClientConnectorStateType::Consumed, + ironrdp::connector::ClientConnectorState::ConnectionInitiationSendRequest => { + ClientConnectorStateType::ConnectionInitiationSendRequest + } + ironrdp::connector::ClientConnectorState::ConnectionInitiationWaitConfirm { .. } => { + ClientConnectorStateType::ConnectionInitiationWaitConfirm + } + ironrdp::connector::ClientConnectorState::EnhancedSecurityUpgrade { .. } => { + ClientConnectorStateType::EnhancedSecurityUpgrade + } + ironrdp::connector::ClientConnectorState::Credssp { .. } => ClientConnectorStateType::Credssp, + ironrdp::connector::ClientConnectorState::BasicSettingsExchangeSendInitial { .. } => { + ClientConnectorStateType::BasicSettingsExchangeSendInitial + } + ironrdp::connector::ClientConnectorState::BasicSettingsExchangeWaitResponse { .. } => { + ClientConnectorStateType::BasicSettingsExchangeWaitResponse + } + ironrdp::connector::ClientConnectorState::ChannelConnection { .. } => { + ClientConnectorStateType::ChannelConnection + } + ironrdp::connector::ClientConnectorState::SecureSettingsExchange { .. } => { + ClientConnectorStateType::SecureSettingsExchange + } + ironrdp::connector::ClientConnectorState::ConnectTimeAutoDetection { .. } => { + ClientConnectorStateType::ConnectTimeAutoDetection + } + ironrdp::connector::ClientConnectorState::LicensingExchange { .. } => { + ClientConnectorStateType::LicensingExchange + } + ironrdp::connector::ClientConnectorState::MultitransportBootstrapping { .. } => { + ClientConnectorStateType::MultitransportBootstrapping + } + ironrdp::connector::ClientConnectorState::CapabilitiesExchange { .. } => { + ClientConnectorStateType::CapabilitiesExchange + } + ironrdp::connector::ClientConnectorState::ConnectionFinalization { .. } => { + ClientConnectorStateType::ConnectionFinalization + } + ironrdp::connector::ClientConnectorState::Connected { .. } => ClientConnectorStateType::Connected, + &_ => return Err("Unknown ClientConnectorStateType".into()), + }; + + Ok(res) + } + + pub fn get_connection_initiation_wait_confirm_requested_protocol( + &mut self, + ) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::ConnectionInitiationWaitConfirm { requested_protocol } => { + Ok(SecurityProtocol(requested_protocol)) + } + _ => Err(IncorrectEnumTypeError::on_variant("ConnectionInitiationWaitConfirm") + .of_enum("ClientConnectorState") + .into()), + } + .map(Box::new) + } + + pub fn get_enhanced_security_upgrade_selected_protocol( + &mut self, + ) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::EnhancedSecurityUpgrade { selected_protocol } => { + Ok(SecurityProtocol(selected_protocol)) + } + _ => Err(IncorrectEnumTypeError::on_variant("EnhancedSecurityUpgrade") + .of_enum("ClientConnectorState") + .into()), + } + .map(Box::new) + } + + pub fn get_credssp_selected_protocol(&mut self) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::Credssp { selected_protocol } => { + Ok(SecurityProtocol(selected_protocol)) + } + _ => Err(IncorrectEnumTypeError::on_variant("Credssp") + .of_enum("ClientConnectorState") + .into()), + } + .map(Box::new) + } + + pub fn get_basic_settings_exchange_send_initial_selected_protocol( + &mut self, + ) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::BasicSettingsExchangeSendInitial { selected_protocol } => { + Ok(SecurityProtocol(selected_protocol)) + } + _ => Err(IncorrectEnumTypeError::on_variant("BasicSettingsExchangeSendInitial") + .of_enum("ClientConnectorState") + .into()), + } + .map(Box::new) + } + + pub fn get_basic_settings_exchange_wait_response_connect_initial( + &mut self, + ) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::BasicSettingsExchangeWaitResponse { connect_initial } => { + Ok(crate::pdu::ffi::ConnectInitial(connect_initial)) + } + _ => Err(IncorrectEnumTypeError::on_variant("BasicSettingsExchangeWaitResponse") + .of_enum("ClientConnectorState") + .into()), + } + .map(Box::new) + } + + // TODO: Add more getters for other states + + pub fn get_connected_result( + &mut self, + ) -> Result, Box> { + match self + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("ClientConnectorState"))? + { + ironrdp::connector::ClientConnectorState::Connected { result } => { + Ok(Box::new(crate::connector::result::ffi::ConnectionResult(Some(result)))) + } + _ => Err(IncorrectEnumTypeError::on_variant("Connected") + .of_enum("ClientConnectorState") + .into()), + } + } + } } diff --git a/ffi/src/error.rs b/ffi/src/error.rs index 3e0de3219..05e26c830 100644 --- a/ffi/src/error.rs +++ b/ffi/src/error.rs @@ -1,7 +1,7 @@ #![allow(clippy::return_self_not_must_use)] use std::fmt::Display; -use ironrdp::connector::ConnectorError; +use ironrdp::{connector::ConnectorError, session::SessionError}; use self::ffi::IronRdpErrorKind; @@ -46,6 +46,15 @@ impl From for IronRdpErrorKind { } } +impl From for IronRdpErrorKind { + fn from(value: SessionError) -> Self { + match value.kind() { + ironrdp::session::SessionErrorKind::Pdu(_) => IronRdpErrorKind::PduError, + _ => IronRdpErrorKind::Generic, + } + } +} + impl From for Box where T: Into + ToString, @@ -81,6 +90,8 @@ pub mod ffi { IO, #[error("Access denied")] AccessDenied, + #[error("Incorrect rust enum type")] + IncorrectEnumType, } /// Stringified Picky error along with an error kind. @@ -136,3 +147,43 @@ impl From for IronRdpErrorKind { IronRdpErrorKind::Consumed } } + +pub struct IncorrectEnumTypeError { + expected: &'static str, + enum_name: &'static str, +} + +impl IncorrectEnumTypeError { + pub fn on_variant(variant: &'static str) -> IncorrectEnumTypeErrorBuilder { + IncorrectEnumTypeErrorBuilder { expected: variant } + } +} + +pub struct IncorrectEnumTypeErrorBuilder { + expected: &'static str, +} + +impl IncorrectEnumTypeErrorBuilder { + pub fn of_enum(self, enum_name: &'static str) -> IncorrectEnumTypeError { + IncorrectEnumTypeError { + expected: self.expected, + enum_name, + } + } +} + +impl Display for IncorrectEnumTypeError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "expected enum variable {}, of enum {}", + self.expected, self.enum_name + ) + } +} + +impl From for IronRdpErrorKind { + fn from(_val: IncorrectEnumTypeError) -> Self { + IronRdpErrorKind::IncorrectEnumType + } +} diff --git a/ffi/src/graphics.rs b/ffi/src/graphics.rs new file mode 100644 index 000000000..24a7f59a6 --- /dev/null +++ b/ffi/src/graphics.rs @@ -0,0 +1,31 @@ +#[diplomat::bridge] +pub mod ffi { + use std::rc::Rc; + + use crate::utils::ffi::BytesSlice; + + #[diplomat::opaque] + pub struct DecodedPointer(pub Rc); + + impl DecodedPointer { + pub fn get_width(&self) -> u16 { + self.0.width + } + + pub fn get_height(&self) -> u16 { + self.0.height + } + + pub fn get_hotspot_x(&self) -> u16 { + self.0.hotspot_x + } + + pub fn get_hotspot_y(&self) -> u16 { + self.0.hotspot_y + } + + pub fn get_data(&self) -> Box> { + Box::new(BytesSlice(&self.0.bitmap_data)) + } + } +} diff --git a/ffi/src/input.rs b/ffi/src/input.rs new file mode 100644 index 000000000..ca7eba7aa --- /dev/null +++ b/ffi/src/input.rs @@ -0,0 +1,11 @@ +#[diplomat::bridge] +pub mod ffi { + #[diplomat::opaque] + pub struct InputDatabase(pub ironrdp::input::Database); + + impl InputDatabase { + pub fn new() -> Box { + Box::new(InputDatabase(ironrdp::input::Database::new())) + } + } +} diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index d8884366b..d16ead910 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -1,9 +1,13 @@ #![allow(clippy::unnecessary_box_returns)] // Diplomat requires returning Boxed types +#![allow(clippy::should_implement_trait)] // Implementing extra traits is not useful for FFI pub mod connector; pub mod credssp; pub mod dvc; pub mod error; +pub mod graphics; +pub mod input; pub mod pdu; +pub mod session; pub mod svc; pub mod utils; diff --git a/ffi/src/pdu.rs b/ffi/src/pdu.rs index a7f887e6f..57bb11555 100644 --- a/ffi/src/pdu.rs +++ b/ffi/src/pdu.rs @@ -20,4 +20,42 @@ pub mod ffi { Ok(()) } } + + #[diplomat::opaque] + pub struct SecurityProtocol(pub ironrdp::pdu::nego::SecurityProtocol); + + #[diplomat::opaque] + pub struct ConnectInitial(pub ironrdp::pdu::mcs::ConnectInitial); + + #[diplomat::opaque] + pub struct InclusiveRectangle(pub ironrdp::pdu::geometry::InclusiveRectangle); + + #[diplomat::opaque] + pub struct IronRdpPdu; // A struct representing the ironrdp_pdu crate + + #[diplomat::opaque] + pub struct PduInfo(pub ironrdp::pdu::PduInfo); + + impl PduInfo { + pub fn get_action(&self) -> Box { + Box::new(Action(self.0.action)) + } + + pub fn get_length(&self) -> usize { + self.0.length + } + } + + #[diplomat::opaque] + pub struct Action(pub ironrdp::pdu::Action); + + impl IronRdpPdu { + pub fn new() -> Box { + Box::new(IronRdpPdu) + } + + pub fn find_size(&self, bytes: &[u8]) -> Result>, Box> { + Ok(ironrdp::pdu::find_size(bytes)?.map(PduInfo).map(Box::new)) + } + } } diff --git a/ffi/src/session/image.rs b/ffi/src/session/image.rs new file mode 100644 index 000000000..c8654e52e --- /dev/null +++ b/ffi/src/session/image.rs @@ -0,0 +1,42 @@ +#[diplomat::bridge] +pub mod ffi { + use crate::utils::ffi::BytesSlice; + + #[diplomat::opaque] + pub struct DecodedImage(pub ironrdp::session::image::DecodedImage); + + impl DecodedImage { + pub fn new(pixel_format: PixelFormat, width: u16, height: u16) -> Box { + Box::new(DecodedImage(ironrdp::session::image::DecodedImage::new( + pixel_format.into(), + width, + height, + ))) + } + + // The bytes array lives as long as the DecodedImage + pub fn get_data(&self) -> Box> { + Box::new(BytesSlice(self.0.data())) + } + + pub fn get_width(&self) -> u16 { + self.0.width() + } + + pub fn get_height(&self) -> u16 { + self.0.height() + } + } + + #[diplomat::enum_convert(ironrdp::graphics::image_processing::PixelFormat)] + pub enum PixelFormat { + ARgb32, + XRgb32, + ABgr32, + XBgr32, + BgrA32, + BgrX32, + RgbA32, + RgbX32, + } +} diff --git a/ffi/src/session/mod.rs b/ffi/src/session/mod.rs new file mode 100644 index 000000000..1ba65faae --- /dev/null +++ b/ffi/src/session/mod.rs @@ -0,0 +1,151 @@ +pub mod image; + +#[diplomat::bridge] +pub mod ffi { + + use crate::{ + connector::{ffi::ConnectionActivationSequence, result::ffi::ConnectionResult}, + error::{ffi::IronRdpError, IncorrectEnumTypeError, ValueConsumedError}, + graphics::ffi::DecodedPointer, + pdu::ffi::{Action, InclusiveRectangle}, + utils::ffi::{BytesSlice, Position}, + }; + + use super::image::ffi::DecodedImage; + + #[diplomat::opaque] + pub struct ActiveStage(pub ironrdp::session::ActiveStage); + + #[diplomat::opaque] + pub struct ActiveStageOutput(pub ironrdp::session::ActiveStageOutput); + + #[diplomat::opaque] + pub struct ActiveStageOutputIterator(pub Vec); + + impl ActiveStageOutputIterator { + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn next(&mut self) -> Option> { + self.0.pop().map(ActiveStageOutput).map(Box::new) + } + } + + impl ActiveStage { + pub fn new(connection_result: &mut ConnectionResult) -> Result, Box> { + Ok(Box::new(ActiveStage(ironrdp::session::ActiveStage::new( + connection_result + .0 + .take() + .ok_or_else(|| ValueConsumedError::for_item("connection_result"))?, + )))) + } + + pub fn process( + &mut self, + image: &mut DecodedImage, + action: &Action, + payload: &[u8], + ) -> Result, Box> { + let outputs = self.0.process(&mut image.0, action.0, payload)?; + Ok(Box::new(ActiveStageOutputIterator(outputs))) + } + } + + pub enum ActiveStageOutputType { + ResponseFrame, + GraphicsUpdate, + PointerDefault, + PointerHidden, + PointerPosition, + PointerBitmap, + Terminate, + DeactivateAll, + } + + impl ActiveStageOutput { + pub fn get_type(&self) -> ActiveStageOutputType { + match &self.0 { + ironrdp::session::ActiveStageOutput::ResponseFrame { .. } => ActiveStageOutputType::ResponseFrame, + ironrdp::session::ActiveStageOutput::GraphicsUpdate { .. } => ActiveStageOutputType::GraphicsUpdate, + ironrdp::session::ActiveStageOutput::PointerDefault { .. } => ActiveStageOutputType::PointerDefault, + ironrdp::session::ActiveStageOutput::PointerHidden { .. } => ActiveStageOutputType::PointerHidden, + ironrdp::session::ActiveStageOutput::PointerPosition { .. } => ActiveStageOutputType::PointerPosition, + ironrdp::session::ActiveStageOutput::PointerBitmap { .. } => ActiveStageOutputType::PointerBitmap, + ironrdp::session::ActiveStageOutput::Terminate { .. } => ActiveStageOutputType::Terminate, + ironrdp::session::ActiveStageOutput::DeactivateAll { .. } => ActiveStageOutputType::DeactivateAll, + } + } + + pub fn get_response_frame(&self) -> Result>, Box> { + match &self.0 { + ironrdp::session::ActiveStageOutput::ResponseFrame(frame) => Ok(Box::new(BytesSlice(frame))), + _ => Err(IncorrectEnumTypeError::on_variant("ResponseFrame") + .of_enum("ActiveStageOutput") + .into()), + } + } + + pub fn get_graphics_update(&self) -> Result, Box> { + match &self.0 { + ironrdp::session::ActiveStageOutput::GraphicsUpdate(rect) => { + Ok(Box::new(InclusiveRectangle(rect.clone()))) + } + _ => Err(IncorrectEnumTypeError::on_variant("GraphicsUpdate") + .of_enum("ActiveStageOutput") + .into()), + } + } + + pub fn get_pointer_position(&self) -> Result> { + match &self.0 { + ironrdp::session::ActiveStageOutput::PointerPosition { x, y } => Ok(Position { x: *x, y: *y }), + _ => Err(IncorrectEnumTypeError::on_variant("PointerPosition") + .of_enum("ActiveStageOutput") + .into()), + } + } + + pub fn get_pointer_bitmap(&self) -> Result, Box> { + match &self.0 { + ironrdp::session::ActiveStageOutput::PointerBitmap(decoded_pointer) => { + Ok(DecodedPointer(std::rc::Rc::clone(decoded_pointer))) + } + _ => Err(IncorrectEnumTypeError::on_variant("PointerBitmap") + .of_enum("ActiveStageOutput") + .into()), + } + .map(Box::new) + } + + pub fn get_terminate(&self) -> Result, Box> { + match &self.0 { + ironrdp::session::ActiveStageOutput::Terminate(reason) => Ok(GracefulDisconnectReason(*reason)), + _ => Err(IncorrectEnumTypeError::on_variant("Terminate") + .of_enum("ActiveStageOutput") + .into()), + } + .map(Box::new) + } + + pub fn get_deactivate_all(&self) -> Result, Box> { + match &self.0 { + ironrdp::session::ActiveStageOutput::DeactivateAll(cas) => { + Ok(ConnectionActivationSequence(cas.clone())) + } + _ => Err(IncorrectEnumTypeError::on_variant("DeactivateAll") + .of_enum("ActiveStageOutput") + .into()), + } + .map(Box::new) + } + } + + #[diplomat::opaque] + pub struct GracefulDisconnectReason(pub ironrdp::session::GracefulDisconnectReason); +} diff --git a/ffi/src/utils/mod.rs b/ffi/src/utils/mod.rs index 6ede3dae6..672c5653e 100644 --- a/ffi/src/utils/mod.rs +++ b/ffi/src/utils/mod.rs @@ -17,7 +17,7 @@ pub mod ffi { pub fn fill(&self, buffer: &mut [u8]) -> Result<(), Box> { if buffer.len() < self.0.len() { - return Err("Buffer is too small".into()); + return Err("buffer is too small".into()); } buffer.copy_from_slice(&self.0); Ok(()) @@ -28,6 +28,45 @@ pub mod ffi { } } + #[diplomat::opaque] + pub struct BytesSlice<'a>(pub &'a [u8]); + + impl<'a> BytesSlice<'a> { + pub fn get_size(&'a self) -> usize { + self.0.len() + } + + pub fn fill(&'a self, buffer: &'a mut [u8]) -> Result<(), Box> { + if buffer.len() < self.0.len() { + return Err("buffer is too small".into()); + } + buffer.copy_from_slice(self.0); + Ok(()) + } + } + + #[diplomat::opaque] + pub struct U32Slice<'a>(pub &'a [u32]); + + impl<'a> U32Slice<'a> { + pub fn get_size(&'a self) -> usize { + self.0.len() + } + + pub fn fill(&'a self, buffer: &'a mut [u32]) -> Result<(), Box> { + if buffer.len() < self.0.len() { + return Err("buffer is too small".into()); + } + buffer.copy_from_slice(self.0); + Ok(()) + } + } + + pub struct Position { + pub x: u16, + pub y: u16, + } + #[diplomat::opaque] pub struct OptionalUsize(pub Option); @@ -37,7 +76,7 @@ pub mod ffi { } pub fn get(&self) -> Result> { - self.0.ok_or_else(|| "Value is None".into()) + self.0.ok_or_else(|| "value is None".into()) } } }