mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
refactor(ffi): ISequence interface for sequences (#475)
It’s possible to implement interfaces even on FFI types, because
they are declared as partials.
```csharp
public partial class MySequence : ISequence {}
```
So long as the type exposes the required functions, this one-liner
is enough.
This commit is contained in:
@@ -416,11 +416,7 @@ public partial class MainWindow : Window
|
||||
var writeBuf = WriteBuf.New();
|
||||
while (true)
|
||||
{
|
||||
var written = await Connection.SingleSequenceStepRead(_framed!, activationSequence, writeBuf);
|
||||
if (written.GetSize().IsSome())
|
||||
{
|
||||
await _framed!.Write(writeBuf);
|
||||
}
|
||||
await Connection.SingleSequenceStep(activationSequence, writeBuf,_framed!);
|
||||
|
||||
if (activationSequence.GetState().GetType() != ConnectionActivationStateType.Finalized)
|
||||
continue;
|
||||
|
||||
@@ -13,10 +13,13 @@ class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
InitializeLogging();
|
||||
try{
|
||||
try
|
||||
{
|
||||
BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
}catch(Exception e){
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Trace.TraceError(e.Message);
|
||||
Trace.TraceError(e.StackTrace);
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ public struct DiplomatWriteable : IDisposable
|
||||
|
||||
IntPtr flushFuncPtr = Marshal.GetFunctionPointerForDelegate(flushFunc);
|
||||
IntPtr growFuncPtr = Marshal.GetFunctionPointerForDelegate(growFunc);
|
||||
|
||||
|
||||
// flushFunc and growFunc are managed objects and might be disposed of by the garbage collector.
|
||||
// To prevent this, we make the context hold the references and protect the context itself
|
||||
// for automatic disposal by moving it behind a GCHandle.
|
||||
DiplomatWriteableContext ctx = new DiplomatWriteableContext();
|
||||
DiplomatWriteableContext ctx = new DiplomatWriteableContext();
|
||||
ctx.flushFunc = flushFunc;
|
||||
ctx.growFunc = growFunc;
|
||||
GCHandle ctxHandle = GCHandle.Alloc(ctx);
|
||||
@@ -81,7 +81,7 @@ public struct DiplomatWriteable : IDisposable
|
||||
{
|
||||
throw new IndexOutOfRangeException("DiplomatWriteable buffer is too big");
|
||||
}
|
||||
return Marshal.PtrToStringUTF8(buf, (int) len);
|
||||
return Marshal.PtrToStringUTF8(buf, (int)len);
|
||||
#else
|
||||
byte[] utf8 = ToUtf8Bytes();
|
||||
return DiplomatUtils.Utf8ToString(utf8);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
public partial class ClientConnector : ISequence
|
||||
{
|
||||
}
|
||||
@@ -29,32 +29,12 @@ public static class Connection
|
||||
var cliprdr = factory.BuildCliprdr();
|
||||
connector.AttachStaticCliprdr(cliprdr);
|
||||
}
|
||||
|
||||
|
||||
await ConnectBegin(framed, connector);
|
||||
var (serverPublicKey, framedSsl) = await SecurityUpgrade(framed, connector);
|
||||
var result = await ConnectFinalize(serverName, connector, serverPublicKey, framedSsl);
|
||||
return (result, framedSsl);
|
||||
}
|
||||
|
||||
public static async Task<Written> SingleSequenceStepRead<TStream>(Framed<TStream> frame, ConnectionActivationSequence sequence, WriteBuf buf)
|
||||
where TStream: Stream
|
||||
{
|
||||
buf.Clear();
|
||||
|
||||
var pduHint = sequence.NextPduHint();
|
||||
|
||||
// FIXME: The NextPduHint() function signature is incorrectly generated: the return value is nullable, so this check is necessary.
|
||||
if (null != pduHint)
|
||||
{
|
||||
|
||||
var pdu = await frame.ReadByHint(pduHint);
|
||||
|
||||
return sequence.Step(pdu, buf);
|
||||
}
|
||||
|
||||
|
||||
return sequence.StepNoInput(buf);
|
||||
}
|
||||
|
||||
private static async Task<(byte[], Framed<SslStream>)> SecurityUpgrade(Framed<NetworkStream> framed,
|
||||
ClientConnector connector)
|
||||
@@ -82,7 +62,7 @@ public static class Connection
|
||||
var writeBuf = WriteBuf.New();
|
||||
while (!connector.ShouldPerformSecurityUpgrade())
|
||||
{
|
||||
await SingleConnectStep(connector, writeBuf, framed);
|
||||
await SingleSequenceStep(connector, writeBuf, framed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +78,7 @@ public static class Connection
|
||||
|
||||
while (!connector.GetDynState().IsTerminal())
|
||||
{
|
||||
await SingleConnectStep(connector, writeBuf2, framedSsl);
|
||||
await SingleSequenceStep(connector, writeBuf2, framedSsl);
|
||||
}
|
||||
|
||||
ClientConnectorState state = connector.ConsumeAndCastToClientConnectorState();
|
||||
@@ -196,23 +176,23 @@ public static class Connection
|
||||
}
|
||||
}
|
||||
|
||||
static async Task SingleConnectStep<T>(ClientConnector connector, WriteBuf buf, Framed<T> framed)
|
||||
public static async Task SingleSequenceStep<S, T>(S sequence, WriteBuf buf, Framed<T> framed)
|
||||
where T : Stream
|
||||
where S : ISequence
|
||||
{
|
||||
buf.Clear();
|
||||
|
||||
var pduHint = connector.NextPduHint();
|
||||
var pduHint = sequence.NextPduHint();
|
||||
Written written;
|
||||
|
||||
// Don't remove, NextPduHint is generated, and it can return null
|
||||
if (pduHint != null)
|
||||
{
|
||||
byte[] pdu = await framed.ReadByHint(pduHint);
|
||||
written = connector.Step(pdu, buf);
|
||||
written = sequence.Step(pdu, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
written = connector.StepNoInput(buf);
|
||||
written = sequence.StepNoInput(buf);
|
||||
}
|
||||
|
||||
if (written.GetWrittenType() == WrittenType.Nothing)
|
||||
@@ -220,7 +200,7 @@ public static class Connection
|
||||
return;
|
||||
}
|
||||
|
||||
// will throw if size is not set
|
||||
// Will throw an exception if the size is not set.
|
||||
var size = written.GetSize().Get();
|
||||
|
||||
var response = new byte[size];
|
||||
@@ -263,4 +243,4 @@ public static class Utils
|
||||
vecU8.Fill(buffer);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
public partial class ConnectionActivationSequence : ISequence
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
public interface ISequence
|
||||
{
|
||||
PduHint? NextPduHint();
|
||||
Written Step(byte[] pduHint, WriteBuf buf);
|
||||
Written StepNoInput(WriteBuf buf);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user