From 65edebca2e04ac5acfd269d3c301607ddb3f97d1 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 11 Jun 2019 10:44:26 -0500 Subject: [PATCH] finished splitting up rdp functionality between classes --- mRemoteV1/Connection/Protocol/ProtocolBase.cs | 4 +- .../Connection/Protocol/ProtocolFactory.cs | 48 +++++++----------- .../Connection/Protocol/RDP/RdpProtocol10.cs | 15 ++++++ .../Connection/Protocol/RDP/RdpProtocol6.cs | 49 ++++++++++++++----- .../Connection/Protocol/RDP/RdpProtocol7.cs | 17 ++++--- .../Connection/Protocol/RDP/RdpProtocol8.cs | 18 +++---- .../Connection/Protocol/RDP/RdpProtocol9.cs | 15 ++++++ .../Protocol/RDP/RdpProtocolFactory.cs | 27 +++++++++- .../Connection/Protocol/RDP/RdpVersion.cs | 1 + mRemoteV1/mRemoteV1.csproj | 2 + 10 files changed, 133 insertions(+), 63 deletions(-) create mode 100644 mRemoteV1/Connection/Protocol/RDP/RdpProtocol10.cs create mode 100644 mRemoteV1/Connection/Protocol/RDP/RdpProtocol9.cs diff --git a/mRemoteV1/Connection/Protocol/ProtocolBase.cs b/mRemoteV1/Connection/Protocol/ProtocolBase.cs index b358c47dd..ba844cc20 100644 --- a/mRemoteV1/Connection/Protocol/ProtocolBase.cs +++ b/mRemoteV1/Connection/Protocol/ProtocolBase.cs @@ -110,7 +110,9 @@ namespace mRemoteNG.Connection.Protocol _interfaceControl.Parent.Tag = _interfaceControl; _interfaceControl.Show(); - if (Control == null) return true; + if (Control == null) + return false; + Control.Name = Name; Control.Parent = _interfaceControl; Control.Location = _interfaceControl.Location; diff --git a/mRemoteV1/Connection/Protocol/ProtocolFactory.cs b/mRemoteV1/Connection/Protocol/ProtocolFactory.cs index 6489eb400..114e93fd8 100644 --- a/mRemoteV1/Connection/Protocol/ProtocolFactory.cs +++ b/mRemoteV1/Connection/Protocol/ProtocolFactory.cs @@ -12,58 +12,46 @@ namespace mRemoteNG.Connection.Protocol { public class ProtocolFactory { + private readonly RdpProtocolFactory _rdpProtocolFactory = new RdpProtocolFactory(); + public ProtocolBase CreateProtocol(ConnectionInfo connectionInfo) { - var newProtocol = default(ProtocolBase); // ReSharper disable once SwitchStatementMissingSomeCases switch (connectionInfo.Protocol) { case ProtocolType.RDP: - newProtocol = new RdpProtocol6 - { - LoadBalanceInfoUseUtf8 = Settings.Default.RdpLoadBalanceInfoUseUtf8 - }; - ((RdpProtocol6)newProtocol).tmrReconnect.Elapsed += ((RdpProtocol6)newProtocol).tmrReconnect_Elapsed; - break; + var rdp = _rdpProtocolFactory.Build(connectionInfo.RdpProtocolVersion); + rdp.LoadBalanceInfoUseUtf8 = Settings.Default.RdpLoadBalanceInfoUseUtf8; + return rdp; case ProtocolType.VNC: - newProtocol = new ProtocolVNC(); - break; + return new ProtocolVNC(); case ProtocolType.SSH1: - newProtocol = new ProtocolSSH1(); - break; + return new ProtocolSSH1(); case ProtocolType.SSH2: - newProtocol = new ProtocolSSH2(); - break; + return new ProtocolSSH2(); case ProtocolType.Telnet: - newProtocol = new ProtocolTelnet(); - break; + return new ProtocolTelnet(); case ProtocolType.Rlogin: - newProtocol = new ProtocolRlogin(); - break; + return new ProtocolRlogin(); case ProtocolType.RAW: - newProtocol = new RawProtocol(); - break; + return new RawProtocol(); case ProtocolType.HTTP: - newProtocol = new ProtocolHTTP(connectionInfo.RenderingEngine); - break; + return new ProtocolHTTP(connectionInfo.RenderingEngine); case ProtocolType.HTTPS: - newProtocol = new ProtocolHTTPS(connectionInfo.RenderingEngine); - break; + return new ProtocolHTTPS(connectionInfo.RenderingEngine); case ProtocolType.ICA: - newProtocol = new IcaProtocol(); - ((IcaProtocol)newProtocol).tmrReconnect.Elapsed += ((IcaProtocol)newProtocol).tmrReconnect_Elapsed; - break; + var icaProtocol = new IcaProtocol(); + icaProtocol.tmrReconnect.Elapsed += icaProtocol.tmrReconnect_Elapsed; + return icaProtocol; case ProtocolType.IntApp: - newProtocol = new IntegratedProgram(); if (connectionInfo.ExtApp == "") { throw (new Exception(Language.strNoExtAppDefined)); } - - break; + return new IntegratedProgram(); } - return newProtocol; + return default(ProtocolBase); } } } \ No newline at end of file diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol10.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol10.cs new file mode 100644 index 000000000..4a73d8268 --- /dev/null +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol10.cs @@ -0,0 +1,15 @@ +using System.Windows.Forms; +using AxMSTSCLib; + +namespace mRemoteNG.Connection.Protocol.RDP +{ + public class RdpProtocol10 : RdpProtocol9 + { + protected override RdpVersion RdpProtocolVersion => RdpVersion.Rdc10; + + protected override AxHost CreateRdpClientControl() + { + return new AxMsRdpClient10NotSafeForScripting(); + } + } +} diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol6.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol6.cs index ba134c6b5..f3c3e945a 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol6.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol6.cs @@ -1,7 +1,8 @@ using System; using System.Diagnostics; -using System.Drawing; +using System.Runtime.InteropServices; using System.Threading; +using System.Timers; using System.Windows.Forms; using AxMSTSCLib; using mRemoteNG.App; @@ -24,14 +25,15 @@ namespace mRemoteNG.Connection.Protocol.RDP * * Windows 8+ support RDP v8 out of the box. */ - protected MsRdpClient6NotSafeForScripting _rdpClient; - private Version _rdpVersion; + private MsRdpClient6NotSafeForScripting _rdpClient; protected ConnectionInfo connectionInfo; protected bool loginComplete; + private Version _rdpVersion; private bool _redirectKeys; private bool _alertOnIdleDisconnect; private readonly DisplayProperties _displayProperties; private readonly FrmMain _frmMain = FrmMain.Default; + protected virtual RdpVersion RdpProtocolVersion => RdpVersion.Rdc6; private AxHost AxHost => (AxHost)Control; #region Properties @@ -98,8 +100,8 @@ namespace mRemoteNG.Connection.Protocol.RDP public RdpProtocol6() { _displayProperties = new DisplayProperties(); - Control = new AxMsRdpClient6NotSafeForScripting(); Connecting += OnConnectingDebugMessage; + tmrReconnect.Elapsed += tmrReconnect_Elapsed; } #endregion @@ -108,10 +110,11 @@ namespace mRemoteNG.Connection.Protocol.RDP private void OnConnectingDebugMessage(object sender) { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Using RDP version: {connectionInfo.RdpProtocolVersion}"); + Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, + $"Requesting RDP version: {connectionInfo.RdpProtocolVersion}. Using: {RdpProtocolVersion}"); } - protected virtual object CreateRdpClientControl() + protected virtual AxHost CreateRdpClientControl() { return new AxMsRdpClient6NotSafeForScripting(); } @@ -119,6 +122,7 @@ namespace mRemoteNG.Connection.Protocol.RDP public override bool Initialize() { + Control = CreateRdpClientControl(); base.Initialize(); try { @@ -134,9 +138,9 @@ namespace mRemoteNG.Connection.Protocol.RDP Application.DoEvents(); } - _rdpClient = (MsRdpClient6NotSafeForScripting)CreateRdpClientControl(); + _rdpClient = (MsRdpClient6NotSafeForScripting)((AxHost)Control).GetOcx(); } - catch (System.Runtime.InteropServices.COMException ex) + catch (COMException ex) { Runtime.MessageCollector.AddExceptionMessage(Language.strRdpControlCreationFailed, ex); Control.Dispose(); @@ -283,6 +287,27 @@ namespace mRemoteNG.Connection.Protocol.RDP Runtime.MessageCollector.AddExceptionStackTrace(Language.strRdpFocusFailed, ex); } } + + /// + /// Determines if this version of the RDP client + /// is supported on this machine. + /// + /// + public bool IsRdpVersionSupported() + { + try + { + using (var control = CreateRdpClientControl()) + { + control.CreateControl(); + return true; + } + } + catch (COMException ex) + { + return false; + } + } #endregion #region Private Methods @@ -749,11 +774,12 @@ namespace mRemoteNG.Connection.Protocol.RDP public static readonly Version RDC70 = new Version(6, 1, 7600); public static readonly Version RDC80 = new Version(6, 2, 9200); public static readonly Version RDC81 = new Version(6, 3, 9600); + public static readonly Version RDC100 = new Version(10, 0, 0); } #region Reconnect Stuff - public void tmrReconnect_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + public void tmrReconnect_Elapsed(object sender, ElapsedEventArgs e) { try { @@ -770,9 +796,8 @@ namespace mRemoteNG.Connection.Protocol.RDP catch (Exception ex) { Runtime.MessageCollector.AddExceptionMessage( - string.Format(Language.AutomaticReconnectError, - connectionInfo.Hostname), - ex, MessageClass.WarningMsg, false); + string.Format(Language.AutomaticReconnectError, connectionInfo.Hostname), + ex, MessageClass.WarningMsg, false); } } diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol7.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol7.cs index 5496d47b6..f65567981 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol7.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol7.cs @@ -2,20 +2,24 @@ using mRemoteNG.App; using MSTSCLib; using System; +using System.Windows.Forms; namespace mRemoteNG.Connection.Protocol.RDP { public class RdpProtocol7 : RdpProtocol6 { - private new MsRdpClient7NotSafeForScripting _rdpClient; + protected override RdpVersion RdpProtocolVersion => RdpVersion.Rdc7; public override bool Initialize() { - base.Initialize(); + if (!base.Initialize()) + return false; + try { - _rdpClient.AdvancedSettings8.AudioQualityMode = (uint)connectionInfo.SoundQuality; - _rdpClient.AdvancedSettings8.AudioCaptureRedirectionMode = connectionInfo.RedirectAudioCapture; + var rdpClient7 = (MsRdpClient7NotSafeForScripting)((AxHost) Control).GetOcx(); + rdpClient7.AdvancedSettings8.AudioQualityMode = (uint)connectionInfo.SoundQuality; + rdpClient7.AdvancedSettings8.AudioCaptureRedirectionMode = connectionInfo.RedirectAudioCapture; } catch (Exception ex) { @@ -26,10 +30,9 @@ namespace mRemoteNG.Connection.Protocol.RDP return true; } - protected override object CreateRdpClientControl() + protected override AxHost CreateRdpClientControl() { - _rdpClient = (MsRdpClient7NotSafeForScripting)((AxMsRdpClient7NotSafeForScripting)Control).GetOcx(); - return _rdpClient; + return new AxMsRdpClient7NotSafeForScripting(); } } } diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol8.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol8.cs index 0cc56e2a7..573201412 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol8.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol8.cs @@ -17,12 +17,14 @@ namespace mRemoteNG.Connection.Protocol.RDP */ public class RdpProtocol8 : RdpProtocol7 { - private new MsRdpClient8NotSafeForScripting _rdpClient; + private MsRdpClient8NotSafeForScripting RdpClient8 => (MsRdpClient8NotSafeForScripting)((AxHost)Control).GetOcx(); private Size _controlBeginningSize; + protected override RdpVersion RdpProtocolVersion => RdpVersion.Rdc8; + public override bool SmartSize { - get { return base.SmartSize; } + get => base.SmartSize; protected set { base.SmartSize = value; @@ -40,11 +42,6 @@ namespace mRemoteNG.Connection.Protocol.RDP } } - public RdpProtocol8() - { - Control = new AxMsRdpClient8NotSafeForScripting(); - } - public override void ResizeBegin(object sender, EventArgs e) { _controlBeginningSize = Control.Size; @@ -69,10 +66,9 @@ namespace mRemoteNG.Connection.Protocol.RDP _controlBeginningSize = Size.Empty; } - protected override object CreateRdpClientControl() + protected override AxHost CreateRdpClientControl() { - _rdpClient = (MsRdpClient8NotSafeForScripting)((AxMsRdpClient8NotSafeForScripting)Control).GetOcx(); - return _rdpClient; + return new AxMsRdpClient8NotSafeForScripting(); } private void ReconnectForResize() @@ -98,7 +94,7 @@ namespace mRemoteNG.Connection.Protocol.RDP var size = Fullscreen ? Screen.FromControl(Control).Bounds.Size : Control.Size; - _rdpClient.Reconnect((uint)size.Width, (uint)size.Height); + RdpClient8.Reconnect((uint)size.Width, (uint)size.Height); } catch (Exception ex) { diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol9.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol9.cs new file mode 100644 index 000000000..1727e9b93 --- /dev/null +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol9.cs @@ -0,0 +1,15 @@ +using System.Windows.Forms; +using AxMSTSCLib; + +namespace mRemoteNG.Connection.Protocol.RDP +{ + public class RdpProtocol9 : RdpProtocol8 + { + protected override RdpVersion RdpProtocolVersion => RdpVersion.Rdc9; + + protected override AxHost CreateRdpClientControl() + { + return new AxMsRdpClient9NotSafeForScripting(); + } + } +} diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocolFactory.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocolFactory.cs index 7d495b314..18dc07027 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocolFactory.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocolFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace mRemoteNG.Connection.Protocol.RDP { @@ -8,16 +9,38 @@ namespace mRemoteNG.Connection.Protocol.RDP { switch (rdpVersion) { + case RdpVersion.Highest: + return BuildHighestSupportedVersion(); case RdpVersion.Rdc6: return new RdpProtocol6(); case RdpVersion.Rdc7: + return new RdpProtocol7(); case RdpVersion.Rdc8: - case RdpVersion.Rdc9: - case RdpVersion.Rdc10: return new RdpProtocol8(); + case RdpVersion.Rdc9: + return new RdpProtocol9(); + case RdpVersion.Rdc10: + return new RdpProtocol10(); default: throw new ArgumentOutOfRangeException(nameof(rdpVersion), rdpVersion, null); } } + + private RdpProtocol6 BuildHighestSupportedVersion() + { + var versions = Enum.GetValues(typeof(RdpVersion)) + .OfType() + .Except(new[] { RdpVersion.Highest }) + .Reverse(); + + foreach (var version in versions) + { + var rdp = Build(version); + if (rdp.RdpVersionSupported()) + return rdp; + } + + throw new ArgumentOutOfRangeException(); + } } } diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpVersion.cs b/mRemoteV1/Connection/Protocol/RDP/RdpVersion.cs index 34d1efaeb..f0ede61c6 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpVersion.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpVersion.cs @@ -7,5 +7,6 @@ Rdc8, Rdc9, Rdc10, + Highest = 1000 } } diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 7f5e9a6e7..bad108213 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -261,8 +261,10 @@ + +