diff --git a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs index 90f8e0cfe..144695aa3 100644 --- a/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs +++ b/mRemoteNG/Connection/Protocol/RDP/RdpProtocol.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Timers; @@ -15,14 +16,13 @@ using mRemoteNG.UI.Forms; using mRemoteNG.UI.Tabs; using MSTSCLib; using mRemoteNG.Resources.Language; -using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; -using System.DirectoryServices.ActiveDirectory; using System.Runtime.Versioning; +using FileDialog = Microsoft.Win32.FileDialog; namespace mRemoteNG.Connection.Protocol.RDP { [SupportedOSPlatform("windows")] - public class RdpProtocol6 : ProtocolBase, ISupportsViewOnly + public class RdpProtocol : ProtocolBase, ISupportsViewOnly { /* RDP v8 requires Windows 7 with: * https://support.microsoft.com/en-us/kb/2592687 @@ -31,17 +31,22 @@ namespace mRemoteNG.Connection.Protocol.RDP * * Windows 8+ support RDP v8 out of the box. */ - private MsRdpClient6NotSafeForScripting _rdpClient; + + private MsRdpClient6NotSafeForScripting _rdpClient; // lowest version supported + protected virtual RdpVersion RdpProtocolVersion => RDP.RdpVersion.Rdc6; protected ConnectionInfo connectionInfo; + protected Version RdpVersion; + private readonly DisplayProperties _displayProperties; + protected readonly FrmMain _frmMain = FrmMain.Default; 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; + protected uint DesktopScaleFactor => (uint)(_displayProperties.ResolutionScalingFactor.Width * 100); + protected readonly uint DeviceScaleFactor = 100; + protected readonly uint Orientation = 0; private AxHost AxHost => (AxHost)Control; + #region Properties public virtual bool SmartSize @@ -58,12 +63,6 @@ namespace mRemoteNG.Connection.Protocol.RDP private bool RedirectKeys { -/* - get - { - return _redirectKeys; - } -*/ set { _redirectKeys = value; @@ -75,7 +74,7 @@ namespace mRemoteNG.Connection.Protocol.RDP } Debug.Assert(Convert.ToBoolean(_rdpClient.SecuredSettingsEnabled)); - var msRdpClientSecuredSettings = _rdpClient.SecuredSettings2; + IMsRdpClientSecuredSettings msRdpClientSecuredSettings = _rdpClient.SecuredSettings2; msRdpClientSecuredSettings.KeyboardHookMode = 1; // Apply key combinations at the remote server. } catch (Exception ex) @@ -97,7 +96,7 @@ namespace mRemoteNG.Connection.Protocol.RDP #region Constructors - public RdpProtocol6() + public RdpProtocol() { _displayProperties = new DisplayProperties(); tmrReconnect.Elapsed += tmrReconnect_Elapsed; @@ -106,27 +105,29 @@ namespace mRemoteNG.Connection.Protocol.RDP #endregion #region Public Methods + protected virtual AxHost CreateActiveXRdpClientControl() { return new AxMsRdpClient6NotSafeForScripting(); } - public override bool Initialize() { connectionInfo = InterfaceControl.Info; - Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, - $"Requesting RDP version: {connectionInfo.RdpVersion}. Using: {RdpProtocolVersion}"); + Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Requesting RDP version: {connectionInfo.RdpVersion}. Using: {RdpProtocolVersion}"); Control = CreateActiveXRdpClientControl(); base.Initialize(); try { - if (!InitializeActiveXControl()) - return false; + if (!InitializeActiveXControl()) return false; + + RdpVersion = new Version(_rdpClient.Version); + + if (RdpVersion < Versions.RDC61) return false; // only RDP versions 6.1 and greater are supported; minimum dll version checked, MSTSCLIB is not capable - _rdpVersion = new Version(_rdpClient.Version); SetRdpClientProperties(); + return true; } catch (Exception ex) @@ -141,23 +142,25 @@ namespace mRemoteNG.Connection.Protocol.RDP try { Control.GotFocus += RdpClient_GotFocus; + Control.CreateControl(); + while (!Control.Created) { - Thread.Sleep(0); + Thread.Sleep(50); Application.DoEvents(); } Control.Anchor = AnchorStyles.None; _rdpClient = (MsRdpClient6NotSafeForScripting)((AxHost)Control).GetOcx(); + return true; } catch (COMException ex) { if (ex.Message.Contains("CLASS_E_CLASSNOTAVAILABLE")) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, - string.Format(Language.RdpProtocolVersionNotSupported, connectionInfo.RdpVersion)); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.RdpProtocolVersionNotSupported, connectionInfo.RdpVersion)); } else { @@ -265,11 +268,9 @@ namespace mRemoteNG.Connection.Protocol.RDP { try { - using (var control = CreateActiveXRdpClientControl()) - { - control.CreateControl(); - return true; - } + using var control = CreateActiveXRdpClientControl(); + control.CreateControl(); + return true; } catch { @@ -280,8 +281,21 @@ namespace mRemoteNG.Connection.Protocol.RDP #region Private Methods + protected static class Versions + { + // https://en.wikipedia.org/wiki/Remote_Desktop_Protocol + public static readonly Version RDC60 = new Version(6, 0, 6000); + public static readonly Version RDC61 = new Version(6, 0, 6001); + 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); + } + private void SetRdpClientProperties() { + // https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/rdp-files + _rdpClient.Server = connectionInfo.Hostname; SetCredentials(); @@ -307,21 +321,12 @@ namespace mRemoteNG.Connection.Protocol.RDP _rdpClient.AdvancedSettings2.overallConnectionTimeout = Settings.Default.ConRDPOverallConnectionTimeout; _rdpClient.AdvancedSettings2.BitmapPeristence = Convert.ToInt32(connectionInfo.CacheBitmaps); - if (_rdpVersion >= Versions.RDC61) + + if (RdpVersion >= Versions.RDC61) { _rdpClient.AdvancedSettings7.EnableCredSspSupport = connectionInfo.UseCredSsp; } - if(_rdpVersion >= Versions.RDC81) - { - if (connectionInfo.UseRestrictedAdmin) - SetExtendedProperty("RestrictedLogon", true); - else if (connectionInfo.UseRCG) - { - SetExtendedProperty("DisableCredentialsDelegation", true); - SetExtendedProperty("RedirectedAuthentication", true); - } - } - + SetUseConsoleSession(); SetPort(); RedirectKeys = connectionInfo.RedirectKeys; @@ -345,10 +350,9 @@ namespace mRemoteNG.Connection.Protocol.RDP // ReSharper disable once UseIndexedProperty return ((IMsRdpExtendedSettings)_rdpClient).get_Property(property); } - catch (Exception e) + catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage($"Error getting extended RDP property '{property}'", - e, MessageClass.WarningMsg, false); + Runtime.MessageCollector.AddExceptionMessage($"Error getting extended RDP property '{property}'", ex, MessageClass.WarningMsg, false); return null; } } @@ -360,10 +364,9 @@ namespace mRemoteNG.Connection.Protocol.RDP // ReSharper disable once UseIndexedProperty ((IMsRdpExtendedSettings)_rdpClient).set_Property(property, ref value); } - catch (Exception e) + catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage($"Error setting extended RDP property '{property}'", - e, MessageClass.WarningMsg, false); + Runtime.MessageCollector.AddExceptionMessage($"Error setting extended RDP property '{property}'", ex, MessageClass.WarningMsg, false); } } @@ -373,63 +376,62 @@ namespace mRemoteNG.Connection.Protocol.RDP { if (_rdpClient.TransportSettings.GatewayIsSupported == 0) { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayNotSupported, - true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayNotSupported, true); return; } - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayIsSupported, - true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayIsSupported, true); - if (connectionInfo.RDGatewayUsageMethod != RDGatewayUsageMethod.Never) + if (connectionInfo.RDGatewayUsageMethod == RDGatewayUsageMethod.Never) return; + + // USE GATEWAY + _rdpClient.TransportSettings.GatewayUsageMethod = (uint)connectionInfo.RDGatewayUsageMethod; + _rdpClient.TransportSettings.GatewayHostname = connectionInfo.RDGatewayHostname; + _rdpClient.TransportSettings.GatewayProfileUsageMethod = 1; // TSC_PROXY_PROFILE_MODE_EXPLICIT + if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard) { - _rdpClient.TransportSettings.GatewayUsageMethod = (uint)connectionInfo.RDGatewayUsageMethod; - _rdpClient.TransportSettings.GatewayHostname = connectionInfo.RDGatewayHostname; - _rdpClient.TransportSettings.GatewayProfileUsageMethod = 1; // TSC_PROXY_PROFILE_MODE_EXPLICIT - if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard) + _rdpClient.TransportSettings.GatewayCredsSource = 1; // TSC_PROXY_CREDS_MODE_SMARTCARD + } + + if (RdpVersion < Versions.RDC61 || Force.HasFlag(ConnectionInfo.Force.NoCredentials)) return; + + switch (connectionInfo.RDGatewayUseConnectionCredentials) + { + case RDGatewayUseConnectionCredentials.Yes: + _rdpClient.TransportSettings2.GatewayUsername = connectionInfo.Username; + _rdpClient.TransportSettings2.GatewayPassword = connectionInfo.Password; + _rdpClient.TransportSettings2.GatewayDomain = connectionInfo?.Domain; + break; + case RDGatewayUseConnectionCredentials.SmartCard: + _rdpClient.TransportSettings2.GatewayCredSharing = 0; + break; + default: { - _rdpClient.TransportSettings.GatewayCredsSource = 1; // TSC_PROXY_CREDS_MODE_SMARTCARD - } + _rdpClient.TransportSettings2.GatewayCredSharing = 0; - if (_rdpVersion >= Versions.RDC61 && !Force.HasFlag(ConnectionInfo.Force.NoCredentials)) - { - if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.Yes) - { - _rdpClient.TransportSettings2.GatewayUsername = connectionInfo.Username; - _rdpClient.TransportSettings2.GatewayPassword = connectionInfo.Password; - _rdpClient.TransportSettings2.GatewayDomain = connectionInfo?.Domain; - } - else if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard) - { - _rdpClient.TransportSettings2.GatewayCredSharing = 0; - } - else - { - _rdpClient.TransportSettings2.GatewayCredSharing = 0; + var gwu = connectionInfo.RDGatewayUsername; + var gwp = connectionInfo.RDGatewayPassword; + var gwd = connectionInfo.RDGatewayDomain; + var pkey = ""; - string gwu = connectionInfo.RDGatewayUsername; - string gwp = connectionInfo.RDGatewayPassword; - string gwd = connectionInfo.RDGatewayDomain; - string pkey = ""; - - // access secret server api if necessary - if (InterfaceControl.Info.RDGatewayExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer) + // access secret server api if necessary + if (InterfaceControl.Info.RDGatewayExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer) + { + try { - try - { - string RDGUserViaAPI = InterfaceControl.Info.RDGatewayUserViaAPI; - ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{RDGUserViaAPI}", out gwu, out gwp, out gwd, out pkey); - } - catch (Exception ex) - { - Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0); - } - + string RDGUserViaAPI = InterfaceControl.Info.RDGatewayUserViaAPI; + ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{RDGUserViaAPI}", out gwu, out gwp, out gwd, out pkey); } - _rdpClient.TransportSettings2.GatewayUsername = gwu; - _rdpClient.TransportSettings2.GatewayPassword = gwp; - _rdpClient.TransportSettings2.GatewayDomain = gwd; + catch (Exception ex) + { + Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0); + } + } + _rdpClient.TransportSettings2.GatewayUsername = gwu; + _rdpClient.TransportSettings2.GatewayPassword = gwp; + _rdpClient.TransportSettings2.GatewayDomain = gwd; + break; } } } @@ -458,20 +460,14 @@ namespace mRemoteNG.Connection.Protocol.RDP value = connectionInfo.UseConsoleSession; } - if (_rdpVersion >= Versions.RDC61) + if (RdpVersion >= Versions.RDC61) { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, - string.Format(Language.RdpSetConsoleSwitch, _rdpVersion), - true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.RdpSetConsoleSwitch, RdpVersion), true); _rdpClient.AdvancedSettings7.ConnectToAdministerServer = value; } else { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, - string.Format(Language.RdpSetConsoleSwitch, _rdpVersion) + - Environment.NewLine + - "No longer supported in this RDP version. Reference: https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx", - true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"{string.Format(Language.RdpSetConsoleSwitch, RdpVersion)}{Environment.NewLine}No longer supported in this RDP version. Reference: https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx", true); // ConnectToServerConsole is deprecated //https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx //_rdpClient.AdvancedSettings2.ConnectToServerConsole = value; @@ -495,21 +491,21 @@ namespace mRemoteNG.Connection.Protocol.RDP var userName = connectionInfo?.Username ?? ""; var password = connectionInfo?.Password ?? ""; var domain = connectionInfo?.Domain ?? ""; - var UserViaAPI = connectionInfo?.UserViaAPI ?? ""; - string pkey = ""; + var userViaApi = connectionInfo?.UserViaAPI ?? ""; + var pkey = ""; // access secret server api if necessary if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer) { try { - ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out userName, out password, out domain, out pkey); + ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{userViaApi}", out userName, out password, out domain, out pkey); } catch (Exception ex) { Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0); } - + } if (string.IsNullOrEmpty(userName)) @@ -581,9 +577,8 @@ namespace mRemoteNG.Connection.Protocol.RDP { try { - var scaleFactor = (uint)(_displayProperties.ResolutionScalingFactor.Width * 100); - SetExtendedProperty("DesktopScaleFactor", scaleFactor); - SetExtendedProperty("DeviceScaleFactor", (uint)100); + SetExtendedProperty("DesktopScaleFactor", DesktopScaleFactor); + SetExtendedProperty("DeviceScaleFactor", DeviceScaleFactor); if (Force.HasFlag(ConnectionInfo.Force.Fullscreen)) { @@ -594,28 +589,33 @@ namespace mRemoteNG.Connection.Protocol.RDP return; } - if (InterfaceControl.Info.Resolution == RDPResolutions.FitToWindow || - InterfaceControl.Info.Resolution == RDPResolutions.SmartSize) + switch (InterfaceControl.Info.Resolution) { - _rdpClient.DesktopWidth = InterfaceControl.Size.Width; - _rdpClient.DesktopHeight = InterfaceControl.Size.Height; + case RDPResolutions.FitToWindow: + case RDPResolutions.SmartSize: + { + _rdpClient.DesktopWidth = InterfaceControl.Size.Width; + _rdpClient.DesktopHeight = InterfaceControl.Size.Height; - if (InterfaceControl.Info.Resolution == RDPResolutions.SmartSize) - { - _rdpClient.AdvancedSettings2.SmartSizing = true; - } - } - else if (InterfaceControl.Info.Resolution == RDPResolutions.Fullscreen) - { - _rdpClient.FullScreen = true; - _rdpClient.DesktopWidth = Screen.FromControl(_frmMain).Bounds.Width; - _rdpClient.DesktopHeight = Screen.FromControl(_frmMain).Bounds.Height; - } - else - { - var resolution = connectionInfo.Resolution.GetResolutionRectangle(); - _rdpClient.DesktopWidth = resolution.Width; - _rdpClient.DesktopHeight = resolution.Height; + if (InterfaceControl.Info.Resolution == RDPResolutions.SmartSize) + { + _rdpClient.AdvancedSettings2.SmartSizing = true; + } + + break; + } + case RDPResolutions.Fullscreen: + _rdpClient.FullScreen = true; + _rdpClient.DesktopWidth = Screen.FromControl(_frmMain).Bounds.Width; + _rdpClient.DesktopHeight = Screen.FromControl(_frmMain).Bounds.Height; + break; + default: + { + var resolution = connectionInfo.Resolution.GetResolutionRectangle(); + _rdpClient.DesktopWidth = resolution.Width; + _rdpClient.DesktopHeight = resolution.Height; + break; + } } } catch (Exception ex) @@ -643,7 +643,7 @@ namespace mRemoteNG.Connection.Protocol.RDP { try { - _rdpClient.AdvancedSettings2.RedirectDrives = connectionInfo.RedirectDiskDrives; + SetDriveRedirection(); _rdpClient.AdvancedSettings2.RedirectPorts = connectionInfo.RedirectPorts; _rdpClient.AdvancedSettings2.RedirectPrinters = connectionInfo.RedirectPrinters; _rdpClient.AdvancedSettings2.RedirectSmartCards = connectionInfo.RedirectSmartCards; @@ -656,6 +656,46 @@ namespace mRemoteNG.Connection.Protocol.RDP } } + private void SetDriveRedirection() + { + if (RDPDiskDrives.None == connectionInfo.RedirectDiskDrives) + _rdpClient.AdvancedSettings2.RedirectDrives = false; + else if (RDPDiskDrives.All == connectionInfo.RedirectDiskDrives) + _rdpClient.AdvancedSettings2.RedirectDrives = true; + else if (RDPDiskDrives.Custom == connectionInfo.RedirectDiskDrives) + { + var rdpNS5 = (IMsRdpClientNonScriptable5)((AxHost)Control).GetOcx(); + for (uint i = 0; i < rdpNS5.DriveCollection.DriveCount; i++) + { + IMsRdpDrive drive = rdpNS5.DriveCollection.DriveByIndex[i]; + drive.RedirectionState = connectionInfo.RedirectDiskDrivesCustom.Contains(drive.Name.Substring(0, 1)); + } + } + else + { + // Local Drives + var rdpNS5 = (IMsRdpClientNonScriptable5)((AxHost)Control).GetOcx(); + for (uint i = 0; i < rdpNS5.DriveCollection.DriveCount; i++) + { + IMsRdpDrive drive = rdpNS5.DriveCollection.DriveByIndex[i]; + drive.RedirectionState = IsLocal(drive); + } + } + } + + private bool IsLocal(IMsRdpDrive drive) + { + DriveInfo[] myDrives = DriveInfo.GetDrives(); + foreach (DriveInfo myDrive in myDrives) + { + if (myDrive.Name.Substring(0, 1).Equals(drive.Name.Substring(0,1))) + { + return myDrive.DriveType == DriveType.Fixed; + } + } + return false; + } + private void SetPerformanceFlags() { try @@ -724,7 +764,7 @@ namespace mRemoteNG.Connection.Protocol.RDP } } - private void SetEventHandlers() + protected virtual void SetEventHandlers() { try { @@ -733,15 +773,15 @@ namespace mRemoteNG.Connection.Protocol.RDP _rdpClient.OnLoginComplete += RDPEvent_OnLoginComplete; _rdpClient.OnFatalError += RDPEvent_OnFatalError; _rdpClient.OnDisconnected += RDPEvent_OnDisconnected; - _rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode; _rdpClient.OnIdleTimeoutNotification += RDPEvent_OnIdleTimeoutNotification; + _rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode; } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace(Language.RdpSetEventHandlersFailed, ex); } } - + #endregion #region Private Events & Handlers @@ -751,11 +791,9 @@ namespace mRemoteNG.Connection.Protocol.RDP Close(); //Simply close the RDP Session if the idle timeout has been triggered. if (!_alertOnIdleDisconnect) return; - MessageBox.Show($"The {connectionInfo.Name} session was disconnected due to inactivity", - "Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show($@"The {connectionInfo.Name} session was disconnected due to inactivity", @"Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information); } - private void RDPEvent_OnFatalError(int errorCode) { var errorMsg = RdpErrorCodes.GetError(errorCode); @@ -767,8 +805,7 @@ namespace mRemoteNG.Connection.Protocol.RDP const int UI_ERR_NORMAL_DISCONNECT = 0xB08; if (discReason != UI_ERR_NORMAL_DISCONNECT) { - var reason = - _rdpClient.GetErrorDescription((uint)discReason, (uint)_rdpClient.ExtendedDisconnectReason); + var reason = _rdpClient.GetErrorDescription((uint)discReason, (uint)_rdpClient.ExtendedDisconnectReason); Event_Disconnected(this, reason, discReason); } @@ -806,7 +843,7 @@ namespace mRemoteNG.Connection.Protocol.RDP private void RDPEvent_OnLeaveFullscreenMode() { Fullscreen = false; - _leaveFullscreenEvent?.Invoke(this, new EventArgs()); + _leaveFullscreenEvent?.Invoke(this, EventArgs.Empty); } private void RdpClient_GotFocus(object sender, EventArgs e) @@ -824,8 +861,7 @@ namespace mRemoteNG.Connection.Protocol.RDP public event LeaveFullscreenEventHandler LeaveFullscreen { add => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value); - remove => - _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); + remove => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); } #endregion @@ -841,20 +877,10 @@ namespace mRemoteNG.Connection.Protocol.RDP } #endregion - - public static class Versions - { - public static readonly Version RDC60 = new Version(6, 0, 6000); - public static readonly Version RDC61 = new Version(6, 0, 6001); - 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, ElapsedEventArgs e) + private void tmrReconnect_Elapsed(object sender, ElapsedEventArgs e) { try { @@ -877,5 +903,6 @@ namespace mRemoteNG.Connection.Protocol.RDP } #endregion + } } \ No newline at end of file